@keq-request/cli 5.0.0-alpha.12 → 5.0.0-alpha.14

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 (33) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cli.cjs +94 -52
  3. package/dist/cli.cjs.map +1 -1
  4. package/dist/cli.js +94 -52
  5. package/dist/cli.js.map +1 -1
  6. package/dist/index.cjs +94 -50
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +93 -50
  11. package/dist/index.js.map +1 -1
  12. package/dist/plugins/body-fallback/index.d.ts.map +1 -1
  13. package/dist/plugins/eslint/index.d.ts.map +1 -1
  14. package/dist/plugins/prettier/index.d.ts.map +1 -1
  15. package/dist/plugins.cjs +13 -21
  16. package/dist/plugins.cjs.map +1 -1
  17. package/dist/plugins.js +13 -21
  18. package/dist/plugins.js.map +1 -1
  19. package/dist/renderer/operation-request/error-to-comment.d.ts +2 -0
  20. package/dist/renderer/operation-request/error-to-comment.d.ts.map +1 -0
  21. package/dist/renderer/operation-request/index.d.ts.map +1 -1
  22. package/dist/renderer/operation-request/request-body.d.ts +4 -0
  23. package/dist/renderer/operation-request/request-body.d.ts.map +1 -0
  24. package/dist/renderer/request/index.d.ts.map +1 -1
  25. package/dist/renderer/utils/generate-schema.d.ts.map +1 -1
  26. package/dist/tasks/compile/index.d.ts.map +1 -1
  27. package/dist/tasks/compile/utils/compile-operation-definition.d.ts.map +1 -1
  28. package/dist/tasks/compile/utils/compile-schema-definition.d.ts.map +1 -1
  29. package/dist/tasks/persist/index.d.ts.map +1 -1
  30. package/dist/tasks/utils/dependency.d.ts +3 -1
  31. package/dist/tasks/utils/dependency.d.ts.map +1 -1
  32. package/dist/types/runtime-config.d.ts +2 -2
  33. package/package.json +3 -3
package/dist/index.cjs CHANGED
@@ -37,6 +37,7 @@ __export(src_exports, {
37
37
  FileNamingStyle: () => FileNamingStyle,
38
38
  ModuleDefinition: () => ModuleDefinition,
39
39
  OperationDefinition: () => OperationDefinition,
40
+ QsArrayFormat: () => QsArrayFormat,
40
41
  RuntimeConfig: () => RuntimeConfig,
41
42
  SchemaDefinition: () => SchemaDefinition,
42
43
  defineKeqConfig: () => defineKeqConfig
@@ -1121,7 +1122,10 @@ function createPersistArtifactTask() {
1121
1122
  title: "Write files",
1122
1123
  task: async (context, task) => {
1123
1124
  if (!context.setup) throw new Error("Please run setup task first.");
1124
- if (!context.compiled) throw new Error("Please run compile task first.");
1125
+ if (!context.compiled) {
1126
+ task.skip("No compiled artifacts to persist.");
1127
+ return;
1128
+ }
1125
1129
  const rc = context.setup.rc;
1126
1130
  const artifacts = context.compiled.artifacts;
1127
1131
  for (const artifact of artifacts) {
@@ -1252,11 +1256,12 @@ function generateArray(schema, alias) {
1252
1256
  return "any[]";
1253
1257
  }
1254
1258
  function indent(space, text) {
1259
+ if (text === "") return "";
1255
1260
  const indentation = " ".repeat(space);
1256
1261
  return text.split("\n").map((line) => `${indentation}${line}`).join("\n");
1257
1262
  }
1258
1263
  function generateObject(schema, alias) {
1259
- if (!schema.properties || !Object.keys(schema.properties).length) {
1264
+ if ((!schema.properties || R11.isEmpty(schema.properties)) && (!schema.additionalProperties || R11.isEmpty(schema.additionalProperties))) {
1260
1265
  return "object";
1261
1266
  }
1262
1267
  const $properties = Object.entries(schema.properties || {}).map(([propertyName, propertySchema]) => {
@@ -1426,15 +1431,17 @@ function toComment(msg) {
1426
1431
 
1427
1432
  // src/tasks/utils/dependency.ts
1428
1433
  var DependencyIdentifier = class {
1429
- constructor(name, alias) {
1434
+ constructor(name, alias, type = false) {
1430
1435
  this.name = name;
1431
1436
  this.alias = alias;
1437
+ this.type = type;
1432
1438
  }
1433
1439
  toCode() {
1440
+ const $type = this.type ? "type " : "";
1434
1441
  if (this.alias) {
1435
- return `${this.name} as ${this.alias}`;
1442
+ return `${$type}${this.name} as ${this.alias}`;
1436
1443
  }
1437
- return this.name;
1444
+ return `${$type}${this.name}`;
1438
1445
  }
1439
1446
  };
1440
1447
  var Dependency = class {
@@ -1445,6 +1452,11 @@ var Dependency = class {
1445
1452
  constructor(source, identifiers, belongTo, options) {
1446
1453
  this.source = source;
1447
1454
  this.identifiers = identifiers.map((i) => typeof i === "string" ? new DependencyIdentifier(i) : i);
1455
+ if (options?.type) {
1456
+ for (const identifier of this.identifiers) {
1457
+ identifier.type = true;
1458
+ }
1459
+ }
1448
1460
  this.export = !!options?.export;
1449
1461
  this.belongTo = belongTo;
1450
1462
  }
@@ -1616,7 +1628,10 @@ async function compileSchemaDefinition(options) {
1616
1628
  const artifact = new Artifact({
1617
1629
  id: filepath,
1618
1630
  filepath,
1619
- content: ""
1631
+ content: [
1632
+ "/* @anchor:file:start */",
1633
+ "/* @anchor:file:end */"
1634
+ ].join("\n")
1620
1635
  });
1621
1636
  for (const schemaDefinition of schemaDefinitions2 || []) {
1622
1637
  const dependentArtifact = artifacts.find(isArtifactCompiledBy(schemaDefinition));
@@ -1632,7 +1647,7 @@ async function compileSchemaDefinition(options) {
1632
1647
  }
1633
1648
 
1634
1649
  // src/tasks/compile/utils/compile-operation-definition.ts
1635
- var R17 = __toESM(require("ramda"), 1);
1650
+ var R18 = __toESM(require("ramda"), 1);
1636
1651
 
1637
1652
  // src/renderer/operation-type/index.ts
1638
1653
  var R15 = __toESM(require("ramda"), 1);
@@ -1729,7 +1744,7 @@ async function operationTypeRenderer(operationDefinition, alias = R15.identity)
1729
1744
  $parameterBodies || void 0,
1730
1745
  $requestParameters,
1731
1746
  "",
1732
- `export interface Operation<STATUS extends keyof ${typeName("ResponseBodies")}, CONTENT_TYPE extends keyof ${typeName("ParameterBodies")}> extends KeqOperation {`,
1747
+ `export interface Operation<STATUS extends keyof ${typeName("ResponseBodies")}, CONTENT_TYPE extends ${$parameterBodies ? `keyof ${typeName("ParameterBodies")}` : "string"} > extends KeqOperation {`,
1733
1748
  ` requestParams: ${typeName("RouteParameters")} & { [key: string]: KeqPathParameterInit }`,
1734
1749
  ` requestQuery: ${typeName("RequestQuery")} & { [key: string]: KeqQueryInit }`,
1735
1750
  ` requestHeaders: ${typeName("RequestHeaders")} & { [key: string]: string | number }`,
@@ -1758,7 +1773,12 @@ function generateParameters(name, parameters, alias) {
1758
1773
  }
1759
1774
 
1760
1775
  // src/renderer/operation-request/index.ts
1776
+ var R17 = __toESM(require("ramda"), 1);
1777
+
1778
+ // src/renderer/operation-request/request-body.ts
1761
1779
  var R16 = __toESM(require("ramda"), 1);
1780
+
1781
+ // src/renderer/operation-request/error-to-comment.ts
1762
1782
  function errorToComment(err, mediaType) {
1763
1783
  const $err = String(err).split("\n").map(((line) => ` * ${line}`)).join("\n");
1764
1784
  return [
@@ -1768,6 +1788,34 @@ function errorToComment(err, mediaType) {
1768
1788
  " */"
1769
1789
  ].join("\n");
1770
1790
  }
1791
+
1792
+ // src/renderer/operation-request/request-body.ts
1793
+ function requestBodyFormDataPropertyRenderer(propertyName, propertySchema, mediaType, operationDefinition) {
1794
+ try {
1795
+ const $propertyName = JSON.stringify(propertyName);
1796
+ const schema = JsonSchemaUtils.isRef(propertySchema) ? SwaggerUtils.dereferenceDeep(propertySchema.$ref, operationDefinition.document.swagger) : propertySchema;
1797
+ if (schema.type === "string" && schema.format === "binary" || schema.contentMediaType === "application/octet-stream") {
1798
+ return `if (args && ${$propertyName} in args && args[${$propertyName}]) req.attach(${$propertyName}, args[${$propertyName}])`;
1799
+ } else if (schema.type === "string" || schema.type === "array" && schema.items && schema.items.type === "string") {
1800
+ return `if (args && ${$propertyName} in args && args[${$propertyName}] !== undefined) req.field(${$propertyName}, args[${$propertyName}])`;
1801
+ } else if (schema.type === "number" || schema.type === "integer") {
1802
+ return `if (args && ${$propertyName} in args && args[${$propertyName}] !== undefined) req.field(${$propertyName}, String(args[${$propertyName}]))`;
1803
+ }
1804
+ return `if (args && ${$propertyName} in args && args[${$propertyName}] !== undefined) req.field(${$propertyName}, String(args[${$propertyName}]) /* type is non-string in schema; triggers type coercion here */)`;
1805
+ } catch (err) {
1806
+ return errorToComment(err, mediaType);
1807
+ }
1808
+ }
1809
+ function requestBodyPropertyRenderer(propertyName, propertySchema, mediaType, operationDefinition) {
1810
+ if (mediaType === "application/json") {
1811
+ const $propertyName = JSON.stringify(propertyName);
1812
+ return `if (args && ${$propertyName} in args) req.send({ ${$propertyName}: args[${$propertyName}] })`;
1813
+ } else if (mediaType === "multipart/form-data") {
1814
+ return requestBodyFormDataPropertyRenderer(propertyName, propertySchema, mediaType, operationDefinition);
1815
+ } else {
1816
+ throw new Error(`Unsupported media type: ${mediaType}`);
1817
+ }
1818
+ }
1771
1819
  function requestBodyRenderer(operationDefinition, typeName) {
1772
1820
  const { operation } = operationDefinition;
1773
1821
  const requestBodyContent = operation.requestBody?.content || {};
@@ -1778,22 +1826,10 @@ function requestBodyRenderer(operationDefinition, typeName) {
1778
1826
  if (schema.type !== "object") return;
1779
1827
  const properties = schema.properties || {};
1780
1828
  return Object.entries(properties).map(([propertyName, propertySchema]) => {
1781
- const $propertyName = JSON.stringify(propertyName);
1782
- if (mediaType === "application/json") {
1783
- return ` if (args && ${$propertyName} in args) req.send({ ${$propertyName}: args[${$propertyName}] })`;
1784
- } else if (mediaType === "multipart/form-data") {
1785
- try {
1786
- const schema2 = JsonSchemaUtils.isRef(propertySchema) ? SwaggerUtils.dereferenceDeep(propertySchema.$ref, operationDefinition.document.swagger) : propertySchema;
1787
- if (schema2.type === "string" && schema2.format === "binary" || schema2.contentMediaType === "application/octet-stream") {
1788
- return ` if (args && ${$propertyName} in args && args[${$propertyName}]) req.attach(${$propertyName}, args[${$propertyName}])`;
1789
- }
1790
- return ` if (args && ${$propertyName} in args && args[${$propertyName}] !== undefined) req.field(${$propertyName}, args[${$propertyName}])`;
1791
- } catch (err) {
1792
- return indent(2, errorToComment(err, mediaType));
1793
- }
1794
- } else {
1795
- throw new Error(`Unsupported media type: ${mediaType}`);
1796
- }
1829
+ return indent(
1830
+ 2,
1831
+ requestBodyPropertyRenderer(propertyName, propertySchema, mediaType, operationDefinition)
1832
+ );
1797
1833
  }).join("\n");
1798
1834
  } catch (err) {
1799
1835
  return indent(2, errorToComment(err, mediaType));
@@ -1801,6 +1837,8 @@ function requestBodyRenderer(operationDefinition, typeName) {
1801
1837
  }).filter(R16.isNotNil).join("\n");
1802
1838
  return $requestBody;
1803
1839
  }
1840
+
1841
+ // src/renderer/operation-request/index.ts
1804
1842
  function requestHeadersRenderer(operationDefinition, typeName) {
1805
1843
  const { operation } = operationDefinition;
1806
1844
  const $headers = (operation.parameters || []).filter((p) => !JsonSchemaUtils.isRef(p)).filter((p) => p.in === "header").map((p) => ` if (args && ${JSON.stringify(p.name)} in args) req.header(${JSON.stringify(p.name)}, args[${JSON.stringify(p.name)}])`).concat("").join("\n");
@@ -1810,7 +1848,7 @@ function requestQueryRenderer(operationDefinition, qs, typeName) {
1810
1848
  const { operation } = operationDefinition;
1811
1849
  const $query = (operation.parameters || []).filter((p) => !JsonSchemaUtils.isRef(p)).filter((p) => p.in === "query").map((p) => {
1812
1850
  const option = qs(p);
1813
- const $option = !option || R16.isEmpty(option) ? "" : `, ${JSON.stringify(option)}`;
1851
+ const $option = !option || R17.isEmpty(option) ? "" : `, ${JSON.stringify(option)}`;
1814
1852
  return ` if (args && ${JSON.stringify(p.name)} in args) req.query(${JSON.stringify(p.name)}, args[${JSON.stringify(p.name)}]${$option})`;
1815
1853
  }).concat("").join("\n");
1816
1854
  return $query;
@@ -1842,9 +1880,9 @@ function operationDeclarationRenderer(operationDefinition, typeName) {
1842
1880
  const { operationId } = operationDefinition;
1843
1881
  const mediaTypes = getRequestMediaTypes(operationDefinition);
1844
1882
  if (mediaTypes.length === 0) {
1845
- return `function ${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}>(args?: ${typeName("RequestParameters")}): Keq<Operation<STATUS, never>>`;
1883
+ return `function ${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}, CONTENT_TYPE extends never = never>(args?: ${typeName("RequestParameters")}): Keq<Operation<STATUS, CONTENT_TYPE>>`;
1846
1884
  } else if (mediaTypes.length === 1) {
1847
- return `function ${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}>(args?: ${typeName("RequestParameters")}): Keq<Operation<STATUS, ${JSON.stringify(mediaTypes[0])}>>`;
1885
+ return `function ${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}, CONTENT_TYPE extends ${JSON.stringify(mediaTypes[0])} = ${JSON.stringify(mediaTypes[0])}>(args?: ${typeName("RequestParameters")}): Keq<Operation<STATUS, CONTENT_TYPE>>`;
1848
1886
  } else if (mediaTypes.length > 1) {
1849
1887
  return `function ${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}, CONTENT_TYPE extends ${typeName("RequestParameters")}["content-type"]>(args?: Extract<${typeName("RequestParameters")}, { "content-type": CONTENT_TYPE }>): Keq<Operation<STATUS, CONTENT_TYPE>>`;
1850
1888
  }
@@ -1856,6 +1894,7 @@ async function operationRequestRenderer(operationDefinition, options) {
1856
1894
  if (!operation.responses) return "";
1857
1895
  const typeName = typeNameFactory(operationDefinition);
1858
1896
  const moduleName = operationDefinition.module.name;
1897
+ const $method = method.toLowerCase();
1859
1898
  const $queryParameters = requestQueryRenderer(operationDefinition, qs, typeName);
1860
1899
  const $headerParameters = requestHeadersRenderer(operationDefinition, typeName);
1861
1900
  const $pathParameters = requestPathParametersRenderer(operationDefinition, typeName);
@@ -1871,7 +1910,7 @@ async function operationRequestRenderer(operationDefinition, options) {
1871
1910
  "",
1872
1911
  "/* @anchor:operation-declaration */",
1873
1912
  `export ${$operationDeclaration} {`,
1874
- ` const req = request.post<${typeName("ResponseBodies")}[STATUS]>("${pathname}")`,
1913
+ ` const req = request.${$method}<${typeName("ResponseBodies")}[STATUS]>("${pathname}")`,
1875
1914
  " .option('module', { name: moduleName, pathname, method })",
1876
1915
  "",
1877
1916
  $mediaType || void 0,
@@ -1892,13 +1931,13 @@ async function operationRequestRenderer(operationDefinition, options) {
1892
1931
  " /* @anchor:body:end */",
1893
1932
  "",
1894
1933
  " /* @anchor:operation-return */",
1895
- ` return req as ReturnType<typeof ${operationId}>`,
1934
+ ` return req as ReturnType<typeof ${operationId}<STATUS${$operationDeclaration.includes("CONTENT_TYPE") ? ", CONTENT_TYPE" : ""}>>`,
1896
1935
  "}",
1897
1936
  "",
1898
1937
  `${operationId}.pathname = pathname`,
1899
1938
  `${operationId}.method = method`,
1900
1939
  "/* @anchor:file:end */"
1901
- ].filter(R16.isNotNil).join("\n");
1940
+ ].filter(R17.isNotNil).join("\n");
1902
1941
  }
1903
1942
 
1904
1943
  // src/tasks/compile/utils/compile-operation-definition.ts
@@ -1995,7 +2034,8 @@ async function compileOperationDefinition(options) {
1995
2034
  "Operation",
1996
2035
  typeName("ResponseBodies"),
1997
2036
  typeName("RequestParameters")
1998
- ]
2037
+ ],
2038
+ { type: true }
1999
2039
  );
2000
2040
  artifact.addDependence(
2001
2041
  typeArtifact,
@@ -2004,11 +2044,11 @@ async function compileOperationDefinition(options) {
2004
2044
  `${typeName("RequestHeaders")}`,
2005
2045
  `${typeName("RequestBodies")}`
2006
2046
  ],
2007
- { export: true }
2047
+ { export: true, type: true }
2008
2048
  );
2009
2049
  return await compiler.hooks.afterCompileOperationRequest.promise(artifact, operationDefinition, task);
2010
2050
  }
2011
- const artifacts = R17.unnest(
2051
+ const artifacts = R18.unnest(
2012
2052
  await Promise.all(
2013
2053
  operationDefinitions.map(async (operationDefinition) => {
2014
2054
  const typeArtifact = await createTypeArtifact(operationDefinition);
@@ -2017,7 +2057,7 @@ async function compileOperationDefinition(options) {
2017
2057
  })
2018
2058
  )
2019
2059
  );
2020
- const operationDefinitionsGroupByModuleName = R17.groupBy(
2060
+ const operationDefinitionsGroupByModuleName = R18.groupBy(
2021
2061
  (operationDefinition) => operationDefinition.module.name,
2022
2062
  operationDefinitions
2023
2063
  );
@@ -2026,7 +2066,10 @@ async function compileOperationDefinition(options) {
2026
2066
  const artifact = new Artifact({
2027
2067
  id: filepath,
2028
2068
  filepath,
2029
- content: ""
2069
+ content: [
2070
+ "/* @anchor:file:start */",
2071
+ "/* @anchor:file:end */"
2072
+ ].join("\n")
2030
2073
  });
2031
2074
  for (const operationDefinition of operationDefinitions2 || []) {
2032
2075
  const dependentArtifact = artifacts.find((artifact2) => artifact2.filepath === genOperationRequestFilepath(operationDefinition));
@@ -2044,14 +2087,12 @@ async function compileOperationDefinition(options) {
2044
2087
  // src/renderer/request/index.ts
2045
2088
  async function requestRenderer() {
2046
2089
  return [
2047
- "import { KeqRequest } from 'keq'",
2048
- "",
2049
2090
  "/* @anchor:file:start */",
2050
2091
  "",
2051
2092
  "/* @anchor:request-declaration */",
2052
2093
  "export const request = new KeqRequest()",
2053
2094
  "",
2054
- "/* @anchor:file:end"
2095
+ "/* @anchor:file:end */"
2055
2096
  ].join("\n");
2056
2097
  }
2057
2098
 
@@ -2064,13 +2105,15 @@ function main6(compiler) {
2064
2105
  const rc = context.setup.rc;
2065
2106
  const matcher = context.setup.matcher;
2066
2107
  const documents = context.shaken.documents.filter((document) => !matcher.isModuleIgnored(document.module));
2067
- const requestArtifact = await compiler.hooks.afterCompileKeqRequest.promise(
2068
- new Artifact({
2069
- id: "request",
2070
- filepath: "request",
2071
- content: await requestRenderer(),
2072
- extensionName: ".ts"
2073
- }),
2108
+ let requestArtifact = new Artifact({
2109
+ id: "request",
2110
+ filepath: "request",
2111
+ content: await requestRenderer(),
2112
+ extensionName: ".ts"
2113
+ });
2114
+ requestArtifact.addDependence("keq", ["KeqRequest"]);
2115
+ requestArtifact = await compiler.hooks.afterCompileKeqRequest.promise(
2116
+ requestArtifact,
2074
2117
  task
2075
2118
  );
2076
2119
  const schemaDefinitions = documents.flatMap((document) => document.schemas);
@@ -2161,7 +2204,7 @@ function createInteractiveTask(options) {
2161
2204
  }
2162
2205
 
2163
2206
  // src/compiler/intercepter/perfect-error-message.ts
2164
- var R18 = __toESM(require("ramda"), 1);
2207
+ var R19 = __toESM(require("ramda"), 1);
2165
2208
  function perfectErrorMessage() {
2166
2209
  return {
2167
2210
  register: (tap) => {
@@ -2193,8 +2236,8 @@ function perfectErrorMessage() {
2193
2236
  }
2194
2237
  if (tap.type === "async") {
2195
2238
  tap.fn = (...args) => {
2196
- const callback = R18.last(args);
2197
- return fn(...R18.init(args), (err, result) => {
2239
+ const callback = R19.last(args);
2240
+ return fn(...R19.init(args), (err, result) => {
2198
2241
  prefix(err);
2199
2242
  return callback(err, result);
2200
2243
  });
@@ -2285,11 +2328,11 @@ var Compiler = class {
2285
2328
  [
2286
2329
  createSetupTask(this, options),
2287
2330
  createDownloadTask(this, { skipIgnoredModules: !options.interactive }),
2288
- createValidateTask(this, { enabled: !!options.build }),
2331
+ createValidateTask(this),
2289
2332
  createInteractiveTask({ enabled: !!options.interactive, ...typeof options.interactive === "object" ? options.interactive : { mode: "except" } }),
2290
2333
  createShakingTask(this, { enabled: !!options.build, ...typeof options.build === "object" ? options.build.shaking : void 0 }),
2291
2334
  createCompileTask(this, { enabled: !!options.build }),
2292
- createPersistTask(this, { enabled: !!options.build })
2335
+ createPersistTask(this)
2293
2336
  ],
2294
2337
  {
2295
2338
  concurrent: false,
@@ -2314,6 +2357,7 @@ var Compiler = class {
2314
2357
  FileNamingStyle,
2315
2358
  ModuleDefinition,
2316
2359
  OperationDefinition,
2360
+ QsArrayFormat,
2317
2361
  RuntimeConfig,
2318
2362
  SchemaDefinition,
2319
2363
  defineKeqConfig