openapi-jsonrpc-jsdoc 1.5.2 → 1.5.3

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.
Files changed (2) hide show
  1. package/index.mjs +111 -80
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -224,6 +224,16 @@ export default async function openapiJsonrpcJsdoc({
224
224
  },
225
225
  error: {
226
226
  type: 'object',
227
+ required: ['code', 'message'],
228
+ properties: {
229
+ code: {
230
+ type: 'integer',
231
+ default: -32001,
232
+ },
233
+ message: {
234
+ type: 'string',
235
+ },
236
+ },
227
237
  },
228
238
  jsonrpc: {
229
239
  type: 'string',
@@ -242,10 +252,10 @@ export default async function openapiJsonrpcJsdoc({
242
252
  const tags = new Set();
243
253
 
244
254
  if (module.tags && Array.isArray(module.tags)) {
245
- for (const {title, value} of module.tags) {
255
+ for (const {title, originalTitle, value} of module.tags) {
246
256
  if (title === 'json-rpc') {
247
257
  isJsonRpc = true;
248
- } else if (value && ['tags', 'tag'].includes(title)) {
258
+ } else if (value && ['tags', 'tag'].includes(originalTitle ?? title)) {
249
259
  value.split(',').map(t => t.trim()).forEach(t => tags.add(t));
250
260
  }
251
261
  }
@@ -256,26 +266,49 @@ export default async function openapiJsonrpcJsdoc({
256
266
  const {filename} = module.meta;
257
267
  const apiName = filename.replace(/\.js$/, '');
258
268
 
269
+ let resultValues;
270
+ switch (module.returns?.[0]?.description) {
271
+ case 'Promise<*>':
272
+ case 'Promise<object>': {
273
+ resultValues = 'object';
274
+ break;
275
+ }
276
+ default: {
277
+ resultValues = '';
278
+ break;
279
+ }
280
+ }
281
+
282
+ let description = module.description;
283
+ if (module.todo?.length) {
284
+ description += '\n\nTODO: ' + module.todo.join();
285
+ }
286
+
259
287
  const schema = {
260
288
  post: {
261
289
  operationId: apiName,
262
290
  deprecated: module.deprecated || false,
263
291
  summary: module.summary ?? `/${apiName}`,
264
- description: module.description,
292
+ description: description,
265
293
  tags: Array.from(tags),
266
294
  responses: {
267
295
  '200': {
268
- description: 'OK',
296
+ description: 'OK response',
269
297
  content: {
270
298
  'application/json': {
271
299
  schema: {
272
300
  type: 'object',
301
+ properties: {
302
+ result: {
303
+ type: resultValues,
304
+ },
305
+ },
273
306
  },
274
307
  },
275
308
  },
276
309
  },
277
- default: {
278
- description: 'unexpected error',
310
+ '400': {
311
+ description: 'Unexpected error',
279
312
  content: {
280
313
  'application/json': {
281
314
  schema: {
@@ -295,16 +328,18 @@ export default async function openapiJsonrpcJsdoc({
295
328
  properties: {
296
329
  method: {
297
330
  type: 'string',
298
- description: `API method ${apiName}`,
331
+ 'default': apiName,
332
+ description: `API method header`,
299
333
  },
300
334
  id: {
301
335
  type: ['string', 'integer'],
302
- description: 'Request ID',
336
+ default: 'swagger_unique_indentifier',
337
+ description: 'Request ID header',
303
338
  },
304
339
  jsonrpc: {
305
340
  type: 'string',
306
341
  default: '2.0',
307
- description: 'JSON-RPC 2.0 protocol',
342
+ description: 'JSON-RPC 2.0 header',
308
343
  },
309
344
  },
310
345
  },
@@ -322,81 +357,77 @@ export default async function openapiJsonrpcJsdoc({
322
357
  }
323
358
  }
324
359
 
325
- const propertiesParameters = module.params.reduce(
326
- (accumulator, parameter) => {
327
- if (parameter.name.startsWith('_')) {
328
- return accumulator;
329
- }
330
- if (!parameter.type) {
331
- throw new Error('JSDoc parameter error: ' + apiName);
332
- }
333
- // если главный параметр объявлен как объект - пропускаем его
334
- if (parameter.type.names.every(name => name.toLowerCase() === 'object')) {
335
- return accumulator;
336
- }
337
- const isPlain = !parameter.name.includes('.');
360
+ let propertiesParameters = {};
361
+ let required = [];
362
+ for (const parameter of module.params) {
363
+ if (parameter.name.startsWith('_')) {
364
+ continue;
365
+ }
366
+ if (!parameter.type) {
367
+ throw new Error('JSDoc parameter error: ' + apiName);
368
+ }
369
+ // если главный параметр объявлен как объект - пропускаем его
370
+ if (parameter.type.names.every(name => name.toLowerCase() === 'object')) {
371
+ continue;
372
+ }
373
+ const isPlain = !parameter.name.includes('.');
338
374
 
339
- const name = extractName(parameter.name);
340
- const prop = {};
341
- const description = parameter.description;
342
- let defaultValue = parameter.defaultvalue;
375
+ const name = extractName(parameter.name);
376
+ const prop = {};
377
+ const description = parameter.description;
378
+ let defaultValue = parameter.defaultvalue;
343
379
 
344
- const {
345
- items,
346
- constant,
347
- enumData,
348
- type,
349
- format,
350
- nullable,
351
- } = resolveSchemaFromTypeNames(parameter.type.names)
352
- if (!parameter.optional) {
353
- if (!accumulator.required) {
354
- accumulator.required = [];
355
- }
356
- accumulator.required.push(name);
357
- }
358
- if (nullable) {
359
- prop.nullable = nullable;
360
- }
361
- if (defaultValue !== undefined) {
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
- };
380
+ const {
381
+ items,
382
+ constant,
383
+ enumData,
384
+ type,
385
+ format,
386
+ nullable,
387
+ } = resolveSchemaFromTypeNames(parameter.type.names)
388
+ if (!parameter.optional) {
389
+ required.push(name);
390
+ }
391
+ if (nullable) {
392
+ prop.nullable = nullable;
393
+ }
394
+ if (defaultValue !== undefined) {
395
+ // fix for array type if it is not properly closed in JSDoc
396
+ if (typeof defaultValue === 'string' && defaultValue.startsWith('[') && !defaultValue.endsWith(']')) {
397
+ defaultValue += ']';
394
398
  }
399
+ prop.default = JSON.parse(defaultValue);
400
+ }
401
+ if (constant) {
402
+ prop.const = constant;
403
+ }
404
+ if (format) {
405
+ prop.format = format;
406
+ }
407
+ if (enumData) {
408
+ prop.enum = enumData;
409
+ }
410
+ if (type) {
411
+ prop.type = type;
412
+ }
413
+ if (description) {
414
+ prop.description = description;
415
+ }
416
+ if (items) {
417
+ prop.items = items;
418
+ }
419
+ if (isPlain) {
420
+ propertiesParameters = Object.assign(propertiesParameters, prop);
421
+ } else if (propertiesParameters.properties) {
422
+ propertiesParameters.properties[name] = prop;
423
+ } else {
424
+ propertiesParameters.properties = {
425
+ [name]: prop,
426
+ };
427
+ }
428
+ }
429
+ propertiesParameters.required = required;
395
430
 
396
- return accumulator;
397
- },
398
- prevObject,
399
- );
400
431
  if (Object.keys(propertiesParameters).length) {
401
432
  const schemaPostJsdoc = schema.post.requestBody.content['application/json'].schema;
402
433
  if (propertiesParameters.properties) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openapi-jsonrpc-jsdoc",
3
- "version": "1.5.2",
3
+ "version": "1.5.3",
4
4
  "description": "Transform JSDoc-annotated JSON-RPC 2.0 methods into OpenAPI specifications.",
5
5
  "main": "index.mjs",
6
6
  "type": "module",