@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/cli.js CHANGED
@@ -1077,7 +1077,10 @@ function createPersistArtifactTask() {
1077
1077
  title: "Write files",
1078
1078
  task: async (context, task) => {
1079
1079
  if (!context.setup) throw new Error("Please run setup task first.");
1080
- if (!context.compiled) throw new Error("Please run compile task first.");
1080
+ if (!context.compiled) {
1081
+ task.skip("No compiled artifacts to persist.");
1082
+ return;
1083
+ }
1081
1084
  const rc = context.setup.rc;
1082
1085
  const artifacts = context.compiled.artifacts;
1083
1086
  for (const artifact of artifacts) {
@@ -1208,11 +1211,12 @@ function generateArray(schema, alias) {
1208
1211
  return "any[]";
1209
1212
  }
1210
1213
  function indent(space, text) {
1214
+ if (text === "") return "";
1211
1215
  const indentation = " ".repeat(space);
1212
1216
  return text.split("\n").map((line) => `${indentation}${line}`).join("\n");
1213
1217
  }
1214
1218
  function generateObject(schema, alias) {
1215
- if (!schema.properties || !Object.keys(schema.properties).length) {
1219
+ if ((!schema.properties || R11.isEmpty(schema.properties)) && (!schema.additionalProperties || R11.isEmpty(schema.additionalProperties))) {
1216
1220
  return "object";
1217
1221
  }
1218
1222
  const $properties = Object.entries(schema.properties || {}).map(([propertyName, propertySchema]) => {
@@ -1382,15 +1386,17 @@ function toComment(msg) {
1382
1386
 
1383
1387
  // src/tasks/utils/dependency.ts
1384
1388
  var DependencyIdentifier = class {
1385
- constructor(name, alias) {
1389
+ constructor(name, alias, type = false) {
1386
1390
  this.name = name;
1387
1391
  this.alias = alias;
1392
+ this.type = type;
1388
1393
  }
1389
1394
  toCode() {
1395
+ const $type = this.type ? "type " : "";
1390
1396
  if (this.alias) {
1391
- return `${this.name} as ${this.alias}`;
1397
+ return `${$type}${this.name} as ${this.alias}`;
1392
1398
  }
1393
- return this.name;
1399
+ return `${$type}${this.name}`;
1394
1400
  }
1395
1401
  };
1396
1402
  var Dependency = class {
@@ -1401,6 +1407,11 @@ var Dependency = class {
1401
1407
  constructor(source, identifiers, belongTo, options) {
1402
1408
  this.source = source;
1403
1409
  this.identifiers = identifiers.map((i) => typeof i === "string" ? new DependencyIdentifier(i) : i);
1410
+ if (options?.type) {
1411
+ for (const identifier of this.identifiers) {
1412
+ identifier.type = true;
1413
+ }
1414
+ }
1404
1415
  this.export = !!options?.export;
1405
1416
  this.belongTo = belongTo;
1406
1417
  }
@@ -1572,7 +1583,10 @@ async function compileSchemaDefinition(options) {
1572
1583
  const artifact = new Artifact({
1573
1584
  id: filepath,
1574
1585
  filepath,
1575
- content: ""
1586
+ content: [
1587
+ "/* @anchor:file:start */",
1588
+ "/* @anchor:file:end */"
1589
+ ].join("\n")
1576
1590
  });
1577
1591
  for (const schemaDefinition of schemaDefinitions2 || []) {
1578
1592
  const dependentArtifact = artifacts.find(isArtifactCompiledBy(schemaDefinition));
@@ -1588,7 +1602,7 @@ async function compileSchemaDefinition(options) {
1588
1602
  }
1589
1603
 
1590
1604
  // src/tasks/compile/utils/compile-operation-definition.ts
1591
- import * as R17 from "ramda";
1605
+ import * as R18 from "ramda";
1592
1606
 
1593
1607
  // src/renderer/operation-type/index.ts
1594
1608
  import * as R15 from "ramda";
@@ -1685,7 +1699,7 @@ async function operationTypeRenderer(operationDefinition, alias = R15.identity)
1685
1699
  $parameterBodies || void 0,
1686
1700
  $requestParameters,
1687
1701
  "",
1688
- `export interface Operation<STATUS extends keyof ${typeName("ResponseBodies")}, CONTENT_TYPE extends keyof ${typeName("ParameterBodies")}> extends KeqOperation {`,
1702
+ `export interface Operation<STATUS extends keyof ${typeName("ResponseBodies")}, CONTENT_TYPE extends ${$parameterBodies ? `keyof ${typeName("ParameterBodies")}` : "string"} > extends KeqOperation {`,
1689
1703
  ` requestParams: ${typeName("RouteParameters")} & { [key: string]: KeqPathParameterInit }`,
1690
1704
  ` requestQuery: ${typeName("RequestQuery")} & { [key: string]: KeqQueryInit }`,
1691
1705
  ` requestHeaders: ${typeName("RequestHeaders")} & { [key: string]: string | number }`,
@@ -1714,7 +1728,12 @@ function generateParameters(name, parameters, alias) {
1714
1728
  }
1715
1729
 
1716
1730
  // src/renderer/operation-request/index.ts
1731
+ import * as R17 from "ramda";
1732
+
1733
+ // src/renderer/operation-request/request-body.ts
1717
1734
  import * as R16 from "ramda";
1735
+
1736
+ // src/renderer/operation-request/error-to-comment.ts
1718
1737
  function errorToComment(err, mediaType) {
1719
1738
  const $err = String(err).split("\n").map(((line) => ` * ${line}`)).join("\n");
1720
1739
  return [
@@ -1724,6 +1743,34 @@ function errorToComment(err, mediaType) {
1724
1743
  " */"
1725
1744
  ].join("\n");
1726
1745
  }
1746
+
1747
+ // src/renderer/operation-request/request-body.ts
1748
+ function requestBodyFormDataPropertyRenderer(propertyName, propertySchema, mediaType, operationDefinition) {
1749
+ try {
1750
+ const $propertyName = JSON.stringify(propertyName);
1751
+ const schema = JsonSchemaUtils.isRef(propertySchema) ? SwaggerUtils.dereferenceDeep(propertySchema.$ref, operationDefinition.document.swagger) : propertySchema;
1752
+ if (schema.type === "string" && schema.format === "binary" || schema.contentMediaType === "application/octet-stream") {
1753
+ return `if (args && ${$propertyName} in args && args[${$propertyName}]) req.attach(${$propertyName}, args[${$propertyName}])`;
1754
+ } else if (schema.type === "string" || schema.type === "array" && schema.items && schema.items.type === "string") {
1755
+ return `if (args && ${$propertyName} in args && args[${$propertyName}] !== undefined) req.field(${$propertyName}, args[${$propertyName}])`;
1756
+ } else if (schema.type === "number" || schema.type === "integer") {
1757
+ return `if (args && ${$propertyName} in args && args[${$propertyName}] !== undefined) req.field(${$propertyName}, String(args[${$propertyName}]))`;
1758
+ }
1759
+ 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 */)`;
1760
+ } catch (err) {
1761
+ return errorToComment(err, mediaType);
1762
+ }
1763
+ }
1764
+ function requestBodyPropertyRenderer(propertyName, propertySchema, mediaType, operationDefinition) {
1765
+ if (mediaType === "application/json") {
1766
+ const $propertyName = JSON.stringify(propertyName);
1767
+ return `if (args && ${$propertyName} in args) req.send({ ${$propertyName}: args[${$propertyName}] })`;
1768
+ } else if (mediaType === "multipart/form-data") {
1769
+ return requestBodyFormDataPropertyRenderer(propertyName, propertySchema, mediaType, operationDefinition);
1770
+ } else {
1771
+ throw new Error(`Unsupported media type: ${mediaType}`);
1772
+ }
1773
+ }
1727
1774
  function requestBodyRenderer(operationDefinition, typeName) {
1728
1775
  const { operation } = operationDefinition;
1729
1776
  const requestBodyContent = operation.requestBody?.content || {};
@@ -1734,22 +1781,10 @@ function requestBodyRenderer(operationDefinition, typeName) {
1734
1781
  if (schema.type !== "object") return;
1735
1782
  const properties = schema.properties || {};
1736
1783
  return Object.entries(properties).map(([propertyName, propertySchema]) => {
1737
- const $propertyName = JSON.stringify(propertyName);
1738
- if (mediaType === "application/json") {
1739
- return ` if (args && ${$propertyName} in args) req.send({ ${$propertyName}: args[${$propertyName}] })`;
1740
- } else if (mediaType === "multipart/form-data") {
1741
- try {
1742
- const schema2 = JsonSchemaUtils.isRef(propertySchema) ? SwaggerUtils.dereferenceDeep(propertySchema.$ref, operationDefinition.document.swagger) : propertySchema;
1743
- if (schema2.type === "string" && schema2.format === "binary" || schema2.contentMediaType === "application/octet-stream") {
1744
- return ` if (args && ${$propertyName} in args && args[${$propertyName}]) req.attach(${$propertyName}, args[${$propertyName}])`;
1745
- }
1746
- return ` if (args && ${$propertyName} in args && args[${$propertyName}] !== undefined) req.field(${$propertyName}, args[${$propertyName}])`;
1747
- } catch (err) {
1748
- return indent(2, errorToComment(err, mediaType));
1749
- }
1750
- } else {
1751
- throw new Error(`Unsupported media type: ${mediaType}`);
1752
- }
1784
+ return indent(
1785
+ 2,
1786
+ requestBodyPropertyRenderer(propertyName, propertySchema, mediaType, operationDefinition)
1787
+ );
1753
1788
  }).join("\n");
1754
1789
  } catch (err) {
1755
1790
  return indent(2, errorToComment(err, mediaType));
@@ -1757,6 +1792,8 @@ function requestBodyRenderer(operationDefinition, typeName) {
1757
1792
  }).filter(R16.isNotNil).join("\n");
1758
1793
  return $requestBody;
1759
1794
  }
1795
+
1796
+ // src/renderer/operation-request/index.ts
1760
1797
  function requestHeadersRenderer(operationDefinition, typeName) {
1761
1798
  const { operation } = operationDefinition;
1762
1799
  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");
@@ -1766,7 +1803,7 @@ function requestQueryRenderer(operationDefinition, qs, typeName) {
1766
1803
  const { operation } = operationDefinition;
1767
1804
  const $query = (operation.parameters || []).filter((p) => !JsonSchemaUtils.isRef(p)).filter((p) => p.in === "query").map((p) => {
1768
1805
  const option = qs(p);
1769
- const $option = !option || R16.isEmpty(option) ? "" : `, ${JSON.stringify(option)}`;
1806
+ const $option = !option || R17.isEmpty(option) ? "" : `, ${JSON.stringify(option)}`;
1770
1807
  return ` if (args && ${JSON.stringify(p.name)} in args) req.query(${JSON.stringify(p.name)}, args[${JSON.stringify(p.name)}]${$option})`;
1771
1808
  }).concat("").join("\n");
1772
1809
  return $query;
@@ -1798,9 +1835,9 @@ function operationDeclarationRenderer(operationDefinition, typeName) {
1798
1835
  const { operationId } = operationDefinition;
1799
1836
  const mediaTypes = getRequestMediaTypes(operationDefinition);
1800
1837
  if (mediaTypes.length === 0) {
1801
- return `function ${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}>(args?: ${typeName("RequestParameters")}): Keq<Operation<STATUS, never>>`;
1838
+ return `function ${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}, CONTENT_TYPE extends never = never>(args?: ${typeName("RequestParameters")}): Keq<Operation<STATUS, CONTENT_TYPE>>`;
1802
1839
  } else if (mediaTypes.length === 1) {
1803
- return `function ${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}>(args?: ${typeName("RequestParameters")}): Keq<Operation<STATUS, ${JSON.stringify(mediaTypes[0])}>>`;
1840
+ 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>>`;
1804
1841
  } else if (mediaTypes.length > 1) {
1805
1842
  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>>`;
1806
1843
  }
@@ -1812,6 +1849,7 @@ async function operationRequestRenderer(operationDefinition, options) {
1812
1849
  if (!operation.responses) return "";
1813
1850
  const typeName = typeNameFactory(operationDefinition);
1814
1851
  const moduleName = operationDefinition.module.name;
1852
+ const $method = method.toLowerCase();
1815
1853
  const $queryParameters = requestQueryRenderer(operationDefinition, qs, typeName);
1816
1854
  const $headerParameters = requestHeadersRenderer(operationDefinition, typeName);
1817
1855
  const $pathParameters = requestPathParametersRenderer(operationDefinition, typeName);
@@ -1827,7 +1865,7 @@ async function operationRequestRenderer(operationDefinition, options) {
1827
1865
  "",
1828
1866
  "/* @anchor:operation-declaration */",
1829
1867
  `export ${$operationDeclaration} {`,
1830
- ` const req = request.post<${typeName("ResponseBodies")}[STATUS]>("${pathname}")`,
1868
+ ` const req = request.${$method}<${typeName("ResponseBodies")}[STATUS]>("${pathname}")`,
1831
1869
  " .option('module', { name: moduleName, pathname, method })",
1832
1870
  "",
1833
1871
  $mediaType || void 0,
@@ -1848,13 +1886,13 @@ async function operationRequestRenderer(operationDefinition, options) {
1848
1886
  " /* @anchor:body:end */",
1849
1887
  "",
1850
1888
  " /* @anchor:operation-return */",
1851
- ` return req as ReturnType<typeof ${operationId}>`,
1889
+ ` return req as ReturnType<typeof ${operationId}<STATUS${$operationDeclaration.includes("CONTENT_TYPE") ? ", CONTENT_TYPE" : ""}>>`,
1852
1890
  "}",
1853
1891
  "",
1854
1892
  `${operationId}.pathname = pathname`,
1855
1893
  `${operationId}.method = method`,
1856
1894
  "/* @anchor:file:end */"
1857
- ].filter(R16.isNotNil).join("\n");
1895
+ ].filter(R17.isNotNil).join("\n");
1858
1896
  }
1859
1897
 
1860
1898
  // src/tasks/compile/utils/compile-operation-definition.ts
@@ -1951,7 +1989,8 @@ async function compileOperationDefinition(options) {
1951
1989
  "Operation",
1952
1990
  typeName("ResponseBodies"),
1953
1991
  typeName("RequestParameters")
1954
- ]
1992
+ ],
1993
+ { type: true }
1955
1994
  );
1956
1995
  artifact.addDependence(
1957
1996
  typeArtifact,
@@ -1960,11 +1999,11 @@ async function compileOperationDefinition(options) {
1960
1999
  `${typeName("RequestHeaders")}`,
1961
2000
  `${typeName("RequestBodies")}`
1962
2001
  ],
1963
- { export: true }
2002
+ { export: true, type: true }
1964
2003
  );
1965
2004
  return await compiler.hooks.afterCompileOperationRequest.promise(artifact, operationDefinition, task);
1966
2005
  }
1967
- const artifacts = R17.unnest(
2006
+ const artifacts = R18.unnest(
1968
2007
  await Promise.all(
1969
2008
  operationDefinitions.map(async (operationDefinition) => {
1970
2009
  const typeArtifact = await createTypeArtifact(operationDefinition);
@@ -1973,7 +2012,7 @@ async function compileOperationDefinition(options) {
1973
2012
  })
1974
2013
  )
1975
2014
  );
1976
- const operationDefinitionsGroupByModuleName = R17.groupBy(
2015
+ const operationDefinitionsGroupByModuleName = R18.groupBy(
1977
2016
  (operationDefinition) => operationDefinition.module.name,
1978
2017
  operationDefinitions
1979
2018
  );
@@ -1982,7 +2021,10 @@ async function compileOperationDefinition(options) {
1982
2021
  const artifact = new Artifact({
1983
2022
  id: filepath,
1984
2023
  filepath,
1985
- content: ""
2024
+ content: [
2025
+ "/* @anchor:file:start */",
2026
+ "/* @anchor:file:end */"
2027
+ ].join("\n")
1986
2028
  });
1987
2029
  for (const operationDefinition of operationDefinitions2 || []) {
1988
2030
  const dependentArtifact = artifacts.find((artifact2) => artifact2.filepath === genOperationRequestFilepath(operationDefinition));
@@ -2000,14 +2042,12 @@ async function compileOperationDefinition(options) {
2000
2042
  // src/renderer/request/index.ts
2001
2043
  async function requestRenderer() {
2002
2044
  return [
2003
- "import { KeqRequest } from 'keq'",
2004
- "",
2005
2045
  "/* @anchor:file:start */",
2006
2046
  "",
2007
2047
  "/* @anchor:request-declaration */",
2008
2048
  "export const request = new KeqRequest()",
2009
2049
  "",
2010
- "/* @anchor:file:end"
2050
+ "/* @anchor:file:end */"
2011
2051
  ].join("\n");
2012
2052
  }
2013
2053
 
@@ -2020,13 +2060,15 @@ function main6(compiler) {
2020
2060
  const rc = context.setup.rc;
2021
2061
  const matcher = context.setup.matcher;
2022
2062
  const documents = context.shaken.documents.filter((document) => !matcher.isModuleIgnored(document.module));
2023
- const requestArtifact = await compiler.hooks.afterCompileKeqRequest.promise(
2024
- new Artifact({
2025
- id: "request",
2026
- filepath: "request",
2027
- content: await requestRenderer(),
2028
- extensionName: ".ts"
2029
- }),
2063
+ let requestArtifact = new Artifact({
2064
+ id: "request",
2065
+ filepath: "request",
2066
+ content: await requestRenderer(),
2067
+ extensionName: ".ts"
2068
+ });
2069
+ requestArtifact.addDependence("keq", ["KeqRequest"]);
2070
+ requestArtifact = await compiler.hooks.afterCompileKeqRequest.promise(
2071
+ requestArtifact,
2030
2072
  task
2031
2073
  );
2032
2074
  const schemaDefinitions = documents.flatMap((document) => document.schemas);
@@ -2117,7 +2159,7 @@ function createInteractiveTask(options) {
2117
2159
  }
2118
2160
 
2119
2161
  // src/compiler/intercepter/perfect-error-message.ts
2120
- import * as R18 from "ramda";
2162
+ import * as R19 from "ramda";
2121
2163
  function perfectErrorMessage() {
2122
2164
  return {
2123
2165
  register: (tap) => {
@@ -2149,8 +2191,8 @@ function perfectErrorMessage() {
2149
2191
  }
2150
2192
  if (tap.type === "async") {
2151
2193
  tap.fn = (...args) => {
2152
- const callback = R18.last(args);
2153
- return fn(...R18.init(args), (err, result) => {
2194
+ const callback = R19.last(args);
2195
+ return fn(...R19.init(args), (err, result) => {
2154
2196
  prefix(err);
2155
2197
  return callback(err, result);
2156
2198
  });
@@ -2241,11 +2283,11 @@ var Compiler = class {
2241
2283
  [
2242
2284
  createSetupTask(this, options),
2243
2285
  createDownloadTask(this, { skipIgnoredModules: !options.interactive }),
2244
- createValidateTask(this, { enabled: !!options.build }),
2286
+ createValidateTask(this),
2245
2287
  createInteractiveTask({ enabled: !!options.interactive, ...typeof options.interactive === "object" ? options.interactive : { mode: "except" } }),
2246
2288
  createShakingTask(this, { enabled: !!options.build, ...typeof options.build === "object" ? options.build.shaking : void 0 }),
2247
2289
  createCompileTask(this, { enabled: !!options.build }),
2248
- createPersistTask(this, { enabled: !!options.build })
2290
+ createPersistTask(this)
2249
2291
  ],
2250
2292
  {
2251
2293
  concurrent: false,
@@ -2331,8 +2373,8 @@ program.command("ignore").addArgument(
2331
2373
  }
2332
2374
  });
2333
2375
  } else {
2334
- if (!options.module && !options.method && !options.pathname) {
2335
- throw new Error("at least one of '--module', '--method' or '--pathname' must be specified");
2376
+ if (!options.method && !options.pathname) {
2377
+ throw new Error("at least one of '-i --interactive', '--method' or '--pathname' must be specified");
2336
2378
  }
2337
2379
  const moduleNames = options.module || ["*"];
2338
2380
  compiler = new Compiler({