Skip to content

Commit

Permalink
feat: add support for Relative JSON Pointer (#3031)
Browse files Browse the repository at this point in the history
  • Loading branch information
char0n authored Aug 14, 2023
1 parent 8d0aa45 commit f537584
Show file tree
Hide file tree
Showing 30 changed files with 992 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ You can install ApiDOM packages using [npm CLI](https://docs.npmjs.com/cli):
$ npm install @swagger-api/apidom-core
$ npm install @swagger-api/apidom-json-path
$ npm install @swagger-api/apidom-json-pointer
$ npm install @swagger-api/apidom-json-pointer-relative
$ npm install @swagger-api/apidom-ls
$ npm install @swagger-api/apidom-ns-api-design-systems
$ npm install @swagger-api/apidom-ns-asyncapi-2
Expand Down
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"clean": "lerna run clean",
"test": "lerna run test",
"link": "npm link --workspaces",
"unlink": "npm unlink --global @swagger-api/apidom-ast @swagger-api/apidom-core @swagger-api/apidom-json-path @swagger-api/apidom-json-pointer @swagger-api/apidom-parser-adapter-json @swagger-api/apidom-ns-api-design-systems @swagger-api/apidom-ns-asyncapi-2 @swagger-api/apidom-ns-json-schema-draft-4 @swagger-api/apidom-ns-json-schema-draft-6 @swagger-api/apidom-ns-json-schema-draft-7 @swagger-api/apidom-ns-openapi-3-0 @swagger-api/apidom-ns-openapi-3-1 @swagger-api/apidom-parser-adapter-yaml-1-2 @swagger-api/apidom-parser-adapter-asyncapi-yaml-2 @swagger-api/apidom-parser-adapter-openapi-yaml-3-0 @swagger-api/apidom-parser-adapter-openapi-yaml-3-1 @swagger-api/apidom-parser @swagger-api/apidom-parser-adapter-api-design-systems-json @swagger-api/apidom-parser-adapter-api-design-systems-yaml @swagger-api/apidom-parser-adapter-asyncapi-json-2 @swagger-api/apidom-ls @swagger-api/apidom-reference @swagger-api/apidom-parser-adapter-openapi-json-3-0 @swagger-api/apidom-parser-adapter-openapi-json-3-1 @swagger-api/apidom-playground",
"unlink": "npm unlink --global @swagger-api/apidom-ast @swagger-api/apidom-core @swagger-api/apidom-json-path @swagger-api/apidom-json-pointer @swagger-api/apidom-json-pointer-relative @swagger-api/apidom-parser-adapter-json @swagger-api/apidom-ns-api-design-systems @swagger-api/apidom-ns-asyncapi-2 @swagger-api/apidom-ns-json-schema-draft-4 @swagger-api/apidom-ns-json-schema-draft-6 @swagger-api/apidom-ns-json-schema-draft-7 @swagger-api/apidom-ns-openapi-3-0 @swagger-api/apidom-ns-openapi-3-1 @swagger-api/apidom-parser-adapter-yaml-1-2 @swagger-api/apidom-parser-adapter-asyncapi-yaml-2 @swagger-api/apidom-parser-adapter-openapi-yaml-3-0 @swagger-api/apidom-parser-adapter-openapi-yaml-3-1 @swagger-api/apidom-parser @swagger-api/apidom-parser-adapter-api-design-systems-json @swagger-api/apidom-parser-adapter-api-design-systems-yaml @swagger-api/apidom-parser-adapter-asyncapi-json-2 @swagger-api/apidom-ls @swagger-api/apidom-reference @swagger-api/apidom-parser-adapter-openapi-json-3-0 @swagger-api/apidom-parser-adapter-openapi-json-3-1 @swagger-api/apidom-playground",
"prepare": "chmod +x ./node_modules/husky/lib/bin.js && husky install"
},
"repository": {
Expand Down
9 changes: 9 additions & 0 deletions packages/apidom-json-pointer-relative/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/dist
/es
/cjs
/types
/config
/.eslintrc.js
/.nyc_output
/node_modules
/**/*.js
6 changes: 6 additions & 0 deletions packages/apidom-json-pointer-relative/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/dist
/es
/cjs
/types
/NOTICE
/swagger-api-apidom-json-pointer-relative-*.tgz
5 changes: 5 additions & 0 deletions packages/apidom-json-pointer-relative/.mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"recursive": true,
"spec": "test/**/*.ts",
"file": ["test/mocha-bootstrap.cjs"]
}
2 changes: 2 additions & 0 deletions packages/apidom-json-pointer-relative/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
save-prefix="="
save=false
Empty file.
64 changes: 64 additions & 0 deletions packages/apidom-json-pointer-relative/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# @swagger-api/apidom-json-pointer

`apidom-json-pointer-relative` is a package that evaluates [Relative JSON Pointer](https://datatracker.ietf.org/doc/html/draft-bhutton-relative-json-pointer-00) against ApiDOM.

## Installation

You can install this package via [npm CLI](https://docs.npmjs.com/cli) by running the following command:

```sh
$ npm install @swagger-api/apidom-json-pointer-relative
```
## Evaluating

```js
import { ObjectElement } from '@swagger-api/apidom-core';
import { evaluate } from '@swagger-api/apidom-json-pointer-relative';

const root = new ObjectElement({ a: { b: 'c' } });
const current = root.get('a').get('b');
const result = evaluate('0#', current, root);
// => StringElement('b')
```

## Parsing

Parses Relative JSON Pointer into AST (Abstract Syntax Tree).

```js
import { parse } from '@swagger-api/apidom-json-pointer-relative';

const tokens = parse('2/foo/0');
// => { nonNegativeIntegerPrefix: 2, indexManipulation: undefined, jsonPointerTokens: ['foo', '0'], hashCharacter: false }
```

## Compiling

Compiles AST into Relative JSON Pointer.

```js
import { compile } from '@swagger-api/apidom-json-pointer-relative';

const relativeJsonPointer = compile({
nonNegativeIntegerPrefix: 2,
indexManipulation: undefined,
jsonPointerTokens: ['highly', 'nested', 'objects'],
hashCharacter: false,
}); // => '2/highly/nested/objects'
```

## Invalid Relative JSON Pointers

If invalid Relative JSON Pointer is supplied to `parse` or `evaluate` functions, `InvalidRelativeJsonPointerError`
is thrown.

```js
import { InvalidRelativeJsonPointerError } from '@swagger-api/apidom-json-pointer-relative';
```

If valid JSON Pointer is supplied to `evaluate` function and the relative pointer cannot be evaluated against
ApiDOM fragment, `EvaluationRelativeJsonPointerError` is thrown.

```js
import { EvaluationRelativeJsonPointerError } from '@swagger-api/apidom-json-pointer-relative';
```
12 changes: 12 additions & 0 deletions packages/apidom-json-pointer-relative/config/rollup/types.dist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import dts from 'rollup-plugin-dts';

const config = [
{
input: './types/index.d.ts',
output: [{ file: 'types/dist.d.ts', format: 'es' }],
plugins: [dts()],
external: ['Function/Curry'],
},
];

export default config;
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import path from 'node:path';

import { nonMinimizeTrait, minimizeTrait } from './traits.config.js';

const browser = {
mode: 'production',
entry: ['./src/index.ts'],
target: 'web',
performance: {
maxEntrypointSize: 1200000,
maxAssetSize: 1200000,
},
output: {
path: path.resolve('./dist'),
filename: 'apidom-json-pointer-relative.browser.js',
libraryTarget: 'umd',
library: 'apidomJsonPointerRelative',
},
resolve: {
extensions: ['.ts', '.mjs', '.js', '.json'],
},
module: {
rules: [
{
test: /\.(ts|js)?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
babelrc: true,
rootMode: 'upward',
},
},
},
],
},
...nonMinimizeTrait,
};

const browserMin = {
mode: 'production',
entry: ['./src/index.ts'],
target: 'web',
output: {
path: path.resolve('./dist'),
filename: 'apidom-json-pointer-relative.browser.min.js',
libraryTarget: 'umd',
library: 'apidomJsonPointerRelative',
},
resolve: {
extensions: ['.ts', '.mjs', '.js', '.json'],
},
module: {
rules: [
{
test: /\.(ts|js)?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
babelrc: true,
rootMode: 'upward',
},
},
},
],
},
...minimizeTrait,
};

export default [browser, browserMin];
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import webpack from 'webpack';
import TerserPlugin from 'terser-webpack-plugin';

export const nonMinimizeTrait = {
optimization: {
minimize: false,
usedExports: false,
concatenateModules: false,
},
};

export const minimizeTrait = {
plugins: [
new webpack.LoaderOptionsPlugin({
minimize: true,
}),
],
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
warnings: false,
},
output: {
comments: false,
},
},
}),
],
},
};
12 changes: 12 additions & 0 deletions packages/apidom-json-pointer-relative/declaration.tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"extends": "./tsconfig.json",
"exclude": [
"test/**/*"
],
"compilerOptions": {
"declaration": true,
"declarationDir": "types",
"noEmit": false,
"emitDeclarationOnly": true
}
}
57 changes: 57 additions & 0 deletions packages/apidom-json-pointer-relative/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"name": "@swagger-api/apidom-json-pointer-relative",
"version": "0.74.1",
"description": "Evaluate Relative JSON Pointer expressions against ApiDOM.",
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org"
},
"type": "module",
"sideEffects": false,
"unpkg": "./dist/apidom-json-pointer-relative.browser.min.js",
"main": "./cjs/index.cjs",
"exports": {
"types": "./types/dist.d.ts",
"import": "./es/index.js",
"require": "./cjs/index.cjs"
},
"types": "./types/dist.d.ts",
"scripts": {
"build": "npm run clean && run-p --max-parallel ${CPU_CORES:-2} typescript:declaration build:es build:cjs build:umd:browser",
"build:es": "cross-env BABEL_ENV=es babel src --out-dir es --extensions '.ts' --root-mode 'upward'",
"build:cjs": "cross-env BABEL_ENV=cjs babel src --out-dir cjs --extensions '.ts' --out-file-extension '.cjs' --root-mode 'upward'",
"build:umd:browser": "cross-env BABEL_ENV=browser BROWSERSLIST_ENV=production webpack --config config/webpack/browser.config.js --progress",
"lint": "eslint ./",
"lint:fix": "eslint ./ --fix",
"clean": "rimraf ./es ./cjs ./dist ./types",
"typescript:check-types": "tsc --noEmit",
"typescript:declaration": "tsc -p declaration.tsconfig.json && rollup -c config/rollup/types.dist.js",
"test": "cross-env NODE_ENV=test BABEL_ENV=cjs mocha",
"prepack": "copyfiles -u 3 ../../LICENSES/* LICENSES && copyfiles -u 2 ../../NOTICE .",
"postpack": "rimraf NOTICE LICENSES"
},
"repository": {
"type": "git",
"url": "git+https://github.com/swagger-api/apidom.git"
},
"author": "Vladimír Gorej",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime-corejs3": "^7.20.7",
"@swagger-api/apidom-core": "^0.74.1",
"@swagger-api/apidom-json-pointer": "^0.74.1",
"@types/ramda": "~0.29.3",
"ramda": "~0.29.0",
"ramda-adjunct": "^4.0.0"
},
"files": [
"cjs/",
"dist/",
"es/",
"types/dist.d.ts",
"LICENSES",
"NOTICE",
"README.md",
"CHANGELOG.md"
]
}
28 changes: 28 additions & 0 deletions packages/apidom-json-pointer-relative/src/compile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { compile as compileJsonPointer } from '@swagger-api/apidom-json-pointer';

import { RelativeJsonPointer } from './types';

// compile :: RelativeJSONPointer -> String
const compile = (relativeJsonPointer: RelativeJsonPointer): string => {
let relativePointer = '';

// non-negative-integer
relativePointer += String(relativeJsonPointer.nonNegativeIntegerPrefix);

// index-manipulation
if (typeof relativeJsonPointer.indexManipulation === 'number') {
relativePointer += String(relativeJsonPointer.indexManipulation);
}

if (Array.isArray(relativeJsonPointer.jsonPointerTokens)) {
// <json-pointer>
relativePointer += compileJsonPointer(relativeJsonPointer.jsonPointerTokens);
} else if (relativeJsonPointer.hashCharacter) {
// "#"
relativePointer += '#';
}

return relativePointer;
};

export default compile;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default class EvaluationRelativeJsonPointerError extends Error {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default class InvalidRelativeJsonPointerError extends Error {
constructor(relativePointer: string) {
super(`Invalid Relative JSON Pointer "${relativePointer}".`);
}
}
2 changes: 2 additions & 0 deletions packages/apidom-json-pointer-relative/src/errors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as EvaluationRelativeJsonPointerError } from './EvaluationRelativeJsonPointerError';
export { default as InvalidRelativeJsonPointerError } from './InvalidRelativeJsonPointerError';
Loading

0 comments on commit f537584

Please sign in to comment.