@sdk-it/typescript 0.42.1 → 0.43.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/index.js CHANGED
@@ -614,7 +614,7 @@ export async function prepare<const E extends keyof typeof schemas>(
614
614
  };
615
615
 
616
616
  // packages/typescript/src/lib/emitters/interface.ts
617
- import { followRef as followRef2, isRef as isRef2, parseRef as parseRef2, pascalcase as pascalcase2 } from "@sdk-it/core";
617
+ import { followRef as followRef2, isRef as isRef2, parseRef as parseRef2, pascalcase as pascalcase2, resolveRef } from "@sdk-it/core";
618
618
  import { isPrimitiveSchema as isPrimitiveSchema2, sanitizeTag as sanitizeTag2 } from "@sdk-it/spec";
619
619
  var TypeScriptEmitter = class {
620
620
  #spec;
@@ -692,7 +692,23 @@ var TypeScriptEmitter = class {
692
692
  return allOfTypes.length > 1 ? `${allOfTypes.join(" & ")}` : allOfTypes[0];
693
693
  }
694
694
  oneOf(schemas, required) {
695
- const oneOfTypes = schemas.map((sub) => this.handle(sub, true));
695
+ const isBareString = (s) => {
696
+ const r = resolveRef(this.#spec, s);
697
+ return r.type === "string" && !r.enum && !r.const && !r.format;
698
+ };
699
+ const isStringLiteral = (s) => {
700
+ const r = resolveRef(this.#spec, s);
701
+ return Array.isArray(r.enum) && r.enum.every((v) => typeof v === "string") || typeof r.const === "string";
702
+ };
703
+ const hasStringLiteral = schemas.some(isStringLiteral);
704
+ const seen = /* @__PURE__ */ new Set();
705
+ const oneOfTypes = [];
706
+ for (const sub of schemas) {
707
+ const part = hasStringLiteral && isBareString(sub) ? "(string & {})" : this.handle(sub, true);
708
+ if (seen.has(part)) continue;
709
+ seen.add(part);
710
+ oneOfTypes.push(part);
711
+ }
696
712
  return appendOptional2(
697
713
  oneOfTypes.length > 1 ? `${oneOfTypes.join(" | ")}` : oneOfTypes[0],
698
714
  required
@@ -784,7 +800,7 @@ function appendOptional2(type, isRequired) {
784
800
  import { merge, template } from "lodash-es";
785
801
  import { join } from "node:path";
786
802
  import { camelcase as camelcase4, spinalcase as spinalcase2 } from "stringcase";
787
- import { followRef as followRef3, isEmpty as isEmpty2, isRef as isRef3, resolveRef, sortArray } from "@sdk-it/core";
803
+ import { followRef as followRef3, isEmpty as isEmpty2, isRef as isRef3, resolveRef as resolveRef2, sortArray } from "@sdk-it/core";
788
804
  import {
789
805
  forEachOperation as forEachOperation3
790
806
  } from "@sdk-it/spec";
@@ -804,6 +820,69 @@ import {
804
820
  // packages/typescript/src/lib/import-utilities.ts
805
821
  import { removeDuplicates } from "@sdk-it/core";
806
822
 
823
+ // packages/typescript/src/lib/pagination-emit.ts
824
+ function describe(p) {
825
+ switch (p.type) {
826
+ case "offset":
827
+ return {
828
+ className: "OffsetPagination",
829
+ items: p.items,
830
+ hasMore: p.hasMore,
831
+ statusCode: p.statusCode,
832
+ sameInputNames: p.limitParamName === "limit" && p.offsetParamName === "offset",
833
+ initialOverride: `limit: input.${p.limitParamName}, offset: input.${p.offsetParamName}`,
834
+ nextPageMapping: `${p.offsetParamName}: nextPageParams.offset, ${p.limitParamName}: nextPageParams.limit`
835
+ };
836
+ case "cursor":
837
+ return {
838
+ className: "CursorPagination",
839
+ items: p.items,
840
+ hasMore: p.hasMore,
841
+ statusCode: p.statusCode,
842
+ sameInputNames: p.cursorParamName === "cursor",
843
+ initialOverride: `cursor: input.${p.cursorParamName}`,
844
+ nextPageMapping: `${p.cursorParamName}: nextPageParams.cursor`
845
+ };
846
+ case "page":
847
+ return {
848
+ className: "Pagination",
849
+ items: p.items,
850
+ hasMore: p.hasMore,
851
+ statusCode: p.statusCode,
852
+ sameInputNames: p.pageNumberParamName === "page" && p.pageSizeParamName === "pageSize",
853
+ initialOverride: `page: input.${p.pageNumberParamName}, pageSize: input.${p.pageSizeParamName}`,
854
+ nextPageMapping: `${p.pageNumberParamName}: nextPageParams.page, ${p.pageSizeParamName}: nextPageParams.pageSize`
855
+ };
856
+ }
857
+ throw new Error(
858
+ `Unknown pagination type: ${p.type}`
859
+ );
860
+ }
861
+ function paginationOperation(pagination) {
862
+ const shape = describe(pagination);
863
+ const initialParams = shape.sameInputNames ? "input" : `{...input, ${shape.initialOverride}}`;
864
+ const nextPageParams = shape.sameInputNames ? "...nextPageParams" : shape.nextPageMapping;
865
+ return `{
866
+ const pagination = new ${shape.className}(${initialParams}, async (nextPageParams, requestOptions) => {
867
+ const dispatcher = new Dispatcher(options.interceptors, options.fetch);
868
+ const result = await dispatcher.send(
869
+ this.toRequest({...input, ${nextPageParams}}),
870
+ this.output,
871
+ requestOptions?.signal ?? options.signal,
872
+ );
873
+ if (result.status !== ${shape.statusCode}) { throw result; }
874
+ return {
875
+ data: result.data.${shape.items},
876
+ meta: {
877
+ hasMore: Boolean(result.data.${shape.hasMore}),
878
+ },
879
+ };
880
+ }, { signal: options.signal });
881
+ await pagination.getNextPage();
882
+ return pagination
883
+ }}`;
884
+ }
885
+
807
886
  // packages/typescript/src/lib/status-map.ts
808
887
  var status_map_default = {
809
888
  "200": "Ok",
@@ -868,7 +947,7 @@ function toEndpoint(groupName, spec, specOperation, operation) {
868
947
  signal?: AbortSignal;
869
948
  interceptors: Interceptor[];
870
949
  fetch: z.infer<typeof fetchType>;
871
- })${specOperation["x-pagination"] ? paginationOperation(specOperation) : normalOperation()}`
950
+ })${specOperation["x-pagination"] ? paginationOperation(specOperation["x-pagination"]) : normalOperation()}`
872
951
  );
873
952
  }
874
953
  return { schemas };
@@ -880,83 +959,6 @@ function normalOperation() {
880
959
  },
881
960
  }`;
882
961
  }
883
- function paginationOperation(operation) {
884
- const pagination = operation["x-pagination"];
885
- const data = `result.data`;
886
- const returnValue = `pagination`;
887
- if (pagination.type === "offset") {
888
- const sameInputNames = pagination.limitParamName === "limit" && pagination.offsetParamName === "offset";
889
- const initialParams = sameInputNames ? "input" : `{...input, limit: input.${pagination.limitParamName}, offset: input.${pagination.offsetParamName}}`;
890
- const nextPageParams = sameInputNames ? "...nextPageParams" : `${pagination.offsetParamName}: nextPageParams.offset, ${pagination.limitParamName}: nextPageParams.limit`;
891
- const logic = `const pagination = new OffsetPagination(${initialParams}, async (nextPageParams, requestOptions) => {
892
- const dispatcher = new Dispatcher(options.interceptors, options.fetch);
893
- const result = await dispatcher.send(
894
- this.toRequest({...input, ${nextPageParams}}),
895
- this.output,
896
- requestOptions?.signal ?? options.signal,
897
- );
898
- return {
899
- data: ${data}.${pagination.items},
900
- meta: {
901
- hasMore: Boolean(${data}.${pagination.hasMore}),
902
- },
903
- };
904
- }, { signal: options.signal });
905
- await pagination.getNextPage();
906
- return ${returnValue}
907
- `;
908
- return `{${logic}}}`;
909
- }
910
- if (pagination.type === "cursor") {
911
- const sameInputNames = pagination.cursorParamName === "cursor";
912
- const initialParams = sameInputNames ? "input" : `{...input, cursor: input.${pagination.cursorParamName}}`;
913
- const nextPageParams = sameInputNames ? "...nextPageParams" : `${pagination.cursorParamName}: nextPageParams.cursor`;
914
- const logic = `
915
- const pagination = new CursorPagination(${initialParams}, async (nextPageParams, requestOptions) => {
916
- const dispatcher = new Dispatcher(options.interceptors, options.fetch);
917
- const result = await dispatcher.send(
918
- this.toRequest({...input, ${nextPageParams}}),
919
- this.output,
920
- requestOptions?.signal ?? options.signal,
921
- );
922
- return {
923
- data: ${data}.${pagination.items},
924
- meta: {
925
- hasMore: Boolean(${data}.${pagination.hasMore}),
926
- },
927
- };
928
- }, { signal: options.signal });
929
- await pagination.getNextPage();
930
- return ${returnValue}
931
- `;
932
- return `{${logic}}}`;
933
- }
934
- if (pagination.type === "page") {
935
- const sameInputNames = pagination.pageNumberParamName === "page" && pagination.pageSizeParamName === "pageSize";
936
- const initialParams = sameInputNames ? "input" : `{...input, page: input.${pagination.pageNumberParamName}, pageSize: input.${pagination.pageSizeParamName}}`;
937
- const nextPageParams = sameInputNames ? "...nextPageParams" : `${pagination.pageNumberParamName}: nextPageParams.page, ${pagination.pageSizeParamName}: nextPageParams.pageSize`;
938
- const logic = `
939
- const pagination = new Pagination(${initialParams}, async (nextPageParams, requestOptions) => {
940
- const dispatcher = new Dispatcher(options.interceptors, options.fetch);
941
- const result = await dispatcher.send(
942
- this.toRequest({...input, ${nextPageParams}}),
943
- this.output,
944
- requestOptions?.signal ?? options.signal,
945
- );
946
- return {
947
- data: ${data}.${pagination.items},
948
- meta: {
949
- hasMore: Boolean(${data}.${pagination.hasMore}),
950
- },
951
- };
952
- }, { signal: options.signal });
953
- await pagination.getNextPage();
954
- return ${returnValue}
955
- `;
956
- return `{${logic}}}`;
957
- }
958
- return normalOperation();
959
- }
960
962
  function toHttpOutput(spec, operationName, status, response, withGenerics = true) {
961
963
  const typeScriptDeserialzer = new TypeScriptEmitter(spec);
962
964
  const interfaceName = pascalcase3(sanitizeTag3(response["x-response-name"]));
@@ -1077,7 +1079,7 @@ var endpoints_default = "type DispatchReturn<E extends keyof typeof schemas> = A
1077
1079
 
1078
1080
  // packages/typescript/src/lib/generator.ts
1079
1081
  function coearceRequestInput(spec, operation, type) {
1080
- let objectSchema = resolveRef(
1082
+ let objectSchema = resolveRef2(
1081
1083
  spec,
1082
1084
  operation.requestBody.content[type].schema
1083
1085
  );
@@ -1768,7 +1770,7 @@ function expandServerUrls(servers) {
1768
1770
 
1769
1771
  // packages/typescript/src/lib/typescript-snippet.ts
1770
1772
  import { camelcase as camelcase5, spinalcase as spinalcase3 } from "stringcase";
1771
- import { isEmpty as isEmpty4, pascalcase as pascalcase4, resolveRef as resolveRef3 } from "@sdk-it/core";
1773
+ import { isEmpty as isEmpty4, pascalcase as pascalcase4, resolveRef as resolveRef4 } from "@sdk-it/core";
1772
1774
  import "@sdk-it/readme";
1773
1775
  import {
1774
1776
  forEachOperation as forEachOperation5,
@@ -1777,7 +1779,7 @@ import {
1777
1779
  } from "@sdk-it/spec";
1778
1780
 
1779
1781
  // packages/typescript/src/lib/emitters/snippet.ts
1780
- import { followRef as followRef5, isRef as isRef5, resolveRef as resolveRef2 } from "@sdk-it/core";
1782
+ import { followRef as followRef5, isRef as isRef5, resolveRef as resolveRef3 } from "@sdk-it/core";
1781
1783
  var SnippetEmitter = class {
1782
1784
  spec;
1783
1785
  generatedRefs = /* @__PURE__ */ new Set();
@@ -1786,12 +1788,12 @@ var SnippetEmitter = class {
1786
1788
  this.spec = spec;
1787
1789
  }
1788
1790
  object(schema) {
1789
- const schemaObj = resolveRef2(this.spec, schema);
1791
+ const schemaObj = resolveRef3(this.spec, schema);
1790
1792
  const result = {};
1791
1793
  const properties = schemaObj.properties || {};
1792
1794
  for (const [propName, propSchema] of Object.entries(properties)) {
1793
1795
  const isRequired = (schemaObj.required ?? []).includes(propName);
1794
- const resolvedProp = resolveRef2(this.spec, propSchema);
1796
+ const resolvedProp = resolveRef3(this.spec, propSchema);
1795
1797
  if (isRequired || resolvedProp.example !== void 0 || resolvedProp.default !== void 0) {
1796
1798
  result[propName] = this.handle(propSchema);
1797
1799
  }
@@ -1804,7 +1806,7 @@ var SnippetEmitter = class {
1804
1806
  return result;
1805
1807
  }
1806
1808
  array(schema) {
1807
- const schemaObj = resolveRef2(this.spec, schema);
1809
+ const schemaObj = resolveRef3(this.spec, schema);
1808
1810
  const itemsSchema = schemaObj.items;
1809
1811
  if (!itemsSchema) {
1810
1812
  return [];
@@ -1916,7 +1918,7 @@ var SnippetEmitter = class {
1916
1918
  if (isRef5(schemaOrRef)) {
1917
1919
  return this.ref(schemaOrRef.$ref);
1918
1920
  }
1919
- const schema = resolveRef2(this.spec, schemaOrRef);
1921
+ const schema = resolveRef3(this.spec, schemaOrRef);
1920
1922
  if (schema.example !== void 0) {
1921
1923
  return schema.example;
1922
1924
  }
@@ -1981,7 +1983,7 @@ var TypeScriptSnippet = class {
1981
1983
  let payload = "{}";
1982
1984
  if (!isEmpty4(operation.requestBody)) {
1983
1985
  const contentTypes = Object.keys(operation.requestBody.content || {});
1984
- const schema = resolveRef3(
1986
+ const schema = resolveRef4(
1985
1987
  this.#spec,
1986
1988
  operation.requestBody.content[contentTypes[0]].schema
1987
1989
  );