openapi-jsonrpc-jsdoc 1.5.2 → 1.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.mjs +125 -83
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -29,6 +29,15 @@ function isBigInt64(n) {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
function normalizeString(s) {
|
|
33
|
+
if (
|
|
34
|
+
(s.startsWith("'") && s.endsWith("'"))
|
|
35
|
+
|| (s.startsWith('"') && s.endsWith('"'))
|
|
36
|
+
) {
|
|
37
|
+
return s.slice(1, -1);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
32
41
|
function resolveSchemaFromTypeNames(names) {
|
|
33
42
|
let type;
|
|
34
43
|
let format;
|
|
@@ -92,8 +101,10 @@ function resolveSchemaFromTypeNames(names) {
|
|
|
92
101
|
return Number(n);
|
|
93
102
|
} else if (isBigInt64(n)) {
|
|
94
103
|
return n;
|
|
104
|
+
} else if (typeof n === 'string') {
|
|
105
|
+
return normalizeString(n)
|
|
95
106
|
}
|
|
96
|
-
return
|
|
107
|
+
return s;
|
|
97
108
|
});
|
|
98
109
|
|
|
99
110
|
if (enumData.every(n => Number.isSafeInteger(n))) {
|
|
@@ -224,6 +235,16 @@ export default async function openapiJsonrpcJsdoc({
|
|
|
224
235
|
},
|
|
225
236
|
error: {
|
|
226
237
|
type: 'object',
|
|
238
|
+
required: ['code', 'message'],
|
|
239
|
+
properties: {
|
|
240
|
+
code: {
|
|
241
|
+
type: 'integer',
|
|
242
|
+
default: -32001,
|
|
243
|
+
},
|
|
244
|
+
message: {
|
|
245
|
+
type: 'string',
|
|
246
|
+
},
|
|
247
|
+
},
|
|
227
248
|
},
|
|
228
249
|
jsonrpc: {
|
|
229
250
|
type: 'string',
|
|
@@ -242,10 +263,10 @@ export default async function openapiJsonrpcJsdoc({
|
|
|
242
263
|
const tags = new Set();
|
|
243
264
|
|
|
244
265
|
if (module.tags && Array.isArray(module.tags)) {
|
|
245
|
-
for (const {title, value} of module.tags) {
|
|
266
|
+
for (const {title, originalTitle, value} of module.tags) {
|
|
246
267
|
if (title === 'json-rpc') {
|
|
247
268
|
isJsonRpc = true;
|
|
248
|
-
} else if (value && ['tags', 'tag'].includes(title)) {
|
|
269
|
+
} else if (value && ['tags', 'tag'].includes(originalTitle ?? title)) {
|
|
249
270
|
value.split(',').map(t => t.trim()).forEach(t => tags.add(t));
|
|
250
271
|
}
|
|
251
272
|
}
|
|
@@ -256,26 +277,49 @@ export default async function openapiJsonrpcJsdoc({
|
|
|
256
277
|
const {filename} = module.meta;
|
|
257
278
|
const apiName = filename.replace(/\.js$/, '');
|
|
258
279
|
|
|
280
|
+
let resultValues;
|
|
281
|
+
switch (module.returns?.[0]?.description) {
|
|
282
|
+
case 'Promise<*>':
|
|
283
|
+
case 'Promise<object>': {
|
|
284
|
+
resultValues = 'object';
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
default: {
|
|
288
|
+
resultValues = '';
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
let description = module.description;
|
|
294
|
+
if (module.todo?.length) {
|
|
295
|
+
description += '\n\nTODO: ' + module.todo.join();
|
|
296
|
+
}
|
|
297
|
+
|
|
259
298
|
const schema = {
|
|
260
299
|
post: {
|
|
261
300
|
operationId: apiName,
|
|
262
301
|
deprecated: module.deprecated || false,
|
|
263
302
|
summary: module.summary ?? `/${apiName}`,
|
|
264
|
-
description:
|
|
303
|
+
description: description,
|
|
265
304
|
tags: Array.from(tags),
|
|
266
305
|
responses: {
|
|
267
306
|
'200': {
|
|
268
|
-
description: 'OK',
|
|
307
|
+
description: 'OK response',
|
|
269
308
|
content: {
|
|
270
309
|
'application/json': {
|
|
271
310
|
schema: {
|
|
272
311
|
type: 'object',
|
|
312
|
+
properties: {
|
|
313
|
+
result: {
|
|
314
|
+
type: resultValues,
|
|
315
|
+
},
|
|
316
|
+
},
|
|
273
317
|
},
|
|
274
318
|
},
|
|
275
319
|
},
|
|
276
320
|
},
|
|
277
|
-
|
|
278
|
-
description: '
|
|
321
|
+
'400': {
|
|
322
|
+
description: 'Unexpected error',
|
|
279
323
|
content: {
|
|
280
324
|
'application/json': {
|
|
281
325
|
schema: {
|
|
@@ -295,16 +339,18 @@ export default async function openapiJsonrpcJsdoc({
|
|
|
295
339
|
properties: {
|
|
296
340
|
method: {
|
|
297
341
|
type: 'string',
|
|
298
|
-
|
|
342
|
+
'default': apiName,
|
|
343
|
+
description: `API method header`,
|
|
299
344
|
},
|
|
300
345
|
id: {
|
|
301
346
|
type: ['string', 'integer'],
|
|
302
|
-
|
|
347
|
+
default: 'swagger_unique_indentifier',
|
|
348
|
+
description: 'Request ID header',
|
|
303
349
|
},
|
|
304
350
|
jsonrpc: {
|
|
305
351
|
type: 'string',
|
|
306
352
|
default: '2.0',
|
|
307
|
-
description: 'JSON-RPC 2.0
|
|
353
|
+
description: 'JSON-RPC 2.0 header',
|
|
308
354
|
},
|
|
309
355
|
},
|
|
310
356
|
},
|
|
@@ -314,89 +360,85 @@ export default async function openapiJsonrpcJsdoc({
|
|
|
314
360
|
},
|
|
315
361
|
};
|
|
316
362
|
if (module.params) {
|
|
317
|
-
|
|
363
|
+
let propertiesParameters = {};
|
|
364
|
+
let required = [];
|
|
365
|
+
|
|
318
366
|
if (module.examples?.length) {
|
|
319
367
|
const exampleJSON = JSON.parse(module.examples[0]);
|
|
320
368
|
if (exampleJSON) {
|
|
321
|
-
|
|
369
|
+
propertiesParameters['default'] = exampleJSON;
|
|
322
370
|
}
|
|
323
371
|
}
|
|
324
372
|
|
|
325
|
-
const
|
|
326
|
-
(
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
const isPlain = !parameter.name.includes('.');
|
|
373
|
+
for (const parameter of module.params) {
|
|
374
|
+
if (parameter.name.startsWith('_')) {
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
if (!parameter.type) {
|
|
378
|
+
throw new Error('JSDoc parameter error: ' + apiName);
|
|
379
|
+
}
|
|
380
|
+
// если главный параметр объявлен как объект - пропускаем его
|
|
381
|
+
if (parameter.type.names.every(name => name.toLowerCase() === 'object')) {
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
const isPlain = !parameter.name.includes('.');
|
|
338
385
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
386
|
+
const name = extractName(parameter.name);
|
|
387
|
+
const prop = {};
|
|
388
|
+
const description = parameter.description;
|
|
389
|
+
let defaultValue = parameter.defaultvalue;
|
|
343
390
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
// fix for array type if it is not properly closed in JSDoc
|
|
363
|
-
if (typeof defaultValue === 'string' && defaultValue.startsWith('[') && !defaultValue.endsWith(']')) {
|
|
364
|
-
defaultValue += ']';
|
|
365
|
-
}
|
|
366
|
-
prop.default = JSON.parse(defaultValue);
|
|
367
|
-
}
|
|
368
|
-
if (constant) {
|
|
369
|
-
prop.const = constant;
|
|
370
|
-
}
|
|
371
|
-
if (format) {
|
|
372
|
-
prop.format = format;
|
|
373
|
-
}
|
|
374
|
-
if (enumData) {
|
|
375
|
-
prop.enum = enumData;
|
|
376
|
-
}
|
|
377
|
-
if (type) {
|
|
378
|
-
prop.type = type;
|
|
379
|
-
}
|
|
380
|
-
if (description) {
|
|
381
|
-
prop.description = description;
|
|
382
|
-
}
|
|
383
|
-
if (items) {
|
|
384
|
-
prop.items = items;
|
|
385
|
-
}
|
|
386
|
-
if (isPlain) {
|
|
387
|
-
accumulator = Object.assign(accumulator, prop);
|
|
388
|
-
} else if (accumulator.properties) {
|
|
389
|
-
accumulator.properties[name] = prop;
|
|
390
|
-
} else {
|
|
391
|
-
accumulator.properties = {
|
|
392
|
-
[name]: prop,
|
|
393
|
-
};
|
|
391
|
+
const {
|
|
392
|
+
items,
|
|
393
|
+
constant,
|
|
394
|
+
enumData,
|
|
395
|
+
type,
|
|
396
|
+
format,
|
|
397
|
+
nullable,
|
|
398
|
+
} = resolveSchemaFromTypeNames(parameter.type.names)
|
|
399
|
+
if (!parameter.optional) {
|
|
400
|
+
required.push(name);
|
|
401
|
+
}
|
|
402
|
+
if (nullable) {
|
|
403
|
+
prop.nullable = nullable;
|
|
404
|
+
}
|
|
405
|
+
if (defaultValue !== undefined) {
|
|
406
|
+
// fix for array type if it is not properly closed in JSDoc
|
|
407
|
+
if (typeof defaultValue === 'string' && defaultValue.startsWith('[') && !defaultValue.endsWith(']')) {
|
|
408
|
+
defaultValue += ']';
|
|
394
409
|
}
|
|
410
|
+
prop.default = JSON.parse(defaultValue);
|
|
411
|
+
}
|
|
412
|
+
if (constant) {
|
|
413
|
+
prop.const = constant;
|
|
414
|
+
}
|
|
415
|
+
if (format) {
|
|
416
|
+
prop.format = format;
|
|
417
|
+
}
|
|
418
|
+
if (enumData) {
|
|
419
|
+
prop.enum = enumData;
|
|
420
|
+
}
|
|
421
|
+
if (type) {
|
|
422
|
+
prop.type = type;
|
|
423
|
+
}
|
|
424
|
+
if (description) {
|
|
425
|
+
prop.description = description;
|
|
426
|
+
}
|
|
427
|
+
if (items) {
|
|
428
|
+
prop.items = items;
|
|
429
|
+
}
|
|
430
|
+
if (isPlain) {
|
|
431
|
+
propertiesParameters = Object.assign(propertiesParameters, prop);
|
|
432
|
+
} else if (propertiesParameters.properties) {
|
|
433
|
+
propertiesParameters.properties[name] = prop;
|
|
434
|
+
} else {
|
|
435
|
+
propertiesParameters.properties = {
|
|
436
|
+
[name]: prop,
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
propertiesParameters.required = required;
|
|
395
441
|
|
|
396
|
-
return accumulator;
|
|
397
|
-
},
|
|
398
|
-
prevObject,
|
|
399
|
-
);
|
|
400
442
|
if (Object.keys(propertiesParameters).length) {
|
|
401
443
|
const schemaPostJsdoc = schema.post.requestBody.content['application/json'].schema;
|
|
402
444
|
if (propertiesParameters.properties) {
|