@povio/openapi-codegen-cli 3.0.0-rc.9 → 3.0.1-rc.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.
@@ -386,12 +386,23 @@ function replaceHyphenatedPath(path) {
386
386
  });
387
387
  return path;
388
388
  }
389
- const isSortingParameterObject = (param) => {
390
- const enumNames = param["x-enumNames"];
391
- const hasEnumNames = Array.isArray(enumNames) && enumNames.length > 0;
392
- const isStringSchema = !!param.schema && isSchemaObject(param.schema) && param.schema.type === "string";
393
- return hasEnumNames && isStringSchema;
389
+ const isSortingParameterObject = (param, schema = param.schema, resolver) => {
390
+ const enumNames = getParameterEnumNames(param, schema);
391
+ return Array.isArray(enumNames) && enumNames.length > 0 && isStringLikeParameterSchema(schema, resolver);
394
392
  };
393
+ function getParameterEnumNames(param, schema = param.schema) {
394
+ return param["x-enumNames"] ?? (schema && isSchemaObject(schema) ? schema["x-enumNames"] : void 0);
395
+ }
396
+ function isStringLikeParameterSchema(schema, resolver) {
397
+ if (!schema) return false;
398
+ if (isReferenceObject(schema)) return resolver ? isStringLikeParameterSchema(resolver.resolveObject(schema), resolver) : true;
399
+ if (schema.type === "string" || Array.isArray(schema.type) && schema.type.includes("string")) return true;
400
+ return [
401
+ ...schema.allOf ?? [],
402
+ ...schema.oneOf ?? [],
403
+ ...schema.anyOf ?? []
404
+ ].some((compositeSchema) => isStringLikeParameterSchema(compositeSchema, resolver));
405
+ }
395
406
  const isPathExcluded = (path, options) => {
396
407
  if (!options.excludePathRegex) return false;
397
408
  return new RegExp(options.excludePathRegex).test(path);
@@ -1397,96 +1408,6 @@ const DEFAULT_GENERATE_OPTIONS = {
1397
1408
  //#region src/generators/utils/array.utils.ts
1398
1409
  const getUniqueArray = (...arrs) => [...new Set(arrs.flat())];
1399
1410
 
1400
- //#endregion
1401
- //#region src/generators/utils/generate/generate.acl.utils.ts
1402
- const getAbilityFunctionName = (endpoint) => `canUse${capitalize(snakeToCamel(endpoint.operationName))}`;
1403
- const getImportedAbilityFunctionName = (endpoint, options) => {
1404
- return `${options.tsNamespaces ? `${getNamespaceName({
1405
- type: GenerateType.Acl,
1406
- tag: getEndpointTag(endpoint, options),
1407
- options
1408
- })}.` : ""}${getAbilityFunctionName(endpoint)}`;
1409
- };
1410
- const getAbilityAction = (endpoint) => endpoint.acl?.[0].action;
1411
- const getAbilitySubject = (endpoint) => endpoint.acl?.[0].subject;
1412
- const hasAbilityConditions = (endpoint) => !!getAbilityConditionsTypes(endpoint)?.length;
1413
- const getAbilityConditionsTypes = (endpoint) => endpoint.acl?.[0].conditionsTypes?.sort((a, b) => a.name.localeCompare(b.name));
1414
- const getAbilityDescription = (endpoint) => endpoint.acl?.[0]?.description;
1415
- const getAbilitySubjectTypes = (endpoint) => {
1416
- const abilitySubject = getAbilitySubject(endpoint);
1417
- const types = [`"${abilitySubject ?? ""}"`];
1418
- if (hasAbilityConditions(endpoint)) types.push(`ForcedSubject<"${abilitySubject}"> & { ${getAbilityConditionsTypes(endpoint)?.map((conditionType) => `${conditionType.name}${conditionType.required ? "" : "?"}: ${conditionType.type ?? ""}${conditionType.zodSchemaName ?? ""},`).join(" ")} }`);
1419
- return types;
1420
- };
1421
- function getAclData({ resolver, data, tag }) {
1422
- const endpoints = data.get(tag)?.endpoints.filter(({ acl }) => acl && acl.length > 0);
1423
- if (!endpoints || endpoints.length === 0) return;
1424
- return {
1425
- endpoints,
1426
- hasAdditionalAbilityImports: endpoints.some(({ acl }) => acl?.[0].conditions && Object.keys(acl[0].conditions).length > 0),
1427
- modelsImports: getModelsImports({
1428
- resolver,
1429
- tag,
1430
- zodSchemasAsTypes: getUniqueArray(endpoints.reduce((acc, endpoint) => {
1431
- const zodSchemas = endpoint.acl?.[0].conditionsTypes?.reduce((acc, propertyType) => [...acc, ...propertyType?.zodSchemaName ? [propertyType.zodSchemaName] : []], []);
1432
- return [...acc, ...zodSchemas ?? []];
1433
- }, []))
1434
- })
1435
- };
1436
- }
1437
- const getAppAbilitiesType = ({ resolver, data }) => {
1438
- const appAbilitiesTypeMap = /* @__PURE__ */ new Map();
1439
- const modelsImportsArr = [];
1440
- let hasAdditionalAbilityImports = false;
1441
- data.forEach((_, tag) => {
1442
- const aclData = getAclData({
1443
- resolver,
1444
- data,
1445
- tag
1446
- });
1447
- if (!aclData) return;
1448
- const { modelsImports: tagModelsImports, hasAdditionalAbilityImports: tagHasAdditionalAbilityImports, endpoints } = aclData;
1449
- modelsImportsArr.push(tagModelsImports);
1450
- hasAdditionalAbilityImports = hasAdditionalAbilityImports || tagHasAdditionalAbilityImports;
1451
- endpoints.forEach((endpoint) => {
1452
- const abilityAction = getAbilityAction(endpoint);
1453
- if (abilityAction) appAbilitiesTypeMap.set(abilityAction, new Set([...appAbilitiesTypeMap.get(abilityAction) ?? [], ...getAbilitySubjectTypes(endpoint)]));
1454
- });
1455
- });
1456
- const modelsImports = mergeImports(resolver.options, ...modelsImportsArr);
1457
- return {
1458
- appAbilitiesType: appAbilitiesTypeMap.size > 0 ? Object.fromEntries(Array.from(appAbilitiesTypeMap.entries()).map(([key, valueSet]) => [key, Array.from(valueSet)])) : void 0,
1459
- modelsImports,
1460
- hasAdditionalAbilityImports
1461
- };
1462
- };
1463
-
1464
- //#endregion
1465
- //#region src/generators/utils/generate/generate.query.utils.ts
1466
- const getQueryName = (endpoint, mutation) => {
1467
- const addMutationSuffix = isQuery(endpoint) && isMutation(endpoint) && mutation;
1468
- return `use${capitalize(snakeToCamel(endpoint.operationName))}${addMutationSuffix ? "Mutation" : ""}`;
1469
- };
1470
- const getInfiniteQueryName = (endpoint) => `use${capitalize(snakeToCamel(endpoint.operationName))}Infinite`;
1471
- const getQueryOptionsName = (endpoint) => `${snakeToCamel(endpoint.operationName)}QueryOptions`;
1472
- const getInfiniteQueryOptionsName = (endpoint) => `${snakeToCamel(endpoint.operationName)}InfiniteQueryOptions`;
1473
- const getPrefetchQueryName = (endpoint) => `prefetch${capitalize(snakeToCamel(endpoint.operationName))}`;
1474
- const getPrefetchInfiniteQueryName = (endpoint) => `prefetch${capitalize(snakeToCamel(endpoint.operationName))}Infinite`;
1475
- const getImportedQueryName = (endpoint, options) => {
1476
- return `${options.tsNamespaces ? `${getNamespaceName({
1477
- type: GenerateType.Queries,
1478
- tag: getEndpointTag(endpoint, options),
1479
- options
1480
- })}.` : ""}${getQueryName(endpoint)}`;
1481
- };
1482
- const getImportedInfiniteQueryName = (endpoint, options) => {
1483
- return `${options.tsNamespaces ? `${getNamespaceName({
1484
- type: GenerateType.Queries,
1485
- tag: getEndpointTag(endpoint, options),
1486
- options
1487
- })}.` : ""}${getInfiniteQueryName(endpoint)}`;
1488
- };
1489
-
1490
1411
  //#endregion
1491
1412
  //#region src/generators/core/openapi/iterateSchema.ts
1492
1413
  function iterateSchema(schema, options) {
@@ -1573,16 +1494,20 @@ function getSchemaDescriptions(schemaObj) {
1573
1494
  const getZodSchemaInferedTypeName = (zodSchemaName, options) => removeSuffix(zodSchemaName, options.schemaSuffix);
1574
1495
  const getImportedZodSchemaName = (resolver, zodSchemaName, namespaceTag) => {
1575
1496
  if (!isNamedZodSchema(zodSchemaName)) return zodSchemaName;
1576
- const tag = namespaceTag ?? resolver.getTagByZodSchemaName(zodSchemaName);
1497
+ const tag = getOwningOrLocalProxyTag(resolver, zodSchemaName, namespaceTag);
1577
1498
  return `${resolver.options.tsNamespaces ? `${getNamespaceName({
1578
1499
  type: GenerateType.Models,
1579
1500
  tag,
1580
1501
  options: resolver.options
1581
1502
  })}.` : ""}${zodSchemaName}`;
1582
1503
  };
1504
+ function getOwningOrLocalProxyTag(resolver, zodSchemaName, namespaceTag) {
1505
+ if (namespaceTag && resolver.options.modelsInCommon && resolver.options.splitByTags) return namespaceTag;
1506
+ return resolver.getTagByZodSchemaName(zodSchemaName) ?? namespaceTag;
1507
+ }
1583
1508
  const getImportedZodSchemaInferedTypeName = (resolver, zodSchemaName, currentTag, namespaceTag) => {
1584
1509
  if (!isNamedZodSchema(zodSchemaName)) return zodSchemaName === VOID_SCHEMA ? "void" : zodSchemaName;
1585
- const tag = namespaceTag ?? resolver.getTagByZodSchemaName(zodSchemaName);
1510
+ const tag = getOwningOrLocalProxyTag(resolver, zodSchemaName, namespaceTag);
1586
1511
  return `${resolver.options.tsNamespaces && (Boolean(namespaceTag) || tag !== currentTag) ? `${getNamespaceName({
1587
1512
  type: GenerateType.Models,
1588
1513
  tag,
@@ -1655,6 +1580,113 @@ function getZodSchemaPropertyDescriptions(resolver, data, tag) {
1655
1580
  return properties;
1656
1581
  }
1657
1582
 
1583
+ //#endregion
1584
+ //#region src/generators/utils/generate/generate.acl.utils.ts
1585
+ const getAbilityFunctionName = (endpoint) => `canUse${capitalize(snakeToCamel(endpoint.operationName))}`;
1586
+ const getImportedAbilityFunctionName = (endpoint, options) => {
1587
+ return `${options.tsNamespaces ? `${getNamespaceName({
1588
+ type: GenerateType.Acl,
1589
+ tag: getEndpointTag(endpoint, options),
1590
+ options
1591
+ })}.` : ""}${getAbilityFunctionName(endpoint)}`;
1592
+ };
1593
+ const getAbilityAction = (endpoint) => endpoint.acl?.[0].action;
1594
+ const getAbilitySubject = (endpoint) => endpoint.acl?.[0].subject;
1595
+ const hasAbilityConditions = (endpoint) => !!getAbilityConditionsTypes(endpoint)?.length;
1596
+ const getAbilityConditionsTypes = (endpoint) => endpoint.acl?.[0].conditionsTypes?.sort((a, b) => a.name.localeCompare(b.name));
1597
+ const getAbilityDescription = (endpoint) => endpoint.acl?.[0]?.description;
1598
+ const getAbilitySubjectTypes = (endpoint, resolver, tag) => {
1599
+ const abilitySubject = getAbilitySubject(endpoint);
1600
+ const types = [`"${abilitySubject ?? ""}"`];
1601
+ if (hasAbilityConditions(endpoint)) types.push(`ForcedSubject<"${abilitySubject}"> & { ${getAbilityConditionsTypes(endpoint)?.map((conditionType) => `${conditionType.name}${conditionType.required ? "" : "?"}: ${getAbilityConditionType(conditionType, resolver, tag)},`).join(" ")} }`);
1602
+ return types;
1603
+ };
1604
+ function getAbilityConditionType(conditionType, resolver, tag) {
1605
+ if (!conditionType.zodSchemaName) return conditionType.type ?? "";
1606
+ if (!resolver) return `${conditionType.type ?? ""}${conditionType.zodSchemaName}`;
1607
+ return getImportedZodSchemaInferedTypeName(resolver, conditionType.zodSchemaName, tag, tag);
1608
+ }
1609
+ function getAclData({ resolver, data, tag }) {
1610
+ const endpoints = data.get(tag)?.endpoints.filter(({ acl }) => acl && acl.length > 0);
1611
+ if (!endpoints || endpoints.length === 0) return;
1612
+ return {
1613
+ endpoints,
1614
+ hasAdditionalAbilityImports: endpoints.some(({ acl }) => acl?.[0].conditions && Object.keys(acl[0].conditions).length > 0),
1615
+ modelsImports: getModelsImports({
1616
+ resolver,
1617
+ tag,
1618
+ zodSchemasAsTypes: getUniqueArray(endpoints.reduce((acc, endpoint) => {
1619
+ const zodSchemas = endpoint.acl?.[0].conditionsTypes?.reduce((acc, propertyType) => [...acc, ...propertyType?.zodSchemaName ? [propertyType.zodSchemaName] : []], []);
1620
+ return [...acc, ...zodSchemas ?? []];
1621
+ }, []))
1622
+ })
1623
+ };
1624
+ }
1625
+ const getAppAbilitiesType = ({ resolver, data }) => {
1626
+ const appAbilitiesTypeMap = /* @__PURE__ */ new Map();
1627
+ const modelsImportsArr = [];
1628
+ let hasAdditionalAbilityImports = false;
1629
+ data.forEach((_, tag) => {
1630
+ const aclData = getAclData({
1631
+ resolver,
1632
+ data,
1633
+ tag
1634
+ });
1635
+ if (!aclData) return;
1636
+ const { modelsImports: tagModelsImports, hasAdditionalAbilityImports: tagHasAdditionalAbilityImports, endpoints } = aclData;
1637
+ modelsImportsArr.push(tagModelsImports);
1638
+ hasAdditionalAbilityImports = hasAdditionalAbilityImports || tagHasAdditionalAbilityImports;
1639
+ endpoints.forEach((endpoint) => {
1640
+ const abilityAction = getAbilityAction(endpoint);
1641
+ if (abilityAction) appAbilitiesTypeMap.set(abilityAction, new Set([...appAbilitiesTypeMap.get(abilityAction) ?? [], ...getAbilitySubjectTypes(endpoint, resolver, tag)]));
1642
+ });
1643
+ });
1644
+ const modelsImports = mergeImports(resolver.options, ...modelsImportsArr);
1645
+ return {
1646
+ appAbilitiesType: appAbilitiesTypeMap.size > 0 ? Object.fromEntries(Array.from(appAbilitiesTypeMap.entries()).map(([key, valueSet]) => [key, Array.from(valueSet)])) : void 0,
1647
+ modelsImports,
1648
+ hasAdditionalAbilityImports
1649
+ };
1650
+ };
1651
+ /** Renders a `checkAcl(...)` call, passing the ability's conditions object only when the
1652
+ * ability function actually expects one (i.e. the endpoint declares matching conditions). */
1653
+ function renderAclCheckCall(resolver, endpoint, replacements, indent = "") {
1654
+ const checkParams = getAbilityConditionsTypes(endpoint)?.map((condition) => invalidVariableNameCharactersToCamel(condition.name));
1655
+ const paramNames = new Set(endpoint.parameters.map((param) => invalidVariableNameCharactersToCamel(param.name)));
1656
+ const hasAllCheckParams = checkParams?.every((param) => paramNames.has(param));
1657
+ const args = hasAbilityConditions(endpoint) && hasAllCheckParams ? `{ ${(checkParams ?? []).map((param) => {
1658
+ const resolvedParam = replacements?.[param] ?? param;
1659
+ return resolvedParam === param ? param : `${param}: ${resolvedParam}`;
1660
+ }).join(", ")} } ` : "";
1661
+ return `${indent}checkAcl(${getImportedAbilityFunctionName(endpoint, resolver.options)}(${args}));`;
1662
+ }
1663
+
1664
+ //#endregion
1665
+ //#region src/generators/utils/generate/generate.query.utils.ts
1666
+ const getQueryName = (endpoint, mutation) => {
1667
+ const addMutationSuffix = isQuery(endpoint) && isMutation(endpoint) && mutation;
1668
+ return `use${capitalize(snakeToCamel(endpoint.operationName))}${addMutationSuffix ? "Mutation" : ""}`;
1669
+ };
1670
+ const getInfiniteQueryName = (endpoint) => `use${capitalize(snakeToCamel(endpoint.operationName))}Infinite`;
1671
+ const getQueryOptionsName = (endpoint) => `${snakeToCamel(endpoint.operationName)}QueryOptions`;
1672
+ const getInfiniteQueryOptionsName = (endpoint) => `${snakeToCamel(endpoint.operationName)}InfiniteQueryOptions`;
1673
+ const getPrefetchQueryName = (endpoint) => `prefetch${capitalize(snakeToCamel(endpoint.operationName))}`;
1674
+ const getPrefetchInfiniteQueryName = (endpoint) => `prefetch${capitalize(snakeToCamel(endpoint.operationName))}Infinite`;
1675
+ const getImportedQueryName = (endpoint, options) => {
1676
+ return `${options.tsNamespaces ? `${getNamespaceName({
1677
+ type: GenerateType.Queries,
1678
+ tag: getEndpointTag(endpoint, options),
1679
+ options
1680
+ })}.` : ""}${getQueryName(endpoint)}`;
1681
+ };
1682
+ const getImportedInfiniteQueryName = (endpoint, options) => {
1683
+ return `${options.tsNamespaces ? `${getNamespaceName({
1684
+ type: GenerateType.Queries,
1685
+ tag: getEndpointTag(endpoint, options),
1686
+ options
1687
+ })}.` : ""}${getInfiniteQueryName(endpoint)}`;
1688
+ };
1689
+
1658
1690
  //#endregion
1659
1691
  //#region src/generators/utils/generate/generate.imports.utils.ts
1660
1692
  function getModelsImports({ resolver, tag, zodSchemas = [], zodSchemasAsTypes = [] }) {
@@ -1972,7 +2004,8 @@ const getEndpointBody$1 = (endpoint) => endpoint.parameters.find((param) => para
1972
2004
  const hasEndpointConfig = (endpoint, resolver) => {
1973
2005
  const endpointConfig = getEndpointConfig(endpoint);
1974
2006
  const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
1975
- return Object.keys(endpointConfig).length > 0 || hasAxiosRequestConfig;
2007
+ const needsBlobConfig = endpoint.mediaDownload || endpoint.response === "z.instanceof(Blob)";
2008
+ return Object.keys(endpointConfig).length > 0 || hasAxiosRequestConfig || needsBlobConfig;
1976
2009
  };
1977
2010
  const getEndpointPath = (endpoint) => endpoint.path.replace(/:([a-zA-Z0-9_]+)/g, "${$1}");
1978
2011
  function mapEndpointParamsToFunctionParams(resolver, endpoint, options) {
@@ -2039,6 +2072,40 @@ function getEndpointConfig(endpoint) {
2039
2072
  ...Object.keys(headers).length ? { headers } : {}
2040
2073
  };
2041
2074
  }
2075
+ /** Renders the body of a media-upload mutationFn: call the endpoint (without the file arg) to
2076
+ * get upload instructions, then upload the file itself to the returned URL. Shared between
2077
+ * renderMutation (*.queries.ts) and renderMutationContent (*.configs.ts / builderConfigs) so
2078
+ * both mutation paths stay in sync. Lines are relative to the caller's own indent. */
2079
+ function renderMediaUploadMutationBody({ resolver, endpointFunction, resolvedEndpointArgs }) {
2080
+ return [
2081
+ `const uploadInstructions = await ${endpointFunction}(${resolvedEndpointArgs}${resolver.options.axiosRequestConfig ? `${resolvedEndpointArgs ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""});`,
2082
+ "",
2083
+ "if (file && uploadInstructions.url) {",
2084
+ ` const method = (${BODY_PARAMETER_NAME}?.method?.toLowerCase() ?? "put") as "put" | "post";`,
2085
+ " let dataToSend: File | FormData = file;",
2086
+ " if (method === \"post\") {",
2087
+ " dataToSend = new FormData();",
2088
+ " if (uploadInstructions.fields) {",
2089
+ " for (const [key, value] of uploadInstructions.fields) {",
2090
+ " dataToSend.append(key, value);",
2091
+ " }",
2092
+ " }",
2093
+ " dataToSend.append(\"file\", file);",
2094
+ " }",
2095
+ " await axios[method](uploadInstructions.url, dataToSend, {",
2096
+ " headers: {",
2097
+ " \"Content-Type\": file.type,",
2098
+ " },",
2099
+ " signal: abortController?.signal,",
2100
+ " onUploadProgress: onUploadProgress",
2101
+ " ? (progressEvent) => onUploadProgress({ loaded: progressEvent.loaded, total: progressEvent.total ?? 0 })",
2102
+ " : undefined,",
2103
+ " });",
2104
+ "}",
2105
+ "",
2106
+ "return uploadInstructions;"
2107
+ ];
2108
+ }
2042
2109
 
2043
2110
  //#endregion
2044
2111
  //#region src/generators/utils/query.utils.ts
@@ -2096,7 +2163,9 @@ function getEndpointAclConditionPropertyType({ resolver, endpoint, acl, name })
2096
2163
  const matchingMediaType = Object.keys(bodyParameter?.bodyObject?.content ?? {}).find(isParamMediaTypeAllowed);
2097
2164
  if (matchingMediaType) {
2098
2165
  schema = bodyParameter?.bodyObject?.content?.[matchingMediaType]?.schema;
2166
+ required = bodyParameter?.bodyObject?.required;
2099
2167
  info = `${isQuery(endpoint) ? "query" : "mutation"} data`;
2168
+ if (pathSplits[index]?.startsWith("$")) index++;
2100
2169
  }
2101
2170
  }
2102
2171
  while (schema && index < pathSplits.length) {
@@ -2171,13 +2240,16 @@ function resolveEndpointZodSchema({ resolver, schema, meta, tag, fallbackName, c
2171
2240
  fallbackName,
2172
2241
  resolver,
2173
2242
  tag
2174
- }) : `${resolveZodSchemaName({
2175
- schema: schemaObject,
2176
- zodSchema,
2177
- fallbackName,
2178
- resolver,
2179
- tag
2180
- })}${zodChain}`;
2243
+ }) : (() => {
2244
+ const name = resolveZodSchemaName({
2245
+ schema: schemaObject,
2246
+ zodSchema,
2247
+ fallbackName,
2248
+ resolver,
2249
+ tag
2250
+ });
2251
+ return isNamedZodSchema(name) ? name : name + zodChain;
2252
+ })();
2181
2253
  entries.set(metaKey, resolved);
2182
2254
  return resolved;
2183
2255
  }
@@ -2228,9 +2300,9 @@ function getEndpointParameter({ resolver, param, operationName, isUniqueOperatio
2228
2300
  if (resolver.options.withDescription && schema) schema.description = (paramObj.description ?? "").trim();
2229
2301
  const fallbackName = getParamZodSchemaName(getZodSchemaOperationName(operationName, isUniqueOperationName, tag), paramObj.name);
2230
2302
  let parameterSortingEnumSchemaName = void 0;
2231
- if (isSortingParameterObject(paramObj)) {
2303
+ if (isSortingParameterObject(paramObj, schema, resolver)) {
2232
2304
  const enumZodSchemaName = getEnumZodSchemaName(fallbackName, resolver.options.enumSuffix, resolver.options.schemaSuffix);
2233
- const code = getEnumZodSchemaCodeFromEnumNames(paramObj["x-enumNames"]);
2305
+ const code = getEnumZodSchemaCodeFromEnumNames(getParameterEnumNames(paramObj, schema) ?? []);
2234
2306
  resolver.setZodSchema(enumZodSchemaName, code, tag);
2235
2307
  parameterSortingEnumSchemaName = enumZodSchemaName;
2236
2308
  }
@@ -2344,7 +2416,7 @@ function getEndpointsFromOpenAPIDoc(resolver) {
2344
2416
  }) ?? mediaTypes.find(isMediaTypeAllowed);
2345
2417
  let schema;
2346
2418
  if (matchingMediaType) {
2347
- endpoint.responseFormat = matchingMediaType;
2419
+ if (isMainResponseStatus(Number(statusCode)) || statusCode === "default" && !endpoint.responseFormat) endpoint.responseFormat = matchingMediaType;
2348
2420
  schema = responseObj.content?.[matchingMediaType]?.schema;
2349
2421
  } else if (statusCode === "200") resolver.validationErrors.push(getInvalidStatusCodeError({
2350
2422
  received: "200",
@@ -2388,7 +2460,7 @@ function getEndpointsFromOpenAPIDoc(resolver) {
2388
2460
  const domainStr = rawSchema["x-domain-error-domain"];
2389
2461
  const domainName = rawSchema["x-domain-error-name"];
2390
2462
  const codeEnumArr = ((rawSchema?.properties)?.code)?.enum;
2391
- const domainCode = Array.isArray(codeEnumArr) && codeEnumArr.length === 1 && typeof codeEnumArr[0] === "number" ? codeEnumArr[0] : void 0;
2463
+ const domainCode = Array.isArray(codeEnumArr) && codeEnumArr.length === 1 && (typeof codeEnumArr[0] === "number" || typeof codeEnumArr[0] === "string") ? codeEnumArr[0] : void 0;
2392
2464
  endpoint.errors.push({
2393
2465
  zodSchema: responseZodSchema,
2394
2466
  status,
@@ -3278,9 +3350,9 @@ function renderWorkspaceAclHook({ resolver, endpoint }) {
3278
3350
  const objectRequired = abilityConditionsTypes.some((propertyType) => propertyType.required && !workspaceConditionNameSet.has(propertyType.name));
3279
3351
  const objectParams = abilityConditionsTypes.map((propertyType) => {
3280
3352
  const isWorkspaceCondition = workspaceConditionNameSet.has(propertyType.name);
3281
- return `${propertyType.name}${propertyType.required && !isWorkspaceCondition ? "" : "?"}: ${(propertyType.type ?? "") + (propertyType.zodSchemaName ?? "")}, `;
3353
+ return `${propertyType.name}${propertyType.required && !isWorkspaceCondition ? "" : "?"}: ${renderConditionType(resolver, endpoint, propertyType)}, `;
3282
3354
  }).join("");
3283
- const contextType = abilityConditionsTypes.filter((propertyType) => workspaceConditionNameSet.has(propertyType.name)).map((propertyType) => `${propertyType.name}?: ${(propertyType.type ?? "") + (propertyType.zodSchemaName ?? "")}`).join("; ");
3355
+ const contextType = abilityConditionsTypes.filter((propertyType) => workspaceConditionNameSet.has(propertyType.name)).map((propertyType) => `${propertyType.name}?: ${renderConditionType(resolver, endpoint, propertyType)}`).join("; ");
3284
3356
  const contextBindings = workspaceConditionNames.map((name) => `${name}: ${name}Workspace`).join(", ");
3285
3357
  const lines = [];
3286
3358
  lines.push(`export const use${capitalize(getAbilityFunctionName(endpoint))} = (`);
@@ -3306,15 +3378,15 @@ function renderAbilityFunction({ resolver, endpoint }) {
3306
3378
  lines.push("/**");
3307
3379
  lines.push(` * Use for ${abilityQuery} ability. ${hasConditions ? "For global ability, omit the object parameter." : ""}${getAbilityDescription(endpoint) ? "" : ""}`);
3308
3380
  if (getAbilityDescription(endpoint)) lines.push(` * @description ${getAbilityDescription(endpoint)}`);
3309
- if (hasConditions) for (const propertyType of abilityConditionsTypes) lines.push(` * @param { ${(propertyType.type ?? "") + (propertyType.zodSchemaName ?? "")} } object.${propertyType.name} ${propertyType.name} from ${propertyType.info}`);
3381
+ if (hasConditions) for (const propertyType of abilityConditionsTypes) lines.push(` * @param { ${renderConditionType(resolver, endpoint, propertyType)} } object.${propertyType.name} ${propertyType.name} from ${propertyType.info}`);
3310
3382
  lines.push(` * @returns { AbilityTuple } An ability tuple indicating the user's ability to use ${abilityQuery}`);
3311
3383
  lines.push(" */");
3312
3384
  lines.push(`export const ${getAbilityFunctionName(endpoint)} = (`);
3313
- if (hasConditions) lines.push(` object?: { ${abilityConditionsTypes.map((propertyType) => `${propertyType.name}${propertyType.required ? "" : "?"}: ${(propertyType.type ?? "") + (propertyType.zodSchemaName ?? "")}, `).join("")} } `);
3385
+ if (hasConditions) lines.push(` object?: { ${abilityConditionsTypes.map((propertyType) => `${propertyType.name}${propertyType.required ? "" : "?"}: ${renderConditionType(resolver, endpoint, propertyType)}, `).join("")} } `);
3314
3386
  lines.push(") => [");
3315
3387
  lines.push(` "${getAbilityAction(endpoint)}",`);
3316
3388
  lines.push(` ${hasConditions ? `object ? subject("${getAbilitySubject(endpoint)}", object) : "${getAbilitySubject(endpoint)}"` : `"${getAbilitySubject(endpoint)}"`}`);
3317
- lines.push(`] as ${CASL_ABILITY_BINDING.abilityTuple}<"${getAbilityAction(endpoint)}", ${getAbilitySubjectTypes(endpoint).join(" | ")}>;`);
3389
+ lines.push(`] as ${CASL_ABILITY_BINDING.abilityTuple}<"${getAbilityAction(endpoint)}", ${getAbilitySubjectTypes(endpoint, resolver, getEndpointTag(endpoint, resolver.options)).join(" | ")}>;`);
3318
3390
  const workspaceAclHook = renderWorkspaceAclHook({
3319
3391
  resolver,
3320
3392
  endpoint
@@ -3325,6 +3397,9 @@ function renderAbilityFunction({ resolver, endpoint }) {
3325
3397
  }
3326
3398
  return lines.join("\n");
3327
3399
  }
3400
+ function renderConditionType(resolver, endpoint, propertyType) {
3401
+ return getAbilityConditionType(propertyType, resolver, getEndpointTag(endpoint, resolver.options));
3402
+ }
3328
3403
 
3329
3404
  //#endregion
3330
3405
  //#region src/generators/const/buildConfigs.const.ts
@@ -3537,7 +3612,7 @@ function getColumnsConfig(resolver, endpoint) {
3537
3612
  ...acc,
3538
3613
  [key]: true
3539
3614
  }), {});
3540
- const sortableEnumSchemaName = endpoint.parameters.find((param) => param.parameterObject && isSortingParameterObject(param.parameterObject))?.parameterSortingEnumSchemaName;
3615
+ const sortableEnumSchemaName = endpoint.parameters.find((param) => param.parameterSortingEnumSchemaName)?.parameterSortingEnumSchemaName;
3541
3616
  return {
3542
3617
  columns: {
3543
3618
  schema: getImportedZodSchemaName(resolver, zodSchema),
@@ -3580,7 +3655,7 @@ const QUERIES_MODULE_NAME = "moduleName";
3580
3655
  //#endregion
3581
3656
  //#region src/generators/generate/generateConfigs.ts
3582
3657
  function generateConfigs(generateTypeParams) {
3583
- const { configs, hasZodImport, modelsImports, aclImports } = getBuilderConfigs(generateTypeParams);
3658
+ const { configs, hasZodImport, modelsImports, queriesImports, aclImports } = getBuilderConfigs(generateTypeParams);
3584
3659
  if (configs.length === 0) return;
3585
3660
  const { resolver, tag } = generateTypeParams;
3586
3661
  const endpoints = configs.flatMap((config) => [
@@ -3590,10 +3665,18 @@ function generateConfigs(generateTypeParams) {
3590
3665
  config.bulkDelete?.mutation
3591
3666
  ]).filter((m) => typeof m !== "string" && m !== void 0);
3592
3667
  const hasMutation = endpoints.length > 0;
3593
- resolver.options.checkAcl && endpoints.some((e) => e.acl);
3668
+ const hasAclCheck = resolver.options.checkAcl && endpoints.some((e) => e.acl);
3594
3669
  const hasMutationEffects = resolver.options.mutationEffects && hasMutation;
3595
3670
  const hasMutationDefaultOnError = resolver.options.mutationDefaultOnError && hasMutation;
3596
- const hasWorkspaceContext = resolver.options.workspaceContext && endpoints.some((e) => resolver.options.workspaceContext);
3671
+ const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
3672
+ const hasAxiosDefaultImport = endpoints.some((e) => e.mediaUpload);
3673
+ const hasAxiosImport = hasAxiosRequestConfig || hasAxiosDefaultImport;
3674
+ const axiosImport = {
3675
+ defaultImport: hasAxiosDefaultImport ? AXIOS_DEFAULT_IMPORT_NAME : void 0,
3676
+ bindings: [],
3677
+ typeBindings: hasAxiosImport ? [AXIOS_REQUEST_CONFIG_TYPE] : [],
3678
+ from: "axios"
3679
+ };
3597
3680
  const endpointsImports = getEndpointsImports({
3598
3681
  tag,
3599
3682
  endpoints,
@@ -3621,10 +3704,6 @@ function generateConfigs(generateTypeParams) {
3621
3704
  bindings: [ACL_CHECK_HOOK],
3622
3705
  from: ACL_PACKAGE_IMPORT_PATH
3623
3706
  };
3624
- const workspaceContextImport = {
3625
- bindings: ["OpenApiWorkspaceContext"],
3626
- from: PACKAGE_IMPORT_PATH
3627
- };
3628
3707
  const hasDynamicInputsImport = configs.some((config) => config.readAll.filters || config.create?.inputDefs || config.update?.inputDefs);
3629
3708
  const dynamicInputsImport = {
3630
3709
  bindings: [BUILDERS_UTILS.dynamicInputs],
@@ -3636,10 +3715,12 @@ function generateConfigs(generateTypeParams) {
3636
3715
  from: resolver.options.dynamicColumnsImportPath
3637
3716
  };
3638
3717
  const lines = [];
3718
+ if (hasAxiosImport) lines.push(renderImport$3(axiosImport));
3639
3719
  if (hasZodImport) lines.push(renderImport$3(ZOD_IMPORT));
3640
3720
  if (hasDynamicInputsImport) lines.push(renderImport$3(dynamicInputsImport));
3641
3721
  if (hasDynamicColumnsImport) lines.push(renderImport$3(dynamicColumnsImport));
3642
3722
  for (const modelsImport of modelsImports) lines.push(renderImport$3(modelsImport));
3723
+ for (const queriesImport of queriesImports) lines.push(renderImport$3(queriesImport));
3643
3724
  for (const endpointsImport of endpointsImports) lines.push(renderImport$3(endpointsImport));
3644
3725
  if (hasMutation) {
3645
3726
  lines.push(renderImport$3(queryImport));
@@ -3648,8 +3729,7 @@ function generateConfigs(generateTypeParams) {
3648
3729
  lines.push(renderImport$3(queryModulesImport));
3649
3730
  lines.push(renderImport$3(mutationEffectsImport));
3650
3731
  }
3651
- lines.push(renderImport$3(aclCheckImport));
3652
- if (hasWorkspaceContext) lines.push(renderImport$3(workspaceContextImport));
3732
+ if (hasAclCheck) lines.push(renderImport$3(aclCheckImport));
3653
3733
  }
3654
3734
  for (const aclImport of aclImports) lines.push(renderImport$3(aclImport));
3655
3735
  lines.push("");
@@ -3707,32 +3787,34 @@ function renderMutationContent(resolver, endpoint, tag) {
3707
3787
  });
3708
3788
  const endpointParamsStr = endpointParams.map((p) => `${p.name}${p.required ? "" : "?"}: ${p.type}`).join("; ");
3709
3789
  const destructuredMutationArgs = endpointParams.map((p) => p.name).join(", ");
3790
+ const resolvedEndpointArgs = mapEndpointParamsToFunctionParams(resolver, endpoint, { modelNamespaceTag: endpointTag }).map((p) => p.name).join(", ");
3710
3791
  const endpointFunction = getImportedEndpointName(endpoint, resolver.options);
3711
3792
  const mutationVariablesType = endpoint.mediaUpload ? `{ ${endpointParamsStr}${endpointParamsStr ? "; " : ""}abortController?: AbortController; onUploadProgress?: (progress: { loaded: number; total: number }) => void }` : `{ ${endpointParamsStr} }`;
3712
3793
  const lines = [];
3713
- lines.push(`(options?: AppMutationOptions<typeof ${endpointFunction}, ${mutationVariablesType}>${hasAxiosRequestConfig ? `, config?: AxiosRequestConfig` : ""}) => {`);
3794
+ lines.push(`(options?: AppMutationOptions<typeof ${endpointFunction}, ${mutationVariablesType}>${hasMutationEffects ? ` & ${MUTATION_EFFECTS.optionsType}` : ""}${hasAxiosRequestConfig ? `, config?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => {`);
3714
3795
  if (hasMutationDefaultOnError) lines.push(" const queryConfig = OpenApiQueryConfig.useConfig();");
3715
- if (hasMutationEffects) lines.push(` const { runMutationEffects } = useMutationEffects<typeof ${QUERY_MODULE_ENUM}.${endpointTag}>({ currentModule: ${QUERY_MODULE_ENUM}.${tag} });`);
3716
- lines.push(` const { checkAcl } = ${ACL_CHECK_HOOK}();`);
3796
+ if (hasMutationEffects) lines.push(` const { runMutationEffects } = useMutationEffects<${QUERY_MODULE_ENUM}.${endpointTag}>({ currentModule: ${QUERY_MODULE_ENUM}.${tag} });`);
3797
+ if (hasAclCheck) lines.push(` const { checkAcl } = ${ACL_CHECK_HOOK}();`);
3717
3798
  lines.push("");
3718
3799
  lines.push(` return ${QUERY_HOOKS.mutation}({`);
3719
3800
  const mutationFnArg = destructuredMutationArgs ? `{ ${destructuredMutationArgs}${endpoint.mediaUpload ? `${destructuredMutationArgs ? ", " : ""}abortController, onUploadProgress` : ""} }` : "";
3720
- lines.push(` mutationFn: (${mutationFnArg}) => {`);
3721
- if (hasAclCheck) lines.push(` checkAcl(${getNamespaceName({
3722
- type: GenerateType.Acl,
3723
- tag: endpointTag,
3724
- options: resolver.options
3725
- })}.canUse${capitalize(snakeToCamel(endpoint.operationName))}({ ${destructuredMutationArgs} }));`);
3726
- lines.push(` return ${endpointFunction}(${destructuredMutationArgs}${hasAxiosRequestConfig ? `${destructuredMutationArgs ? ", " : ""}config` : ""});`);
3801
+ lines.push(` mutationFn: ${endpoint.mediaUpload ? "async " : ""}(${mutationFnArg}) => {`);
3802
+ if (hasAclCheck) lines.push(renderAclCheckCall(resolver, endpoint, void 0, " "));
3803
+ if (endpoint.mediaUpload) lines.push(...renderMediaUploadMutationBody({
3804
+ resolver,
3805
+ endpointFunction,
3806
+ resolvedEndpointArgs
3807
+ }).map((line) => ` ${line}`));
3808
+ else lines.push(` return ${endpointFunction}(${destructuredMutationArgs}${hasAxiosRequestConfig ? `${destructuredMutationArgs ? ", " : ""}config` : ""});`);
3727
3809
  lines.push(" },");
3810
+ lines.push(" ...options,");
3811
+ if (hasMutationDefaultOnError) lines.push(" onError: options?.onError ?? queryConfig.onError,");
3728
3812
  if (hasMutationEffects) {
3729
- lines.push(" onSuccess: async (...args) => {");
3730
- lines.push(" await runMutationEffects();");
3731
- lines.push(" await options?.onSuccess?.(...args);");
3813
+ lines.push(" onSuccess: async (resData, variables, onMutateResult, context) => {");
3814
+ lines.push(" await runMutationEffects(resData, variables, options);");
3815
+ lines.push(" options?.onSuccess?.(resData, variables, onMutateResult, context);");
3732
3816
  lines.push(" },");
3733
3817
  }
3734
- lines.push(" ...options,");
3735
- if (hasMutationDefaultOnError) lines.push(" onError: options?.onError ?? queryConfig.onError,");
3736
3818
  lines.push(" });");
3737
3819
  lines.push("}");
3738
3820
  return lines.map((line) => " " + line).join("\n").trimStart();
@@ -3809,10 +3891,11 @@ function generateEndpoints({ resolver, data, tag }) {
3809
3891
  from: getAppRestClientImportPath(resolver.options)
3810
3892
  };
3811
3893
  const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
3812
- const hasAxiosImport = hasAxiosRequestConfig;
3894
+ const hasGetEndpoints = endpoints.some((endpoint) => endpoint.method === "get");
3895
+ const hasAxiosImport = hasAxiosRequestConfig || hasGetEndpoints;
3813
3896
  const axiosImport = {
3814
3897
  bindings: [],
3815
- typeBindings: hasAxiosRequestConfig ? [AXIOS_REQUEST_CONFIG_TYPE] : [],
3898
+ typeBindings: hasAxiosImport ? [AXIOS_REQUEST_CONFIG_TYPE] : [],
3816
3899
  from: AXIOS_IMPORT.from
3817
3900
  };
3818
3901
  const generateParse = resolver.options.parseRequestParams;
@@ -3850,9 +3933,10 @@ function generateEndpoints({ resolver, data, tag }) {
3850
3933
  const endpointBody = getEndpointBody$1(endpoint);
3851
3934
  const hasUndefinedEndpointBody = requiresBody(endpoint) && !endpointBody && hasEndpointConfig(endpoint, resolver);
3852
3935
  const endpointConfig = renderEndpointConfig(resolver, endpoint, tag);
3853
- lines.push(`export const ${getEndpointName(endpoint)} = (${endpointParams}${hasAxiosRequestConfig ? `${AXIOS_REQUEST_CONFIG_NAME}?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => {`);
3936
+ const hasRequestConfigParam = hasAxiosRequestConfig || endpoint.method === "get";
3937
+ lines.push(`export const ${getEndpointName(endpoint)} = (${endpointParams}${hasRequestConfigParam ? `${AXIOS_REQUEST_CONFIG_NAME}?: ${getRequestConfigType$1()}` : ""}) => {`);
3854
3938
  lines.push(` return ${APP_REST_CLIENT_NAME}.${endpoint.method}(`);
3855
- lines.push(` { resSchema: ${getImportedZodSchemaName(resolver, endpoint.response)} },`);
3939
+ lines.push(` ${renderRequestInfo(resolver, endpoint, tag)},`);
3856
3940
  lines.push(` \`${getEndpointPath(endpoint)}\`,`);
3857
3941
  if (endpointBody) lines.push(` ${generateParse ? renderEndpointParamParse(resolver, endpointBody, endpointBody.name, tag) : endpointBody.name},`);
3858
3942
  else if (hasUndefinedEndpointBody) lines.push(" undefined,");
@@ -3863,6 +3947,12 @@ function generateEndpoints({ resolver, data, tag }) {
3863
3947
  if (resolver.options.tsNamespaces) lines.push("}");
3864
3948
  return lines.join("\n").trimEnd() + "\n";
3865
3949
  }
3950
+ function renderRequestInfo(resolver, endpoint, tag) {
3951
+ return `{ resSchema: ${getImportedZodSchemaName(resolver, endpoint.response, resolver.options.modelsInCommon && resolver.options.splitByTags ? tag : void 0)} }`;
3952
+ }
3953
+ function getRequestConfigType$1() {
3954
+ return `${AXIOS_REQUEST_CONFIG_TYPE} & { allowInvalidResponseData?: boolean }`;
3955
+ }
3866
3956
  function renderImport$2(importData) {
3867
3957
  const namedImports = [...importData.bindings, ...(importData.typeBindings ?? []).map((binding) => importData.typeOnly ? binding : `type ${binding}`)];
3868
3958
  const names = [...importData.defaultImport ? [importData.defaultImport] : [], ...namedImports.length > 0 ? [`{ ${namedImports.join(", ")} }`] : []].join(", ");
@@ -3876,17 +3966,24 @@ function renderEndpointArgs$1(resolver, endpoint, options) {
3876
3966
  }
3877
3967
  function renderEndpointParamParse(resolver, param, paramName, modelNamespaceTag) {
3878
3968
  const addOptional = !(param.parameterObject ?? param.bodyObject)?.required && (Boolean(param.parameterSortingEnumSchemaName) || isNamedZodSchema(param.zodSchema));
3879
- const schemaValue = param.parameterSortingEnumSchemaName ? `${ZOD_EXTENDED.namespace}.${ZOD_EXTENDED.exports.sortExp}(${getImportedZodSchemaName(resolver, param.parameterSortingEnumSchemaName, modelNamespaceTag)})${addOptional ? ".optional()" : ""}` : `${getImportedZodSchemaName(resolver, param.zodSchema, modelNamespaceTag)}${addOptional ? ".optional()" : ""}`;
3969
+ const schemaValue = param.parameterSortingEnumSchemaName ? `${ZOD_EXTENDED.namespace}.${ZOD_EXTENDED.exports.sortExp}(${getImportedZodSchemaName(resolver, param.parameterSortingEnumSchemaName, modelNamespaceTag)})${getSortingPresenceChain$1(resolver, param)}` : `${getImportedZodSchemaName(resolver, param.zodSchema, modelNamespaceTag)}${addOptional ? ".optional()" : ""}`;
3880
3970
  const queryArgs = param.type === "Query" ? `, { type: "query", name: "${paramName}" }` : "";
3881
3971
  return `${ZOD_EXTENDED.namespace}.${ZOD_EXTENDED.exports.parse}(${schemaValue}, ${paramName}${queryArgs})`;
3882
3972
  }
3973
+ function getSortingPresenceChain$1(resolver, param) {
3974
+ const zodSchemaCode = resolver.getCodeByZodSchemaName(param.zodSchema) ?? param.zodSchema;
3975
+ if (zodSchemaCode.includes(".nullish()")) return ".nullish()";
3976
+ if (zodSchemaCode.includes(".nullable()")) return ".nullable()";
3977
+ return !(param.parameterObject ?? param.bodyObject)?.required ? ".optional()" : "";
3978
+ }
3883
3979
  function renderEndpointConfig(resolver, endpoint, modelNamespaceTag) {
3884
3980
  const endpointConfig = getEndpointConfig(endpoint);
3885
- const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
3886
- if (Object.keys(endpointConfig).length === 0) return hasAxiosRequestConfig ? AXIOS_REQUEST_CONFIG_NAME : "";
3981
+ const hasRequestConfigParam = resolver.options.axiosRequestConfig || endpoint.method === "get";
3982
+ const needsBlobConfig = endpoint.mediaDownload || endpoint.response === "z.instanceof(Blob)";
3983
+ if (Object.keys(endpointConfig).length === 0 && !needsBlobConfig) return hasRequestConfigParam ? AXIOS_REQUEST_CONFIG_NAME : "";
3887
3984
  const lines = [];
3888
3985
  lines.push("{");
3889
- if (hasAxiosRequestConfig) lines.push(` ...${AXIOS_REQUEST_CONFIG_NAME},`);
3986
+ if (hasRequestConfigParam) lines.push(` ...${AXIOS_REQUEST_CONFIG_NAME},`);
3890
3987
  if (endpointConfig.params) {
3891
3988
  lines.push(" params: {");
3892
3989
  for (const param of endpointConfig.params) {
@@ -4061,11 +4158,12 @@ function generateQueries(params) {
4061
4158
  const endpointGroups = groupEndpoints(endpoints, resolver);
4062
4159
  const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
4063
4160
  const hasAxiosDefaultImport = endpoints.some(({ mediaUpload }) => mediaUpload);
4064
- const hasAxiosImport = hasAxiosRequestConfig || hasAxiosDefaultImport;
4161
+ const hasGetEndpoints = endpoints.some((endpoint) => endpoint.method === "get");
4162
+ const hasAxiosImport = hasAxiosRequestConfig || hasAxiosDefaultImport || hasGetEndpoints;
4065
4163
  const axiosImport = {
4066
4164
  defaultImport: hasAxiosDefaultImport ? AXIOS_DEFAULT_IMPORT_NAME : void 0,
4067
4165
  bindings: [],
4068
- typeBindings: hasAxiosRequestConfig ? [AXIOS_REQUEST_CONFIG_TYPE] : [],
4166
+ typeBindings: hasAxiosImport ? [AXIOS_REQUEST_CONFIG_TYPE] : [],
4069
4167
  from: AXIOS_IMPORT.from
4070
4168
  };
4071
4169
  const { queryEndpoints, infiniteQueryEndpoints, mutationEndpoints, aclEndpoints } = endpointGroups;
@@ -4096,7 +4194,7 @@ function generateQueries(params) {
4096
4194
  from: ACL_PACKAGE_IMPORT_PATH
4097
4195
  };
4098
4196
  const queryTypesImport = {
4099
- bindings: [...hasMutationDefaultOnError ? ["OpenApiQueryConfig"] : []],
4197
+ bindings: [...queryEndpoints.length > 0 || infiniteQueryEndpoints.length > 0 || hasMutationDefaultOnError ? ["OpenApiQueryConfig"] : []],
4100
4198
  typeBindings: [
4101
4199
  ...queryEndpoints.length > 0 ? [QUERY_OPTIONS_TYPES.query] : [],
4102
4200
  ...resolver.options.infiniteQueries && infiniteQueryEndpoints.length > 0 ? [QUERY_OPTIONS_TYPES.infiniteQuery] : [],
@@ -4335,16 +4433,6 @@ function renderWorkspaceParamResolutions({ replacements, paramTypes, indent }) {
4335
4433
  indent
4336
4434
  })];
4337
4435
  }
4338
- function renderAclCheckCall(resolver, endpoint, replacements, indent = "") {
4339
- const checkParams = getAbilityConditionsTypes(endpoint)?.map((condition) => invalidVariableNameCharactersToCamel(condition.name));
4340
- const paramNames = new Set(endpoint.parameters.map((param) => invalidVariableNameCharactersToCamel(param.name)));
4341
- const hasAllCheckParams = checkParams?.every((param) => paramNames.has(param));
4342
- const args = hasAbilityConditions(endpoint) && hasAllCheckParams ? `{ ${(checkParams ?? []).map((param) => {
4343
- const resolvedParam = replacements?.[param] ?? param;
4344
- return resolvedParam === param ? param : `${param}: ${resolvedParam}`;
4345
- }).join(", ")} } ` : "";
4346
- return `${indent}checkAcl(${getImportedAbilityFunctionName(endpoint, resolver.options)}(${args}));`;
4347
- }
4348
4436
  function addAsteriskAfterNewLine(str) {
4349
4437
  return str.replace(/\n/g, "\n *");
4350
4438
  }
@@ -4399,9 +4487,10 @@ function renderInlineEndpoints({ resolver, endpoints, tag }) {
4399
4487
  const endpointBody = getEndpointBody$1(endpoint);
4400
4488
  const hasUndefinedEndpointBody = requiresBody(endpoint) && !endpointBody && hasEndpointConfig(endpoint, resolver);
4401
4489
  const endpointConfig = renderInlineEndpointConfig(resolver, endpoint, tag);
4402
- lines.push(`const ${getEndpointName(endpoint)} = (${endpointParams}${resolver.options.axiosRequestConfig ? `${AXIOS_REQUEST_CONFIG_NAME}?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => {`);
4490
+ const hasRequestConfigParam = resolver.options.axiosRequestConfig || endpoint.method === "get";
4491
+ lines.push(`const ${getEndpointName(endpoint)} = (${endpointParams}${hasRequestConfigParam ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}?: ${getRequestConfigType()}` : ""}) => {`);
4403
4492
  lines.push(` return ${APP_REST_CLIENT_NAME}.${endpoint.method}(`);
4404
- lines.push(` { resSchema: ${getImportedZodSchemaName(resolver, endpoint.response, tag)} },`);
4493
+ lines.push(` ${renderInlineRequestInfo(resolver, endpoint, tag)},`);
4405
4494
  lines.push(` \`${getEndpointPath(endpoint)}\`,`);
4406
4495
  if (endpointBody) lines.push(` ${resolver.options.parseRequestParams ? renderInlineEndpointParamParse(resolver, endpointBody, endpointBody.name, tag) : endpointBody.name},`);
4407
4496
  else if (hasUndefinedEndpointBody) lines.push(" undefined,");
@@ -4412,19 +4501,35 @@ function renderInlineEndpoints({ resolver, endpoints, tag }) {
4412
4501
  }
4413
4502
  return lines;
4414
4503
  }
4504
+ function renderInlineRequestInfo(resolver, endpoint, tag) {
4505
+ return `{ resSchema: ${getImportedZodSchemaName(resolver, endpoint.response, tag)} }`;
4506
+ }
4507
+ function getRequestConfigType() {
4508
+ return `${AXIOS_REQUEST_CONFIG_TYPE} & { allowInvalidResponseData?: boolean }`;
4509
+ }
4510
+ function renderRequestConfigWithSignal(hasRequestConfigParam) {
4511
+ return `{ ${hasRequestConfigParam ? `...${AXIOS_REQUEST_CONFIG_NAME}, ` : ""}signal }`;
4512
+ }
4415
4513
  function renderInlineEndpointParamParse(resolver, param, paramName, modelNamespaceTag) {
4416
4514
  const addOptional = !(param.parameterObject ?? param.bodyObject)?.required && (Boolean(param.parameterSortingEnumSchemaName) || isNamedZodSchema(param.zodSchema));
4417
- const schemaValue = param.parameterSortingEnumSchemaName ? `${ZOD_EXTENDED.namespace}.${ZOD_EXTENDED.exports.sortExp}(${getImportedZodSchemaName(resolver, param.parameterSortingEnumSchemaName, modelNamespaceTag)})${addOptional ? ".optional()" : ""}` : `${getImportedZodSchemaName(resolver, param.zodSchema, modelNamespaceTag)}${addOptional ? ".optional()" : ""}`;
4515
+ const schemaValue = param.parameterSortingEnumSchemaName ? `${ZOD_EXTENDED.namespace}.${ZOD_EXTENDED.exports.sortExp}(${getImportedZodSchemaName(resolver, param.parameterSortingEnumSchemaName, modelNamespaceTag)})${getSortingPresenceChain(resolver, param)}` : `${getImportedZodSchemaName(resolver, param.zodSchema, modelNamespaceTag)}${addOptional ? ".optional()" : ""}`;
4418
4516
  const queryArgs = param.type === "Query" ? `, { type: "query", name: "${paramName}" }` : "";
4419
4517
  return `${ZOD_EXTENDED.namespace}.${ZOD_EXTENDED.exports.parse}(${schemaValue}, ${paramName}${queryArgs})`;
4420
4518
  }
4519
+ function getSortingPresenceChain(resolver, param) {
4520
+ const zodSchemaCode = resolver.getCodeByZodSchemaName(param.zodSchema) ?? param.zodSchema;
4521
+ if (zodSchemaCode.includes(".nullish()")) return ".nullish()";
4522
+ if (zodSchemaCode.includes(".nullable()")) return ".nullable()";
4523
+ return !(param.parameterObject ?? param.bodyObject)?.required ? ".optional()" : "";
4524
+ }
4421
4525
  function renderInlineEndpointConfig(resolver, endpoint, modelNamespaceTag) {
4422
4526
  const endpointConfig = getEndpointConfig(endpoint);
4423
- const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
4424
- if (Object.keys(endpointConfig).length === 0) return hasAxiosRequestConfig ? AXIOS_REQUEST_CONFIG_NAME : "";
4527
+ const hasRequestConfigParam = resolver.options.axiosRequestConfig || endpoint.method === "get";
4528
+ const needsBlobConfig = endpoint.mediaDownload || endpoint.response === "z.instanceof(Blob)";
4529
+ if (Object.keys(endpointConfig).length === 0 && !needsBlobConfig) return hasRequestConfigParam ? AXIOS_REQUEST_CONFIG_NAME : "";
4425
4530
  const lines = [];
4426
4531
  lines.push("{");
4427
- if (hasAxiosRequestConfig) lines.push(` ...${AXIOS_REQUEST_CONFIG_NAME},`);
4532
+ if (hasRequestConfigParam) lines.push(` ...${AXIOS_REQUEST_CONFIG_NAME},`);
4428
4533
  if (endpointConfig.params) {
4429
4534
  lines.push(" params: {");
4430
4535
  for (const param of endpointConfig.params) {
@@ -4444,19 +4549,20 @@ function renderInlineEndpointConfig(resolver, endpoint, modelNamespaceTag) {
4444
4549
  return lines.join("\n");
4445
4550
  }
4446
4551
  function renderQueryOptions({ resolver, endpoint, inlineEndpoints }) {
4447
- const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
4552
+ const hasRequestConfigParam = resolver.options.axiosRequestConfig || endpoint.method === "get";
4448
4553
  const endpointParams = renderEndpointParams(resolver, endpoint, { modelNamespaceTag: getEndpointTag(endpoint, resolver.options) });
4449
4554
  const endpointArgs = renderEndpointArgs(resolver, endpoint, {});
4450
4555
  const endpointFunction = inlineEndpoints ? getEndpointName(endpoint) : getImportedEndpointName(endpoint, resolver.options);
4451
4556
  const lines = [];
4452
- lines.push(`const ${getQueryOptionsName(endpoint)} = (${endpointParams ? `{ ${endpointArgs} }: { ${endpointParams} }` : ""}${hasAxiosRequestConfig ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => ({`);
4557
+ lines.push(`const ${getQueryOptionsName(endpoint)} = (${endpointParams ? `{ ${endpointArgs} }: { ${endpointParams} }` : ""}${hasRequestConfigParam ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}?: ${getRequestConfigType()}` : ""}) => ({`);
4453
4558
  lines.push(` queryKey: keys.${getEndpointName(endpoint)}(${endpointArgs}),`);
4454
- lines.push(` queryFn: () => ${endpointFunction}(${endpointArgs}${hasAxiosRequestConfig ? `${endpointArgs ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""}),`);
4559
+ const requestConfigWithSignal = renderRequestConfigWithSignal(hasRequestConfigParam);
4560
+ lines.push(` queryFn: ({ signal }: { signal: AbortSignal }) => ${endpointFunction}(${endpointArgs}${hasRequestConfigParam ? `${endpointArgs ? ", " : ""}${requestConfigWithSignal}` : ""}),`);
4455
4561
  lines.push("});");
4456
4562
  return lines.join("\n");
4457
4563
  }
4458
4564
  function renderInfiniteQueryOptions({ resolver, endpoint, inlineEndpoints }) {
4459
- const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
4565
+ const hasRequestConfigParam = resolver.options.axiosRequestConfig || endpoint.method === "get";
4460
4566
  const endpointParams = renderEndpointParams(resolver, endpoint, {
4461
4567
  excludePageParam: true,
4462
4568
  modelNamespaceTag: getEndpointTag(endpoint, resolver.options)
@@ -4465,13 +4571,14 @@ function renderInfiniteQueryOptions({ resolver, endpoint, inlineEndpoints }) {
4465
4571
  const endpointArgsWithPage = renderEndpointArgs(resolver, endpoint, { replacePageParam: true });
4466
4572
  const endpointFunction = inlineEndpoints ? getEndpointName(endpoint) : getImportedEndpointName(endpoint, resolver.options);
4467
4573
  const lines = [];
4468
- lines.push(`const ${getInfiniteQueryOptionsName(endpoint)} = (${endpointParams ? `{ ${endpointArgsWithoutPage} }: { ${endpointParams} }` : ""}${hasAxiosRequestConfig ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => ({`);
4574
+ lines.push(`const ${getInfiniteQueryOptionsName(endpoint)} = (${endpointParams ? `{ ${endpointArgsWithoutPage} }: { ${endpointParams} }` : ""}${hasRequestConfigParam ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}?: ${getRequestConfigType()}` : ""}) => ({`);
4469
4575
  lines.push(` queryKey: keys.${getEndpointName(endpoint)}Infinite(${endpointArgsWithoutPage}),`);
4470
- lines.push(` queryFn: ({ pageParam }: { pageParam: number }) => ${endpointFunction}(${endpointArgsWithPage}${hasAxiosRequestConfig ? `, ${AXIOS_REQUEST_CONFIG_NAME}` : ""}),`);
4576
+ const requestConfigWithSignal = renderRequestConfigWithSignal(hasRequestConfigParam);
4577
+ lines.push(` queryFn: ({ pageParam, signal }: { pageParam: number; signal: AbortSignal }) => ${endpointFunction}(${endpointArgsWithPage}${hasRequestConfigParam ? `, ${requestConfigWithSignal}` : ""}),`);
4471
4578
  lines.push(" initialPageParam: 1,");
4472
4579
  lines.push(` getNextPageParam: ({ ${resolver.options.infiniteQueryResponseParamNames.page}, ${resolver.options.infiniteQueryResponseParamNames.totalItems}, ${resolver.options.infiniteQueryResponseParamNames.limit}: limitParam }: Awaited<ReturnType<typeof ${endpointFunction}>>) => {`);
4473
4580
  lines.push(` const pageParam = ${resolver.options.infiniteQueryResponseParamNames.page} ?? 1;`);
4474
- lines.push(` return pageParam * limitParam < ${resolver.options.infiniteQueryResponseParamNames.totalItems} ? pageParam + 1 : null;`);
4581
+ lines.push(` return pageParam * limitParam < (${resolver.options.infiniteQueryResponseParamNames.totalItems} ?? 0) ? pageParam + 1 : null;`);
4475
4582
  lines.push(" },");
4476
4583
  lines.push("});");
4477
4584
  return lines.join("\n");
@@ -4514,7 +4621,8 @@ function renderQuery({ resolver, endpoint, inlineEndpoints }) {
4514
4621
  });
4515
4622
  const queryOptionsName = getQueryOptionsName(endpoint);
4516
4623
  const hasQueryFnOverride = hasAclCheck;
4517
- const queryOptionsArgs = `${resolvedEndpointArgs ? `{ ${resolvedEndpointArgs} }` : ""}${hasAxiosRequestConfig ? `${resolvedEndpointArgs ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""}`;
4624
+ const requestConfig = `{ ${hasAxiosRequestConfig ? `...${AXIOS_REQUEST_CONFIG_NAME}, ` : ""}allowInvalidResponseData: queryConfig.allowInvalidResponseData }`;
4625
+ const queryOptionsArgs = `${resolvedEndpointArgs ? `{ ${resolvedEndpointArgs} }, ` : ""}${requestConfig}`;
4518
4626
  const lines = [];
4519
4627
  lines.push(renderQueryJsDocs({
4520
4628
  resolver,
@@ -4523,6 +4631,7 @@ function renderQuery({ resolver, endpoint, inlineEndpoints }) {
4523
4631
  tag
4524
4632
  }));
4525
4633
  lines.push(`export const ${getQueryName(endpoint)} = <TData>(${endpointParams ? `{ ${endpointArgs} }: { ${endpointParams} }, ` : ""}options?: AppQueryOptions<typeof ${inlineEndpoints ? getEndpointName(endpoint) : getImportedEndpointName(endpoint, resolver.options)}, TData>${hasAxiosRequestConfig ? `, ${AXIOS_REQUEST_CONFIG_NAME}?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => {`);
4634
+ lines.push(" const queryConfig = OpenApiQueryConfig.useConfig();");
4526
4635
  if (hasAclCheck) lines.push(` const { checkAcl } = ${ACL_CHECK_HOOK}();`);
4527
4636
  lines.push(...renderWorkspaceParamResolutions({
4528
4637
  replacements: workspaceParamReplacements,
@@ -4533,9 +4642,9 @@ function renderQuery({ resolver, endpoint, inlineEndpoints }) {
4533
4642
  lines.push(` return ${QUERY_HOOKS.query}({`);
4534
4643
  lines.push(` ...${queryOptionsName}(${queryOptionsArgs}),`);
4535
4644
  if (hasQueryFnOverride) {
4536
- lines.push(" queryFn: async () => {");
4645
+ lines.push(" queryFn: async ({ signal }: { signal: AbortSignal }) => {");
4537
4646
  if (hasAclCheck) lines.push(renderAclCheckCall(resolver, endpoint, workspaceParamReplacements, " "));
4538
- lines.push(` return ${queryOptionsName}(${queryOptionsArgs}).queryFn();`);
4647
+ lines.push(` return ${queryOptionsName}(${queryOptionsArgs}).queryFn({ signal });`);
4539
4648
  lines.push(" },");
4540
4649
  }
4541
4650
  lines.push(" ...options,");
@@ -4615,34 +4724,12 @@ function renderMutation({ resolver, endpoint, inlineEndpoints, precomputed }) {
4615
4724
  indent: " "
4616
4725
  }));
4617
4726
  if (hasAclCheck) lines.push(renderAclCheckCall(resolver, endpoint, workspaceParamReplacements, " "));
4618
- if (endpoint.mediaUpload) {
4619
- lines.push(` const uploadInstructions = await ${endpointFunction}(${resolvedEndpointArgs}${hasAxiosRequestConfig ? `${resolvedEndpointArgs ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""});`);
4620
- lines.push(" ");
4621
- lines.push(" if (file && uploadInstructions.url) {");
4622
- lines.push(" const method = (data?.method?.toLowerCase() ?? \"put\") as \"put\" | \"post\";");
4623
- lines.push(" let dataToSend: File | FormData = file;");
4624
- lines.push(" if (method === \"post\") {");
4625
- lines.push(" dataToSend = new FormData();");
4626
- lines.push(" if (uploadInstructions.fields) {");
4627
- lines.push(" for (const [key, value] of uploadInstructions.fields) {");
4628
- lines.push(" dataToSend.append(key, value);");
4629
- lines.push(" }");
4630
- lines.push(" }");
4631
- lines.push(" dataToSend.append(\"file\", file);");
4632
- lines.push(" }");
4633
- lines.push(" await axios[method](uploadInstructions.url, dataToSend, {");
4634
- lines.push(" headers: {");
4635
- lines.push(" \"Content-Type\": file.type,");
4636
- lines.push(" },");
4637
- lines.push(" signal: abortController?.signal,");
4638
- lines.push(" onUploadProgress: onUploadProgress");
4639
- lines.push(" ? (progressEvent) => onUploadProgress({ loaded: progressEvent.loaded, total: progressEvent.total ?? 0 })");
4640
- lines.push(" : undefined,");
4641
- lines.push(" });");
4642
- lines.push(" }");
4643
- lines.push(" ");
4644
- lines.push(" return uploadInstructions;");
4645
- } else lines.push(` ${hasMutationFnBody ? "return " : ""}${endpointFunction}(${resolvedEndpointArgs}${hasAxiosRequestConfig ? `${resolvedEndpointArgs ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""})`);
4727
+ if (endpoint.mediaUpload) lines.push(...renderMediaUploadMutationBody({
4728
+ resolver,
4729
+ endpointFunction,
4730
+ resolvedEndpointArgs
4731
+ }).map((line) => ` ${line}`));
4732
+ else lines.push(` ${hasMutationFnBody ? "return " : ""}${endpointFunction}(${resolvedEndpointArgs}${hasAxiosRequestConfig ? `${resolvedEndpointArgs ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""})`);
4646
4733
  if (hasMutationFnBody) lines.push(" },");
4647
4734
  else lines.push(",");
4648
4735
  if (isScoped) {
@@ -4722,7 +4809,8 @@ function renderInfiniteQuery({ resolver, endpoint, inlineEndpoints }) {
4722
4809
  const endpointArgsWithoutPage = renderEndpointArgs(resolver, endpoint, { excludePageParam: true });
4723
4810
  const resolvedEndpointArgsWithoutPage = renderEndpointObjectArgs(resolver, endpoint, { excludePageParam: true }, workspaceParamReplacements);
4724
4811
  const queryOptionsName = getInfiniteQueryOptionsName(endpoint);
4725
- const queryOptionsArgs = `${resolvedEndpointArgsWithoutPage ? `{ ${resolvedEndpointArgsWithoutPage} }` : ""}${hasAxiosRequestConfig ? `${resolvedEndpointArgsWithoutPage ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""}`;
4812
+ const requestConfig = `{ ${hasAxiosRequestConfig ? `...${AXIOS_REQUEST_CONFIG_NAME}, ` : ""}allowInvalidResponseData: queryConfig.allowInvalidResponseData }`;
4813
+ const queryOptionsArgs = `${resolvedEndpointArgsWithoutPage ? `{ ${resolvedEndpointArgsWithoutPage} }, ` : ""}${requestConfig}`;
4726
4814
  const hasQueryFnOverride = hasAclCheck;
4727
4815
  const lines = [];
4728
4816
  lines.push(renderQueryJsDocs({
@@ -4732,6 +4820,7 @@ function renderInfiniteQuery({ resolver, endpoint, inlineEndpoints }) {
4732
4820
  tag
4733
4821
  }));
4734
4822
  lines.push(`export const ${getInfiniteQueryName(endpoint)} = <TData>(${endpointParams ? `{ ${endpointArgsWithoutPage} }: { ${endpointParams} }, ` : ""}options?: AppInfiniteQueryOptions<typeof ${inlineEndpoints ? getEndpointName(endpoint) : getImportedEndpointName(endpoint, resolver.options)}, TData>${hasAxiosRequestConfig ? `, ${AXIOS_REQUEST_CONFIG_NAME}?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => {`);
4823
+ lines.push(" const queryConfig = OpenApiQueryConfig.useConfig();");
4735
4824
  if (hasAclCheck) lines.push(` const { checkAcl } = ${ACL_CHECK_HOOK}();`);
4736
4825
  lines.push(...renderWorkspaceParamResolutions({
4737
4826
  replacements: workspaceParamReplacements,
@@ -4742,9 +4831,9 @@ function renderInfiniteQuery({ resolver, endpoint, inlineEndpoints }) {
4742
4831
  lines.push(` return ${QUERY_HOOKS.infiniteQuery}({`);
4743
4832
  lines.push(` ...${queryOptionsName}(${queryOptionsArgs}),`);
4744
4833
  if (hasQueryFnOverride) {
4745
- lines.push(" queryFn: async ({ pageParam }) => {");
4834
+ lines.push(" queryFn: async ({ pageParam, signal }: { pageParam: number; signal: AbortSignal }) => {");
4746
4835
  lines.push(renderAclCheckCall(resolver, endpoint, workspaceParamReplacements, " "));
4747
- lines.push(` return ${queryOptionsName}(${queryOptionsArgs}).queryFn({ pageParam });`);
4836
+ lines.push(` return ${queryOptionsName}(${queryOptionsArgs}).queryFn({ pageParam, signal });`);
4748
4837
  lines.push(" },");
4749
4838
  }
4750
4839
  lines.push(" ...options,");
@@ -4771,6 +4860,7 @@ export const ${APP_REST_CLIENT_NAME} = new RestClient({
4771
4860
  function domainToPascalCase(domain) {
4772
4861
  return domain.split(/[-_]/).map(capitalize).join("");
4773
4862
  }
4863
+ const VALID_IDENTIFIER = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
4774
4864
  function generateDomainErrors({ data }) {
4775
4865
  const byDomain = /* @__PURE__ */ new Map();
4776
4866
  for (const { endpoints } of data.values()) for (const endpoint of endpoints) for (const error of endpoint.errors) {
@@ -4788,8 +4878,16 @@ function generateDomainErrors({ data }) {
4788
4878
  const blocks = [];
4789
4879
  for (const [domain, codes] of [...byDomain.entries()].sort(([a], [b]) => a.localeCompare(b))) {
4790
4880
  const pascalName = domainToPascalCase(domain);
4791
- const entries = [...codes.values()].sort((a, b) => a.code - b.code).map(({ code, name, description }) => {
4792
- return `${description ? ` /** ${description} */\n ` : " "}${name ?? `ERROR_${code}`}: ${code}`;
4881
+ const entries = [...codes.values()].sort((a, b) => {
4882
+ if (typeof a.code === "number" && typeof b.code === "number") return a.code - b.code;
4883
+ const sa = String(a.code);
4884
+ const sb = String(b.code);
4885
+ return sa < sb ? -1 : sa > sb ? 1 : 0;
4886
+ }).map(({ code, name, description }) => {
4887
+ const comment = description ? ` /** ${description} */\n ` : " ";
4888
+ const key = name ?? (typeof code === "string" ? code : `ERROR_${code}`);
4889
+ if (!VALID_IDENTIFIER.test(key)) throw new Error(`Domain error code "${code}" produces an invalid identifier "${key}". Use the 'name' field on @ApiDomainErrorResponse to provide a valid identifier.`);
4890
+ return `${comment}${key}: ${typeof code === "string" ? `"${code}"` : String(code)}`;
4793
4891
  }).join(",\n");
4794
4892
  blocks.push(`export const ${pascalName}DomainErrors = {\n${entries},\n} as const;`);
4795
4893
  blocks.push(`export type ${pascalName}DomainErrorCode = (typeof ${pascalName}DomainErrors)[keyof typeof ${pascalName}DomainErrors];`);