@povio/openapi-codegen-cli 3.0.0-rc.9 → 3.1.0-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,32 @@ 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
+ }
4415
4510
  function renderInlineEndpointParamParse(resolver, param, paramName, modelNamespaceTag) {
4416
4511
  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()" : ""}`;
4512
+ 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
4513
  const queryArgs = param.type === "Query" ? `, { type: "query", name: "${paramName}" }` : "";
4419
4514
  return `${ZOD_EXTENDED.namespace}.${ZOD_EXTENDED.exports.parse}(${schemaValue}, ${paramName}${queryArgs})`;
4420
4515
  }
4516
+ function getSortingPresenceChain(resolver, param) {
4517
+ const zodSchemaCode = resolver.getCodeByZodSchemaName(param.zodSchema) ?? param.zodSchema;
4518
+ if (zodSchemaCode.includes(".nullish()")) return ".nullish()";
4519
+ if (zodSchemaCode.includes(".nullable()")) return ".nullable()";
4520
+ return !(param.parameterObject ?? param.bodyObject)?.required ? ".optional()" : "";
4521
+ }
4421
4522
  function renderInlineEndpointConfig(resolver, endpoint, modelNamespaceTag) {
4422
4523
  const endpointConfig = getEndpointConfig(endpoint);
4423
- const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
4424
- if (Object.keys(endpointConfig).length === 0) return hasAxiosRequestConfig ? AXIOS_REQUEST_CONFIG_NAME : "";
4524
+ const hasRequestConfigParam = resolver.options.axiosRequestConfig || endpoint.method === "get";
4525
+ const needsBlobConfig = endpoint.mediaDownload || endpoint.response === "z.instanceof(Blob)";
4526
+ if (Object.keys(endpointConfig).length === 0 && !needsBlobConfig) return hasRequestConfigParam ? AXIOS_REQUEST_CONFIG_NAME : "";
4425
4527
  const lines = [];
4426
4528
  lines.push("{");
4427
- if (hasAxiosRequestConfig) lines.push(` ...${AXIOS_REQUEST_CONFIG_NAME},`);
4529
+ if (hasRequestConfigParam) lines.push(` ...${AXIOS_REQUEST_CONFIG_NAME},`);
4428
4530
  if (endpointConfig.params) {
4429
4531
  lines.push(" params: {");
4430
4532
  for (const param of endpointConfig.params) {
@@ -4444,19 +4546,19 @@ function renderInlineEndpointConfig(resolver, endpoint, modelNamespaceTag) {
4444
4546
  return lines.join("\n");
4445
4547
  }
4446
4548
  function renderQueryOptions({ resolver, endpoint, inlineEndpoints }) {
4447
- const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
4549
+ const hasRequestConfigParam = resolver.options.axiosRequestConfig || endpoint.method === "get";
4448
4550
  const endpointParams = renderEndpointParams(resolver, endpoint, { modelNamespaceTag: getEndpointTag(endpoint, resolver.options) });
4449
4551
  const endpointArgs = renderEndpointArgs(resolver, endpoint, {});
4450
4552
  const endpointFunction = inlineEndpoints ? getEndpointName(endpoint) : getImportedEndpointName(endpoint, resolver.options);
4451
4553
  const lines = [];
4452
- lines.push(`const ${getQueryOptionsName(endpoint)} = (${endpointParams ? `{ ${endpointArgs} }: { ${endpointParams} }` : ""}${hasAxiosRequestConfig ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => ({`);
4554
+ lines.push(`const ${getQueryOptionsName(endpoint)} = (${endpointParams ? `{ ${endpointArgs} }: { ${endpointParams} }` : ""}${hasRequestConfigParam ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}?: ${getRequestConfigType()}` : ""}) => ({`);
4453
4555
  lines.push(` queryKey: keys.${getEndpointName(endpoint)}(${endpointArgs}),`);
4454
- lines.push(` queryFn: () => ${endpointFunction}(${endpointArgs}${hasAxiosRequestConfig ? `${endpointArgs ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""}),`);
4556
+ lines.push(` queryFn: () => ${endpointFunction}(${endpointArgs}${hasRequestConfigParam ? `${endpointArgs ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""}),`);
4455
4557
  lines.push("});");
4456
4558
  return lines.join("\n");
4457
4559
  }
4458
4560
  function renderInfiniteQueryOptions({ resolver, endpoint, inlineEndpoints }) {
4459
- const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
4561
+ const hasRequestConfigParam = resolver.options.axiosRequestConfig || endpoint.method === "get";
4460
4562
  const endpointParams = renderEndpointParams(resolver, endpoint, {
4461
4563
  excludePageParam: true,
4462
4564
  modelNamespaceTag: getEndpointTag(endpoint, resolver.options)
@@ -4465,13 +4567,13 @@ function renderInfiniteQueryOptions({ resolver, endpoint, inlineEndpoints }) {
4465
4567
  const endpointArgsWithPage = renderEndpointArgs(resolver, endpoint, { replacePageParam: true });
4466
4568
  const endpointFunction = inlineEndpoints ? getEndpointName(endpoint) : getImportedEndpointName(endpoint, resolver.options);
4467
4569
  const lines = [];
4468
- lines.push(`const ${getInfiniteQueryOptionsName(endpoint)} = (${endpointParams ? `{ ${endpointArgsWithoutPage} }: { ${endpointParams} }` : ""}${hasAxiosRequestConfig ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => ({`);
4570
+ lines.push(`const ${getInfiniteQueryOptionsName(endpoint)} = (${endpointParams ? `{ ${endpointArgsWithoutPage} }: { ${endpointParams} }` : ""}${hasRequestConfigParam ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}?: ${getRequestConfigType()}` : ""}) => ({`);
4469
4571
  lines.push(` queryKey: keys.${getEndpointName(endpoint)}Infinite(${endpointArgsWithoutPage}),`);
4470
- lines.push(` queryFn: ({ pageParam }: { pageParam: number }) => ${endpointFunction}(${endpointArgsWithPage}${hasAxiosRequestConfig ? `, ${AXIOS_REQUEST_CONFIG_NAME}` : ""}),`);
4572
+ lines.push(` queryFn: ({ pageParam }: { pageParam: number }) => ${endpointFunction}(${endpointArgsWithPage}${hasRequestConfigParam ? `, ${AXIOS_REQUEST_CONFIG_NAME}` : ""}),`);
4471
4573
  lines.push(" initialPageParam: 1,");
4472
4574
  lines.push(` getNextPageParam: ({ ${resolver.options.infiniteQueryResponseParamNames.page}, ${resolver.options.infiniteQueryResponseParamNames.totalItems}, ${resolver.options.infiniteQueryResponseParamNames.limit}: limitParam }: Awaited<ReturnType<typeof ${endpointFunction}>>) => {`);
4473
4575
  lines.push(` const pageParam = ${resolver.options.infiniteQueryResponseParamNames.page} ?? 1;`);
4474
- lines.push(` return pageParam * limitParam < ${resolver.options.infiniteQueryResponseParamNames.totalItems} ? pageParam + 1 : null;`);
4576
+ lines.push(` return pageParam * limitParam < (${resolver.options.infiniteQueryResponseParamNames.totalItems} ?? 0) ? pageParam + 1 : null;`);
4475
4577
  lines.push(" },");
4476
4578
  lines.push("});");
4477
4579
  return lines.join("\n");
@@ -4514,7 +4616,8 @@ function renderQuery({ resolver, endpoint, inlineEndpoints }) {
4514
4616
  });
4515
4617
  const queryOptionsName = getQueryOptionsName(endpoint);
4516
4618
  const hasQueryFnOverride = hasAclCheck;
4517
- const queryOptionsArgs = `${resolvedEndpointArgs ? `{ ${resolvedEndpointArgs} }` : ""}${hasAxiosRequestConfig ? `${resolvedEndpointArgs ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""}`;
4619
+ const requestConfig = `{ ${hasAxiosRequestConfig ? `...${AXIOS_REQUEST_CONFIG_NAME}, ` : ""}allowInvalidResponseData: queryConfig.allowInvalidResponseData }`;
4620
+ const queryOptionsArgs = `${resolvedEndpointArgs ? `{ ${resolvedEndpointArgs} }, ` : ""}${requestConfig}`;
4518
4621
  const lines = [];
4519
4622
  lines.push(renderQueryJsDocs({
4520
4623
  resolver,
@@ -4523,6 +4626,7 @@ function renderQuery({ resolver, endpoint, inlineEndpoints }) {
4523
4626
  tag
4524
4627
  }));
4525
4628
  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}` : ""}) => {`);
4629
+ lines.push(" const queryConfig = OpenApiQueryConfig.useConfig();");
4526
4630
  if (hasAclCheck) lines.push(` const { checkAcl } = ${ACL_CHECK_HOOK}();`);
4527
4631
  lines.push(...renderWorkspaceParamResolutions({
4528
4632
  replacements: workspaceParamReplacements,
@@ -4615,34 +4719,12 @@ function renderMutation({ resolver, endpoint, inlineEndpoints, precomputed }) {
4615
4719
  indent: " "
4616
4720
  }));
4617
4721
  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}` : ""})`);
4722
+ if (endpoint.mediaUpload) lines.push(...renderMediaUploadMutationBody({
4723
+ resolver,
4724
+ endpointFunction,
4725
+ resolvedEndpointArgs
4726
+ }).map((line) => ` ${line}`));
4727
+ else lines.push(` ${hasMutationFnBody ? "return " : ""}${endpointFunction}(${resolvedEndpointArgs}${hasAxiosRequestConfig ? `${resolvedEndpointArgs ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""})`);
4646
4728
  if (hasMutationFnBody) lines.push(" },");
4647
4729
  else lines.push(",");
4648
4730
  if (isScoped) {
@@ -4722,7 +4804,8 @@ function renderInfiniteQuery({ resolver, endpoint, inlineEndpoints }) {
4722
4804
  const endpointArgsWithoutPage = renderEndpointArgs(resolver, endpoint, { excludePageParam: true });
4723
4805
  const resolvedEndpointArgsWithoutPage = renderEndpointObjectArgs(resolver, endpoint, { excludePageParam: true }, workspaceParamReplacements);
4724
4806
  const queryOptionsName = getInfiniteQueryOptionsName(endpoint);
4725
- const queryOptionsArgs = `${resolvedEndpointArgsWithoutPage ? `{ ${resolvedEndpointArgsWithoutPage} }` : ""}${hasAxiosRequestConfig ? `${resolvedEndpointArgsWithoutPage ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""}`;
4807
+ const requestConfig = `{ ${hasAxiosRequestConfig ? `...${AXIOS_REQUEST_CONFIG_NAME}, ` : ""}allowInvalidResponseData: queryConfig.allowInvalidResponseData }`;
4808
+ const queryOptionsArgs = `${resolvedEndpointArgsWithoutPage ? `{ ${resolvedEndpointArgsWithoutPage} }, ` : ""}${requestConfig}`;
4726
4809
  const hasQueryFnOverride = hasAclCheck;
4727
4810
  const lines = [];
4728
4811
  lines.push(renderQueryJsDocs({
@@ -4732,6 +4815,7 @@ function renderInfiniteQuery({ resolver, endpoint, inlineEndpoints }) {
4732
4815
  tag
4733
4816
  }));
4734
4817
  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}` : ""}) => {`);
4818
+ lines.push(" const queryConfig = OpenApiQueryConfig.useConfig();");
4735
4819
  if (hasAclCheck) lines.push(` const { checkAcl } = ${ACL_CHECK_HOOK}();`);
4736
4820
  lines.push(...renderWorkspaceParamResolutions({
4737
4821
  replacements: workspaceParamReplacements,
@@ -4771,6 +4855,7 @@ export const ${APP_REST_CLIENT_NAME} = new RestClient({
4771
4855
  function domainToPascalCase(domain) {
4772
4856
  return domain.split(/[-_]/).map(capitalize).join("");
4773
4857
  }
4858
+ const VALID_IDENTIFIER = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
4774
4859
  function generateDomainErrors({ data }) {
4775
4860
  const byDomain = /* @__PURE__ */ new Map();
4776
4861
  for (const { endpoints } of data.values()) for (const endpoint of endpoints) for (const error of endpoint.errors) {
@@ -4788,8 +4873,16 @@ function generateDomainErrors({ data }) {
4788
4873
  const blocks = [];
4789
4874
  for (const [domain, codes] of [...byDomain.entries()].sort(([a], [b]) => a.localeCompare(b))) {
4790
4875
  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}`;
4876
+ const entries = [...codes.values()].sort((a, b) => {
4877
+ if (typeof a.code === "number" && typeof b.code === "number") return a.code - b.code;
4878
+ const sa = String(a.code);
4879
+ const sb = String(b.code);
4880
+ return sa < sb ? -1 : sa > sb ? 1 : 0;
4881
+ }).map(({ code, name, description }) => {
4882
+ const comment = description ? ` /** ${description} */\n ` : " ";
4883
+ const key = name ?? (typeof code === "string" ? code : `ERROR_${code}`);
4884
+ 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.`);
4885
+ return `${comment}${key}: ${typeof code === "string" ? `"${code}"` : String(code)}`;
4793
4886
  }).join(",\n");
4794
4887
  blocks.push(`export const ${pascalName}DomainErrors = {\n${entries},\n} as const;`);
4795
4888
  blocks.push(`export type ${pascalName}DomainErrorCode = (typeof ${pascalName}DomainErrors)[keyof typeof ${pascalName}DomainErrors];`);