Skip to content

Commit 9be7c79

Browse files
committed
chore: updating amf + TS support
Signed-off-by: Pawel Psztyc <jarrodek@gmail.com>
1 parent 4289865 commit 9be7c79

10 files changed

Lines changed: 3730 additions & 3985 deletions

.eslintignore

Lines changed: 0 additions & 1 deletion
This file was deleted.

.eslintrc.js

Lines changed: 130 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,132 @@
1-
1+
/* eslint-disable import/no-commonjs */
22
module.exports = {
3-
extends: ['@advanced-rest-client/eslint-config'].map(require.resolve),
3+
extends: [
4+
require.resolve('eslint-config-google'),
5+
require.resolve('eslint-config-node'),
6+
],
7+
parser: 'babel-eslint',
8+
parserOptions: {
9+
sourceType: 'module',
10+
ecmaVersion: 8,
11+
},
12+
env: {
13+
browser: false,
14+
mocha: true,
15+
node: true,
16+
es6: true,
17+
},
18+
plugins: [
19+
'no-only-tests',
20+
'babel',
21+
'import',
22+
],
23+
overrides: [
24+
{
25+
files: [
26+
'**/test/**/*.js',
27+
'**/test/**/*.mjs',
28+
],
29+
rules: {
30+
'no-console': 'off',
31+
'no-plusplus': 'off',
32+
'no-unused-expressions': 'off',
33+
'class-methods-use-this': 'off',
34+
'import/no-extraneous-dependencies': 'off',
35+
'require-jsdoc': 'off',
36+
},
37+
},
38+
],
39+
ignorePatterns: [
40+
'**/*.d.ts',
41+
],
42+
rules: {
43+
'arrow-parens': [
44+
'error',
45+
'always',
46+
{
47+
'requireForBlockBody': true,
48+
},
49+
],
50+
'lines-between-class-members': 'error',
51+
'no-underscore-dangle': 'off',
52+
'no-only-tests/no-only-tests': 'error',
53+
'import/extensions': [
54+
'error',
55+
'always',
56+
{
57+
ignorePackages: true,
58+
},
59+
],
60+
'import/prefer-default-export': 'off',
61+
'import/no-nodejs-modules': 'off',
62+
'import/no-extraneous-dependencies': [
63+
'error',
64+
{
65+
'devDependencies': [
66+
'**/test/**/*.js',
67+
'**/*.config.js',
68+
'**/*.conf.js',
69+
],
70+
},
71+
],
72+
'class-methods-use-this': [
73+
// this is unnecessary for node apps.
74+
'off',
75+
{
76+
'exceptMethods': [],
77+
},
78+
],
79+
'no-undef': 'error',
80+
'require-jsdoc': ['warn', {
81+
require: {
82+
FunctionDeclaration: true,
83+
MethodDefinition: true,
84+
ClassDeclaration: true,
85+
ArrowFunctionExpression: true,
86+
FunctionExpression: true,
87+
},
88+
}],
89+
'comma-dangle': 'warn',
90+
'new-cap': [
91+
'error',
92+
{
93+
properties: false,
94+
capIsNew: false,
95+
},
96+
],
97+
'max-len': [
98+
'error',
99+
{
100+
code: 120,
101+
},
102+
],
103+
'object-curly-spacing': [
104+
'error',
105+
'always',
106+
],
107+
'no-console': [
108+
'error',
109+
],
110+
'no-unused-expressions': 'error',
111+
'babel/no-unused-expressions': 'error',
112+
'prefer-template': 'error',
113+
'no-return-await': 'error',
114+
'no-template-curly-in-string': 'error',
115+
'indent': [
116+
'error',
117+
2,
118+
{
119+
SwitchCase: 1,
120+
VariableDeclarator: 1,
121+
outerIIFEBody: 0,
122+
MemberExpression: 0,
123+
},
124+
],
125+
'no-shadow': [
126+
'error',
127+
{
128+
builtinGlobals: true,
129+
},
130+
],
131+
},
4132
};

index.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { ApiGenerationOptions, ApiConfiguration } from './types';
2+
3+
declare function process(init: string|Map<string, ApiConfiguration|string|string[]>, opts?: ApiGenerationOptions): Promise<void>;
4+
5+
export = process;

index.js

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable import/no-commonjs */
12
const amf = require('amf-client-js');
23
const fs = require('fs-extra');
34
const path = require('path');
@@ -6,15 +7,20 @@ amf.plugins.document.WebApi.register();
67
amf.plugins.document.Vocabularies.register();
78
amf.plugins.features.AMFValidation.register();
89

10+
/** @typedef {import('./types').ApiConfiguration} ApiConfiguration */
11+
/** @typedef {import('./types').FilePrepareResult} FilePrepareResult */
12+
/** @typedef {import('./types').ApiGenerationOptions} ApiGenerationOptions */
13+
/** @typedef {import('./types').ApiType} ApiType */
14+
915
/**
1016
* Generates json/ld file from parsed document.
1117
*
12-
* @param {Object} doc
13-
* @param {String} file
14-
* @param {String} type
15-
* @param {String} destPath
16-
* @param {String} resolution
17-
* @return {Promise}
18+
* @param {amf.model.document.BaseUnit} doc
19+
* @param {string} file
20+
* @param {string} type
21+
* @param {string} destPath
22+
* @param {string} resolution
23+
* @return {Promise<void>}
1824
*/
1925
async function processFile(doc, file, type, destPath, resolution) {
2026
let validateProfile;
@@ -26,16 +32,17 @@ async function processFile(doc, file, type, destPath, resolution) {
2632
validateProfile = amf.ProfileNames.OAS;
2733
break;
2834
case 'ASYNC 2.0':
35+
// @ts-ignore
2936
validateProfile = amf.ProfileNames.ASYNC20;
3037
break;
3138
}
32-
let dest = file.substr(0, file.lastIndexOf('.')) + '.json';
39+
let dest = `${file.substr(0, file.lastIndexOf('.')) }.json`;
3340
if (dest.indexOf('/') !== -1) {
3441
dest = dest.substr(dest.lastIndexOf('/'));
3542
}
3643

3744
const generator = amf.Core.generator('AMF Graph', 'application/ld+json');
38-
const vResult = await amf.AMF.validate(doc, validateProfile);
45+
const vResult = await amf.AMF.validate(doc, validateProfile, undefined);
3946
if (!vResult.conforms) {
4047
/* eslint-disable-next-line no-console */
4148
console.log(vResult.toString());
@@ -55,11 +62,13 @@ async function processFile(doc, file, type, destPath, resolution) {
5562
const compactDest = dest.replace('.json', '-compact.json');
5663
const compactFile = path.join(destPath, compactDest);
5764

65+
// @ts-ignore
5866
const fullOpts = amf.render.RenderOptions().withSourceMaps;
5967
const fullData = await generator.generateString(doc, fullOpts);
6068
await fs.ensureFile(fullFile);
6169
await fs.writeFile(fullFile, fullData, 'utf8');
6270

71+
// @ts-ignore
6372
const compactOpts = amf.render.RenderOptions().withSourceMaps.withCompactUris;
6473
// withRawSourceMaps.
6574
const compactData = await generator.generateString(doc, compactOpts);
@@ -69,56 +78,52 @@ async function processFile(doc, file, type, destPath, resolution) {
6978

7079
/**
7180
* Normalizes input options to a common structure.
72-
* @param {String|Array|Object} input User input
73-
* @return {Object} A resulting configuration options with:
74-
* - required `type`
75-
* - optional `mime`
76-
* - optional `resolution`
81+
* @param {ApiConfiguration|string|string[]} input User input
82+
* @return {ApiConfiguration} A resulting configuration options with
7783
*/
7884
function normalizeOptions(input) {
7985
if (Array.isArray(input)) {
8086
const [type, mime, resolution] = input;
87+
// @ts-ignore
8188
return { type, mime, resolution };
8289
}
8390
if (typeof input === 'object') {
8491
return input;
8592
}
8693
return {
87-
type: input,
88-
}
94+
type: /** @type ApiType */ (input),
95+
};
8996
}
9097

9198
/**
9299
* Parses file and sends it to process.
93100
*
94-
* @param {String} file File name in `demo` folder
95-
* @param {String|Array<String>} input Source file type or an array where
96-
* first element is API spec format and second is API file media type
97-
* @param {Object} opts
98-
* - `src` String, default to 'demo/'
99-
* - `dest` String, default to 'demo/'
100-
* @return {String}
101+
* @param {string} file File name in `demo` folder
102+
* @param {ApiConfiguration|string|string[]} cnf
103+
* @param {ApiGenerationOptions} opts Processing options
104+
* @return {Promise<void>}
101105
*/
102-
async function parseFile(file, input, opts) {
103-
let srcDir = opts.src || 'demo/';
104-
if (srcDir[srcDir.length - 1] !== '/') {
105-
srcDir += '/';
106+
async function parseFile(file, cnf, opts) {
107+
let { src='demo/', dest='demo/' } = opts;
108+
if (!src.endsWith('/')) {
109+
src += '/';
106110
}
107-
let dest = opts.dest || 'demo/';
108-
if (dest[dest.length - 1] !== '/') {
111+
if (!dest.endsWith('/')) {
109112
dest += '/';
110113
}
111-
const { type, mime='application/yaml', resolution='editing' } = normalizeOptions(input);
114+
const { type, mime='application/yaml', resolution='editing' } = normalizeOptions(cnf);
112115
const parser = amf.Core.parser(type, mime);
113-
const doc = await parser.parseFileAsync(`file://${srcDir}${file}`);
116+
const doc = await parser.parseFileAsync(`file://${src}${file}`);
114117
return processFile(doc, file, type, dest, resolution);
115118
}
119+
116120
/**
117121
* Reads `file` as JSON and creates a Map with definitions from the file.
118122
* The keys are paths to the API file relative to `opts.src` and values is
119123
* API type.
120-
* @param {String} file Path to a file definition.
121-
* @return {Array} First item is the files map and second build configuration if any.
124+
* @param {string} file Path to a file definition.
125+
* @return {FilePrepareResult} The key is the api file location in the `opts.src`
126+
* directory. The value is the build configuration.
122127
*/
123128
function prepareFile(file) {
124129
file = path.resolve(process.cwd(), file);
@@ -136,17 +141,26 @@ function prepareFile(file) {
136141
break;
137142
}
138143
});
139-
return [files, opts];
144+
return {
145+
files,
146+
opts,
147+
};
140148
}
141149

142-
module.exports = async function(files, opts={}) {
143-
if (typeof files === 'string') {
144-
const [cnfFiles, cnfOpts] = prepareFile(files);
145-
files = cnfFiles;
146-
opts = Object.assign(cnfOpts, opts);
150+
/**
151+
* @param {string|Map<string, ApiConfiguration|string|string[]>} init If string then this is a location of
152+
* the file that holds processing configuration. Otherwise it is already prepared configuration.
153+
* @param {ApiGenerationOptions=} opts Processing options.
154+
* @return {Promise<void>}
155+
*/
156+
module.exports = async function(init, opts={}) {
157+
if (typeof init === 'string') {
158+
const { files: cnfFiles, opts: cnfOpts } = prepareFile(init);
159+
init = cnfFiles;
160+
opts = { ...cnfOpts, ...opts };
147161
}
148162
await amf.Core.init();
149-
for (const [file, type] of files) {
163+
for (const [file, type] of init) {
150164
await parseFile(file, type, opts);
151165
}
152166
};

0 commit comments

Comments
 (0)