From da74344c89c7e93185ad71b7b01a5d3e5f4cab85 Mon Sep 17 00:00:00 2001 From: Lench Volodymyr Date: Thu, 1 Jul 2021 16:52:53 +0300 Subject: [PATCH 1/4] fix fe empty request bodies --- .../componentsHelpers/parametersHelper.js | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/forward_engineering/helpers/componentsHelpers/parametersHelper.js b/forward_engineering/helpers/componentsHelpers/parametersHelper.js index b069f1d..d273515 100644 --- a/forward_engineering/helpers/componentsHelpers/parametersHelper.js +++ b/forward_engineering/helpers/componentsHelpers/parametersHelper.js @@ -99,16 +99,21 @@ function getContent(data, isParentActivated) { return; } - return Object.keys(data.properties).reduce((acc, key) => { + const result = Object.keys(data.properties).reduce((acc, key) => { const properties = get(data, `properties[${key}].properties`); if (!properties) { - return; + return acc; } const schemaKeyword = getSchemaKeyword(properties); + + if (!schemaKeyword) { + return acc; + } + const isSchemaEmpty = properties[schemaKeyword] && get(properties, [schemaKeyword, 'type']) === 'object' && !get(properties, [schemaKeyword, 'properties']); const isExamplesEmpty = !get(properties, 'examples.properties'); if (isSchemaEmpty && isExamplesEmpty) { - return; + return acc; } const isActivated = data.properties[key].isActivated; acc[key] = commentDeactivatedItemInner( @@ -121,6 +126,12 @@ function getContent(data, isParentActivated) { ); return acc; }, {}); + + if (!Object.keys(result).length) { + return; + } + + return result; } function mapMediaTypeObject(data, isParentActivated = false) { From 71efb3dae3352dbfa3803be88ef6323fb7f98cf6 Mon Sep 17 00:00:00 2001 From: Lench Volodymyr Date: Thu, 1 Jul 2021 17:05:52 +0300 Subject: [PATCH 2/4] fix fe request body for get and delete requests --- forward_engineering/helpers/pathHelper.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/forward_engineering/helpers/pathHelper.js b/forward_engineering/helpers/pathHelper.js index 3863f41..8e626bf 100644 --- a/forward_engineering/helpers/pathHelper.js +++ b/forward_engineering/helpers/pathHelper.js @@ -49,7 +49,7 @@ function getRequestData(collections, containers, containerId, containersPath = [ .map(data => { const isRequestActivated = data.isActivated && isPathActivated; const requestBodyPropKeyword = getRequestBodyPropKeyword(data.properties); - const request = { + let request = { tags: commonHelper.mapArrayFieldByName(data.tags, 'tag'), summary: data.summary, description: data.description, @@ -58,12 +58,20 @@ function getRequestData(collections, containers, containerId, containersPath = [ parameters: mapRequestParameters( get(data, 'properties.parameters'), isRequestActivated - ), - requestBody: mapRequestBody( + ) + }; + const extensions = getExtensions(data.scopesExtensions); + + if (!['get', 'delete'].includes(String(data.collectionName).toLowerCase())) { + request.requestBody = mapRequestBody( get(data.properties, requestBodyPropKeyword), get(data, 'required', []).includes(requestBodyPropKeyword), isRequestActivated - ), + ); + } + + request = { + ...request, responses: mapResponses( collections, data.GUID, @@ -81,7 +89,6 @@ function getRequestData(collections, containers, containerId, containersPath = [ methodName: data.collectionName, isActivated: data.isActivated, }; - const extensions = getExtensions(data.scopesExtensions); return Object.assign({}, request, extensions); }) From 5e7632299d71cd479e16003cda37765827029e6d Mon Sep 17 00:00:00 2001 From: Lench Volodymyr Date: Thu, 1 Jul 2021 17:26:45 +0300 Subject: [PATCH 3/4] allow re script with comments --- reverse_engineering/helpers/dataHelper.js | 3 +- .../node_modules/array-timsort/LICENSE | 21 + .../node_modules/array-timsort/README.md | 288 +++++ .../node_modules/array-timsort/package.json | 80 ++ .../node_modules/array-timsort/src/index.js | 1080 +++++++++++++++++ .../node_modules/comment-json/HISTORY.md | 1 + .../node_modules/comment-json/LICENSE | 21 + .../node_modules/comment-json/README.md | 580 +++++++++ .../node_modules/comment-json/index.d.ts | 85 ++ .../node_modules/comment-json/package.json | 97 ++ .../node_modules/comment-json/src/array.js | 287 +++++ .../node_modules/comment-json/src/common.js | 175 +++ .../node_modules/comment-json/src/index.js | 13 + .../node_modules/comment-json/src/parse.js | 451 +++++++ .../comment-json/src/stringify.js | 367 ++++++ .../node_modules/core-util-is/LICENSE | 19 + .../node_modules/core-util-is/README.md | 3 + .../node_modules/core-util-is/float.patch | 604 +++++++++ .../node_modules/core-util-is/lib/util.js | 107 ++ .../node_modules/core-util-is/package.json | 62 + .../node_modules/core-util-is/test.js | 68 ++ .../node_modules/has-own-prop/index.d.ts | 17 + .../node_modules/has-own-prop/index.js | 4 + .../node_modules/has-own-prop/license | 9 + .../node_modules/has-own-prop/package.json | 65 + .../node_modules/has-own-prop/readme.md | 30 + .../node_modules/repeat-string/LICENSE | 21 + .../node_modules/repeat-string/README.md | 136 +++ .../node_modules/repeat-string/index.js | 70 ++ .../node_modules/repeat-string/package.json | 128 ++ reverse_engineering/package.json | 1 + 31 files changed, 4892 insertions(+), 1 deletion(-) create mode 100644 reverse_engineering/node_modules/array-timsort/LICENSE create mode 100644 reverse_engineering/node_modules/array-timsort/README.md create mode 100644 reverse_engineering/node_modules/array-timsort/package.json create mode 100644 reverse_engineering/node_modules/array-timsort/src/index.js create mode 100644 reverse_engineering/node_modules/comment-json/HISTORY.md create mode 100644 reverse_engineering/node_modules/comment-json/LICENSE create mode 100644 reverse_engineering/node_modules/comment-json/README.md create mode 100644 reverse_engineering/node_modules/comment-json/index.d.ts create mode 100644 reverse_engineering/node_modules/comment-json/package.json create mode 100644 reverse_engineering/node_modules/comment-json/src/array.js create mode 100644 reverse_engineering/node_modules/comment-json/src/common.js create mode 100644 reverse_engineering/node_modules/comment-json/src/index.js create mode 100644 reverse_engineering/node_modules/comment-json/src/parse.js create mode 100644 reverse_engineering/node_modules/comment-json/src/stringify.js create mode 100644 reverse_engineering/node_modules/core-util-is/LICENSE create mode 100644 reverse_engineering/node_modules/core-util-is/README.md create mode 100644 reverse_engineering/node_modules/core-util-is/float.patch create mode 100644 reverse_engineering/node_modules/core-util-is/lib/util.js create mode 100644 reverse_engineering/node_modules/core-util-is/package.json create mode 100644 reverse_engineering/node_modules/core-util-is/test.js create mode 100644 reverse_engineering/node_modules/has-own-prop/index.d.ts create mode 100644 reverse_engineering/node_modules/has-own-prop/index.js create mode 100644 reverse_engineering/node_modules/has-own-prop/license create mode 100644 reverse_engineering/node_modules/has-own-prop/package.json create mode 100644 reverse_engineering/node_modules/has-own-prop/readme.md create mode 100644 reverse_engineering/node_modules/repeat-string/LICENSE create mode 100644 reverse_engineering/node_modules/repeat-string/README.md create mode 100644 reverse_engineering/node_modules/repeat-string/index.js create mode 100644 reverse_engineering/node_modules/repeat-string/package.json diff --git a/reverse_engineering/helpers/dataHelper.js b/reverse_engineering/helpers/dataHelper.js index 59b531d..1d37a00 100644 --- a/reverse_engineering/helpers/dataHelper.js +++ b/reverse_engineering/helpers/dataHelper.js @@ -1,6 +1,7 @@ const commonHelper = require('./commonHelper'); const propertiesConfig = require('../propertiesConfig'); +const jsonComment = require('comment-json'); const REQUEST = 'request'; const RESPONSE = 'response'; @@ -868,7 +869,7 @@ const getModelContent = (pathData, fieldOrder, callbacksComponent) => { const getOpenAPIJsonSchema = (data, fileName, extension) => { const schema = extension !== '.json' ? commonHelper.convertYamlToJson(data) : data; - const openAPISchema = typeof schema === 'string' ? JSON.parse(schema) : schema; + const openAPISchema = typeof schema === 'string' ? jsonComment.parse(schema.replace(/^#.+$/mg, '')) : schema; const updatedOpenApiSchema = copyPathItemLevelParametersToOperationObject(openAPISchema); const openAPISchemaWithModelName = Object.assign({}, updatedOpenApiSchema, { modelName: fileName diff --git a/reverse_engineering/node_modules/array-timsort/LICENSE b/reverse_engineering/node_modules/array-timsort/LICENSE new file mode 100644 index 0000000..9208ac5 --- /dev/null +++ b/reverse_engineering/node_modules/array-timsort/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2015 Marco Ziccardi + +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. diff --git a/reverse_engineering/node_modules/array-timsort/README.md b/reverse_engineering/node_modules/array-timsort/README.md new file mode 100644 index 0000000..8d41fbe --- /dev/null +++ b/reverse_engineering/node_modules/array-timsort/README.md @@ -0,0 +1,288 @@ +[![Build Status](https://travis-ci.org/kaelzhang/node-array-timsort.svg?branch=master)](https://travis-ci.org/kaelzhang/node-array-timsort) +[![Coverage](https://codecov.io/gh/kaelzhang/node-array-timsort/branch/master/graph/badge.svg)](https://codecov.io/gh/kaelzhang/node-array-timsort) + +# array-timsort + +A fork of [`timsort`](https://npmjs.org/package/timsort) with the following differences: + +- `array-timsort` returns an array which records how the index of items have been sorted, while `timsort` returns `undefined`. See the example below. +- improves test coverage +- removes some dead code branches that could never be reached +- no longer built with UMD + +```js +const {sort} = require('array-timsort') + +const array = [3, 2, 1, 5] + +sort(array) // returns [2, 1, 0, 4] + +console.log(array) // [1, 2, 3, 5] +``` + +**** + +An adaptive and **stable** sort algorithm based on merging that requires fewer than nlog(n) +comparisons when run on partially sorted arrays. The algorithm uses O(n) memory and still runs in O(nlogn) +(worst case) on random arrays. +This implementation is based on the original +[TimSort](http://svn.python.org/projects/python/trunk/Objects/listsort.txt) developed +by Tim Peters for Python's lists (code [here](http://svn.python.org/projects/python/trunk/Objects/listobject.c)). +TimSort has been also adopted in Java starting from version 7. + +## Acknowledgments + +- @novacrazy: ported the module to ES6/ES7 and made it available via bower +- @kasperisager: implemented faster lexicographic comparison of small integers + +## Usage + +Install the package with npm: + +```sh +npm i array-timsort +``` + +And use it: + +```js +const {sort} = require('array-timsort') + +const arr = [...] + +sort(arr) +``` + +As `array.sort()` by default the `array-timsort` module sorts according to +lexicographical order. + +You can also provide your own compare function (to sort any object) as: + +```js +function numberCompare (a, b) { + return a - b +} + +const arr = [...] + +sort(arr, numberCompare) +``` + +You can also sort only a specific subrange of the array: + +```js +sort(arr, 5, 10) +sort(arr, numberCompare, 5, 10) +``` + +## Performance + +A benchmark is provided in `benchmark/index.js`. It compares the `array-timsort` module against +the default `array.sort` method in the numerical sorting of different types of integer array +(as described [here](http://svn.python.org/projects/python/trunk/Objects/listsort.txt)): + +- *Random array* +- *Descending array* +- *Ascending array* +- *Ascending array with 3 random exchanges* +- *Ascending array with 10 random numbers in the end* +- *Array of equal elements* +- *Random Array with many duplicates* +- *Random Array with some duplicates* + +For any of the array types the sorting is repeated several times and for +different array sizes, average execution time is then printed. +I run the benchmark on Node v6.3.1 (both pre-compiled and compiled from source, +results are very similar), obtaining the following values: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Execution Time (ns)Speedup
Array TypeLengthTimSort.sortarray.sort
Random1040415833.91
100714744420.62
100096395599790.62
10000134104460980654.55
Descending10180188110.41
1006821921028.14
1000380918518548.61
10000358785392428150.30
Ascending101738164.69
1005781814731.34
10002551331993130.12
10000220985382446243.57
Ascending + 3 Rand Exc102329273.99
10010591579214.90
1000352530070885.29
10000274554781370174.15
Ascending + 10 Rand End1037814253.77
10017072334613.67
1000581833474457.53
10000380344985473131.08
Equal Elements101647664.68
10052031886.12
100023402797111.95
100001701128167216.56
Many Repetitions1039614823.74
1007282252673.47
10001055284201203.98
10000139612057873994.15
Some Repetitions1039014633.75
1006678200823.01
10001043443741033.59
10000133381654740004.10
+ +`TimSort.sort` **is faster** than `array.sort` on almost of the tested array types. +In general, the more ordered the array is the better `TimSort.sort` performs with respect to `array.sort` (up to 243 times faster on already sorted arrays). +And also, in general, the bigger the array the more we benefit from using +the `array-timsort` module. + +These data strongly depend on Node.js version and the machine on which the benchmark is run. I strongly encourage you to run the benchmark on your own setup with: +``` +npm run benchmark +``` +Please also notice that: + +- This benchmark is far from exhaustive. Several cases are not considered +and the results must be taken as partial +- *inlining* is surely playing an active role in `array-timsort` module's good performance +- A more accurate comparison of the algorithms would require implementing `array.sort` in pure javascript +and counting element comparisons + +## Stability + +TimSort is *stable* which means that equal items maintain their relative order +after sorting. Stability is a desirable property for a sorting algorithm. +Consider the following array of items with an height and a weight. +```javascript +[ + { height: 100, weight: 80 }, + { height: 90, weight: 90 }, + { height: 70, weight: 95 }, + { height: 100, weight: 100 }, + { height: 80, weight: 110 }, + { height: 110, weight: 115 }, + { height: 100, weight: 120 }, + { height: 70, weight: 125 }, + { height: 70, weight: 130 }, + { height: 100, weight: 135 }, + { height: 75, weight: 140 }, + { height: 70, weight: 140 } +] +``` +Items are already sorted by `weight`. Sorting the array +according to the item's `height` with the `array-timsort` module +results in the following array: +```javascript +[ + { height: 70, weight: 95 }, + { height: 70, weight: 125 }, + { height: 70, weight: 130 }, + { height: 70, weight: 140 }, + { height: 75, weight: 140 }, + { height: 80, weight: 110 }, + { height: 90, weight: 90 }, + { height: 100, weight: 80 }, + { height: 100, weight: 100 }, + { height: 100, weight: 120 }, + { height: 100, weight: 135 }, + { height: 110, weight: 115 } +] +``` +Items with the same `height` are still sorted by `weight` which means they preserved their relative order. + +`array.sort`, instead, is not guarranteed to be *stable*. In Node v0.12.7 +sorting the previous array by `height` with `array.sort` results in: +```javascript +[ + { height: 70, weight: 140 }, + { height: 70, weight: 95 }, + { height: 70, weight: 125 }, + { height: 70, weight: 130 }, + { height: 75, weight: 140 }, + { height: 80, weight: 110 }, + { height: 90, weight: 90 }, + { height: 100, weight: 100 }, + { height: 100, weight: 80 }, + { height: 100, weight: 135 }, + { height: 100, weight: 120 }, + { height: 110, weight: 115 } +] +``` +As you can see the sorting did not preserve `weight` ordering for items with the +same `height`. diff --git a/reverse_engineering/node_modules/array-timsort/package.json b/reverse_engineering/node_modules/array-timsort/package.json new file mode 100644 index 0000000..d653b0a --- /dev/null +++ b/reverse_engineering/node_modules/array-timsort/package.json @@ -0,0 +1,80 @@ +{ + "_from": "array-timsort@^1.0.3", + "_id": "array-timsort@1.0.3", + "_inBundle": false, + "_integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", + "_location": "/array-timsort", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "array-timsort@^1.0.3", + "name": "array-timsort", + "escapedName": "array-timsort", + "rawSpec": "^1.0.3", + "saveSpec": null, + "fetchSpec": "^1.0.3" + }, + "_requiredBy": [ + "/comment-json" + ], + "_resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", + "_shasum": "3c9e4199e54fb2b9c3fe5976396a21614ef0d926", + "_spec": "array-timsort@^1.0.3", + "_where": "/home/volodymyr/projects/plugins/OpenAPI/reverse_engineering/node_modules/comment-json", + "ava": { + "files": [ + "test/*.test.js" + ] + }, + "bugs": { + "url": "https://github.com/kaelzhang/node-array-timsort/issues" + }, + "bundleDependencies": false, + "dependencies": {}, + "deprecated": false, + "description": "Fast JavaScript array sorting by implementing Python's Timsort algorithm", + "devDependencies": { + "@ostai/eslint-config": "^3.5.0", + "ava": "^3.13.0", + "codecov": "^3.7.2", + "eslint": "^7.10.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-mocha": "^8.0.0", + "nyc": "^15.1.0" + }, + "files": [ + "src" + ], + "homepage": "https://github.com/kaelzhang/node-array-timsort", + "keywords": [ + "fast sort", + "array soft", + "sort", + "compare", + "TimSort", + "algorithm", + "python", + "performance" + ], + "license": "MIT", + "main": "./src", + "name": "array-timsort", + "repository": { + "type": "git", + "url": "git+https://github.com/kaelzhang/node-array-timsort.git" + }, + "scripts": { + "benchmark": "node benchmark/index.js", + "fix": "eslint . --fix", + "lint": "eslint .", + "posttest": "npm run report", + "report": "nyc report --reporter=text-lcov > coverage.lcov && codecov", + "report:dev": "nyc report --reporter=html && npm run report:open", + "report:open": "open coverage/index.html", + "test": "npm run test:only", + "test:dev": "npm run test:only && npm run report:dev", + "test:only": "NODE_DEBUG=array-timsort nyc ava --timeout=10s --verbose" + }, + "version": "1.0.3" +} diff --git a/reverse_engineering/node_modules/array-timsort/src/index.js b/reverse_engineering/node_modules/array-timsort/src/index.js new file mode 100644 index 0000000..03db228 --- /dev/null +++ b/reverse_engineering/node_modules/array-timsort/src/index.js @@ -0,0 +1,1080 @@ +/** + * Default minimum size of a run. + */ +const DEFAULT_MIN_MERGE = 32 + +/** + * Minimum ordered subsequece required to do galloping. + */ +const DEFAULT_MIN_GALLOPING = 7 + +/** + * Default tmp storage length. Can increase depending on the size of the + * smallest run to merge. + */ +const DEFAULT_TMP_STORAGE_LENGTH = 256 + +/** + * Pre-computed powers of 10 for efficient lexicographic comparison of + * small integers. + */ +const POWERS_OF_TEN = [1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9] + +let results + +/** + * Estimate the logarithm base 10 of a small integer. + * + * @param {number} x - The integer to estimate the logarithm of. + * @return {number} - The estimated logarithm of the integer. + */ +const log10 = x => x < 1e5 + ? x < 1e2 + ? x < 1e1 + ? 0 + : 1 + : x < 1e4 + ? x < 1e3 + ? 2 + : 3 + : 4 + : x < 1e7 + ? x < 1e6 + ? 5 + : 6 + : x < 1e9 + ? x < 1e8 + ? 7 + : 8 + : 9 + +/** + * Default alphabetical comparison of items. + * + * @param {string|object|number} a - First element to compare. + * @param {string|object|number} b - Second element to compare. + * @return {number} - A positive number if a.toString() > b.toString(), a + * negative number if .toString() < b.toString(), 0 otherwise. + */ +function alphabeticalCompare (a, b) { + if (a === b) { + return 0 + } + + if (~ ~ a === a && ~ ~ b === b) { + if (a === 0 || b === 0) { + return a < b ? - 1 : 1 + } + + if (a < 0 || b < 0) { + if (b >= 0) { + return - 1 + } + + if (a >= 0) { + return 1 + } + + a = - a + b = - b + } + + const al = log10(a) + const bl = log10(b) + + let t = 0 + + if (al < bl) { + a *= POWERS_OF_TEN[bl - al - 1] + b /= 10 + t = - 1 + } else if (al > bl) { + b *= POWERS_OF_TEN[al - bl - 1] + a /= 10 + t = 1 + } + + if (a === b) { + return t + } + + return a < b ? - 1 : 1 + } + + const aStr = String(a) + const bStr = String(b) + + if (aStr === bStr) { + return 0 + } + + return aStr < bStr ? - 1 : 1 +} + +/** + * Compute minimum run length for TimSort + * + * @param {number} n - The size of the array to sort. + */ +function minRunLength (n) { + let r = 0 + + while (n >= DEFAULT_MIN_MERGE) { + r |= (n & 1) + n >>= 1 + } + + return n + r +} + +/** + * Counts the length of a monotonically ascending or strictly monotonically + * descending sequence (run) starting at array[lo] in the range [lo, hi). If + * the run is descending it is made ascending. + * + * @param {array} array - The array to reverse. + * @param {number} lo - First element in the range (inclusive). + * @param {number} hi - Last element in the range. + * @param {function} compare - Item comparison function. + * @return {number} - The length of the run. + */ +function makeAscendingRun (array, lo, hi, compare) { + let runHi = lo + 1 + + if (runHi === hi) { + return 1 + } + + // Descending + if (compare(array[runHi ++], array[lo]) < 0) { + while (runHi < hi && compare(array[runHi], array[runHi - 1]) < 0) { + runHi ++ + } + + reverseRun(array, lo, runHi) + reverseRun(results, lo, runHi) + // Ascending + } else { + while (runHi < hi && compare(array[runHi], array[runHi - 1]) >= 0) { + runHi ++ + } + } + + return runHi - lo +} + +/** + * Reverse an array in the range [lo, hi). + * + * @param {array} array - The array to reverse. + * @param {number} lo - First element in the range (inclusive). + * @param {number} hi - Last element in the range. + */ +function reverseRun (array, lo, hi) { + hi -- + + while (lo < hi) { + const t = array[lo] + array[lo ++] = array[hi] + array[hi --] = t + } +} + +/** + * Perform the binary sort of the array in the range [lo, hi) where start is + * the first element possibly out of order. + * + * @param {array} array - The array to sort. + * @param {number} lo - First element in the range (inclusive). + * @param {number} hi - Last element in the range. + * @param {number} start - First element possibly out of order. + * @param {function} compare - Item comparison function. + */ +function binaryInsertionSort (array, lo, hi, start, compare) { + if (start === lo) { + start ++ + } + + for (; start < hi; start ++) { + const pivot = array[start] + const pivotIndex = results[start] + + // Ranges of the array where pivot belongs + let left = lo + let right = start + + /* + * pivot >= array[i] for i in [lo, left) + * pivot < array[i] for i in in [right, start) + */ + while (left < right) { + const mid = (left + right) >>> 1 + + if (compare(pivot, array[mid]) < 0) { + right = mid + } else { + left = mid + 1 + } + } + + /* + * Move elements right to make room for the pivot. If there are elements + * equal to pivot, left points to the first slot after them: this is also + * a reason for which TimSort is stable + */ + let n = start - left + // Switch is just an optimization for small arrays + switch (n) { + case 3: + array[left + 3] = array[left + 2] + results[left + 3] = results[left + 2] + /* falls through */ + case 2: + array[left + 2] = array[left + 1] + results[left + 2] = results[left + 1] + /* falls through */ + case 1: + array[left + 1] = array[left] + results[left + 1] = results[left] + break + default: + while (n > 0) { + array[left + n] = array[left + n - 1] + results[left + n] = results[left + n - 1] + n -- + } + } + + array[left] = pivot + results[left] = pivotIndex + } +} + +/** + * Find the position at which to insert a value in a sorted range. If the range + * contains elements equal to the value the leftmost element index is returned + * (for stability). + * + * @param {number} value - Value to insert. + * @param {array} array - The array in which to insert value. + * @param {number} start - First element in the range. + * @param {number} length - Length of the range. + * @param {number} hint - The index at which to begin the search. + * @param {function} compare - Item comparison function. + * @return {number} - The index where to insert value. + */ +function gallopLeft (value, array, start, length, hint, compare) { + let lastOffset = 0 + let maxOffset = 0 + let offset = 1 + + if (compare(value, array[start + hint]) > 0) { + maxOffset = length - hint + + while ( + offset < maxOffset + && compare(value, array[start + hint + offset]) > 0 + ) { + lastOffset = offset + offset = (offset << 1) + 1 + + if (offset <= 0) { + offset = maxOffset + } + } + + if (offset > maxOffset) { + offset = maxOffset + } + + // Make offsets relative to start + lastOffset += hint + offset += hint + + // value <= array[start + hint] + } else { + maxOffset = hint + 1 + while ( + offset < maxOffset + && compare(value, array[start + hint - offset]) <= 0 + ) { + lastOffset = offset + offset = (offset << 1) + 1 + + if (offset <= 0) { + offset = maxOffset + } + } + if (offset > maxOffset) { + offset = maxOffset + } + + // Make offsets relative to start + const tmp = lastOffset + lastOffset = hint - offset + offset = hint - tmp + } + + /* + * Now array[start+lastOffset] < value <= array[start+offset], so value + * belongs somewhere in the range (start + lastOffset, start + offset]. Do a + * binary search, with invariant array[start + lastOffset - 1] < value <= + * array[start + offset]. + */ + lastOffset ++ + while (lastOffset < offset) { + const m = lastOffset + ((offset - lastOffset) >>> 1) + + if (compare(value, array[start + m]) > 0) { + lastOffset = m + 1 + } else { + offset = m + } + } + return offset +} + +/** + * Find the position at which to insert a value in a sorted range. If the range + * contains elements equal to the value the rightmost element index is returned + * (for stability). + * + * @param {number} value - Value to insert. + * @param {array} array - The array in which to insert value. + * @param {number} start - First element in the range. + * @param {number} length - Length of the range. + * @param {number} hint - The index at which to begin the search. + * @param {function} compare - Item comparison function. + * @return {number} - The index where to insert value. + */ +function gallopRight (value, array, start, length, hint, compare) { + let lastOffset = 0 + let maxOffset = 0 + let offset = 1 + + if (compare(value, array[start + hint]) < 0) { + maxOffset = hint + 1 + + while ( + offset < maxOffset + && compare(value, array[start + hint - offset]) < 0 + ) { + lastOffset = offset + offset = (offset << 1) + 1 + + if (offset <= 0) { + offset = maxOffset + } + } + + if (offset > maxOffset) { + offset = maxOffset + } + + // Make offsets relative to start + const tmp = lastOffset + lastOffset = hint - offset + offset = hint - tmp + + // value >= array[start + hint] + } else { + maxOffset = length - hint + + while ( + offset < maxOffset + && compare(value, array[start + hint + offset]) >= 0 + ) { + lastOffset = offset + offset = (offset << 1) + 1 + + if (offset <= 0) { + offset = maxOffset + } + } + + if (offset > maxOffset) { + offset = maxOffset + } + + // Make offsets relative to start + lastOffset += hint + offset += hint + } + + /* + * Now array[start+lastOffset] < value <= array[start+offset], so value + * belongs somewhere in the range (start + lastOffset, start + offset]. Do a + * binary search, with invariant array[start + lastOffset - 1] < value <= + * array[start + offset]. + */ + lastOffset ++ + + while (lastOffset < offset) { + const m = lastOffset + ((offset - lastOffset) >>> 1) + + if (compare(value, array[start + m]) < 0) { + offset = m + } else { + lastOffset = m + 1 + } + } + + return offset +} + +class TimSort { + constructor (array, compare) { + this.array = array + this.compare = compare + + const {length} = array + + this.length = length + this.minGallop = DEFAULT_MIN_GALLOPING + + this.tmpStorageLength = length < 2 * DEFAULT_TMP_STORAGE_LENGTH + ? length >>> 1 + : DEFAULT_TMP_STORAGE_LENGTH + + this.tmp = new Array(this.tmpStorageLength) + this.tmpIndex = new Array(this.tmpStorageLength) + + this.stackLength = length < 120 + ? 5 + : length < 1542 + ? 10 + : length < 119151 + ? 19 + : 40 + + this.runStart = new Array(this.stackLength) + this.runLength = new Array(this.stackLength) + + this.stackSize = 0 + } + + /** + * Push a new run on TimSort's stack. + * + * @param {number} runStart - Start index of the run in the original array. + * @param {number} runLength - Length of the run; + */ + pushRun (runStart, runLength) { + this.runStart[this.stackSize] = runStart + this.runLength[this.stackSize] = runLength + this.stackSize += 1 + } + + /** + * Merge runs on TimSort's stack so that the following holds for all i: + * 1) runLength[i - 3] > runLength[i - 2] + runLength[i - 1] + * 2) runLength[i - 2] > runLength[i - 1] + */ + mergeRuns () { + while (this.stackSize > 1) { + let n = this.stackSize - 2 + + if ( + ( + n >= 1 + && this.runLength[n - 1] <= this.runLength[n] + this.runLength[n + 1] + ) + || ( + n >= 2 + && this.runLength[n - 2] <= this.runLength[n] + this.runLength[n - 1] + ) + ) { + if (this.runLength[n - 1] < this.runLength[n + 1]) { + n -- + } + } else if (this.runLength[n] > this.runLength[n + 1]) { + break + } + this.mergeAt(n) + } + } + + /** + * Merge all runs on TimSort's stack until only one remains. + */ + forceMergeRuns () { + while (this.stackSize > 1) { + let n = this.stackSize - 2 + + if (n > 0 && this.runLength[n - 1] < this.runLength[n + 1]) { + n -- + } + + this.mergeAt(n) + } + } + + /** + * Merge the runs on the stack at positions i and i+1. Must be always be called + * with i=stackSize-2 or i=stackSize-3 (that is, we merge on top of the stack). + * + * @param {number} i - Index of the run to merge in TimSort's stack. + */ + mergeAt (i) { + const {compare} = this + const {array} = this + + let start1 = this.runStart[i] + let length1 = this.runLength[i] + const start2 = this.runStart[i + 1] + let length2 = this.runLength[i + 1] + + this.runLength[i] = length1 + length2 + + if (i === this.stackSize - 3) { + this.runStart[i + 1] = this.runStart[i + 2] + this.runLength[i + 1] = this.runLength[i + 2] + } + + this.stackSize -- + + /* + * Find where the first element in the second run goes in run1. Previous + * elements in run1 are already in place + */ + const k = gallopRight(array[start2], array, start1, length1, 0, compare) + start1 += k + length1 -= k + + if (length1 === 0) { + return + } + + /* + * Find where the last element in the first run goes in run2. Next elements + * in run2 are already in place + */ + length2 = gallopLeft( + array[start1 + length1 - 1], + array, + start2, + length2, + length2 - 1, + compare + ) + + if (length2 === 0) { + return + } + + /* + * Merge remaining runs. A tmp array with length = min(length1, length2) is + * used + */ + if (length1 <= length2) { + this.mergeLow(start1, length1, start2, length2) + } else { + this.mergeHigh(start1, length1, start2, length2) + } + } + + /** + * Merge two adjacent runs in a stable way. The runs must be such that the + * first element of run1 is bigger than the first element in run2 and the + * last element of run1 is greater than all the elements in run2. + * The method should be called when run1.length <= run2.length as it uses + * TimSort temporary array to store run1. Use mergeHigh if run1.length > + * run2.length. + * + * @param {number} start1 - First element in run1. + * @param {number} length1 - Length of run1. + * @param {number} start2 - First element in run2. + * @param {number} length2 - Length of run2. + */ + mergeLow (start1, length1, start2, length2) { + const {compare} = this + const {array} = this + const {tmp} = this + const {tmpIndex} = this + let i = 0 + + for (i = 0; i < length1; i ++) { + tmp[i] = array[start1 + i] + tmpIndex[i] = results[start1 + i] + } + + let cursor1 = 0 + let cursor2 = start2 + let dest = start1 + + array[dest] = array[cursor2] + results[dest] = results[cursor2] + + dest ++ + cursor2 ++ + + if (-- length2 === 0) { + for (i = 0; i < length1; i ++) { + array[dest + i] = tmp[cursor1 + i] + results[dest + i] = tmpIndex[cursor1 + i] + } + return + } + + if (length1 === 1) { + for (i = 0; i < length2; i ++) { + array[dest + i] = array[cursor2 + i] + results[dest + i] = results[cursor2 + i] + } + array[dest + length2] = tmp[cursor1] + results[dest + length2] = tmpIndex[cursor1] + return + } + + let {minGallop} = this + + while (true) { + let count1 = 0 + let count2 = 0 + let exit = false + + do { + if (compare(array[cursor2], tmp[cursor1]) < 0) { + array[dest] = array[cursor2] + results[dest] = results[cursor2] + dest ++ + cursor2 ++ + count2 ++ + count1 = 0 + + if (-- length2 === 0) { + exit = true + break + } + } else { + array[dest] = tmp[cursor1] + results[dest] = tmpIndex[cursor1] + dest ++ + cursor1 ++ + count1 ++ + count2 = 0 + if (-- length1 === 1) { + exit = true + break + } + } + } while ((count1 | count2) < minGallop) + + if (exit) { + break + } + + do { + count1 = gallopRight(array[cursor2], tmp, cursor1, length1, 0, compare) + + if (count1 !== 0) { + for (i = 0; i < count1; i ++) { + array[dest + i] = tmp[cursor1 + i] + results[dest + i] = tmpIndex[cursor1 + i] + } + + dest += count1 + cursor1 += count1 + length1 -= count1 + if (length1 <= 1) { + exit = true + break + } + } + + array[dest] = array[cursor2] + results[dest] = results[cursor2] + + dest ++ + cursor2 ++ + + if (-- length2 === 0) { + exit = true + break + } + + count2 = gallopLeft(tmp[cursor1], array, cursor2, length2, 0, compare) + + if (count2 !== 0) { + for (i = 0; i < count2; i ++) { + array[dest + i] = array[cursor2 + i] + results[dest + i] = results[cursor2 + i] + } + + dest += count2 + cursor2 += count2 + length2 -= count2 + + if (length2 === 0) { + exit = true + break + } + } + array[dest] = tmp[cursor1] + results[dest] = tmpIndex[cursor1] + dest ++ + cursor1 ++ + + if (-- length1 === 1) { + exit = true + break + } + + minGallop -- + } while ( + count1 >= DEFAULT_MIN_GALLOPING + || count2 >= DEFAULT_MIN_GALLOPING + ) + + if (exit) { + break + } + + if (minGallop < 0) { + minGallop = 0 + } + + minGallop += 2 + } + + this.minGallop = minGallop + + if (minGallop < 1) { + this.minGallop = 1 + } + + if (length1 === 1) { + for (i = 0; i < length2; i ++) { + array[dest + i] = array[cursor2 + i] + results[dest + i] = results[cursor2 + i] + } + array[dest + length2] = tmp[cursor1] + results[dest + length2] = tmpIndex[cursor1] + } else if (length1 === 0) { + throw new Error('mergeLow preconditions were not respected') + } else { + for (i = 0; i < length1; i ++) { + array[dest + i] = tmp[cursor1 + i] + results[dest + i] = tmpIndex[cursor1 + i] + } + } + } + + /** + * Merge two adjacent runs in a stable way. The runs must be such that the + * first element of run1 is bigger than the first element in run2 and the + * last element of run1 is greater than all the elements in run2. + * The method should be called when run1.length > run2.length as it uses + * TimSort temporary array to store run2. Use mergeLow if run1.length <= + * run2.length. + * + * @param {number} start1 - First element in run1. + * @param {number} length1 - Length of run1. + * @param {number} start2 - First element in run2. + * @param {number} length2 - Length of run2. + */ + mergeHigh (start1, length1, start2, length2) { + const {compare} = this + const {array} = this + const {tmp} = this + const {tmpIndex} = this + let i = 0 + + for (i = 0; i < length2; i ++) { + tmp[i] = array[start2 + i] + tmpIndex[i] = results[start2 + i] + } + + let cursor1 = start1 + length1 - 1 + let cursor2 = length2 - 1 + let dest = start2 + length2 - 1 + let customCursor = 0 + let customDest = 0 + + array[dest] = array[cursor1] + results[dest] = results[cursor1] + + dest -- + cursor1 -- + + if (-- length1 === 0) { + customCursor = dest - (length2 - 1) + + for (i = 0; i < length2; i ++) { + array[customCursor + i] = tmp[i] + results[customCursor + i] = tmpIndex[i] + } + + return + } + + if (length2 === 1) { + dest -= length1 + cursor1 -= length1 + customDest = dest + 1 + customCursor = cursor1 + 1 + + for (i = length1 - 1; i >= 0; i --) { + array[customDest + i] = array[customCursor + i] + results[customDest + i] = results[customCursor + i] + } + + array[dest] = tmp[cursor2] + results[dest] = tmpIndex[cursor2] + return + } + + let {minGallop} = this + + while (true) { + let count1 = 0 + let count2 = 0 + let exit = false + + do { + if (compare(tmp[cursor2], array[cursor1]) < 0) { + array[dest] = array[cursor1] + results[dest] = results[cursor1] + dest -- + cursor1 -- + count1 ++ + count2 = 0 + if (-- length1 === 0) { + exit = true + break + } + } else { + array[dest] = tmp[cursor2] + results[dest] = tmpIndex[cursor2] + dest -- + cursor2 -- + count2 ++ + count1 = 0 + if (-- length2 === 1) { + exit = true + break + } + } + } while ((count1 | count2) < minGallop) + + if (exit) { + break + } + + do { + count1 = length1 - gallopRight( + tmp[cursor2], + array, + start1, + length1, + length1 - 1, + compare + ) + + if (count1 !== 0) { + dest -= count1 + cursor1 -= count1 + length1 -= count1 + customDest = dest + 1 + customCursor = cursor1 + 1 + + for (i = count1 - 1; i >= 0; i --) { + array[customDest + i] = array[customCursor + i] + results[customDest + i] = results[customCursor + i] + } + + if (length1 === 0) { + exit = true + break + } + } + + array[dest] = tmp[cursor2] + results[dest] = tmpIndex[cursor2] + dest -- + cursor2 -- + + if (-- length2 === 1) { + exit = true + break + } + + count2 = length2 - gallopLeft( + array[cursor1], + tmp, + 0, + length2, + length2 - 1, + compare + ) + + if (count2 !== 0) { + dest -= count2 + cursor2 -= count2 + length2 -= count2 + customDest = dest + 1 + customCursor = cursor2 + 1 + + for (i = 0; i < count2; i ++) { + array[customDest + i] = tmp[customCursor + i] + results[customDest + i] = tmpIndex[customCursor + i] + } + + if (length2 <= 1) { + exit = true + break + } + } + + array[dest] = array[cursor1] + results[dest] = results[cursor1] + dest -- + cursor1 -- + + if (-- length1 === 0) { + exit = true + break + } + + minGallop -- + } while ( + count1 >= DEFAULT_MIN_GALLOPING + || count2 >= DEFAULT_MIN_GALLOPING + ) + + if (exit) { + break + } + + if (minGallop < 0) { + minGallop = 0 + } + + minGallop += 2 + } + + this.minGallop = minGallop + + if (minGallop < 1) { + this.minGallop = 1 + } + + if (length2 === 1) { + dest -= length1 + cursor1 -= length1 + customDest = dest + 1 + customCursor = cursor1 + 1 + + for (i = length1 - 1; i >= 0; i --) { + array[customDest + i] = array[customCursor + i] + results[customDest + i] = results[customCursor + i] + } + + array[dest] = tmp[cursor2] + results[dest] = tmpIndex[cursor2] + } else if (length2 === 0) { + throw new Error('mergeHigh preconditions were not respected') + } else { + customCursor = dest - (length2 - 1) + for (i = 0; i < length2; i ++) { + array[customCursor + i] = tmp[i] + results[customCursor + i] = tmpIndex[i] + } + } + } +} + +/** + * Sort an array in the range [lo, hi) using TimSort. + * + * @param {array} array - The array to sort. + * @param {function=} compare - Item comparison function. Default is + * alphabetical + * @param {number} lo - First element in the range (inclusive). + * @param {number} hi - Last element in the range. + * comparator. + */ +function sort (array, compare, lo, hi) { + if (!Array.isArray(array)) { + throw new TypeError( + `The "array" argument must be an array. Received ${array}` + ) + } + + results = [] + + const {length} = array + + let i = 0 + + while (i < length) { + results[i] = i ++ + } + + /* + * Handle the case where a comparison function is not provided. We do + * lexicographic sorting + */ + if (!compare) { + compare = alphabeticalCompare + } else if (typeof compare !== 'function') { + hi = lo + lo = compare + compare = alphabeticalCompare + } + + if (!lo) { + lo = 0 + } + if (!hi) { + hi = length + } + + let remaining = hi - lo + + // The array is already sorted + if (remaining < 2) { + return results + } + + let runLength = 0 + // On small arrays binary sort can be used directly + if (remaining < DEFAULT_MIN_MERGE) { + runLength = makeAscendingRun(array, lo, hi, compare) + binaryInsertionSort(array, lo, hi, lo + runLength, compare) + return results + } + + const ts = new TimSort(array, compare) + + const minRun = minRunLength(remaining) + + do { + runLength = makeAscendingRun(array, lo, hi, compare) + if (runLength < minRun) { + let force = remaining + if (force > minRun) { + force = minRun + } + + binaryInsertionSort(array, lo, lo + force, lo + runLength, compare) + runLength = force + } + // Push new run and merge if necessary + ts.pushRun(lo, runLength) + ts.mergeRuns() + + // Go find next run + remaining -= runLength + lo += runLength + } while (remaining !== 0) + + // Force merging of remaining runs + ts.forceMergeRuns() + + return results +} + +module.exports = { + sort +} diff --git a/reverse_engineering/node_modules/comment-json/HISTORY.md b/reverse_engineering/node_modules/comment-json/HISTORY.md new file mode 100644 index 0000000..e061a53 --- /dev/null +++ b/reverse_engineering/node_modules/comment-json/HISTORY.md @@ -0,0 +1 @@ +# History diff --git a/reverse_engineering/node_modules/comment-json/LICENSE b/reverse_engineering/node_modules/comment-json/LICENSE new file mode 100644 index 0000000..fedca17 --- /dev/null +++ b/reverse_engineering/node_modules/comment-json/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2013 kaelzhang <>, contributors +http://kael.me/ + +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. diff --git a/reverse_engineering/node_modules/comment-json/README.md b/reverse_engineering/node_modules/comment-json/README.md new file mode 100644 index 0000000..052b073 --- /dev/null +++ b/reverse_engineering/node_modules/comment-json/README.md @@ -0,0 +1,580 @@ +[![Build Status](https://travis-ci.org/kaelzhang/node-comment-json.svg?branch=master)](https://travis-ci.org/kaelzhang/node-comment-json) +[![Coverage](https://codecov.io/gh/kaelzhang/node-comment-json/branch/master/graph/badge.svg)](https://codecov.io/gh/kaelzhang/node-comment-json) +[![npm module downloads per month](http://img.shields.io/npm/dm/comment-json.svg)](https://www.npmjs.org/package/comment-json) + + + + +# comment-json + +Parse and stringify JSON with comments. It will retain comments even after saved! + +- [Parse](#parse) JSON strings with comments into JavaScript objects and MAINTAIN comments + - supports comments everywhere, yes, **EVERYWHERE** in a JSON file, eventually πŸ˜† + - fixes the known issue about comments inside arrays. +- [Stringify](#stringify) the objects into JSON strings with comments if there are + +The usage of `comment-json` is exactly the same as the vanilla [`JSON`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) object. + +## Table of Contents + +- [Why](#why) and [How](#how) +- [Usage and examples](#usage) +- API reference + - [parse](#parse) + - [stringify](#stringify) + - [assign](#assigntarget-object-source-object-keys-array) + - [CommentArray](#commentarray) +- [Change Logs](https://github.com/kaelzhang/node-comment-json/releases) + +## Why? + +There are many other libraries that can deal with JSON with comments, such as [json5](https://npmjs.org/package/json5), or [strip-json-comments](https://npmjs.org/package/strip-json-comments), but none of them can stringify the parsed object and return back a JSON string the same as the original content. + +Imagine that if the user settings are saved in `${library}.json`, and the user has written a lot of comments to improve readability. If the library `library` need to modify the user setting, such as modifying some property values and adding new fields, and if the library uses `json5` to read the settings, all comments will disappear after modified which will drive people insane. + +So, **if you want to parse a JSON string with comments, modify it, then save it back**, `comment-json` is your must choice! + +## How? + +`comment-json` parse JSON strings with comments and save comment tokens into [symbol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) properties. + +For JSON array with comments, `comment-json` extends the vanilla `Array` object into [`CommentArray`](#commentarray) whose instances could handle comments changes even after a comment array is modified. + +## Install + +```sh +$ npm i comment-json +``` + +~~For TypeScript developers, [`@types/comment-json`](https://www.npmjs.com/package/@types/comment-json) could be used~~ + +Since `2.4.1`, `comment-json` contains typescript declarations, so you might as well remove `@types/comment-json`. + +## Usage + +package.json: + +```js +{ + // package name + "name": "comment-json" +} +``` + +```js +const { + parse, + stringify, + assign +} = require('comment-json') +const fs = require('fs') + +const obj = parse(fs.readFileSync('package.json').toString()) + +console.log(obj.name) // comment-json + +stringify(obj, null, 2) +// Will be the same as package.json, Oh yeah! πŸ˜† +// which will be very useful if we use a json file to store configurations. +``` + +### Sort keys + +It is a common use case to sort the keys of a JSON file + +```js +const parsed = parse(`{ + // b + "b": 2 + // a + "a": 1 +}`) + +// Copy the properties including comments from `parsed` to the new object `{}` +// according to the sequence of the given keys +const sorted = assign( + {}, + parsed, + // You could also use your custom sorting function + Object.keys(parsed).sort() +) + +console.log(stringify(sorted, null, 2)) +// { +// // a +// "a": 1, +// // b +// "b": 2 +// } +``` + +For details about `assign`, see [here](#assigntarget-object-source-object-keys-array). + +## parse() + +```ts +parse(text, reviver? = null, remove_comments? = false) + : object | string | number | boolean | null +``` + +- **text** `string` The string to parse as JSON. See the [JSON](http://json.org/) object for a description of JSON syntax. +- **reviver?** `Function() | null` Default to `null`. It acts the same as the second parameter of [`JSON.parse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse). If a function, prescribes how the value originally produced by parsing is transformed, before being returned. +- **remove_comments?** `boolean = false` If true, the comments won't be maintained, which is often used when we want to get a clean object. + +Returns `object | string | number | boolean | null` corresponding to the given JSON text. + +If the `content` is: + +```js +/** + before-all + */ +// before-all +{ // before:foo + // before:foo + /* before:foo */ + "foo" /* after-prop:foo */: // after-colon:foo + 1 // after-value:foo + // after-value:foo + , // after:foo + // before:bar + "bar": [ // before:0 + // before:0 + "baz" // after-value:0 + // after-value:0 + , // after:0 + "quux" + // after:1 + ] // after:bar + // after:bar +} +// after-all +``` + +```js +const {inspect} = require('util') + +const parsed = parse(content) + +console.log( + inspect(parsed, { + // Since 4.0.0, symbol properties of comments are not enumerable, + // use `showHidden: true` to print them + showHidden: true + }) +) + +console.log(Object.keys(parsed)) +// > ['foo', 'bar'] + +console.log(stringify(parsed, null, 2)) +// πŸš€ Exact as the content above! πŸš€ +``` + +And the value of `parsed` will be: + +```js +{ + // Comments before the JSON object + [Symbol.for('before-all')]: [{ + type: 'BlockComment', + value: '\n before-all\n ', + inline: false, + loc: { + // The start location of `/**` + start: { + line: 1, + column: 0 + }, + // The end location of `*/` + end: { + line: 3, + column: 3 + } + } + }, { + type: 'LineComment', + value: ' before-all', + inline: false, + loc: ... + }], + ... + + [Symbol.for('after-prop:foo')]: [{ + type: 'BlockComment', + value: ' after-prop:foo ', + inline: true, + loc: ... + }], + + // The real value + foo: 1, + bar: [ + "baz", + "quux", + + // The property of the array + [Symbol.for('after-value:0')]: [{ + type: 'LineComment', + value: ' after-value:0', + inline: true, + loc: ... + }, ...], + ... + ] +} +``` + +There are **EIGHT** kinds of symbol properties: + +```js +// Comments before everything +Symbol.for('before-all') + +// If all things inside an object or an array are comments +Symbol.for('before') + +// comment tokens before +// - a property of an object +// - an item of an array +// and after the previous comma(`,`) or the opening bracket(`{` or `[`) +Symbol.for(`before:${prop}`) + +// comment tokens after property key `prop` and before colon(`:`) +Symbol.for(`after-prop:${prop}`) + +// comment tokens after the colon(`:`) of property `prop` and before property value +Symbol.for(`after-colon:${prop}`) + +// comment tokens after +// - the value of property `prop` inside an object +// - the item of index `prop` inside an array +// and before the next key-value/item delimiter(`,`) +// or the closing bracket(`}` or `]`) +Symbol.for(`after-value:${prop}`) + +// comment tokens after +// - comma(`,`) +// - the value of property `prop` if it is the last property +Symbol.for(`after:${prop}`) + +// Comments after everything +Symbol.for('after-all') +``` + +And the value of each symbol property is an **array** of `CommentToken` + +```ts +interface CommentToken { + type: 'BlockComment' | 'LineComment' + // The content of the comment, including whitespaces and line breaks + value: string + // If the start location is the same line as the previous token, + // then `inline` is `true` + inline: boolean + + // But pay attention that, + // locations will NOT be maintained when stringified + loc: CommentLocation +} + +interface CommentLocation { + // The start location begins at the `//` or `/*` symbol + start: Location + // The end location of multi-line comment ends at the `*/` symbol + end: Location +} + +interface Location { + line: number + column: number +} +``` + +### Parse into an object without comments + +```js +console.log(parse(content, null, true)) +``` + +And the result will be: + +```js +{ + foo: 1, + bar: [ + "baz", + "quux" + ] +} +``` + +### Special cases + +```js +const parsed = parse(` +// comment +1 +`) + +console.log(parsed === 1) +// false +``` + +If we parse a JSON of primative type with `remove_comments:false`, then the return value of `parse()` will be of object type. + +The value of `parsed` is equivalent to: + +```js +const parsed = new Number(1) + +parsed[Symbol.for('before-all')] = [{ + type: 'LineComment', + value: ' comment', + inline: false, + loc: ... +}] +``` + +Which is similar for: + +- `Boolean` type +- `String` type + +For example + +```js +const parsed = parse(` +"foo" /* comment */ +`) +``` + +Which is equivalent to + +```js +const parsed = new String('foo') + +parsed[Symbol.for('after-all')] = [{ + type: 'BlockComment', + value: ' comment ', + inline: true, + loc: ... +}] +``` + +But there is one exception: + +```js +const parsed = parse(` +// comment +null +`) + +console.log(parsed === null) // true +``` + +## stringify() + +```ts +stringify(object: any, replacer?, space?): string +``` + +The arguments are the same as the vanilla [`JSON.stringify`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify). + +And it does the similar thing as the vanilla one, but also deal with extra properties and convert them into comments. + +```js +console.log(stringify(parsed, null, 2)) +// Exactly the same as `content` +``` + +#### space + +If space is not specified, or the space is an empty string, the result of `stringify()` will have no comments. + +For the case above: + +```js +console.log(stringify(result)) // {"a":1} +console.log(stringify(result, null, 2)) // is the same as `code` +``` + +## assign(target: object, source?: object, keys?: Array) + +- **target** `object` the target object +- **source?** `object` the source object. This parameter is optional but it is silly to not pass this argument. +- **keys?** `Array` If not specified, all enumerable own properties of `source` will be used. + +This method is used to copy the enumerable own properties and their corresponding comment symbol properties to the target object. + +```js +const parsed = parse(`// before all +{ + // This is a comment + "foo": "bar" +}`) + +const obj = assign({ + bar: 'baz' +}, parsed) + +stringify(obj, null, 2) +// // before all +// { +// "bar": "baz", +// // This is a comment +// "foo": "bar" +// } +``` + +### Special cases about `keys` + +But if argument `keys` is specified and is not empty, then comment ` before all`, which belongs to no properties, will **NOT** be copied. + +```js +const obj = assign({ + bar: 'baz' +}, parsed, ['foo']) + +stringify(obj, null, 2) +// { +// "bar": "baz", +// // This is a comment +// "foo": "bar" +// } +``` + +Specifying the argument `keys` as an empty array indicates that it will only copy non-property symbols of comments + +```js +const obj = assign({ + bar: 'baz' +}, parsed, []) + +stringify(obj, null, 2) +// // before all +// { +// "bar": "baz", +// } +``` + +Non-property symbols include: + +```js +Symbol.for('before-all') +Symbol.for('before') +Symbol.for('after-all') +``` + +## `CommentArray` + +> Advanced Section + +All arrays of the parsed object are `CommentArray`s. + +The constructor of `CommentArray` could be accessed by: + +```js +const {CommentArray} = require('comment-json') +``` + +If we modify a comment array, its comment symbol properties could be handled automatically. + +```js +const parsed = parse(`{ + "foo": [ + // bar + "bar", + // baz, + "baz" + ] +}`) + +parsed.foo.unshift('qux') + +stringify(parsed, null, 2) +// { +// "foo": [ +// "qux", +// // bar +// "bar", +// // baz +// "baz" +// ] +// } +``` + +Oh yeah! πŸ˜† + +But pay attention, if you reassign the property of a comment array with a normal array, all comments will be gone: + +```js +parsed.foo = ['quux'].concat(parsed.foo) +stringify(parsed, null, 2) +// { +// "foo": [ +// "quux", +// "qux", +// "bar", +// "baz" +// ] +// } + +// Whoooops!! 😩 Comments are gone +``` + +Instead, we should: + +```js +parsed.foo = new CommentArray('quux').concat(parsed.foo) +stringify(parsed, null, 2) +// { +// "foo": [ +// "quux", +// "qux", +// // bar +// "bar", +// // baz +// "baz" +// ] +// } +``` + +## Special Cases about Trailing Comma + +If we have a JSON string `str` + +```js +{ + "foo": "bar", // comment +} +``` + +```js +// When stringify, trailing commas will be eliminated +const stringified = stringify(parse(str), null, 2) +console.log(stringified) +``` + +And it will print: + +```js +{ + "foo": "bar" // comment +} +``` + +## License + +[MIT](LICENSE) + +## Change Logs + +See [releases](https://github.com/kaelzhang/node-comment-json/releases) diff --git a/reverse_engineering/node_modules/comment-json/index.d.ts b/reverse_engineering/node_modules/comment-json/index.d.ts new file mode 100644 index 0000000..d5cace3 --- /dev/null +++ b/reverse_engineering/node_modules/comment-json/index.d.ts @@ -0,0 +1,85 @@ +// Original from DefinitelyTyped. Thanks a million +// Type definitions for comment-json 1.1 +// Project: https://github.com/kaelzhang/node-comment-json +// Definitions by: Jason Dent +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +// For now, typescript does not support symbol as object/array index key, +// just use any to clean the mess +// https://github.com/microsoft/TypeScript/issues/1863 +export type CommentJSONValue = any; +export type CommentArray = any; + +// export type CommentJSONValue = number | string | null | boolean | CommentJSONArray | CommentJSONObject + +// // export type CommentJSONArray = Array + +// export class CommentJSONArray extends Array { +// [key: symbol]: CommentToken +// } + +// export interface CommentJSONObject { +// [key: string]: CommentJSONValue +// [key: symbol]: CommentToken +// } + +// export interface CommentToken { +// type: 'BlockComment' | 'LineComment' +// // The content of the comment, including whitespaces and line breaks +// value: string +// // If the start location is the same line as the previous token, +// // then `inline` is `true` +// inline: boolean + +// // But pay attention that, +// // locations will NOT be maintained when stringified +// loc: CommentLocation +// } + +// export interface CommentLocation { +// // The start location begins at the `//` or `/*` symbol +// start: Location +// // The end location of multi-line comment ends at the `*/` symbol +// end: Location +// } + +// export interface Location { +// line: number +// column: number +// } + +export type Reviver = (k: number | string, v: any) => any; + +/** + * Converts a JavaScript Object Notation (JSON) string into an object. + * @param json A valid JSON string. + * @param reviver A function that transforms the results. This function is called for each member of the object. + * @param removes_comments If true, the comments won't be maintained, which is often used when we want to get a clean object. + * If a member contains nested objects, the nested objects are transformed before the parent object is. + */ +export function parse(json: string, reviver?: Reviver, removes_comments?: boolean): CommentJSONValue; + +/** + * Converts a JavaScript value to a JavaScript Object Notation (JSON) string. + * @param value A JavaScript value, usually an object or array, to be converted. + * @param replacer A function that transforms the results or an array of strings and numbers that acts as a approved list for selecting the object properties that will be stringified. + * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. + */ +export function stringify(value: any, replacer?: ((key: string, value: any) => any) | Array | null, space?: string | number): string; + + +export function tokenize(input: string, config?: TokenizeOptions): Token[]; + +export interface Token { + type: string; + value: string; +} + +export interface TokenizeOptions { + tolerant?: boolean; + range?: boolean; + loc?: boolean; + comment?: boolean; +} + +export function assign(target: any, source: any, keys?: Array): any; diff --git a/reverse_engineering/node_modules/comment-json/package.json b/reverse_engineering/node_modules/comment-json/package.json new file mode 100644 index 0000000..21e6132 --- /dev/null +++ b/reverse_engineering/node_modules/comment-json/package.json @@ -0,0 +1,97 @@ +{ + "_from": "comment-json", + "_id": "comment-json@4.1.0", + "_inBundle": false, + "_integrity": "sha512-WEghmVYaNq9NlWbrkzQTSsya9ycLyxJxpTQfZEan6a5Jomnjw18zS3Podf8q1Zf9BvonvQd/+Z7Z39L7KKzzdQ==", + "_location": "/comment-json", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "comment-json", + "name": "comment-json", + "escapedName": "comment-json", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.1.0.tgz", + "_shasum": "09d08f0fbc4ad5eeccbac20f469adbb967dcbd2c", + "_spec": "comment-json", + "_where": "/home/volodymyr/projects/plugins/OpenAPI/reverse_engineering", + "author": { + "name": "kaelzhang" + }, + "ava": { + "files": [ + "test/*.test.js" + ] + }, + "bugs": { + "url": "https://github.com/kaelzhang/node-comment-json/issues" + }, + "bundleDependencies": false, + "dependencies": { + "array-timsort": "^1.0.3", + "core-util-is": "^1.0.2", + "esprima": "^4.0.1", + "has-own-prop": "^2.0.0", + "repeat-string": "^1.6.1" + }, + "deprecated": false, + "description": "Parse and stringify JSON with comments. It will retain comments even after saved!", + "devDependencies": { + "@ostai/eslint-config": "^3.5.0", + "ava": "^3.13.0", + "codecov": "^3.7.2", + "eslint": "^7.10.0", + "eslint-plugin-import": "^2.22.1", + "nyc": "^15.1.0", + "test-fixture": "^2.4.1", + "typescript": "^4.0.3" + }, + "engines": { + "node": ">= 6" + }, + "files": [ + "src/", + "index.d.ts" + ], + "homepage": "https://github.com/kaelzhang/node-comment-json#readme", + "keywords": [ + "comment-json", + "comments", + "annotations", + "json", + "json-stringify", + "json-parse", + "parser", + "comments-json", + "json-comments" + ], + "license": "MIT", + "main": "src/index.js", + "name": "comment-json", + "repository": { + "type": "git", + "url": "git://github.com/kaelzhang/node-comment-json.git" + }, + "scripts": { + "fix": "eslint . --fix", + "lint": "eslint .", + "posttest": "npm run report", + "report": "nyc report --reporter=text-lcov > coverage.lcov && codecov", + "report:dev": "nyc report --reporter=html && npm run report:open", + "report:open": "open coverage/index.html", + "test": "npm run test:only", + "test:dev": "npm run test:only && npm run report:dev", + "test:node": "NODE_DEBUG=comment-json nyc ava --timeout=10s --verbose", + "test:only": "npm run test:ts && npm run test:node", + "test:ts": "tsc test/ts/test-ts.ts && node test/ts/test-ts.js" + }, + "version": "4.1.0" +} diff --git a/reverse_engineering/node_modules/comment-json/src/array.js b/reverse_engineering/node_modules/comment-json/src/array.js new file mode 100644 index 0000000..9a09df4 --- /dev/null +++ b/reverse_engineering/node_modules/comment-json/src/array.js @@ -0,0 +1,287 @@ +const {isArray} = require('core-util-is') +const {sort} = require('array-timsort') + +const { + SYMBOL_PREFIXES, + + UNDEFINED, + + symbol, + copy_comments, + swap_comments +} = require('./common') + + +const reverse_comments = array => { + const {length} = array + let i = 0 + const max = length / 2 + + for (; i < max; i ++) { + swap_comments(array, i, length - i - 1) + } +} + +const move_comment = (target, source, i, offset, remove) => { + copy_comments(target, source, i + offset, i, remove) +} + +const move_comments = ( + // `Array` target array + target, + // `Array` source array + source, + // `number` start index + start, + // `number` number of indexes to move + count, + // `number` offset to move + offset, + // `boolean` whether should remove the comments from source + remove +) => { + if (offset > 0) { + let i = count + // | count | offset | + // source: ------------- + // target: ------------- + // | remove | + // => remove === offset + + // From [count - 1, 0] + while (i -- > 0) { + move_comment(target, source, start + i, offset, remove) + } + return + } + + let i = 0 + // | remove | count | + // ------------- + // ------------- + // | offset | + + // From [0, count - 1] + while (i < count) { + const ii = i ++ + move_comment(target, source, start + ii, offset, remove) + } +} + +const remove_comments = (array, key) => { + SYMBOL_PREFIXES.forEach(prefix => { + const prop = symbol(prefix, key) + delete array[prop] + }) +} + +const get_mapped = (map, key) => { + let mapped = key + + while (mapped in map) { + mapped = map[mapped] + } + + return mapped +} + + +class CommentArray extends Array { + // - deleteCount + items.length + + // We should avoid `splice(begin, deleteCount, ...items)`, + // because `splice(0, undefined)` is not equivalent to `splice(0)`, + // as well as: + // - slice + splice (...args) { + const {length} = this + const ret = super.splice(...args) + + // #16 + // If no element removed, we might still need to move comments, + // because splice could add new items + + // if (!ret.length) { + // return ret + // } + + // JavaScript syntax is silly + // eslint-disable-next-line prefer-const + let [begin, deleteCount, ...items] = args + + if (begin < 0) { + begin += length + } + + if (arguments.length === 1) { + deleteCount = length - begin + } else { + deleteCount = Math.min(length - begin, deleteCount) + } + + const { + length: item_length + } = items + + // itemsToDelete: - + // itemsToAdd: + + // | dc | count | + // =======-------------============ + // =======++++++============ + // | il | + const offset = item_length - deleteCount + const start = begin + deleteCount + const count = length - start + + move_comments(this, this, start, count, offset, true) + + return ret + } + + slice (...args) { + const {length} = this + const array = super.slice(...args) + if (!array.length) { + return new CommentArray() + } + + let [begin, before] = args + + // Ref: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice + if (before === UNDEFINED) { + before = length + } else if (before < 0) { + before += length + } + + if (begin < 0) { + begin += length + } else if (begin === UNDEFINED) { + begin = 0 + } + + move_comments(array, this, begin, before - begin, - begin) + + return array + } + + unshift (...items) { + const {length} = this + const ret = super.unshift(...items) + const { + length: items_length + } = items + + if (items_length > 0) { + move_comments(this, this, 0, length, items_length, true) + } + + return ret + } + + shift () { + const ret = super.shift() + const {length} = this + + remove_comments(this, 0) + move_comments(this, this, 1, length, - 1, true) + + return ret + } + + reverse () { + super.reverse() + + reverse_comments(this) + + return this + } + + pop () { + const ret = super.pop() + + // Removes comments + remove_comments(this, this.length) + + return ret + } + + concat (...items) { + let {length} = this + const ret = super.concat(...items) + + if (!items.length) { + return ret + } + + items.forEach(item => { + const prev = length + length += isArray(item) + ? item.length + : 1 + + if (!(item instanceof CommentArray)) { + return + } + + move_comments(ret, item, 0, item.length, prev) + }) + + return ret + } + + sort (...args) { + const result = sort( + this, + // Make sure there is no more than one argument + ...args.slice(0, 1) + ) + + // For example, + // if we sort ['b', 'd', 'c', 'a'], + // then `result` will be [3, 0, 2, 1], and the array is ['a', 'b', 'c', 'd'] + + // First, we swap index 0 (b) and index 3 (a), then the array comments are + // ['a.comments', 'd.comments', 'c.comments', 'b.comments'] + // index 0 is finalized + // index 3 is actually mapped to original index 0, we present as 0 -> 3 + + // Then swap index 1 (d) and index 0 (-> 3, b) + // 1 (index) -> 0 (new index) -> 3 (real_index) + // ['d.comments', 'b.comments', 'c.comments', 'd.comments'] + // index 1 is finalized + // index 3 is contains the item of original index 1 + // - we present as 1 -> 3 + // - it is ok that we don't remove mapping 0 -> 3 + + // Then index 2 should be skipped + + // Then swap index 3 (d) and index 1 (-> 3, b), skipped + + const map = Object.create(null) + + result.forEach((source_index, index) => { + if (source_index === index) { + return + } + + const real_source_index = get_mapped(map, source_index) + + if (real_source_index === index) { + return + } + + // The item of index `index` gets the final value + // delete map[index] + map[index] = real_source_index + + swap_comments(this, index, real_source_index) + }) + } +} + + +module.exports = { + CommentArray +} diff --git a/reverse_engineering/node_modules/comment-json/src/common.js b/reverse_engineering/node_modules/comment-json/src/common.js new file mode 100644 index 0000000..6749f96 --- /dev/null +++ b/reverse_engineering/node_modules/comment-json/src/common.js @@ -0,0 +1,175 @@ +const hasOwnProperty = require('has-own-prop') +const {isObject, isArray} = require('core-util-is') + + +const PREFIX_BEFORE = 'before' +const PREFIX_AFTER_PROP = 'after-prop' +const PREFIX_AFTER_COLON = 'after-colon' +const PREFIX_AFTER_VALUE = 'after-value' +const PREFIX_AFTER = 'after' + +const PREFIX_BEFORE_ALL = 'before-all' +const PREFIX_AFTER_ALL = 'after-all' + +const BRACKET_OPEN = '[' +const BRACKET_CLOSE = ']' +const CURLY_BRACKET_OPEN = '{' +const CURLY_BRACKET_CLOSE = '}' +const COMMA = ',' +const EMPTY = '' +const MINUS = '-' + +const SYMBOL_PREFIXES = [ + PREFIX_BEFORE, + PREFIX_AFTER_PROP, + PREFIX_AFTER_COLON, + PREFIX_AFTER_VALUE, + PREFIX_AFTER +] + +const NON_PROP_SYMBOL_KEYS = [ + PREFIX_BEFORE, + PREFIX_BEFORE_ALL, + PREFIX_AFTER_ALL +].map(Symbol.for) + +const COLON = ':' +const UNDEFINED = undefined + + +const symbol = (prefix, key) => Symbol.for(prefix + COLON + key) + +const define = (target, key, value) => Object.defineProperty(target, key, { + value, + writable: true, + configurable: true +}) + +const copy_comments_by_kind = ( + target, source, target_key, source_key, prefix, remove_source +) => { + const source_prop = symbol(prefix, source_key) + if (!hasOwnProperty(source, source_prop)) { + return + } + + const target_prop = target_key === source_key + ? source_prop + : symbol(prefix, target_key) + + define(target, target_prop, source[source_prop]) + + if (remove_source) { + delete source[source_prop] + } +} + +const copy_comments = ( + target, source, target_key, source_key, remove_source +) => { + SYMBOL_PREFIXES.forEach(prefix => { + copy_comments_by_kind( + target, source, target_key, source_key, prefix, remove_source + ) + }) +} + +const swap_comments = (array, from, to) => { + if (from === to) { + return + } + + SYMBOL_PREFIXES.forEach(prefix => { + const target_prop = symbol(prefix, to) + if (!hasOwnProperty(array, target_prop)) { + copy_comments_by_kind(array, array, to, from, prefix, true) + return + } + + const comments = array[target_prop] + delete array[target_prop] + + copy_comments_by_kind(array, array, to, from, prefix, true) + define(array, symbol(prefix, from), comments) + }) +} + +const assign_non_prop_comments = (target, source) => { + NON_PROP_SYMBOL_KEYS.forEach(key => { + const comments = source[key] + + if (comments) { + define(target, key, comments) + } + }) +} + +// Assign keys and comments +const assign = (target, source, keys) => { + keys.forEach(key => { + if (!hasOwnProperty(source, key)) { + return + } + + target[key] = source[key] + copy_comments(target, source, key, key) + }) + + return target +} + + +module.exports = { + SYMBOL_PREFIXES, + + PREFIX_BEFORE, + PREFIX_AFTER_PROP, + PREFIX_AFTER_COLON, + PREFIX_AFTER_VALUE, + PREFIX_AFTER, + + PREFIX_BEFORE_ALL, + PREFIX_AFTER_ALL, + + BRACKET_OPEN, + BRACKET_CLOSE, + CURLY_BRACKET_OPEN, + CURLY_BRACKET_CLOSE, + + COLON, + COMMA, + MINUS, + EMPTY, + + UNDEFINED, + + symbol, + define, + copy_comments, + swap_comments, + assign_non_prop_comments, + + assign (target, source, keys) { + if (!isObject(target)) { + throw new TypeError('Cannot convert undefined or null to object') + } + + if (!isObject(source)) { + return target + } + + if (keys === UNDEFINED) { + keys = Object.keys(source) + // We assign non-property comments + // if argument `keys` is not specified + assign_non_prop_comments(target, source) + } else if (!isArray(keys)) { + throw new TypeError('keys must be array or undefined') + } else if (keys.length === 0) { + // Or argument `keys` is an empty array + assign_non_prop_comments(target, source) + } + + return assign(target, source, keys) + } +} diff --git a/reverse_engineering/node_modules/comment-json/src/index.js b/reverse_engineering/node_modules/comment-json/src/index.js new file mode 100644 index 0000000..7da46fd --- /dev/null +++ b/reverse_engineering/node_modules/comment-json/src/index.js @@ -0,0 +1,13 @@ +const {parse, tokenize} = require('./parse') +const stringify = require('./stringify') +const {CommentArray} = require('./array') +const {assign} = require('./common') + +module.exports = { + parse, + stringify, + tokenize, + + CommentArray, + assign +} diff --git a/reverse_engineering/node_modules/comment-json/src/parse.js b/reverse_engineering/node_modules/comment-json/src/parse.js new file mode 100644 index 0000000..aa5dd81 --- /dev/null +++ b/reverse_engineering/node_modules/comment-json/src/parse.js @@ -0,0 +1,451 @@ +// JSON formatting + +const esprima = require('esprima') + +const { + CommentArray, +} = require('./array') + +const { + PREFIX_BEFORE, + PREFIX_AFTER_PROP, + PREFIX_AFTER_COLON, + PREFIX_AFTER_VALUE, + PREFIX_AFTER, + + PREFIX_BEFORE_ALL, + PREFIX_AFTER_ALL, + + BRACKET_OPEN, + BRACKET_CLOSE, + CURLY_BRACKET_OPEN, + CURLY_BRACKET_CLOSE, + + COLON, + COMMA, + MINUS, + EMPTY, + + UNDEFINED, + + define, + assign_non_prop_comments +} = require('./common') + +const tokenize = code => esprima.tokenize(code, { + comment: true, + loc: true +}) + +const previous_hosts = [] +let comments_host = null +let unassigned_comments = null + +const previous_props = [] +let last_prop + +let remove_comments = false +let inline = false +let tokens = null +let last = null +let current = null +let index +let reviver = null + +const clean = () => { + previous_props.length = + previous_hosts.length = 0 + + last = null + last_prop = UNDEFINED +} + +const free = () => { + clean() + + tokens.length = 0 + + unassigned_comments = + comments_host = + tokens = + last = + current = + reviver = null +} + +const symbolFor = prefix => Symbol.for( + last_prop !== UNDEFINED + ? prefix + COLON + last_prop + : prefix +) + +const transform = (k, v) => reviver + ? reviver(k, v) + : v + +const unexpected = () => { + const error = new SyntaxError(`Unexpected token ${current.value.slice(0, 1)}`) + Object.assign(error, current.loc.start) + + throw error +} + +const unexpected_end = () => { + const error = new SyntaxError('Unexpected end of JSON input') + Object.assign(error, last + ? last.loc.end + // Empty string + : { + line: 1, + column: 0 + }) + + throw error +} + +// Move the reader to the next +const next = () => { + const new_token = tokens[++ index] + inline = current + && new_token + && current.loc.end.line === new_token.loc.start.line + || false + + last = current + current = new_token +} + +const type = () => { + if (!current) { + unexpected_end() + } + + return current.type === 'Punctuator' + ? current.value + : current.type +} + +const is = t => type() === t + +const expect = a => { + if (!is(a)) { + unexpected() + } +} + +const set_comments_host = new_host => { + previous_hosts.push(comments_host) + comments_host = new_host +} + +const restore_comments_host = () => { + comments_host = previous_hosts.pop() +} + +const assign_after_comments = () => { + if (!unassigned_comments) { + return + } + + const after_comments = [] + + for (const comment of unassigned_comments) { + // If the comment is inline, then it is an after-comma comment + if (comment.inline) { + after_comments.push(comment) + // Otherwise, all comments are before: comment + } else { + break + } + } + + const {length} = after_comments + if (!length) { + return + } + + if (length === unassigned_comments.length) { + // If unassigned_comments are all consumed + unassigned_comments = null + } else { + unassigned_comments.splice(0, length) + } + + define(comments_host, symbolFor(PREFIX_AFTER), after_comments) +} + +const assign_comments = prefix => { + if (!unassigned_comments) { + return + } + + define(comments_host, symbolFor(prefix), unassigned_comments) + + unassigned_comments = null +} + +const parse_comments = prefix => { + const comments = [] + + while ( + current + && ( + is('LineComment') + || is('BlockComment') + ) + ) { + const comment = { + ...current, + inline + } + + // delete comment.loc + comments.push(comment) + + next() + } + + if (remove_comments) { + return + } + + if (!comments.length) { + return + } + + if (prefix) { + define(comments_host, symbolFor(prefix), comments) + return + } + + unassigned_comments = comments +} + +const set_prop = (prop, push) => { + if (push) { + previous_props.push(last_prop) + } + + last_prop = prop +} + +const restore_prop = () => { + last_prop = previous_props.pop() +} + +const parse_object = () => { + const obj = {} + set_comments_host(obj) + set_prop(UNDEFINED, true) + + let started = false + let name + + parse_comments() + + while (!is(CURLY_BRACKET_CLOSE)) { + if (started) { + assign_comments(PREFIX_AFTER_VALUE) + + // key-value pair delimiter + expect(COMMA) + next() + parse_comments() + + assign_after_comments() + + // If there is a trailing comma, we might reach the end + // ``` + // { + // "a": 1, + // } + // ``` + if (is(CURLY_BRACKET_CLOSE)) { + break + } + } + + started = true + expect('String') + name = JSON.parse(current.value) + + set_prop(name) + assign_comments(PREFIX_BEFORE) + + next() + parse_comments(PREFIX_AFTER_PROP) + + expect(COLON) + + next() + parse_comments(PREFIX_AFTER_COLON) + + obj[name] = transform(name, walk()) + parse_comments() + } + + if (started) { + // If there are properties, + // then the unassigned comments are after comments + assign_comments(PREFIX_AFTER) + } + + // bypass } + next() + last_prop = undefined + + if (!started) { + // Otherwise, they are before comments + assign_comments(PREFIX_BEFORE) + } + + restore_comments_host() + restore_prop() + + return obj +} + +const parse_array = () => { + const array = new CommentArray() + set_comments_host(array) + set_prop(UNDEFINED, true) + + let started = false + let i = 0 + + parse_comments() + + while (!is(BRACKET_CLOSE)) { + if (started) { + assign_comments(PREFIX_AFTER_VALUE) + expect(COMMA) + next() + parse_comments() + + assign_after_comments() + + if (is(BRACKET_CLOSE)) { + break + } + } + + started = true + + set_prop(i) + assign_comments(PREFIX_BEFORE) + + array[i] = transform(i, walk()) + i ++ + + parse_comments() + } + + if (started) { + assign_comments(PREFIX_AFTER) + } + + next() + last_prop = undefined + + if (!started) { + assign_comments(PREFIX_BEFORE) + } + + restore_comments_host() + restore_prop() + + return array +} + +function walk () { + let tt = type() + + if (tt === CURLY_BRACKET_OPEN) { + next() + return parse_object() + } + + if (tt === BRACKET_OPEN) { + next() + return parse_array() + } + + let negative = EMPTY + + // -1 + if (tt === MINUS) { + next() + tt = type() + negative = MINUS + } + + let v + + switch (tt) { + case 'String': + case 'Boolean': + case 'Null': + case 'Numeric': + v = current.value + next() + return JSON.parse(negative + v) + default: + } +} + +const isObject = subject => Object(subject) === subject + +const parse = (code, rev, no_comments) => { + // Clean variables in closure + clean() + + tokens = tokenize(code) + reviver = rev + remove_comments = no_comments + + if (!tokens.length) { + unexpected_end() + } + + index = - 1 + next() + + set_comments_host({}) + + parse_comments(PREFIX_BEFORE_ALL) + + let result = walk() + + parse_comments(PREFIX_AFTER_ALL) + + if (current) { + unexpected() + } + + if (!no_comments && result !== null) { + if (!isObject(result)) { + // 1 -> new Number(1) + // true -> new Boolean(1) + // "foo" -> new String("foo") + + // eslint-disable-next-line no-new-object + result = new Object(result) + } + + assign_non_prop_comments(result, comments_host) + } + + restore_comments_host() + + // reviver + result = transform('', result) + + free() + + return result +} + +module.exports = { + parse, + tokenize +} diff --git a/reverse_engineering/node_modules/comment-json/src/stringify.js b/reverse_engineering/node_modules/comment-json/src/stringify.js new file mode 100644 index 0000000..998ec36 --- /dev/null +++ b/reverse_engineering/node_modules/comment-json/src/stringify.js @@ -0,0 +1,367 @@ +const { + isArray, isObject, isFunction, isNumber, isString +} = require('core-util-is') +const repeat = require('repeat-string') + +const { + PREFIX_BEFORE_ALL, + PREFIX_BEFORE, + PREFIX_AFTER_PROP, + PREFIX_AFTER_COLON, + PREFIX_AFTER_VALUE, + PREFIX_AFTER, + PREFIX_AFTER_ALL, + + BRACKET_OPEN, + BRACKET_CLOSE, + CURLY_BRACKET_OPEN, + CURLY_BRACKET_CLOSE, + COLON, + COMMA, + EMPTY, + + UNDEFINED +} = require('./common') + +// eslint-disable-next-line no-control-regex, no-misleading-character-class +const ESCAPABLE = /[\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g + +// String constants +const SPACE = ' ' +const LF = '\n' +const STR_NULL = 'null' + +// Symbol tags +const BEFORE = prop => `${PREFIX_BEFORE}:${prop}` +const AFTER_PROP = prop => `${PREFIX_AFTER_PROP}:${prop}` +const AFTER_COLON = prop => `${PREFIX_AFTER_COLON}:${prop}` +const AFTER_VALUE = prop => `${PREFIX_AFTER_VALUE}:${prop}` +const AFTER = prop => `${PREFIX_AFTER}:${prop}` + +// table of character substitutions +const meta = { + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"': '\\"', + '\\': '\\\\' +} + +const escape = string => { + ESCAPABLE.lastIndex = 0 + + if (!ESCAPABLE.test(string)) { + return string + } + + return string.replace(ESCAPABLE, a => { + const c = meta[a] + return typeof c === 'string' + ? c + : a + }) +} + +// Escape no control characters, no quote characters, +// and no backslash characters, +// then we can safely slap some quotes around it. +const quote = string => `"${escape(string)}"` +const comment_stringify = (value, line) => line + ? `//${value}` + : `/*${value}*/` + +// display_block `boolean` whether the +// WHOLE block of comments is always a block group +const process_comments = (host, symbol_tag, deeper_gap, display_block) => { + const comments = host[Symbol.for(symbol_tag)] + if (!comments || !comments.length) { + return EMPTY + } + + let is_line_comment = false + + const str = comments.reduce((prev, { + inline, + type, + value + }) => { + const delimiter = inline + ? SPACE + : LF + deeper_gap + + is_line_comment = type === 'LineComment' + + return prev + delimiter + comment_stringify(value, is_line_comment) + }, EMPTY) + + + return display_block + // line comment should always end with a LF + || is_line_comment + ? str + LF + deeper_gap + : str +} + +let replacer = null +let indent = EMPTY + +const clean = () => { + replacer = null + indent = EMPTY +} + +const join = (one, two, gap) => + one + ? two + // Symbol.for('before') and Symbol.for('before:prop') + // might both exist if user mannually add comments to the object + // and make a mistake. + // SO, we are not to only trimRight but trim for both sides + ? one + two.trim() + LF + gap + : one.trimRight() + LF + gap + : two + ? two.trimRight() + LF + gap + : EMPTY + +const join_content = (inside, value, gap) => { + const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true) + + return join(comment, inside, gap) +} + +// | deeper_gap | +// | gap | indent | +// [ +// "foo", +// "bar" +// ] +const array_stringify = (value, gap) => { + const deeper_gap = gap + indent + + const {length} = value + + // From the item to before close + let inside = EMPTY + let after_comma = EMPTY + + // Never use Array.prototype.forEach, + // that we should iterate all items + for (let i = 0; i < length; i ++) { + if (i !== 0) { + inside += COMMA + } + + const before = join( + after_comma, + process_comments(value, BEFORE(i), deeper_gap), + deeper_gap + ) + + inside += before || (LF + deeper_gap) + + // JSON.stringify([undefined]) => [null] + inside += stringify(i, value, deeper_gap) || STR_NULL + + inside += process_comments(value, AFTER_VALUE(i), deeper_gap) + + after_comma = process_comments(value, AFTER(i), deeper_gap) + } + + inside += join( + after_comma, + process_comments(value, PREFIX_AFTER, deeper_gap), + deeper_gap + ) + + return BRACKET_OPEN + + join_content(inside, value, gap) + + BRACKET_CLOSE +} + +// | deeper_gap | +// | gap | indent | +// { +// "foo": 1, +// "bar": 2 +// } +const object_stringify = (value, gap) => { + // Due to a specification blunder in ECMAScript, typeof null is 'object', + // so watch out for that case. + if (!value) { + return 'null' + } + + const deeper_gap = gap + indent + + // From the first element to before close + let inside = EMPTY + let after_comma = EMPTY + let first = true + + const keys = isArray(replacer) + ? replacer + : Object.keys(value) + + const iteratee = key => { + // Stringified value + const sv = stringify(key, value, deeper_gap) + + // If a value is undefined, then the key-value pair should be ignored + if (sv === UNDEFINED) { + return + } + + // The treat ment + if (!first) { + inside += COMMA + } + + first = false + + const before = join( + after_comma, + process_comments(value, BEFORE(key), deeper_gap), + deeper_gap + ) + + inside += before || (LF + deeper_gap) + + inside += quote(key) + + process_comments(value, AFTER_PROP(key), deeper_gap) + + COLON + + process_comments(value, AFTER_COLON(key), deeper_gap) + + SPACE + + sv + + process_comments(value, AFTER_VALUE(key), deeper_gap) + + after_comma = process_comments(value, AFTER(key), deeper_gap) + } + + keys.forEach(iteratee) + + // if (after_comma) { + // inside += COMMA + // } + + inside += join( + after_comma, + process_comments(value, PREFIX_AFTER, deeper_gap), + deeper_gap + ) + + return CURLY_BRACKET_OPEN + + join_content(inside, value, gap) + + CURLY_BRACKET_CLOSE +} + +// @param {string} key +// @param {Object} holder +// @param {function()|Array} replacer +// @param {string} indent +// @param {string} gap +function stringify (key, holder, gap) { + let value = holder[key] + + // If the value has a toJSON method, call it to obtain a replacement value. + if (isObject(value) && isFunction(value.toJSON)) { + value = value.toJSON(key) + } + + // If we were called with a replacer function, then call the replacer to + // obtain a replacement value. + if (isFunction(replacer)) { + value = replacer.call(holder, key, value) + } + + switch (typeof value) { + case 'string': + return quote(value) + + case 'number': + // JSON numbers must be finite. Encode non-finite numbers as null. + return Number.isFinite(value) ? String(value) : STR_NULL + + case 'boolean': + case 'null': + + // If the value is a boolean or null, convert it to a string. Note: + // typeof null does not produce 'null'. The case is included here in + // the remote chance that this gets fixed someday. + return String(value) + + // If the type is 'object', we might be dealing with an object or an array or + // null. + case 'object': + return isArray(value) + ? array_stringify(value, gap) + : object_stringify(value, gap) + + // undefined + default: + // JSON.stringify(undefined) === undefined + // JSON.stringify('foo', () => undefined) === undefined + } +} + +const get_indent = space => isString(space) + // If the space parameter is a string, it will be used as the indent string. + ? space + : isNumber(space) + ? repeat(SPACE, space) + : EMPTY + +const {toString} = Object.prototype +const PRIMITIVE_OBJECT_TYPES = [ + '[object Number]', + '[object String]', + '[object Boolean]' +] + +const is_primitive_object = subject => { + if (typeof subject !== 'object') { + return false + } + + const str = toString.call(subject) + return PRIMITIVE_OBJECT_TYPES.includes(str) +} + +// @param {function()|Array} replacer +// @param {string|number} space +module.exports = (value, replacer_, space) => { + // The stringify method takes a value and an optional replacer, and an optional + // space parameter, and returns a JSON text. The replacer can be a function + // that can replace values, or an array of strings that will select the keys. + // A default replacer method can be provided. Use of the space parameter can + // produce text that is more easily readable. + + // If the space parameter is a number, make an indent string containing that + // many spaces. + const indent_ = get_indent(space) + + if (!indent_) { + return JSON.stringify(value, replacer_) + } + + // vanilla `JSON.parse` allow invalid replacer + if (!isFunction(replacer_) && !isArray(replacer_)) { + replacer_ = null + } + + replacer = replacer_ + indent = indent_ + + const str = is_primitive_object(value) + ? JSON.stringify(value) + : stringify('', {'': value}, EMPTY) + + clean() + + return isObject(value) + ? process_comments(value, PREFIX_BEFORE_ALL, EMPTY).trimLeft() + + str + + process_comments(value, PREFIX_AFTER_ALL, EMPTY).trimRight() + : str +} diff --git a/reverse_engineering/node_modules/core-util-is/LICENSE b/reverse_engineering/node_modules/core-util-is/LICENSE new file mode 100644 index 0000000..d8d7f94 --- /dev/null +++ b/reverse_engineering/node_modules/core-util-is/LICENSE @@ -0,0 +1,19 @@ +Copyright Node.js contributors. All rights reserved. + +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. diff --git a/reverse_engineering/node_modules/core-util-is/README.md b/reverse_engineering/node_modules/core-util-is/README.md new file mode 100644 index 0000000..5a76b41 --- /dev/null +++ b/reverse_engineering/node_modules/core-util-is/README.md @@ -0,0 +1,3 @@ +# core-util-is + +The `util.is*` functions introduced in Node v0.12. diff --git a/reverse_engineering/node_modules/core-util-is/float.patch b/reverse_engineering/node_modules/core-util-is/float.patch new file mode 100644 index 0000000..a06d5c0 --- /dev/null +++ b/reverse_engineering/node_modules/core-util-is/float.patch @@ -0,0 +1,604 @@ +diff --git a/lib/util.js b/lib/util.js +index a03e874..9074e8e 100644 +--- a/lib/util.js ++++ b/lib/util.js +@@ -19,430 +19,6 @@ + // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + // USE OR OTHER DEALINGS IN THE SOFTWARE. + +-var formatRegExp = /%[sdj%]/g; +-exports.format = function(f) { +- if (!isString(f)) { +- var objects = []; +- for (var i = 0; i < arguments.length; i++) { +- objects.push(inspect(arguments[i])); +- } +- return objects.join(' '); +- } +- +- var i = 1; +- var args = arguments; +- var len = args.length; +- var str = String(f).replace(formatRegExp, function(x) { +- if (x === '%%') return '%'; +- if (i >= len) return x; +- switch (x) { +- case '%s': return String(args[i++]); +- case '%d': return Number(args[i++]); +- case '%j': +- try { +- return JSON.stringify(args[i++]); +- } catch (_) { +- return '[Circular]'; +- } +- default: +- return x; +- } +- }); +- for (var x = args[i]; i < len; x = args[++i]) { +- if (isNull(x) || !isObject(x)) { +- str += ' ' + x; +- } else { +- str += ' ' + inspect(x); +- } +- } +- return str; +-}; +- +- +-// Mark that a method should not be used. +-// Returns a modified function which warns once by default. +-// If --no-deprecation is set, then it is a no-op. +-exports.deprecate = function(fn, msg) { +- // Allow for deprecating things in the process of starting up. +- if (isUndefined(global.process)) { +- return function() { +- return exports.deprecate(fn, msg).apply(this, arguments); +- }; +- } +- +- if (process.noDeprecation === true) { +- return fn; +- } +- +- var warned = false; +- function deprecated() { +- if (!warned) { +- if (process.throwDeprecation) { +- throw new Error(msg); +- } else if (process.traceDeprecation) { +- console.trace(msg); +- } else { +- console.error(msg); +- } +- warned = true; +- } +- return fn.apply(this, arguments); +- } +- +- return deprecated; +-}; +- +- +-var debugs = {}; +-var debugEnviron; +-exports.debuglog = function(set) { +- if (isUndefined(debugEnviron)) +- debugEnviron = process.env.NODE_DEBUG || ''; +- set = set.toUpperCase(); +- if (!debugs[set]) { +- if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { +- var pid = process.pid; +- debugs[set] = function() { +- var msg = exports.format.apply(exports, arguments); +- console.error('%s %d: %s', set, pid, msg); +- }; +- } else { +- debugs[set] = function() {}; +- } +- } +- return debugs[set]; +-}; +- +- +-/** +- * Echos the value of a value. Trys to print the value out +- * in the best way possible given the different types. +- * +- * @param {Object} obj The object to print out. +- * @param {Object} opts Optional options object that alters the output. +- */ +-/* legacy: obj, showHidden, depth, colors*/ +-function inspect(obj, opts) { +- // default options +- var ctx = { +- seen: [], +- stylize: stylizeNoColor +- }; +- // legacy... +- if (arguments.length >= 3) ctx.depth = arguments[2]; +- if (arguments.length >= 4) ctx.colors = arguments[3]; +- if (isBoolean(opts)) { +- // legacy... +- ctx.showHidden = opts; +- } else if (opts) { +- // got an "options" object +- exports._extend(ctx, opts); +- } +- // set default options +- if (isUndefined(ctx.showHidden)) ctx.showHidden = false; +- if (isUndefined(ctx.depth)) ctx.depth = 2; +- if (isUndefined(ctx.colors)) ctx.colors = false; +- if (isUndefined(ctx.customInspect)) ctx.customInspect = true; +- if (ctx.colors) ctx.stylize = stylizeWithColor; +- return formatValue(ctx, obj, ctx.depth); +-} +-exports.inspect = inspect; +- +- +-// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +-inspect.colors = { +- 'bold' : [1, 22], +- 'italic' : [3, 23], +- 'underline' : [4, 24], +- 'inverse' : [7, 27], +- 'white' : [37, 39], +- 'grey' : [90, 39], +- 'black' : [30, 39], +- 'blue' : [34, 39], +- 'cyan' : [36, 39], +- 'green' : [32, 39], +- 'magenta' : [35, 39], +- 'red' : [31, 39], +- 'yellow' : [33, 39] +-}; +- +-// Don't use 'blue' not visible on cmd.exe +-inspect.styles = { +- 'special': 'cyan', +- 'number': 'yellow', +- 'boolean': 'yellow', +- 'undefined': 'grey', +- 'null': 'bold', +- 'string': 'green', +- 'date': 'magenta', +- // "name": intentionally not styling +- 'regexp': 'red' +-}; +- +- +-function stylizeWithColor(str, styleType) { +- var style = inspect.styles[styleType]; +- +- if (style) { +- return '\u001b[' + inspect.colors[style][0] + 'm' + str + +- '\u001b[' + inspect.colors[style][1] + 'm'; +- } else { +- return str; +- } +-} +- +- +-function stylizeNoColor(str, styleType) { +- return str; +-} +- +- +-function arrayToHash(array) { +- var hash = {}; +- +- array.forEach(function(val, idx) { +- hash[val] = true; +- }); +- +- return hash; +-} +- +- +-function formatValue(ctx, value, recurseTimes) { +- // Provide a hook for user-specified inspect functions. +- // Check that value is an object with an inspect function on it +- if (ctx.customInspect && +- value && +- isFunction(value.inspect) && +- // Filter out the util module, it's inspect function is special +- value.inspect !== exports.inspect && +- // Also filter out any prototype objects using the circular check. +- !(value.constructor && value.constructor.prototype === value)) { +- var ret = value.inspect(recurseTimes, ctx); +- if (!isString(ret)) { +- ret = formatValue(ctx, ret, recurseTimes); +- } +- return ret; +- } +- +- // Primitive types cannot have properties +- var primitive = formatPrimitive(ctx, value); +- if (primitive) { +- return primitive; +- } +- +- // Look up the keys of the object. +- var keys = Object.keys(value); +- var visibleKeys = arrayToHash(keys); +- +- if (ctx.showHidden) { +- keys = Object.getOwnPropertyNames(value); +- } +- +- // Some type of object without properties can be shortcutted. +- if (keys.length === 0) { +- if (isFunction(value)) { +- var name = value.name ? ': ' + value.name : ''; +- return ctx.stylize('[Function' + name + ']', 'special'); +- } +- if (isRegExp(value)) { +- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); +- } +- if (isDate(value)) { +- return ctx.stylize(Date.prototype.toString.call(value), 'date'); +- } +- if (isError(value)) { +- return formatError(value); +- } +- } +- +- var base = '', array = false, braces = ['{', '}']; +- +- // Make Array say that they are Array +- if (isArray(value)) { +- array = true; +- braces = ['[', ']']; +- } +- +- // Make functions say that they are functions +- if (isFunction(value)) { +- var n = value.name ? ': ' + value.name : ''; +- base = ' [Function' + n + ']'; +- } +- +- // Make RegExps say that they are RegExps +- if (isRegExp(value)) { +- base = ' ' + RegExp.prototype.toString.call(value); +- } +- +- // Make dates with properties first say the date +- if (isDate(value)) { +- base = ' ' + Date.prototype.toUTCString.call(value); +- } +- +- // Make error with message first say the error +- if (isError(value)) { +- base = ' ' + formatError(value); +- } +- +- if (keys.length === 0 && (!array || value.length == 0)) { +- return braces[0] + base + braces[1]; +- } +- +- if (recurseTimes < 0) { +- if (isRegExp(value)) { +- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); +- } else { +- return ctx.stylize('[Object]', 'special'); +- } +- } +- +- ctx.seen.push(value); +- +- var output; +- if (array) { +- output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); +- } else { +- output = keys.map(function(key) { +- return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); +- }); +- } +- +- ctx.seen.pop(); +- +- return reduceToSingleString(output, base, braces); +-} +- +- +-function formatPrimitive(ctx, value) { +- if (isUndefined(value)) +- return ctx.stylize('undefined', 'undefined'); +- if (isString(value)) { +- var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') +- .replace(/'/g, "\\'") +- .replace(/\\"/g, '"') + '\''; +- return ctx.stylize(simple, 'string'); +- } +- if (isNumber(value)) { +- // Format -0 as '-0'. Strict equality won't distinguish 0 from -0, +- // so instead we use the fact that 1 / -0 < 0 whereas 1 / 0 > 0 . +- if (value === 0 && 1 / value < 0) +- return ctx.stylize('-0', 'number'); +- return ctx.stylize('' + value, 'number'); +- } +- if (isBoolean(value)) +- return ctx.stylize('' + value, 'boolean'); +- // For some reason typeof null is "object", so special case here. +- if (isNull(value)) +- return ctx.stylize('null', 'null'); +-} +- +- +-function formatError(value) { +- return '[' + Error.prototype.toString.call(value) + ']'; +-} +- +- +-function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { +- var output = []; +- for (var i = 0, l = value.length; i < l; ++i) { +- if (hasOwnProperty(value, String(i))) { +- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, +- String(i), true)); +- } else { +- output.push(''); +- } +- } +- keys.forEach(function(key) { +- if (!key.match(/^\d+$/)) { +- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, +- key, true)); +- } +- }); +- return output; +-} +- +- +-function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { +- var name, str, desc; +- desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; +- if (desc.get) { +- if (desc.set) { +- str = ctx.stylize('[Getter/Setter]', 'special'); +- } else { +- str = ctx.stylize('[Getter]', 'special'); +- } +- } else { +- if (desc.set) { +- str = ctx.stylize('[Setter]', 'special'); +- } +- } +- if (!hasOwnProperty(visibleKeys, key)) { +- name = '[' + key + ']'; +- } +- if (!str) { +- if (ctx.seen.indexOf(desc.value) < 0) { +- if (isNull(recurseTimes)) { +- str = formatValue(ctx, desc.value, null); +- } else { +- str = formatValue(ctx, desc.value, recurseTimes - 1); +- } +- if (str.indexOf('\n') > -1) { +- if (array) { +- str = str.split('\n').map(function(line) { +- return ' ' + line; +- }).join('\n').substr(2); +- } else { +- str = '\n' + str.split('\n').map(function(line) { +- return ' ' + line; +- }).join('\n'); +- } +- } +- } else { +- str = ctx.stylize('[Circular]', 'special'); +- } +- } +- if (isUndefined(name)) { +- if (array && key.match(/^\d+$/)) { +- return str; +- } +- name = JSON.stringify('' + key); +- if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { +- name = name.substr(1, name.length - 2); +- name = ctx.stylize(name, 'name'); +- } else { +- name = name.replace(/'/g, "\\'") +- .replace(/\\"/g, '"') +- .replace(/(^"|"$)/g, "'"); +- name = ctx.stylize(name, 'string'); +- } +- } +- +- return name + ': ' + str; +-} +- +- +-function reduceToSingleString(output, base, braces) { +- var numLinesEst = 0; +- var length = output.reduce(function(prev, cur) { +- numLinesEst++; +- if (cur.indexOf('\n') >= 0) numLinesEst++; +- return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; +- }, 0); +- +- if (length > 60) { +- return braces[0] + +- (base === '' ? '' : base + '\n ') + +- ' ' + +- output.join(',\n ') + +- ' ' + +- braces[1]; +- } +- +- return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +-} +- +- + // NOTE: These type checking functions intentionally don't use `instanceof` + // because it is fragile and can be easily faked with `Object.create()`. + function isArray(ar) { +@@ -522,166 +98,10 @@ function isPrimitive(arg) { + exports.isPrimitive = isPrimitive; + + function isBuffer(arg) { +- return arg instanceof Buffer; ++ return Buffer.isBuffer(arg); + } + exports.isBuffer = isBuffer; + + function objectToString(o) { + return Object.prototype.toString.call(o); +-} +- +- +-function pad(n) { +- return n < 10 ? '0' + n.toString(10) : n.toString(10); +-} +- +- +-var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', +- 'Oct', 'Nov', 'Dec']; +- +-// 26 Feb 16:19:34 +-function timestamp() { +- var d = new Date(); +- var time = [pad(d.getHours()), +- pad(d.getMinutes()), +- pad(d.getSeconds())].join(':'); +- return [d.getDate(), months[d.getMonth()], time].join(' '); +-} +- +- +-// log is just a thin wrapper to console.log that prepends a timestamp +-exports.log = function() { +- console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +-}; +- +- +-/** +- * Inherit the prototype methods from one constructor into another. +- * +- * The Function.prototype.inherits from lang.js rewritten as a standalone +- * function (not on Function.prototype). NOTE: If this file is to be loaded +- * during bootstrapping this function needs to be rewritten using some native +- * functions as prototype setup using normal JavaScript does not work as +- * expected during bootstrapping (see mirror.js in r114903). +- * +- * @param {function} ctor Constructor function which needs to inherit the +- * prototype. +- * @param {function} superCtor Constructor function to inherit prototype from. +- */ +-exports.inherits = function(ctor, superCtor) { +- ctor.super_ = superCtor; +- ctor.prototype = Object.create(superCtor.prototype, { +- constructor: { +- value: ctor, +- enumerable: false, +- writable: true, +- configurable: true +- } +- }); +-}; +- +-exports._extend = function(origin, add) { +- // Don't do anything if add isn't an object +- if (!add || !isObject(add)) return origin; +- +- var keys = Object.keys(add); +- var i = keys.length; +- while (i--) { +- origin[keys[i]] = add[keys[i]]; +- } +- return origin; +-}; +- +-function hasOwnProperty(obj, prop) { +- return Object.prototype.hasOwnProperty.call(obj, prop); +-} +- +- +-// Deprecated old stuff. +- +-exports.p = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- console.error(exports.inspect(arguments[i])); +- } +-}, 'util.p: Use console.error() instead'); +- +- +-exports.exec = exports.deprecate(function() { +- return require('child_process').exec.apply(this, arguments); +-}, 'util.exec is now called `child_process.exec`.'); +- +- +-exports.print = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stdout.write(String(arguments[i])); +- } +-}, 'util.print: Use console.log instead'); +- +- +-exports.puts = exports.deprecate(function() { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stdout.write(arguments[i] + '\n'); +- } +-}, 'util.puts: Use console.log instead'); +- +- +-exports.debug = exports.deprecate(function(x) { +- process.stderr.write('DEBUG: ' + x + '\n'); +-}, 'util.debug: Use console.error instead'); +- +- +-exports.error = exports.deprecate(function(x) { +- for (var i = 0, len = arguments.length; i < len; ++i) { +- process.stderr.write(arguments[i] + '\n'); +- } +-}, 'util.error: Use console.error instead'); +- +- +-exports.pump = exports.deprecate(function(readStream, writeStream, callback) { +- var callbackCalled = false; +- +- function call(a, b, c) { +- if (callback && !callbackCalled) { +- callback(a, b, c); +- callbackCalled = true; +- } +- } +- +- readStream.addListener('data', function(chunk) { +- if (writeStream.write(chunk) === false) readStream.pause(); +- }); +- +- writeStream.addListener('drain', function() { +- readStream.resume(); +- }); +- +- readStream.addListener('end', function() { +- writeStream.end(); +- }); +- +- readStream.addListener('close', function() { +- call(); +- }); +- +- readStream.addListener('error', function(err) { +- writeStream.end(); +- call(err); +- }); +- +- writeStream.addListener('error', function(err) { +- readStream.destroy(); +- call(err); +- }); +-}, 'util.pump(): Use readableStream.pipe() instead'); +- +- +-var uv; +-exports._errnoException = function(err, syscall) { +- if (isUndefined(uv)) uv = process.binding('uv'); +- var errname = uv.errname(err); +- var e = new Error(syscall + ' ' + errname); +- e.code = errname; +- e.errno = errname; +- e.syscall = syscall; +- return e; +-}; ++} \ No newline at end of file diff --git a/reverse_engineering/node_modules/core-util-is/lib/util.js b/reverse_engineering/node_modules/core-util-is/lib/util.js new file mode 100644 index 0000000..ff4c851 --- /dev/null +++ b/reverse_engineering/node_modules/core-util-is/lib/util.js @@ -0,0 +1,107 @@ +// Copyright Joyent, Inc. and other Node contributors. +// +// 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. + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. + +function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); + } + return objectToString(arg) === '[object Array]'; +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = Buffer.isBuffer; + +function objectToString(o) { + return Object.prototype.toString.call(o); +} diff --git a/reverse_engineering/node_modules/core-util-is/package.json b/reverse_engineering/node_modules/core-util-is/package.json new file mode 100644 index 0000000..973ec46 --- /dev/null +++ b/reverse_engineering/node_modules/core-util-is/package.json @@ -0,0 +1,62 @@ +{ + "_from": "core-util-is@^1.0.2", + "_id": "core-util-is@1.0.2", + "_inBundle": false, + "_integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "_location": "/core-util-is", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "core-util-is@^1.0.2", + "name": "core-util-is", + "escapedName": "core-util-is", + "rawSpec": "^1.0.2", + "saveSpec": null, + "fetchSpec": "^1.0.2" + }, + "_requiredBy": [ + "/comment-json" + ], + "_resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "_shasum": "b5fd54220aa2bc5ab57aab7140c940754503c1a7", + "_spec": "core-util-is@^1.0.2", + "_where": "/home/volodymyr/projects/plugins/OpenAPI/reverse_engineering/node_modules/comment-json", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/core-util-is/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "The `util.is*` functions introduced in Node v0.12.", + "devDependencies": { + "tap": "^2.3.0" + }, + "homepage": "https://github.com/isaacs/core-util-is#readme", + "keywords": [ + "util", + "isBuffer", + "isArray", + "isNumber", + "isString", + "isRegExp", + "isThis", + "isThat", + "polyfill" + ], + "license": "MIT", + "main": "lib/util.js", + "name": "core-util-is", + "repository": { + "type": "git", + "url": "git://github.com/isaacs/core-util-is.git" + }, + "scripts": { + "test": "tap test.js" + }, + "version": "1.0.2" +} diff --git a/reverse_engineering/node_modules/core-util-is/test.js b/reverse_engineering/node_modules/core-util-is/test.js new file mode 100644 index 0000000..1a490c6 --- /dev/null +++ b/reverse_engineering/node_modules/core-util-is/test.js @@ -0,0 +1,68 @@ +var assert = require('tap'); + +var t = require('./lib/util'); + +assert.equal(t.isArray([]), true); +assert.equal(t.isArray({}), false); + +assert.equal(t.isBoolean(null), false); +assert.equal(t.isBoolean(true), true); +assert.equal(t.isBoolean(false), true); + +assert.equal(t.isNull(null), true); +assert.equal(t.isNull(undefined), false); +assert.equal(t.isNull(false), false); +assert.equal(t.isNull(), false); + +assert.equal(t.isNullOrUndefined(null), true); +assert.equal(t.isNullOrUndefined(undefined), true); +assert.equal(t.isNullOrUndefined(false), false); +assert.equal(t.isNullOrUndefined(), true); + +assert.equal(t.isNumber(null), false); +assert.equal(t.isNumber('1'), false); +assert.equal(t.isNumber(1), true); + +assert.equal(t.isString(null), false); +assert.equal(t.isString('1'), true); +assert.equal(t.isString(1), false); + +assert.equal(t.isSymbol(null), false); +assert.equal(t.isSymbol('1'), false); +assert.equal(t.isSymbol(1), false); +assert.equal(t.isSymbol(Symbol()), true); + +assert.equal(t.isUndefined(null), false); +assert.equal(t.isUndefined(undefined), true); +assert.equal(t.isUndefined(false), false); +assert.equal(t.isUndefined(), true); + +assert.equal(t.isRegExp(null), false); +assert.equal(t.isRegExp('1'), false); +assert.equal(t.isRegExp(new RegExp()), true); + +assert.equal(t.isObject({}), true); +assert.equal(t.isObject([]), true); +assert.equal(t.isObject(new RegExp()), true); +assert.equal(t.isObject(new Date()), true); + +assert.equal(t.isDate(null), false); +assert.equal(t.isDate('1'), false); +assert.equal(t.isDate(new Date()), true); + +assert.equal(t.isError(null), false); +assert.equal(t.isError({ err: true }), false); +assert.equal(t.isError(new Error()), true); + +assert.equal(t.isFunction(null), false); +assert.equal(t.isFunction({ }), false); +assert.equal(t.isFunction(function() {}), true); + +assert.equal(t.isPrimitive(null), true); +assert.equal(t.isPrimitive(''), true); +assert.equal(t.isPrimitive(0), true); +assert.equal(t.isPrimitive(new Date()), false); + +assert.equal(t.isBuffer(null), false); +assert.equal(t.isBuffer({}), false); +assert.equal(t.isBuffer(new Buffer(0)), true); diff --git a/reverse_engineering/node_modules/has-own-prop/index.d.ts b/reverse_engineering/node_modules/has-own-prop/index.d.ts new file mode 100644 index 0000000..b74bd5f --- /dev/null +++ b/reverse_engineering/node_modules/has-own-prop/index.d.ts @@ -0,0 +1,17 @@ +/** +Shortcut for `Object.prototype.hasOwnProperty.call(object, property)`. + +@example +``` +import hasOwnProp = require('has-own-prop'); + +hasOwnProp({}, 'hello'); +//=> false + +hasOwnProp([1, 2, 3], 0); +//=> true +``` +*/ +declare function hasOwnProp(object: unknown, key: string | number | symbol): boolean; + +export = hasOwnProp; diff --git a/reverse_engineering/node_modules/has-own-prop/index.js b/reverse_engineering/node_modules/has-own-prop/index.js new file mode 100644 index 0000000..bb1d335 --- /dev/null +++ b/reverse_engineering/node_modules/has-own-prop/index.js @@ -0,0 +1,4 @@ +'use strict'; +const hasOwnProp = Object.prototype.hasOwnProperty; + +module.exports = (object, property) => hasOwnProp.call(object, property); diff --git a/reverse_engineering/node_modules/has-own-prop/license b/reverse_engineering/node_modules/has-own-prop/license new file mode 100644 index 0000000..e7af2f7 --- /dev/null +++ b/reverse_engineering/node_modules/has-own-prop/license @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) Sindre Sorhus (sindresorhus.com) + +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. diff --git a/reverse_engineering/node_modules/has-own-prop/package.json b/reverse_engineering/node_modules/has-own-prop/package.json new file mode 100644 index 0000000..50605ab --- /dev/null +++ b/reverse_engineering/node_modules/has-own-prop/package.json @@ -0,0 +1,65 @@ +{ + "_from": "has-own-prop@^2.0.0", + "_id": "has-own-prop@2.0.0", + "_inBundle": false, + "_integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", + "_location": "/has-own-prop", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "has-own-prop@^2.0.0", + "name": "has-own-prop", + "escapedName": "has-own-prop", + "rawSpec": "^2.0.0", + "saveSpec": null, + "fetchSpec": "^2.0.0" + }, + "_requiredBy": [ + "/comment-json" + ], + "_resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", + "_shasum": "f0f95d58f65804f5d218db32563bb85b8e0417af", + "_spec": "has-own-prop@^2.0.0", + "_where": "/home/volodymyr/projects/plugins/OpenAPI/reverse_engineering/node_modules/comment-json", + "author": { + "name": "Sindre Sorhus", + "email": "sindresorhus@gmail.com", + "url": "sindresorhus.com" + }, + "bugs": { + "url": "https://github.com/sindresorhus/has-own-prop/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "A safer `.hasOwnProperty()`", + "devDependencies": { + "ava": "^2.1.0", + "tsd": "^0.7.3", + "xo": "^0.24.0" + }, + "engines": { + "node": ">=8" + }, + "files": [ + "index.js", + "index.d.ts" + ], + "homepage": "https://github.com/sindresorhus/has-own-prop#readme", + "keywords": [ + "object", + "has", + "own", + "property" + ], + "license": "MIT", + "name": "has-own-prop", + "repository": { + "type": "git", + "url": "git+https://github.com/sindresorhus/has-own-prop.git" + }, + "scripts": { + "test": "xo && ava && tsd" + }, + "version": "2.0.0" +} diff --git a/reverse_engineering/node_modules/has-own-prop/readme.md b/reverse_engineering/node_modules/has-own-prop/readme.md new file mode 100644 index 0000000..b934b60 --- /dev/null +++ b/reverse_engineering/node_modules/has-own-prop/readme.md @@ -0,0 +1,30 @@ +# has-own-prop [![Build Status](https://travis-ci.org/sindresorhus/has-own-prop.svg?branch=master)](https://travis-ci.org/sindresorhus/has-own-prop) + +> A safer `.hasOwnProperty()` + +Shortcut for `Object.prototype.hasOwnProperty.call(object, property)`. + +You shouldn't use `.hasOwnProperty()` as it won't exist on [objects created with `Object.create(null)`](https://stackoverflow.com/a/12017703/64949) or it can have been overridden. + + +## Install + +``` +$ npm install has-own-prop +``` + + +## Usage + +```js +const hasOwnProp = require('has-own-prop'); + +const object = Object.create(null); +object.unicorn = true; + +object.hasOwnProperty('unicorn'); +//=> 'TypeError: undefined is not a function' + +hasOwnProp(object, 'unicorn'); +//=> true +``` diff --git a/reverse_engineering/node_modules/repeat-string/LICENSE b/reverse_engineering/node_modules/repeat-string/LICENSE new file mode 100644 index 0000000..39245ac --- /dev/null +++ b/reverse_engineering/node_modules/repeat-string/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014-2016, Jon Schlinkert. + +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. diff --git a/reverse_engineering/node_modules/repeat-string/README.md b/reverse_engineering/node_modules/repeat-string/README.md new file mode 100644 index 0000000..aaa5e91 --- /dev/null +++ b/reverse_engineering/node_modules/repeat-string/README.md @@ -0,0 +1,136 @@ +# repeat-string [![NPM version](https://img.shields.io/npm/v/repeat-string.svg?style=flat)](https://www.npmjs.com/package/repeat-string) [![NPM monthly downloads](https://img.shields.io/npm/dm/repeat-string.svg?style=flat)](https://npmjs.org/package/repeat-string) [![NPM total downloads](https://img.shields.io/npm/dt/repeat-string.svg?style=flat)](https://npmjs.org/package/repeat-string) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/repeat-string.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/repeat-string) + +> Repeat the given string n times. Fastest implementation for repeating a string. + +## Install + +Install with [npm](https://www.npmjs.com/): + +```sh +$ npm install --save repeat-string +``` + +## Usage + +### [repeat](index.js#L41) + +Repeat the given `string` the specified `number` of times. + +**Example:** + +**Example** + +```js +var repeat = require('repeat-string'); +repeat('A', 5); +//=> AAAAA +``` + +**Params** + +* `string` **{String}**: The string to repeat +* `number` **{Number}**: The number of times to repeat the string +* `returns` **{String}**: Repeated string + +## Benchmarks + +Repeat string is significantly faster than the native method (which is itself faster than [repeating](https://github.com/sindresorhus/repeating)): + +```sh +# 2x +repeat-string β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (26,953,977 ops/sec) +repeating β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (9,855,695 ops/sec) +native β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (19,453,895 ops/sec) + +# 3x +repeat-string β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (19,445,252 ops/sec) +repeating β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (8,661,565 ops/sec) +native β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (16,020,598 ops/sec) + +# 10x +repeat-string β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (23,792,521 ops/sec) +repeating β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (8,571,332 ops/sec) +native β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (14,582,955 ops/sec) + +# 50x +repeat-string β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (23,640,179 ops/sec) +repeating β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (5,505,509 ops/sec) +native β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (10,085,557 ops/sec) + +# 250x +repeat-string β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (23,489,618 ops/sec) +repeating β–ˆβ–ˆβ–ˆβ–ˆ (3,962,937 ops/sec) +native β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (7,724,892 ops/sec) + +# 2000x +repeat-string β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (20,315,172 ops/sec) +repeating β–ˆβ–ˆβ–ˆβ–ˆ (3,297,079 ops/sec) +native β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (6,203,331 ops/sec) + +# 20000x +repeat-string β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (23,382,915 ops/sec) +repeating β–ˆβ–ˆβ–ˆ (2,980,058 ops/sec) +native β–ˆβ–ˆβ–ˆβ–ˆβ–ˆ (5,578,808 ops/sec) +``` + +**Run the benchmarks** + +Install dev dependencies: + +```sh +npm i -d && node benchmark +``` + +## About + +### Related projects + +[repeat-element](https://www.npmjs.com/package/repeat-element): Create an array by repeating the given value n times. | [homepage](https://github.com/jonschlinkert/repeat-element "Create an array by repeating the given value n times.") + +### Contributing + +Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). + +### Contributors + +| **Commits** | **Contributor**
| +| --- | --- | +| 51 | [jonschlinkert](https://github.com/jonschlinkert) | +| 2 | [LinusU](https://github.com/LinusU) | +| 2 | [tbusser](https://github.com/tbusser) | +| 1 | [doowb](https://github.com/doowb) | +| 1 | [wooorm](https://github.com/wooorm) | + +### Building docs + +_(This document was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_ + +To generate the readme and API documentation with [verb](https://github.com/verbose/verb): + +```sh +$ npm install -g verb verb-generate-readme && verb +``` + +### Running tests + +Install dev dependencies: + +```sh +$ npm install -d && npm test +``` + +### Author + +**Jon Schlinkert** + +* [github/jonschlinkert](https://github.com/jonschlinkert) +* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) + +### License + +Copyright Β© 2016, [Jon Schlinkert](http://github.com/jonschlinkert). +Released under the [MIT license](https://github.com/jonschlinkert/repeat-string/blob/master/LICENSE). + +*** + +_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.2.0, on October 23, 2016._ \ No newline at end of file diff --git a/reverse_engineering/node_modules/repeat-string/index.js b/reverse_engineering/node_modules/repeat-string/index.js new file mode 100644 index 0000000..4459afd --- /dev/null +++ b/reverse_engineering/node_modules/repeat-string/index.js @@ -0,0 +1,70 @@ +/*! + * repeat-string + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +'use strict'; + +/** + * Results cache + */ + +var res = ''; +var cache; + +/** + * Expose `repeat` + */ + +module.exports = repeat; + +/** + * Repeat the given `string` the specified `number` + * of times. + * + * **Example:** + * + * ```js + * var repeat = require('repeat-string'); + * repeat('A', 5); + * //=> AAAAA + * ``` + * + * @param {String} `string` The string to repeat + * @param {Number} `number` The number of times to repeat the string + * @return {String} Repeated string + * @api public + */ + +function repeat(str, num) { + if (typeof str !== 'string') { + throw new TypeError('expected a string'); + } + + // cover common, quick use cases + if (num === 1) return str; + if (num === 2) return str + str; + + var max = str.length * num; + if (cache !== str || typeof cache === 'undefined') { + cache = str; + res = ''; + } else if (res.length >= max) { + return res.substr(0, max); + } + + while (max > res.length && num > 1) { + if (num & 1) { + res += str; + } + + num >>= 1; + str += str; + } + + res += str; + res = res.substr(0, max); + return res; +} diff --git a/reverse_engineering/node_modules/repeat-string/package.json b/reverse_engineering/node_modules/repeat-string/package.json new file mode 100644 index 0000000..d5d2a56 --- /dev/null +++ b/reverse_engineering/node_modules/repeat-string/package.json @@ -0,0 +1,128 @@ +{ + "_from": "repeat-string@^1.6.1", + "_id": "repeat-string@1.6.1", + "_inBundle": false, + "_integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "_location": "/repeat-string", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "repeat-string@^1.6.1", + "name": "repeat-string", + "escapedName": "repeat-string", + "rawSpec": "^1.6.1", + "saveSpec": null, + "fetchSpec": "^1.6.1" + }, + "_requiredBy": [ + "/comment-json" + ], + "_resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "_shasum": "8dcae470e1c88abc2d600fff4a776286da75e637", + "_spec": "repeat-string@^1.6.1", + "_where": "/home/volodymyr/projects/plugins/OpenAPI/reverse_engineering/node_modules/comment-json", + "author": { + "name": "Jon Schlinkert", + "url": "http://github.com/jonschlinkert" + }, + "bugs": { + "url": "https://github.com/jonschlinkert/repeat-string/issues" + }, + "bundleDependencies": false, + "contributors": [ + { + "name": "Brian Woodward", + "email": "brian.woodward@gmail.com", + "url": "https://github.com/doowb" + }, + { + "name": "Jon Schlinkert", + "email": "jon.schlinkert@sellside.com", + "url": "http://twitter.com/jonschlinkert" + }, + { + "name": "Linus UnnebΓ€ck", + "email": "linus@folkdatorn.se", + "url": "http://linus.unnebΓ€ck.se" + }, + { + "name": "Thijs Busser", + "email": "tbusser@gmail.com", + "url": "http://tbusser.net" + }, + { + "name": "Titus", + "email": "tituswormer@gmail.com", + "url": "wooorm.com" + } + ], + "deprecated": false, + "description": "Repeat the given string n times. Fastest implementation for repeating a string.", + "devDependencies": { + "ansi-cyan": "^0.1.1", + "benchmarked": "^0.2.5", + "gulp-format-md": "^0.1.11", + "isobject": "^2.1.0", + "mocha": "^3.1.2", + "repeating": "^3.0.0", + "text-table": "^0.2.0", + "yargs-parser": "^4.0.2" + }, + "engines": { + "node": ">=0.10" + }, + "files": [ + "index.js" + ], + "homepage": "https://github.com/jonschlinkert/repeat-string", + "keywords": [ + "fast", + "fastest", + "fill", + "left", + "left-pad", + "multiple", + "pad", + "padding", + "repeat", + "repeating", + "repetition", + "right", + "right-pad", + "string", + "times" + ], + "license": "MIT", + "main": "index.js", + "name": "repeat-string", + "repository": { + "type": "git", + "url": "git+https://github.com/jonschlinkert/repeat-string.git" + }, + "scripts": { + "test": "mocha" + }, + "verb": { + "toc": false, + "layout": "default", + "tasks": [ + "readme" + ], + "plugins": [ + "gulp-format-md" + ], + "related": { + "list": [ + "repeat-element" + ] + }, + "helpers": [ + "./benchmark/helper.js" + ], + "reflinks": [ + "verb" + ] + }, + "version": "1.6.1" +} diff --git a/reverse_engineering/package.json b/reverse_engineering/package.json index 74a98ba..65d2de9 100644 --- a/reverse_engineering/package.json +++ b/reverse_engineering/package.json @@ -4,6 +4,7 @@ "description": "", "author": "Hackolade", "dependencies": { + "comment-json": "^4.1.0", "js-yaml": "^3.13.0", "lodash.isplainobject": "^4.0.6", "lodash.partial": "^4.2.1", From 9b874ec0d1bc5dbbb0572a586fa7e7c3dd29198f Mon Sep 17 00:00:00 2001 From: Lench Volodymyr Date: Fri, 2 Jul 2021 09:59:05 +0300 Subject: [PATCH 4/4] fix spaces before the comments --- reverse_engineering/helpers/dataHelper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reverse_engineering/helpers/dataHelper.js b/reverse_engineering/helpers/dataHelper.js index 1d37a00..32c093a 100644 --- a/reverse_engineering/helpers/dataHelper.js +++ b/reverse_engineering/helpers/dataHelper.js @@ -869,7 +869,7 @@ const getModelContent = (pathData, fieldOrder, callbacksComponent) => { const getOpenAPIJsonSchema = (data, fileName, extension) => { const schema = extension !== '.json' ? commonHelper.convertYamlToJson(data) : data; - const openAPISchema = typeof schema === 'string' ? jsonComment.parse(schema.replace(/^#.+$/mg, '')) : schema; + const openAPISchema = typeof schema === 'string' ? jsonComment.parse(schema.replace(/^\s*#.+$/mg, '')) : schema; const updatedOpenApiSchema = copyPathItemLevelParametersToOperationObject(openAPISchema); const openAPISchemaWithModelName = Object.assign({}, updatedOpenApiSchema, { modelName: fileName