Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

drafter

Package Overview
Dependencies
Maintainers
5
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

drafter - npm Package Compare versions

Comparing version 0.2.8 to 1.0.0

.npmignore

397

lib/drafter.js

@@ -1,390 +0,15 @@

// Generated by CoffeeScript 1.7.1
var Drafter, EXPAND_TYPES, GENERATE_BODY, GENERATE_SCHEMA, async, boutique, deepEqual, deepcopy, fs, gatherPayloads, generateBody, generateSchema, options, protagonist,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
try {
var protagonist = require('protagonist');
protagonist = require('protagonist');
boutique = require('boutique');
options = require('./options');
fs = require('fs');
async = require('async');
deepcopy = require('deepcopy');
deepEqual = require('deep-equal');
GENERATE_BODY = true;
GENERATE_SCHEMA = true;
EXPAND_TYPES = true;
gatherPayloads = function(result) {
var action, actionElement, attributes, element, example, payloads, request, resolvedAttributes, response, subElement, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _len6, _m, _n, _o, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6;
payloads = [];
_ref = result.ast.content;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
element = _ref[_i];
if (element.element === 'category') {
_ref1 = element.content;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
subElement = _ref1[_j];
if (subElement.element === 'resource') {
_ref2 = subElement.actions;
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
action = _ref2[_k];
attributes = null;
resolvedAttributes = null;
_ref3 = action.content;
for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
actionElement = _ref3[_l];
if (actionElement.element === 'dataStructure') {
attributes = actionElement;
}
if (actionElement.element === 'resolvedDataStructure') {
resolvedAttributes = actionElement;
}
}
if (resolvedAttributes == null) {
resolvedAttributes = attributes;
}
_ref4 = action.examples;
for (_m = 0, _len4 = _ref4.length; _m < _len4; _m++) {
example = _ref4[_m];
_ref5 = example.requests;
for (_n = 0, _len5 = _ref5.length; _n < _len5; _n++) {
request = _ref5[_n];
payloads.push({
payload: request,
actionAttributes: resolvedAttributes
});
}
_ref6 = example.responses;
for (_o = 0, _len6 = _ref6.length; _o < _len6; _o++) {
response = _ref6[_o];
payloads.push({
payload: response,
actionAttributes: resolvedAttributes
});
}
}
}
}
}
}
}
return payloads;
};
generateBody = function(payload, attributes, contentType, callback) {
if (GENERATE_BODY !== true) {
return callback(null);
}
if ((attributes == null) || (contentType == null) || payload.body) {
return callback(null);
}
return boutique.represent({
ast: attributes,
contentType: contentType
}, function(error, body) {
var resolved;
if ((error == null) && body) {
resolved = {
element: 'resolvedAsset',
attributes: {
role: 'bodyExample'
},
content: body
};
payload.content.push(resolved);
payload.body = body;
}
return callback(null);
});
};
generateSchema = function(payload, attributes, contentType, callback) {
if (GENERATE_SCHEMA !== true) {
return callback(null);
}
if ((attributes == null) || payload.schema || contentType.indexOf('json') === -1) {
return callback(null);
}
return boutique.represent({
ast: attributes,
contentType: 'application/schema+json'
}, function(error, body) {
var resolved;
if ((error == null) && body) {
resolved = {
element: 'resolvedAsset',
attributes: {
role: 'bodySchema'
},
content: body
};
payload.content.push(resolved);
payload.schema = body;
}
return callback(null);
});
};
Drafter = (function() {
Drafter.dataStructures = {};
Drafter.origDataStructures = {};
Drafter.appendResolved = {};
Drafter.defaultConfig = {
requireBlueprintName: false,
exportSourcemap: false
module.exports = {
parse: protagonist.parse,
parseSync: protagonist.parseSync,
};
} catch (error) {
var drafterjs = require('drafter.js');
function Drafter(config) {
this.config = config;
if (!this.config) {
this.config = Drafter.defaultConfig;
}
}
Drafter.prototype.makeFromPath = function(blueprintPath, callback) {
return fs.readFile(blueprintPath, 'utf8', (function(_this) {
return function(error, source) {
if (error) {
return callback(error);
}
return _this.make(source, callback);
};
})(this));
module.exports = {
parse: drafterjs.parse,
parseSync: drafterjs.parseSync,
};
Drafter.prototype.make = function(source, callback) {
return protagonist.parse(source, this.config, (function(_this) {
return function(error, result) {
var payloads, rule, ruleList, rules;
if (error) {
return callback(error);
}
if (EXPAND_TYPES !== true) {
return callback(null, result);
}
ruleList = ['mson-inheritance', 'mson-mixin', 'mson-member-type-name'];
rules = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = ruleList.length; _i < _len; _i++) {
rule = ruleList[_i];
_results.push(require('./rules/' + rule));
}
return _results;
})();
_this.dataStructures = {};
_this.origDataStructures = {};
_this.appendResolved = {};
delete result.ast.resourceGroups;
_this.expandNode(result.ast, rules, 'blueprint');
payloads = gatherPayloads(result);
return async.each(payloads, _this.resolvePayload, function(error) {
_this.reconstructResourceGroups(result.ast);
return callback(error || null, result);
});
};
})(this));
};
Drafter.prototype.resolvePayload = function(_arg, callback) {
var actionAttributes, attributes, contentType, element, header, payload, resolvedAttributes, _i, _j, _len, _len1, _ref, _ref1;
payload = _arg.payload, actionAttributes = _arg.actionAttributes;
attributes = null;
resolvedAttributes = null;
contentType = '';
_ref = payload.headers;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
header = _ref[_i];
if (header.name === 'Content-Type') {
contentType = header.value;
}
}
_ref1 = payload.content;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
element = _ref1[_j];
if (element.element === 'dataStructure') {
attributes = element;
}
if (element.element === 'resolvedDataStructure') {
resolvedAttributes = element;
}
}
if (resolvedAttributes == null) {
resolvedAttributes = attributes;
}
if (resolvedAttributes == null) {
resolvedAttributes = actionAttributes;
}
return generateBody(payload, resolvedAttributes, contentType, function(error) {
if (error) {
return callback(error);
}
return generateSchema(payload, resolvedAttributes, contentType, function(error) {
return callback(error || null);
});
});
};
Drafter.prototype.expandNode = function(node, rules, elementType, parentContent, parentElementType) {
var action, dataStructure, element, example, name, newNode, request, resourceSubElement, response, rule, subElement, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _len6, _len7, _len8, _len9, _m, _n, _o, _p, _q, _r, _ref, _ref1, _ref10, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9, _results;
if (elementType == null) {
elementType = node.element;
}
if (elementType === 'blueprint') {
_ref = node.content;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
element = _ref[_i];
if (element.element === 'category') {
_ref1 = element.content;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
subElement = _ref1[_j];
switch (subElement.element) {
case 'dataStructure':
if (typeof subElement.name === 'object' && ((_ref2 = subElement.name) != null ? _ref2.literal : void 0)) {
this.dataStructures[subElement.name.literal] = deepcopy(subElement);
this.origDataStructures[subElement.name.literal] = subElement;
this.appendResolved[subElement.name.literal] = element.content;
}
break;
case 'resource':
_ref3 = subElement.content;
for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) {
resourceSubElement = _ref3[_k];
if (resourceSubElement.element === 'dataStructure' && typeof resourceSubElement.name === 'object' && ((_ref4 = resourceSubElement.name) != null ? _ref4.literal : void 0)) {
this.dataStructures[resourceSubElement.name.literal] = deepcopy(resourceSubElement);
this.origDataStructures[resourceSubElement.name.literal] = resourceSubElement;
this.appendResolved[resourceSubElement.name.literal] = subElement.content;
}
}
}
}
}
}
for (_l = 0, _len3 = rules.length; _l < _len3; _l++) {
rule = rules[_l];
if (rule.init) {
rule.init.call(rule, this.dataStructures);
}
}
_ref5 = this.dataStructures;
for (name in _ref5) {
dataStructure = _ref5[name];
if (!deepEqual(dataStructure, this.origDataStructures[name])) {
dataStructure.element = 'resolvedDataStructure';
this.appendResolved[name].push(dataStructure);
}
}
}
if (elementType === 'resolvedDataStructure') {
return;
}
if (elementType === 'dataStructure') {
newNode = deepcopy(node);
} else {
newNode = node;
}
for (_m = 0, _len4 = rules.length; _m < _len4; _m++) {
rule = rules[_m];
if (__indexOf.call(Object.keys(rule), elementType) >= 0) {
rule[elementType].call(rule, newNode);
}
}
if ((parentElementType !== 'resource' && parentElementType !== 'blueprint') && elementType === 'dataStructure' && !deepEqual(node, newNode)) {
newNode.element = 'resolvedDataStructure';
parentContent.push(newNode);
}
switch (elementType) {
case 'resource':
_ref6 = node.actions;
for (_n = 0, _len5 = _ref6.length; _n < _len5; _n++) {
action = _ref6[_n];
this.expandNode(action, rules, 'action');
}
break;
case 'action':
_ref7 = node.examples;
for (_o = 0, _len6 = _ref7.length; _o < _len6; _o++) {
example = _ref7[_o];
this.expandNode(example, rules, 'transactionExample');
}
break;
case 'transactionExample':
_ref8 = node.requests;
for (_p = 0, _len7 = _ref8.length; _p < _len7; _p++) {
request = _ref8[_p];
this.expandNode(request, rules, 'payload');
}
_ref9 = node.responses;
for (_q = 0, _len8 = _ref9.length; _q < _len8; _q++) {
response = _ref9[_q];
this.expandNode(response, rules, 'payload');
}
}
if (node.content && Array.isArray(node.content)) {
_ref10 = node.content;
_results = [];
for (_r = 0, _len9 = _ref10.length; _r < _len9; _r++) {
element = _ref10[_r];
_results.push(this.expandNode(element, rules, null, node.content, elementType));
}
return _results;
}
};
Drafter.prototype.reconstructResourceGroups = function(ast) {
var description, element, name, resources, subElement, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3, _ref4, _results;
ast.resourceGroups = [];
_ref = ast.content;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
element = _ref[_i];
if (element.element === 'category') {
resources = [];
_ref1 = element.content;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
subElement = _ref1[_j];
if (subElement.element === 'resource') {
resources.push(subElement);
}
}
description = null;
name = (_ref2 = element.attributes) != null ? _ref2.name : void 0;
if (((_ref3 = element.content[0]) != null ? _ref3.element : void 0) === 'copy') {
if (((_ref4 = element.content[0]) != null ? _ref4.element : void 0) === 'copy') {
description = element.content[0].content;
}
}
if (resources.length || description || name) {
_results.push(ast.resourceGroups.push({
name: name || '',
description: description || '',
resources: resources
}));
} else {
_results.push(void 0);
}
} else {
_results.push(void 0);
}
}
return _results;
};
return Drafter;
})();
module.exports = Drafter;
module.exports.options = options;
}
{
"name": "drafter",
"version": "0.2.8",
"author": "Apiary.io <support@apiary.io>",
"description": "Snow Crash parser harness",
"license": "MIT",
"version": "1.0.0",
"description": "Node API Blueprint Parser",
"main": "lib/drafter.js",
"bin": {
"drafter": "bin/drafter"
},
"repository": "apiaryio/drafter.js",
"engines": {
"node": ">= 0.10.x"
"node": ">= 0.12"
},
"repository": {
"type": "git",
"url": "https://github.com/apiaryio/drafter-npm"
},
"author": "Apiary Czech Republic, s.r.o. <support@apiary.io>",
"license": "MIT",
"bugs": {
"url": "https://github.com/apiaryio/drafter-npm/issues"
},
"homepage": "https://github.com/apiaryio/drafter-npm",
"scripts": {
"test": "scripts/test",
"prepublish": "scripts/build"
"test": "mocha"
},
"dependencies": {
"async": "~0.9.0",
"boutique": "~0.1.7",
"deep-equal": "1.0.x",
"deepcopy": "0.4.x",
"protagonist": "~0.20.1",
"yargs": "~1.3.3"
"drafter.js": "^2.4.3"
},
"optionalDependencies": {
"protagonist": "^1.4.1"
},
"devDependencies": {
"coffee-script": "~1.7.1",
"chai": "~1.10.0",
"mocha": "~2.0.1"
"mocha": "~1.17.1",
"chai": "~1.9.0"
}
}

@@ -1,104 +0,81 @@

# Drafter
![logo](https://raw.github.com/apiaryio/api-blueprint/master/assets/logo_apiblueprint.png)
[![Circle CI](https://circleci.com/gh/apiaryio/drafter.js.svg?style=svg&circle-token=f4b9c3fc34979e81d36c9d15e576e23f62e1e913)](https://circleci.com/gh/apiaryio/drafter.js)
# Drafter NPM Package [![Build Status](https://travis-ci.org/apiaryio/drafter-npm.svg?branch=master)](https://travis-ci.org/apiaryio/drafter-npm)
Snow Crash parser harness.
The Drafter NPM package is an API Blueprint parser for Node. This package is a
wrapper around the underlying C++ parser
[Drafter](https://github.com/apiaryio/drafter). Drafter NPM optionally depends
on the C++ binding to Drafter
[Protagonist](https://github.com/apiaryio/protagonist). If for any reason
Protagonist is not installable, this package will fallback to using the slower,
pure JavaScript version of Drafter,
[drafter.js](https://github.com/apiaryio/drafter.js).
## Introduction
Drafter takes an API blueprint on its input, parses, and then processes the AST to exposes the [Parse Result][] for further use. Drafter expands MSON data structures from the AST and generates JSON representations and JSON Schema representation of MSON structures where they are not found in the original AST.
## Installation
Node.js v0.10 is required.
Drafter can be installed from NPM. If you want to use Drafter from a web
browser, check out [drafter.js](https://github.com/apiaryio/drafter.js).
```shell
$ npm install -g drafter
$ npm install drafter
```
## Getting Started
## Usage
### Library
```js
var Drafter = require('drafter');
var blueprint = '# GET /message\n' +
'+ Response 200\n' +
'\n' +
' Hello World!\n'
var drafter = require('drafter');
```
var drafter = new Drafter;
drafter.make(blueprint, function(error, result) {
if (error) {
console.log(error);
return;
}
Once you've included drafter, you can parse an API Blueprint asynchronously:
console.log(JSON.stringify(result, null, 2));
```js
var options = {
generateSourcemap: true,
};
drafter.parse('# API Blueprint...', options, function(err, result) {
if (err) {
console.log(err);
} else {
console.log(result);
}
});
```
### CLI Tool
Alternatively, you can use Drafter synchronously:
```shell
$ cat << 'EOF' > blueprint.apib
# GET /message
+ Response 200
Hello World!
EOF
$ drafter blueprint.apib
```js
try {
var result = drafter.parse('# API Blueprint...', options);
console.log(result);
} catch (err) {
console.log(err);
}
```
## Resolved Named Types
### Parsing Options
The three rules for when MSON AST is expanded are:
Options can be passed to the parser as an optional second argument to both the
asynchronous and synchronous interfaces:
* If a named type is a sub-type of another named type
* If a named types includes a mixin
* If a value member or property member is referencing a named type
```js
var options = {
generateSourceMap: true
}
The expanded data structures are added to the array which has the original data structures with their element name set to `resolvedDataStructure`.
## Resolved Assets
The resolved assets for a *payload body example* and *payload body schema* are added to the array in the `content` key of the **Payload Object** with their element name set to `resolvedAsset` and `role` in `attributes` set as `bodyExample` and `bodySchema` respectively.
A sample part of payload object is given below
```json
{
"content": [
{
"element": "resolvedAsset",
"attributes": {
"role": "bodyExample"
},
"content": "{\"id\":\"250FF\",\"percent_off\":25,\"redeem_by\":null}"
},
{
"element": "resolvedAsset",
"attributes": {
"role": "bodySchema"
},
"content": "{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"string\"},\"percent_off\":{\"type\":\"number\"},\"redeem_by\":{\"type\":\"number\",\"description\":\"Date after which the coupon can no longer be redeemed\"}},\"$schema\":\"http://json-schema.org/draft-04/schema#\"}"
}
]
}
drafter.parse('# My API', options, callback);
```
## Testing
The available options are:
Inside the drafter repository you can execute the following to run the test suite:
Name | Description
---------------------- | ----------------------------------------------------------
`requireBlueprintName` | Require parsed blueprints have a title (default: false)
`generateSourceMap` | Enable sourcemap generation (default: false)
`type` | Set the output structure type as either `ast` or `refract` (default: `refract`)
```bash
$ npm install
$ npm test
```
**NOTE**: *The `ast` option is deprecated in favour of `refract`.*
### Contribute
Fork & Pull Request.
## License
MIT License. See the [LICENSE](https://github.com/apiaryio/drafter.js/blob/master/LICENSE) file.
[Boutique]: https://github.com/apiaryio/boutique.js
[Parse Result]: https://github.com/apiaryio/api-blueprint-ast/blob/master/Parse%20Result.md
MIT License. See the [LICENSE](LICENSE) file.

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc