@rvoh/psychic 0.28.6 → 0.29.1

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.
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
@@ -6,6 +29,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
29
  const dream_1 = require("@rvoh/dream");
7
30
  const cache_js_1 = require("../psychic-application/cache.js");
8
31
  const isBlankDescription_js_1 = __importDefault(require("./helpers/isBlankDescription.js"));
32
+ const primitiveOpenapiStatementToOpenapi_js_1 = __importStar(require("./helpers/primitiveOpenapiStatementToOpenapi.js"));
9
33
  const serializer_js_1 = __importDefault(require("./serializer.js"));
10
34
  class OpenapiBodySegmentRenderer {
11
35
  controllerClass;
@@ -113,23 +137,40 @@ class OpenapiBodySegmentRenderer {
113
137
  return 'anyOf';
114
138
  if (allOfBodySegment.allOf)
115
139
  return 'allOf';
116
- if (objectBodySegment.type === 'object')
140
+ if (this.maybeNullTypeToType(objectBodySegment) === 'object')
117
141
  return 'object';
118
- else if (arrayBodySegment.type === 'array')
142
+ else if (this.maybeNullTypeToType(arrayBodySegment) === 'array')
119
143
  return 'array';
120
144
  else {
121
145
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
122
146
  if (dream_1.openapiShorthandPrimitiveTypes.includes(bodySegment))
123
147
  return 'openapi_primitive_literal';
124
148
  if (typeof bodySegment === 'object') {
125
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
126
- if (dream_1.openapiShorthandPrimitiveTypes.includes(bodySegment.type))
149
+ if (dream_1.openapiShorthandPrimitiveTypes.includes(this.maybeNullTypeToType(bodySegment)))
127
150
  return 'openapi_primitive_object';
128
151
  }
129
152
  if (typeof bodySegment === 'object')
130
153
  return 'unknown_object';
131
154
  }
132
155
  }
156
+ maybeNullTypeToType(bodySegment) {
157
+ if (bodySegment === undefined)
158
+ return undefined;
159
+ if (typeof bodySegment === 'string')
160
+ return bodySegment;
161
+ const safeBodySegment = bodySegment;
162
+ const openapiType = safeBodySegment.type;
163
+ if (Array.isArray(openapiType)) {
164
+ if (openapiType[1] === 'null')
165
+ return openapiType[0];
166
+ if (openapiType[0] === 'null')
167
+ return openapiType[1];
168
+ return undefined;
169
+ }
170
+ else {
171
+ return openapiType;
172
+ }
173
+ }
133
174
  /**
134
175
  * @internal
135
176
  *
@@ -170,13 +211,9 @@ class OpenapiBodySegmentRenderer {
170
211
  */
171
212
  arrayStatement(bodySegment) {
172
213
  const data = this.applyCommonFieldsToPayload({
173
- type: 'array',
174
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
214
+ type: bodySegment.type,
175
215
  items: this.recursivelyParseBody(bodySegment.items),
176
216
  });
177
- if (bodySegment.nullable) {
178
- data.nullable = true;
179
- }
180
217
  const description = bodySegment.description;
181
218
  if (description) {
182
219
  data.description = description;
@@ -191,14 +228,11 @@ class OpenapiBodySegmentRenderer {
191
228
  objectStatement(bodySegment) {
192
229
  const objectBodySegment = bodySegment;
193
230
  const data = {
194
- type: 'object',
231
+ type: bodySegment.type,
195
232
  };
196
233
  if (objectBodySegment.description) {
197
234
  data.description = objectBodySegment.description;
198
235
  }
199
- if (objectBodySegment.nullable) {
200
- data.nullable = true;
201
- }
202
236
  if (objectBodySegment.summary) {
203
237
  data.summary = objectBodySegment.summary;
204
238
  }
@@ -246,7 +280,7 @@ class OpenapiBodySegmentRenderer {
246
280
  * recursively parses a primitive literal type (i.e. string or boolean[])
247
281
  */
248
282
  primitiveLiteralStatement(bodySegment) {
249
- return this.parseAttributeValue(bodySegment);
283
+ return (0, primitiveOpenapiStatementToOpenapi_js_1.default)(bodySegment);
250
284
  }
251
285
  /**
252
286
  * @internal
@@ -254,53 +288,22 @@ class OpenapiBodySegmentRenderer {
254
288
  * recursively parses a primitive object type (i.e. { type: 'string[]' })
255
289
  */
256
290
  primitiveObjectStatement(bodySegment) {
257
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument
258
- if (/\[\]$/.test(bodySegment.type)) {
259
- return this.applyConfigurationOptions(this.applyCommonFieldsToPayload(
260
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
261
- this.expandShorthandArray(bodySegment)));
291
+ const safeBodySegment = bodySegment;
292
+ if (this.typeIsOpenapiArrayPrimitive(safeBodySegment.type)) {
293
+ return this.applyConfigurationOptions(this.applyCommonFieldsToPayload({
294
+ ...safeBodySegment,
295
+ ...(0, primitiveOpenapiStatementToOpenapi_js_1.default)(safeBodySegment.type),
296
+ }));
262
297
  }
263
298
  else {
264
- return this.applyConfigurationOptions(this.applyCommonFieldsToPayload(
265
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
266
- this.expandType(bodySegment)));
299
+ return this.applyConfigurationOptions(this.applyCommonFieldsToPayload({
300
+ ...safeBodySegment,
301
+ ...(0, primitiveOpenapiStatementToOpenapi_js_1.default)(safeBodySegment.type),
302
+ }));
267
303
  }
268
304
  }
269
- expandShorthandArray(bodySegment) {
270
- const retObj = {
271
- ...bodySegment,
272
- type: 'array',
273
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
274
- items: this.expandType({
275
- // ...bodySegment,
276
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
277
- type: bodySegment.type.replace(/\[\]$/, ''),
278
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
279
- }),
280
- };
281
- if (bodySegment.nullable) {
282
- retObj.nullable = true;
283
- }
284
- return retObj;
285
- }
286
- expandType(bodySegment) {
287
- switch (bodySegment.type) {
288
- case 'decimal':
289
- case 'double':
290
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
291
- ;
292
- bodySegment.format = bodySegment.type;
293
- bodySegment.type = 'number';
294
- break;
295
- case 'date':
296
- case 'date-time':
297
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
298
- ;
299
- bodySegment.format = bodySegment.type;
300
- bodySegment.type = 'string';
301
- break;
302
- }
303
- return bodySegment;
305
+ typeIsOpenapiArrayPrimitive(openapiType) {
306
+ return /\[\]$/.test((0, primitiveOpenapiStatementToOpenapi_js_1.maybeNullPrimitiveToPrimitive)(openapiType));
304
307
  }
305
308
  applyConfigurationOptions(obj) {
306
309
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment
@@ -359,19 +362,17 @@ The following values will be allowed:
359
362
  };
360
363
  if (serializerRefBodySegment.many) {
361
364
  const returnVal = {
362
- type: 'array',
365
+ type: serializerRefBodySegment.maybeNull ? ['array', 'null'] : 'array',
363
366
  items: {
364
367
  $ref: `#/components/schemas/${serializerKey}`,
365
368
  },
366
369
  };
367
- if (serializerRefBodySegment.nullable)
368
- returnVal.nullable = true;
369
370
  return returnVal;
370
371
  }
371
372
  else {
372
- if (serializerRefBodySegment.nullable) {
373
+ if (serializerRefBodySegment.maybeNull) {
373
374
  return {
374
- allOf: [{ $ref: `#/components/schemas/${serializerKey}` }, { nullable: true }],
375
+ allOf: [{ $ref: `#/components/schemas/${serializerKey}` }, { type: 'null' }],
375
376
  };
376
377
  }
377
378
  else {
@@ -412,81 +413,6 @@ The following values will be allowed:
412
413
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
413
414
  return this.applyCommonFieldsToPayload(bodySegment);
414
415
  }
415
- /**
416
- * @internal
417
- *
418
- * parses a primitive stored type
419
- */
420
- parseAttributeValue(data) {
421
- if (!data)
422
- return {
423
- type: 'object',
424
- nullable: true,
425
- };
426
- switch (data) {
427
- case 'string[]':
428
- case 'number[]':
429
- case 'boolean[]':
430
- case 'integer[]':
431
- return (0, dream_1.compact)({
432
- type: 'array',
433
- items: {
434
- type: this.serializerTypeToOpenapiType(data),
435
- },
436
- });
437
- case 'decimal[]':
438
- case 'double[]':
439
- return (0, dream_1.compact)({
440
- type: 'array',
441
- items: {
442
- type: 'number',
443
- format: data.replace(/\[\]$/, ''),
444
- },
445
- });
446
- case 'date[]':
447
- case 'date-time[]':
448
- return (0, dream_1.compact)({
449
- type: 'array',
450
- items: {
451
- type: 'string',
452
- format: data.replace(/\[\]$/, ''),
453
- },
454
- });
455
- case 'decimal':
456
- case 'double':
457
- return (0, dream_1.compact)({
458
- type: 'number',
459
- format: data,
460
- });
461
- case 'date':
462
- case 'date-time':
463
- return (0, dream_1.compact)({
464
- type: 'string',
465
- format: data,
466
- });
467
- default:
468
- return (0, dream_1.compact)({
469
- type: this.serializerTypeToOpenapiType(data),
470
- });
471
- }
472
- }
473
- /**
474
- * @internal
475
- *
476
- * sanitizes primitive openapi type before putting in
477
- * openapi type fields
478
- */
479
- serializerTypeToOpenapiType(type) {
480
- switch (type) {
481
- case 'date':
482
- case 'date-time':
483
- case 'date[]':
484
- case 'date-time[]':
485
- return 'string';
486
- default:
487
- return type.replace(/\[\]$/, '');
488
- }
489
- }
490
416
  /**
491
417
  * @internal
492
418
  *
@@ -497,11 +423,6 @@ The following values will be allowed:
497
423
  const returnObj = {
498
424
  ...obj,
499
425
  };
500
- if (objectCast.nullable) {
501
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
502
- ;
503
- returnObj.nullable = true;
504
- }
505
426
  if (objectCast.description) {
506
427
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
507
428
  ;
@@ -10,6 +10,7 @@ const index_js_1 = __importDefault(require("../psychic-application/index.js"));
10
10
  const body_segment_js_1 = __importDefault(require("./body-segment.js"));
11
11
  const defaults_js_1 = require("./defaults.js");
12
12
  const openapiRoute_js_1 = __importDefault(require("./helpers/openapiRoute.js"));
13
+ const primitiveOpenapiStatementToOpenapi_js_1 = __importDefault(require("./helpers/primitiveOpenapiStatementToOpenapi.js"));
13
14
  const serializer_js_1 = __importDefault(require("./serializer.js"));
14
15
  class OpenapiEndpointRenderer {
15
16
  dreamsOrSerializers;
@@ -27,7 +28,6 @@ class OpenapiEndpointRenderer {
27
28
  security;
28
29
  summary;
29
30
  description;
30
- nullable;
31
31
  omitDefaultHeaders;
32
32
  omitDefaultResponses;
33
33
  defaultResponse;
@@ -47,7 +47,7 @@ class OpenapiEndpointRenderer {
47
47
  * const json = JSON.encode(openapiJsonContents, null, 2)
48
48
  * ```
49
49
  */
50
- constructor(dreamsOrSerializers, controllerClass, action, { requestBody, headers, many, query, responses, serializerKey, status, tags, security, pathParams, description, nullable, summary, omitDefaultHeaders, omitDefaultResponses, defaultResponse, } = {}) {
50
+ constructor(dreamsOrSerializers, controllerClass, action, { requestBody, headers, many, query, responses, serializerKey, status, tags, security, pathParams, description, summary, omitDefaultHeaders, omitDefaultResponses, defaultResponse, } = {}) {
51
51
  this.dreamsOrSerializers = dreamsOrSerializers;
52
52
  this.controllerClass = controllerClass;
53
53
  this.action = action;
@@ -62,7 +62,6 @@ class OpenapiEndpointRenderer {
62
62
  this.pathParams = pathParams;
63
63
  this.summary = summary;
64
64
  this.description = description;
65
- this.nullable = nullable;
66
65
  this.tags = tags === undefined ? controllerClass.openapiConfig?.tags || [] : tags;
67
66
  this.omitDefaultHeaders =
68
67
  omitDefaultHeaders === undefined
@@ -406,6 +405,7 @@ class OpenapiEndpointRenderer {
406
405
  }
407
406
  for (const columnName of paramSafeColumns) {
408
407
  const columnMetadata = columns[columnName];
408
+ const nullableColumn = columnMetadata?.allowNull;
409
409
  switch (columnMetadata?.dbType) {
410
410
  case 'boolean':
411
411
  case 'boolean[]':
@@ -415,9 +415,7 @@ class OpenapiEndpointRenderer {
415
415
  case 'integer[]':
416
416
  paramsShape.properties = {
417
417
  ...paramsShape.properties,
418
- [columnName]: {
419
- type: columnMetadata.dbType,
420
- },
418
+ [columnName]: (0, primitiveOpenapiStatementToOpenapi_js_1.default)(columnMetadata.dbType, nullableColumn),
421
419
  };
422
420
  break;
423
421
  case 'character varying':
@@ -427,9 +425,7 @@ class OpenapiEndpointRenderer {
427
425
  case 'bigint':
428
426
  paramsShape.properties = {
429
427
  ...paramsShape.properties,
430
- [columnName]: {
431
- type: 'string',
432
- },
428
+ [columnName]: (0, primitiveOpenapiStatementToOpenapi_js_1.default)('string', nullableColumn),
433
429
  };
434
430
  break;
435
431
  case 'character varying[]':
@@ -439,12 +435,7 @@ class OpenapiEndpointRenderer {
439
435
  case 'bigint[]':
440
436
  paramsShape.properties = {
441
437
  ...paramsShape.properties,
442
- [columnName]: {
443
- type: 'array',
444
- items: {
445
- type: 'string',
446
- },
447
- },
438
+ [columnName]: (0, primitiveOpenapiStatementToOpenapi_js_1.default)('string[]', nullableColumn),
448
439
  };
449
440
  break;
450
441
  case 'timestamp':
@@ -452,9 +443,7 @@ class OpenapiEndpointRenderer {
452
443
  case 'timestamp without time zone':
453
444
  paramsShape.properties = {
454
445
  ...paramsShape.properties,
455
- [columnName]: {
456
- type: 'date-time',
457
- },
446
+ [columnName]: (0, primitiveOpenapiStatementToOpenapi_js_1.default)('date-time', nullableColumn),
458
447
  };
459
448
  break;
460
449
  case 'timestamp[]':
@@ -462,12 +451,7 @@ class OpenapiEndpointRenderer {
462
451
  case 'timestamp without time zone[]':
463
452
  paramsShape.properties = {
464
453
  ...paramsShape.properties,
465
- [columnName]: {
466
- type: 'array',
467
- items: {
468
- type: 'date-time',
469
- },
470
- },
454
+ [columnName]: (0, primitiveOpenapiStatementToOpenapi_js_1.default)('date-time[]', nullableColumn),
471
455
  };
472
456
  break;
473
457
  case 'json':
@@ -475,7 +459,7 @@ class OpenapiEndpointRenderer {
475
459
  paramsShape.properties = {
476
460
  ...paramsShape.properties,
477
461
  [columnName]: {
478
- type: 'object',
462
+ type: nullableColumn ? ['object', 'null'] : 'object',
479
463
  },
480
464
  };
481
465
  break;
@@ -484,7 +468,7 @@ class OpenapiEndpointRenderer {
484
468
  paramsShape.properties = {
485
469
  ...paramsShape.properties,
486
470
  [columnName]: {
487
- type: 'array',
471
+ type: nullableColumn ? ['array', 'null'] : 'array',
488
472
  items: {
489
473
  type: 'object',
490
474
  },
@@ -494,20 +478,13 @@ class OpenapiEndpointRenderer {
494
478
  case 'numeric':
495
479
  paramsShape.properties = {
496
480
  ...paramsShape.properties,
497
- [columnName]: {
498
- type: 'number',
499
- },
481
+ [columnName]: (0, primitiveOpenapiStatementToOpenapi_js_1.default)('number', nullableColumn),
500
482
  };
501
483
  break;
502
484
  case 'numeric[]':
503
485
  paramsShape.properties = {
504
486
  ...paramsShape.properties,
505
- [columnName]: {
506
- type: 'array',
507
- items: {
508
- type: 'number',
509
- },
510
- },
487
+ [columnName]: (0, primitiveOpenapiStatementToOpenapi_js_1.default)('number[]', nullableColumn),
511
488
  };
512
489
  break;
513
490
  default:
@@ -526,9 +503,9 @@ class OpenapiEndpointRenderer {
526
503
  ...paramsShape.properties,
527
504
  [columnName]: {
528
505
  anyOf: [
529
- { type: 'string', nullable: true },
530
- { type: 'number', nullable: true },
531
- { type: 'object', nullable: true },
506
+ { type: ['string', 'null'] },
507
+ { type: ['number', 'null'] },
508
+ { type: ['object', 'null'] },
532
509
  ],
533
510
  },
534
511
  };
@@ -539,10 +516,10 @@ class OpenapiEndpointRenderer {
539
516
  paramsShape.properties = {
540
517
  ...paramsShape.properties,
541
518
  [columnName]: {
542
- type: 'array',
519
+ type: nullableColumn ? ['array', 'null'] : 'array',
543
520
  items: {
544
521
  type: 'string',
545
- enum: [...columnMetadata.enumValues, ...(columnMetadata.allowNull ? ['null'] : [])],
522
+ enum: [...columnMetadata.enumValues],
546
523
  },
547
524
  },
548
525
  };
@@ -551,17 +528,13 @@ class OpenapiEndpointRenderer {
551
528
  paramsShape.properties = {
552
529
  ...paramsShape.properties,
553
530
  [columnName]: {
554
- type: 'string',
555
- enum: [...columnMetadata.enumValues, ...(columnMetadata.allowNull ? ['null'] : [])],
531
+ type: nullableColumn ? ['string', 'null'] : 'string',
532
+ enum: [...columnMetadata.enumValues],
556
533
  },
557
534
  };
558
535
  }
559
536
  }
560
537
  }
561
- if (columnMetadata?.allowNull && paramsShape.properties[columnName]) {
562
- ;
563
- paramsShape.properties[columnName].nullable = true;
564
- }
565
538
  }
566
539
  return {
567
540
  content: {
@@ -668,16 +641,6 @@ class OpenapiEndpointRenderer {
668
641
  }
669
642
  return this.parseSingleEntitySerializerResponseShape();
670
643
  }
671
- accountForNullableOption(bodySegment, nullable) {
672
- if (nullable) {
673
- return {
674
- allOf: [bodySegment, { nullable: true }],
675
- };
676
- }
677
- else {
678
- return bodySegment;
679
- }
680
- }
681
644
  /**
682
645
  * @internal
683
646
  *
@@ -694,16 +657,15 @@ class OpenapiEndpointRenderer {
694
657
  if (serializerClass === undefined)
695
658
  throw new Error('getSerializerClasses returned no serializer classes');
696
659
  const serializerKey = serializerClass.openapiName;
697
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
698
- const serializerObject = this.accountForNullableOption({
699
- $ref: `#/components/schemas/${serializerKey}`,
700
- }, this.nullable || false);
660
+ const serializerObject = { $ref: `#/components/schemas/${serializerKey}` };
701
661
  const baseSchema = this.many
702
662
  ? {
703
663
  type: 'array',
704
664
  items: serializerObject,
705
665
  }
706
- : serializerObject;
666
+ : this.defaultResponse?.maybeNull
667
+ ? { anyOf: [serializerObject, { type: 'null' }] }
668
+ : serializerObject;
707
669
  const finalOutput = {
708
670
  content: {
709
671
  'application/json': {
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = primitiveOpenapiStatementToOpenapi;
4
+ exports.maybeNullPrimitiveToPrimitive = maybeNullPrimitiveToPrimitive;
5
+ exports.booleanNullFromMaybeNullPrimitive = booleanNullFromMaybeNullPrimitive;
6
+ /**
7
+ * @internal
8
+ *
9
+ * parses a primitive stored type
10
+ */
11
+ function primitiveOpenapiStatementToOpenapi(data, maybeNull = false) {
12
+ if (!data)
13
+ return { type: ['object', 'null'] };
14
+ const primitiveString = maybeNullPrimitiveToPrimitive(data);
15
+ maybeNull = maybeNull || booleanNullFromMaybeNullPrimitive(data);
16
+ switch (primitiveString) {
17
+ case 'string':
18
+ case 'number':
19
+ case 'boolean':
20
+ case 'integer':
21
+ return {
22
+ type: maybeNull ? [primitiveString, 'null'] : primitiveString,
23
+ };
24
+ case 'decimal':
25
+ case 'double':
26
+ return {
27
+ type: maybeNull ? ['number', 'null'] : 'number',
28
+ format: primitiveString,
29
+ };
30
+ case 'date':
31
+ case 'date-time':
32
+ return {
33
+ type: maybeNull ? ['string', 'null'] : 'string',
34
+ format: primitiveString,
35
+ };
36
+ case 'string[]':
37
+ case 'number[]':
38
+ case 'boolean[]':
39
+ case 'integer[]':
40
+ return {
41
+ type: maybeNull ? ['array', 'null'] : 'array',
42
+ items: {
43
+ type: primitiveTypeToOpenapiType(primitiveString),
44
+ },
45
+ };
46
+ case 'decimal[]':
47
+ case 'double[]':
48
+ return {
49
+ type: maybeNull ? ['array', 'null'] : 'array',
50
+ items: {
51
+ type: 'number',
52
+ format: stripBracketsFromPrimitiveString(primitiveString),
53
+ },
54
+ };
55
+ case 'date[]':
56
+ case 'date-time[]':
57
+ return {
58
+ type: maybeNull ? ['array', 'null'] : 'array',
59
+ items: {
60
+ type: 'string',
61
+ format: stripBracketsFromPrimitiveString(primitiveString),
62
+ },
63
+ };
64
+ case 'null':
65
+ return {
66
+ type: 'null',
67
+ };
68
+ default:
69
+ throw new Error(`Unrecognized primitive type ${primitiveString}`);
70
+ }
71
+ }
72
+ function maybeNullPrimitiveToPrimitive(openapiType) {
73
+ if (Array.isArray(openapiType)) {
74
+ if (openapiType[1] === 'null')
75
+ return openapiType[0];
76
+ if (openapiType[0] === 'null')
77
+ return openapiType[1];
78
+ throw new Error(`Expected array with 'null' and an OpenAPI primitive string: ${JSON.stringify(openapiType)}`);
79
+ }
80
+ else {
81
+ return openapiType;
82
+ }
83
+ }
84
+ function booleanNullFromMaybeNullPrimitive(openapiType) {
85
+ if (Array.isArray(openapiType)) {
86
+ if (openapiType[1] === 'null')
87
+ return true;
88
+ if (openapiType[0] === 'null')
89
+ return true;
90
+ throw new Error(`Expected array with 'null' and an OpenAPI primitive string: ${JSON.stringify(openapiType)}`);
91
+ }
92
+ else {
93
+ return false;
94
+ }
95
+ }
96
+ /**
97
+ * @internal
98
+ *
99
+ * removes array brackets from primitive openapi type before putting in
100
+ * openapi type fields
101
+ */
102
+ function primitiveTypeToOpenapiType(type) {
103
+ switch (type) {
104
+ case 'date':
105
+ case 'date-time':
106
+ case 'date[]':
107
+ case 'date-time[]':
108
+ return 'string';
109
+ default:
110
+ return stripBracketsFromPrimitiveString(type);
111
+ }
112
+ }
113
+ /**
114
+ * @internal
115
+ *
116
+ * removes array brackets from primitive openapi format types before putting in
117
+ * openapi type fields
118
+ */
119
+ function stripBracketsFromPrimitiveString(type) {
120
+ return type.replace(/\[\]$/, '');
121
+ }