1+ /* eslint-disable import/no-commonjs */
12const amf = require ( 'amf-client-js' ) ;
23const fs = require ( 'fs-extra' ) ;
34const path = require ( 'path' ) ;
@@ -6,15 +7,20 @@ amf.plugins.document.WebApi.register();
67amf . plugins . document . Vocabularies . register ( ) ;
78amf . 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 */
1925async 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 */
7884function 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 */
123128function 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