Befor generating
This commit is contained in:
-1
@@ -1 +0,0 @@
|
|||||||
../baseline-browser-mapping/dist/cli.cjs
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../browserslist/cli.js
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../esprima/bin/esparse.js
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../esprima/bin/esvalidate.js
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../glob/dist/esm/bin.mjs
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../js-yaml/bin/js-yaml.js
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../jsesc/bin/jsesc
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../json5/lib/cli.js
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../loose-envify/cli.js
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../which/bin/node-which
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../@babel/parser/bin/babel-parser.js
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../regjsparser/bin/parser
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../resolve/bin/resolve
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../rimraf/dist/esm/bin.mjs
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../rollup/dist/bin/rollup
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../semver/bin/semver.js
|
|
||||||
-1
@@ -1 +0,0 @@
|
|||||||
../update-browserslist-db/cli.js
|
|
||||||
-3106
File diff suppressed because it is too large
Load Diff
-21
@@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2015 James Messinger
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
-162
@@ -1,162 +0,0 @@
|
|||||||
JSON Schema $Ref Parser
|
|
||||||
============================
|
|
||||||
#### Parse, Resolve, and Dereference JSON Schema $ref pointers
|
|
||||||
|
|
||||||
[](https://github.com/APIDevTools/json-schema-ref-parser/actions)
|
|
||||||
[](https://coveralls.io/github/APIDevTools/json-schema-ref-parser)
|
|
||||||
|
|
||||||
[](https://www.npmjs.com/package/@apidevtools/json-schema-ref-parser)
|
|
||||||
[](https://david-dm.org/APIDevTools/json-schema-ref-parser)
|
|
||||||
[](LICENSE)
|
|
||||||
[](https://plant.treeware.earth/APIDevTools/json-schema-ref-parser)
|
|
||||||
|
|
||||||
|
|
||||||
[](https://github.com/APIDevTools/json-schema-ref-parser/actions)
|
|
||||||
|
|
||||||
|
|
||||||
The Problem:
|
|
||||||
--------------------------
|
|
||||||
You've got a JSON Schema with `$ref` pointers to other files and/or URLs. Maybe you know all the referenced files ahead of time. Maybe you don't. Maybe some are local files, and others are remote URLs. Maybe they are a mix of JSON and YAML format. Maybe some of the files contain cross-references to each other.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
{
|
|
||||||
"definitions": {
|
|
||||||
"person": {
|
|
||||||
// references an external file
|
|
||||||
"$ref": "schemas/people/Bruce-Wayne.json"
|
|
||||||
},
|
|
||||||
"place": {
|
|
||||||
// references a sub-schema in an external file
|
|
||||||
"$ref": "schemas/places.yaml#/definitions/Gotham-City"
|
|
||||||
},
|
|
||||||
"thing": {
|
|
||||||
// references a URL
|
|
||||||
"$ref": "http://wayne-enterprises.com/things/batmobile"
|
|
||||||
},
|
|
||||||
"color": {
|
|
||||||
// references a value in an external file via an internal reference
|
|
||||||
"$ref": "#/definitions/thing/properties/colors/black-as-the-night"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
The Solution:
|
|
||||||
--------------------------
|
|
||||||
JSON Schema $Ref Parser is a full [JSON Reference](https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03) and [JSON Pointer](https://tools.ietf.org/html/rfc6901) implementation that crawls even the most complex [JSON Schemas](http://json-schema.org/latest/json-schema-core.html) and gives you simple, straightforward JavaScript objects.
|
|
||||||
|
|
||||||
- Use **JSON** or **YAML** schemas — or even a mix of both!
|
|
||||||
- Supports `$ref` pointers to external files and URLs, as well as [custom sources](https://apitools.dev/json-schema-ref-parser/docs/plugins/resolvers.html) such as databases
|
|
||||||
- Can [bundle](https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#bundlepath-options-callback) multiple files into a single schema that only has _internal_ `$ref` pointers
|
|
||||||
- Can [dereference](https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#dereferencepath-options-callback) your schema, producing a plain-old JavaScript object that's easy to work with
|
|
||||||
- Supports [circular references](https://apitools.dev/json-schema-ref-parser/docs/#circular-refs), nested references, back-references, and cross-references between files
|
|
||||||
- Maintains object reference equality — `$ref` pointers to the same value always resolve to the same object instance
|
|
||||||
- Tested in Node v10, v12, & v14, and all major web browsers on Windows, Mac, and Linux
|
|
||||||
|
|
||||||
|
|
||||||
Example
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
$RefParser.dereference(mySchema, (err, schema) => {
|
|
||||||
if (err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// `schema` is just a normal JavaScript object that contains your entire JSON Schema,
|
|
||||||
// including referenced files, combined into a single object
|
|
||||||
console.log(schema.definitions.person.properties.firstName);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
```
|
|
||||||
|
|
||||||
Or use `async`/`await` syntax instead. The following example is the same as above:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
try {
|
|
||||||
let schema = await $RefParser.dereference(mySchema);
|
|
||||||
console.log(schema.definitions.person.properties.firstName);
|
|
||||||
}
|
|
||||||
catch(err) {
|
|
||||||
console.error(err);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
For more detailed examples, please see the [API Documentation](https://apitools.dev/json-schema-ref-parser/docs/)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Installation
|
|
||||||
--------------------------
|
|
||||||
Install using [npm](https://docs.npmjs.com/about-npm/):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install @apidevtools/json-schema-ref-parser
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Usage
|
|
||||||
--------------------------
|
|
||||||
When using JSON Schema $Ref Parser in Node.js apps, you'll probably want to use **CommonJS** syntax:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const $RefParser = require("@apidevtools/json-schema-ref-parser");
|
|
||||||
```
|
|
||||||
|
|
||||||
When using a transpiler such as [Babel](https://babeljs.io/) or [TypeScript](https://www.typescriptlang.org/), or a bundler such as [Webpack](https://webpack.js.org/) or [Rollup](https://rollupjs.org/), you can use **ECMAScript modules** syntax instead:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
import $RefParser from "@apidevtools/json-schema-ref-parser";
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Browser support
|
|
||||||
--------------------------
|
|
||||||
JSON Schema $Ref Parser supports recent versions of every major web browser. Older browsers may require [Babel](https://babeljs.io/) and/or [polyfills](https://babeljs.io/docs/en/next/babel-polyfill).
|
|
||||||
|
|
||||||
To use JSON Schema $Ref Parser in a browser, you'll need to use a bundling tool such as [Webpack](https://webpack.js.org/), [Rollup](https://rollupjs.org/), [Parcel](https://parceljs.org/), or [Browserify](http://browserify.org/). Some bundlers may require a bit of configuration, such as setting `browser: true` in [rollup-plugin-resolve](https://github.com/rollup/rollup-plugin-node-resolve).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
API Documentation
|
|
||||||
--------------------------
|
|
||||||
Full API documentation is available [right here](https://apitools.dev/json-schema-ref-parser/docs/)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Contributing
|
|
||||||
--------------------------
|
|
||||||
I welcome any contributions, enhancements, and bug-fixes. [Open an issue](https://github.com/APIDevTools/json-schema-ref-parser/issues) on GitHub and [submit a pull request](https://github.com/APIDevTools/json-schema-ref-parser/pulls).
|
|
||||||
|
|
||||||
#### Building/Testing
|
|
||||||
To build/test the project locally on your computer:
|
|
||||||
|
|
||||||
1. __Clone this repo__<br>
|
|
||||||
`git clone https://github.com/APIDevTools/json-schema-ref-parser.git`
|
|
||||||
|
|
||||||
2. __Install dependencies__<br>
|
|
||||||
`npm install`
|
|
||||||
|
|
||||||
3. __Run the tests__<br>
|
|
||||||
`npm test`
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
License
|
|
||||||
--------------------------
|
|
||||||
JSON Schema $Ref Parser is 100% free and open-source, under the [MIT license](LICENSE). Use it however you want.
|
|
||||||
|
|
||||||
This package is [Treeware](http://treeware.earth). If you use it in production, then we ask that you [**buy the world a tree**](https://plant.treeware.earth/APIDevTools/json-schema-ref-parser) to thank us for our work. By contributing to the Treeware forest you’ll be creating employment for local families and restoring wildlife habitats.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Big Thanks To
|
|
||||||
--------------------------
|
|
||||||
Thanks to these awesome companies for their support of Open Source developers ❤
|
|
||||||
|
|
||||||
[](https://stoplight.io/?utm_source=github&utm_medium=readme&utm_campaign=json_schema_ref_parser)
|
|
||||||
[](https://saucelabs.com)
|
|
||||||
[](https://coveralls.io)
|
|
||||||
-261
@@ -1,261 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
const $Ref = require("./ref");
|
|
||||||
const Pointer = require("./pointer");
|
|
||||||
const url = require("./util/url");
|
|
||||||
|
|
||||||
module.exports = bundle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bundles all external JSON references into the main JSON schema, thus resulting in a schema that
|
|
||||||
* only has *internal* references, not any *external* references.
|
|
||||||
* This method mutates the JSON schema object, adding new references and re-mapping existing ones.
|
|
||||||
*
|
|
||||||
* @param {$RefParser} parser
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
*/
|
|
||||||
function bundle (parser, options) {
|
|
||||||
// console.log('Bundling $ref pointers in %s', parser.$refs._root$Ref.path);
|
|
||||||
|
|
||||||
// Build an inventory of all $ref pointers in the JSON Schema
|
|
||||||
let inventory = [];
|
|
||||||
crawl(parser, "schema", parser.$refs._root$Ref.path + "#", "#", 0, inventory, parser.$refs, options);
|
|
||||||
|
|
||||||
// Remap all $ref pointers
|
|
||||||
remap(inventory);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively crawls the given value, and inventories all JSON references.
|
|
||||||
*
|
|
||||||
* @param {object} parent - The object containing the value to crawl. If the value is not an object or array, it will be ignored.
|
|
||||||
* @param {string} key - The property key of `parent` to be crawled
|
|
||||||
* @param {string} path - The full path of the property being crawled, possibly with a JSON Pointer in the hash
|
|
||||||
* @param {string} pathFromRoot - The path of the property being crawled, from the schema root
|
|
||||||
* @param {object[]} inventory - An array of already-inventoried $ref pointers
|
|
||||||
* @param {$Refs} $refs
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
*/
|
|
||||||
function crawl (parent, key, path, pathFromRoot, indirections, inventory, $refs, options) {
|
|
||||||
let obj = key === null ? parent : parent[key];
|
|
||||||
|
|
||||||
if (obj && typeof obj === "object" && !ArrayBuffer.isView(obj)) {
|
|
||||||
if ($Ref.isAllowed$Ref(obj)) {
|
|
||||||
inventory$Ref(parent, key, path, pathFromRoot, indirections, inventory, $refs, options);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Crawl the object in a specific order that's optimized for bundling.
|
|
||||||
// This is important because it determines how `pathFromRoot` gets built,
|
|
||||||
// which later determines which keys get dereferenced and which ones get remapped
|
|
||||||
let keys = Object.keys(obj)
|
|
||||||
.sort((a, b) => {
|
|
||||||
// Most people will expect references to be bundled into the the "definitions" property,
|
|
||||||
// so we always crawl that property first, if it exists.
|
|
||||||
if (a === "definitions") {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
else if (b === "definitions") {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Otherwise, crawl the keys based on their length.
|
|
||||||
// This produces the shortest possible bundled references
|
|
||||||
return a.length - b.length;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-shadow
|
|
||||||
for (let key of keys) {
|
|
||||||
let keyPath = Pointer.join(path, key);
|
|
||||||
let keyPathFromRoot = Pointer.join(pathFromRoot, key);
|
|
||||||
let value = obj[key];
|
|
||||||
|
|
||||||
if ($Ref.isAllowed$Ref(value)) {
|
|
||||||
inventory$Ref(obj, key, path, keyPathFromRoot, indirections, inventory, $refs, options);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
crawl(obj, key, keyPath, keyPathFromRoot, indirections, inventory, $refs, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inventories the given JSON Reference (i.e. records detailed information about it so we can
|
|
||||||
* optimize all $refs in the schema), and then crawls the resolved value.
|
|
||||||
*
|
|
||||||
* @param {object} $refParent - The object that contains a JSON Reference as one of its keys
|
|
||||||
* @param {string} $refKey - The key in `$refParent` that is a JSON Reference
|
|
||||||
* @param {string} path - The full path of the JSON Reference at `$refKey`, possibly with a JSON Pointer in the hash
|
|
||||||
* @param {string} pathFromRoot - The path of the JSON Reference at `$refKey`, from the schema root
|
|
||||||
* @param {object[]} inventory - An array of already-inventoried $ref pointers
|
|
||||||
* @param {$Refs} $refs
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
*/
|
|
||||||
function inventory$Ref ($refParent, $refKey, path, pathFromRoot, indirections, inventory, $refs, options) {
|
|
||||||
let $ref = $refKey === null ? $refParent : $refParent[$refKey];
|
|
||||||
let $refPath = url.resolve(path, $ref.$ref);
|
|
||||||
let pointer = $refs._resolve($refPath, pathFromRoot, options);
|
|
||||||
if (pointer === null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let depth = Pointer.parse(pathFromRoot).length;
|
|
||||||
let file = url.stripHash(pointer.path);
|
|
||||||
let hash = url.getHash(pointer.path);
|
|
||||||
let external = file !== $refs._root$Ref.path;
|
|
||||||
let extended = $Ref.isExtended$Ref($ref);
|
|
||||||
indirections += pointer.indirections;
|
|
||||||
|
|
||||||
let existingEntry = findInInventory(inventory, $refParent, $refKey);
|
|
||||||
if (existingEntry) {
|
|
||||||
// This $Ref has already been inventoried, so we don't need to process it again
|
|
||||||
if (depth < existingEntry.depth || indirections < existingEntry.indirections) {
|
|
||||||
removeFromInventory(inventory, existingEntry);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inventory.push({
|
|
||||||
$ref, // The JSON Reference (e.g. {$ref: string})
|
|
||||||
parent: $refParent, // The object that contains this $ref pointer
|
|
||||||
key: $refKey, // The key in `parent` that is the $ref pointer
|
|
||||||
pathFromRoot, // The path to the $ref pointer, from the JSON Schema root
|
|
||||||
depth, // How far from the JSON Schema root is this $ref pointer?
|
|
||||||
file, // The file that the $ref pointer resolves to
|
|
||||||
hash, // The hash within `file` that the $ref pointer resolves to
|
|
||||||
value: pointer.value, // The resolved value of the $ref pointer
|
|
||||||
circular: pointer.circular, // Is this $ref pointer DIRECTLY circular? (i.e. it references itself)
|
|
||||||
extended, // Does this $ref extend its resolved value? (i.e. it has extra properties, in addition to "$ref")
|
|
||||||
external, // Does this $ref pointer point to a file other than the main JSON Schema file?
|
|
||||||
indirections, // The number of indirect references that were traversed to resolve the value
|
|
||||||
});
|
|
||||||
|
|
||||||
// Recursively crawl the resolved value
|
|
||||||
if (!existingEntry) {
|
|
||||||
crawl(pointer.value, null, pointer.path, pathFromRoot, indirections + 1, inventory, $refs, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Re-maps every $ref pointer, so that they're all relative to the root of the JSON Schema.
|
|
||||||
* Each referenced value is dereferenced EXACTLY ONCE. All subsequent references to the same
|
|
||||||
* value are re-mapped to point to the first reference.
|
|
||||||
*
|
|
||||||
* @example:
|
|
||||||
* {
|
|
||||||
* first: { $ref: somefile.json#/some/part },
|
|
||||||
* second: { $ref: somefile.json#/another/part },
|
|
||||||
* third: { $ref: somefile.json },
|
|
||||||
* fourth: { $ref: somefile.json#/some/part/sub/part }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* In this example, there are four references to the same file, but since the third reference points
|
|
||||||
* to the ENTIRE file, that's the only one we need to dereference. The other three can just be
|
|
||||||
* remapped to point inside the third one.
|
|
||||||
*
|
|
||||||
* On the other hand, if the third reference DIDN'T exist, then the first and second would both need
|
|
||||||
* to be dereferenced, since they point to different parts of the file. The fourth reference does NOT
|
|
||||||
* need to be dereferenced, because it can be remapped to point inside the first one.
|
|
||||||
*
|
|
||||||
* @param {object[]} inventory
|
|
||||||
*/
|
|
||||||
function remap (inventory) {
|
|
||||||
// Group & sort all the $ref pointers, so they're in the order that we need to dereference/remap them
|
|
||||||
inventory.sort((a, b) => {
|
|
||||||
if (a.file !== b.file) {
|
|
||||||
// Group all the $refs that point to the same file
|
|
||||||
return a.file < b.file ? -1 : +1;
|
|
||||||
}
|
|
||||||
else if (a.hash !== b.hash) {
|
|
||||||
// Group all the $refs that point to the same part of the file
|
|
||||||
return a.hash < b.hash ? -1 : +1;
|
|
||||||
}
|
|
||||||
else if (a.circular !== b.circular) {
|
|
||||||
// If the $ref points to itself, then sort it higher than other $refs that point to this $ref
|
|
||||||
return a.circular ? -1 : +1;
|
|
||||||
}
|
|
||||||
else if (a.extended !== b.extended) {
|
|
||||||
// If the $ref extends the resolved value, then sort it lower than other $refs that don't extend the value
|
|
||||||
return a.extended ? +1 : -1;
|
|
||||||
}
|
|
||||||
else if (a.indirections !== b.indirections) {
|
|
||||||
// Sort direct references higher than indirect references
|
|
||||||
return a.indirections - b.indirections;
|
|
||||||
}
|
|
||||||
else if (a.depth !== b.depth) {
|
|
||||||
// Sort $refs by how close they are to the JSON Schema root
|
|
||||||
return a.depth - b.depth;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Determine how far each $ref is from the "definitions" property.
|
|
||||||
// Most people will expect references to be bundled into the the "definitions" property if possible.
|
|
||||||
let aDefinitionsIndex = a.pathFromRoot.lastIndexOf("/definitions");
|
|
||||||
let bDefinitionsIndex = b.pathFromRoot.lastIndexOf("/definitions");
|
|
||||||
|
|
||||||
if (aDefinitionsIndex !== bDefinitionsIndex) {
|
|
||||||
// Give higher priority to the $ref that's closer to the "definitions" property
|
|
||||||
return bDefinitionsIndex - aDefinitionsIndex;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// All else is equal, so use the shorter path, which will produce the shortest possible reference
|
|
||||||
return a.pathFromRoot.length - b.pathFromRoot.length;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let file, hash, pathFromRoot;
|
|
||||||
for (let entry of inventory) {
|
|
||||||
// console.log('Re-mapping $ref pointer "%s" at %s', entry.$ref.$ref, entry.pathFromRoot);
|
|
||||||
|
|
||||||
if (!entry.external) {
|
|
||||||
// This $ref already resolves to the main JSON Schema file
|
|
||||||
entry.$ref.$ref = entry.hash;
|
|
||||||
}
|
|
||||||
else if (entry.file === file && entry.hash === hash) {
|
|
||||||
// This $ref points to the same value as the prevous $ref, so remap it to the same path
|
|
||||||
entry.$ref.$ref = pathFromRoot;
|
|
||||||
}
|
|
||||||
else if (entry.file === file && entry.hash.indexOf(hash + "/") === 0) {
|
|
||||||
// This $ref points to a sub-value of the prevous $ref, so remap it beneath that path
|
|
||||||
entry.$ref.$ref = Pointer.join(pathFromRoot, Pointer.parse(entry.hash.replace(hash, "#")));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// We've moved to a new file or new hash
|
|
||||||
file = entry.file;
|
|
||||||
hash = entry.hash;
|
|
||||||
pathFromRoot = entry.pathFromRoot;
|
|
||||||
|
|
||||||
// This is the first $ref to point to this value, so dereference the value.
|
|
||||||
// Any other $refs that point to the same value will point to this $ref instead
|
|
||||||
entry.$ref = entry.parent[entry.key] = $Ref.dereference(entry.$ref, entry.value);
|
|
||||||
|
|
||||||
if (entry.circular) {
|
|
||||||
// This $ref points to itself
|
|
||||||
entry.$ref.$ref = entry.pathFromRoot;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log(' new value: %s', (entry.$ref && entry.$ref.$ref) ? entry.$ref.$ref : '[object Object]');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO
|
|
||||||
*/
|
|
||||||
function findInInventory (inventory, $refParent, $refKey) {
|
|
||||||
for (let i = 0; i < inventory.length; i++) {
|
|
||||||
let existingEntry = inventory[i];
|
|
||||||
if (existingEntry.parent === $refParent && existingEntry.key === $refKey) {
|
|
||||||
return existingEntry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeFromInventory (inventory, entry) {
|
|
||||||
let index = inventory.indexOf(entry);
|
|
||||||
inventory.splice(index, 1);
|
|
||||||
}
|
|
||||||
Generated
Vendored
-205
@@ -1,205 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
const $Ref = require("./ref");
|
|
||||||
const Pointer = require("./pointer");
|
|
||||||
const { ono } = require("@jsdevtools/ono");
|
|
||||||
const url = require("./util/url");
|
|
||||||
|
|
||||||
module.exports = dereference;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Crawls the JSON schema, finds all JSON references, and dereferences them.
|
|
||||||
* This method mutates the JSON schema object, replacing JSON references with their resolved value.
|
|
||||||
*
|
|
||||||
* @param {$RefParser} parser
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
*/
|
|
||||||
function dereference (parser, options) {
|
|
||||||
// console.log('Dereferencing $ref pointers in %s', parser.$refs._root$Ref.path);
|
|
||||||
let dereferenced = crawl(parser.schema, parser.$refs._root$Ref.path, "#", new Set(), new Set(), new Map(), parser.$refs, options);
|
|
||||||
parser.$refs.circular = dereferenced.circular;
|
|
||||||
parser.schema = dereferenced.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively crawls the given value, and dereferences any JSON references.
|
|
||||||
*
|
|
||||||
* @param {*} obj - The value to crawl. If it's not an object or array, it will be ignored.
|
|
||||||
* @param {string} path - The full path of `obj`, possibly with a JSON Pointer in the hash
|
|
||||||
* @param {string} pathFromRoot - The path of `obj` from the schema root
|
|
||||||
* @param {Set<object>} parents - An array of the parent objects that have already been dereferenced
|
|
||||||
* @param {Set<object>} processedObjects - An array of all the objects that have already been processed
|
|
||||||
* @param {Map<string,object>} dereferencedCache - An map of all the dereferenced objects
|
|
||||||
* @param {$Refs} $refs
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
* @returns {{value: object, circular: boolean}}
|
|
||||||
*/
|
|
||||||
function crawl (obj, path, pathFromRoot, parents, processedObjects, dereferencedCache, $refs, options) {
|
|
||||||
let dereferenced;
|
|
||||||
let result = {
|
|
||||||
value: obj,
|
|
||||||
circular: false
|
|
||||||
};
|
|
||||||
|
|
||||||
let isExcludedPath = options.dereference.excludedPathMatcher;
|
|
||||||
|
|
||||||
if (options.dereference.circular === "ignore" || !processedObjects.has(obj)) {
|
|
||||||
if (obj && typeof obj === "object" && !ArrayBuffer.isView(obj) && !isExcludedPath(pathFromRoot)) {
|
|
||||||
parents.add(obj);
|
|
||||||
processedObjects.add(obj);
|
|
||||||
|
|
||||||
if ($Ref.isAllowed$Ref(obj, options)) {
|
|
||||||
dereferenced = dereference$Ref(obj, path, pathFromRoot, parents, processedObjects, dereferencedCache, $refs, options);
|
|
||||||
result.circular = dereferenced.circular;
|
|
||||||
result.value = dereferenced.value;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (const key of Object.keys(obj)) {
|
|
||||||
let keyPath = Pointer.join(path, key);
|
|
||||||
let keyPathFromRoot = Pointer.join(pathFromRoot, key);
|
|
||||||
|
|
||||||
if (isExcludedPath(keyPathFromRoot)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let value = obj[key];
|
|
||||||
let circular = false;
|
|
||||||
|
|
||||||
if ($Ref.isAllowed$Ref(value, options)) {
|
|
||||||
dereferenced = dereference$Ref(value, keyPath, keyPathFromRoot, parents, processedObjects, dereferencedCache, $refs, options);
|
|
||||||
circular = dereferenced.circular;
|
|
||||||
// Avoid pointless mutations; breaks frozen objects to no profit
|
|
||||||
if (obj[key] !== dereferenced.value) {
|
|
||||||
obj[key] = dereferenced.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!parents.has(value)) {
|
|
||||||
dereferenced = crawl(value, keyPath, keyPathFromRoot, parents, processedObjects, dereferencedCache, $refs, options);
|
|
||||||
circular = dereferenced.circular;
|
|
||||||
// Avoid pointless mutations; breaks frozen objects to no profit
|
|
||||||
if (obj[key] !== dereferenced.value) {
|
|
||||||
obj[key] = dereferenced.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
circular = foundCircularReference(keyPath, $refs, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the "isCircular" flag if this or any other property is circular
|
|
||||||
result.circular = result.circular || circular;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parents.delete(obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dereferences the given JSON Reference, and then crawls the resulting value.
|
|
||||||
*
|
|
||||||
* @param {{$ref: string}} $ref - The JSON Reference to resolve
|
|
||||||
* @param {string} path - The full path of `$ref`, possibly with a JSON Pointer in the hash
|
|
||||||
* @param {string} pathFromRoot - The path of `$ref` from the schema root
|
|
||||||
* @param {Set<object>} parents - An array of the parent objects that have already been dereferenced
|
|
||||||
* @param {Set<object>} processedObjects - An array of all the objects that have already been dereferenced
|
|
||||||
* @param {Map<string,object>} dereferencedCache - An map of all the dereferenced objects
|
|
||||||
* @param {$Refs} $refs
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
* @returns {{value: object, circular: boolean}}
|
|
||||||
*/
|
|
||||||
function dereference$Ref ($ref, path, pathFromRoot, parents, processedObjects, dereferencedCache, $refs, options) {
|
|
||||||
// console.log('Dereferencing $ref pointer "%s" at %s', $ref.$ref, path);
|
|
||||||
|
|
||||||
let $refPath = url.resolve(path, $ref.$ref);
|
|
||||||
|
|
||||||
const cache = dereferencedCache.get($refPath);
|
|
||||||
if (cache) {
|
|
||||||
const refKeys = Object.keys($ref);
|
|
||||||
if (refKeys.length > 1) {
|
|
||||||
const extraKeys = {};
|
|
||||||
for (let key of refKeys) {
|
|
||||||
if (key !== "$ref" && !(key in cache.value)) {
|
|
||||||
extraKeys[key] = $ref[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
circular: cache.circular,
|
|
||||||
value: Object.assign({}, cache.value, extraKeys),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return cache;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let pointer = $refs._resolve($refPath, path, options);
|
|
||||||
|
|
||||||
if (pointer === null) {
|
|
||||||
return {
|
|
||||||
circular: false,
|
|
||||||
value: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for circular references
|
|
||||||
let directCircular = pointer.circular;
|
|
||||||
let circular = directCircular || parents.has(pointer.value);
|
|
||||||
circular && foundCircularReference(path, $refs, options);
|
|
||||||
|
|
||||||
// Dereference the JSON reference
|
|
||||||
let dereferencedValue = $Ref.dereference($ref, pointer.value);
|
|
||||||
|
|
||||||
// Crawl the dereferenced value (unless it's circular)
|
|
||||||
if (!circular) {
|
|
||||||
// Determine if the dereferenced value is circular
|
|
||||||
let dereferenced = crawl(dereferencedValue, pointer.path, pathFromRoot, parents, processedObjects, dereferencedCache, $refs, options);
|
|
||||||
circular = dereferenced.circular;
|
|
||||||
dereferencedValue = dereferenced.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (circular && !directCircular && options.dereference.circular === "ignore") {
|
|
||||||
// The user has chosen to "ignore" circular references, so don't change the value
|
|
||||||
dereferencedValue = $ref;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (directCircular) {
|
|
||||||
// The pointer is a DIRECT circular reference (i.e. it references itself).
|
|
||||||
// So replace the $ref path with the absolute path from the JSON Schema root
|
|
||||||
dereferencedValue.$ref = pathFromRoot;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const dereferencedObject = {
|
|
||||||
circular,
|
|
||||||
value: dereferencedValue
|
|
||||||
};
|
|
||||||
|
|
||||||
// only cache if no extra properties than $ref
|
|
||||||
if (Object.keys($ref).length === 1) {
|
|
||||||
dereferencedCache.set($refPath, dereferencedObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dereferencedObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a circular reference is found.
|
|
||||||
* It sets the {@link $Refs#circular} flag, and throws an error if options.dereference.circular is false.
|
|
||||||
*
|
|
||||||
* @param {string} keyPath - The JSON Reference path of the circular reference
|
|
||||||
* @param {$Refs} $refs
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
* @returns {boolean} - always returns true, to indicate that a circular reference was found
|
|
||||||
*/
|
|
||||||
function foundCircularReference (keyPath, $refs, options) {
|
|
||||||
$refs.circular = true;
|
|
||||||
if (!options.dereference.circular) {
|
|
||||||
throw ono.reference(`Circular $ref pointer found at ${keyPath}`);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
-487
@@ -1,487 +0,0 @@
|
|||||||
import { JSONSchema4, JSONSchema4Type, JSONSchema6, JSONSchema6Type, JSONSchema7, JSONSchema7Type } from "json-schema";
|
|
||||||
|
|
||||||
export = $RefParser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the default export of JSON Schema $Ref Parser. You can creates instances of this class using new $RefParser(), or you can just call its static methods.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html
|
|
||||||
*/
|
|
||||||
declare class $RefParser {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `schema` property is the parsed/bundled/dereferenced JSON Schema object. This is the same value that is passed to the callback function (or Promise) when calling the parse, bundle, or dereference methods.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#schema
|
|
||||||
*/
|
|
||||||
public schema: $RefParser.JSONSchema;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The $refs property is a `$Refs` object, which lets you access all of the externally-referenced files in the schema, as well as easily get and set specific values in the schema using JSON pointers.
|
|
||||||
*
|
|
||||||
* This is the same value that is passed to the callback function (or Promise) when calling the `resolve` method.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#refs
|
|
||||||
*/
|
|
||||||
public $refs: $RefParser.$Refs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dereferences all `$ref` pointers in the JSON Schema, replacing each reference with its resolved value. This results in a schema object that does not contain any `$ref` pointers. Instead, it's a normal JavaScript object tree that can easily be crawled and used just like any other JavaScript object. This is great for programmatic usage, especially when using tools that don't understand JSON references.
|
|
||||||
*
|
|
||||||
* The dereference method maintains object reference equality, meaning that all `$ref` pointers that point to the same object will be replaced with references to the same object. Again, this is great for programmatic usage, but it does introduce the risk of circular references, so be careful if you intend to serialize the schema using `JSON.stringify()`. Consider using the bundle method instead, which does not create circular references.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#dereferenceschema-options-callback
|
|
||||||
*
|
|
||||||
* @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info.
|
|
||||||
* @param options (optional)
|
|
||||||
* @param callback (optional) A callback that will receive the dereferenced schema object
|
|
||||||
*/
|
|
||||||
public dereference(schema: string | $RefParser.JSONSchema, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public dereference(schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public dereference(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public dereference(schema: string | $RefParser.JSONSchema): Promise<$RefParser.JSONSchema>;
|
|
||||||
public dereference(schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.JSONSchema>;
|
|
||||||
public dereference(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.JSONSchema>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dereferences all `$ref` pointers in the JSON Schema, replacing each reference with its resolved value. This results in a schema object that does not contain any `$ref` pointers. Instead, it's a normal JavaScript object tree that can easily be crawled and used just like any other JavaScript object. This is great for programmatic usage, especially when using tools that don't understand JSON references.
|
|
||||||
*
|
|
||||||
* The dereference method maintains object reference equality, meaning that all `$ref` pointers that point to the same object will be replaced with references to the same object. Again, this is great for programmatic usage, but it does introduce the risk of circular references, so be careful if you intend to serialize the schema using `JSON.stringify()`. Consider using the bundle method instead, which does not create circular references.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#dereferenceschema-options-callback
|
|
||||||
*
|
|
||||||
* @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info.
|
|
||||||
* @param options (optional)
|
|
||||||
* @param callback (optional) A callback that will receive the dereferenced schema object
|
|
||||||
*/
|
|
||||||
public static dereference(schema: string | $RefParser.JSONSchema, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public static dereference(schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public static dereference(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public static dereference(schema: string | $RefParser.JSONSchema): Promise<$RefParser.JSONSchema>;
|
|
||||||
public static dereference(schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.JSONSchema>;
|
|
||||||
public static dereference(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.JSONSchema>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bundles all referenced files/URLs into a single schema that only has internal `$ref` pointers. This lets you split-up your schema however you want while you're building it, but easily combine all those files together when it's time to package or distribute the schema to other people. The resulting schema size will be small, since it will still contain internal JSON references rather than being fully-dereferenced.
|
|
||||||
*
|
|
||||||
* This also eliminates the risk of circular references, so the schema can be safely serialized using `JSON.stringify()`.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#bundleschema-options-callback
|
|
||||||
*
|
|
||||||
* @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info.
|
|
||||||
* @param options (optional)
|
|
||||||
* @param callback (optional) A callback that will receive the bundled schema object
|
|
||||||
*/
|
|
||||||
public bundle(schema: string | $RefParser.JSONSchema, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public bundle(schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public bundle(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public bundle(schema: string | $RefParser.JSONSchema): Promise<$RefParser.JSONSchema>;
|
|
||||||
public bundle(schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.JSONSchema>;
|
|
||||||
public bundle(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.JSONSchema>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bundles all referenced files/URLs into a single schema that only has internal `$ref` pointers. This lets you split-up your schema however you want while you're building it, but easily combine all those files together when it's time to package or distribute the schema to other people. The resulting schema size will be small, since it will still contain internal JSON references rather than being fully-dereferenced.
|
|
||||||
*
|
|
||||||
* This also eliminates the risk of circular references, so the schema can be safely serialized using `JSON.stringify()`.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#bundleschema-options-callback
|
|
||||||
*
|
|
||||||
* @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info.
|
|
||||||
* @param options (optional)
|
|
||||||
* @param callback (optional) A callback that will receive the bundled schema object
|
|
||||||
*/
|
|
||||||
public static bundle(schema: string | $RefParser.JSONSchema, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public static bundle(schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public static bundle(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public static bundle(schema: string | $RefParser.JSONSchema): Promise<$RefParser.JSONSchema>;
|
|
||||||
public static bundle(schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.JSONSchema>;
|
|
||||||
public static bundle(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.JSONSchema>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* *This method is used internally by other methods, such as `bundle` and `dereference`. You probably won't need to call this method yourself.*
|
|
||||||
*
|
|
||||||
* Parses the given JSON Schema file (in JSON or YAML format), and returns it as a JavaScript object. This method `does not` resolve `$ref` pointers or dereference anything. It simply parses one file and returns it.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#parseschema-options-callback
|
|
||||||
*
|
|
||||||
* @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. The path can be absolute or relative. In Node, the path is relative to `process.cwd()`. In the browser, it's relative to the URL of the page.
|
|
||||||
* @param options (optional)
|
|
||||||
* @param callback (optional) A callback that will receive the parsed schema object, or an error
|
|
||||||
*/
|
|
||||||
public parse(schema: string | $RefParser.JSONSchema, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public parse(schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public parse(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public parse(schema: string | $RefParser.JSONSchema): Promise<$RefParser.JSONSchema>;
|
|
||||||
public parse(schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.JSONSchema>;
|
|
||||||
public parse(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.JSONSchema>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* *This method is used internally by other methods, such as `bundle` and `dereference`. You probably won't need to call this method yourself.*
|
|
||||||
*
|
|
||||||
* Parses the given JSON Schema file (in JSON or YAML format), and returns it as a JavaScript object. This method `does not` resolve `$ref` pointers or dereference anything. It simply parses one file and returns it.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#parseschema-options-callback
|
|
||||||
*
|
|
||||||
* @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. The path can be absolute or relative. In Node, the path is relative to `process.cwd()`. In the browser, it's relative to the URL of the page.
|
|
||||||
* @param options (optional)
|
|
||||||
* @param callback (optional) A callback that will receive the parsed schema object, or an error
|
|
||||||
*/
|
|
||||||
public static parse(schema: string | $RefParser.JSONSchema, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public static parse(schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public static parse(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.SchemaCallback): void;
|
|
||||||
public static parse(schema: string | $RefParser.JSONSchema): Promise<$RefParser.JSONSchema>;
|
|
||||||
public static parse(schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.JSONSchema>;
|
|
||||||
public static parse(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.JSONSchema>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* *This method is used internally by other methods, such as `bundle` and `dereference`. You probably won't need to call this method yourself.*
|
|
||||||
*
|
|
||||||
* Resolves all JSON references (`$ref` pointers) in the given JSON Schema file. If it references any other files/URLs, then they will be downloaded and resolved as well. This method **does not** dereference anything. It simply gives you a `$Refs` object, which is a map of all the resolved references and their values.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#resolveschema-options-callback
|
|
||||||
*
|
|
||||||
* @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info.
|
|
||||||
* @param options (optional)
|
|
||||||
* @param callback (optional) A callback that will receive a `$Refs` object
|
|
||||||
*/
|
|
||||||
public resolve(schema: string | $RefParser.JSONSchema, callback: $RefParser.$RefsCallback): void;
|
|
||||||
public resolve(schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.$RefsCallback): void;
|
|
||||||
public resolve(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.$RefsCallback): void;
|
|
||||||
public resolve(schema: string | $RefParser.JSONSchema): Promise<$RefParser.$Refs>;
|
|
||||||
public resolve(schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.$Refs>;
|
|
||||||
public resolve(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.$Refs>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* *This method is used internally by other methods, such as `bundle` and `dereference`. You probably won't need to call this method yourself.*
|
|
||||||
*
|
|
||||||
* Resolves all JSON references (`$ref` pointers) in the given JSON Schema file. If it references any other files/URLs, then they will be downloaded and resolved as well. This method **does not** dereference anything. It simply gives you a `$Refs` object, which is a map of all the resolved references and their values.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#resolveschema-options-callback
|
|
||||||
*
|
|
||||||
* @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info.
|
|
||||||
* @param options (optional)
|
|
||||||
* @param callback (optional) A callback that will receive a `$Refs` object
|
|
||||||
*/
|
|
||||||
public static resolve(schema: string | $RefParser.JSONSchema, callback: $RefParser.$RefsCallback): void;
|
|
||||||
public static resolve(schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.$RefsCallback): void;
|
|
||||||
public static resolve(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options, callback: $RefParser.$RefsCallback): void;
|
|
||||||
public static resolve(schema: string | $RefParser.JSONSchema): Promise<$RefParser.$Refs>;
|
|
||||||
public static resolve(schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.$Refs>;
|
|
||||||
public static resolve(baseUrl: string, schema: string | $RefParser.JSONSchema, options: $RefParser.Options): Promise<$RefParser.$Refs>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-redeclare
|
|
||||||
declare namespace $RefParser {
|
|
||||||
|
|
||||||
export type JSONSchema = JSONSchema4 | JSONSchema6 | JSONSchema7;
|
|
||||||
export type SchemaCallback = (err: Error | null, schema?: JSONSchema) => any;
|
|
||||||
export type $RefsCallback = (err: Error | null, $refs?: $Refs) => any;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/options.html
|
|
||||||
*/
|
|
||||||
export interface Options {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `parse` options determine how different types of files will be parsed.
|
|
||||||
*
|
|
||||||
* JSON Schema `$Ref` Parser comes with built-in JSON, YAML, plain-text, and binary parsers, any of which you can configure or disable. You can also add your own custom parsers if you want.
|
|
||||||
*/
|
|
||||||
parse?: {
|
|
||||||
json?: ParserOptions | boolean;
|
|
||||||
yaml?: ParserOptions | boolean;
|
|
||||||
text?: (ParserOptions & { encoding?: string }) | boolean;
|
|
||||||
[key: string]: ParserOptions | boolean | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `resolve` options control how JSON Schema $Ref Parser will resolve file paths and URLs, and how those files will be read/downloaded.
|
|
||||||
*
|
|
||||||
* JSON Schema `$Ref` Parser comes with built-in support for HTTP and HTTPS, as well as support for local files (when running in Node.js). You can configure or disable either of these built-in resolvers. You can also add your own custom resolvers if you want.
|
|
||||||
*/
|
|
||||||
resolve?: {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether external $ref pointers will be resolved. If this option is disabled, then external `$ref` pointers will simply be ignored.
|
|
||||||
*/
|
|
||||||
external?: boolean;
|
|
||||||
file?: Partial<ResolverOptions> | boolean;
|
|
||||||
http?: HTTPResolverOptions | boolean;
|
|
||||||
} & {
|
|
||||||
[key: string]: Partial<ResolverOptions> | HTTPResolverOptions | boolean | undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default, JSON Schema $Ref Parser throws the first error it encounters. Setting `continueOnError` to `true`
|
|
||||||
* causes it to keep processing as much as possible and then throw a single error that contains all errors
|
|
||||||
* that were encountered.
|
|
||||||
*/
|
|
||||||
continueOnError?: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `dereference` options control how JSON Schema `$Ref` Parser will dereference `$ref` pointers within the JSON schema.
|
|
||||||
*/
|
|
||||||
dereference?: {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether circular `$ref` pointers are handled.
|
|
||||||
*
|
|
||||||
* If set to `false`, then a `ReferenceError` will be thrown if the schema contains any circular references.
|
|
||||||
*
|
|
||||||
* If set to `"ignore"`, then circular references will simply be ignored. No error will be thrown, but the `$Refs.circular` property will still be set to `true`.
|
|
||||||
*/
|
|
||||||
circular?: boolean | "ignore";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A function, called for each path, which can return true to stop this path and all
|
|
||||||
* subpaths from being dereferenced further. This is useful in schemas where some
|
|
||||||
* subpaths contain literal $ref keys that should not be dereferenced.
|
|
||||||
*/
|
|
||||||
excludedPathMatcher?(path: string): boolean;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface HTTPResolverOptions extends Partial<ResolverOptions> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* You can specify any HTTP headers that should be sent when downloading files. For example, some servers may require you to set the `Accept` or `Referrer` header.
|
|
||||||
*/
|
|
||||||
headers?: object;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The amount of time (in milliseconds) to wait for a response from the server when downloading files. The default is 5 seconds.
|
|
||||||
*/
|
|
||||||
timeout?: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of HTTP redirects to follow per file. The default is 5. To disable automatic following of redirects, set this to zero.
|
|
||||||
*/
|
|
||||||
redirects?: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set this to `true` if you're downloading files from a CORS-enabled server that requires authentication
|
|
||||||
*/
|
|
||||||
withCredentials?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JSON Schema `$Ref` Parser comes with built-in resolvers for HTTP and HTTPS URLs, as well as local filesystem paths (when running in Node.js). You can add your own custom resolvers to support additional protocols, or even replace any of the built-in resolvers with your own custom implementation.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/plugins/resolvers.html
|
|
||||||
*/
|
|
||||||
export interface ResolverOptions {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All resolvers have an order property, even the built-in resolvers. If you don't specify an order property, then your resolver will run last. Specifying `order: 1`, like we did in this example, will make your resolver run first. Or you can squeeze your resolver in-between some of the built-in resolvers. For example, `order: 101` would make it run after the file resolver, but before the HTTP resolver. You can see the order of all the built-in resolvers by looking at their source code.
|
|
||||||
*
|
|
||||||
* The order property and canRead property are related to each other. For each file that JSON Schema $Ref Parser needs to resolve, it first determines which resolvers can read that file by checking their canRead property. If only one resolver matches a file, then only that one resolver is called, regardless of its order. If multiple resolvers match a file, then those resolvers are tried in order until one of them successfully reads the file. Once a resolver successfully reads the file, the rest of the resolvers are skipped.
|
|
||||||
*/
|
|
||||||
order?: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `canRead` property tells JSON Schema `$Ref` Parser what kind of files your resolver can read. In this example, we've simply specified a regular expression that matches "mogodb://" URLs, but we could have used a simple boolean, or even a function with custom logic to determine which files to resolve. Here are examples of each approach:
|
|
||||||
*/
|
|
||||||
canRead: boolean | RegExp | string | string[] | ((file: FileInfo) => boolean);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is where the real work of a resolver happens. The `read` method accepts the same file info object as the `canRead` function, but rather than returning a boolean value, the `read` method should return the contents of the file. The file contents should be returned in as raw a form as possible, such as a string or a byte array. Any further parsing or processing should be done by parsers.
|
|
||||||
*
|
|
||||||
* Unlike the `canRead` function, the `read` method can also be asynchronous. This might be important if your resolver needs to read data from a database or some other external source. You can return your asynchronous value using either an ES6 Promise or a Node.js-style error-first callback. Of course, if your resolver has the ability to return its data synchronously, then that's fine too. Here are examples of all three approaches:
|
|
||||||
*/
|
|
||||||
read(
|
|
||||||
file: FileInfo,
|
|
||||||
callback?: (error: Error | null, data: string | null) => any
|
|
||||||
): string | Buffer | JSONSchema | Promise<string | Buffer | JSONSchema>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ParserOptions {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parsers run in a specific order, relative to other parsers. For example, a parser with `order: 5` will run before a parser with `order: 10`. If a parser is unable to successfully parse a file, then the next parser is tried, until one succeeds or they all fail.
|
|
||||||
*
|
|
||||||
* You can change the order in which parsers run, which is useful if you know that most of your referenced files will be a certain type, or if you add your own custom parser that you want to run first.
|
|
||||||
*/
|
|
||||||
order?: number;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All of the built-in parsers allow empty files by default. The JSON and YAML parsers will parse empty files as `undefined`. The text parser will parse empty files as an empty string. The binary parser will parse empty files as an empty byte array.
|
|
||||||
*
|
|
||||||
* You can set `allowEmpty: false` on any parser, which will cause an error to be thrown if a file empty.
|
|
||||||
*/
|
|
||||||
allowEmpty?: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines which parsers will be used for which files.
|
|
||||||
*
|
|
||||||
* A regular expression can be used to match files by their full path. A string (or array of strings) can be used to match files by their file extension. Or a function can be used to perform more complex matching logic. See the custom parser docs for details.
|
|
||||||
*/
|
|
||||||
canParse?: boolean | RegExp | string | string[] | ((file: FileInfo) => boolean);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is where the real work of a parser happens. The `parse` method accepts the same file info object as the `canParse` function, but rather than returning a boolean value, the `parse` method should return a JavaScript representation of the file contents. For our CSV parser, that is a two-dimensional array of lines and values. For your parser, it might be an object, a string, a custom class, or anything else.
|
|
||||||
*
|
|
||||||
* Unlike the `canParse` function, the `parse` method can also be asynchronous. This might be important if your parser needs to retrieve data from a database or if it relies on an external HTTP service to return the parsed value. You can return your asynchronous value via a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or a Node.js-style error-first callback. Here are examples of both approaches:
|
|
||||||
*/
|
|
||||||
parse(
|
|
||||||
file: FileInfo,
|
|
||||||
callback?: (error: Error | null, data: string | null) => any
|
|
||||||
): unknown | Promise<unknown>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JSON Schema `$Ref` Parser supports plug-ins, such as resolvers and parsers. These plug-ins can have methods such as `canRead()`, `read()`, `canParse()`, and `parse()`. All of these methods accept the same object as their parameter: an object containing information about the file being read or parsed.
|
|
||||||
*
|
|
||||||
* The file info object currently only consists of a few properties, but it may grow in the future if plug-ins end up needing more information.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/plugins/file-info-object.html
|
|
||||||
*/
|
|
||||||
export interface FileInfo {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The full URL of the file. This could be any type of URL, including "http://", "https://", "file://", "ftp://", "mongodb://", or even a local filesystem path (when running in Node.js).
|
|
||||||
*/
|
|
||||||
url: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The lowercase file extension, such as ".json", ".yaml", ".txt", etc.
|
|
||||||
*/
|
|
||||||
extension: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The raw file contents, in whatever form they were returned by the resolver that read the file.
|
|
||||||
*/
|
|
||||||
data: string | Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When you call the resolve method, the value that gets passed to the callback function (or Promise) is a $Refs object. This same object is accessible via the parser.$refs property of $RefParser objects.
|
|
||||||
*
|
|
||||||
* This object is a map of JSON References and their resolved values. It also has several convenient helper methods that make it easy for you to navigate and manipulate the JSON References.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/refs.html
|
|
||||||
*/
|
|
||||||
export class $Refs {
|
|
||||||
/**
|
|
||||||
* This property is true if the schema contains any circular references. You may want to check this property before serializing the dereferenced schema as JSON, since JSON.stringify() does not support circular references by default.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/refs.html#circular
|
|
||||||
*/
|
|
||||||
public circular: boolean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the paths/URLs of all the files in your schema (including the main schema file).
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/refs.html#pathstypes
|
|
||||||
*
|
|
||||||
* @param types (optional) Optionally only return certain types of paths ("file", "http", etc.)
|
|
||||||
*/
|
|
||||||
public paths(...types: string[]): string[]
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a map of paths/URLs and their correspond values.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/refs.html#valuestypes
|
|
||||||
*
|
|
||||||
* @param types (optional) Optionally only return values from certain locations ("file", "http", etc.)
|
|
||||||
*/
|
|
||||||
public values(...types: string[]): { [url: string]: $RefParser.JSONSchema }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns `true` if the given path exists in the schema; otherwise, returns `false`
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/refs.html#existsref
|
|
||||||
*
|
|
||||||
* @param $ref The JSON Reference path, optionally with a JSON Pointer in the hash
|
|
||||||
*/
|
|
||||||
public exists($ref: string): boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the value at the given path in the schema. Throws an error if the path does not exist.
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/refs.html#getref
|
|
||||||
*
|
|
||||||
* @param $ref The JSON Reference path, optionally with a JSON Pointer in the hash
|
|
||||||
*/
|
|
||||||
public get($ref: string): JSONSchema4Type | JSONSchema6Type | JSONSchema7Type
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value at the given path in the schema. If the property, or any of its parents, don't exist, they will be created.
|
|
||||||
*
|
|
||||||
* @param $ref The JSON Reference path, optionally with a JSON Pointer in the hash
|
|
||||||
* @param value The value to assign. Can be anything (object, string, number, etc.)
|
|
||||||
*/
|
|
||||||
public set($ref: string, value: JSONSchema4Type | JSONSchema6Type | JSONSchema7Type): void
|
|
||||||
}
|
|
||||||
|
|
||||||
export type JSONParserErrorType = "EUNKNOWN" | "EPARSER" | "EUNMATCHEDPARSER" | "ERESOLVER" | "EUNMATCHEDRESOLVER" | "EMISSINGPOINTER" | "EINVALIDPOINTER";
|
|
||||||
|
|
||||||
export class JSONParserError extends Error {
|
|
||||||
public constructor(message: string, source: string);
|
|
||||||
|
|
||||||
public readonly name: string;
|
|
||||||
public readonly message: string;
|
|
||||||
public readonly source: string;
|
|
||||||
public readonly path: Array<string | number>;
|
|
||||||
public readonly errors: string;
|
|
||||||
public readonly code: JSONParserErrorType;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class JSONParserErrorGroup extends Error {
|
|
||||||
/**
|
|
||||||
* List of all errors
|
|
||||||
*
|
|
||||||
* See https://github.com/APIDevTools/json-schema-ref-parser/blob/master/docs/ref-parser.md#errors
|
|
||||||
*/
|
|
||||||
public readonly errors: Array<$RefParser.JSONParserError | $RefParser.InvalidPointerError | $RefParser.ResolverError | $RefParser.ParserError | $RefParser.MissingPointerError | $RefParser.UnmatchedParserError | $RefParser.UnmatchedResolverError>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The fields property is a `$RefParser` instance
|
|
||||||
*
|
|
||||||
* See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html
|
|
||||||
*/
|
|
||||||
public readonly files: $RefParser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* User friendly message containing the total amount of errors, as well as the absolute path to the source document
|
|
||||||
*/
|
|
||||||
public readonly message: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ParserError extends JSONParserError {
|
|
||||||
public constructor(message: string, source: string);
|
|
||||||
|
|
||||||
public readonly name = "ParserError";
|
|
||||||
public readonly code = "EPARSER";
|
|
||||||
}
|
|
||||||
export class UnmatchedParserError extends JSONParserError {
|
|
||||||
public constructor(source: string);
|
|
||||||
|
|
||||||
public readonly name = "UnmatchedParserError";
|
|
||||||
public readonly code = "EUNMATCHEDPARSER";
|
|
||||||
}
|
|
||||||
export class ResolverError extends JSONParserError {
|
|
||||||
public constructor(ex: Error | NodeJS.ErrnoException, source: string);
|
|
||||||
|
|
||||||
public readonly name = "ResolverError";
|
|
||||||
public readonly code = "ERESOLVER";
|
|
||||||
public readonly ioErrorCode?: string;
|
|
||||||
}
|
|
||||||
export class UnmatchedResolverError extends JSONParserError {
|
|
||||||
public constructor(source: string);
|
|
||||||
|
|
||||||
public readonly name = "UnmatchedResolverError";
|
|
||||||
public readonly code = "EUNMATCHEDRESOLVER";
|
|
||||||
}
|
|
||||||
export class MissingPointerError extends JSONParserError {
|
|
||||||
public constructor(token: string | number, source: string);
|
|
||||||
|
|
||||||
public readonly name = "MissingPointerError";
|
|
||||||
public readonly code = "EMISSINGPOINTER";
|
|
||||||
}
|
|
||||||
export class InvalidPointerError extends JSONParserError {
|
|
||||||
public constructor(pointer: string, source: string);
|
|
||||||
|
|
||||||
public readonly name = "InvalidPointerError";
|
|
||||||
public readonly code = "EINVALIDPOINTER";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-283
@@ -1,283 +0,0 @@
|
|||||||
/* eslint-disable no-unused-vars */
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const $Refs = require("./refs");
|
|
||||||
const _parse = require("./parse");
|
|
||||||
const normalizeArgs = require("./normalize-args");
|
|
||||||
const resolveExternal = require("./resolve-external");
|
|
||||||
const _bundle = require("./bundle");
|
|
||||||
const _dereference = require("./dereference");
|
|
||||||
const url = require("./util/url");
|
|
||||||
const { JSONParserError, InvalidPointerError, MissingPointerError, ResolverError, ParserError, UnmatchedParserError, UnmatchedResolverError, isHandledError, JSONParserErrorGroup } = require("./util/errors");
|
|
||||||
const maybe = require("call-me-maybe");
|
|
||||||
const { ono } = require("@jsdevtools/ono");
|
|
||||||
|
|
||||||
module.exports = $RefParser;
|
|
||||||
module.exports.default = $RefParser;
|
|
||||||
module.exports.JSONParserError = JSONParserError;
|
|
||||||
module.exports.InvalidPointerError = InvalidPointerError;
|
|
||||||
module.exports.MissingPointerError = MissingPointerError;
|
|
||||||
module.exports.ResolverError = ResolverError;
|
|
||||||
module.exports.ParserError = ParserError;
|
|
||||||
module.exports.UnmatchedParserError = UnmatchedParserError;
|
|
||||||
module.exports.UnmatchedResolverError = UnmatchedResolverError;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class parses a JSON schema, builds a map of its JSON references and their resolved values,
|
|
||||||
* and provides methods for traversing, manipulating, and dereferencing those references.
|
|
||||||
*
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function $RefParser () {
|
|
||||||
/**
|
|
||||||
* The parsed (and possibly dereferenced) JSON schema object
|
|
||||||
*
|
|
||||||
* @type {object}
|
|
||||||
* @readonly
|
|
||||||
*/
|
|
||||||
this.schema = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The resolved JSON references
|
|
||||||
*
|
|
||||||
* @type {$Refs}
|
|
||||||
* @readonly
|
|
||||||
*/
|
|
||||||
this.$refs = new $Refs();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given JSON schema.
|
|
||||||
* This method does not resolve any JSON references.
|
|
||||||
* It just reads a single file in JSON or YAML format, and parse it as a JavaScript object.
|
|
||||||
*
|
|
||||||
* @param {string} [path] - The file path or URL of the JSON schema
|
|
||||||
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
|
|
||||||
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed
|
|
||||||
* @param {function} [callback] - An error-first callback. The second parameter is the parsed JSON schema object.
|
|
||||||
* @returns {Promise} - The returned promise resolves with the parsed JSON schema object.
|
|
||||||
*/
|
|
||||||
$RefParser.parse = function parse (path, schema, options, callback) {
|
|
||||||
let Class = this; // eslint-disable-line consistent-this
|
|
||||||
let instance = new Class();
|
|
||||||
return instance.parse.apply(instance, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given JSON schema.
|
|
||||||
* This method does not resolve any JSON references.
|
|
||||||
* It just reads a single file in JSON or YAML format, and parse it as a JavaScript object.
|
|
||||||
*
|
|
||||||
* @param {string} [path] - The file path or URL of the JSON schema
|
|
||||||
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
|
|
||||||
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed
|
|
||||||
* @param {function} [callback] - An error-first callback. The second parameter is the parsed JSON schema object.
|
|
||||||
* @returns {Promise} - The returned promise resolves with the parsed JSON schema object.
|
|
||||||
*/
|
|
||||||
$RefParser.prototype.parse = async function parse (path, schema, options, callback) {
|
|
||||||
let args = normalizeArgs(arguments);
|
|
||||||
let promise;
|
|
||||||
|
|
||||||
if (!args.path && !args.schema) {
|
|
||||||
let err = ono(`Expected a file path, URL, or object. Got ${args.path || args.schema}`);
|
|
||||||
return maybe(args.callback, Promise.reject(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset everything
|
|
||||||
this.schema = null;
|
|
||||||
this.$refs = new $Refs();
|
|
||||||
|
|
||||||
// If the path is a filesystem path, then convert it to a URL.
|
|
||||||
// NOTE: According to the JSON Reference spec, these should already be URLs,
|
|
||||||
// but, in practice, many people use local filesystem paths instead.
|
|
||||||
// So we're being generous here and doing the conversion automatically.
|
|
||||||
// This is not intended to be a 100% bulletproof solution.
|
|
||||||
// If it doesn't work for your use-case, then use a URL instead.
|
|
||||||
let pathType = "http";
|
|
||||||
if (url.isFileSystemPath(args.path)) {
|
|
||||||
args.path = url.fromFileSystemPath(args.path);
|
|
||||||
pathType = "file";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve the absolute path of the schema
|
|
||||||
args.path = url.resolve(url.cwd(), args.path);
|
|
||||||
|
|
||||||
if (args.schema && typeof args.schema === "object") {
|
|
||||||
// A schema object was passed-in.
|
|
||||||
// So immediately add a new $Ref with the schema object as its value
|
|
||||||
let $ref = this.$refs._add(args.path);
|
|
||||||
$ref.value = args.schema;
|
|
||||||
$ref.pathType = pathType;
|
|
||||||
promise = Promise.resolve(args.schema);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Parse the schema file/url
|
|
||||||
promise = _parse(args.path, this.$refs, args.options);
|
|
||||||
}
|
|
||||||
|
|
||||||
let me = this;
|
|
||||||
try {
|
|
||||||
let result = await promise;
|
|
||||||
|
|
||||||
if (result !== null && typeof result === "object" && !Buffer.isBuffer(result)) {
|
|
||||||
me.schema = result;
|
|
||||||
return maybe(args.callback, Promise.resolve(me.schema));
|
|
||||||
}
|
|
||||||
else if (args.options.continueOnError) {
|
|
||||||
me.schema = null; // it's already set to null at line 79, but let's set it again for the sake of readability
|
|
||||||
return maybe(args.callback, Promise.resolve(me.schema));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw ono.syntax(`"${me.$refs._root$Ref.path || result}" is not a valid JSON Schema`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (!args.options.continueOnError || !isHandledError(err)) {
|
|
||||||
return maybe(args.callback, Promise.reject(err));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.$refs._$refs[url.stripHash(args.path)]) {
|
|
||||||
this.$refs._$refs[url.stripHash(args.path)].addError(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
return maybe(args.callback, Promise.resolve(null));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given JSON schema and resolves any JSON references, including references in
|
|
||||||
* externally-referenced files.
|
|
||||||
*
|
|
||||||
* @param {string} [path] - The file path or URL of the JSON schema
|
|
||||||
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
|
|
||||||
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed and resolved
|
|
||||||
* @param {function} [callback]
|
|
||||||
* - An error-first callback. The second parameter is a {@link $Refs} object containing the resolved JSON references
|
|
||||||
*
|
|
||||||
* @returns {Promise}
|
|
||||||
* The returned promise resolves with a {@link $Refs} object containing the resolved JSON references
|
|
||||||
*/
|
|
||||||
$RefParser.resolve = function resolve (path, schema, options, callback) {
|
|
||||||
let Class = this; // eslint-disable-line consistent-this
|
|
||||||
let instance = new Class();
|
|
||||||
return instance.resolve.apply(instance, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given JSON schema and resolves any JSON references, including references in
|
|
||||||
* externally-referenced files.
|
|
||||||
*
|
|
||||||
* @param {string} [path] - The file path or URL of the JSON schema
|
|
||||||
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
|
|
||||||
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed and resolved
|
|
||||||
* @param {function} [callback]
|
|
||||||
* - An error-first callback. The second parameter is a {@link $Refs} object containing the resolved JSON references
|
|
||||||
*
|
|
||||||
* @returns {Promise}
|
|
||||||
* The returned promise resolves with a {@link $Refs} object containing the resolved JSON references
|
|
||||||
*/
|
|
||||||
$RefParser.prototype.resolve = async function resolve (path, schema, options, callback) {
|
|
||||||
let me = this;
|
|
||||||
let args = normalizeArgs(arguments);
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.parse(args.path, args.schema, args.options);
|
|
||||||
await resolveExternal(me, args.options);
|
|
||||||
finalize(me);
|
|
||||||
return maybe(args.callback, Promise.resolve(me.$refs));
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
return maybe(args.callback, Promise.reject(err));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given JSON schema, resolves any JSON references, and bundles all external references
|
|
||||||
* into the main JSON schema. This produces a JSON schema that only has *internal* references,
|
|
||||||
* not any *external* references.
|
|
||||||
*
|
|
||||||
* @param {string} [path] - The file path or URL of the JSON schema
|
|
||||||
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
|
|
||||||
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed, resolved, and dereferenced
|
|
||||||
* @param {function} [callback] - An error-first callback. The second parameter is the bundled JSON schema object
|
|
||||||
* @returns {Promise} - The returned promise resolves with the bundled JSON schema object.
|
|
||||||
*/
|
|
||||||
$RefParser.bundle = function bundle (path, schema, options, callback) {
|
|
||||||
let Class = this; // eslint-disable-line consistent-this
|
|
||||||
let instance = new Class();
|
|
||||||
return instance.bundle.apply(instance, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given JSON schema, resolves any JSON references, and bundles all external references
|
|
||||||
* into the main JSON schema. This produces a JSON schema that only has *internal* references,
|
|
||||||
* not any *external* references.
|
|
||||||
*
|
|
||||||
* @param {string} [path] - The file path or URL of the JSON schema
|
|
||||||
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
|
|
||||||
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed, resolved, and dereferenced
|
|
||||||
* @param {function} [callback] - An error-first callback. The second parameter is the bundled JSON schema object
|
|
||||||
* @returns {Promise} - The returned promise resolves with the bundled JSON schema object.
|
|
||||||
*/
|
|
||||||
$RefParser.prototype.bundle = async function bundle (path, schema, options, callback) {
|
|
||||||
let me = this;
|
|
||||||
let args = normalizeArgs(arguments);
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.resolve(args.path, args.schema, args.options);
|
|
||||||
_bundle(me, args.options);
|
|
||||||
finalize(me);
|
|
||||||
return maybe(args.callback, Promise.resolve(me.schema));
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
return maybe(args.callback, Promise.reject(err));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given JSON schema, resolves any JSON references, and dereferences the JSON schema.
|
|
||||||
* That is, all JSON references are replaced with their resolved values.
|
|
||||||
*
|
|
||||||
* @param {string} [path] - The file path or URL of the JSON schema
|
|
||||||
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
|
|
||||||
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed, resolved, and dereferenced
|
|
||||||
* @param {function} [callback] - An error-first callback. The second parameter is the dereferenced JSON schema object
|
|
||||||
* @returns {Promise} - The returned promise resolves with the dereferenced JSON schema object.
|
|
||||||
*/
|
|
||||||
$RefParser.dereference = function dereference (path, schema, options, callback) {
|
|
||||||
let Class = this; // eslint-disable-line consistent-this
|
|
||||||
let instance = new Class();
|
|
||||||
return instance.dereference.apply(instance, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given JSON schema, resolves any JSON references, and dereferences the JSON schema.
|
|
||||||
* That is, all JSON references are replaced with their resolved values.
|
|
||||||
*
|
|
||||||
* @param {string} [path] - The file path or URL of the JSON schema
|
|
||||||
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
|
|
||||||
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed, resolved, and dereferenced
|
|
||||||
* @param {function} [callback] - An error-first callback. The second parameter is the dereferenced JSON schema object
|
|
||||||
* @returns {Promise} - The returned promise resolves with the dereferenced JSON schema object.
|
|
||||||
*/
|
|
||||||
$RefParser.prototype.dereference = async function dereference (path, schema, options, callback) {
|
|
||||||
let me = this;
|
|
||||||
let args = normalizeArgs(arguments);
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.resolve(args.path, args.schema, args.options);
|
|
||||||
_dereference(me, args.options);
|
|
||||||
finalize(me);
|
|
||||||
return maybe(args.callback, Promise.resolve(me.schema));
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
return maybe(args.callback, Promise.reject(err));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function finalize (parser) {
|
|
||||||
const errors = JSONParserErrorGroup.getParserErrors(parser);
|
|
||||||
if (errors.length > 0) {
|
|
||||||
throw new JSONParserErrorGroup(parser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Generated
Vendored
-53
@@ -1,53 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
const Options = require("./options");
|
|
||||||
|
|
||||||
module.exports = normalizeArgs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normalizes the given arguments, accounting for optional args.
|
|
||||||
*
|
|
||||||
* @param {Arguments} args
|
|
||||||
* @returns {object}
|
|
||||||
*/
|
|
||||||
function normalizeArgs (args) {
|
|
||||||
let path, schema, options, callback;
|
|
||||||
args = Array.prototype.slice.call(args);
|
|
||||||
|
|
||||||
if (typeof args[args.length - 1] === "function") {
|
|
||||||
// The last parameter is a callback function
|
|
||||||
callback = args.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof args[0] === "string") {
|
|
||||||
// The first parameter is the path
|
|
||||||
path = args[0];
|
|
||||||
if (typeof args[2] === "object") {
|
|
||||||
// The second parameter is the schema, and the third parameter is the options
|
|
||||||
schema = args[1];
|
|
||||||
options = args[2];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// The second parameter is the options
|
|
||||||
schema = undefined;
|
|
||||||
options = args[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// The first parameter is the schema
|
|
||||||
path = "";
|
|
||||||
schema = args[0];
|
|
||||||
options = args[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(options instanceof Options)) {
|
|
||||||
options = new Options(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
path,
|
|
||||||
schema,
|
|
||||||
options,
|
|
||||||
callback
|
|
||||||
};
|
|
||||||
}
|
|
||||||
-130
@@ -1,130 +0,0 @@
|
|||||||
/* eslint lines-around-comment: [2, {beforeBlockComment: false}] */
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const jsonParser = require("./parsers/json");
|
|
||||||
const yamlParser = require("./parsers/yaml");
|
|
||||||
const textParser = require("./parsers/text");
|
|
||||||
const binaryParser = require("./parsers/binary");
|
|
||||||
const fileResolver = require("./resolvers/file");
|
|
||||||
const httpResolver = require("./resolvers/http");
|
|
||||||
|
|
||||||
module.exports = $RefParserOptions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Options that determine how JSON schemas are parsed, resolved, and dereferenced.
|
|
||||||
*
|
|
||||||
* @param {object|$RefParserOptions} [options] - Overridden options
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function $RefParserOptions (options) {
|
|
||||||
merge(this, $RefParserOptions.defaults);
|
|
||||||
merge(this, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
$RefParserOptions.defaults = {
|
|
||||||
/**
|
|
||||||
* Determines how different types of files will be parsed.
|
|
||||||
*
|
|
||||||
* You can add additional parsers of your own, replace an existing one with
|
|
||||||
* your own implementation, or disable any parser by setting it to false.
|
|
||||||
*/
|
|
||||||
parse: {
|
|
||||||
json: jsonParser,
|
|
||||||
yaml: yamlParser,
|
|
||||||
text: textParser,
|
|
||||||
binary: binaryParser,
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines how JSON References will be resolved.
|
|
||||||
*
|
|
||||||
* You can add additional resolvers of your own, replace an existing one with
|
|
||||||
* your own implementation, or disable any resolver by setting it to false.
|
|
||||||
*/
|
|
||||||
resolve: {
|
|
||||||
file: fileResolver,
|
|
||||||
http: httpResolver,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether external $ref pointers will be resolved.
|
|
||||||
* If this option is disabled, then none of above resolvers will be called.
|
|
||||||
* Instead, external $ref pointers will simply be ignored.
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
external: true,
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default, JSON Schema $Ref Parser throws the first error it encounters. Setting `continueOnError` to `true`
|
|
||||||
* causes it to keep processing as much as possible and then throw a single error that contains all errors
|
|
||||||
* that were encountered.
|
|
||||||
*/
|
|
||||||
continueOnError: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines the types of JSON references that are allowed.
|
|
||||||
*/
|
|
||||||
dereference: {
|
|
||||||
/**
|
|
||||||
* Dereference circular (recursive) JSON references?
|
|
||||||
* If false, then a {@link ReferenceError} will be thrown if a circular reference is found.
|
|
||||||
* If "ignore", then circular references will not be dereferenced.
|
|
||||||
*
|
|
||||||
* @type {boolean|string}
|
|
||||||
*/
|
|
||||||
circular: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A function, called for each path, which can return true to stop this path and all
|
|
||||||
* subpaths from being dereferenced further. This is useful in schemas where some
|
|
||||||
* subpaths contain literal $ref keys that should not be dereferenced.
|
|
||||||
*
|
|
||||||
* @type {function}
|
|
||||||
*/
|
|
||||||
excludedPathMatcher: () => false
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Merges the properties of the source object into the target object.
|
|
||||||
*
|
|
||||||
* @param {object} target - The object that we're populating
|
|
||||||
* @param {?object} source - The options that are being merged
|
|
||||||
* @returns {object}
|
|
||||||
*/
|
|
||||||
function merge (target, source) {
|
|
||||||
if (isMergeable(source)) {
|
|
||||||
let keys = Object.keys(source);
|
|
||||||
for (let i = 0; i < keys.length; i++) {
|
|
||||||
let key = keys[i];
|
|
||||||
let sourceSetting = source[key];
|
|
||||||
let targetSetting = target[key];
|
|
||||||
|
|
||||||
if (isMergeable(sourceSetting)) {
|
|
||||||
// It's a nested object, so merge it recursively
|
|
||||||
target[key] = merge(targetSetting || {}, sourceSetting);
|
|
||||||
}
|
|
||||||
else if (sourceSetting !== undefined) {
|
|
||||||
// It's a scalar value, function, or array. No merging necessary. Just overwrite the target value.
|
|
||||||
target[key] = sourceSetting;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the given value can be merged,
|
|
||||||
* or if it is a scalar value that should just override the target value.
|
|
||||||
*
|
|
||||||
* @param {*} val
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
function isMergeable (val) {
|
|
||||||
return val &&
|
|
||||||
(typeof val === "object") &&
|
|
||||||
!Array.isArray(val) &&
|
|
||||||
!(val instanceof RegExp) &&
|
|
||||||
!(val instanceof Date);
|
|
||||||
}
|
|
||||||
-164
@@ -1,164 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
const { ono } = require("@jsdevtools/ono");
|
|
||||||
const url = require("./util/url");
|
|
||||||
const plugins = require("./util/plugins");
|
|
||||||
const { ResolverError, ParserError, UnmatchedParserError, UnmatchedResolverError, isHandledError } = require("./util/errors");
|
|
||||||
|
|
||||||
module.exports = parse;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads and parses the specified file path or URL.
|
|
||||||
*
|
|
||||||
* @param {string} path - This path MUST already be resolved, since `read` doesn't know the resolution context
|
|
||||||
* @param {$Refs} $refs
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
*
|
|
||||||
* @returns {Promise}
|
|
||||||
* The promise resolves with the parsed file contents, NOT the raw (Buffer) contents.
|
|
||||||
*/
|
|
||||||
async function parse (path, $refs, options) {
|
|
||||||
// Remove the URL fragment, if any
|
|
||||||
path = url.stripHash(path);
|
|
||||||
|
|
||||||
// Add a new $Ref for this file, even though we don't have the value yet.
|
|
||||||
// This ensures that we don't simultaneously read & parse the same file multiple times
|
|
||||||
let $ref = $refs._add(path);
|
|
||||||
|
|
||||||
// This "file object" will be passed to all resolvers and parsers.
|
|
||||||
let file = {
|
|
||||||
url: path,
|
|
||||||
extension: url.getExtension(path),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Read the file and then parse the data
|
|
||||||
try {
|
|
||||||
const resolver = await readFile(file, options, $refs);
|
|
||||||
$ref.pathType = resolver.plugin.name;
|
|
||||||
file.data = resolver.result;
|
|
||||||
|
|
||||||
const parser = await parseFile(file, options, $refs);
|
|
||||||
$ref.value = parser.result;
|
|
||||||
|
|
||||||
return parser.result;
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (isHandledError(err)) {
|
|
||||||
$ref.value = err;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the given file, using the configured resolver plugins
|
|
||||||
*
|
|
||||||
* @param {object} file - An object containing information about the referenced file
|
|
||||||
* @param {string} file.url - The full URL of the referenced file
|
|
||||||
* @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
*
|
|
||||||
* @returns {Promise}
|
|
||||||
* The promise resolves with the raw file contents and the resolver that was used.
|
|
||||||
*/
|
|
||||||
function readFile (file, options, $refs) {
|
|
||||||
return new Promise(((resolve, reject) => {
|
|
||||||
// console.log('Reading %s', file.url);
|
|
||||||
|
|
||||||
// Find the resolvers that can read this file
|
|
||||||
let resolvers = plugins.all(options.resolve);
|
|
||||||
resolvers = plugins.filter(resolvers, "canRead", file);
|
|
||||||
|
|
||||||
// Run the resolvers, in order, until one of them succeeds
|
|
||||||
plugins.sort(resolvers);
|
|
||||||
plugins.run(resolvers, "read", file, $refs)
|
|
||||||
.then(resolve, onError);
|
|
||||||
|
|
||||||
function onError (err) {
|
|
||||||
if (!err && options.continueOnError) {
|
|
||||||
// No resolver could be matched
|
|
||||||
reject(new UnmatchedResolverError(file.url));
|
|
||||||
}
|
|
||||||
else if (!err || !("error" in err)) {
|
|
||||||
// Throw a generic, friendly error.
|
|
||||||
reject(ono.syntax(`Unable to resolve $ref pointer "${file.url}"`));
|
|
||||||
}
|
|
||||||
// Throw the original error, if it's one of our own (user-friendly) errors.
|
|
||||||
else if (err.error instanceof ResolverError) {
|
|
||||||
reject(err.error);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
reject(new ResolverError(err, file.url));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given file's contents, using the configured parser plugins.
|
|
||||||
*
|
|
||||||
* @param {object} file - An object containing information about the referenced file
|
|
||||||
* @param {string} file.url - The full URL of the referenced file
|
|
||||||
* @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
|
|
||||||
* @param {*} file.data - The file contents. This will be whatever data type was returned by the resolver
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
*
|
|
||||||
* @returns {Promise}
|
|
||||||
* The promise resolves with the parsed file contents and the parser that was used.
|
|
||||||
*/
|
|
||||||
function parseFile (file, options, $refs) {
|
|
||||||
return new Promise(((resolve, reject) => {
|
|
||||||
// console.log('Parsing %s', file.url);
|
|
||||||
|
|
||||||
// Find the parsers that can read this file type.
|
|
||||||
// If none of the parsers are an exact match for this file, then we'll try ALL of them.
|
|
||||||
// This handles situations where the file IS a supported type, just with an unknown extension.
|
|
||||||
let allParsers = plugins.all(options.parse);
|
|
||||||
let filteredParsers = plugins.filter(allParsers, "canParse", file);
|
|
||||||
let parsers = filteredParsers.length > 0 ? filteredParsers : allParsers;
|
|
||||||
|
|
||||||
// Run the parsers, in order, until one of them succeeds
|
|
||||||
plugins.sort(parsers);
|
|
||||||
plugins.run(parsers, "parse", file, $refs)
|
|
||||||
.then(onParsed, onError);
|
|
||||||
|
|
||||||
function onParsed (parser) {
|
|
||||||
if (!parser.plugin.allowEmpty && isEmpty(parser.result)) {
|
|
||||||
reject(ono.syntax(`Error parsing "${file.url}" as ${parser.plugin.name}. \nParsed value is empty`));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
resolve(parser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onError (err) {
|
|
||||||
if (!err && options.continueOnError) {
|
|
||||||
// No resolver could be matched
|
|
||||||
reject(new UnmatchedParserError(file.url));
|
|
||||||
}
|
|
||||||
else if (!err || !("error" in err)) {
|
|
||||||
reject(ono.syntax(`Unable to parse ${file.url}`));
|
|
||||||
}
|
|
||||||
else if (err.error instanceof ParserError) {
|
|
||||||
reject(err.error);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
reject(new ParserError(err.error.message, file.url));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the parsed value is "empty".
|
|
||||||
*
|
|
||||||
* @param {*} value
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
function isEmpty (value) {
|
|
||||||
return value === undefined ||
|
|
||||||
(typeof value === "object" && Object.keys(value).length === 0) ||
|
|
||||||
(typeof value === "string" && value.trim().length === 0) ||
|
|
||||||
(Buffer.isBuffer(value) && value.length === 0);
|
|
||||||
}
|
|
||||||
Generated
Vendored
-55
@@ -1,55 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let BINARY_REGEXP = /\.(jpeg|jpg|gif|png|bmp|ico)$/i;
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
/**
|
|
||||||
* The order that this parser will run, in relation to other parsers.
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
order: 400,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to allow "empty" files (zero bytes).
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
allowEmpty: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether this parser can parse a given file reference.
|
|
||||||
* Parsers that return true will be tried, in order, until one successfully parses the file.
|
|
||||||
* Parsers that return false will be skipped, UNLESS all parsers returned false, in which case
|
|
||||||
* every parser will be tried.
|
|
||||||
*
|
|
||||||
* @param {object} file - An object containing information about the referenced file
|
|
||||||
* @param {string} file.url - The full URL of the referenced file
|
|
||||||
* @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
|
|
||||||
* @param {*} file.data - The file contents. This will be whatever data type was returned by the resolver
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
canParse (file) {
|
|
||||||
// Use this parser if the file is a Buffer, and has a known binary extension
|
|
||||||
return Buffer.isBuffer(file.data) && BINARY_REGEXP.test(file.url);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given data as a Buffer (byte array).
|
|
||||||
*
|
|
||||||
* @param {object} file - An object containing information about the referenced file
|
|
||||||
* @param {string} file.url - The full URL of the referenced file
|
|
||||||
* @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
|
|
||||||
* @param {*} file.data - The file contents. This will be whatever data type was returned by the resolver
|
|
||||||
* @returns {Buffer}
|
|
||||||
*/
|
|
||||||
parse (file) {
|
|
||||||
if (Buffer.isBuffer(file.data)) {
|
|
||||||
return file.data;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// This will reject if data is anything other than a string or typed array
|
|
||||||
return Buffer.from(file.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Generated
Vendored
-63
@@ -1,63 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
const { ParserError } = require("../util/errors");
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
/**
|
|
||||||
* The order that this parser will run, in relation to other parsers.
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
order: 100,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to allow "empty" files. This includes zero-byte files, as well as empty JSON objects.
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
allowEmpty: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether this parser can parse a given file reference.
|
|
||||||
* Parsers that match will be tried, in order, until one successfully parses the file.
|
|
||||||
* Parsers that don't match will be skipped, UNLESS none of the parsers match, in which case
|
|
||||||
* every parser will be tried.
|
|
||||||
*
|
|
||||||
* @type {RegExp|string|string[]|function}
|
|
||||||
*/
|
|
||||||
canParse: ".json",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given file as JSON
|
|
||||||
*
|
|
||||||
* @param {object} file - An object containing information about the referenced file
|
|
||||||
* @param {string} file.url - The full URL of the referenced file
|
|
||||||
* @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
|
|
||||||
* @param {*} file.data - The file contents. This will be whatever data type was returned by the resolver
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
async parse (file) { // eslint-disable-line require-await
|
|
||||||
let data = file.data;
|
|
||||||
if (Buffer.isBuffer(data)) {
|
|
||||||
data = data.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof data === "string") {
|
|
||||||
if (data.trim().length === 0) {
|
|
||||||
return; // This mirrors the YAML behavior
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
try {
|
|
||||||
return JSON.parse(data);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
throw new ParserError(e.message, file.url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// data is already a JavaScript value (object, array, number, null, NaN, etc.)
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Generated
Vendored
-66
@@ -1,66 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
const { ParserError } = require("../util/errors");
|
|
||||||
|
|
||||||
let TEXT_REGEXP = /\.(txt|htm|html|md|xml|js|min|map|css|scss|less|svg)$/i;
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
/**
|
|
||||||
* The order that this parser will run, in relation to other parsers.
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
order: 300,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to allow "empty" files (zero bytes).
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
allowEmpty: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The encoding that the text is expected to be in.
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
encoding: "utf8",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether this parser can parse a given file reference.
|
|
||||||
* Parsers that return true will be tried, in order, until one successfully parses the file.
|
|
||||||
* Parsers that return false will be skipped, UNLESS all parsers returned false, in which case
|
|
||||||
* every parser will be tried.
|
|
||||||
*
|
|
||||||
* @param {object} file - An object containing information about the referenced file
|
|
||||||
* @param {string} file.url - The full URL of the referenced file
|
|
||||||
* @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
|
|
||||||
* @param {*} file.data - The file contents. This will be whatever data type was returned by the resolver
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
canParse (file) {
|
|
||||||
// Use this parser if the file is a string or Buffer, and has a known text-based extension
|
|
||||||
return (typeof file.data === "string" || Buffer.isBuffer(file.data)) && TEXT_REGEXP.test(file.url);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given file as text
|
|
||||||
*
|
|
||||||
* @param {object} file - An object containing information about the referenced file
|
|
||||||
* @param {string} file.url - The full URL of the referenced file
|
|
||||||
* @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
|
|
||||||
* @param {*} file.data - The file contents. This will be whatever data type was returned by the resolver
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
parse (file) {
|
|
||||||
if (typeof file.data === "string") {
|
|
||||||
return file.data;
|
|
||||||
}
|
|
||||||
else if (Buffer.isBuffer(file.data)) {
|
|
||||||
return file.data.toString(this.encoding);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new ParserError("data is not text", file.url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Generated
Vendored
-60
@@ -1,60 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
const { ParserError } = require("../util/errors");
|
|
||||||
const yaml = require("js-yaml");
|
|
||||||
const { JSON_SCHEMA } = require("js-yaml");
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
/**
|
|
||||||
* The order that this parser will run, in relation to other parsers.
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
order: 200,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether to allow "empty" files. This includes zero-byte files, as well as empty JSON objects.
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
allowEmpty: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether this parser can parse a given file reference.
|
|
||||||
* Parsers that match will be tried, in order, until one successfully parses the file.
|
|
||||||
* Parsers that don't match will be skipped, UNLESS none of the parsers match, in which case
|
|
||||||
* every parser will be tried.
|
|
||||||
*
|
|
||||||
* @type {RegExp|string[]|function}
|
|
||||||
*/
|
|
||||||
canParse: [".yaml", ".yml", ".json"], // JSON is valid YAML
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the given file as YAML
|
|
||||||
*
|
|
||||||
* @param {object} file - An object containing information about the referenced file
|
|
||||||
* @param {string} file.url - The full URL of the referenced file
|
|
||||||
* @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
|
|
||||||
* @param {*} file.data - The file contents. This will be whatever data type was returned by the resolver
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
async parse (file) { // eslint-disable-line require-await
|
|
||||||
let data = file.data;
|
|
||||||
if (Buffer.isBuffer(data)) {
|
|
||||||
data = data.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof data === "string") {
|
|
||||||
try {
|
|
||||||
return yaml.load(data, { schema: JSON_SCHEMA });
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
throw new ParserError(e.message, file.url);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// data is already a JavaScript value (object, array, number, null, NaN, etc.)
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
-295
@@ -1,295 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
module.exports = Pointer;
|
|
||||||
|
|
||||||
const $Ref = require("./ref");
|
|
||||||
const url = require("./util/url");
|
|
||||||
const { JSONParserError, InvalidPointerError, MissingPointerError, isHandledError } = require("./util/errors");
|
|
||||||
const slashes = /\//g;
|
|
||||||
const tildes = /~/g;
|
|
||||||
const escapedSlash = /~1/g;
|
|
||||||
const escapedTilde = /~0/g;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class represents a single JSON pointer and its resolved value.
|
|
||||||
*
|
|
||||||
* @param {$Ref} $ref
|
|
||||||
* @param {string} path
|
|
||||||
* @param {string} [friendlyPath] - The original user-specified path (used for error messages)
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function Pointer ($ref, path, friendlyPath) {
|
|
||||||
/**
|
|
||||||
* The {@link $Ref} object that contains this {@link Pointer} object.
|
|
||||||
* @type {$Ref}
|
|
||||||
*/
|
|
||||||
this.$ref = $ref;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The file path or URL, containing the JSON pointer in the hash.
|
|
||||||
* This path is relative to the path of the main JSON schema file.
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
this.path = path;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The original path or URL, used for error messages.
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
this.originalPath = friendlyPath || path;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The value of the JSON pointer.
|
|
||||||
* Can be any JSON type, not just objects. Unknown file types are represented as Buffers (byte arrays).
|
|
||||||
* @type {?*}
|
|
||||||
*/
|
|
||||||
this.value = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether the pointer references itself.
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
this.circular = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of indirect references that were traversed to resolve the value.
|
|
||||||
* Resolving a single pointer may require resolving multiple $Refs.
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.indirections = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the value of a nested property within the given object.
|
|
||||||
*
|
|
||||||
* @param {*} obj - The object that will be crawled
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
* @param {string} pathFromRoot - the path of place that initiated resolving
|
|
||||||
*
|
|
||||||
* @returns {Pointer}
|
|
||||||
* Returns a JSON pointer whose {@link Pointer#value} is the resolved value.
|
|
||||||
* If resolving this value required resolving other JSON references, then
|
|
||||||
* the {@link Pointer#$ref} and {@link Pointer#path} will reflect the resolution path
|
|
||||||
* of the resolved value.
|
|
||||||
*/
|
|
||||||
Pointer.prototype.resolve = function (obj, options, pathFromRoot) {
|
|
||||||
let tokens = Pointer.parse(this.path, this.originalPath);
|
|
||||||
|
|
||||||
// Crawl the object, one token at a time
|
|
||||||
this.value = unwrapOrThrow(obj);
|
|
||||||
|
|
||||||
for (let i = 0; i < tokens.length; i++) {
|
|
||||||
if (resolveIf$Ref(this, options)) {
|
|
||||||
// The $ref path has changed, so append the remaining tokens to the path
|
|
||||||
this.path = Pointer.join(this.path, tokens.slice(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof this.value === "object" && this.value !== null && "$ref" in this.value) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
let token = tokens[i];
|
|
||||||
if (this.value[token] === undefined || this.value[token] === null) {
|
|
||||||
this.value = null;
|
|
||||||
throw new MissingPointerError(token, decodeURI(this.originalPath));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.value = this.value[token];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve the final value
|
|
||||||
if (!this.value || this.value.$ref && url.resolve(this.path, this.value.$ref) !== pathFromRoot) {
|
|
||||||
resolveIf$Ref(this, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value of a nested property within the given object.
|
|
||||||
*
|
|
||||||
* @param {*} obj - The object that will be crawled
|
|
||||||
* @param {*} value - the value to assign
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
*
|
|
||||||
* @returns {*}
|
|
||||||
* Returns the modified object, or an entirely new object if the entire object is overwritten.
|
|
||||||
*/
|
|
||||||
Pointer.prototype.set = function (obj, value, options) {
|
|
||||||
let tokens = Pointer.parse(this.path);
|
|
||||||
let token;
|
|
||||||
|
|
||||||
if (tokens.length === 0) {
|
|
||||||
// There are no tokens, replace the entire object with the new value
|
|
||||||
this.value = value;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Crawl the object, one token at a time
|
|
||||||
this.value = unwrapOrThrow(obj);
|
|
||||||
|
|
||||||
for (let i = 0; i < tokens.length - 1; i++) {
|
|
||||||
resolveIf$Ref(this, options);
|
|
||||||
|
|
||||||
token = tokens[i];
|
|
||||||
if (this.value && this.value[token] !== undefined) {
|
|
||||||
// The token exists
|
|
||||||
this.value = this.value[token];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// The token doesn't exist, so create it
|
|
||||||
this.value = setValue(this, token, {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the value of the final token
|
|
||||||
resolveIf$Ref(this, options);
|
|
||||||
token = tokens[tokens.length - 1];
|
|
||||||
setValue(this, token, value);
|
|
||||||
|
|
||||||
// Return the updated object
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses a JSON pointer (or a path containing a JSON pointer in the hash)
|
|
||||||
* and returns an array of the pointer's tokens.
|
|
||||||
* (e.g. "schema.json#/definitions/person/name" => ["definitions", "person", "name"])
|
|
||||||
*
|
|
||||||
* The pointer is parsed according to RFC 6901
|
|
||||||
* {@link https://tools.ietf.org/html/rfc6901#section-3}
|
|
||||||
*
|
|
||||||
* @param {string} path
|
|
||||||
* @param {string} [originalPath]
|
|
||||||
* @returns {string[]}
|
|
||||||
*/
|
|
||||||
Pointer.parse = function (path, originalPath) {
|
|
||||||
// Get the JSON pointer from the path's hash
|
|
||||||
let pointer = url.getHash(path).substr(1);
|
|
||||||
|
|
||||||
// If there's no pointer, then there are no tokens,
|
|
||||||
// so return an empty array
|
|
||||||
if (!pointer) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Split into an array
|
|
||||||
pointer = pointer.split("/");
|
|
||||||
|
|
||||||
// Decode each part, according to RFC 6901
|
|
||||||
for (let i = 0; i < pointer.length; i++) {
|
|
||||||
pointer[i] = decodeURIComponent(pointer[i].replace(escapedSlash, "/").replace(escapedTilde, "~"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pointer[0] !== "") {
|
|
||||||
throw new InvalidPointerError(pointer, originalPath === undefined ? path : originalPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return pointer.slice(1);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a JSON pointer path, by joining one or more tokens to a base path.
|
|
||||||
*
|
|
||||||
* @param {string} base - The base path (e.g. "schema.json#/definitions/person")
|
|
||||||
* @param {string|string[]} tokens - The token(s) to append (e.g. ["name", "first"])
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
Pointer.join = function (base, tokens) {
|
|
||||||
// Ensure that the base path contains a hash
|
|
||||||
if (base.indexOf("#") === -1) {
|
|
||||||
base += "#";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Append each token to the base path
|
|
||||||
tokens = Array.isArray(tokens) ? tokens : [tokens];
|
|
||||||
for (let i = 0; i < tokens.length; i++) {
|
|
||||||
let token = tokens[i];
|
|
||||||
// Encode the token, according to RFC 6901
|
|
||||||
base += "/" + encodeURIComponent(token.replace(tildes, "~0").replace(slashes, "~1"));
|
|
||||||
}
|
|
||||||
|
|
||||||
return base;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If the given pointer's {@link Pointer#value} is a JSON reference,
|
|
||||||
* then the reference is resolved and {@link Pointer#value} is replaced with the resolved value.
|
|
||||||
* In addition, {@link Pointer#path} and {@link Pointer#$ref} are updated to reflect the
|
|
||||||
* resolution path of the new value.
|
|
||||||
*
|
|
||||||
* @param {Pointer} pointer
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
* @returns {boolean} - Returns `true` if the resolution path changed
|
|
||||||
*/
|
|
||||||
function resolveIf$Ref (pointer, options) {
|
|
||||||
// Is the value a JSON reference? (and allowed?)
|
|
||||||
|
|
||||||
if ($Ref.isAllowed$Ref(pointer.value, options)) {
|
|
||||||
let $refPath = url.resolve(pointer.path, pointer.value.$ref);
|
|
||||||
|
|
||||||
if ($refPath === pointer.path) {
|
|
||||||
// The value is a reference to itself, so there's nothing to do.
|
|
||||||
pointer.circular = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let resolved = pointer.$ref.$refs._resolve($refPath, pointer.path, options);
|
|
||||||
if (resolved === null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pointer.indirections += resolved.indirections + 1;
|
|
||||||
|
|
||||||
if ($Ref.isExtended$Ref(pointer.value)) {
|
|
||||||
// This JSON reference "extends" the resolved value, rather than simply pointing to it.
|
|
||||||
// So the resolved path does NOT change. Just the value does.
|
|
||||||
pointer.value = $Ref.dereference(pointer.value, resolved.value);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Resolve the reference
|
|
||||||
pointer.$ref = resolved.$ref;
|
|
||||||
pointer.path = resolved.path;
|
|
||||||
pointer.value = resolved.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the specified token value of the {@link Pointer#value}.
|
|
||||||
*
|
|
||||||
* The token is evaluated according to RFC 6901.
|
|
||||||
* {@link https://tools.ietf.org/html/rfc6901#section-4}
|
|
||||||
*
|
|
||||||
* @param {Pointer} pointer - The JSON Pointer whose value will be modified
|
|
||||||
* @param {string} token - A JSON Pointer token that indicates how to modify `obj`
|
|
||||||
* @param {*} value - The value to assign
|
|
||||||
* @returns {*} - Returns the assigned value
|
|
||||||
*/
|
|
||||||
function setValue (pointer, token, value) {
|
|
||||||
if (pointer.value && typeof pointer.value === "object") {
|
|
||||||
if (token === "-" && Array.isArray(pointer.value)) {
|
|
||||||
pointer.value.push(value);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pointer.value[token] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new JSONParserError(`Error assigning $ref pointer "${pointer.path}". \nCannot set "${token}" of a non-object.`);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function unwrapOrThrow (value) {
|
|
||||||
if (isHandledError(value)) {
|
|
||||||
throw value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
-294
@@ -1,294 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
module.exports = $Ref;
|
|
||||||
|
|
||||||
const Pointer = require("./pointer");
|
|
||||||
const { InvalidPointerError, isHandledError, normalizeError } = require("./util/errors");
|
|
||||||
const { safePointerToPath, stripHash, getHash } = require("./util/url");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class represents a single JSON reference and its resolved value.
|
|
||||||
*
|
|
||||||
* @class
|
|
||||||
*/
|
|
||||||
function $Ref () {
|
|
||||||
/**
|
|
||||||
* The file path or URL of the referenced file.
|
|
||||||
* This path is relative to the path of the main JSON schema file.
|
|
||||||
*
|
|
||||||
* This path does NOT contain document fragments (JSON pointers). It always references an ENTIRE file.
|
|
||||||
* Use methods such as {@link $Ref#get}, {@link $Ref#resolve}, and {@link $Ref#exists} to get
|
|
||||||
* specific JSON pointers within the file.
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
*/
|
|
||||||
this.path = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The resolved value of the JSON reference.
|
|
||||||
* Can be any JSON type, not just objects. Unknown file types are represented as Buffers (byte arrays).
|
|
||||||
*
|
|
||||||
* @type {?*}
|
|
||||||
*/
|
|
||||||
this.value = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link $Refs} object that contains this {@link $Ref} object.
|
|
||||||
*
|
|
||||||
* @type {$Refs}
|
|
||||||
*/
|
|
||||||
this.$refs = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates the type of {@link $Ref#path} (e.g. "file", "http", etc.)
|
|
||||||
*
|
|
||||||
* @type {?string}
|
|
||||||
*/
|
|
||||||
this.pathType = undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* List of all errors. Undefined if no errors.
|
|
||||||
*
|
|
||||||
* @type {Array<JSONParserError | ResolverError | ParserError | MissingPointerError>}
|
|
||||||
*/
|
|
||||||
this.errors = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pushes an error to errors array.
|
|
||||||
*
|
|
||||||
* @param {Array<JSONParserError | JSONParserErrorGroup>} err - The error to be pushed
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
$Ref.prototype.addError = function (err) {
|
|
||||||
if (this.errors === undefined) {
|
|
||||||
this.errors = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const existingErrors = this.errors.map(({ footprint }) => footprint);
|
|
||||||
|
|
||||||
// the path has been almost certainly set at this point,
|
|
||||||
// but just in case something went wrong, normalizeError injects path if necessary
|
|
||||||
// moreover, certain errors might point at the same spot, so filter them out to reduce noise
|
|
||||||
if (Array.isArray(err.errors)) {
|
|
||||||
this.errors.push(...err.errors
|
|
||||||
.map(normalizeError)
|
|
||||||
.filter(({ footprint }) => !existingErrors.includes(footprint)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (!existingErrors.includes(err.footprint)) {
|
|
||||||
this.errors.push(normalizeError(err));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the given JSON reference exists within this {@link $Ref#value}.
|
|
||||||
*
|
|
||||||
* @param {string} path - The full path being resolved, optionally with a JSON pointer in the hash
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
$Ref.prototype.exists = function (path, options) {
|
|
||||||
try {
|
|
||||||
this.resolve(path, options);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the given JSON reference within this {@link $Ref#value} and returns the resolved value.
|
|
||||||
*
|
|
||||||
* @param {string} path - The full path being resolved, optionally with a JSON pointer in the hash
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
* @returns {*} - Returns the resolved value
|
|
||||||
*/
|
|
||||||
$Ref.prototype.get = function (path, options) {
|
|
||||||
return this.resolve(path, options).value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the given JSON reference within this {@link $Ref#value}.
|
|
||||||
*
|
|
||||||
* @param {string} path - The full path being resolved, optionally with a JSON pointer in the hash
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
* @param {string} friendlyPath - The original user-specified path (used for error messages)
|
|
||||||
* @param {string} pathFromRoot - The path of `obj` from the schema root
|
|
||||||
* @returns {Pointer | null}
|
|
||||||
*/
|
|
||||||
$Ref.prototype.resolve = function (path, options, friendlyPath, pathFromRoot) {
|
|
||||||
let pointer = new Pointer(this, path, friendlyPath);
|
|
||||||
try {
|
|
||||||
return pointer.resolve(this.value, options, pathFromRoot);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (!options || !options.continueOnError || !isHandledError(err)) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err.path === null) {
|
|
||||||
err.path = safePointerToPath(getHash(pathFromRoot));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err instanceof InvalidPointerError) {
|
|
||||||
// this is a special case - InvalidPointerError is thrown when dereferencing external file,
|
|
||||||
// but the issue is caused by the source file that referenced the file that undergoes dereferencing
|
|
||||||
err.source = decodeURI(stripHash(pathFromRoot));
|
|
||||||
}
|
|
||||||
|
|
||||||
this.addError(err);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value of a nested property within this {@link $Ref#value}.
|
|
||||||
* If the property, or any of its parents don't exist, they will be created.
|
|
||||||
*
|
|
||||||
* @param {string} path - The full path of the property to set, optionally with a JSON pointer in the hash
|
|
||||||
* @param {*} value - The value to assign
|
|
||||||
*/
|
|
||||||
$Ref.prototype.set = function (path, value) {
|
|
||||||
let pointer = new Pointer(this, path);
|
|
||||||
this.value = pointer.set(this.value, value);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the given value is a JSON reference.
|
|
||||||
*
|
|
||||||
* @param {*} value - The value to inspect
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
$Ref.is$Ref = function (value) {
|
|
||||||
return value && typeof value === "object" && typeof value.$ref === "string" && value.$ref.length > 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the given value is an external JSON reference.
|
|
||||||
*
|
|
||||||
* @param {*} value - The value to inspect
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
$Ref.isExternal$Ref = function (value) {
|
|
||||||
return $Ref.is$Ref(value) && value.$ref[0] !== "#";
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the given value is a JSON reference, and whether it is allowed by the options.
|
|
||||||
* For example, if it references an external file, then options.resolve.external must be true.
|
|
||||||
*
|
|
||||||
* @param {*} value - The value to inspect
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
$Ref.isAllowed$Ref = function (value, options) {
|
|
||||||
if ($Ref.is$Ref(value)) {
|
|
||||||
if (value.$ref.substr(0, 2) === "#/" || value.$ref === "#") {
|
|
||||||
// It's a JSON Pointer reference, which is always allowed
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (value.$ref[0] !== "#" && (!options || options.resolve.external)) {
|
|
||||||
// It's an external reference, which is allowed by the options
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the given value is a JSON reference that "extends" its resolved value.
|
|
||||||
* That is, it has extra properties (in addition to "$ref"), so rather than simply pointing to
|
|
||||||
* an existing value, this $ref actually creates a NEW value that is a shallow copy of the resolved
|
|
||||||
* value, plus the extra properties.
|
|
||||||
*
|
|
||||||
* @example:
|
|
||||||
* {
|
|
||||||
* person: {
|
|
||||||
* properties: {
|
|
||||||
* firstName: { type: string }
|
|
||||||
* lastName: { type: string }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* employee: {
|
|
||||||
* properties: {
|
|
||||||
* $ref: #/person/properties
|
|
||||||
* salary: { type: number }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* In this example, "employee" is an extended $ref, since it extends "person" with an additional
|
|
||||||
* property (salary). The result is a NEW value that looks like this:
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* properties: {
|
|
||||||
* firstName: { type: string }
|
|
||||||
* lastName: { type: string }
|
|
||||||
* salary: { type: number }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* @param {*} value - The value to inspect
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
$Ref.isExtended$Ref = function (value) {
|
|
||||||
return $Ref.is$Ref(value) && Object.keys(value).length > 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the resolved value of a JSON Reference.
|
|
||||||
* If necessary, the resolved value is merged with the JSON Reference to create a new object
|
|
||||||
*
|
|
||||||
* @example:
|
|
||||||
* {
|
|
||||||
* person: {
|
|
||||||
* properties: {
|
|
||||||
* firstName: { type: string }
|
|
||||||
* lastName: { type: string }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* employee: {
|
|
||||||
* properties: {
|
|
||||||
* $ref: #/person/properties
|
|
||||||
* salary: { type: number }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* When "person" and "employee" are merged, you end up with the following object:
|
|
||||||
*
|
|
||||||
* {
|
|
||||||
* properties: {
|
|
||||||
* firstName: { type: string }
|
|
||||||
* lastName: { type: string }
|
|
||||||
* salary: { type: number }
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* @param {object} $ref - The JSON reference object (the one with the "$ref" property)
|
|
||||||
* @param {*} resolvedValue - The resolved value, which can be any type
|
|
||||||
* @returns {*} - Returns the dereferenced value
|
|
||||||
*/
|
|
||||||
$Ref.dereference = function ($ref, resolvedValue) {
|
|
||||||
if (resolvedValue && typeof resolvedValue === "object" && $Ref.isExtended$Ref($ref)) {
|
|
||||||
let merged = {};
|
|
||||||
for (let key of Object.keys($ref)) {
|
|
||||||
if (key !== "$ref") {
|
|
||||||
merged[key] = $ref[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let key of Object.keys(resolvedValue)) {
|
|
||||||
if (!(key in merged)) {
|
|
||||||
merged[key] = resolvedValue[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return merged;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Completely replace the original reference with the resolved value
|
|
||||||
return resolvedValue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
-197
@@ -1,197 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
const { ono } = require("@jsdevtools/ono");
|
|
||||||
const $Ref = require("./ref");
|
|
||||||
const url = require("./util/url");
|
|
||||||
|
|
||||||
module.exports = $Refs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is a map of JSON references and their resolved values.
|
|
||||||
*/
|
|
||||||
function $Refs () {
|
|
||||||
/**
|
|
||||||
* Indicates whether the schema contains any circular references.
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
this.circular = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A map of paths/urls to {@link $Ref} objects
|
|
||||||
*
|
|
||||||
* @type {object}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this._$refs = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link $Ref} object that is the root of the JSON schema.
|
|
||||||
*
|
|
||||||
* @type {$Ref}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
this._root$Ref = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the paths of all the files/URLs that are referenced by the JSON schema,
|
|
||||||
* including the schema itself.
|
|
||||||
*
|
|
||||||
* @param {...string|string[]} [types] - Only return paths of the given types ("file", "http", etc.)
|
|
||||||
* @returns {string[]}
|
|
||||||
*/
|
|
||||||
$Refs.prototype.paths = function (types) { // eslint-disable-line no-unused-vars
|
|
||||||
let paths = getPaths(this._$refs, arguments);
|
|
||||||
return paths.map((path) => {
|
|
||||||
return path.decoded;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the map of JSON references and their resolved values.
|
|
||||||
*
|
|
||||||
* @param {...string|string[]} [types] - Only return references of the given types ("file", "http", etc.)
|
|
||||||
* @returns {object}
|
|
||||||
*/
|
|
||||||
$Refs.prototype.values = function (types) { // eslint-disable-line no-unused-vars
|
|
||||||
let $refs = this._$refs;
|
|
||||||
let paths = getPaths($refs, arguments);
|
|
||||||
return paths.reduce((obj, path) => {
|
|
||||||
obj[path.decoded] = $refs[path.encoded].value;
|
|
||||||
return obj;
|
|
||||||
}, {});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a POJO (plain old JavaScript object) for serialization as JSON.
|
|
||||||
*
|
|
||||||
* @returns {object}
|
|
||||||
*/
|
|
||||||
$Refs.prototype.toJSON = $Refs.prototype.values;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the given JSON reference exists.
|
|
||||||
*
|
|
||||||
* @param {string} path - The path being resolved, optionally with a JSON pointer in the hash
|
|
||||||
* @param {$RefParserOptions} [options]
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
$Refs.prototype.exists = function (path, options) {
|
|
||||||
try {
|
|
||||||
this._resolve(path, "", options);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the given JSON reference and returns the resolved value.
|
|
||||||
*
|
|
||||||
* @param {string} path - The path being resolved, with a JSON pointer in the hash
|
|
||||||
* @param {$RefParserOptions} [options]
|
|
||||||
* @returns {*} - Returns the resolved value
|
|
||||||
*/
|
|
||||||
$Refs.prototype.get = function (path, options) {
|
|
||||||
return this._resolve(path, "", options).value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the value of a nested property within this {@link $Ref#value}.
|
|
||||||
* If the property, or any of its parents don't exist, they will be created.
|
|
||||||
*
|
|
||||||
* @param {string} path - The path of the property to set, optionally with a JSON pointer in the hash
|
|
||||||
* @param {*} value - The value to assign
|
|
||||||
*/
|
|
||||||
$Refs.prototype.set = function (path, value) {
|
|
||||||
let absPath = url.resolve(this._root$Ref.path, path);
|
|
||||||
let withoutHash = url.stripHash(absPath);
|
|
||||||
let $ref = this._$refs[withoutHash];
|
|
||||||
|
|
||||||
if (!$ref) {
|
|
||||||
throw ono(`Error resolving $ref pointer "${path}". \n"${withoutHash}" not found.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
$ref.set(absPath, value);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new {@link $Ref} object and adds it to this {@link $Refs} object.
|
|
||||||
*
|
|
||||||
* @param {string} path - The file path or URL of the referenced file
|
|
||||||
*/
|
|
||||||
$Refs.prototype._add = function (path) {
|
|
||||||
let withoutHash = url.stripHash(path);
|
|
||||||
|
|
||||||
let $ref = new $Ref();
|
|
||||||
$ref.path = withoutHash;
|
|
||||||
$ref.$refs = this;
|
|
||||||
|
|
||||||
this._$refs[withoutHash] = $ref;
|
|
||||||
this._root$Ref = this._root$Ref || $ref;
|
|
||||||
|
|
||||||
return $ref;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the given JSON reference.
|
|
||||||
*
|
|
||||||
* @param {string} path - The path being resolved, optionally with a JSON pointer in the hash
|
|
||||||
* @param {string} pathFromRoot - The path of `obj` from the schema root
|
|
||||||
* @param {$RefParserOptions} [options]
|
|
||||||
* @returns {Pointer}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
$Refs.prototype._resolve = function (path, pathFromRoot, options) {
|
|
||||||
let absPath = url.resolve(this._root$Ref.path, path);
|
|
||||||
let withoutHash = url.stripHash(absPath);
|
|
||||||
let $ref = this._$refs[withoutHash];
|
|
||||||
|
|
||||||
if (!$ref) {
|
|
||||||
throw ono(`Error resolving $ref pointer "${path}". \n"${withoutHash}" not found.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $ref.resolve(absPath, options, path, pathFromRoot);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the specified {@link $Ref} object, or undefined.
|
|
||||||
*
|
|
||||||
* @param {string} path - The path being resolved, optionally with a JSON pointer in the hash
|
|
||||||
* @returns {$Ref|undefined}
|
|
||||||
* @protected
|
|
||||||
*/
|
|
||||||
$Refs.prototype._get$Ref = function (path) {
|
|
||||||
path = url.resolve(this._root$Ref.path, path);
|
|
||||||
let withoutHash = url.stripHash(path);
|
|
||||||
return this._$refs[withoutHash];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the encoded and decoded paths keys of the given object.
|
|
||||||
*
|
|
||||||
* @param {object} $refs - The object whose keys are URL-encoded paths
|
|
||||||
* @param {...string|string[]} [types] - Only return paths of the given types ("file", "http", etc.)
|
|
||||||
* @returns {object[]}
|
|
||||||
*/
|
|
||||||
function getPaths ($refs, types) {
|
|
||||||
let paths = Object.keys($refs);
|
|
||||||
|
|
||||||
// Filter the paths by type
|
|
||||||
types = Array.isArray(types[0]) ? types[0] : Array.prototype.slice.call(types);
|
|
||||||
if (types.length > 0 && types[0]) {
|
|
||||||
paths = paths.filter((key) => {
|
|
||||||
return types.indexOf($refs[key].pathType) !== -1;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decode local filesystem paths
|
|
||||||
return paths.map((path) => {
|
|
||||||
return {
|
|
||||||
encoded: path,
|
|
||||||
decoded: $refs[path].pathType === "file" ? url.toFileSystemPath(path, true) : path
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Generated
Vendored
-129
@@ -1,129 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
const $Ref = require("./ref");
|
|
||||||
const Pointer = require("./pointer");
|
|
||||||
const parse = require("./parse");
|
|
||||||
const url = require("./util/url");
|
|
||||||
const { isHandledError } = require("./util/errors");
|
|
||||||
|
|
||||||
module.exports = resolveExternal;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Crawls the JSON schema, finds all external JSON references, and resolves their values.
|
|
||||||
* This method does not mutate the JSON schema. The resolved values are added to {@link $RefParser#$refs}.
|
|
||||||
*
|
|
||||||
* NOTE: We only care about EXTERNAL references here. INTERNAL references are only relevant when dereferencing.
|
|
||||||
*
|
|
||||||
* @param {$RefParser} parser
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
*
|
|
||||||
* @returns {Promise}
|
|
||||||
* The promise resolves once all JSON references in the schema have been resolved,
|
|
||||||
* including nested references that are contained in externally-referenced files.
|
|
||||||
*/
|
|
||||||
function resolveExternal (parser, options) {
|
|
||||||
if (!options.resolve.external) {
|
|
||||||
// Nothing to resolve, so exit early
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// console.log('Resolving $ref pointers in %s', parser.$refs._root$Ref.path);
|
|
||||||
let promises = crawl(parser.schema, parser.$refs._root$Ref.path + "#", parser.$refs, options);
|
|
||||||
return Promise.all(promises);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return Promise.reject(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively crawls the given value, and resolves any external JSON references.
|
|
||||||
*
|
|
||||||
* @param {*} obj - The value to crawl. If it's not an object or array, it will be ignored.
|
|
||||||
* @param {string} path - The full path of `obj`, possibly with a JSON Pointer in the hash
|
|
||||||
* @param {$Refs} $refs
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
* @param {Set} seen - Internal.
|
|
||||||
*
|
|
||||||
* @returns {Promise[]}
|
|
||||||
* Returns an array of promises. There will be one promise for each JSON reference in `obj`.
|
|
||||||
* If `obj` does not contain any JSON references, then the array will be empty.
|
|
||||||
* If any of the JSON references point to files that contain additional JSON references,
|
|
||||||
* then the corresponding promise will internally reference an array of promises.
|
|
||||||
*/
|
|
||||||
function crawl (obj, path, $refs, options, seen) {
|
|
||||||
seen = seen || new Set();
|
|
||||||
let promises = [];
|
|
||||||
|
|
||||||
if (obj && typeof obj === "object" && !ArrayBuffer.isView(obj) && !seen.has(obj)) {
|
|
||||||
seen.add(obj); // Track previously seen objects to avoid infinite recursion
|
|
||||||
if ($Ref.isExternal$Ref(obj)) {
|
|
||||||
promises.push(resolve$Ref(obj, path, $refs, options));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (let key of Object.keys(obj)) {
|
|
||||||
let keyPath = Pointer.join(path, key);
|
|
||||||
let value = obj[key];
|
|
||||||
|
|
||||||
if ($Ref.isExternal$Ref(value)) {
|
|
||||||
promises.push(resolve$Ref(value, keyPath, $refs, options));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
promises = promises.concat(crawl(value, keyPath, $refs, options, seen));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return promises;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves the given JSON Reference, and then crawls the resulting value.
|
|
||||||
*
|
|
||||||
* @param {{$ref: string}} $ref - The JSON Reference to resolve
|
|
||||||
* @param {string} path - The full path of `$ref`, possibly with a JSON Pointer in the hash
|
|
||||||
* @param {$Refs} $refs
|
|
||||||
* @param {$RefParserOptions} options
|
|
||||||
*
|
|
||||||
* @returns {Promise}
|
|
||||||
* The promise resolves once all JSON references in the object have been resolved,
|
|
||||||
* including nested references that are contained in externally-referenced files.
|
|
||||||
*/
|
|
||||||
async function resolve$Ref ($ref, path, $refs, options) {
|
|
||||||
// console.log('Resolving $ref pointer "%s" at %s', $ref.$ref, path);
|
|
||||||
|
|
||||||
let resolvedPath = url.resolve(path, $ref.$ref);
|
|
||||||
let withoutHash = url.stripHash(resolvedPath);
|
|
||||||
|
|
||||||
// Do we already have this $ref?
|
|
||||||
$ref = $refs._$refs[withoutHash];
|
|
||||||
if ($ref) {
|
|
||||||
// We've already parsed this $ref, so use the existing value
|
|
||||||
return Promise.resolve($ref.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the $referenced file/url
|
|
||||||
try {
|
|
||||||
const result = await parse(resolvedPath, $refs, options);
|
|
||||||
|
|
||||||
// Crawl the parsed value
|
|
||||||
// console.log('Resolving $ref pointers in %s', withoutHash);
|
|
||||||
let promises = crawl(result, withoutHash + "#", $refs, options);
|
|
||||||
|
|
||||||
return Promise.all(promises);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
if (!options.continueOnError || !isHandledError(err)) {
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($refs._$refs[withoutHash]) {
|
|
||||||
err.source = decodeURI(url.stripHash(path));
|
|
||||||
err.path = url.safePointerToPath(url.getHash(path));
|
|
||||||
}
|
|
||||||
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Generated
Vendored
-64
@@ -1,64 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
const fs = require("fs");
|
|
||||||
const { ono } = require("@jsdevtools/ono");
|
|
||||||
const url = require("../util/url");
|
|
||||||
const { ResolverError } = require("../util/errors");
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
/**
|
|
||||||
* The order that this resolver will run, in relation to other resolvers.
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
order: 100,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether this resolver can read a given file reference.
|
|
||||||
* Resolvers that return true will be tried, in order, until one successfully resolves the file.
|
|
||||||
* Resolvers that return false will not be given a chance to resolve the file.
|
|
||||||
*
|
|
||||||
* @param {object} file - An object containing information about the referenced file
|
|
||||||
* @param {string} file.url - The full URL of the referenced file
|
|
||||||
* @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
canRead (file) {
|
|
||||||
return url.isFileSystemPath(file.url);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the given file and returns its raw contents as a Buffer.
|
|
||||||
*
|
|
||||||
* @param {object} file - An object containing information about the referenced file
|
|
||||||
* @param {string} file.url - The full URL of the referenced file
|
|
||||||
* @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
|
|
||||||
* @returns {Promise<Buffer>}
|
|
||||||
*/
|
|
||||||
read (file) {
|
|
||||||
return new Promise(((resolve, reject) => {
|
|
||||||
let path;
|
|
||||||
try {
|
|
||||||
path = url.toFileSystemPath(file.url);
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
reject(new ResolverError(ono.uri(err, `Malformed URI: ${file.url}`), file.url));
|
|
||||||
}
|
|
||||||
|
|
||||||
// console.log('Opening file: %s', path);
|
|
||||||
|
|
||||||
try {
|
|
||||||
fs.readFile(path, (err, data) => {
|
|
||||||
if (err) {
|
|
||||||
reject(new ResolverError(ono(err, `Error opening file "${path}"`), path));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
resolve(data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
catch (err) {
|
|
||||||
reject(new ResolverError(ono(err, `Error opening file "${path}"`), path));
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Generated
Vendored
-180
@@ -1,180 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
const http = require("http");
|
|
||||||
const https = require("https");
|
|
||||||
const { ono } = require("@jsdevtools/ono");
|
|
||||||
const url = require("../util/url");
|
|
||||||
const { ResolverError } = require("../util/errors");
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
/**
|
|
||||||
* The order that this resolver will run, in relation to other resolvers.
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
order: 200,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTTP headers to send when downloading files.
|
|
||||||
*
|
|
||||||
* @example:
|
|
||||||
* {
|
|
||||||
* "User-Agent": "JSON Schema $Ref Parser",
|
|
||||||
* Accept: "application/json"
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* @type {object}
|
|
||||||
*/
|
|
||||||
headers: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* HTTP request timeout (in milliseconds).
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
timeout: 5000, // 5 seconds
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum number of HTTP redirects to follow.
|
|
||||||
* To disable automatic following of redirects, set this to zero.
|
|
||||||
*
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
redirects: 5,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `withCredentials` option of XMLHttpRequest.
|
|
||||||
* Set this to `true` if you're downloading files from a CORS-enabled server that requires authentication
|
|
||||||
*
|
|
||||||
* @type {boolean}
|
|
||||||
*/
|
|
||||||
withCredentials: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether this resolver can read a given file reference.
|
|
||||||
* Resolvers that return true will be tried in order, until one successfully resolves the file.
|
|
||||||
* Resolvers that return false will not be given a chance to resolve the file.
|
|
||||||
*
|
|
||||||
* @param {object} file - An object containing information about the referenced file
|
|
||||||
* @param {string} file.url - The full URL of the referenced file
|
|
||||||
* @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
canRead (file) {
|
|
||||||
return url.isHttp(file.url);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the given URL and returns its raw contents as a Buffer.
|
|
||||||
*
|
|
||||||
* @param {object} file - An object containing information about the referenced file
|
|
||||||
* @param {string} file.url - The full URL of the referenced file
|
|
||||||
* @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
|
|
||||||
* @returns {Promise<Buffer>}
|
|
||||||
*/
|
|
||||||
read (file) {
|
|
||||||
let u = url.parse(file.url);
|
|
||||||
|
|
||||||
if (process.browser && !u.protocol) {
|
|
||||||
// Use the protocol of the current page
|
|
||||||
u.protocol = url.parse(location.href).protocol;
|
|
||||||
}
|
|
||||||
|
|
||||||
return download(u, this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Downloads the given file.
|
|
||||||
*
|
|
||||||
* @param {Url|string} u - The url to download (can be a parsed {@link Url} object)
|
|
||||||
* @param {object} httpOptions - The `options.resolve.http` object
|
|
||||||
* @param {number} [redirects] - The redirect URLs that have already been followed
|
|
||||||
*
|
|
||||||
* @returns {Promise<Buffer>}
|
|
||||||
* The promise resolves with the raw downloaded data, or rejects if there is an HTTP error.
|
|
||||||
*/
|
|
||||||
function download (u, httpOptions, redirects) {
|
|
||||||
return new Promise(((resolve, reject) => {
|
|
||||||
u = url.parse(u);
|
|
||||||
redirects = redirects || [];
|
|
||||||
redirects.push(u.href);
|
|
||||||
|
|
||||||
get(u, httpOptions)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.statusCode >= 400) {
|
|
||||||
throw ono({ status: res.statusCode }, `HTTP ERROR ${res.statusCode}`);
|
|
||||||
}
|
|
||||||
else if (res.statusCode >= 300) {
|
|
||||||
if (redirects.length > httpOptions.redirects) {
|
|
||||||
reject(new ResolverError(ono({ status: res.statusCode },
|
|
||||||
`Error downloading ${redirects[0]}. \nToo many redirects: \n ${redirects.join(" \n ")}`)));
|
|
||||||
}
|
|
||||||
else if (!res.headers.location) {
|
|
||||||
throw ono({ status: res.statusCode }, `HTTP ${res.statusCode} redirect with no location header`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// console.log('HTTP %d redirect %s -> %s', res.statusCode, u.href, res.headers.location);
|
|
||||||
let redirectTo = url.resolve(u, res.headers.location);
|
|
||||||
download(redirectTo, httpOptions, redirects).then(resolve, reject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
resolve(res.body || Buffer.alloc(0));
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
reject(new ResolverError(ono(err, `Error downloading ${u.href}`), u.href));
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends an HTTP GET request.
|
|
||||||
*
|
|
||||||
* @param {Url} u - A parsed {@link Url} object
|
|
||||||
* @param {object} httpOptions - The `options.resolve.http` object
|
|
||||||
*
|
|
||||||
* @returns {Promise<Response>}
|
|
||||||
* The promise resolves with the HTTP Response object.
|
|
||||||
*/
|
|
||||||
function get (u, httpOptions) {
|
|
||||||
return new Promise(((resolve, reject) => {
|
|
||||||
// console.log('GET', u.href);
|
|
||||||
|
|
||||||
let protocol = u.protocol === "https:" ? https : http;
|
|
||||||
let req = protocol.get({
|
|
||||||
hostname: u.hostname,
|
|
||||||
port: u.port,
|
|
||||||
path: u.path,
|
|
||||||
auth: u.auth,
|
|
||||||
protocol: u.protocol,
|
|
||||||
headers: httpOptions.headers || {},
|
|
||||||
withCredentials: httpOptions.withCredentials
|
|
||||||
});
|
|
||||||
|
|
||||||
if (typeof req.setTimeout === "function") {
|
|
||||||
req.setTimeout(httpOptions.timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
req.on("timeout", () => {
|
|
||||||
req.abort();
|
|
||||||
});
|
|
||||||
|
|
||||||
req.on("error", reject);
|
|
||||||
|
|
||||||
req.once("response", (res) => {
|
|
||||||
res.body = Buffer.alloc(0);
|
|
||||||
|
|
||||||
res.on("data", (data) => {
|
|
||||||
res.body = Buffer.concat([res.body, Buffer.from(data)]);
|
|
||||||
});
|
|
||||||
|
|
||||||
res.on("error", reject);
|
|
||||||
|
|
||||||
res.on("end", () => {
|
|
||||||
resolve(res);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
Generated
Vendored
-136
@@ -1,136 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
const { Ono } = require("@jsdevtools/ono");
|
|
||||||
|
|
||||||
const { stripHash, toFileSystemPath } = require("./url");
|
|
||||||
|
|
||||||
const JSONParserError = exports.JSONParserError = class JSONParserError extends Error {
|
|
||||||
constructor (message, source) {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.code = "EUNKNOWN";
|
|
||||||
this.message = message;
|
|
||||||
this.source = source;
|
|
||||||
this.path = null;
|
|
||||||
|
|
||||||
Ono.extend(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
get footprint () {
|
|
||||||
return `${this.path}+${this.source}+${this.code}+${this.message}`;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
setErrorName(JSONParserError);
|
|
||||||
|
|
||||||
const JSONParserErrorGroup = exports.JSONParserErrorGroup = class JSONParserErrorGroup extends Error {
|
|
||||||
constructor (parser) {
|
|
||||||
super();
|
|
||||||
|
|
||||||
this.files = parser;
|
|
||||||
this.message = `${this.errors.length} error${this.errors.length > 1 ? "s" : ""} occurred while reading '${toFileSystemPath(parser.$refs._root$Ref.path)}'`;
|
|
||||||
|
|
||||||
Ono.extend(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
static getParserErrors (parser) {
|
|
||||||
const errors = [];
|
|
||||||
|
|
||||||
for (const $ref of Object.values(parser.$refs._$refs)) {
|
|
||||||
if ($ref.errors) {
|
|
||||||
errors.push(...$ref.errors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
get errors () {
|
|
||||||
return JSONParserErrorGroup.getParserErrors(this.files);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
setErrorName(JSONParserErrorGroup);
|
|
||||||
|
|
||||||
const ParserError = exports.ParserError = class ParserError extends JSONParserError {
|
|
||||||
constructor (message, source) {
|
|
||||||
super(`Error parsing ${source}: ${message}`, source);
|
|
||||||
|
|
||||||
this.code = "EPARSER";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
setErrorName(ParserError);
|
|
||||||
|
|
||||||
const UnmatchedParserError = exports.UnmatchedParserError = class UnmatchedParserError extends JSONParserError {
|
|
||||||
constructor (source) {
|
|
||||||
super(`Could not find parser for "${source}"`, source);
|
|
||||||
|
|
||||||
this.code = "EUNMATCHEDPARSER";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
setErrorName(UnmatchedParserError);
|
|
||||||
|
|
||||||
const ResolverError = exports.ResolverError = class ResolverError extends JSONParserError {
|
|
||||||
constructor (ex, source) {
|
|
||||||
super(ex.message || `Error reading file "${source}"`, source);
|
|
||||||
|
|
||||||
this.code = "ERESOLVER";
|
|
||||||
|
|
||||||
if ("code" in ex) {
|
|
||||||
this.ioErrorCode = String(ex.code);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
setErrorName(ResolverError);
|
|
||||||
|
|
||||||
const UnmatchedResolverError = exports.UnmatchedResolverError = class UnmatchedResolverError extends JSONParserError {
|
|
||||||
constructor (source) {
|
|
||||||
super(`Could not find resolver for "${source}"`, source);
|
|
||||||
|
|
||||||
this.code = "EUNMATCHEDRESOLVER";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
setErrorName(UnmatchedResolverError);
|
|
||||||
|
|
||||||
const MissingPointerError = exports.MissingPointerError = class MissingPointerError extends JSONParserError {
|
|
||||||
constructor (token, path) {
|
|
||||||
super(`Token "${token}" does not exist.`, stripHash(path));
|
|
||||||
|
|
||||||
this.code = "EMISSINGPOINTER";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
setErrorName(MissingPointerError);
|
|
||||||
|
|
||||||
const InvalidPointerError = exports.InvalidPointerError = class InvalidPointerError extends JSONParserError {
|
|
||||||
constructor (pointer, path) {
|
|
||||||
super(`Invalid $ref pointer "${pointer}". Pointers must begin with "#/"`, stripHash(path));
|
|
||||||
|
|
||||||
this.code = "EINVALIDPOINTER";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
setErrorName(InvalidPointerError);
|
|
||||||
|
|
||||||
function setErrorName (err) {
|
|
||||||
Object.defineProperty(err.prototype, "name", {
|
|
||||||
value: err.name,
|
|
||||||
enumerable: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.isHandledError = function (err) {
|
|
||||||
return err instanceof JSONParserError || err instanceof JSONParserErrorGroup;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.normalizeError = function (err) {
|
|
||||||
if (err.path === null) {
|
|
||||||
err.path = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return err;
|
|
||||||
};
|
|
||||||
Generated
Vendored
-159
@@ -1,159 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the given plugins as an array, rather than an object map.
|
|
||||||
* All other methods in this module expect an array of plugins rather than an object map.
|
|
||||||
*
|
|
||||||
* @param {object} plugins - A map of plugin objects
|
|
||||||
* @return {object[]}
|
|
||||||
*/
|
|
||||||
exports.all = function (plugins) {
|
|
||||||
return Object.keys(plugins)
|
|
||||||
.filter((key) => {
|
|
||||||
return typeof plugins[key] === "object";
|
|
||||||
})
|
|
||||||
.map((key) => {
|
|
||||||
plugins[key].name = key;
|
|
||||||
return plugins[key];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filters the given plugins, returning only the ones return `true` for the given method.
|
|
||||||
*
|
|
||||||
* @param {object[]} plugins - An array of plugin objects
|
|
||||||
* @param {string} method - The name of the filter method to invoke for each plugin
|
|
||||||
* @param {object} file - A file info object, which will be passed to each method
|
|
||||||
* @return {object[]}
|
|
||||||
*/
|
|
||||||
exports.filter = function (plugins, method, file) {
|
|
||||||
return plugins
|
|
||||||
.filter((plugin) => {
|
|
||||||
return !!getResult(plugin, method, file);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sorts the given plugins, in place, by their `order` property.
|
|
||||||
*
|
|
||||||
* @param {object[]} plugins - An array of plugin objects
|
|
||||||
* @returns {object[]}
|
|
||||||
*/
|
|
||||||
exports.sort = function (plugins) {
|
|
||||||
for (let plugin of plugins) {
|
|
||||||
plugin.order = plugin.order || Number.MAX_SAFE_INTEGER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return plugins.sort((a, b) => { return a.order - b.order; });
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs the specified method of the given plugins, in order, until one of them returns a successful result.
|
|
||||||
* Each method can return a synchronous value, a Promise, or call an error-first callback.
|
|
||||||
* If the promise resolves successfully, or the callback is called without an error, then the result
|
|
||||||
* is immediately returned and no further plugins are called.
|
|
||||||
* If the promise rejects, or the callback is called with an error, then the next plugin is called.
|
|
||||||
* If ALL plugins fail, then the last error is thrown.
|
|
||||||
*
|
|
||||||
* @param {object[]} plugins - An array of plugin objects
|
|
||||||
* @param {string} method - The name of the method to invoke for each plugin
|
|
||||||
* @param {object} file - A file info object, which will be passed to each method
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
|
||||||
exports.run = function (plugins, method, file, $refs) {
|
|
||||||
let plugin, lastError, index = 0;
|
|
||||||
|
|
||||||
return new Promise(((resolve, reject) => {
|
|
||||||
runNextPlugin();
|
|
||||||
|
|
||||||
function runNextPlugin () {
|
|
||||||
plugin = plugins[index++];
|
|
||||||
if (!plugin) {
|
|
||||||
// There are no more functions, so re-throw the last error
|
|
||||||
return reject(lastError);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// console.log(' %s', plugin.name);
|
|
||||||
let result = getResult(plugin, method, file, callback, $refs);
|
|
||||||
if (result && typeof result.then === "function") {
|
|
||||||
// A promise was returned
|
|
||||||
result.then(onSuccess, onError);
|
|
||||||
}
|
|
||||||
else if (result !== undefined) {
|
|
||||||
// A synchronous result was returned
|
|
||||||
onSuccess(result);
|
|
||||||
}
|
|
||||||
else if (index === plugins.length) {
|
|
||||||
throw new Error("No promise has been returned or callback has been called.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
onError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function callback (err, result) {
|
|
||||||
if (err) {
|
|
||||||
onError(err);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
onSuccess(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSuccess (result) {
|
|
||||||
// console.log(' success');
|
|
||||||
resolve({
|
|
||||||
plugin,
|
|
||||||
result
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function onError (error) {
|
|
||||||
// console.log(' %s', err.message || err);
|
|
||||||
lastError = {
|
|
||||||
plugin,
|
|
||||||
error,
|
|
||||||
};
|
|
||||||
runNextPlugin();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the value of the given property.
|
|
||||||
* If the property is a function, then the result of the function is returned.
|
|
||||||
* If the value is a RegExp, then it will be tested against the file URL.
|
|
||||||
* If the value is an aray, then it will be compared against the file extension.
|
|
||||||
*
|
|
||||||
* @param {object} obj - The object whose property/method is called
|
|
||||||
* @param {string} prop - The name of the property/method to invoke
|
|
||||||
* @param {object} file - A file info object, which will be passed to the method
|
|
||||||
* @param {function} [callback] - A callback function, which will be passed to the method
|
|
||||||
* @returns {*}
|
|
||||||
*/
|
|
||||||
function getResult (obj, prop, file, callback, $refs) {
|
|
||||||
let value = obj[prop];
|
|
||||||
|
|
||||||
if (typeof value === "function") {
|
|
||||||
return value.apply(obj, [file, callback, $refs]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!callback) {
|
|
||||||
// The synchronous plugin functions (canParse and canRead)
|
|
||||||
// allow a "shorthand" syntax, where the user can match
|
|
||||||
// files by RegExp or by file extension.
|
|
||||||
if (value instanceof RegExp) {
|
|
||||||
return value.test(file.url);
|
|
||||||
}
|
|
||||||
else if (typeof value === "string") {
|
|
||||||
return value === file.extension;
|
|
||||||
}
|
|
||||||
else if (Array.isArray(value)) {
|
|
||||||
return value.indexOf(file.extension) !== -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
Generated
Vendored
-271
@@ -1,271 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let isWindows = /^win/.test(process.platform),
|
|
||||||
forwardSlashPattern = /\//g,
|
|
||||||
protocolPattern = /^(\w{2,}):\/\//i,
|
|
||||||
url = module.exports,
|
|
||||||
jsonPointerSlash = /~1/g,
|
|
||||||
jsonPointerTilde = /~0/g;
|
|
||||||
|
|
||||||
// RegExp patterns to URL-encode special characters in local filesystem paths
|
|
||||||
let urlEncodePatterns = [
|
|
||||||
/\?/g, "%3F",
|
|
||||||
/\#/g, "%23",
|
|
||||||
];
|
|
||||||
|
|
||||||
// RegExp patterns to URL-decode special characters for local filesystem paths
|
|
||||||
let urlDecodePatterns = [
|
|
||||||
/\%23/g, "#",
|
|
||||||
/\%24/g, "$",
|
|
||||||
/\%26/g, "&",
|
|
||||||
/\%2C/g, ",",
|
|
||||||
/\%40/g, "@"
|
|
||||||
];
|
|
||||||
|
|
||||||
exports.parse = require("url").parse;
|
|
||||||
exports.resolve = require("url").resolve;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the current working directory (in Node) or the current page URL (in browsers).
|
|
||||||
*
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
exports.cwd = function cwd () {
|
|
||||||
if (process.browser) {
|
|
||||||
return location.href;
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = process.cwd();
|
|
||||||
|
|
||||||
let lastChar = path.slice(-1);
|
|
||||||
if (lastChar === "/" || lastChar === "\\") {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return path + "/";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the protocol of the given URL, or `undefined` if it has no protocol.
|
|
||||||
*
|
|
||||||
* @param {string} path
|
|
||||||
* @returns {?string}
|
|
||||||
*/
|
|
||||||
exports.getProtocol = function getProtocol (path) {
|
|
||||||
let match = protocolPattern.exec(path);
|
|
||||||
if (match) {
|
|
||||||
return match[1].toLowerCase();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the lowercased file extension of the given URL,
|
|
||||||
* or an empty string if it has no extension.
|
|
||||||
*
|
|
||||||
* @param {string} path
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
exports.getExtension = function getExtension (path) {
|
|
||||||
let lastDot = path.lastIndexOf(".");
|
|
||||||
if (lastDot >= 0) {
|
|
||||||
return url.stripQuery(path.substr(lastDot).toLowerCase());
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the query, if any, from the given path.
|
|
||||||
*
|
|
||||||
* @param {string} path
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
exports.stripQuery = function stripQuery (path) {
|
|
||||||
let queryIndex = path.indexOf("?");
|
|
||||||
if (queryIndex >= 0) {
|
|
||||||
path = path.substr(0, queryIndex);
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the hash (URL fragment), of the given path.
|
|
||||||
* If there is no hash, then the root hash ("#") is returned.
|
|
||||||
*
|
|
||||||
* @param {string} path
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
exports.getHash = function getHash (path) {
|
|
||||||
let hashIndex = path.indexOf("#");
|
|
||||||
if (hashIndex >= 0) {
|
|
||||||
return path.substr(hashIndex);
|
|
||||||
}
|
|
||||||
return "#";
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the hash (URL fragment), if any, from the given path.
|
|
||||||
*
|
|
||||||
* @param {string} path
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
exports.stripHash = function stripHash (path) {
|
|
||||||
let hashIndex = path.indexOf("#");
|
|
||||||
if (hashIndex >= 0) {
|
|
||||||
path = path.substr(0, hashIndex);
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the given path is an HTTP(S) URL.
|
|
||||||
*
|
|
||||||
* @param {string} path
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
exports.isHttp = function isHttp (path) {
|
|
||||||
let protocol = url.getProtocol(path);
|
|
||||||
if (protocol === "http" || protocol === "https") {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (protocol === undefined) {
|
|
||||||
// There is no protocol. If we're running in a browser, then assume it's HTTP.
|
|
||||||
return process.browser;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// It's some other protocol, such as "ftp://", "mongodb://", etc.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the given path is a filesystem path.
|
|
||||||
* This includes "file://" URLs.
|
|
||||||
*
|
|
||||||
* @param {string} path
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
exports.isFileSystemPath = function isFileSystemPath (path) {
|
|
||||||
if (process.browser) {
|
|
||||||
// We're running in a browser, so assume that all paths are URLs.
|
|
||||||
// This way, even relative paths will be treated as URLs rather than as filesystem paths
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let protocol = url.getProtocol(path);
|
|
||||||
return protocol === undefined || protocol === "file";
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a filesystem path to a properly-encoded URL.
|
|
||||||
*
|
|
||||||
* This is intended to handle situations where JSON Schema $Ref Parser is called
|
|
||||||
* with a filesystem path that contains characters which are not allowed in URLs.
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* The following filesystem paths would be converted to the following URLs:
|
|
||||||
*
|
|
||||||
* <"!@#$%^&*+=?'>.json ==> %3C%22!@%23$%25%5E&*+=%3F\'%3E.json
|
|
||||||
* C:\\My Documents\\File (1).json ==> C:/My%20Documents/File%20(1).json
|
|
||||||
* file://Project #42/file.json ==> file://Project%20%2342/file.json
|
|
||||||
*
|
|
||||||
* @param {string} path
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
exports.fromFileSystemPath = function fromFileSystemPath (path) {
|
|
||||||
// Step 1: On Windows, replace backslashes with forward slashes,
|
|
||||||
// rather than encoding them as "%5C"
|
|
||||||
if (isWindows) {
|
|
||||||
path = path.replace(/\\/g, "/");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 2: `encodeURI` will take care of MOST characters
|
|
||||||
path = encodeURI(path);
|
|
||||||
|
|
||||||
// Step 3: Manually encode characters that are not encoded by `encodeURI`.
|
|
||||||
// This includes characters such as "#" and "?", which have special meaning in URLs,
|
|
||||||
// but are just normal characters in a filesystem path.
|
|
||||||
for (let i = 0; i < urlEncodePatterns.length; i += 2) {
|
|
||||||
path = path.replace(urlEncodePatterns[i], urlEncodePatterns[i + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a URL to a local filesystem path.
|
|
||||||
*
|
|
||||||
* @param {string} path
|
|
||||||
* @param {boolean} [keepFileProtocol] - If true, then "file://" will NOT be stripped
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
exports.toFileSystemPath = function toFileSystemPath (path, keepFileProtocol) {
|
|
||||||
// Step 1: `decodeURI` will decode characters such as Cyrillic characters, spaces, etc.
|
|
||||||
path = decodeURI(path);
|
|
||||||
|
|
||||||
// Step 2: Manually decode characters that are not decoded by `decodeURI`.
|
|
||||||
// This includes characters such as "#" and "?", which have special meaning in URLs,
|
|
||||||
// but are just normal characters in a filesystem path.
|
|
||||||
for (let i = 0; i < urlDecodePatterns.length; i += 2) {
|
|
||||||
path = path.replace(urlDecodePatterns[i], urlDecodePatterns[i + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3: If it's a "file://" URL, then format it consistently
|
|
||||||
// or convert it to a local filesystem path
|
|
||||||
let isFileUrl = path.substr(0, 7).toLowerCase() === "file://";
|
|
||||||
if (isFileUrl) {
|
|
||||||
// Strip-off the protocol, and the initial "/", if there is one
|
|
||||||
path = path[7] === "/" ? path.substr(8) : path.substr(7);
|
|
||||||
|
|
||||||
// insert a colon (":") after the drive letter on Windows
|
|
||||||
if (isWindows && path[1] === "/") {
|
|
||||||
path = path[0] + ":" + path.substr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (keepFileProtocol) {
|
|
||||||
// Return the consistently-formatted "file://" URL
|
|
||||||
path = "file:///" + path;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Convert the "file://" URL to a local filesystem path.
|
|
||||||
// On Windows, it will start with something like "C:/".
|
|
||||||
// On Posix, it will start with "/"
|
|
||||||
isFileUrl = false;
|
|
||||||
path = isWindows ? path : "/" + path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 4: Normalize Windows paths (unless it's a "file://" URL)
|
|
||||||
if (isWindows && !isFileUrl) {
|
|
||||||
// Replace forward slashes with backslashes
|
|
||||||
path = path.replace(forwardSlashPattern, "\\");
|
|
||||||
|
|
||||||
// Capitalize the drive letter
|
|
||||||
if (path.substr(1, 2) === ":\\") {
|
|
||||||
path = path[0].toUpperCase() + path.substr(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a $ref pointer to a valid JSON Path.
|
|
||||||
*
|
|
||||||
* @param {string} pointer
|
|
||||||
* @returns {Array<number | string>}
|
|
||||||
*/
|
|
||||||
exports.safePointerToPath = function safePointerToPath (pointer) {
|
|
||||||
if (pointer.length <= 1 || pointer[0] !== "#" || pointer[1] !== "/") {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return pointer
|
|
||||||
.slice(2)
|
|
||||||
.split("/")
|
|
||||||
.map((value) => {
|
|
||||||
return decodeURIComponent(value)
|
|
||||||
.replace(jsonPointerSlash, "/")
|
|
||||||
.replace(jsonPointerTilde, "~");
|
|
||||||
});
|
|
||||||
};
|
|
||||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
|||||||
../js-yaml/bin/js-yaml.js
|
|
||||||
openapi_templete/node_modules/@apidevtools/json-schema-ref-parser/node_modules/argparse/CHANGELOG.md
Generated
Vendored
-216
@@ -1,216 +0,0 @@
|
|||||||
# Changelog
|
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
||||||
|
|
||||||
|
|
||||||
## [2.0.1] - 2020-08-29
|
|
||||||
### Fixed
|
|
||||||
- Fix issue with `process.argv` when used with interpreters (`coffee`, `ts-node`, etc.), #150.
|
|
||||||
|
|
||||||
|
|
||||||
## [2.0.0] - 2020-08-14
|
|
||||||
### Changed
|
|
||||||
- Full rewrite. Now port from python 3.9.0 & more precise following.
|
|
||||||
See [doc](./doc) for difference and migration info.
|
|
||||||
- node.js 10+ required
|
|
||||||
- Removed most of local docs in favour of original ones.
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.10] - 2018-02-15
|
|
||||||
### Fixed
|
|
||||||
- Use .concat instead of + for arrays, #122.
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.9] - 2016-09-29
|
|
||||||
### Changed
|
|
||||||
- Rerelease after 1.0.8 - deps cleanup.
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.8] - 2016-09-29
|
|
||||||
### Changed
|
|
||||||
- Maintenance (deps bump, fix node 6.5+ tests, coverage report).
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.7] - 2016-03-17
|
|
||||||
### Changed
|
|
||||||
- Teach `addArgument` to accept string arg names. #97, @tomxtobin.
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.6] - 2016-02-06
|
|
||||||
### Changed
|
|
||||||
- Maintenance: moved to eslint & updated CS.
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.5] - 2016-02-05
|
|
||||||
### Changed
|
|
||||||
- Removed lodash dependency to significantly reduce install size.
|
|
||||||
Thanks to @mourner.
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.4] - 2016-01-17
|
|
||||||
### Changed
|
|
||||||
- Maintenance: lodash update to 4.0.0.
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.3] - 2015-10-27
|
|
||||||
### Fixed
|
|
||||||
- Fix parse `=` in args: `--examplepath="C:\myfolder\env=x64"`. #84, @CatWithApple.
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.2] - 2015-03-22
|
|
||||||
### Changed
|
|
||||||
- Relaxed lodash version dependency.
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.1] - 2015-02-20
|
|
||||||
### Changed
|
|
||||||
- Changed dependencies to be compatible with ancient nodejs.
|
|
||||||
|
|
||||||
|
|
||||||
## [1.0.0] - 2015-02-19
|
|
||||||
### Changed
|
|
||||||
- Maintenance release.
|
|
||||||
- Replaced `underscore` with `lodash`.
|
|
||||||
- Bumped version to 1.0.0 to better reflect semver meaning.
|
|
||||||
- HISTORY.md -> CHANGELOG.md
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.16] - 2013-12-01
|
|
||||||
### Changed
|
|
||||||
- Maintenance release. Updated dependencies and docs.
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.15] - 2013-05-13
|
|
||||||
### Fixed
|
|
||||||
- Fixed #55, @trebor89
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.14] - 2013-05-12
|
|
||||||
### Fixed
|
|
||||||
- Fixed #62, @maxtaco
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.13] - 2013-04-08
|
|
||||||
### Changed
|
|
||||||
- Added `.npmignore` to reduce package size
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.12] - 2013-02-10
|
|
||||||
### Fixed
|
|
||||||
- Fixed conflictHandler (#46), @hpaulj
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.11] - 2013-02-07
|
|
||||||
### Added
|
|
||||||
- Added 70+ tests (ported from python), @hpaulj
|
|
||||||
- Added conflictHandler, @applepicke
|
|
||||||
- Added fromfilePrefixChar, @hpaulj
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
- Multiple bugfixes, @hpaulj
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.10] - 2012-12-30
|
|
||||||
### Added
|
|
||||||
- Added [mutual exclusion](http://docs.python.org/dev/library/argparse.html#mutual-exclusion)
|
|
||||||
support, thanks to @hpaulj
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
- Fixed options check for `storeConst` & `appendConst` actions, thanks to @hpaulj
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.9] - 2012-12-27
|
|
||||||
### Fixed
|
|
||||||
- Fixed option dest interferens with other options (issue #23), thanks to @hpaulj
|
|
||||||
- Fixed default value behavior with `*` positionals, thanks to @hpaulj
|
|
||||||
- Improve `getDefault()` behavior, thanks to @hpaulj
|
|
||||||
- Improve negative argument parsing, thanks to @hpaulj
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.8] - 2012-12-01
|
|
||||||
### Fixed
|
|
||||||
- Fixed parser parents (issue #19), thanks to @hpaulj
|
|
||||||
- Fixed negative argument parse (issue #20), thanks to @hpaulj
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.7] - 2012-10-14
|
|
||||||
### Fixed
|
|
||||||
- Fixed 'choices' argument parse (issue #16)
|
|
||||||
- Fixed stderr output (issue #15)
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.6] - 2012-09-09
|
|
||||||
### Fixed
|
|
||||||
- Fixed check for conflict of options (thanks to @tomxtobin)
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.5] - 2012-09-03
|
|
||||||
### Fixed
|
|
||||||
- Fix parser #setDefaults method (thanks to @tomxtobin)
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.4] - 2012-07-30
|
|
||||||
### Fixed
|
|
||||||
- Fixed pseudo-argument support (thanks to @CGamesPlay)
|
|
||||||
- Fixed addHelp default (should be true), if not set (thanks to @benblank)
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.3] - 2012-06-27
|
|
||||||
### Fixed
|
|
||||||
- Fixed formatter api name: Formatter -> HelpFormatter
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.2] - 2012-05-29
|
|
||||||
### Fixed
|
|
||||||
- Removed excess whitespace in help
|
|
||||||
- Fixed error reporting, when parcer with subcommands
|
|
||||||
called with empty arguments
|
|
||||||
|
|
||||||
### Added
|
|
||||||
- Added basic tests
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.1] - 2012-05-23
|
|
||||||
### Fixed
|
|
||||||
- Fixed line wrapping in help formatter
|
|
||||||
- Added better error reporting on invalid arguments
|
|
||||||
|
|
||||||
|
|
||||||
## [0.1.0] - 2012-05-16
|
|
||||||
### Added
|
|
||||||
- First release.
|
|
||||||
|
|
||||||
|
|
||||||
[2.0.1]: https://github.com/nodeca/argparse/compare/2.0.0...2.0.1
|
|
||||||
[2.0.0]: https://github.com/nodeca/argparse/compare/1.0.10...2.0.0
|
|
||||||
[1.0.10]: https://github.com/nodeca/argparse/compare/1.0.9...1.0.10
|
|
||||||
[1.0.9]: https://github.com/nodeca/argparse/compare/1.0.8...1.0.9
|
|
||||||
[1.0.8]: https://github.com/nodeca/argparse/compare/1.0.7...1.0.8
|
|
||||||
[1.0.7]: https://github.com/nodeca/argparse/compare/1.0.6...1.0.7
|
|
||||||
[1.0.6]: https://github.com/nodeca/argparse/compare/1.0.5...1.0.6
|
|
||||||
[1.0.5]: https://github.com/nodeca/argparse/compare/1.0.4...1.0.5
|
|
||||||
[1.0.4]: https://github.com/nodeca/argparse/compare/1.0.3...1.0.4
|
|
||||||
[1.0.3]: https://github.com/nodeca/argparse/compare/1.0.2...1.0.3
|
|
||||||
[1.0.2]: https://github.com/nodeca/argparse/compare/1.0.1...1.0.2
|
|
||||||
[1.0.1]: https://github.com/nodeca/argparse/compare/1.0.0...1.0.1
|
|
||||||
[1.0.0]: https://github.com/nodeca/argparse/compare/0.1.16...1.0.0
|
|
||||||
[0.1.16]: https://github.com/nodeca/argparse/compare/0.1.15...0.1.16
|
|
||||||
[0.1.15]: https://github.com/nodeca/argparse/compare/0.1.14...0.1.15
|
|
||||||
[0.1.14]: https://github.com/nodeca/argparse/compare/0.1.13...0.1.14
|
|
||||||
[0.1.13]: https://github.com/nodeca/argparse/compare/0.1.12...0.1.13
|
|
||||||
[0.1.12]: https://github.com/nodeca/argparse/compare/0.1.11...0.1.12
|
|
||||||
[0.1.11]: https://github.com/nodeca/argparse/compare/0.1.10...0.1.11
|
|
||||||
[0.1.10]: https://github.com/nodeca/argparse/compare/0.1.9...0.1.10
|
|
||||||
[0.1.9]: https://github.com/nodeca/argparse/compare/0.1.8...0.1.9
|
|
||||||
[0.1.8]: https://github.com/nodeca/argparse/compare/0.1.7...0.1.8
|
|
||||||
[0.1.7]: https://github.com/nodeca/argparse/compare/0.1.6...0.1.7
|
|
||||||
[0.1.6]: https://github.com/nodeca/argparse/compare/0.1.5...0.1.6
|
|
||||||
[0.1.5]: https://github.com/nodeca/argparse/compare/0.1.4...0.1.5
|
|
||||||
[0.1.4]: https://github.com/nodeca/argparse/compare/0.1.3...0.1.4
|
|
||||||
[0.1.3]: https://github.com/nodeca/argparse/compare/0.1.2...0.1.3
|
|
||||||
[0.1.2]: https://github.com/nodeca/argparse/compare/0.1.1...0.1.2
|
|
||||||
[0.1.1]: https://github.com/nodeca/argparse/compare/0.1.0...0.1.1
|
|
||||||
[0.1.0]: https://github.com/nodeca/argparse/releases/tag/0.1.0
|
|
||||||
Generated
Vendored
-254
@@ -1,254 +0,0 @@
|
|||||||
A. HISTORY OF THE SOFTWARE
|
|
||||||
==========================
|
|
||||||
|
|
||||||
Python was created in the early 1990s by Guido van Rossum at Stichting
|
|
||||||
Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
|
|
||||||
as a successor of a language called ABC. Guido remains Python's
|
|
||||||
principal author, although it includes many contributions from others.
|
|
||||||
|
|
||||||
In 1995, Guido continued his work on Python at the Corporation for
|
|
||||||
National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
|
|
||||||
in Reston, Virginia where he released several versions of the
|
|
||||||
software.
|
|
||||||
|
|
||||||
In May 2000, Guido and the Python core development team moved to
|
|
||||||
BeOpen.com to form the BeOpen PythonLabs team. In October of the same
|
|
||||||
year, the PythonLabs team moved to Digital Creations, which became
|
|
||||||
Zope Corporation. In 2001, the Python Software Foundation (PSF, see
|
|
||||||
https://www.python.org/psf/) was formed, a non-profit organization
|
|
||||||
created specifically to own Python-related Intellectual Property.
|
|
||||||
Zope Corporation was a sponsoring member of the PSF.
|
|
||||||
|
|
||||||
All Python releases are Open Source (see http://www.opensource.org for
|
|
||||||
the Open Source Definition). Historically, most, but not all, Python
|
|
||||||
releases have also been GPL-compatible; the table below summarizes
|
|
||||||
the various releases.
|
|
||||||
|
|
||||||
Release Derived Year Owner GPL-
|
|
||||||
from compatible? (1)
|
|
||||||
|
|
||||||
0.9.0 thru 1.2 1991-1995 CWI yes
|
|
||||||
1.3 thru 1.5.2 1.2 1995-1999 CNRI yes
|
|
||||||
1.6 1.5.2 2000 CNRI no
|
|
||||||
2.0 1.6 2000 BeOpen.com no
|
|
||||||
1.6.1 1.6 2001 CNRI yes (2)
|
|
||||||
2.1 2.0+1.6.1 2001 PSF no
|
|
||||||
2.0.1 2.0+1.6.1 2001 PSF yes
|
|
||||||
2.1.1 2.1+2.0.1 2001 PSF yes
|
|
||||||
2.1.2 2.1.1 2002 PSF yes
|
|
||||||
2.1.3 2.1.2 2002 PSF yes
|
|
||||||
2.2 and above 2.1.1 2001-now PSF yes
|
|
||||||
|
|
||||||
Footnotes:
|
|
||||||
|
|
||||||
(1) GPL-compatible doesn't mean that we're distributing Python under
|
|
||||||
the GPL. All Python licenses, unlike the GPL, let you distribute
|
|
||||||
a modified version without making your changes open source. The
|
|
||||||
GPL-compatible licenses make it possible to combine Python with
|
|
||||||
other software that is released under the GPL; the others don't.
|
|
||||||
|
|
||||||
(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
|
|
||||||
because its license has a choice of law clause. According to
|
|
||||||
CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
|
|
||||||
is "not incompatible" with the GPL.
|
|
||||||
|
|
||||||
Thanks to the many outside volunteers who have worked under Guido's
|
|
||||||
direction to make these releases possible.
|
|
||||||
|
|
||||||
|
|
||||||
B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
|
|
||||||
===============================================================
|
|
||||||
|
|
||||||
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
|
|
||||||
--------------------------------------------
|
|
||||||
|
|
||||||
1. This LICENSE AGREEMENT is between the Python Software Foundation
|
|
||||||
("PSF"), and the Individual or Organization ("Licensee") accessing and
|
|
||||||
otherwise using this software ("Python") in source or binary form and
|
|
||||||
its associated documentation.
|
|
||||||
|
|
||||||
2. Subject to the terms and conditions of this License Agreement, PSF hereby
|
|
||||||
grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
|
|
||||||
analyze, test, perform and/or display publicly, prepare derivative works,
|
|
||||||
distribute, and otherwise use Python alone or in any derivative version,
|
|
||||||
provided, however, that PSF's License Agreement and PSF's notice of copyright,
|
|
||||||
i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
|
||||||
2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020 Python Software Foundation;
|
|
||||||
All Rights Reserved" are retained in Python alone or in any derivative version
|
|
||||||
prepared by Licensee.
|
|
||||||
|
|
||||||
3. In the event Licensee prepares a derivative work that is based on
|
|
||||||
or incorporates Python or any part thereof, and wants to make
|
|
||||||
the derivative work available to others as provided herein, then
|
|
||||||
Licensee hereby agrees to include in any such work a brief summary of
|
|
||||||
the changes made to Python.
|
|
||||||
|
|
||||||
4. PSF is making Python available to Licensee on an "AS IS"
|
|
||||||
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
|
||||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
|
|
||||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
|
||||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
|
|
||||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
|
||||||
|
|
||||||
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
|
||||||
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
|
||||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
|
|
||||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
|
||||||
|
|
||||||
6. This License Agreement will automatically terminate upon a material
|
|
||||||
breach of its terms and conditions.
|
|
||||||
|
|
||||||
7. Nothing in this License Agreement shall be deemed to create any
|
|
||||||
relationship of agency, partnership, or joint venture between PSF and
|
|
||||||
Licensee. This License Agreement does not grant permission to use PSF
|
|
||||||
trademarks or trade name in a trademark sense to endorse or promote
|
|
||||||
products or services of Licensee, or any third party.
|
|
||||||
|
|
||||||
8. By copying, installing or otherwise using Python, Licensee
|
|
||||||
agrees to be bound by the terms and conditions of this License
|
|
||||||
Agreement.
|
|
||||||
|
|
||||||
|
|
||||||
BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
|
|
||||||
-------------------------------------------
|
|
||||||
|
|
||||||
BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
|
|
||||||
|
|
||||||
1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
|
|
||||||
office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
|
|
||||||
Individual or Organization ("Licensee") accessing and otherwise using
|
|
||||||
this software in source or binary form and its associated
|
|
||||||
documentation ("the Software").
|
|
||||||
|
|
||||||
2. Subject to the terms and conditions of this BeOpen Python License
|
|
||||||
Agreement, BeOpen hereby grants Licensee a non-exclusive,
|
|
||||||
royalty-free, world-wide license to reproduce, analyze, test, perform
|
|
||||||
and/or display publicly, prepare derivative works, distribute, and
|
|
||||||
otherwise use the Software alone or in any derivative version,
|
|
||||||
provided, however, that the BeOpen Python License is retained in the
|
|
||||||
Software, alone or in any derivative version prepared by Licensee.
|
|
||||||
|
|
||||||
3. BeOpen is making the Software available to Licensee on an "AS IS"
|
|
||||||
basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
|
||||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
|
|
||||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
|
||||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
|
|
||||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
|
||||||
|
|
||||||
4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
|
|
||||||
SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
|
|
||||||
AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
|
|
||||||
DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
|
||||||
|
|
||||||
5. This License Agreement will automatically terminate upon a material
|
|
||||||
breach of its terms and conditions.
|
|
||||||
|
|
||||||
6. This License Agreement shall be governed by and interpreted in all
|
|
||||||
respects by the law of the State of California, excluding conflict of
|
|
||||||
law provisions. Nothing in this License Agreement shall be deemed to
|
|
||||||
create any relationship of agency, partnership, or joint venture
|
|
||||||
between BeOpen and Licensee. This License Agreement does not grant
|
|
||||||
permission to use BeOpen trademarks or trade names in a trademark
|
|
||||||
sense to endorse or promote products or services of Licensee, or any
|
|
||||||
third party. As an exception, the "BeOpen Python" logos available at
|
|
||||||
http://www.pythonlabs.com/logos.html may be used according to the
|
|
||||||
permissions granted on that web page.
|
|
||||||
|
|
||||||
7. By copying, installing or otherwise using the software, Licensee
|
|
||||||
agrees to be bound by the terms and conditions of this License
|
|
||||||
Agreement.
|
|
||||||
|
|
||||||
|
|
||||||
CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
1. This LICENSE AGREEMENT is between the Corporation for National
|
|
||||||
Research Initiatives, having an office at 1895 Preston White Drive,
|
|
||||||
Reston, VA 20191 ("CNRI"), and the Individual or Organization
|
|
||||||
("Licensee") accessing and otherwise using Python 1.6.1 software in
|
|
||||||
source or binary form and its associated documentation.
|
|
||||||
|
|
||||||
2. Subject to the terms and conditions of this License Agreement, CNRI
|
|
||||||
hereby grants Licensee a nonexclusive, royalty-free, world-wide
|
|
||||||
license to reproduce, analyze, test, perform and/or display publicly,
|
|
||||||
prepare derivative works, distribute, and otherwise use Python 1.6.1
|
|
||||||
alone or in any derivative version, provided, however, that CNRI's
|
|
||||||
License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
|
|
||||||
1995-2001 Corporation for National Research Initiatives; All Rights
|
|
||||||
Reserved" are retained in Python 1.6.1 alone or in any derivative
|
|
||||||
version prepared by Licensee. Alternately, in lieu of CNRI's License
|
|
||||||
Agreement, Licensee may substitute the following text (omitting the
|
|
||||||
quotes): "Python 1.6.1 is made available subject to the terms and
|
|
||||||
conditions in CNRI's License Agreement. This Agreement together with
|
|
||||||
Python 1.6.1 may be located on the Internet using the following
|
|
||||||
unique, persistent identifier (known as a handle): 1895.22/1013. This
|
|
||||||
Agreement may also be obtained from a proxy server on the Internet
|
|
||||||
using the following URL: http://hdl.handle.net/1895.22/1013".
|
|
||||||
|
|
||||||
3. In the event Licensee prepares a derivative work that is based on
|
|
||||||
or incorporates Python 1.6.1 or any part thereof, and wants to make
|
|
||||||
the derivative work available to others as provided herein, then
|
|
||||||
Licensee hereby agrees to include in any such work a brief summary of
|
|
||||||
the changes made to Python 1.6.1.
|
|
||||||
|
|
||||||
4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
|
|
||||||
basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
|
||||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
|
|
||||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
|
||||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
|
|
||||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
|
||||||
|
|
||||||
5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
|
||||||
1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
|
||||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
|
|
||||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
|
||||||
|
|
||||||
6. This License Agreement will automatically terminate upon a material
|
|
||||||
breach of its terms and conditions.
|
|
||||||
|
|
||||||
7. This License Agreement shall be governed by the federal
|
|
||||||
intellectual property law of the United States, including without
|
|
||||||
limitation the federal copyright law, and, to the extent such
|
|
||||||
U.S. federal law does not apply, by the law of the Commonwealth of
|
|
||||||
Virginia, excluding Virginia's conflict of law provisions.
|
|
||||||
Notwithstanding the foregoing, with regard to derivative works based
|
|
||||||
on Python 1.6.1 that incorporate non-separable material that was
|
|
||||||
previously distributed under the GNU General Public License (GPL), the
|
|
||||||
law of the Commonwealth of Virginia shall govern this License
|
|
||||||
Agreement only as to issues arising under or with respect to
|
|
||||||
Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
|
|
||||||
License Agreement shall be deemed to create any relationship of
|
|
||||||
agency, partnership, or joint venture between CNRI and Licensee. This
|
|
||||||
License Agreement does not grant permission to use CNRI trademarks or
|
|
||||||
trade name in a trademark sense to endorse or promote products or
|
|
||||||
services of Licensee, or any third party.
|
|
||||||
|
|
||||||
8. By clicking on the "ACCEPT" button where indicated, or by copying,
|
|
||||||
installing or otherwise using Python 1.6.1, Licensee agrees to be
|
|
||||||
bound by the terms and conditions of this License Agreement.
|
|
||||||
|
|
||||||
ACCEPT
|
|
||||||
|
|
||||||
|
|
||||||
CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
|
|
||||||
The Netherlands. All rights reserved.
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and distribute this software and its
|
|
||||||
documentation for any purpose and without fee is hereby granted,
|
|
||||||
provided that the above copyright notice appear in all copies and that
|
|
||||||
both that copyright notice and this permission notice appear in
|
|
||||||
supporting documentation, and that the name of Stichting Mathematisch
|
|
||||||
Centrum or CWI not be used in advertising or publicity pertaining to
|
|
||||||
distribution of the software without specific, written prior
|
|
||||||
permission.
|
|
||||||
|
|
||||||
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
|
||||||
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
||||||
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
|
|
||||||
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
|
||||||
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
Generated
Vendored
-84
@@ -1,84 +0,0 @@
|
|||||||
argparse
|
|
||||||
========
|
|
||||||
|
|
||||||
[](http://travis-ci.org/nodeca/argparse)
|
|
||||||
[](https://www.npmjs.org/package/argparse)
|
|
||||||
|
|
||||||
CLI arguments parser for node.js, with [sub-commands](https://docs.python.org/3.9/library/argparse.html#sub-commands) support. Port of python's [argparse](http://docs.python.org/dev/library/argparse.html) (version [3.9.0](https://github.com/python/cpython/blob/v3.9.0rc1/Lib/argparse.py)).
|
|
||||||
|
|
||||||
**Difference with original.**
|
|
||||||
|
|
||||||
- JS has no keyword arguments support.
|
|
||||||
- Pass options instead: `new ArgumentParser({ description: 'example', add_help: true })`.
|
|
||||||
- JS has no python's types `int`, `float`, ...
|
|
||||||
- Use string-typed names: `.add_argument('-b', { type: 'int', help: 'help' })`.
|
|
||||||
- `%r` format specifier uses `require('util').inspect()`.
|
|
||||||
|
|
||||||
More details in [doc](./doc).
|
|
||||||
|
|
||||||
|
|
||||||
Example
|
|
||||||
-------
|
|
||||||
|
|
||||||
`test.js` file:
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
#!/usr/bin/env node
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
const { ArgumentParser } = require('argparse');
|
|
||||||
const { version } = require('./package.json');
|
|
||||||
|
|
||||||
const parser = new ArgumentParser({
|
|
||||||
description: 'Argparse example'
|
|
||||||
});
|
|
||||||
|
|
||||||
parser.add_argument('-v', '--version', { action: 'version', version });
|
|
||||||
parser.add_argument('-f', '--foo', { help: 'foo bar' });
|
|
||||||
parser.add_argument('-b', '--bar', { help: 'bar foo' });
|
|
||||||
parser.add_argument('--baz', { help: 'baz bar' });
|
|
||||||
|
|
||||||
console.dir(parser.parse_args());
|
|
||||||
```
|
|
||||||
|
|
||||||
Display help:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ ./test.js -h
|
|
||||||
usage: test.js [-h] [-v] [-f FOO] [-b BAR] [--baz BAZ]
|
|
||||||
|
|
||||||
Argparse example
|
|
||||||
|
|
||||||
optional arguments:
|
|
||||||
-h, --help show this help message and exit
|
|
||||||
-v, --version show program's version number and exit
|
|
||||||
-f FOO, --foo FOO foo bar
|
|
||||||
-b BAR, --bar BAR bar foo
|
|
||||||
--baz BAZ baz bar
|
|
||||||
```
|
|
||||||
|
|
||||||
Parse arguments:
|
|
||||||
|
|
||||||
```
|
|
||||||
$ ./test.js -f=3 --bar=4 --baz 5
|
|
||||||
{ foo: '3', bar: '4', baz: '5' }
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
API docs
|
|
||||||
--------
|
|
||||||
|
|
||||||
Since this is a port with minimal divergence, there's no separate documentation.
|
|
||||||
Use original one instead, with notes about difference.
|
|
||||||
|
|
||||||
1. [Original doc](https://docs.python.org/3.9/library/argparse.html).
|
|
||||||
2. [Original tutorial](https://docs.python.org/3.9/howto/argparse.html).
|
|
||||||
3. [Difference with python](./doc).
|
|
||||||
|
|
||||||
|
|
||||||
argparse for enterprise
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
Available as part of the Tidelift Subscription
|
|
||||||
|
|
||||||
The maintainers of argparse and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-argparse?utm_source=npm-argparse&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
|
|
||||||
Generated
Vendored
-3707
File diff suppressed because it is too large
Load Diff
Generated
Vendored
-67
@@ -1,67 +0,0 @@
|
|||||||
// Limited implementation of python % string operator, supports only %s and %r for now
|
|
||||||
// (other formats are not used here, but may appear in custom templates)
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const { inspect } = require('util')
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = function sub(pattern, ...values) {
|
|
||||||
let regex = /%(?:(%)|(-)?(\*)?(?:\((\w+)\))?([A-Za-z]))/g
|
|
||||||
|
|
||||||
let result = pattern.replace(regex, function (_, is_literal, is_left_align, is_padded, name, format) {
|
|
||||||
if (is_literal) return '%'
|
|
||||||
|
|
||||||
let padded_count = 0
|
|
||||||
if (is_padded) {
|
|
||||||
if (values.length === 0) throw new TypeError('not enough arguments for format string')
|
|
||||||
padded_count = values.shift()
|
|
||||||
if (!Number.isInteger(padded_count)) throw new TypeError('* wants int')
|
|
||||||
}
|
|
||||||
|
|
||||||
let str
|
|
||||||
if (name !== undefined) {
|
|
||||||
let dict = values[0]
|
|
||||||
if (typeof dict !== 'object' || dict === null) throw new TypeError('format requires a mapping')
|
|
||||||
if (!(name in dict)) throw new TypeError(`no such key: '${name}'`)
|
|
||||||
str = dict[name]
|
|
||||||
} else {
|
|
||||||
if (values.length === 0) throw new TypeError('not enough arguments for format string')
|
|
||||||
str = values.shift()
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (format) {
|
|
||||||
case 's':
|
|
||||||
str = String(str)
|
|
||||||
break
|
|
||||||
case 'r':
|
|
||||||
str = inspect(str)
|
|
||||||
break
|
|
||||||
case 'd':
|
|
||||||
case 'i':
|
|
||||||
if (typeof str !== 'number') {
|
|
||||||
throw new TypeError(`%${format} format: a number is required, not ${typeof str}`)
|
|
||||||
}
|
|
||||||
str = String(str.toFixed(0))
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
throw new TypeError(`unsupported format character '${format}'`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (padded_count > 0) {
|
|
||||||
return is_left_align ? str.padEnd(padded_count) : str.padStart(padded_count)
|
|
||||||
} else {
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (values.length) {
|
|
||||||
if (values.length === 1 && typeof values[0] === 'object' && values[0] !== null) {
|
|
||||||
// mapping
|
|
||||||
} else {
|
|
||||||
throw new TypeError('not all arguments converted during string formatting')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
Generated
Vendored
-440
@@ -1,440 +0,0 @@
|
|||||||
// Partial port of python's argparse module, version 3.9.0 (only wrap and fill functions):
|
|
||||||
// https://github.com/python/cpython/blob/v3.9.0b4/Lib/textwrap.py
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Text wrapping and filling.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Copyright (C) 1999-2001 Gregory P. Ward.
|
|
||||||
// Copyright (C) 2002, 2003 Python Software Foundation.
|
|
||||||
// Copyright (C) 2020 argparse.js authors
|
|
||||||
// Originally written by Greg Ward <gward@python.net>
|
|
||||||
|
|
||||||
// Hardcode the recognized whitespace characters to the US-ASCII
|
|
||||||
// whitespace characters. The main reason for doing this is that
|
|
||||||
// some Unicode spaces (like \u00a0) are non-breaking whitespaces.
|
|
||||||
//
|
|
||||||
// This less funky little regex just split on recognized spaces. E.g.
|
|
||||||
// "Hello there -- you goof-ball, use the -b option!"
|
|
||||||
// splits into
|
|
||||||
// Hello/ /there/ /--/ /you/ /goof-ball,/ /use/ /the/ /-b/ /option!/
|
|
||||||
const wordsep_simple_re = /([\t\n\x0b\x0c\r ]+)/
|
|
||||||
|
|
||||||
class TextWrapper {
|
|
||||||
/*
|
|
||||||
* Object for wrapping/filling text. The public interface consists of
|
|
||||||
* the wrap() and fill() methods; the other methods are just there for
|
|
||||||
* subclasses to override in order to tweak the default behaviour.
|
|
||||||
* If you want to completely replace the main wrapping algorithm,
|
|
||||||
* you'll probably have to override _wrap_chunks().
|
|
||||||
*
|
|
||||||
* Several instance attributes control various aspects of wrapping:
|
|
||||||
* width (default: 70)
|
|
||||||
* the maximum width of wrapped lines (unless break_long_words
|
|
||||||
* is false)
|
|
||||||
* initial_indent (default: "")
|
|
||||||
* string that will be prepended to the first line of wrapped
|
|
||||||
* output. Counts towards the line's width.
|
|
||||||
* subsequent_indent (default: "")
|
|
||||||
* string that will be prepended to all lines save the first
|
|
||||||
* of wrapped output; also counts towards each line's width.
|
|
||||||
* expand_tabs (default: true)
|
|
||||||
* Expand tabs in input text to spaces before further processing.
|
|
||||||
* Each tab will become 0 .. 'tabsize' spaces, depending on its position
|
|
||||||
* in its line. If false, each tab is treated as a single character.
|
|
||||||
* tabsize (default: 8)
|
|
||||||
* Expand tabs in input text to 0 .. 'tabsize' spaces, unless
|
|
||||||
* 'expand_tabs' is false.
|
|
||||||
* replace_whitespace (default: true)
|
|
||||||
* Replace all whitespace characters in the input text by spaces
|
|
||||||
* after tab expansion. Note that if expand_tabs is false and
|
|
||||||
* replace_whitespace is true, every tab will be converted to a
|
|
||||||
* single space!
|
|
||||||
* fix_sentence_endings (default: false)
|
|
||||||
* Ensure that sentence-ending punctuation is always followed
|
|
||||||
* by two spaces. Off by default because the algorithm is
|
|
||||||
* (unavoidably) imperfect.
|
|
||||||
* break_long_words (default: true)
|
|
||||||
* Break words longer than 'width'. If false, those words will not
|
|
||||||
* be broken, and some lines might be longer than 'width'.
|
|
||||||
* break_on_hyphens (default: true)
|
|
||||||
* Allow breaking hyphenated words. If true, wrapping will occur
|
|
||||||
* preferably on whitespaces and right after hyphens part of
|
|
||||||
* compound words.
|
|
||||||
* drop_whitespace (default: true)
|
|
||||||
* Drop leading and trailing whitespace from lines.
|
|
||||||
* max_lines (default: None)
|
|
||||||
* Truncate wrapped lines.
|
|
||||||
* placeholder (default: ' [...]')
|
|
||||||
* Append to the last line of truncated text.
|
|
||||||
*/
|
|
||||||
|
|
||||||
constructor(options = {}) {
|
|
||||||
let {
|
|
||||||
width = 70,
|
|
||||||
initial_indent = '',
|
|
||||||
subsequent_indent = '',
|
|
||||||
expand_tabs = true,
|
|
||||||
replace_whitespace = true,
|
|
||||||
fix_sentence_endings = false,
|
|
||||||
break_long_words = true,
|
|
||||||
drop_whitespace = true,
|
|
||||||
break_on_hyphens = true,
|
|
||||||
tabsize = 8,
|
|
||||||
max_lines = undefined,
|
|
||||||
placeholder=' [...]'
|
|
||||||
} = options
|
|
||||||
|
|
||||||
this.width = width
|
|
||||||
this.initial_indent = initial_indent
|
|
||||||
this.subsequent_indent = subsequent_indent
|
|
||||||
this.expand_tabs = expand_tabs
|
|
||||||
this.replace_whitespace = replace_whitespace
|
|
||||||
this.fix_sentence_endings = fix_sentence_endings
|
|
||||||
this.break_long_words = break_long_words
|
|
||||||
this.drop_whitespace = drop_whitespace
|
|
||||||
this.break_on_hyphens = break_on_hyphens
|
|
||||||
this.tabsize = tabsize
|
|
||||||
this.max_lines = max_lines
|
|
||||||
this.placeholder = placeholder
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -- Private methods -----------------------------------------------
|
|
||||||
// (possibly useful for subclasses to override)
|
|
||||||
|
|
||||||
_munge_whitespace(text) {
|
|
||||||
/*
|
|
||||||
* _munge_whitespace(text : string) -> string
|
|
||||||
*
|
|
||||||
* Munge whitespace in text: expand tabs and convert all other
|
|
||||||
* whitespace characters to spaces. Eg. " foo\\tbar\\n\\nbaz"
|
|
||||||
* becomes " foo bar baz".
|
|
||||||
*/
|
|
||||||
if (this.expand_tabs) {
|
|
||||||
text = text.replace(/\t/g, ' '.repeat(this.tabsize)) // not strictly correct in js
|
|
||||||
}
|
|
||||||
if (this.replace_whitespace) {
|
|
||||||
text = text.replace(/[\t\n\x0b\x0c\r]/g, ' ')
|
|
||||||
}
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
|
|
||||||
_split(text) {
|
|
||||||
/*
|
|
||||||
* _split(text : string) -> [string]
|
|
||||||
*
|
|
||||||
* Split the text to wrap into indivisible chunks. Chunks are
|
|
||||||
* not quite the same as words; see _wrap_chunks() for full
|
|
||||||
* details. As an example, the text
|
|
||||||
* Look, goof-ball -- use the -b option!
|
|
||||||
* breaks into the following chunks:
|
|
||||||
* 'Look,', ' ', 'goof-', 'ball', ' ', '--', ' ',
|
|
||||||
* 'use', ' ', 'the', ' ', '-b', ' ', 'option!'
|
|
||||||
* if break_on_hyphens is True, or in:
|
|
||||||
* 'Look,', ' ', 'goof-ball', ' ', '--', ' ',
|
|
||||||
* 'use', ' ', 'the', ' ', '-b', ' ', option!'
|
|
||||||
* otherwise.
|
|
||||||
*/
|
|
||||||
let chunks = text.split(wordsep_simple_re)
|
|
||||||
chunks = chunks.filter(Boolean)
|
|
||||||
return chunks
|
|
||||||
}
|
|
||||||
|
|
||||||
_handle_long_word(reversed_chunks, cur_line, cur_len, width) {
|
|
||||||
/*
|
|
||||||
* _handle_long_word(chunks : [string],
|
|
||||||
* cur_line : [string],
|
|
||||||
* cur_len : int, width : int)
|
|
||||||
*
|
|
||||||
* Handle a chunk of text (most likely a word, not whitespace) that
|
|
||||||
* is too long to fit in any line.
|
|
||||||
*/
|
|
||||||
// Figure out when indent is larger than the specified width, and make
|
|
||||||
// sure at least one character is stripped off on every pass
|
|
||||||
let space_left
|
|
||||||
if (width < 1) {
|
|
||||||
space_left = 1
|
|
||||||
} else {
|
|
||||||
space_left = width - cur_len
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're allowed to break long words, then do so: put as much
|
|
||||||
// of the next chunk onto the current line as will fit.
|
|
||||||
if (this.break_long_words) {
|
|
||||||
cur_line.push(reversed_chunks[reversed_chunks.length - 1].slice(0, space_left))
|
|
||||||
reversed_chunks[reversed_chunks.length - 1] = reversed_chunks[reversed_chunks.length - 1].slice(space_left)
|
|
||||||
|
|
||||||
// Otherwise, we have to preserve the long word intact. Only add
|
|
||||||
// it to the current line if there's nothing already there --
|
|
||||||
// that minimizes how much we violate the width constraint.
|
|
||||||
} else if (!cur_line) {
|
|
||||||
cur_line.push(...reversed_chunks.pop())
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're not allowed to break long words, and there's already
|
|
||||||
// text on the current line, do nothing. Next time through the
|
|
||||||
// main loop of _wrap_chunks(), we'll wind up here again, but
|
|
||||||
// cur_len will be zero, so the next line will be entirely
|
|
||||||
// devoted to the long word that we can't handle right now.
|
|
||||||
}
|
|
||||||
|
|
||||||
_wrap_chunks(chunks) {
|
|
||||||
/*
|
|
||||||
* _wrap_chunks(chunks : [string]) -> [string]
|
|
||||||
*
|
|
||||||
* Wrap a sequence of text chunks and return a list of lines of
|
|
||||||
* length 'self.width' or less. (If 'break_long_words' is false,
|
|
||||||
* some lines may be longer than this.) Chunks correspond roughly
|
|
||||||
* to words and the whitespace between them: each chunk is
|
|
||||||
* indivisible (modulo 'break_long_words'), but a line break can
|
|
||||||
* come between any two chunks. Chunks should not have internal
|
|
||||||
* whitespace; ie. a chunk is either all whitespace or a "word".
|
|
||||||
* Whitespace chunks will be removed from the beginning and end of
|
|
||||||
* lines, but apart from that whitespace is preserved.
|
|
||||||
*/
|
|
||||||
let lines = []
|
|
||||||
let indent
|
|
||||||
if (this.width <= 0) {
|
|
||||||
throw Error(`invalid width ${this.width} (must be > 0)`)
|
|
||||||
}
|
|
||||||
if (this.max_lines !== undefined) {
|
|
||||||
if (this.max_lines > 1) {
|
|
||||||
indent = this.subsequent_indent
|
|
||||||
} else {
|
|
||||||
indent = this.initial_indent
|
|
||||||
}
|
|
||||||
if (indent.length + this.placeholder.trimStart().length > this.width) {
|
|
||||||
throw Error('placeholder too large for max width')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Arrange in reverse order so items can be efficiently popped
|
|
||||||
// from a stack of chucks.
|
|
||||||
chunks = chunks.reverse()
|
|
||||||
|
|
||||||
while (chunks.length > 0) {
|
|
||||||
|
|
||||||
// Start the list of chunks that will make up the current line.
|
|
||||||
// cur_len is just the length of all the chunks in cur_line.
|
|
||||||
let cur_line = []
|
|
||||||
let cur_len = 0
|
|
||||||
|
|
||||||
// Figure out which static string will prefix this line.
|
|
||||||
let indent
|
|
||||||
if (lines) {
|
|
||||||
indent = this.subsequent_indent
|
|
||||||
} else {
|
|
||||||
indent = this.initial_indent
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maximum width for this line.
|
|
||||||
let width = this.width - indent.length
|
|
||||||
|
|
||||||
// First chunk on line is whitespace -- drop it, unless this
|
|
||||||
// is the very beginning of the text (ie. no lines started yet).
|
|
||||||
if (this.drop_whitespace && chunks[chunks.length - 1].trim() === '' && lines.length > 0) {
|
|
||||||
chunks.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
while (chunks.length > 0) {
|
|
||||||
let l = chunks[chunks.length - 1].length
|
|
||||||
|
|
||||||
// Can at least squeeze this chunk onto the current line.
|
|
||||||
if (cur_len + l <= width) {
|
|
||||||
cur_line.push(chunks.pop())
|
|
||||||
cur_len += l
|
|
||||||
|
|
||||||
// Nope, this line is full.
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The current line is full, and the next chunk is too big to
|
|
||||||
// fit on *any* line (not just this one).
|
|
||||||
if (chunks.length && chunks[chunks.length - 1].length > width) {
|
|
||||||
this._handle_long_word(chunks, cur_line, cur_len, width)
|
|
||||||
cur_len = cur_line.map(l => l.length).reduce((a, b) => a + b, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the last chunk on this line is all whitespace, drop it.
|
|
||||||
if (this.drop_whitespace && cur_line.length > 0 && cur_line[cur_line.length - 1].trim() === '') {
|
|
||||||
cur_len -= cur_line[cur_line.length - 1].length
|
|
||||||
cur_line.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cur_line) {
|
|
||||||
if (this.max_lines === undefined ||
|
|
||||||
lines.length + 1 < this.max_lines ||
|
|
||||||
(chunks.length === 0 ||
|
|
||||||
this.drop_whitespace &&
|
|
||||||
chunks.length === 1 &&
|
|
||||||
!chunks[0].trim()) && cur_len <= width) {
|
|
||||||
// Convert current line back to a string and store it in
|
|
||||||
// list of all lines (return value).
|
|
||||||
lines.push(indent + cur_line.join(''))
|
|
||||||
} else {
|
|
||||||
let had_break = false
|
|
||||||
while (cur_line) {
|
|
||||||
if (cur_line[cur_line.length - 1].trim() &&
|
|
||||||
cur_len + this.placeholder.length <= width) {
|
|
||||||
cur_line.push(this.placeholder)
|
|
||||||
lines.push(indent + cur_line.join(''))
|
|
||||||
had_break = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
cur_len -= cur_line[-1].length
|
|
||||||
cur_line.pop()
|
|
||||||
}
|
|
||||||
if (!had_break) {
|
|
||||||
if (lines) {
|
|
||||||
let prev_line = lines[lines.length - 1].trimEnd()
|
|
||||||
if (prev_line.length + this.placeholder.length <=
|
|
||||||
this.width) {
|
|
||||||
lines[lines.length - 1] = prev_line + this.placeholder
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lines.push(indent + this.placeholder.lstrip())
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return lines
|
|
||||||
}
|
|
||||||
|
|
||||||
_split_chunks(text) {
|
|
||||||
text = this._munge_whitespace(text)
|
|
||||||
return this._split(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Public interface ----------------------------------------------
|
|
||||||
|
|
||||||
wrap(text) {
|
|
||||||
/*
|
|
||||||
* wrap(text : string) -> [string]
|
|
||||||
*
|
|
||||||
* Reformat the single paragraph in 'text' so it fits in lines of
|
|
||||||
* no more than 'self.width' columns, and return a list of wrapped
|
|
||||||
* lines. Tabs in 'text' are expanded with string.expandtabs(),
|
|
||||||
* and all other whitespace characters (including newline) are
|
|
||||||
* converted to space.
|
|
||||||
*/
|
|
||||||
let chunks = this._split_chunks(text)
|
|
||||||
// not implemented in js
|
|
||||||
//if (this.fix_sentence_endings) {
|
|
||||||
// this._fix_sentence_endings(chunks)
|
|
||||||
//}
|
|
||||||
return this._wrap_chunks(chunks)
|
|
||||||
}
|
|
||||||
|
|
||||||
fill(text) {
|
|
||||||
/*
|
|
||||||
* fill(text : string) -> string
|
|
||||||
*
|
|
||||||
* Reformat the single paragraph in 'text' to fit in lines of no
|
|
||||||
* more than 'self.width' columns, and return a new string
|
|
||||||
* containing the entire wrapped paragraph.
|
|
||||||
*/
|
|
||||||
return this.wrap(text).join('\n')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// -- Convenience interface ---------------------------------------------
|
|
||||||
|
|
||||||
function wrap(text, options = {}) {
|
|
||||||
/*
|
|
||||||
* Wrap a single paragraph of text, returning a list of wrapped lines.
|
|
||||||
*
|
|
||||||
* Reformat the single paragraph in 'text' so it fits in lines of no
|
|
||||||
* more than 'width' columns, and return a list of wrapped lines. By
|
|
||||||
* default, tabs in 'text' are expanded with string.expandtabs(), and
|
|
||||||
* all other whitespace characters (including newline) are converted to
|
|
||||||
* space. See TextWrapper class for available keyword args to customize
|
|
||||||
* wrapping behaviour.
|
|
||||||
*/
|
|
||||||
let { width = 70, ...kwargs } = options
|
|
||||||
let w = new TextWrapper(Object.assign({ width }, kwargs))
|
|
||||||
return w.wrap(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
function fill(text, options = {}) {
|
|
||||||
/*
|
|
||||||
* Fill a single paragraph of text, returning a new string.
|
|
||||||
*
|
|
||||||
* Reformat the single paragraph in 'text' to fit in lines of no more
|
|
||||||
* than 'width' columns, and return a new string containing the entire
|
|
||||||
* wrapped paragraph. As with wrap(), tabs are expanded and other
|
|
||||||
* whitespace characters converted to space. See TextWrapper class for
|
|
||||||
* available keyword args to customize wrapping behaviour.
|
|
||||||
*/
|
|
||||||
let { width = 70, ...kwargs } = options
|
|
||||||
let w = new TextWrapper(Object.assign({ width }, kwargs))
|
|
||||||
return w.fill(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Loosely related functionality -------------------------------------
|
|
||||||
|
|
||||||
let _whitespace_only_re = /^[ \t]+$/mg
|
|
||||||
let _leading_whitespace_re = /(^[ \t]*)(?:[^ \t\n])/mg
|
|
||||||
|
|
||||||
function dedent(text) {
|
|
||||||
/*
|
|
||||||
* Remove any common leading whitespace from every line in `text`.
|
|
||||||
*
|
|
||||||
* This can be used to make triple-quoted strings line up with the left
|
|
||||||
* edge of the display, while still presenting them in the source code
|
|
||||||
* in indented form.
|
|
||||||
*
|
|
||||||
* Note that tabs and spaces are both treated as whitespace, but they
|
|
||||||
* are not equal: the lines " hello" and "\\thello" are
|
|
||||||
* considered to have no common leading whitespace.
|
|
||||||
*
|
|
||||||
* Entirely blank lines are normalized to a newline character.
|
|
||||||
*/
|
|
||||||
// Look for the longest leading string of spaces and tabs common to
|
|
||||||
// all lines.
|
|
||||||
let margin = undefined
|
|
||||||
text = text.replace(_whitespace_only_re, '')
|
|
||||||
let indents = text.match(_leading_whitespace_re) || []
|
|
||||||
for (let indent of indents) {
|
|
||||||
indent = indent.slice(0, -1)
|
|
||||||
|
|
||||||
if (margin === undefined) {
|
|
||||||
margin = indent
|
|
||||||
|
|
||||||
// Current line more deeply indented than previous winner:
|
|
||||||
// no change (previous winner is still on top).
|
|
||||||
} else if (indent.startsWith(margin)) {
|
|
||||||
// pass
|
|
||||||
|
|
||||||
// Current line consistent with and no deeper than previous winner:
|
|
||||||
// it's the new winner.
|
|
||||||
} else if (margin.startsWith(indent)) {
|
|
||||||
margin = indent
|
|
||||||
|
|
||||||
// Find the largest common whitespace between current line and previous
|
|
||||||
// winner.
|
|
||||||
} else {
|
|
||||||
for (let i = 0; i < margin.length && i < indent.length; i++) {
|
|
||||||
if (margin[i] !== indent[i]) {
|
|
||||||
margin = margin.slice(0, i)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (margin) {
|
|
||||||
text = text.replace(new RegExp('^' + margin, 'mg'), '')
|
|
||||||
}
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { wrap, fill, dedent }
|
|
||||||
openapi_templete/node_modules/@apidevtools/json-schema-ref-parser/node_modules/argparse/package.json
Generated
Vendored
-31
@@ -1,31 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "argparse",
|
|
||||||
"description": "CLI arguments parser. Native port of python's argparse.",
|
|
||||||
"version": "2.0.1",
|
|
||||||
"keywords": [
|
|
||||||
"cli",
|
|
||||||
"parser",
|
|
||||||
"argparse",
|
|
||||||
"option",
|
|
||||||
"args"
|
|
||||||
],
|
|
||||||
"main": "argparse.js",
|
|
||||||
"files": [
|
|
||||||
"argparse.js",
|
|
||||||
"lib/"
|
|
||||||
],
|
|
||||||
"license": "Python-2.0",
|
|
||||||
"repository": "nodeca/argparse",
|
|
||||||
"scripts": {
|
|
||||||
"lint": "eslint .",
|
|
||||||
"test": "npm run lint && nyc mocha",
|
|
||||||
"coverage": "npm run test && nyc report --reporter html"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@babel/eslint-parser": "^7.11.0",
|
|
||||||
"@babel/plugin-syntax-class-properties": "^7.10.4",
|
|
||||||
"eslint": "^7.5.0",
|
|
||||||
"mocha": "^8.0.1",
|
|
||||||
"nyc": "^15.1.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Generated
Vendored
-21
@@ -1,21 +0,0 @@
|
|||||||
(The MIT License)
|
|
||||||
|
|
||||||
Copyright (C) 2011-2015 by Vitaly Puzrin
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
Generated
Vendored
-231
@@ -1,231 +0,0 @@
|
|||||||
JS-YAML - YAML 1.2 parser / writer for JavaScript
|
|
||||||
=================================================
|
|
||||||
|
|
||||||
[](https://github.com/nodeca/js-yaml/actions/workflows/ci.yml)
|
|
||||||
[](https://www.npmjs.org/package/js-yaml)
|
|
||||||
|
|
||||||
__[Online Demo](https://nodeca.github.io/js-yaml/)__
|
|
||||||
|
|
||||||
|
|
||||||
This is an implementation of [YAML](https://yaml.org/), a human-friendly data
|
|
||||||
serialization language. Started as [PyYAML](https://pyyaml.org/) port, it was
|
|
||||||
completely rewritten from scratch. Now it's very fast, and supports 1.2 spec.
|
|
||||||
|
|
||||||
|
|
||||||
Installation
|
|
||||||
------------
|
|
||||||
|
|
||||||
### YAML module for node.js
|
|
||||||
|
|
||||||
```
|
|
||||||
npm install js-yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### CLI executable
|
|
||||||
|
|
||||||
If you want to inspect your YAML files from CLI, install js-yaml globally:
|
|
||||||
|
|
||||||
```
|
|
||||||
npm install -g js-yaml
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Usage
|
|
||||||
|
|
||||||
```
|
|
||||||
usage: js-yaml [-h] [-v] [-c] [-t] file
|
|
||||||
|
|
||||||
Positional arguments:
|
|
||||||
file File with YAML document(s)
|
|
||||||
|
|
||||||
Optional arguments:
|
|
||||||
-h, --help Show this help message and exit.
|
|
||||||
-v, --version Show program's version number and exit.
|
|
||||||
-c, --compact Display errors in compact mode
|
|
||||||
-t, --trace Show stack trace on error
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
API
|
|
||||||
---
|
|
||||||
|
|
||||||
Here we cover the most 'useful' methods. If you need advanced details (creating
|
|
||||||
your own tags), see [examples](https://github.com/nodeca/js-yaml/tree/master/examples)
|
|
||||||
for more info.
|
|
||||||
|
|
||||||
``` javascript
|
|
||||||
const yaml = require('js-yaml');
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
// Get document, or throw exception on error
|
|
||||||
try {
|
|
||||||
const doc = yaml.load(fs.readFileSync('/home/ixti/example.yml', 'utf8'));
|
|
||||||
console.log(doc);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### load (string [ , options ])
|
|
||||||
|
|
||||||
Parses `string` as single YAML document. Returns either a
|
|
||||||
plain object, a string, a number, `null` or `undefined`, or throws `YAMLException` on error. By default, does
|
|
||||||
not support regexps, functions and undefined.
|
|
||||||
|
|
||||||
options:
|
|
||||||
|
|
||||||
- `filename` _(default: null)_ - string to be used as a file path in
|
|
||||||
error/warning messages.
|
|
||||||
- `onWarning` _(default: null)_ - function to call on warning messages.
|
|
||||||
Loader will call this function with an instance of `YAMLException` for each warning.
|
|
||||||
- `schema` _(default: `DEFAULT_SCHEMA`)_ - specifies a schema to use.
|
|
||||||
- `FAILSAFE_SCHEMA` - only strings, arrays and plain objects:
|
|
||||||
https://www.yaml.org/spec/1.2/spec.html#id2802346
|
|
||||||
- `JSON_SCHEMA` - all JSON-supported types:
|
|
||||||
https://www.yaml.org/spec/1.2/spec.html#id2803231
|
|
||||||
- `CORE_SCHEMA` - same as `JSON_SCHEMA`:
|
|
||||||
https://www.yaml.org/spec/1.2/spec.html#id2804923
|
|
||||||
- `DEFAULT_SCHEMA` - all supported YAML types.
|
|
||||||
- `json` _(default: false)_ - compatibility with JSON.parse behaviour. If true, then duplicate keys in a mapping will override values rather than throwing an error.
|
|
||||||
- `maxDepth` _(default: 100)_ - limits nesting depth for collections.
|
|
||||||
- `maxMergeSeqLength` _(default: 20)_ - limits the number of elements in merge
|
|
||||||
(`<<`) sequences.
|
|
||||||
|
|
||||||
NOTE: This function **does not** understand multi-document sources, it throws
|
|
||||||
exception on those.
|
|
||||||
|
|
||||||
NOTE: JS-YAML **does not** support schema-specific tag resolution restrictions.
|
|
||||||
So, the JSON schema is not as strictly defined in the YAML specification.
|
|
||||||
It allows numbers in any notation, use `Null` and `NULL` as `null`, etc.
|
|
||||||
The core schema also has no such restrictions. It allows binary notation for integers.
|
|
||||||
|
|
||||||
|
|
||||||
### loadAll (string [, iterator] [, options ])
|
|
||||||
|
|
||||||
Same as `load()`, but understands multi-document sources. Applies
|
|
||||||
`iterator` to each document if specified, or returns array of documents.
|
|
||||||
|
|
||||||
``` javascript
|
|
||||||
const yaml = require('js-yaml');
|
|
||||||
|
|
||||||
yaml.loadAll(data, function (doc) {
|
|
||||||
console.log(doc);
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### dump (object [ , options ])
|
|
||||||
|
|
||||||
Serializes `object` as a YAML document. Uses `DEFAULT_SCHEMA`, so it will
|
|
||||||
throw an exception if you try to dump regexps or functions. However, you can
|
|
||||||
disable exceptions by setting the `skipInvalid` option to `true`.
|
|
||||||
|
|
||||||
options:
|
|
||||||
|
|
||||||
- `indent` _(default: 2)_ - indentation width to use (in spaces).
|
|
||||||
- `noArrayIndent` _(default: false)_ - when true, will not add an indentation level to array elements
|
|
||||||
- `skipInvalid` _(default: false)_ - do not throw on invalid types (like function
|
|
||||||
in the safe schema) and skip pairs and single values with such types.
|
|
||||||
- `flowLevel` _(default: -1)_ - specifies level of nesting, when to switch from
|
|
||||||
block to flow style for collections. -1 means block style everwhere
|
|
||||||
- `styles` - "tag" => "style" map. Each tag may have own set of styles.
|
|
||||||
- `schema` _(default: `DEFAULT_SCHEMA`)_ specifies a schema to use.
|
|
||||||
- `sortKeys` _(default: `false`)_ - if `true`, sort keys when dumping YAML. If a
|
|
||||||
function, use the function to sort the keys.
|
|
||||||
- `lineWidth` _(default: `80`)_ - set max line width. Set `-1` for unlimited width.
|
|
||||||
- `noRefs` _(default: `false`)_ - if `true`, don't convert duplicate objects into references
|
|
||||||
- `noCompatMode` _(default: `false`)_ - if `true` don't try to be compatible with older
|
|
||||||
yaml versions. Currently: don't quote "yes", "no" and so on, as required for YAML 1.1
|
|
||||||
- `condenseFlow` _(default: `false`)_ - if `true` flow sequences will be condensed, omitting the space between `a, b`. Eg. `'[a,b]'`, and omitting the space between `key: value` and quoting the key. Eg. `'{"a":b}'` Can be useful when using yaml for pretty URL query params as spaces are %-encoded.
|
|
||||||
- `quotingType` _(`'` or `"`, default: `'`)_ - strings will be quoted using this quoting style. If you specify single quotes, double quotes will still be used for non-printable characters.
|
|
||||||
- `forceQuotes` _(default: `false`)_ - if `true`, all non-key strings will be quoted even if they normally don't need to.
|
|
||||||
- `replacer` - callback `function (key, value)` called recursively on each key/value in source object (see `replacer` docs for `JSON.stringify`).
|
|
||||||
|
|
||||||
The following table show availlable styles (e.g. "canonical",
|
|
||||||
"binary"...) available for each tag (.e.g. !!null, !!int ...). Yaml
|
|
||||||
output is shown on the right side after `=>` (default setting) or `->`:
|
|
||||||
|
|
||||||
``` none
|
|
||||||
!!null
|
|
||||||
"canonical" -> "~"
|
|
||||||
"lowercase" => "null"
|
|
||||||
"uppercase" -> "NULL"
|
|
||||||
"camelcase" -> "Null"
|
|
||||||
"empty" -> ""
|
|
||||||
|
|
||||||
!!int
|
|
||||||
"binary" -> "0b1", "0b101010", "0b1110001111010"
|
|
||||||
"octal" -> "0o1", "0o52", "0o16172"
|
|
||||||
"decimal" => "1", "42", "7290"
|
|
||||||
"hexadecimal" -> "0x1", "0x2A", "0x1C7A"
|
|
||||||
|
|
||||||
!!bool
|
|
||||||
"lowercase" => "true", "false"
|
|
||||||
"uppercase" -> "TRUE", "FALSE"
|
|
||||||
"camelcase" -> "True", "False"
|
|
||||||
|
|
||||||
!!float
|
|
||||||
"lowercase" => ".nan", '.inf'
|
|
||||||
"uppercase" -> ".NAN", '.INF'
|
|
||||||
"camelcase" -> ".NaN", '.Inf'
|
|
||||||
```
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
``` javascript
|
|
||||||
dump(object, {
|
|
||||||
'styles': {
|
|
||||||
'!!null': 'canonical' // dump null as ~
|
|
||||||
},
|
|
||||||
'sortKeys': true // sort object keys
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
Supported YAML types
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
The list of standard YAML tags and corresponding JavaScript types. See also
|
|
||||||
[YAML tag discussion](https://pyyaml.org/wiki/YAMLTagDiscussion) and
|
|
||||||
[YAML types repository](https://yaml.org/type/).
|
|
||||||
|
|
||||||
```
|
|
||||||
!!null '' # null
|
|
||||||
!!bool 'yes' # bool
|
|
||||||
!!int '3...' # number
|
|
||||||
!!float '3.14...' # number
|
|
||||||
!!binary '...base64...' # buffer
|
|
||||||
!!timestamp 'YYYY-...' # date
|
|
||||||
!!omap [ ... ] # array of key-value pairs
|
|
||||||
!!pairs [ ... ] # array or array pairs
|
|
||||||
!!set { ... } # array of objects with given keys and null values
|
|
||||||
!!str '...' # string
|
|
||||||
!!seq [ ... ] # array
|
|
||||||
!!map { ... } # object
|
|
||||||
```
|
|
||||||
|
|
||||||
**JavaScript-specific tags**
|
|
||||||
|
|
||||||
See [js-yaml-js-types](https://github.com/nodeca/js-yaml-js-types) for
|
|
||||||
extra types.
|
|
||||||
|
|
||||||
|
|
||||||
Caveats
|
|
||||||
-------
|
|
||||||
|
|
||||||
Note, that you use arrays or objects as key in JS-YAML. JS does not allow objects
|
|
||||||
or arrays as keys, and stringifies (by calling `toString()` method) them at the
|
|
||||||
moment of adding them.
|
|
||||||
|
|
||||||
``` yaml
|
|
||||||
---
|
|
||||||
? [ foo, bar ]
|
|
||||||
: - baz
|
|
||||||
? { foo: bar }
|
|
||||||
: - baz
|
|
||||||
- baz
|
|
||||||
```
|
|
||||||
|
|
||||||
``` javascript
|
|
||||||
{ "foo,bar": ["baz"], "[object Object]": ["baz", "baz"] }
|
|
||||||
```
|
|
||||||
Generated
Vendored
-117
@@ -1,117 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const fs = require('fs')
|
|
||||||
const argparse = require('argparse')
|
|
||||||
const yaml = require('..')
|
|
||||||
|
|
||||||
/// /////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const cli = new argparse.ArgumentParser({
|
|
||||||
prog: 'js-yaml',
|
|
||||||
add_help: true
|
|
||||||
})
|
|
||||||
|
|
||||||
cli.add_argument('-v', '--version', {
|
|
||||||
action: 'version',
|
|
||||||
version: require('../package.json').version
|
|
||||||
})
|
|
||||||
|
|
||||||
cli.add_argument('-c', '--compact', {
|
|
||||||
help: 'Display errors in compact mode',
|
|
||||||
action: 'store_true'
|
|
||||||
})
|
|
||||||
|
|
||||||
// deprecated (not needed after we removed output colors)
|
|
||||||
// option suppressed, but not completely removed for compatibility
|
|
||||||
cli.add_argument('-j', '--to-json', {
|
|
||||||
help: argparse.SUPPRESS,
|
|
||||||
dest: 'json',
|
|
||||||
action: 'store_true'
|
|
||||||
})
|
|
||||||
|
|
||||||
cli.add_argument('-t', '--trace', {
|
|
||||||
help: 'Show stack trace on error',
|
|
||||||
action: 'store_true'
|
|
||||||
})
|
|
||||||
|
|
||||||
cli.add_argument('file', {
|
|
||||||
help: 'File to read, utf-8 encoded without BOM',
|
|
||||||
nargs: '?',
|
|
||||||
default: '-'
|
|
||||||
})
|
|
||||||
|
|
||||||
/// /////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const options = cli.parse_args()
|
|
||||||
|
|
||||||
/// /////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
function readFile (filename, encoding, callback) {
|
|
||||||
if (options.file === '-') {
|
|
||||||
// read from stdin
|
|
||||||
|
|
||||||
const chunks = []
|
|
||||||
|
|
||||||
process.stdin.on('data', function (chunk) {
|
|
||||||
chunks.push(chunk)
|
|
||||||
})
|
|
||||||
|
|
||||||
process.stdin.on('end', function () {
|
|
||||||
return callback(null, Buffer.concat(chunks).toString(encoding))
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
fs.readFile(filename, encoding, callback)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
readFile(options.file, 'utf8', function (error, input) {
|
|
||||||
let output
|
|
||||||
let isYaml
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
if (error.code === 'ENOENT') {
|
|
||||||
console.error('File not found: ' + options.file)
|
|
||||||
process.exit(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
console.error(
|
|
||||||
(options.trace && error.stack) ||
|
|
||||||
error.message ||
|
|
||||||
String(error))
|
|
||||||
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
output = JSON.parse(input)
|
|
||||||
isYaml = false
|
|
||||||
} catch (err) {
|
|
||||||
if (err instanceof SyntaxError) {
|
|
||||||
try {
|
|
||||||
output = []
|
|
||||||
yaml.loadAll(input, function (doc) { output.push(doc) }, {})
|
|
||||||
isYaml = true
|
|
||||||
|
|
||||||
if (output.length === 0) output = null
|
|
||||||
else if (output.length === 1) output = output[0]
|
|
||||||
} catch (e) {
|
|
||||||
if (options.trace && err.stack) console.error(e.stack)
|
|
||||||
else console.error(e.toString(options.compact))
|
|
||||||
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error(
|
|
||||||
(options.trace && err.stack) ||
|
|
||||||
err.message ||
|
|
||||||
String(err))
|
|
||||||
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isYaml) console.log(JSON.stringify(output, null, ' '))
|
|
||||||
else console.log(yaml.dump(output))
|
|
||||||
})
|
|
||||||
Generated
Vendored
-2404
File diff suppressed because it is too large
Load Diff
Generated
Vendored
-1
File diff suppressed because one or more lines are too long
Generated
Vendored
-33
File diff suppressed because one or more lines are too long
Generated
Vendored
-1
File diff suppressed because one or more lines are too long
Generated
Vendored
-2382
File diff suppressed because it is too large
Load Diff
Generated
Vendored
-1
File diff suppressed because one or more lines are too long
Generated
Vendored
-44
@@ -1,44 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const loader = require('./lib/loader')
|
|
||||||
const dumper = require('./lib/dumper')
|
|
||||||
|
|
||||||
function renamed (from, to) {
|
|
||||||
return function () {
|
|
||||||
throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' +
|
|
||||||
'Use yaml.' + to + ' instead, which is now safe by default.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.Type = require('./lib/type')
|
|
||||||
module.exports.Schema = require('./lib/schema')
|
|
||||||
module.exports.FAILSAFE_SCHEMA = require('./lib/schema/failsafe')
|
|
||||||
module.exports.JSON_SCHEMA = require('./lib/schema/json')
|
|
||||||
module.exports.CORE_SCHEMA = require('./lib/schema/core')
|
|
||||||
module.exports.DEFAULT_SCHEMA = require('./lib/schema/default')
|
|
||||||
module.exports.load = loader.load
|
|
||||||
module.exports.loadAll = loader.loadAll
|
|
||||||
module.exports.dump = dumper.dump
|
|
||||||
module.exports.YAMLException = require('./lib/exception')
|
|
||||||
|
|
||||||
// Re-export all types in case user wants to create custom schema
|
|
||||||
module.exports.types = {
|
|
||||||
binary: require('./lib/type/binary'),
|
|
||||||
float: require('./lib/type/float'),
|
|
||||||
map: require('./lib/type/map'),
|
|
||||||
null: require('./lib/type/null'),
|
|
||||||
pairs: require('./lib/type/pairs'),
|
|
||||||
set: require('./lib/type/set'),
|
|
||||||
timestamp: require('./lib/type/timestamp'),
|
|
||||||
bool: require('./lib/type/bool'),
|
|
||||||
int: require('./lib/type/int'),
|
|
||||||
merge: require('./lib/type/merge'),
|
|
||||||
omap: require('./lib/type/omap'),
|
|
||||||
seq: require('./lib/type/seq'),
|
|
||||||
str: require('./lib/type/str')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removed functions from JS-YAML 3.0.x
|
|
||||||
module.exports.safeLoad = renamed('safeLoad', 'load')
|
|
||||||
module.exports.safeLoadAll = renamed('safeLoadAll', 'loadAll')
|
|
||||||
module.exports.safeDump = renamed('safeDump', 'dump')
|
|
||||||
openapi_templete/node_modules/@apidevtools/json-schema-ref-parser/node_modules/js-yaml/lib/common.js
Generated
Vendored
-50
@@ -1,50 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
function isNothing (subject) {
|
|
||||||
return (typeof subject === 'undefined') || (subject === null)
|
|
||||||
}
|
|
||||||
|
|
||||||
function isObject (subject) {
|
|
||||||
return (typeof subject === 'object') && (subject !== null)
|
|
||||||
}
|
|
||||||
|
|
||||||
function toArray (sequence) {
|
|
||||||
if (Array.isArray(sequence)) return sequence
|
|
||||||
else if (isNothing(sequence)) return []
|
|
||||||
|
|
||||||
return [sequence]
|
|
||||||
}
|
|
||||||
|
|
||||||
function extend (target, source) {
|
|
||||||
if (source) {
|
|
||||||
const sourceKeys = Object.keys(source)
|
|
||||||
|
|
||||||
for (let index = 0, length = sourceKeys.length; index < length; index += 1) {
|
|
||||||
const key = sourceKeys[index]
|
|
||||||
target[key] = source[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return target
|
|
||||||
}
|
|
||||||
|
|
||||||
function repeat (string, count) {
|
|
||||||
let result = ''
|
|
||||||
|
|
||||||
for (let cycle = 0; cycle < count; cycle += 1) {
|
|
||||||
result += string
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
function isNegativeZero (number) {
|
|
||||||
return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.isNothing = isNothing
|
|
||||||
module.exports.isObject = isObject
|
|
||||||
module.exports.toArray = toArray
|
|
||||||
module.exports.repeat = repeat
|
|
||||||
module.exports.isNegativeZero = isNegativeZero
|
|
||||||
module.exports.extend = extend
|
|
||||||
openapi_templete/node_modules/@apidevtools/json-schema-ref-parser/node_modules/js-yaml/lib/dumper.js
Generated
Vendored
-937
@@ -1,937 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const common = require('./common')
|
|
||||||
const YAMLException = require('./exception')
|
|
||||||
const DEFAULT_SCHEMA = require('./schema/default')
|
|
||||||
|
|
||||||
const _toString = Object.prototype.toString
|
|
||||||
const _hasOwnProperty = Object.prototype.hasOwnProperty
|
|
||||||
|
|
||||||
const CHAR_BOM = 0xFEFF
|
|
||||||
const CHAR_TAB = 0x09 /* Tab */
|
|
||||||
const CHAR_LINE_FEED = 0x0A /* LF */
|
|
||||||
const CHAR_CARRIAGE_RETURN = 0x0D /* CR */
|
|
||||||
const CHAR_SPACE = 0x20 /* Space */
|
|
||||||
const CHAR_EXCLAMATION = 0x21 /* ! */
|
|
||||||
const CHAR_DOUBLE_QUOTE = 0x22 /* " */
|
|
||||||
const CHAR_SHARP = 0x23 /* # */
|
|
||||||
const CHAR_PERCENT = 0x25 /* % */
|
|
||||||
const CHAR_AMPERSAND = 0x26 /* & */
|
|
||||||
const CHAR_SINGLE_QUOTE = 0x27 /* ' */
|
|
||||||
const CHAR_ASTERISK = 0x2A /* * */
|
|
||||||
const CHAR_COMMA = 0x2C /* , */
|
|
||||||
const CHAR_MINUS = 0x2D /* - */
|
|
||||||
const CHAR_COLON = 0x3A /* : */
|
|
||||||
const CHAR_EQUALS = 0x3D /* = */
|
|
||||||
const CHAR_GREATER_THAN = 0x3E /* > */
|
|
||||||
const CHAR_QUESTION = 0x3F /* ? */
|
|
||||||
const CHAR_COMMERCIAL_AT = 0x40 /* @ */
|
|
||||||
const CHAR_LEFT_SQUARE_BRACKET = 0x5B /* [ */
|
|
||||||
const CHAR_RIGHT_SQUARE_BRACKET = 0x5D /* ] */
|
|
||||||
const CHAR_GRAVE_ACCENT = 0x60 /* ` */
|
|
||||||
const CHAR_LEFT_CURLY_BRACKET = 0x7B /* { */
|
|
||||||
const CHAR_VERTICAL_LINE = 0x7C /* | */
|
|
||||||
const CHAR_RIGHT_CURLY_BRACKET = 0x7D /* } */
|
|
||||||
|
|
||||||
const ESCAPE_SEQUENCES = {}
|
|
||||||
|
|
||||||
ESCAPE_SEQUENCES[0x00] = '\\0'
|
|
||||||
ESCAPE_SEQUENCES[0x07] = '\\a'
|
|
||||||
ESCAPE_SEQUENCES[0x08] = '\\b'
|
|
||||||
ESCAPE_SEQUENCES[0x09] = '\\t'
|
|
||||||
ESCAPE_SEQUENCES[0x0A] = '\\n'
|
|
||||||
ESCAPE_SEQUENCES[0x0B] = '\\v'
|
|
||||||
ESCAPE_SEQUENCES[0x0C] = '\\f'
|
|
||||||
ESCAPE_SEQUENCES[0x0D] = '\\r'
|
|
||||||
ESCAPE_SEQUENCES[0x1B] = '\\e'
|
|
||||||
ESCAPE_SEQUENCES[0x22] = '\\"'
|
|
||||||
ESCAPE_SEQUENCES[0x5C] = '\\\\'
|
|
||||||
ESCAPE_SEQUENCES[0x85] = '\\N'
|
|
||||||
ESCAPE_SEQUENCES[0xA0] = '\\_'
|
|
||||||
ESCAPE_SEQUENCES[0x2028] = '\\L'
|
|
||||||
ESCAPE_SEQUENCES[0x2029] = '\\P'
|
|
||||||
|
|
||||||
const DEPRECATED_BOOLEANS_SYNTAX = [
|
|
||||||
'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON',
|
|
||||||
'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF'
|
|
||||||
]
|
|
||||||
|
|
||||||
const DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/
|
|
||||||
|
|
||||||
function compileStyleMap (schema, map) {
|
|
||||||
if (map === null) return {}
|
|
||||||
|
|
||||||
const result = {}
|
|
||||||
const keys = Object.keys(map)
|
|
||||||
|
|
||||||
for (let index = 0, length = keys.length; index < length; index += 1) {
|
|
||||||
let tag = keys[index]
|
|
||||||
let style = String(map[tag])
|
|
||||||
|
|
||||||
if (tag.slice(0, 2) === '!!') {
|
|
||||||
tag = 'tag:yaml.org,2002:' + tag.slice(2)
|
|
||||||
}
|
|
||||||
const type = schema.compiledTypeMap['fallback'][tag]
|
|
||||||
|
|
||||||
if (type && _hasOwnProperty.call(type.styleAliases, style)) {
|
|
||||||
style = type.styleAliases[style]
|
|
||||||
}
|
|
||||||
|
|
||||||
result[tag] = style
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
function encodeHex (character) {
|
|
||||||
let handle
|
|
||||||
let length
|
|
||||||
|
|
||||||
const string = character.toString(16).toUpperCase()
|
|
||||||
|
|
||||||
if (character <= 0xFF) {
|
|
||||||
handle = 'x'
|
|
||||||
length = 2
|
|
||||||
} else if (character <= 0xFFFF) {
|
|
||||||
handle = 'u'
|
|
||||||
length = 4
|
|
||||||
} else if (character <= 0xFFFFFFFF) {
|
|
||||||
handle = 'U'
|
|
||||||
length = 8
|
|
||||||
} else {
|
|
||||||
throw new YAMLException('code point within a string may not be greater than 0xFFFFFFFF')
|
|
||||||
}
|
|
||||||
|
|
||||||
return '\\' + handle + common.repeat('0', length - string.length) + string
|
|
||||||
}
|
|
||||||
|
|
||||||
const QUOTING_TYPE_SINGLE = 1
|
|
||||||
const QUOTING_TYPE_DOUBLE = 2
|
|
||||||
|
|
||||||
function State (options) {
|
|
||||||
this.schema = options['schema'] || DEFAULT_SCHEMA
|
|
||||||
this.indent = Math.max(1, (options['indent'] || 2))
|
|
||||||
this.noArrayIndent = options['noArrayIndent'] || false
|
|
||||||
this.skipInvalid = options['skipInvalid'] || false
|
|
||||||
this.flowLevel = (common.isNothing(options['flowLevel']) ? -1 : options['flowLevel'])
|
|
||||||
this.styleMap = compileStyleMap(this.schema, options['styles'] || null)
|
|
||||||
this.sortKeys = options['sortKeys'] || false
|
|
||||||
this.lineWidth = options['lineWidth'] || 80
|
|
||||||
this.noRefs = options['noRefs'] || false
|
|
||||||
this.noCompatMode = options['noCompatMode'] || false
|
|
||||||
this.condenseFlow = options['condenseFlow'] || false
|
|
||||||
this.quotingType = options['quotingType'] === '"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE
|
|
||||||
this.forceQuotes = options['forceQuotes'] || false
|
|
||||||
this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null
|
|
||||||
|
|
||||||
this.implicitTypes = this.schema.compiledImplicit
|
|
||||||
this.explicitTypes = this.schema.compiledExplicit
|
|
||||||
|
|
||||||
this.tag = null
|
|
||||||
this.result = ''
|
|
||||||
|
|
||||||
this.duplicates = []
|
|
||||||
this.usedDuplicates = null
|
|
||||||
}
|
|
||||||
|
|
||||||
// Indents every line in a string. Empty lines (\n only) are not indented.
|
|
||||||
function indentString (string, spaces) {
|
|
||||||
const ind = common.repeat(' ', spaces)
|
|
||||||
let position = 0
|
|
||||||
let result = ''
|
|
||||||
const length = string.length
|
|
||||||
|
|
||||||
while (position < length) {
|
|
||||||
let line
|
|
||||||
const next = string.indexOf('\n', position)
|
|
||||||
if (next === -1) {
|
|
||||||
line = string.slice(position)
|
|
||||||
position = length
|
|
||||||
} else {
|
|
||||||
line = string.slice(position, next + 1)
|
|
||||||
position = next + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line.length && line !== '\n') result += ind
|
|
||||||
|
|
||||||
result += line
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateNextLine (state, level) {
|
|
||||||
return '\n' + common.repeat(' ', state.indent * level)
|
|
||||||
}
|
|
||||||
|
|
||||||
function testImplicitResolving (state, str) {
|
|
||||||
for (let index = 0, length = state.implicitTypes.length; index < length; index += 1) {
|
|
||||||
const type = state.implicitTypes[index]
|
|
||||||
|
|
||||||
if (type.resolve(str)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// [33] s-white ::= s-space | s-tab
|
|
||||||
function isWhitespace (c) {
|
|
||||||
return c === CHAR_SPACE || c === CHAR_TAB
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if the character can be printed without escaping.
|
|
||||||
// From YAML 1.2: "any allowed characters known to be non-printable
|
|
||||||
// should also be escaped. [However,] This isn’t mandatory"
|
|
||||||
// Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029.
|
|
||||||
function isPrintable (c) {
|
|
||||||
return (c >= 0x00020 && c <= 0x00007E) ||
|
|
||||||
((c >= 0x000A1 && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029) ||
|
|
||||||
((c >= 0x0E000 && c <= 0x00FFFD) && c !== CHAR_BOM) ||
|
|
||||||
(c >= 0x10000 && c <= 0x10FFFF)
|
|
||||||
}
|
|
||||||
|
|
||||||
// [34] ns-char ::= nb-char - s-white
|
|
||||||
// [27] nb-char ::= c-printable - b-char - c-byte-order-mark
|
|
||||||
// [26] b-char ::= b-line-feed | b-carriage-return
|
|
||||||
// Including s-white (for some reason, examples doesn't match specs in this aspect)
|
|
||||||
// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark
|
|
||||||
function isNsCharOrWhitespace (c) {
|
|
||||||
return isPrintable(c) &&
|
|
||||||
c !== CHAR_BOM &&
|
|
||||||
// - b-char
|
|
||||||
c !== CHAR_CARRIAGE_RETURN &&
|
|
||||||
c !== CHAR_LINE_FEED
|
|
||||||
}
|
|
||||||
|
|
||||||
// [127] ns-plain-safe(c) ::= c = flow-out ⇒ ns-plain-safe-out
|
|
||||||
// c = flow-in ⇒ ns-plain-safe-in
|
|
||||||
// c = block-key ⇒ ns-plain-safe-out
|
|
||||||
// c = flow-key ⇒ ns-plain-safe-in
|
|
||||||
// [128] ns-plain-safe-out ::= ns-char
|
|
||||||
// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator
|
|
||||||
// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - “:” - “#” )
|
|
||||||
// | ( /* An ns-char preceding */ “#” )
|
|
||||||
// | ( “:” /* Followed by an ns-plain-safe(c) */ )
|
|
||||||
function isPlainSafe (c, prev, inblock) {
|
|
||||||
const cIsNsCharOrWhitespace = isNsCharOrWhitespace(c)
|
|
||||||
const cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c)
|
|
||||||
return (
|
|
||||||
(
|
|
||||||
// ns-plain-safe
|
|
||||||
inblock // c = flow-in
|
|
||||||
? cIsNsCharOrWhitespace
|
|
||||||
: cIsNsCharOrWhitespace &&
|
|
||||||
// - c-flow-indicator
|
|
||||||
c !== CHAR_COMMA &&
|
|
||||||
c !== CHAR_LEFT_SQUARE_BRACKET &&
|
|
||||||
c !== CHAR_RIGHT_SQUARE_BRACKET &&
|
|
||||||
c !== CHAR_LEFT_CURLY_BRACKET &&
|
|
||||||
c !== CHAR_RIGHT_CURLY_BRACKET
|
|
||||||
) &&
|
|
||||||
// ns-plain-char
|
|
||||||
c !== CHAR_SHARP && // false on '#'
|
|
||||||
!(prev === CHAR_COLON && !cIsNsChar)
|
|
||||||
) || // false on ': '
|
|
||||||
(isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) || // change to true on '[^ ]#'
|
|
||||||
(prev === CHAR_COLON && cIsNsChar) // change to true on ':[^ ]'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simplified test for values allowed as the first character in plain style.
|
|
||||||
function isPlainSafeFirst (c) {
|
|
||||||
// Uses a subset of ns-char - c-indicator
|
|
||||||
// where ns-char = nb-char - s-white.
|
|
||||||
// No support of ( ( “?” | “:” | “-” ) /* Followed by an ns-plain-safe(c)) */ ) part
|
|
||||||
return isPrintable(c) &&
|
|
||||||
c !== CHAR_BOM &&
|
|
||||||
!isWhitespace(c) && // - s-white
|
|
||||||
// - (c-indicator ::=
|
|
||||||
// “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}”
|
|
||||||
c !== CHAR_MINUS &&
|
|
||||||
c !== CHAR_QUESTION &&
|
|
||||||
c !== CHAR_COLON &&
|
|
||||||
c !== CHAR_COMMA &&
|
|
||||||
c !== CHAR_LEFT_SQUARE_BRACKET &&
|
|
||||||
c !== CHAR_RIGHT_SQUARE_BRACKET &&
|
|
||||||
c !== CHAR_LEFT_CURLY_BRACKET &&
|
|
||||||
c !== CHAR_RIGHT_CURLY_BRACKET &&
|
|
||||||
// | “#” | “&” | “*” | “!” | “|” | “=” | “>” | “'” | “"”
|
|
||||||
c !== CHAR_SHARP &&
|
|
||||||
c !== CHAR_AMPERSAND &&
|
|
||||||
c !== CHAR_ASTERISK &&
|
|
||||||
c !== CHAR_EXCLAMATION &&
|
|
||||||
c !== CHAR_VERTICAL_LINE &&
|
|
||||||
c !== CHAR_EQUALS &&
|
|
||||||
c !== CHAR_GREATER_THAN &&
|
|
||||||
c !== CHAR_SINGLE_QUOTE &&
|
|
||||||
c !== CHAR_DOUBLE_QUOTE &&
|
|
||||||
// | “%” | “@” | “`”)
|
|
||||||
c !== CHAR_PERCENT &&
|
|
||||||
c !== CHAR_COMMERCIAL_AT &&
|
|
||||||
c !== CHAR_GRAVE_ACCENT
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simplified test for values allowed as the last character in plain style.
|
|
||||||
function isPlainSafeLast (c) {
|
|
||||||
// just not whitespace or colon, it will be checked to be plain character later
|
|
||||||
return !isWhitespace(c) && c !== CHAR_COLON
|
|
||||||
}
|
|
||||||
|
|
||||||
// Same as 'string'.codePointAt(pos), but works in older browsers.
|
|
||||||
function codePointAt (string, pos) {
|
|
||||||
const first = string.charCodeAt(pos)
|
|
||||||
let second
|
|
||||||
|
|
||||||
if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) {
|
|
||||||
second = string.charCodeAt(pos + 1)
|
|
||||||
if (second >= 0xDC00 && second <= 0xDFFF) {
|
|
||||||
// https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
|
|
||||||
return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return first
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determines whether block indentation indicator is required.
|
|
||||||
function needIndentIndicator (string) {
|
|
||||||
const leadingSpaceRe = /^\n* /
|
|
||||||
return leadingSpaceRe.test(string)
|
|
||||||
}
|
|
||||||
|
|
||||||
const STYLE_PLAIN = 1
|
|
||||||
const STYLE_SINGLE = 2
|
|
||||||
const STYLE_LITERAL = 3
|
|
||||||
const STYLE_FOLDED = 4
|
|
||||||
const STYLE_DOUBLE = 5
|
|
||||||
|
|
||||||
// Determines which scalar styles are possible and returns the preferred style.
|
|
||||||
// lineWidth = -1 => no limit.
|
|
||||||
// Pre-conditions: str.length > 0.
|
|
||||||
// Post-conditions:
|
|
||||||
// STYLE_PLAIN or STYLE_SINGLE => no \n are in the string.
|
|
||||||
// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1).
|
|
||||||
// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1).
|
|
||||||
function chooseScalarStyle (string, singleLineOnly, indentPerLevel, lineWidth,
|
|
||||||
testAmbiguousType, quotingType, forceQuotes, inblock) {
|
|
||||||
let i
|
|
||||||
let char = 0
|
|
||||||
let prevChar = null
|
|
||||||
let hasLineBreak = false
|
|
||||||
let hasFoldableLine = false // only checked if shouldTrackWidth
|
|
||||||
const shouldTrackWidth = lineWidth !== -1
|
|
||||||
let previousLineBreak = -1 // count the first line correctly
|
|
||||||
let plain = isPlainSafeFirst(codePointAt(string, 0)) &&
|
|
||||||
isPlainSafeLast(codePointAt(string, string.length - 1))
|
|
||||||
|
|
||||||
if (singleLineOnly || forceQuotes) {
|
|
||||||
// Case: no block styles.
|
|
||||||
// Check for disallowed characters to rule out plain and single.
|
|
||||||
for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {
|
|
||||||
char = codePointAt(string, i)
|
|
||||||
if (!isPrintable(char)) {
|
|
||||||
return STYLE_DOUBLE
|
|
||||||
}
|
|
||||||
plain = plain && isPlainSafe(char, prevChar, inblock)
|
|
||||||
prevChar = char
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Case: block styles permitted.
|
|
||||||
for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {
|
|
||||||
char = codePointAt(string, i)
|
|
||||||
if (char === CHAR_LINE_FEED) {
|
|
||||||
hasLineBreak = true
|
|
||||||
// Check if any line can be folded.
|
|
||||||
if (shouldTrackWidth) {
|
|
||||||
hasFoldableLine = hasFoldableLine ||
|
|
||||||
// Foldable line = too long, and not more-indented.
|
|
||||||
(i - previousLineBreak - 1 > lineWidth &&
|
|
||||||
string[previousLineBreak + 1] !== ' ')
|
|
||||||
previousLineBreak = i
|
|
||||||
}
|
|
||||||
} else if (!isPrintable(char)) {
|
|
||||||
return STYLE_DOUBLE
|
|
||||||
}
|
|
||||||
plain = plain && isPlainSafe(char, prevChar, inblock)
|
|
||||||
prevChar = char
|
|
||||||
}
|
|
||||||
// in case the end is missing a \n
|
|
||||||
hasFoldableLine = hasFoldableLine || (shouldTrackWidth &&
|
|
||||||
(i - previousLineBreak - 1 > lineWidth &&
|
|
||||||
string[previousLineBreak + 1] !== ' '))
|
|
||||||
}
|
|
||||||
// Although every style can represent \n without escaping, prefer block styles
|
|
||||||
// for multiline, since they're more readable and they don't add empty lines.
|
|
||||||
// Also prefer folding a super-long line.
|
|
||||||
if (!hasLineBreak && !hasFoldableLine) {
|
|
||||||
// Strings interpretable as another type have to be quoted;
|
|
||||||
// e.g. the string 'true' vs. the boolean true.
|
|
||||||
if (plain && !forceQuotes && !testAmbiguousType(string)) {
|
|
||||||
return STYLE_PLAIN
|
|
||||||
}
|
|
||||||
return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE
|
|
||||||
}
|
|
||||||
// Edge case: block indentation indicator can only have one digit.
|
|
||||||
if (indentPerLevel > 9 && needIndentIndicator(string)) {
|
|
||||||
return STYLE_DOUBLE
|
|
||||||
}
|
|
||||||
// At this point we know block styles are valid.
|
|
||||||
// Prefer literal style unless we want to fold.
|
|
||||||
if (!forceQuotes) {
|
|
||||||
return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL
|
|
||||||
}
|
|
||||||
return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: line breaking/folding is implemented for only the folded style.
|
|
||||||
// NB. We drop the last trailing newline (if any) of a returned block scalar
|
|
||||||
// since the dumper adds its own newline. This always works:
|
|
||||||
// • No ending newline => unaffected; already using strip "-" chomping.
|
|
||||||
// • Ending newline => removed then restored.
|
|
||||||
// Importantly, this keeps the "+" chomp indicator from gaining an extra line.
|
|
||||||
function writeScalar (state, string, level, iskey, inblock) {
|
|
||||||
state.dump = (function () {
|
|
||||||
if (string.length === 0) {
|
|
||||||
return state.quotingType === QUOTING_TYPE_DOUBLE ? '""' : "''"
|
|
||||||
}
|
|
||||||
if (!state.noCompatMode) {
|
|
||||||
if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) {
|
|
||||||
return state.quotingType === QUOTING_TYPE_DOUBLE ? ('"' + string + '"') : ("'" + string + "'")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const indent = state.indent * Math.max(1, level) // no 0-indent scalars
|
|
||||||
// As indentation gets deeper, let the width decrease monotonically
|
|
||||||
// to the lower bound min(state.lineWidth, 40).
|
|
||||||
// Note that this implies
|
|
||||||
// state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound.
|
|
||||||
// state.lineWidth > 40 + state.indent: width decreases until the lower bound.
|
|
||||||
// This behaves better than a constant minimum width which disallows narrower options,
|
|
||||||
// or an indent threshold which causes the width to suddenly increase.
|
|
||||||
const lineWidth = (state.lineWidth === -1)
|
|
||||||
? -1
|
|
||||||
: Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent)
|
|
||||||
|
|
||||||
// Without knowing if keys are implicit/explicit, assume implicit for safety.
|
|
||||||
const singleLineOnly = iskey ||
|
|
||||||
// No block styles in flow mode.
|
|
||||||
(state.flowLevel > -1 && level >= state.flowLevel)
|
|
||||||
function testAmbiguity (string) {
|
|
||||||
return testImplicitResolving(state, string)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth,
|
|
||||||
testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) {
|
|
||||||
case STYLE_PLAIN:
|
|
||||||
return string
|
|
||||||
case STYLE_SINGLE:
|
|
||||||
return "'" + string.replace(/'/g, "''") + "'"
|
|
||||||
case STYLE_LITERAL:
|
|
||||||
return '|' + blockHeader(string, state.indent) +
|
|
||||||
dropEndingNewline(indentString(string, indent))
|
|
||||||
case STYLE_FOLDED:
|
|
||||||
return '>' + blockHeader(string, state.indent) +
|
|
||||||
dropEndingNewline(indentString(foldString(string, lineWidth), indent))
|
|
||||||
case STYLE_DOUBLE:
|
|
||||||
return '"' + escapeString(string, lineWidth) + '"'
|
|
||||||
default:
|
|
||||||
throw new YAMLException('impossible error: invalid scalar style')
|
|
||||||
}
|
|
||||||
}())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9.
|
|
||||||
function blockHeader (string, indentPerLevel) {
|
|
||||||
const indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : ''
|
|
||||||
|
|
||||||
// note the special case: the string '\n' counts as a "trailing" empty line.
|
|
||||||
const clip = string[string.length - 1] === '\n'
|
|
||||||
const keep = clip && (string[string.length - 2] === '\n' || string === '\n')
|
|
||||||
const chomp = keep ? '+' : (clip ? '' : '-')
|
|
||||||
|
|
||||||
return indentIndicator + chomp + '\n'
|
|
||||||
}
|
|
||||||
|
|
||||||
// (See the note for writeScalar.)
|
|
||||||
function dropEndingNewline (string) {
|
|
||||||
return string[string.length - 1] === '\n' ? string.slice(0, -1) : string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: a long line without a suitable break point will exceed the width limit.
|
|
||||||
// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0.
|
|
||||||
function foldString (string, width) {
|
|
||||||
// In folded style, $k$ consecutive newlines output as $k+1$ newlines—
|
|
||||||
// unless they're before or after a more-indented line, or at the very
|
|
||||||
// beginning or end, in which case $k$ maps to $k$.
|
|
||||||
// Therefore, parse each chunk as newline(s) followed by a content line.
|
|
||||||
const lineRe = /(\n+)([^\n]*)/g
|
|
||||||
|
|
||||||
// first line (possibly an empty line)
|
|
||||||
let result = (function () {
|
|
||||||
let nextLF = string.indexOf('\n')
|
|
||||||
nextLF = nextLF !== -1 ? nextLF : string.length
|
|
||||||
lineRe.lastIndex = nextLF
|
|
||||||
return foldLine(string.slice(0, nextLF), width)
|
|
||||||
}())
|
|
||||||
// If we haven't reached the first content line yet, don't add an extra \n.
|
|
||||||
let prevMoreIndented = string[0] === '\n' || string[0] === ' '
|
|
||||||
let moreIndented
|
|
||||||
|
|
||||||
// rest of the lines
|
|
||||||
let match
|
|
||||||
while ((match = lineRe.exec(string))) {
|
|
||||||
const prefix = match[1]
|
|
||||||
const line = match[2]
|
|
||||||
|
|
||||||
moreIndented = (line[0] === ' ')
|
|
||||||
result += prefix +
|
|
||||||
((!prevMoreIndented && !moreIndented && line !== '') ? '\n' : '') +
|
|
||||||
foldLine(line, width)
|
|
||||||
prevMoreIndented = moreIndented
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// Greedy line breaking.
|
|
||||||
// Picks the longest line under the limit each time,
|
|
||||||
// otherwise settles for the shortest line over the limit.
|
|
||||||
// NB. More-indented lines *cannot* be folded, as that would add an extra \n.
|
|
||||||
function foldLine (line, width) {
|
|
||||||
if (line === '' || line[0] === ' ') return line
|
|
||||||
|
|
||||||
// Since a more-indented line adds a \n, breaks can't be followed by a space.
|
|
||||||
const breakRe = / [^ ]/g // note: the match index will always be <= length-2.
|
|
||||||
let match
|
|
||||||
// start is an inclusive index. end, curr, and next are exclusive.
|
|
||||||
let start = 0
|
|
||||||
let end
|
|
||||||
let curr = 0
|
|
||||||
let next = 0
|
|
||||||
let result = ''
|
|
||||||
|
|
||||||
// Invariants: 0 <= start <= length-1.
|
|
||||||
// 0 <= curr <= next <= max(0, length-2). curr - start <= width.
|
|
||||||
// Inside the loop:
|
|
||||||
// A match implies length >= 2, so curr and next are <= length-2.
|
|
||||||
while ((match = breakRe.exec(line))) {
|
|
||||||
next = match.index
|
|
||||||
// maintain invariant: curr - start <= width
|
|
||||||
if (next - start > width) {
|
|
||||||
end = (curr > start) ? curr : next // derive end <= length-2
|
|
||||||
result += '\n' + line.slice(start, end)
|
|
||||||
// skip the space that was output as \n
|
|
||||||
start = end + 1 // derive start <= length-1
|
|
||||||
}
|
|
||||||
curr = next
|
|
||||||
}
|
|
||||||
|
|
||||||
// By the invariants, start <= length-1, so there is something left over.
|
|
||||||
// It is either the whole string or a part starting from non-whitespace.
|
|
||||||
result += '\n'
|
|
||||||
// Insert a break if the remainder is too long and there is a break available.
|
|
||||||
if (line.length - start > width && curr > start) {
|
|
||||||
result += line.slice(start, curr) + '\n' + line.slice(curr + 1)
|
|
||||||
} else {
|
|
||||||
result += line.slice(start)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.slice(1) // drop extra \n joiner
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escapes a double-quoted string.
|
|
||||||
function escapeString (string) {
|
|
||||||
let result = ''
|
|
||||||
let char = 0
|
|
||||||
|
|
||||||
for (let i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) {
|
|
||||||
char = codePointAt(string, i)
|
|
||||||
const escapeSeq = ESCAPE_SEQUENCES[char]
|
|
||||||
|
|
||||||
if (!escapeSeq && isPrintable(char)) {
|
|
||||||
result += string[i]
|
|
||||||
if (char >= 0x10000) result += string[i + 1]
|
|
||||||
} else {
|
|
||||||
result += escapeSeq || encodeHex(char)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeFlowSequence (state, level, object) {
|
|
||||||
let _result = ''
|
|
||||||
const _tag = state.tag
|
|
||||||
|
|
||||||
for (let index = 0, length = object.length; index < length; index += 1) {
|
|
||||||
let value = object[index]
|
|
||||||
|
|
||||||
if (state.replacer) {
|
|
||||||
value = state.replacer.call(object, String(index), value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write only valid elements, put null instead of invalid elements.
|
|
||||||
if (writeNode(state, level, value, false, false) ||
|
|
||||||
(typeof value === 'undefined' &&
|
|
||||||
writeNode(state, level, null, false, false))) {
|
|
||||||
if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : '')
|
|
||||||
_result += state.dump
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
state.tag = _tag
|
|
||||||
state.dump = '[' + _result + ']'
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeBlockSequence (state, level, object, compact) {
|
|
||||||
let _result = ''
|
|
||||||
const _tag = state.tag
|
|
||||||
|
|
||||||
for (let index = 0, length = object.length; index < length; index += 1) {
|
|
||||||
let value = object[index]
|
|
||||||
|
|
||||||
if (state.replacer) {
|
|
||||||
value = state.replacer.call(object, String(index), value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write only valid elements, put null instead of invalid elements.
|
|
||||||
if (writeNode(state, level + 1, value, true, true, false, true) ||
|
|
||||||
(typeof value === 'undefined' &&
|
|
||||||
writeNode(state, level + 1, null, true, true, false, true))) {
|
|
||||||
if (!compact || _result !== '') {
|
|
||||||
_result += generateNextLine(state, level)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
|
|
||||||
_result += '-'
|
|
||||||
} else {
|
|
||||||
_result += '- '
|
|
||||||
}
|
|
||||||
|
|
||||||
_result += state.dump
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
state.tag = _tag
|
|
||||||
state.dump = _result || '[]' // Empty sequence if no valid values.
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeFlowMapping (state, level, object) {
|
|
||||||
let _result = ''
|
|
||||||
const _tag = state.tag
|
|
||||||
const objectKeyList = Object.keys(object)
|
|
||||||
|
|
||||||
for (let index = 0, length = objectKeyList.length; index < length; index += 1) {
|
|
||||||
let pairBuffer = ''
|
|
||||||
if (_result !== '') pairBuffer += ', '
|
|
||||||
|
|
||||||
if (state.condenseFlow) pairBuffer += '"'
|
|
||||||
|
|
||||||
const objectKey = objectKeyList[index]
|
|
||||||
let objectValue = object[objectKey]
|
|
||||||
|
|
||||||
if (state.replacer) {
|
|
||||||
objectValue = state.replacer.call(object, objectKey, objectValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!writeNode(state, level, objectKey, false, false)) {
|
|
||||||
continue // Skip this pair because of invalid key;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.dump.length > 1024) pairBuffer += '? '
|
|
||||||
|
|
||||||
pairBuffer += state.dump + (state.condenseFlow ? '"' : '') + ':' + (state.condenseFlow ? '' : ' ')
|
|
||||||
|
|
||||||
if (!writeNode(state, level, objectValue, false, false)) {
|
|
||||||
continue // Skip this pair because of invalid value.
|
|
||||||
}
|
|
||||||
|
|
||||||
pairBuffer += state.dump
|
|
||||||
|
|
||||||
// Both key and value are valid.
|
|
||||||
_result += pairBuffer
|
|
||||||
}
|
|
||||||
|
|
||||||
state.tag = _tag
|
|
||||||
state.dump = '{' + _result + '}'
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeBlockMapping (state, level, object, compact) {
|
|
||||||
let _result = ''
|
|
||||||
const _tag = state.tag
|
|
||||||
const objectKeyList = Object.keys(object)
|
|
||||||
|
|
||||||
// Allow sorting keys so that the output file is deterministic
|
|
||||||
if (state.sortKeys === true) {
|
|
||||||
// Default sorting
|
|
||||||
objectKeyList.sort()
|
|
||||||
} else if (typeof state.sortKeys === 'function') {
|
|
||||||
// Custom sort function
|
|
||||||
objectKeyList.sort(state.sortKeys)
|
|
||||||
} else if (state.sortKeys) {
|
|
||||||
// Something is wrong
|
|
||||||
throw new YAMLException('sortKeys must be a boolean or a function')
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let index = 0, length = objectKeyList.length; index < length; index += 1) {
|
|
||||||
let pairBuffer = ''
|
|
||||||
|
|
||||||
if (!compact || _result !== '') {
|
|
||||||
pairBuffer += generateNextLine(state, level)
|
|
||||||
}
|
|
||||||
|
|
||||||
const objectKey = objectKeyList[index]
|
|
||||||
let objectValue = object[objectKey]
|
|
||||||
|
|
||||||
if (state.replacer) {
|
|
||||||
objectValue = state.replacer.call(object, objectKey, objectValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!writeNode(state, level + 1, objectKey, true, true, true)) {
|
|
||||||
continue // Skip this pair because of invalid key.
|
|
||||||
}
|
|
||||||
|
|
||||||
const explicitPair = (state.tag !== null && state.tag !== '?') ||
|
|
||||||
(state.dump && state.dump.length > 1024)
|
|
||||||
|
|
||||||
if (explicitPair) {
|
|
||||||
if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
|
|
||||||
pairBuffer += '?'
|
|
||||||
} else {
|
|
||||||
pairBuffer += '? '
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pairBuffer += state.dump
|
|
||||||
|
|
||||||
if (explicitPair) {
|
|
||||||
pairBuffer += generateNextLine(state, level)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!writeNode(state, level + 1, objectValue, true, explicitPair)) {
|
|
||||||
continue // Skip this pair because of invalid value.
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) {
|
|
||||||
pairBuffer += ':'
|
|
||||||
} else {
|
|
||||||
pairBuffer += ': '
|
|
||||||
}
|
|
||||||
|
|
||||||
pairBuffer += state.dump
|
|
||||||
|
|
||||||
// Both key and value are valid.
|
|
||||||
_result += pairBuffer
|
|
||||||
}
|
|
||||||
|
|
||||||
state.tag = _tag
|
|
||||||
state.dump = _result || '{}' // Empty mapping if no valid pairs.
|
|
||||||
}
|
|
||||||
|
|
||||||
function detectType (state, object, explicit) {
|
|
||||||
const typeList = explicit ? state.explicitTypes : state.implicitTypes
|
|
||||||
|
|
||||||
for (let index = 0, length = typeList.length; index < length; index += 1) {
|
|
||||||
const type = typeList[index]
|
|
||||||
|
|
||||||
if ((type.instanceOf || type.predicate) &&
|
|
||||||
(!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) &&
|
|
||||||
(!type.predicate || type.predicate(object))) {
|
|
||||||
if (explicit) {
|
|
||||||
if (type.multi && type.representName) {
|
|
||||||
state.tag = type.representName(object)
|
|
||||||
} else {
|
|
||||||
state.tag = type.tag
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
state.tag = '?'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.represent) {
|
|
||||||
const style = state.styleMap[type.tag] || type.defaultStyle
|
|
||||||
|
|
||||||
let _result
|
|
||||||
if (_toString.call(type.represent) === '[object Function]') {
|
|
||||||
_result = type.represent(object, style)
|
|
||||||
} else if (_hasOwnProperty.call(type.represent, style)) {
|
|
||||||
_result = type.represent[style](object, style)
|
|
||||||
} else {
|
|
||||||
throw new YAMLException('!<' + type.tag + '> tag resolver accepts not "' + style + '" style')
|
|
||||||
}
|
|
||||||
|
|
||||||
state.dump = _result
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serializes `object` and writes it to global `result`.
|
|
||||||
// Returns true on success, or false on invalid object.
|
|
||||||
//
|
|
||||||
function writeNode (state, level, object, block, compact, iskey, isblockseq) {
|
|
||||||
state.tag = null
|
|
||||||
state.dump = object
|
|
||||||
|
|
||||||
if (!detectType(state, object, false)) {
|
|
||||||
detectType(state, object, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
const type = _toString.call(state.dump)
|
|
||||||
const inblock = block
|
|
||||||
|
|
||||||
if (block) {
|
|
||||||
block = (state.flowLevel < 0 || state.flowLevel > level)
|
|
||||||
}
|
|
||||||
|
|
||||||
const objectOrArray = type === '[object Object]' || type === '[object Array]'
|
|
||||||
let duplicateIndex
|
|
||||||
let duplicate
|
|
||||||
|
|
||||||
if (objectOrArray) {
|
|
||||||
duplicateIndex = state.duplicates.indexOf(object)
|
|
||||||
duplicate = duplicateIndex !== -1
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) {
|
|
||||||
compact = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (duplicate && state.usedDuplicates[duplicateIndex]) {
|
|
||||||
state.dump = '*ref_' + duplicateIndex
|
|
||||||
} else {
|
|
||||||
if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) {
|
|
||||||
state.usedDuplicates[duplicateIndex] = true
|
|
||||||
}
|
|
||||||
if (type === '[object Object]') {
|
|
||||||
if (block && (Object.keys(state.dump).length !== 0)) {
|
|
||||||
writeBlockMapping(state, level, state.dump, compact)
|
|
||||||
if (duplicate) {
|
|
||||||
state.dump = '&ref_' + duplicateIndex + state.dump
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
writeFlowMapping(state, level, state.dump)
|
|
||||||
if (duplicate) {
|
|
||||||
state.dump = '&ref_' + duplicateIndex + ' ' + state.dump
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (type === '[object Array]') {
|
|
||||||
if (block && (state.dump.length !== 0)) {
|
|
||||||
if (state.noArrayIndent && !isblockseq && level > 0) {
|
|
||||||
writeBlockSequence(state, level - 1, state.dump, compact)
|
|
||||||
} else {
|
|
||||||
writeBlockSequence(state, level, state.dump, compact)
|
|
||||||
}
|
|
||||||
if (duplicate) {
|
|
||||||
state.dump = '&ref_' + duplicateIndex + state.dump
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
writeFlowSequence(state, level, state.dump)
|
|
||||||
if (duplicate) {
|
|
||||||
state.dump = '&ref_' + duplicateIndex + ' ' + state.dump
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (type === '[object String]') {
|
|
||||||
if (state.tag !== '?') {
|
|
||||||
writeScalar(state, state.dump, level, iskey, inblock)
|
|
||||||
}
|
|
||||||
} else if (type === '[object Undefined]') {
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
if (state.skipInvalid) return false
|
|
||||||
throw new YAMLException('unacceptable kind of an object to dump ' + type)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.tag !== null && state.tag !== '?') {
|
|
||||||
// Need to encode all characters except those allowed by the spec:
|
|
||||||
//
|
|
||||||
// [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */
|
|
||||||
// [36] ns-hex-digit ::= ns-dec-digit
|
|
||||||
// | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */
|
|
||||||
// [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */
|
|
||||||
// [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | “-”
|
|
||||||
// [39] ns-uri-char ::= “%” ns-hex-digit ns-hex-digit | ns-word-char | “#”
|
|
||||||
// | “;” | “/” | “?” | “:” | “@” | “&” | “=” | “+” | “$” | “,”
|
|
||||||
// | “_” | “.” | “!” | “~” | “*” | “'” | “(” | “)” | “[” | “]”
|
|
||||||
//
|
|
||||||
// Also need to encode '!' because it has special meaning (end of tag prefix).
|
|
||||||
//
|
|
||||||
let tagStr = encodeURI(
|
|
||||||
state.tag[0] === '!' ? state.tag.slice(1) : state.tag
|
|
||||||
).replace(/!/g, '%21')
|
|
||||||
|
|
||||||
if (state.tag[0] === '!') {
|
|
||||||
tagStr = '!' + tagStr
|
|
||||||
} else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') {
|
|
||||||
tagStr = '!!' + tagStr.slice(18)
|
|
||||||
} else {
|
|
||||||
tagStr = '!<' + tagStr + '>'
|
|
||||||
}
|
|
||||||
|
|
||||||
state.dump = tagStr + ' ' + state.dump
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDuplicateReferences (object, state) {
|
|
||||||
const objects = []
|
|
||||||
const duplicatesIndexes = []
|
|
||||||
|
|
||||||
inspectNode(object, objects, duplicatesIndexes)
|
|
||||||
|
|
||||||
const length = duplicatesIndexes.length
|
|
||||||
for (let index = 0; index < length; index += 1) {
|
|
||||||
state.duplicates.push(objects[duplicatesIndexes[index]])
|
|
||||||
}
|
|
||||||
state.usedDuplicates = new Array(length)
|
|
||||||
}
|
|
||||||
|
|
||||||
function inspectNode (object, objects, duplicatesIndexes) {
|
|
||||||
if (object !== null && typeof object === 'object') {
|
|
||||||
const index = objects.indexOf(object)
|
|
||||||
if (index !== -1) {
|
|
||||||
if (duplicatesIndexes.indexOf(index) === -1) {
|
|
||||||
duplicatesIndexes.push(index)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
objects.push(object)
|
|
||||||
|
|
||||||
if (Array.isArray(object)) {
|
|
||||||
for (let i = 0, length = object.length; i < length; i += 1) {
|
|
||||||
inspectNode(object[i], objects, duplicatesIndexes)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const objectKeyList = Object.keys(object)
|
|
||||||
|
|
||||||
for (let i = 0, length = objectKeyList.length; i < length; i += 1) {
|
|
||||||
inspectNode(object[objectKeyList[i]], objects, duplicatesIndexes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function dump (input, options) {
|
|
||||||
options = options || {}
|
|
||||||
|
|
||||||
const state = new State(options)
|
|
||||||
|
|
||||||
if (!state.noRefs) getDuplicateReferences(input, state)
|
|
||||||
|
|
||||||
let value = input
|
|
||||||
|
|
||||||
if (state.replacer) {
|
|
||||||
value = state.replacer.call({ '': value }, '', value)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (writeNode(state, 0, value, true, true)) return state.dump + '\n'
|
|
||||||
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports.dump = dump
|
|
||||||
Generated
Vendored
-51
@@ -1,51 +0,0 @@
|
|||||||
// YAML error class. http://stackoverflow.com/questions/8458984
|
|
||||||
//
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
function formatError (exception, compact) {
|
|
||||||
let where = ''
|
|
||||||
const message = exception.reason || '(unknown reason)'
|
|
||||||
|
|
||||||
if (!exception.mark) return message
|
|
||||||
|
|
||||||
if (exception.mark.name) {
|
|
||||||
where += 'in "' + exception.mark.name + '" '
|
|
||||||
}
|
|
||||||
|
|
||||||
where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')'
|
|
||||||
|
|
||||||
if (!compact && exception.mark.snippet) {
|
|
||||||
where += '\n\n' + exception.mark.snippet
|
|
||||||
}
|
|
||||||
|
|
||||||
return message + ' ' + where
|
|
||||||
}
|
|
||||||
|
|
||||||
function YAMLException (reason, mark) {
|
|
||||||
// Super constructor
|
|
||||||
Error.call(this)
|
|
||||||
|
|
||||||
this.name = 'YAMLException'
|
|
||||||
this.reason = reason
|
|
||||||
this.mark = mark
|
|
||||||
this.message = formatError(this, false)
|
|
||||||
|
|
||||||
// Include stack trace in error object
|
|
||||||
if (Error.captureStackTrace) {
|
|
||||||
// Chrome and NodeJS
|
|
||||||
Error.captureStackTrace(this, this.constructor)
|
|
||||||
} else {
|
|
||||||
// FF, IE 10+ and Safari 6+. Fallback for others
|
|
||||||
this.stack = (new Error()).stack || ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inherit from Error
|
|
||||||
YAMLException.prototype = Object.create(Error.prototype)
|
|
||||||
YAMLException.prototype.constructor = YAMLException
|
|
||||||
|
|
||||||
YAMLException.prototype.toString = function toString (compact) {
|
|
||||||
return this.name + ': ' + formatError(this, compact)
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = YAMLException
|
|
||||||
Generated
Vendored
-37
@@ -1,37 +0,0 @@
|
|||||||
import yaml from '../index.js'
|
|
||||||
|
|
||||||
const {
|
|
||||||
Type,
|
|
||||||
Schema,
|
|
||||||
FAILSAFE_SCHEMA,
|
|
||||||
JSON_SCHEMA,
|
|
||||||
CORE_SCHEMA,
|
|
||||||
DEFAULT_SCHEMA,
|
|
||||||
load,
|
|
||||||
loadAll,
|
|
||||||
dump,
|
|
||||||
YAMLException,
|
|
||||||
types,
|
|
||||||
safeLoad,
|
|
||||||
safeLoadAll,
|
|
||||||
safeDump
|
|
||||||
} = yaml
|
|
||||||
|
|
||||||
export {
|
|
||||||
Type,
|
|
||||||
Schema,
|
|
||||||
FAILSAFE_SCHEMA,
|
|
||||||
JSON_SCHEMA,
|
|
||||||
CORE_SCHEMA,
|
|
||||||
DEFAULT_SCHEMA,
|
|
||||||
load,
|
|
||||||
loadAll,
|
|
||||||
dump,
|
|
||||||
YAMLException,
|
|
||||||
types,
|
|
||||||
safeLoad,
|
|
||||||
safeLoadAll,
|
|
||||||
safeDump
|
|
||||||
}
|
|
||||||
|
|
||||||
export default yaml
|
|
||||||
openapi_templete/node_modules/@apidevtools/json-schema-ref-parser/node_modules/js-yaml/lib/loader.js
Generated
Vendored
-1794
File diff suppressed because it is too large
Load Diff
openapi_templete/node_modules/@apidevtools/json-schema-ref-parser/node_modules/js-yaml/lib/schema.js
Generated
Vendored
-109
@@ -1,109 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const YAMLException = require('./exception')
|
|
||||||
const Type = require('./type')
|
|
||||||
|
|
||||||
function compileList (schema, name) {
|
|
||||||
const result = []
|
|
||||||
|
|
||||||
schema[name].forEach(function (currentType) {
|
|
||||||
let newIndex = result.length
|
|
||||||
|
|
||||||
result.forEach(function (previousType, previousIndex) {
|
|
||||||
if (previousType.tag === currentType.tag &&
|
|
||||||
previousType.kind === currentType.kind &&
|
|
||||||
previousType.multi === currentType.multi) {
|
|
||||||
newIndex = previousIndex
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
result[newIndex] = currentType
|
|
||||||
})
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
function compileMap (/* lists... */) {
|
|
||||||
const result = {
|
|
||||||
scalar: {},
|
|
||||||
sequence: {},
|
|
||||||
mapping: {},
|
|
||||||
fallback: {},
|
|
||||||
multi: {
|
|
||||||
scalar: [],
|
|
||||||
sequence: [],
|
|
||||||
mapping: [],
|
|
||||||
fallback: []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function collectType (type) {
|
|
||||||
if (type.multi) {
|
|
||||||
result.multi[type.kind].push(type)
|
|
||||||
result.multi['fallback'].push(type)
|
|
||||||
} else {
|
|
||||||
result[type.kind][type.tag] = result['fallback'][type.tag] = type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let index = 0, length = arguments.length; index < length; index += 1) {
|
|
||||||
arguments[index].forEach(collectType)
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
function Schema (definition) {
|
|
||||||
return this.extend(definition)
|
|
||||||
}
|
|
||||||
|
|
||||||
Schema.prototype.extend = function extend (definition) {
|
|
||||||
let implicit = []
|
|
||||||
let explicit = []
|
|
||||||
|
|
||||||
if (definition instanceof Type) {
|
|
||||||
// Schema.extend(type)
|
|
||||||
explicit.push(definition)
|
|
||||||
} else if (Array.isArray(definition)) {
|
|
||||||
// Schema.extend([ type1, type2, ... ])
|
|
||||||
explicit = explicit.concat(definition)
|
|
||||||
} else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) {
|
|
||||||
// Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] })
|
|
||||||
if (definition.implicit) implicit = implicit.concat(definition.implicit)
|
|
||||||
if (definition.explicit) explicit = explicit.concat(definition.explicit)
|
|
||||||
} else {
|
|
||||||
throw new YAMLException('Schema.extend argument should be a Type, [ Type ], ' +
|
|
||||||
'or a schema definition ({ implicit: [...], explicit: [...] })')
|
|
||||||
}
|
|
||||||
|
|
||||||
implicit.forEach(function (type) {
|
|
||||||
if (!(type instanceof Type)) {
|
|
||||||
throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.loadKind && type.loadKind !== 'scalar') {
|
|
||||||
throw new YAMLException('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type.multi) {
|
|
||||||
throw new YAMLException('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
explicit.forEach(function (type) {
|
|
||||||
if (!(type instanceof Type)) {
|
|
||||||
throw new YAMLException('Specified list of YAML types (or a single Type object) contains a non-Type object.')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const result = Object.create(Schema.prototype)
|
|
||||||
|
|
||||||
result.implicit = (this.implicit || []).concat(implicit)
|
|
||||||
result.explicit = (this.explicit || []).concat(explicit)
|
|
||||||
|
|
||||||
result.compiledImplicit = compileList(result, 'implicit')
|
|
||||||
result.compiledExplicit = compileList(result, 'explicit')
|
|
||||||
result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit)
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Schema
|
|
||||||
Generated
Vendored
-9
@@ -1,9 +0,0 @@
|
|||||||
// Standard YAML's Core schema.
|
|
||||||
// http://www.yaml.org/spec/1.2/spec.html#id2804923
|
|
||||||
//
|
|
||||||
// NOTE: JS-YAML does not support schema-specific tag resolution restrictions.
|
|
||||||
// So, Core schema has no distinctions from JSON schema is JS-YAML.
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
module.exports = require('./json')
|
|
||||||
Generated
Vendored
-20
@@ -1,20 +0,0 @@
|
|||||||
// JS-YAML's default schema for `safeLoad` function.
|
|
||||||
// It is not described in the YAML specification.
|
|
||||||
//
|
|
||||||
// This schema is based on standard YAML's Core schema and includes most of
|
|
||||||
// extra types described at YAML tag repository. (http://yaml.org/type/)
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
module.exports = require('./core').extend({
|
|
||||||
implicit: [
|
|
||||||
require('../type/timestamp'),
|
|
||||||
require('../type/merge')
|
|
||||||
],
|
|
||||||
explicit: [
|
|
||||||
require('../type/binary'),
|
|
||||||
require('../type/omap'),
|
|
||||||
require('../type/pairs'),
|
|
||||||
require('../type/set')
|
|
||||||
]
|
|
||||||
})
|
|
||||||
Generated
Vendored
-14
@@ -1,14 +0,0 @@
|
|||||||
// Standard YAML's Failsafe schema.
|
|
||||||
// http://www.yaml.org/spec/1.2/spec.html#id2802346
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const Schema = require('../schema')
|
|
||||||
|
|
||||||
module.exports = new Schema({
|
|
||||||
explicit: [
|
|
||||||
require('../type/str'),
|
|
||||||
require('../type/seq'),
|
|
||||||
require('../type/map')
|
|
||||||
]
|
|
||||||
})
|
|
||||||
Generated
Vendored
-17
@@ -1,17 +0,0 @@
|
|||||||
// Standard YAML's JSON schema.
|
|
||||||
// http://www.yaml.org/spec/1.2/spec.html#id2803231
|
|
||||||
//
|
|
||||||
// NOTE: JS-YAML does not support schema-specific tag resolution restrictions.
|
|
||||||
// So, this schema is not such strict as defined in the YAML specification.
|
|
||||||
// It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc.
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
module.exports = require('./failsafe').extend({
|
|
||||||
implicit: [
|
|
||||||
require('../type/null'),
|
|
||||||
require('../type/bool'),
|
|
||||||
require('../type/int'),
|
|
||||||
require('../type/float')
|
|
||||||
]
|
|
||||||
})
|
|
||||||
Generated
Vendored
-96
@@ -1,96 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const common = require('./common')
|
|
||||||
|
|
||||||
// get snippet for a single line, respecting maxLength
|
|
||||||
function getLine (buffer, lineStart, lineEnd, position, maxLineLength) {
|
|
||||||
let head = ''
|
|
||||||
let tail = ''
|
|
||||||
const maxHalfLength = Math.floor(maxLineLength / 2) - 1
|
|
||||||
|
|
||||||
if (position - lineStart > maxHalfLength) {
|
|
||||||
head = ' ... '
|
|
||||||
lineStart = position - maxHalfLength + head.length
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lineEnd - position > maxHalfLength) {
|
|
||||||
tail = ' ...'
|
|
||||||
lineEnd = position + maxHalfLength - tail.length
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, '→') + tail,
|
|
||||||
pos: position - lineStart + head.length // relative position
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function padStart (string, max) {
|
|
||||||
return common.repeat(' ', max - string.length) + string
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeSnippet (mark, options) {
|
|
||||||
options = Object.create(options || null)
|
|
||||||
|
|
||||||
if (!mark.buffer) return null
|
|
||||||
|
|
||||||
if (!options.maxLength) options.maxLength = 79
|
|
||||||
if (typeof options.indent !== 'number') options.indent = 1
|
|
||||||
if (typeof options.linesBefore !== 'number') options.linesBefore = 3
|
|
||||||
if (typeof options.linesAfter !== 'number') options.linesAfter = 2
|
|
||||||
|
|
||||||
const re = /\r?\n|\r|\0/g
|
|
||||||
const lineStarts = [0]
|
|
||||||
const lineEnds = []
|
|
||||||
let match
|
|
||||||
let foundLineNo = -1
|
|
||||||
|
|
||||||
while ((match = re.exec(mark.buffer))) {
|
|
||||||
lineEnds.push(match.index)
|
|
||||||
lineStarts.push(match.index + match[0].length)
|
|
||||||
|
|
||||||
if (mark.position <= match.index && foundLineNo < 0) {
|
|
||||||
foundLineNo = lineStarts.length - 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (foundLineNo < 0) foundLineNo = lineStarts.length - 1
|
|
||||||
|
|
||||||
let result = ''
|
|
||||||
const lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length
|
|
||||||
const maxLineLength = options.maxLength - (options.indent + lineNoLength + 3)
|
|
||||||
|
|
||||||
for (let i = 1; i <= options.linesBefore; i++) {
|
|
||||||
if (foundLineNo - i < 0) break
|
|
||||||
const line = getLine(
|
|
||||||
mark.buffer,
|
|
||||||
lineStarts[foundLineNo - i],
|
|
||||||
lineEnds[foundLineNo - i],
|
|
||||||
mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),
|
|
||||||
maxLineLength
|
|
||||||
)
|
|
||||||
result = common.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) +
|
|
||||||
' | ' + line.str + '\n' + result
|
|
||||||
}
|
|
||||||
|
|
||||||
const line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength)
|
|
||||||
result += common.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) +
|
|
||||||
' | ' + line.str + '\n'
|
|
||||||
result += common.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\n'
|
|
||||||
|
|
||||||
for (let i = 1; i <= options.linesAfter; i++) {
|
|
||||||
if (foundLineNo + i >= lineEnds.length) break
|
|
||||||
const line = getLine(
|
|
||||||
mark.buffer,
|
|
||||||
lineStarts[foundLineNo + i],
|
|
||||||
lineEnds[foundLineNo + i],
|
|
||||||
mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),
|
|
||||||
maxLineLength
|
|
||||||
)
|
|
||||||
result += common.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) +
|
|
||||||
' | ' + line.str + '\n'
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.replace(/\n$/, '')
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = makeSnippet
|
|
||||||
Generated
Vendored
-66
@@ -1,66 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const YAMLException = require('./exception')
|
|
||||||
|
|
||||||
const TYPE_CONSTRUCTOR_OPTIONS = [
|
|
||||||
'kind',
|
|
||||||
'multi',
|
|
||||||
'resolve',
|
|
||||||
'construct',
|
|
||||||
'instanceOf',
|
|
||||||
'predicate',
|
|
||||||
'represent',
|
|
||||||
'representName',
|
|
||||||
'defaultStyle',
|
|
||||||
'styleAliases'
|
|
||||||
]
|
|
||||||
|
|
||||||
const YAML_NODE_KINDS = [
|
|
||||||
'scalar',
|
|
||||||
'sequence',
|
|
||||||
'mapping'
|
|
||||||
]
|
|
||||||
|
|
||||||
function compileStyleAliases (map) {
|
|
||||||
const result = {}
|
|
||||||
|
|
||||||
if (map !== null) {
|
|
||||||
Object.keys(map).forEach(function (style) {
|
|
||||||
map[style].forEach(function (alias) {
|
|
||||||
result[String(alias)] = style
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
function Type (tag, options) {
|
|
||||||
options = options || {}
|
|
||||||
|
|
||||||
Object.keys(options).forEach(function (name) {
|
|
||||||
if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {
|
|
||||||
throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// TODO: Add tag format check.
|
|
||||||
this.options = options // keep original options in case user wants to extend this type later
|
|
||||||
this.tag = tag
|
|
||||||
this.kind = options['kind'] || null
|
|
||||||
this.resolve = options['resolve'] || function () { return true }
|
|
||||||
this.construct = options['construct'] || function (data) { return data }
|
|
||||||
this.instanceOf = options['instanceOf'] || null
|
|
||||||
this.predicate = options['predicate'] || null
|
|
||||||
this.represent = options['represent'] || null
|
|
||||||
this.representName = options['representName'] || null
|
|
||||||
this.defaultStyle = options['defaultStyle'] || null
|
|
||||||
this.multi = options['multi'] || false
|
|
||||||
this.styleAliases = compileStyleAliases(options['styleAliases'] || null)
|
|
||||||
|
|
||||||
if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {
|
|
||||||
throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Type
|
|
||||||
Generated
Vendored
-122
@@ -1,122 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const Type = require('../type')
|
|
||||||
|
|
||||||
// [ 64, 65, 66 ] -> [ padding, CR, LF ]
|
|
||||||
const BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'
|
|
||||||
|
|
||||||
function resolveYamlBinary (data) {
|
|
||||||
if (data === null) return false
|
|
||||||
|
|
||||||
let bitlen = 0
|
|
||||||
const max = data.length
|
|
||||||
const map = BASE64_MAP
|
|
||||||
|
|
||||||
// Convert one by one.
|
|
||||||
for (let idx = 0; idx < max; idx++) {
|
|
||||||
const code = map.indexOf(data.charAt(idx))
|
|
||||||
|
|
||||||
// Skip CR/LF
|
|
||||||
if (code > 64) continue
|
|
||||||
|
|
||||||
// Fail on illegal characters
|
|
||||||
if (code < 0) return false
|
|
||||||
|
|
||||||
bitlen += 6
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are any bits left, source was corrupted
|
|
||||||
return (bitlen % 8) === 0
|
|
||||||
}
|
|
||||||
|
|
||||||
function constructYamlBinary (data) {
|
|
||||||
const input = data.replace(/[\r\n=]/g, '') // remove CR/LF & padding to simplify scan
|
|
||||||
const max = input.length
|
|
||||||
const map = BASE64_MAP
|
|
||||||
let bits = 0
|
|
||||||
const result = []
|
|
||||||
|
|
||||||
// Collect by 6*4 bits (3 bytes)
|
|
||||||
|
|
||||||
for (let idx = 0; idx < max; idx++) {
|
|
||||||
if ((idx % 4 === 0) && idx) {
|
|
||||||
result.push((bits >> 16) & 0xFF)
|
|
||||||
result.push((bits >> 8) & 0xFF)
|
|
||||||
result.push(bits & 0xFF)
|
|
||||||
}
|
|
||||||
|
|
||||||
bits = (bits << 6) | map.indexOf(input.charAt(idx))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dump tail
|
|
||||||
|
|
||||||
const tailbits = (max % 4) * 6
|
|
||||||
|
|
||||||
if (tailbits === 0) {
|
|
||||||
result.push((bits >> 16) & 0xFF)
|
|
||||||
result.push((bits >> 8) & 0xFF)
|
|
||||||
result.push(bits & 0xFF)
|
|
||||||
} else if (tailbits === 18) {
|
|
||||||
result.push((bits >> 10) & 0xFF)
|
|
||||||
result.push((bits >> 2) & 0xFF)
|
|
||||||
} else if (tailbits === 12) {
|
|
||||||
result.push((bits >> 4) & 0xFF)
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Uint8Array(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
function representYamlBinary (object /*, style */) {
|
|
||||||
let result = ''
|
|
||||||
let bits = 0
|
|
||||||
const max = object.length
|
|
||||||
const map = BASE64_MAP
|
|
||||||
|
|
||||||
// Convert every three bytes to 4 ASCII characters.
|
|
||||||
|
|
||||||
for (let idx = 0; idx < max; idx++) {
|
|
||||||
if ((idx % 3 === 0) && idx) {
|
|
||||||
result += map[(bits >> 18) & 0x3F]
|
|
||||||
result += map[(bits >> 12) & 0x3F]
|
|
||||||
result += map[(bits >> 6) & 0x3F]
|
|
||||||
result += map[bits & 0x3F]
|
|
||||||
}
|
|
||||||
|
|
||||||
bits = (bits << 8) + object[idx]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dump tail
|
|
||||||
|
|
||||||
const tail = max % 3
|
|
||||||
|
|
||||||
if (tail === 0) {
|
|
||||||
result += map[(bits >> 18) & 0x3F]
|
|
||||||
result += map[(bits >> 12) & 0x3F]
|
|
||||||
result += map[(bits >> 6) & 0x3F]
|
|
||||||
result += map[bits & 0x3F]
|
|
||||||
} else if (tail === 2) {
|
|
||||||
result += map[(bits >> 10) & 0x3F]
|
|
||||||
result += map[(bits >> 4) & 0x3F]
|
|
||||||
result += map[(bits << 2) & 0x3F]
|
|
||||||
result += map[64]
|
|
||||||
} else if (tail === 1) {
|
|
||||||
result += map[(bits >> 2) & 0x3F]
|
|
||||||
result += map[(bits << 4) & 0x3F]
|
|
||||||
result += map[64]
|
|
||||||
result += map[64]
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
function isBinary (obj) {
|
|
||||||
return Object.prototype.toString.call(obj) === '[object Uint8Array]'
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new Type('tag:yaml.org,2002:binary', {
|
|
||||||
kind: 'scalar',
|
|
||||||
resolve: resolveYamlBinary,
|
|
||||||
construct: constructYamlBinary,
|
|
||||||
predicate: isBinary,
|
|
||||||
represent: representYamlBinary
|
|
||||||
})
|
|
||||||
Generated
Vendored
-35
@@ -1,35 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const Type = require('../type')
|
|
||||||
|
|
||||||
function resolveYamlBoolean (data) {
|
|
||||||
if (data === null) return false
|
|
||||||
|
|
||||||
const max = data.length
|
|
||||||
|
|
||||||
return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||
|
|
||||||
(max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'))
|
|
||||||
}
|
|
||||||
|
|
||||||
function constructYamlBoolean (data) {
|
|
||||||
return data === 'true' ||
|
|
||||||
data === 'True' ||
|
|
||||||
data === 'TRUE'
|
|
||||||
}
|
|
||||||
|
|
||||||
function isBoolean (object) {
|
|
||||||
return Object.prototype.toString.call(object) === '[object Boolean]'
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new Type('tag:yaml.org,2002:bool', {
|
|
||||||
kind: 'scalar',
|
|
||||||
resolve: resolveYamlBoolean,
|
|
||||||
construct: constructYamlBoolean,
|
|
||||||
predicate: isBoolean,
|
|
||||||
represent: {
|
|
||||||
lowercase: function (object) { return object ? 'true' : 'false' },
|
|
||||||
uppercase: function (object) { return object ? 'TRUE' : 'FALSE' },
|
|
||||||
camelcase: function (object) { return object ? 'True' : 'False' }
|
|
||||||
},
|
|
||||||
defaultStyle: 'lowercase'
|
|
||||||
})
|
|
||||||
Generated
Vendored
-99
@@ -1,99 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const common = require('../common')
|
|
||||||
const Type = require('../type')
|
|
||||||
|
|
||||||
const YAML_FLOAT_PATTERN = new RegExp(
|
|
||||||
// 2.5e4, 2.5 and integers
|
|
||||||
'^(?:[-+]?(?:[0-9]+)(?:\\.[0-9]*)?(?:[eE][-+]?[0-9]+)?' +
|
|
||||||
// .2e4, .2
|
|
||||||
// special case, seems not from spec
|
|
||||||
'|\\.[0-9]+(?:[eE][-+]?[0-9]+)?' +
|
|
||||||
// .inf
|
|
||||||
'|[-+]?\\.(?:inf|Inf|INF)' +
|
|
||||||
// .nan
|
|
||||||
'|\\.(?:nan|NaN|NAN))$')
|
|
||||||
|
|
||||||
const YAML_FLOAT_SPECIAL_PATTERN = new RegExp(
|
|
||||||
'^(?:' +
|
|
||||||
// .inf
|
|
||||||
'[-+]?\\.(?:inf|Inf|INF)' +
|
|
||||||
// .nan
|
|
||||||
'|\\.(?:nan|NaN|NAN))$')
|
|
||||||
|
|
||||||
function resolveYamlFloat (data) {
|
|
||||||
if (data === null) return false
|
|
||||||
|
|
||||||
if (!YAML_FLOAT_PATTERN.test(data)) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Number.isFinite(parseFloat(data, 10))) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return YAML_FLOAT_SPECIAL_PATTERN.test(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
function constructYamlFloat (data) {
|
|
||||||
let value = data.toLowerCase()
|
|
||||||
const sign = value[0] === '-' ? -1 : 1
|
|
||||||
|
|
||||||
if ('+-'.indexOf(value[0]) >= 0) {
|
|
||||||
value = value.slice(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value === '.inf') {
|
|
||||||
return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY
|
|
||||||
} else if (value === '.nan') {
|
|
||||||
return NaN
|
|
||||||
}
|
|
||||||
return sign * parseFloat(value, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
const SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/
|
|
||||||
|
|
||||||
function representYamlFloat (object, style) {
|
|
||||||
if (isNaN(object)) {
|
|
||||||
switch (style) {
|
|
||||||
case 'lowercase': return '.nan'
|
|
||||||
case 'uppercase': return '.NAN'
|
|
||||||
case 'camelcase': return '.NaN'
|
|
||||||
}
|
|
||||||
} else if (Number.POSITIVE_INFINITY === object) {
|
|
||||||
switch (style) {
|
|
||||||
case 'lowercase': return '.inf'
|
|
||||||
case 'uppercase': return '.INF'
|
|
||||||
case 'camelcase': return '.Inf'
|
|
||||||
}
|
|
||||||
} else if (Number.NEGATIVE_INFINITY === object) {
|
|
||||||
switch (style) {
|
|
||||||
case 'lowercase': return '-.inf'
|
|
||||||
case 'uppercase': return '-.INF'
|
|
||||||
case 'camelcase': return '-.Inf'
|
|
||||||
}
|
|
||||||
} else if (common.isNegativeZero(object)) {
|
|
||||||
return '-0.0'
|
|
||||||
}
|
|
||||||
|
|
||||||
const res = object.toString(10)
|
|
||||||
|
|
||||||
// JS stringifier can build scientific format without dots: 5e-100,
|
|
||||||
// while YAML requres dot: 5.e-100. Fix it with simple hack
|
|
||||||
|
|
||||||
return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res
|
|
||||||
}
|
|
||||||
|
|
||||||
function isFloat (object) {
|
|
||||||
return (Object.prototype.toString.call(object) === '[object Number]') &&
|
|
||||||
(object % 1 !== 0 || common.isNegativeZero(object))
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new Type('tag:yaml.org,2002:float', {
|
|
||||||
kind: 'scalar',
|
|
||||||
resolve: resolveYamlFloat,
|
|
||||||
construct: constructYamlFloat,
|
|
||||||
predicate: isFloat,
|
|
||||||
represent: representYamlFloat,
|
|
||||||
defaultStyle: 'lowercase'
|
|
||||||
})
|
|
||||||
Generated
Vendored
-142
@@ -1,142 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const common = require('../common')
|
|
||||||
const Type = require('../type')
|
|
||||||
|
|
||||||
function isHexCode (c) {
|
|
||||||
return ((c >= 0x30/* 0 */) && (c <= 0x39/* 9 */)) ||
|
|
||||||
((c >= 0x41/* A */) && (c <= 0x46/* F */)) ||
|
|
||||||
((c >= 0x61/* a */) && (c <= 0x66/* f */))
|
|
||||||
}
|
|
||||||
|
|
||||||
function isOctCode (c) {
|
|
||||||
return ((c >= 0x30/* 0 */) && (c <= 0x37/* 7 */))
|
|
||||||
}
|
|
||||||
|
|
||||||
function isDecCode (c) {
|
|
||||||
return ((c >= 0x30/* 0 */) && (c <= 0x39/* 9 */))
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveYamlInteger (data) {
|
|
||||||
if (data === null) return false
|
|
||||||
|
|
||||||
const max = data.length
|
|
||||||
let index = 0
|
|
||||||
let hasDigits = false
|
|
||||||
|
|
||||||
if (!max) return false
|
|
||||||
|
|
||||||
let ch = data[index]
|
|
||||||
|
|
||||||
// sign
|
|
||||||
if (ch === '-' || ch === '+') {
|
|
||||||
ch = data[++index]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch === '0') {
|
|
||||||
// 0
|
|
||||||
if (index + 1 === max) return true
|
|
||||||
ch = data[++index]
|
|
||||||
|
|
||||||
// base 2, base 8, base 16
|
|
||||||
|
|
||||||
if (ch === 'b') {
|
|
||||||
// base 2
|
|
||||||
index++
|
|
||||||
|
|
||||||
for (; index < max; index++) {
|
|
||||||
ch = data[index]
|
|
||||||
if (ch !== '0' && ch !== '1') return false
|
|
||||||
hasDigits = true
|
|
||||||
}
|
|
||||||
return hasDigits && Number.isFinite(parseYamlInteger(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch === 'x') {
|
|
||||||
// base 16
|
|
||||||
index++
|
|
||||||
|
|
||||||
for (; index < max; index++) {
|
|
||||||
if (!isHexCode(data.charCodeAt(index))) return false
|
|
||||||
hasDigits = true
|
|
||||||
}
|
|
||||||
return hasDigits && Number.isFinite(parseYamlInteger(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ch === 'o') {
|
|
||||||
// base 8
|
|
||||||
index++
|
|
||||||
|
|
||||||
for (; index < max; index++) {
|
|
||||||
if (!isOctCode(data.charCodeAt(index))) return false
|
|
||||||
hasDigits = true
|
|
||||||
}
|
|
||||||
return hasDigits && Number.isFinite(parseYamlInteger(data))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// base 10 (except 0)
|
|
||||||
|
|
||||||
for (; index < max; index++) {
|
|
||||||
if (!isDecCode(data.charCodeAt(index))) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
hasDigits = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasDigits) return false
|
|
||||||
|
|
||||||
return Number.isFinite(parseYamlInteger(data))
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseYamlInteger (data) {
|
|
||||||
let value = data
|
|
||||||
let sign = 1
|
|
||||||
|
|
||||||
let ch = value[0]
|
|
||||||
|
|
||||||
if (ch === '-' || ch === '+') {
|
|
||||||
if (ch === '-') sign = -1
|
|
||||||
value = value.slice(1)
|
|
||||||
ch = value[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value === '0') return 0
|
|
||||||
|
|
||||||
if (ch === '0') {
|
|
||||||
if (value[1] === 'b') return sign * parseInt(value.slice(2), 2)
|
|
||||||
if (value[1] === 'x') return sign * parseInt(value.slice(2), 16)
|
|
||||||
if (value[1] === 'o') return sign * parseInt(value.slice(2), 8)
|
|
||||||
}
|
|
||||||
|
|
||||||
return sign * parseInt(value, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
function constructYamlInteger (data) {
|
|
||||||
return parseYamlInteger(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
function isInteger (object) {
|
|
||||||
return (Object.prototype.toString.call(object)) === '[object Number]' &&
|
|
||||||
(object % 1 === 0 && !common.isNegativeZero(object))
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new Type('tag:yaml.org,2002:int', {
|
|
||||||
kind: 'scalar',
|
|
||||||
resolve: resolveYamlInteger,
|
|
||||||
construct: constructYamlInteger,
|
|
||||||
predicate: isInteger,
|
|
||||||
represent: {
|
|
||||||
binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1) },
|
|
||||||
octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1) },
|
|
||||||
decimal: function (obj) { return obj.toString(10) },
|
|
||||||
hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1) }
|
|
||||||
},
|
|
||||||
defaultStyle: 'decimal',
|
|
||||||
styleAliases: {
|
|
||||||
binary: [2, 'bin'],
|
|
||||||
octal: [8, 'oct'],
|
|
||||||
decimal: [10, 'dec'],
|
|
||||||
hexadecimal: [16, 'hex']
|
|
||||||
}
|
|
||||||
})
|
|
||||||
Generated
Vendored
-8
@@ -1,8 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const Type = require('../type')
|
|
||||||
|
|
||||||
module.exports = new Type('tag:yaml.org,2002:map', {
|
|
||||||
kind: 'mapping',
|
|
||||||
construct: function (data) { return data !== null ? data : {} }
|
|
||||||
})
|
|
||||||
Generated
Vendored
-12
@@ -1,12 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const Type = require('../type')
|
|
||||||
|
|
||||||
function resolveYamlMerge (data) {
|
|
||||||
return data === '<<' || data === null
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new Type('tag:yaml.org,2002:merge', {
|
|
||||||
kind: 'scalar',
|
|
||||||
resolve: resolveYamlMerge
|
|
||||||
})
|
|
||||||
Generated
Vendored
-35
@@ -1,35 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const Type = require('../type')
|
|
||||||
|
|
||||||
function resolveYamlNull (data) {
|
|
||||||
if (data === null) return true
|
|
||||||
|
|
||||||
const max = data.length
|
|
||||||
|
|
||||||
return (max === 1 && data === '~') ||
|
|
||||||
(max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'))
|
|
||||||
}
|
|
||||||
|
|
||||||
function constructYamlNull () {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
function isNull (object) {
|
|
||||||
return object === null
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new Type('tag:yaml.org,2002:null', {
|
|
||||||
kind: 'scalar',
|
|
||||||
resolve: resolveYamlNull,
|
|
||||||
construct: constructYamlNull,
|
|
||||||
predicate: isNull,
|
|
||||||
represent: {
|
|
||||||
canonical: function () { return '~' },
|
|
||||||
lowercase: function () { return 'null' },
|
|
||||||
uppercase: function () { return 'NULL' },
|
|
||||||
camelcase: function () { return 'Null' },
|
|
||||||
empty: function () { return '' }
|
|
||||||
},
|
|
||||||
defaultStyle: 'lowercase'
|
|
||||||
})
|
|
||||||
Generated
Vendored
-45
@@ -1,45 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const Type = require('../type')
|
|
||||||
|
|
||||||
const _hasOwnProperty = Object.prototype.hasOwnProperty
|
|
||||||
const _toString = Object.prototype.toString
|
|
||||||
|
|
||||||
function resolveYamlOmap (data) {
|
|
||||||
if (data === null) return true
|
|
||||||
|
|
||||||
const objectKeys = []
|
|
||||||
const object = data
|
|
||||||
|
|
||||||
for (let index = 0, length = object.length; index < length; index += 1) {
|
|
||||||
const pair = object[index]
|
|
||||||
let pairHasKey = false
|
|
||||||
|
|
||||||
if (_toString.call(pair) !== '[object Object]') return false
|
|
||||||
|
|
||||||
let pairKey
|
|
||||||
for (pairKey in pair) {
|
|
||||||
if (_hasOwnProperty.call(pair, pairKey)) {
|
|
||||||
if (!pairHasKey) pairHasKey = true
|
|
||||||
else return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pairHasKey) return false
|
|
||||||
|
|
||||||
if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey)
|
|
||||||
else return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
function constructYamlOmap (data) {
|
|
||||||
return data !== null ? data : []
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new Type('tag:yaml.org,2002:omap', {
|
|
||||||
kind: 'sequence',
|
|
||||||
resolve: resolveYamlOmap,
|
|
||||||
construct: constructYamlOmap
|
|
||||||
})
|
|
||||||
Generated
Vendored
-50
@@ -1,50 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const Type = require('../type')
|
|
||||||
|
|
||||||
const _toString = Object.prototype.toString
|
|
||||||
|
|
||||||
function resolveYamlPairs (data) {
|
|
||||||
if (data === null) return true
|
|
||||||
|
|
||||||
const object = data
|
|
||||||
|
|
||||||
const result = new Array(object.length)
|
|
||||||
|
|
||||||
for (let index = 0, length = object.length; index < length; index += 1) {
|
|
||||||
const pair = object[index]
|
|
||||||
|
|
||||||
if (_toString.call(pair) !== '[object Object]') return false
|
|
||||||
|
|
||||||
const keys = Object.keys(pair)
|
|
||||||
|
|
||||||
if (keys.length !== 1) return false
|
|
||||||
|
|
||||||
result[index] = [keys[0], pair[keys[0]]]
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
function constructYamlPairs (data) {
|
|
||||||
if (data === null) return []
|
|
||||||
|
|
||||||
const object = data
|
|
||||||
const result = new Array(object.length)
|
|
||||||
|
|
||||||
for (let index = 0, length = object.length; index < length; index += 1) {
|
|
||||||
const pair = object[index]
|
|
||||||
|
|
||||||
const keys = Object.keys(pair)
|
|
||||||
|
|
||||||
result[index] = [keys[0], pair[keys[0]]]
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new Type('tag:yaml.org,2002:pairs', {
|
|
||||||
kind: 'sequence',
|
|
||||||
resolve: resolveYamlPairs,
|
|
||||||
construct: constructYamlPairs
|
|
||||||
})
|
|
||||||
Generated
Vendored
-8
@@ -1,8 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const Type = require('../type')
|
|
||||||
|
|
||||||
module.exports = new Type('tag:yaml.org,2002:seq', {
|
|
||||||
kind: 'sequence',
|
|
||||||
construct: function (data) { return data !== null ? data : [] }
|
|
||||||
})
|
|
||||||
Generated
Vendored
-29
@@ -1,29 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const Type = require('../type')
|
|
||||||
|
|
||||||
const _hasOwnProperty = Object.prototype.hasOwnProperty
|
|
||||||
|
|
||||||
function resolveYamlSet (data) {
|
|
||||||
if (data === null) return true
|
|
||||||
|
|
||||||
const object = data
|
|
||||||
|
|
||||||
for (const key in object) {
|
|
||||||
if (_hasOwnProperty.call(object, key)) {
|
|
||||||
if (object[key] !== null) return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
function constructYamlSet (data) {
|
|
||||||
return data !== null ? data : {}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new Type('tag:yaml.org,2002:set', {
|
|
||||||
kind: 'mapping',
|
|
||||||
resolve: resolveYamlSet,
|
|
||||||
construct: constructYamlSet
|
|
||||||
})
|
|
||||||
Generated
Vendored
-8
@@ -1,8 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const Type = require('../type')
|
|
||||||
|
|
||||||
module.exports = new Type('tag:yaml.org,2002:str', {
|
|
||||||
kind: 'scalar',
|
|
||||||
construct: function (data) { return data !== null ? data : '' }
|
|
||||||
})
|
|
||||||
Generated
Vendored
-88
@@ -1,88 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const Type = require('../type')
|
|
||||||
|
|
||||||
const YAML_DATE_REGEXP = new RegExp(
|
|
||||||
'^([0-9][0-9][0-9][0-9])' + // [1] year
|
|
||||||
'-([0-9][0-9])' + // [2] month
|
|
||||||
'-([0-9][0-9])$') // [3] day
|
|
||||||
|
|
||||||
const YAML_TIMESTAMP_REGEXP = new RegExp(
|
|
||||||
'^([0-9][0-9][0-9][0-9])' + // [1] year
|
|
||||||
'-([0-9][0-9]?)' + // [2] month
|
|
||||||
'-([0-9][0-9]?)' + // [3] day
|
|
||||||
'(?:[Tt]|[ \\t]+)' + // ...
|
|
||||||
'([0-9][0-9]?)' + // [4] hour
|
|
||||||
':([0-9][0-9])' + // [5] minute
|
|
||||||
':([0-9][0-9])' + // [6] second
|
|
||||||
'(?:\\.([0-9]*))?' + // [7] fraction
|
|
||||||
'(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tzHour
|
|
||||||
'(?::([0-9][0-9]))?))?$') // [11] tzMinute
|
|
||||||
|
|
||||||
function resolveYamlTimestamp (data) {
|
|
||||||
if (data === null) return false
|
|
||||||
if (YAML_DATE_REGEXP.exec(data) !== null) return true
|
|
||||||
if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
function constructYamlTimestamp (data) {
|
|
||||||
let fraction = 0
|
|
||||||
let delta = null
|
|
||||||
|
|
||||||
let match = YAML_DATE_REGEXP.exec(data)
|
|
||||||
if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data)
|
|
||||||
|
|
||||||
if (match === null) throw new Error('Date resolve error')
|
|
||||||
|
|
||||||
// match: [1] year [2] month [3] day
|
|
||||||
|
|
||||||
const year = +(match[1])
|
|
||||||
const month = +(match[2]) - 1 // JS month starts with 0
|
|
||||||
const day = +(match[3])
|
|
||||||
|
|
||||||
if (!match[4]) { // no hour
|
|
||||||
return new Date(Date.UTC(year, month, day))
|
|
||||||
}
|
|
||||||
|
|
||||||
// match: [4] hour [5] minute [6] second [7] fraction
|
|
||||||
|
|
||||||
const hour = +(match[4])
|
|
||||||
const minute = +(match[5])
|
|
||||||
const second = +(match[6])
|
|
||||||
|
|
||||||
if (match[7]) {
|
|
||||||
fraction = match[7].slice(0, 3)
|
|
||||||
while (fraction.length < 3) { // milli-seconds
|
|
||||||
fraction += '0'
|
|
||||||
}
|
|
||||||
fraction = +fraction
|
|
||||||
}
|
|
||||||
|
|
||||||
// match: [8] tz [9] tz_sign [10] tzHour [11] tzMinute
|
|
||||||
|
|
||||||
if (match[9]) {
|
|
||||||
const tzHour = +(match[10])
|
|
||||||
const tzMinute = +(match[11] || 0)
|
|
||||||
delta = (tzHour * 60 + tzMinute) * 60000 // delta in mili-seconds
|
|
||||||
if (match[9] === '-') delta = -delta
|
|
||||||
}
|
|
||||||
|
|
||||||
const date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction))
|
|
||||||
|
|
||||||
if (delta) date.setTime(date.getTime() - delta)
|
|
||||||
|
|
||||||
return date
|
|
||||||
}
|
|
||||||
|
|
||||||
function representYamlTimestamp (object /*, style */) {
|
|
||||||
return object.toISOString()
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new Type('tag:yaml.org,2002:timestamp', {
|
|
||||||
kind: 'scalar',
|
|
||||||
resolve: resolveYamlTimestamp,
|
|
||||||
construct: constructYamlTimestamp,
|
|
||||||
instanceOf: Date,
|
|
||||||
represent: representYamlTimestamp
|
|
||||||
})
|
|
||||||
Generated
Vendored
-77
@@ -1,77 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "js-yaml",
|
|
||||||
"version": "4.2.0",
|
|
||||||
"description": "YAML 1.2 parser and serializer",
|
|
||||||
"keywords": [
|
|
||||||
"yaml",
|
|
||||||
"parser",
|
|
||||||
"serializer",
|
|
||||||
"pyyaml"
|
|
||||||
],
|
|
||||||
"author": "Vladimir Zapparov <dervus.grim@gmail.com>",
|
|
||||||
"contributors": [
|
|
||||||
"Aleksey V Zapparov <ixti@member.fsf.org> (http://www.ixti.net/)",
|
|
||||||
"Vitaly Puzrin <vitaly@rcdesign.ru> (https://github.com/puzrin)",
|
|
||||||
"Martin Grenfell <martin.grenfell@gmail.com> (http://got-ravings.blogspot.com)"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"repository": "nodeca/js-yaml",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/puzrin"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/nodeca"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"files": [
|
|
||||||
"index.js",
|
|
||||||
"lib/",
|
|
||||||
"bin/",
|
|
||||||
"dist/"
|
|
||||||
],
|
|
||||||
"bin": {
|
|
||||||
"js-yaml": "bin/js-yaml.js"
|
|
||||||
},
|
|
||||||
"module": "./dist/js-yaml.mjs",
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"import": "./dist/js-yaml.mjs",
|
|
||||||
"require": "./index.js"
|
|
||||||
},
|
|
||||||
"./package.json": "./package.json"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"lint": "eslint .",
|
|
||||||
"lint-fix": "eslint . --fix",
|
|
||||||
"test": "npm run lint && npm run test:core && npm run test:build",
|
|
||||||
"test:core": "node --test test/core/*.test.*",
|
|
||||||
"test:build": "npm run build && node --test test/build/*.test.*",
|
|
||||||
"coverage": "npm run build && c8 --include 'lib/**' -r text -r html -r lcov node --test test/core/*.test.*",
|
|
||||||
"build": "node support/build-dist.mjs",
|
|
||||||
"build:demo": "npm run lint && node support/build_demo.mjs",
|
|
||||||
"gh-demo": "npm run build:demo && gh-pages -d demo -f",
|
|
||||||
"prepack": "npm test && npm run build && npm run build:demo",
|
|
||||||
"postpublish": "npm run gh-demo"
|
|
||||||
},
|
|
||||||
"unpkg": "dist/js-yaml.min.js",
|
|
||||||
"jsdelivr": "dist/js-yaml.min.js",
|
|
||||||
"dependencies": {
|
|
||||||
"argparse": "^2.0.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"c8": "^11.0.0",
|
|
||||||
"codemirror": "^5.65.21",
|
|
||||||
"eslint": "^9.39.4",
|
|
||||||
"fast-check": "^4.8.0",
|
|
||||||
"gh-pages": "^6.3.0",
|
|
||||||
"neostandard": "^0.13.0",
|
|
||||||
"tinybench": "^6.0.2",
|
|
||||||
"vite": "^8.0.14",
|
|
||||||
"vite-plugin-node-polyfills": "^0.28.0",
|
|
||||||
"vite-plugin-singlefile": "^2.3.3",
|
|
||||||
"workerpool": "^10.0.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-105
@@ -1,105 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@apidevtools/json-schema-ref-parser",
|
|
||||||
"version": "9.1.2",
|
|
||||||
"description": "Parse, Resolve, and Dereference JSON Schema $ref pointers",
|
|
||||||
"keywords": [
|
|
||||||
"json",
|
|
||||||
"schema",
|
|
||||||
"jsonschema",
|
|
||||||
"json-schema",
|
|
||||||
"json-pointer",
|
|
||||||
"$ref",
|
|
||||||
"dereference",
|
|
||||||
"resolve"
|
|
||||||
],
|
|
||||||
"author": {
|
|
||||||
"name": "James Messinger",
|
|
||||||
"url": "https://jamesmessinger.com"
|
|
||||||
},
|
|
||||||
"contributors": [
|
|
||||||
{
|
|
||||||
"name": "Boris Cherny",
|
|
||||||
"email": "boris@performancejs.com"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Jakub Rożek",
|
|
||||||
"email": "jakub@stoplight.io"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"homepage": "https://apitools.dev/json-schema-ref-parser/",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/APIDevTools/json-schema-ref-parser.git"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"main": "lib/index.js",
|
|
||||||
"typings": "lib/index.d.ts",
|
|
||||||
"browser": {
|
|
||||||
"fs": false
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"lib"
|
|
||||||
],
|
|
||||||
"scripts": {
|
|
||||||
"build": "cp LICENSE *.md dist",
|
|
||||||
"clean": "shx rm -rf .nyc_output coverage",
|
|
||||||
"lint": "eslint lib test/fixtures test/specs",
|
|
||||||
"test": "npm run test:node && npm run test:typescript && npm run test:browser && npm run lint",
|
|
||||||
"test:node": "mocha",
|
|
||||||
"test:browser": "karma start --single-run",
|
|
||||||
"test:typescript": "tsc --noEmit --strict --lib esnext,dom test/specs/typescript-definition.spec.ts",
|
|
||||||
"coverage": "npm run coverage:node && npm run coverage:browser",
|
|
||||||
"coverage:node": "nyc node_modules/mocha/bin/mocha",
|
|
||||||
"coverage:browser": "npm run test:browser -- --coverage",
|
|
||||||
"upgrade": "npm-check -u && npm audit fix"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@babel/polyfill": "^7.12.1",
|
|
||||||
"@jsdevtools/eslint-config": "^1.0.7",
|
|
||||||
"@jsdevtools/host-environment": "^2.1.2",
|
|
||||||
"@jsdevtools/karma-config": "^3.1.7",
|
|
||||||
"@types/node": "^14.14.21",
|
|
||||||
"chai": "^4.2.0",
|
|
||||||
"chai-subset": "^1.6.0",
|
|
||||||
"eslint": "^7.18.0",
|
|
||||||
"karma": "^5.0.2",
|
|
||||||
"karma-cli": "^2.0.0",
|
|
||||||
"mocha": "^8.2.1",
|
|
||||||
"npm-check": "^5.9.0",
|
|
||||||
"nyc": "^15.0.1",
|
|
||||||
"semantic-release-plugin-update-version-in-files": "^1.1.0",
|
|
||||||
"shx": "^0.3.2",
|
|
||||||
"typescript": "^4.0.5"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@jsdevtools/ono": "^7.1.3",
|
|
||||||
"@types/json-schema": "^7.0.6",
|
|
||||||
"call-me-maybe": "^1.0.1",
|
|
||||||
"js-yaml": "^4.1.0"
|
|
||||||
},
|
|
||||||
"release": {
|
|
||||||
"branches": [
|
|
||||||
"main",
|
|
||||||
"v9",
|
|
||||||
{
|
|
||||||
"name": "v9.1.x",
|
|
||||||
"range": "9.1.x"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"plugins": [
|
|
||||||
"@semantic-release/commit-analyzer",
|
|
||||||
"@semantic-release/release-notes-generator",
|
|
||||||
[
|
|
||||||
"semantic-release-plugin-update-version-in-files",
|
|
||||||
{
|
|
||||||
"files": [
|
|
||||||
"dist/package.json"
|
|
||||||
],
|
|
||||||
"placeholder": "X.X.X"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"@semantic-release/npm",
|
|
||||||
"@semantic-release/github"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-201
@@ -1,201 +0,0 @@
|
|||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright The Linux Foundation
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
-108
@@ -1,108 +0,0 @@
|
|||||||
[](https://www.asyncapi.com)
|
|
||||||
|
|
||||||
AsyncAPI React SDK is a set of components/functions to use React as render engine in the [Generator](https://github.com/asyncapi/generator).
|
|
||||||
|
|
||||||
<!-- toc is generated with GitHub Actions do not remove toc markers -->
|
|
||||||
|
|
||||||
<!-- toc -->
|
|
||||||
|
|
||||||
- [Installation](#installation)
|
|
||||||
- [How it works](#how-it-works)
|
|
||||||
* [The Transpile Process](#the-transpile-process)
|
|
||||||
* [The Rendering Process](#the-rendering-process)
|
|
||||||
+ [Requirements](#requirements)
|
|
||||||
- [The debug flag](#the-debug-flag)
|
|
||||||
- [Example](#example)
|
|
||||||
- [Resources](#resources)
|
|
||||||
- [Development](#development)
|
|
||||||
- [Contributing](#contributing)
|
|
||||||
|
|
||||||
<!-- tocstop -->
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Run this command to install the SDK in your project:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm install --save @asyncapi/generator-react-sdk
|
|
||||||
```
|
|
||||||
|
|
||||||
## How it works
|
|
||||||
|
|
||||||
The process of creating content from React components consists of two main process: transpile and rendering.
|
|
||||||
|
|
||||||
### The Transpile Process
|
|
||||||
|
|
||||||
The SDK has a custom transpiler which ensures that any directory are transpiled using [Rollup](https://www.npmjs.com/package/rollup). Rollup helps bundling all dependencies and transpile them into CommonJS modules. This is required because this library will be used through NodeJS which does not understand these new modules natively and we do not want to limit the developer in which syntax they prefer nor how they want to separate code.
|
|
||||||
|
|
||||||
### The Rendering Process
|
|
||||||
|
|
||||||
SDK has its own reconciler for React components. It traverses through each element in the template structure and transforms it into a pure string. Additionally, prop `children` is also converted to a regular string and stored in the` childrenContent` prop, which is appended to each component. See [example](#example).
|
|
||||||
|
|
||||||
Restrictions:
|
|
||||||
|
|
||||||
- React hooks is not allowed.
|
|
||||||
- HTML tags at the moment is not supported.
|
|
||||||
- React internal components like Fragments, Suspense etc. are skipped.
|
|
||||||
|
|
||||||
#### Requirements
|
|
||||||
|
|
||||||
To render the transpiled template SDK requires:
|
|
||||||
|
|
||||||
* Node.js v12.16 and higher
|
|
||||||
|
|
||||||
## The debug flag
|
|
||||||
|
|
||||||
When rendering you have the option of passing a `debug` flag which does not remove the transpiled files after the rendering process is done.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { Text, Indent, IndentationTypes, render } from '@asyncapi/generator-react-sdk';
|
|
||||||
|
|
||||||
class ClassComponent extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
// In `childrenContent` prop is stored `text wrapped by custom component\n\n`.
|
|
||||||
// The content of the `children` prop is transformed to string and saved to the `childrenContent` prop.
|
|
||||||
return this.props.childrenContent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function FunctionComponent() {
|
|
||||||
return (
|
|
||||||
<Indent size={3} type={IndentationTypes.TABS}>
|
|
||||||
indented text
|
|
||||||
<ClassComponent>
|
|
||||||
<Text newLines={2}>
|
|
||||||
text wrapped by custom component
|
|
||||||
</Text>
|
|
||||||
</ClassComponent>
|
|
||||||
</Indent>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// content will be `\t\t\tindented text text wrapped by custom component\n\n`
|
|
||||||
const content = render(<FunctionComponent />);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Resources
|
|
||||||
|
|
||||||
- [`template-for-generator-templates`](https://github.com/asyncapi/template-for-generator-templates) template showcases features of [the AsyncAPI Generator](https://github.com/asyncapi/generator), including the React renderer. It shows how to write templates, reusable parts (components), what are the recommended patterns. It has simple and complex examples of using `React`.
|
|
||||||
- [`markdown-template`](https://github.com/asyncapi/markdown-template) is written using React. It generates documentation into a Markdown file.
|
|
||||||
|
|
||||||
For more help join our [Slack](https://www.asyncapi.com/slack-invite/) workspace.
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
1. Setup project by installing dependencies `npm install`
|
|
||||||
2. Write code and tests.
|
|
||||||
3. Make sure all tests pass `npm test`
|
|
||||||
4. Make sure code is well formatted and secure `npm run lint`
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Read [CONTRIBUTING](https://github.com/asyncapi/.github/blob/master/CONTRIBUTING.md) guide.
|
|
||||||
Generated
Vendored
-35
@@ -1,35 +0,0 @@
|
|||||||
import PropTypes from 'prop-types';
|
|
||||||
import { FunctionComponent } from "../types";
|
|
||||||
export interface FileProps {
|
|
||||||
/**
|
|
||||||
* `name` prop describes the filename for which should be used when generating the file. If none is specified the filename for the template are used.
|
|
||||||
*/
|
|
||||||
name?: string;
|
|
||||||
/**
|
|
||||||
* `permissions` prop describes the permissions the file should be created with. This is interpreted as an octal number such as 0o777
|
|
||||||
*/
|
|
||||||
permissions?: number;
|
|
||||||
}
|
|
||||||
export declare const FilePropTypes: {
|
|
||||||
/**
|
|
||||||
* `name` prop describes the filename for which should be used when generating the file. If none is specified the filename for the template are used.
|
|
||||||
*/
|
|
||||||
name: PropTypes.Requireable<string>;
|
|
||||||
/**
|
|
||||||
* `permissions` prop describes the permissions the file should be created with. This is interpreted as an octal number such as 0o777
|
|
||||||
*/
|
|
||||||
permissions: PropTypes.Requireable<number>;
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Component is used to describe to the generator that you want a file to be created and rendered based on the defined children.
|
|
||||||
*
|
|
||||||
* @component
|
|
||||||
* @example
|
|
||||||
* const name = "test.js"
|
|
||||||
* const permissions = 0o777
|
|
||||||
* return (
|
|
||||||
* <File name={name} permissions={permissions}>Test</File>
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
declare const File: FunctionComponent<FileProps>;
|
|
||||||
export default File;
|
|
||||||
Generated
Vendored
-47
@@ -1,47 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __assign = (this && this.__assign) || function () {
|
|
||||||
__assign = Object.assign || function(t) {
|
|
||||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
||||||
s = arguments[i];
|
|
||||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
||||||
t[p] = s[p];
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
};
|
|
||||||
return __assign.apply(this, arguments);
|
|
||||||
};
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.FilePropTypes = void 0;
|
|
||||||
var jsx_runtime_1 = require("react/jsx-runtime");
|
|
||||||
var prop_types_1 = __importDefault(require("prop-types"));
|
|
||||||
exports.FilePropTypes = {
|
|
||||||
/**
|
|
||||||
* `name` prop describes the filename for which should be used when generating the file. If none is specified the filename for the template are used.
|
|
||||||
*/
|
|
||||||
name: prop_types_1.default.string,
|
|
||||||
/**
|
|
||||||
* `permissions` prop describes the permissions the file should be created with. This is interpreted as an octal number such as 0o777
|
|
||||||
*/
|
|
||||||
permissions: prop_types_1.default.number,
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Component is used to describe to the generator that you want a file to be created and rendered based on the defined children.
|
|
||||||
*
|
|
||||||
* @component
|
|
||||||
* @example
|
|
||||||
* const name = "test.js"
|
|
||||||
* const permissions = 0o777
|
|
||||||
* return (
|
|
||||||
* <File name={name} permissions={permissions}>Test</File>
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
var File = function (_a) {
|
|
||||||
var children = _a.children;
|
|
||||||
return jsx_runtime_1.jsx(jsx_runtime_1.Fragment, { children: children }, void 0);
|
|
||||||
};
|
|
||||||
File.propTypes = __assign({}, exports.FilePropTypes);
|
|
||||||
exports.default = File;
|
|
||||||
//# sourceMappingURL=File.js.map
|
|
||||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"File.js","sourceRoot":"","sources":["../../src/components/File.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,0DAAmC;AAetB,QAAA,aAAa,GAAG;IAC3B;;OAEG;IACH,IAAI,EAAE,oBAAS,CAAC,MAAM;IACtB;;OAEG;IACH,WAAW,EAAE,oBAAS,CAAC,MAAM;CAC9B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,IAAM,IAAI,GAAiC,UAAC,EAAY;QAAV,QAAQ,cAAA;IACpD,OAAO,sDAAG,QAAQ,WAAI,CAAC;AACzB,CAAC,CAAC;AAEF,IAAI,CAAC,SAAS,gBACT,qBAAa,CACjB,CAAC;AACF,kBAAe,IAAI,CAAC"}
|
|
||||||
Generated
Vendored
-38
@@ -1,38 +0,0 @@
|
|||||||
import PropTypes from 'prop-types';
|
|
||||||
import { IndentationTypes } from "../utils";
|
|
||||||
import { FunctionComponent } from "../types";
|
|
||||||
export interface IndentProps {
|
|
||||||
/**
|
|
||||||
* `size` prop expects a string which format should be a number which represent the number of `type`'s to indent each content. Default to no indentation.
|
|
||||||
*/
|
|
||||||
size?: number;
|
|
||||||
/**
|
|
||||||
* `type` prop expects a string, you can use the `IndentationTypes` enum, as either `TABS` or `SPACES`. The `type` defaults to `SPACES`.
|
|
||||||
*/
|
|
||||||
type?: IndentationTypes;
|
|
||||||
}
|
|
||||||
export declare const IndentPropTypes: {
|
|
||||||
/**
|
|
||||||
* `size` prop expects a string which format should be a number which represent the number of `type`'s to indent each content. Default to no indentation.
|
|
||||||
*/
|
|
||||||
size: PropTypes.Requireable<number>;
|
|
||||||
/**
|
|
||||||
* `type` prop expects a string, you can use the `IndentationTypes` enum, as either `TABS` or `SPACES`. The `type` defaults to `SPACES`.
|
|
||||||
*/
|
|
||||||
type: PropTypes.Requireable<IndentationTypes>;
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Component is for wrapping multiple components and apply an indentation on those.
|
|
||||||
*
|
|
||||||
* It supports any form of nested components as well, meaning you can have as many nested `Indent` components as you would like.
|
|
||||||
*
|
|
||||||
* @component
|
|
||||||
* @example
|
|
||||||
* const size = 4
|
|
||||||
* const type = IndentationTypes.SPACES
|
|
||||||
* return (
|
|
||||||
* <Indent size={size} type={type}>test</Indent>
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
declare const Indent: FunctionComponent<IndentProps>;
|
|
||||||
export default Indent;
|
|
||||||
Generated
Vendored
-50
@@ -1,50 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __assign = (this && this.__assign) || function () {
|
|
||||||
__assign = Object.assign || function(t) {
|
|
||||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
||||||
s = arguments[i];
|
|
||||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
||||||
t[p] = s[p];
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
};
|
|
||||||
return __assign.apply(this, arguments);
|
|
||||||
};
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.IndentPropTypes = void 0;
|
|
||||||
var jsx_runtime_1 = require("react/jsx-runtime");
|
|
||||||
var prop_types_1 = __importDefault(require("prop-types"));
|
|
||||||
var utils_1 = require("../utils");
|
|
||||||
exports.IndentPropTypes = {
|
|
||||||
/**
|
|
||||||
* `size` prop expects a string which format should be a number which represent the number of `type`'s to indent each content. Default to no indentation.
|
|
||||||
*/
|
|
||||||
size: prop_types_1.default.number,
|
|
||||||
/**
|
|
||||||
* `type` prop expects a string, you can use the `IndentationTypes` enum, as either `TABS` or `SPACES`. The `type` defaults to `SPACES`.
|
|
||||||
*/
|
|
||||||
type: prop_types_1.default.oneOf(Object.values(utils_1.IndentationTypes)),
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Component is for wrapping multiple components and apply an indentation on those.
|
|
||||||
*
|
|
||||||
* It supports any form of nested components as well, meaning you can have as many nested `Indent` components as you would like.
|
|
||||||
*
|
|
||||||
* @component
|
|
||||||
* @example
|
|
||||||
* const size = 4
|
|
||||||
* const type = IndentationTypes.SPACES
|
|
||||||
* return (
|
|
||||||
* <Indent size={size} type={type}>test</Indent>
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
var Indent = function (_a) {
|
|
||||||
var _b = _a.size, size = _b === void 0 ? 0 : _b, _c = _a.type, type = _c === void 0 ? utils_1.IndentationTypes.SPACES : _c, childrenContent = _a.childrenContent;
|
|
||||||
return jsx_runtime_1.jsx(jsx_runtime_1.Fragment, { children: utils_1.withIndendation(childrenContent, size, type) }, void 0);
|
|
||||||
};
|
|
||||||
Indent.propTypes = __assign({}, exports.IndentPropTypes);
|
|
||||||
exports.default = Indent;
|
|
||||||
//# sourceMappingURL=Indent.js.map
|
|
||||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"Indent.js","sourceRoot":"","sources":["../../src/components/Indent.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,0DAAmC;AAEnC,kCAA6D;AAchD,QAAA,eAAe,GAAG;IAC7B;;OAEG;IACH,IAAI,EAAE,oBAAS,CAAC,MAAM;IACtB;;OAEG;IACH,IAAI,EAAE,oBAAS,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,wBAAgB,CAAC,CAAC;CACvD,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,IAAM,MAAM,GAAmC,UAAC,EAA6D;QAA3D,YAAQ,EAAR,IAAI,mBAAG,CAAC,KAAA,EAAE,YAA8B,EAA9B,IAAI,mBAAG,wBAAgB,CAAC,MAAM,KAAA,EAAE,eAAe,qBAAA;IACzG,OAAO,sDAAG,uBAAe,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,CAAC,WAAI,CAAC;AAC7D,CAAC,CAAC;AAEF,MAAM,CAAC,SAAS,gBACX,uBAAe,CACnB,CAAC;AACF,kBAAe,MAAM,CAAC"}
|
|
||||||
Generated
Vendored
-45
@@ -1,45 +0,0 @@
|
|||||||
import PropTypes from 'prop-types';
|
|
||||||
import { IndentationTypes } from "../utils";
|
|
||||||
import { FunctionComponent } from "../types";
|
|
||||||
export interface TextProps {
|
|
||||||
/**
|
|
||||||
* `indent` prop represents the number of `type`'s to indent each content. Default to no indentation.
|
|
||||||
*/
|
|
||||||
indent?: number;
|
|
||||||
/**
|
|
||||||
* `type` prop expects a string, you can use the `IndentationTypes` enum, as either `TABS` or `SPACES`. The `type` defaults to `SPACES`.
|
|
||||||
*/
|
|
||||||
type?: IndentationTypes;
|
|
||||||
/**
|
|
||||||
* `newLines` prop represents the number of appended new lines. Default to one new line.
|
|
||||||
*/
|
|
||||||
newLines?: number;
|
|
||||||
}
|
|
||||||
export declare const TextPropTypes: {
|
|
||||||
/**
|
|
||||||
* `size` prop expects a string which format should be a number which represent the number of `type`'s to indent each content. Default to no indentation.
|
|
||||||
*/
|
|
||||||
size: PropTypes.Requireable<number>;
|
|
||||||
/**
|
|
||||||
* `type` prop expects a string, you can use the `IndentationTypes` enum, as either `TABS` or `SPACES`. The `type` defaults to `SPACES`.
|
|
||||||
*/
|
|
||||||
type: PropTypes.Requireable<IndentationTypes>;
|
|
||||||
/**
|
|
||||||
* `newLines` prop represents the number of appended new lines. Default to one new line.
|
|
||||||
*/
|
|
||||||
newLines: PropTypes.Requireable<number>;
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Component is for defining a group of text which should be rendered on the same line.
|
|
||||||
*
|
|
||||||
* @component
|
|
||||||
* @example
|
|
||||||
* const indent = 4
|
|
||||||
* const type = IndentationTypes.SPACES
|
|
||||||
* const newLines = 2
|
|
||||||
* return (
|
|
||||||
* <Text indent={size} type={type} newLines={newLines}>Test</Text>
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
declare const Text: FunctionComponent<TextProps>;
|
|
||||||
export default Text;
|
|
||||||
Generated
Vendored
-54
@@ -1,54 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __assign = (this && this.__assign) || function () {
|
|
||||||
__assign = Object.assign || function(t) {
|
|
||||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
||||||
s = arguments[i];
|
|
||||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
||||||
t[p] = s[p];
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
};
|
|
||||||
return __assign.apply(this, arguments);
|
|
||||||
};
|
|
||||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
||||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.TextPropTypes = void 0;
|
|
||||||
var jsx_runtime_1 = require("react/jsx-runtime");
|
|
||||||
var prop_types_1 = __importDefault(require("prop-types"));
|
|
||||||
var utils_1 = require("../utils");
|
|
||||||
exports.TextPropTypes = {
|
|
||||||
/**
|
|
||||||
* `size` prop expects a string which format should be a number which represent the number of `type`'s to indent each content. Default to no indentation.
|
|
||||||
*/
|
|
||||||
size: prop_types_1.default.number,
|
|
||||||
/**
|
|
||||||
* `type` prop expects a string, you can use the `IndentationTypes` enum, as either `TABS` or `SPACES`. The `type` defaults to `SPACES`.
|
|
||||||
*/
|
|
||||||
type: prop_types_1.default.oneOf(Object.values(utils_1.IndentationTypes)),
|
|
||||||
/**
|
|
||||||
* `newLines` prop represents the number of appended new lines. Default to one new line.
|
|
||||||
*/
|
|
||||||
newLines: prop_types_1.default.number,
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Component is for defining a group of text which should be rendered on the same line.
|
|
||||||
*
|
|
||||||
* @component
|
|
||||||
* @example
|
|
||||||
* const indent = 4
|
|
||||||
* const type = IndentationTypes.SPACES
|
|
||||||
* const newLines = 2
|
|
||||||
* return (
|
|
||||||
* <Text indent={size} type={type} newLines={newLines}>Test</Text>
|
|
||||||
* )
|
|
||||||
*/
|
|
||||||
var Text = function (_a) {
|
|
||||||
var _b = _a.indent, indent = _b === void 0 ? 0 : _b, _c = _a.type, type = _c === void 0 ? utils_1.IndentationTypes.SPACES : _c, _d = _a.newLines, newLines = _d === void 0 ? 1 : _d, childrenContent = _a.childrenContent;
|
|
||||||
var contentWithLines = utils_1.withNewLines(childrenContent, newLines);
|
|
||||||
return jsx_runtime_1.jsx(jsx_runtime_1.Fragment, { children: utils_1.withIndendation(contentWithLines, indent, type) }, void 0);
|
|
||||||
};
|
|
||||||
Text.propTypes = __assign({}, exports.TextPropTypes);
|
|
||||||
exports.default = Text;
|
|
||||||
//# sourceMappingURL=Text.js.map
|
|
||||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"Text.js","sourceRoot":"","sources":["../../src/components/Text.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,0DAAmC;AAEnC,kCAA2E;AAkB9D,QAAA,aAAa,GAAG;IAC3B;;OAEG;IACH,IAAI,EAAE,oBAAS,CAAC,MAAM;IACtB;;OAEG;IACH,IAAI,EAAE,oBAAS,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,wBAAgB,CAAC,CAAC;IACtD;;OAEG;IACH,QAAQ,EAAE,oBAAS,CAAC,MAAM;CAC3B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,IAAM,IAAI,GAAiC,UAAC,EAA6E;QAA3E,cAAU,EAAV,MAAM,mBAAG,CAAC,KAAA,EAAE,YAA8B,EAA9B,IAAI,mBAAG,wBAAgB,CAAC,MAAM,KAAA,EAAE,gBAAY,EAAZ,QAAQ,mBAAG,CAAC,KAAA,EAAE,eAAe,qBAAA;IACrH,IAAM,gBAAgB,GAAG,oBAAY,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;IACjE,OAAO,sDAAG,uBAAe,CAAC,gBAAgB,EAAE,MAAM,EAAE,IAAI,CAAC,WAAI,CAAC;AAChE,CAAC,CAAC;AAEF,IAAI,CAAC,SAAS,gBACT,qBAAa,CACjB,CAAC;AACF,kBAAe,IAAI,CAAC"}
|
|
||||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
|||||||
export {};
|
|
||||||
Generated
Vendored
-50
@@ -1,50 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
var __assign = (this && this.__assign) || function () {
|
|
||||||
__assign = Object.assign || function(t) {
|
|
||||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
||||||
s = arguments[i];
|
|
||||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
||||||
t[p] = s[p];
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
};
|
|
||||||
return __assign.apply(this, arguments);
|
|
||||||
};
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
var jsx_runtime_1 = require("react/jsx-runtime");
|
|
||||||
var utils_1 = require("../../utils");
|
|
||||||
var __1 = require("../../");
|
|
||||||
describe('<File />', function () {
|
|
||||||
test('Should always render as is with default ptops', function () {
|
|
||||||
var defaultProps = {};
|
|
||||||
var wrapper = __1.render(jsx_runtime_1.jsx(__1.File, __assign({}, defaultProps, { children: "Test" }), void 0));
|
|
||||||
expect(wrapper).toEqual('Test');
|
|
||||||
});
|
|
||||||
test('Should alwyas render as is with props', function () {
|
|
||||||
var defaultProps = {
|
|
||||||
fileName: 'test.ts',
|
|
||||||
permissions: 511
|
|
||||||
};
|
|
||||||
var wrapper = __1.render(jsx_runtime_1.jsx(__1.File, __assign({}, defaultProps, { children: "Test" }), void 0));
|
|
||||||
expect(wrapper).toEqual('Test');
|
|
||||||
});
|
|
||||||
test('Should always be able to render Indent', function () {
|
|
||||||
var defaultProps = {};
|
|
||||||
var indentProps = {
|
|
||||||
size: 4,
|
|
||||||
type: utils_1.IndentationTypes.SPACES
|
|
||||||
};
|
|
||||||
var wrapper = __1.render(jsx_runtime_1.jsx(__1.File, __assign({}, defaultProps, { children: jsx_runtime_1.jsx(__1.Indent, __assign({}, indentProps, { children: "Test" }), void 0) }), void 0));
|
|
||||||
expect(wrapper).toEqual(' Test');
|
|
||||||
});
|
|
||||||
test('Should always be able to render Text', function () {
|
|
||||||
var defaultProps = {};
|
|
||||||
var textProps = {
|
|
||||||
indent: 4,
|
|
||||||
type: utils_1.IndentationTypes.SPACES
|
|
||||||
};
|
|
||||||
var wrapper = __1.render(jsx_runtime_1.jsx(__1.File, __assign({}, defaultProps, { children: jsx_runtime_1.jsx(__1.Text, __assign({}, textProps, { children: "Test" }), void 0) }), void 0));
|
|
||||||
expect(wrapper).toEqual(' Test\n');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
//# sourceMappingURL=File.spec.js.map
|
|
||||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
|||||||
{"version":3,"file":"File.spec.js","sourceRoot":"","sources":["../../../src/components/__tests__/File.spec.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;AACA,qCAA+C;AAC/C,4BAAoD;AAEpD,QAAQ,CAAC,UAAU,EAAE;IACnB,IAAI,CAAC,+CAA+C,EAAE;QACpD,IAAM,YAAY,GAAG,EAAE,CAAC;QACxB,IAAM,OAAO,GAAG,UAAM,CAAC,kBAAC,QAAI,eAAK,YAAY,gCAAa,CAAC,CAAC;QAC5D,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,uCAAuC,EAAE;QAC5C,IAAM,YAAY,GAAG;YACnB,QAAQ,EAAE,SAAS;YACnB,WAAW,EAAE,GAAK;SACnB,CAAC;QACF,IAAM,OAAO,GAAG,UAAM,CAAC,kBAAC,QAAI,eAAK,YAAY,gCAAa,CAAC,CAAC;QAC5D,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,wCAAwC,EAAE;QAC7C,IAAM,YAAY,GAAG,EAAE,CAAC;QACxB,IAAM,WAAW,GAAG;YAClB,IAAI,EAAE,CAAC;YACP,IAAI,EAAE,wBAAgB,CAAC,MAAM;SAC9B,CAAC;QACF,IAAM,OAAO,GAAG,UAAM,CAAC,kBAAC,QAAI,eAAK,YAAY,cAAE,kBAAC,UAAM,eAAK,WAAW,gCAAe,YAAO,CAAC,CAAC;QAC9F,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,sCAAsC,EAAE;QAC3C,IAAM,YAAY,GAAG,EAAE,CAAC;QACxB,IAAM,SAAS,GAAG;YAChB,MAAM,EAAE,CAAC;YACT,IAAI,EAAE,wBAAgB,CAAC,MAAM;SAC9B,CAAC;QACF,IAAM,OAAO,GAAG,UAAM,CAAC,kBAAC,QAAI,eAAK,YAAY,cAAE,kBAAC,QAAI,eAAK,SAAS,gCAAa,YAAO,CAAC,CAAC;QACxF,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
||||||
Generated
Vendored
-1
@@ -1 +0,0 @@
|
|||||||
export {};
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user