@haddowg/json-api-codegen 1.15.1 → 1.17.0

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/dist/cli.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as CodegenConfig } from "./index-FaJ8Xx6v.mjs";
1
+ import { r as CodegenConfig } from "./index-DabrCjXa.mjs";
2
2
 
3
3
  //#region src/cli.d.ts
4
4
  declare const USAGE = "Usage: json-api-codegen --input <url|file> --output <file> [--server <name>] [--schemas <url|file>] [--examples] [--check]";
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { i as generateFiles, t as check } from "./src-i5j2I9fk.mjs";
2
+ import { i as generateFiles, t as check } from "./src-B1diyKmJ.mjs";
3
3
  import { realpathSync } from "node:fs";
4
4
  import { fileURLToPath } from "node:url";
5
5
  //#region src/cli.ts
@@ -23,6 +23,11 @@ interface SchemaObject {
23
23
  oneOf?: readonly SchemaObject[];
24
24
  'x-enum-varnames'?: readonly string[];
25
25
  'x-enum-descriptions'?: readonly string[];
26
+ /** On a `sort` array: the families of keys it accepts by prefix beside its fixed enum. */
27
+ 'x-sort-families'?: readonly {
28
+ prefix?: unknown;
29
+ suffixPattern?: unknown;
30
+ }[];
26
31
  [key: string]: unknown;
27
32
  }
28
33
  /** A property entry: either a schema, or the literal `false` (a forbidden member). */
@@ -301,11 +306,18 @@ declare class DescriptorBuilder {
301
306
  */
302
307
  private includable;
303
308
  /**
304
- * The sort tokens the COLLECTION read accepts — the `sort` query parameter's
305
- * `schema.items.enum` (signed field names) on the collection GET. Returns `undefined` when
306
- * the collection advertises no `sort` parameter (sorting unsupported).
309
+ * The sort tokens the COLLECTION read accepts — the `sort` query parameter's fixed enum
310
+ * (signed field names) on the collection GET: `schema.items.enum`, or the enum branch of
311
+ * `schema.items.anyOf` when the parameter also accepts sort families. Returns `undefined` when
312
+ * the collection advertises no `sort` parameter or no fixed keys.
307
313
  */
308
314
  private sortable;
315
+ /**
316
+ * The sort families the COLLECTION read accepts, from the `sort` parameter's
317
+ * `x-sort-families`: each a key prefix and the pattern its suffix must match. Returns
318
+ * `undefined` when the parameter lists none.
319
+ */
320
+ private sortFamilies;
309
321
  /**
310
322
  * The filter keys the COLLECTION read accepts in `filter[...]` (the `filter[<key>]` parameter
311
323
  * names, `<key>` extracted), sorted for deterministic output. Returns `undefined` when the
@@ -342,7 +354,7 @@ declare function buildExamples(doc: OpenApiDocument, descriptor: ApiDescriptor):
342
354
  /** Below this the document predates the structures this codegen reads. */
343
355
  declare const MINIMUM_CONTRACT = 1;
344
356
  /** Above this the document carries structures this codegen does not read. */
345
- declare const MAXIMUM_CONTRACT = 19;
357
+ declare const MAXIMUM_CONTRACT = 21;
346
358
  /**
347
359
  * Check the document's `info.x-generator.contract` against the range this codegen reads. A
348
360
  * document older than the range throws; a newer one returns a warning, because its new
@@ -763,4 +775,4 @@ declare function generateFiles(config: CodegenConfig): Promise<string[]>;
763
775
  declare function check(config: CodegenConfig): Promise<CheckResult>;
764
776
  //#endregion
765
777
  export { operationExamples as A, PathItemObject as B, VerbCollision as C, MINIMUM_CONTRACT as D, MAXIMUM_CONTRACT as E, InfoObject as F, SecurityRequirement as G, ResponseObject as H, MediaTypeObject as I, SecuritySchemeObject as K, OpenApiDocument as L, buildAtomic as M, buildDescriptor as N, checkContract as O, HttpMethod as P, OperationObject as R, Emitter as S, emit as T, SchemaObject as U, RequestBodyObject as V, SchemaOrBool as W, emitExamples as _, examplesOutputPath as a, emitErrorCodes as b, schemasOutputPath as c, hashJson as d, provenanceLines as f, readSchemas as g, readDocument as h, check as i, DescriptorBuilder as j, buildExamples as k, Provenance as l, SchemaBundle as m, CheckResult as n, generate as o, emitSchemas as p, CodegenConfig as r, generateFiles as s, ArtifactDrift as t, deriveProvenance as u, DocumentedErrorCode as v, detectVerbCollisions as w, readErrorCatalogue as x, ErrorCatalogue as y, ParameterObject as z };
766
- //# sourceMappingURL=index-FaJ8Xx6v.d.mts.map
778
+ //# sourceMappingURL=index-DabrCjXa.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-DabrCjXa.d.mts","names":[],"sources":["../src/openapi.ts","../src/build-descriptor.ts","../src/build-examples.ts","../src/contract.ts","../src/emit.ts","../src/error-codes.ts","../src/emit-examples.ts","../src/reader.ts","../src/emit-schemas.ts","../src/provenance.ts","../src/index.ts"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { A as operationExamples, B as PathItemObject, C as VerbCollision, D as MINIMUM_CONTRACT, E as MAXIMUM_CONTRACT, F as InfoObject, G as SecurityRequirement, H as ResponseObject, I as MediaTypeObject, K as SecuritySchemeObject, L as OpenApiDocument, M as buildAtomic, N as buildDescriptor, O as checkContract, P as HttpMethod, R as OperationObject, S as Emitter, T as emit, U as SchemaObject, V as RequestBodyObject, W as SchemaOrBool, _ as emitExamples, a as examplesOutputPath, b as emitErrorCodes, c as schemasOutputPath, d as hashJson, f as provenanceLines, g as readSchemas, h as readDocument, i as check, j as DescriptorBuilder, k as buildExamples, l as Provenance, m as SchemaBundle, n as CheckResult, o as generate, p as emitSchemas, r as CodegenConfig, s as generateFiles, t as ArtifactDrift, u as deriveProvenance, v as DocumentedErrorCode, w as detectVerbCollisions, x as readErrorCatalogue, y as ErrorCatalogue, z as ParameterObject } from "./index-FaJ8Xx6v.mjs";
1
+ import { A as operationExamples, B as PathItemObject, C as VerbCollision, D as MINIMUM_CONTRACT, E as MAXIMUM_CONTRACT, F as InfoObject, G as SecurityRequirement, H as ResponseObject, I as MediaTypeObject, K as SecuritySchemeObject, L as OpenApiDocument, M as buildAtomic, N as buildDescriptor, O as checkContract, P as HttpMethod, R as OperationObject, S as Emitter, T as emit, U as SchemaObject, V as RequestBodyObject, W as SchemaOrBool, _ as emitExamples, a as examplesOutputPath, b as emitErrorCodes, c as schemasOutputPath, d as hashJson, f as provenanceLines, g as readSchemas, h as readDocument, i as check, j as DescriptorBuilder, k as buildExamples, l as Provenance, m as SchemaBundle, n as CheckResult, o as generate, p as emitSchemas, r as CodegenConfig, s as generateFiles, t as ArtifactDrift, u as deriveProvenance, v as DocumentedErrorCode, w as detectVerbCollisions, x as readErrorCatalogue, y as ErrorCatalogue, z as ParameterObject } from "./index-DabrCjXa.mjs";
2
2
  export { ArtifactDrift, CheckResult, CodegenConfig, DescriptorBuilder, type DocumentedErrorCode, Emitter, type ErrorCatalogue, type HttpMethod, type InfoObject, MAXIMUM_CONTRACT, MINIMUM_CONTRACT, type MediaTypeObject, type OpenApiDocument, type OperationObject, type ParameterObject, type PathItemObject, type Provenance, type RequestBodyObject, type ResponseObject, type SchemaBundle, type SchemaObject, type SchemaOrBool, type SecurityRequirement, type SecuritySchemeObject, type VerbCollision, buildAtomic, buildDescriptor, buildExamples, check, checkContract, deriveProvenance, detectVerbCollisions, emit, emitErrorCodes, emitExamples, emitSchemas, examplesOutputPath, generate, generateFiles, hashJson, operationExamples, provenanceLines, readDocument, readErrorCatalogue, readSchemas, schemasOutputPath };
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { C as DescriptorBuilder, S as operationExamples, T as buildDescriptor, _ as readErrorCatalogue, a as schemasOutputPath, b as checkContract, c as emitSchemas, d as detectVerbCollisions, f as emit, g as emitErrorCodes, h as provenanceLines, i as generateFiles, l as emitExamples, m as hashJson, n as examplesOutputPath, o as readDocument, p as deriveProvenance, r as generate, s as readSchemas, t as check, u as Emitter, v as MAXIMUM_CONTRACT, w as buildAtomic, x as buildExamples, y as MINIMUM_CONTRACT } from "./src-i5j2I9fk.mjs";
1
+ import { C as DescriptorBuilder, S as operationExamples, T as buildDescriptor, _ as readErrorCatalogue, a as schemasOutputPath, b as checkContract, c as emitSchemas, d as detectVerbCollisions, f as emit, g as emitErrorCodes, h as provenanceLines, i as generateFiles, l as emitExamples, m as hashJson, n as examplesOutputPath, o as readDocument, p as deriveProvenance, r as generate, s as readSchemas, t as check, u as Emitter, v as MAXIMUM_CONTRACT, w as buildAtomic, x as buildExamples, y as MINIMUM_CONTRACT } from "./src-B1diyKmJ.mjs";
2
2
  export { DescriptorBuilder, Emitter, MAXIMUM_CONTRACT, MINIMUM_CONTRACT, buildAtomic, buildDescriptor, buildExamples, check, checkContract, deriveProvenance, detectVerbCollisions, emit, emitErrorCodes, emitExamples, emitSchemas, examplesOutputPath, generate, generateFiles, hashJson, operationExamples, provenanceLines, readDocument, readErrorCatalogue, readSchemas, schemasOutputPath };
@@ -177,6 +177,8 @@ var DescriptorBuilder = class {
177
177
  if (included !== void 0) descriptor.included = included;
178
178
  const sortable = this.sortable(collection);
179
179
  if (sortable !== void 0) descriptor.sortable = sortable;
180
+ const sortFamilies = this.sortFamilies(collection);
181
+ if (sortFamilies !== void 0) descriptor.sortFamilies = sortFamilies;
180
182
  const filterable = this.filterable(collection);
181
183
  if (filterable !== void 0) descriptor.filterable = filterable;
182
184
  if (Object.keys(actions).length > 0) descriptor.actions = actions;
@@ -829,14 +831,32 @@ var DescriptorBuilder = class {
829
831
  return tokens !== void 0 && tokens.length > 0 ? tokens : void 0;
830
832
  }
831
833
  /**
832
- * The sort tokens the COLLECTION read accepts — the `sort` query parameter's
833
- * `schema.items.enum` (signed field names) on the collection GET. Returns `undefined` when
834
- * the collection advertises no `sort` parameter (sorting unsupported).
834
+ * The sort tokens the COLLECTION read accepts — the `sort` query parameter's fixed enum
835
+ * (signed field names) on the collection GET: `schema.items.enum`, or the enum branch of
836
+ * `schema.items.anyOf` when the parameter also accepts sort families. Returns `undefined` when
837
+ * the collection advertises no `sort` parameter or no fixed keys.
835
838
  */
836
839
  sortable(collection) {
837
840
  if (collection === void 0) return;
838
- const tokens = paramItemsEnum(this.operation(collection, "get"), "sort");
839
- return tokens !== void 0 && tokens.length > 0 ? tokens : void 0;
841
+ const items = paramSchema(this.operation(collection, "get"), "sort")?.items;
842
+ const tokens = (items?.anyOf ?? (items === void 0 ? [] : [items])).flatMap((branch) => Array.isArray(branch.enum) ? branch.enum.filter((v) => typeof v === "string") : []);
843
+ return tokens.length > 0 ? tokens : void 0;
844
+ }
845
+ /**
846
+ * The sort families the COLLECTION read accepts, from the `sort` parameter's
847
+ * `x-sort-families`: each a key prefix and the pattern its suffix must match. Returns
848
+ * `undefined` when the parameter lists none.
849
+ */
850
+ sortFamilies(collection) {
851
+ if (collection === void 0) return;
852
+ const declared = paramSchema(this.operation(collection, "get"), "sort")?.["x-sort-families"];
853
+ if (!Array.isArray(declared)) return;
854
+ const families = [];
855
+ for (const family of declared) if (typeof family.prefix === "string" && typeof family.suffixPattern === "string") families.push({
856
+ prefix: family.prefix,
857
+ suffixPattern: family.suffixPattern
858
+ });
859
+ return families.length > 0 ? families : void 0;
840
860
  }
841
861
  /**
842
862
  * The filter keys the COLLECTION read accepts in `filter[...]` (the `filter[<key>]` parameter
@@ -930,17 +950,18 @@ function withCountParam(op) {
930
950
  };
931
951
  }
932
952
  }
953
+ /** The schema of the operation's parameter of that name, if it carries one. */
954
+ function paramSchema(op, paramName) {
955
+ return op?.parameters?.find((param) => param.name === paramName)?.schema;
956
+ }
933
957
  /**
934
958
  * The string members of an array-valued query parameter's `schema.items.enum` (the shape the
935
- * `include` and `sort` parameters use). Returns `undefined` when the operation carries no
936
- * parameter of that name, or one whose schema declares no enum.
959
+ * `include` parameter uses). Returns `undefined` when the operation carries no parameter of
960
+ * that name, or one whose schema declares no enum.
937
961
  */
938
962
  function paramItemsEnum(op, paramName) {
939
- for (const param of op?.parameters ?? []) {
940
- if (param.name !== paramName) continue;
941
- const enumValues = param.schema?.items?.enum;
942
- return Array.isArray(enumValues) ? enumValues.filter((v) => typeof v === "string") : void 0;
943
- }
963
+ const enumValues = paramSchema(op, paramName)?.items?.enum;
964
+ return Array.isArray(enumValues) ? enumValues.filter((v) => typeof v === "string") : void 0;
944
965
  }
945
966
  /**
946
967
  * True for the Atomic Operations ext media type — `application/vnd.api+json` carrying the
@@ -1230,7 +1251,7 @@ function buildExamples(doc, descriptor) {
1230
1251
  /** Below this the document predates the structures this codegen reads. */
1231
1252
  const MINIMUM_CONTRACT = 1;
1232
1253
  /** Above this the document carries structures this codegen does not read. */
1233
- const MAXIMUM_CONTRACT = 19;
1254
+ const MAXIMUM_CONTRACT = 21;
1234
1255
  /**
1235
1256
  * Check the document's `info.x-generator.contract` against the range this codegen reads. A
1236
1257
  * document older than the range throws; a newer one returns a warning, because its new
@@ -1240,8 +1261,8 @@ const MAXIMUM_CONTRACT = 19;
1240
1261
  function checkContract(doc) {
1241
1262
  const contract = doc.info?.["x-generator"]?.contract;
1242
1263
  if (typeof contract !== "number") return;
1243
- if (contract < 1) throw new Error(`the document declares contract ${contract}, which predates what this codegen reads (it supports 1 to 19). Use an older codegen release, or regenerate the document from a newer server.`);
1244
- if (contract > 19) return `the document declares contract ${contract} and this codegen reads up to 19. It describes capabilities that were not generated; upgrade the codegen to pick them up.`;
1264
+ if (contract < 1) throw new Error(`the document declares contract ${contract}, which predates what this codegen reads (it supports 1 to 21). Use an older codegen release, or regenerate the document from a newer server.`);
1265
+ if (contract > 21) return `the document declares contract ${contract} and this codegen reads up to 21. It describes capabilities that were not generated; upgrade the codegen to pick them up.`;
1245
1266
  }
1246
1267
  //#endregion
1247
1268
  //#region src/declared-links.ts
@@ -1848,6 +1869,22 @@ function exampleDoc(op) {
1848
1869
  function escapeRegExp(value) {
1849
1870
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1850
1871
  }
1872
+ /** Whether a TS type has a `|` or `&` outside its braces, brackets and string literals. */
1873
+ function hasTopLevelOperator(type) {
1874
+ let depth = 0;
1875
+ let quoted = false;
1876
+ for (let i = 0; i < type.length; i++) {
1877
+ const char = type[i];
1878
+ if (quoted) {
1879
+ if (char === "\\") i++;
1880
+ else if (char === "\"") quoted = false;
1881
+ } else if (char === "\"") quoted = true;
1882
+ else if (char === "{" || char === "[" || char === "(" || char === "<") depth++;
1883
+ else if (char === "}" || char === "]" || char === ")" || char === ">") depth--;
1884
+ else if (depth === 0 && (char === "|" || char === "&")) return true;
1885
+ }
1886
+ return false;
1887
+ }
1851
1888
  var Emitter = class {
1852
1889
  descriptor;
1853
1890
  atomic;
@@ -2498,6 +2535,9 @@ var Emitter = class {
2498
2535
  }
2499
2536
  /** The non-nullable TS type for the declared JSON type(s). */
2500
2537
  baseTsType(schema, types) {
2538
+ const constant = schema["const"];
2539
+ if (typeof constant === "string") return stringLiteral(constant);
2540
+ if (typeof constant === "number" || typeof constant === "boolean") return String(constant);
2501
2541
  if (Array.isArray(schema.enum) && schema.enum.length > 0) return schema.enum.map((value) => stringLiteral(String(value))).join(" | ");
2502
2542
  if (types.length === 0) return "unknown";
2503
2543
  const mapped = types.map((t) => this.scalarOrComposite(schema, t));
@@ -2531,7 +2571,7 @@ var Emitter = class {
2531
2571
  arrayType(schema) {
2532
2572
  const items = schema.items;
2533
2573
  const element = isSchema(items) ? this.tsType(items) : "unknown";
2534
- const list = /[|&]/.test(element) ? `(${element})[]` : `${element}[]`;
2574
+ const list = hasTopLevelOperator(element) ? `(${element})[]` : `${element}[]`;
2535
2575
  const minItems = schema["minItems"];
2536
2576
  return typeof minItems === "number" && minItems >= 1 ? `[${element}, ...${list}]` : list;
2537
2577
  }
@@ -2875,4 +2915,4 @@ async function check(config) {
2875
2915
  //#endregion
2876
2916
  export { DescriptorBuilder as C, operationExamples as S, buildDescriptor as T, readErrorCatalogue as _, schemasOutputPath as a, checkContract as b, emitSchemas as c, detectVerbCollisions as d, emit as f, emitErrorCodes as g, provenanceLines as h, generateFiles as i, emitExamples as l, hashJson as m, examplesOutputPath as n, readDocument as o, deriveProvenance as p, generate as r, readSchemas as s, check as t, Emitter as u, MAXIMUM_CONTRACT as v, buildAtomic as w, buildExamples as x, MINIMUM_CONTRACT as y };
2877
2917
 
2878
- //# sourceMappingURL=src-i5j2I9fk.mjs.map
2918
+ //# sourceMappingURL=src-B1diyKmJ.mjs.map