@povio/openapi-codegen-cli 3.0.0-rc.1 → 3.0.0-rc.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -92,7 +92,10 @@ yarn openapi-codegen generate --config my-config.ts
92
92
  --axiosRequestConfig Include Axios request config parameters in query hooks (default: false)
93
93
  --infiniteQueries Generate infinite queries for paginated API endpoints (default: false)
94
94
  --mutationEffects Add mutation effects options to mutation hooks (default: true)
95
- --mutationScope Serialize mutations for the same path-param resource via TanStack scope.id (default: false)
95
+ --mutationScope Serialize mutations for the same path-param resource via TanStack scope.id (default: false).
96
+ In config files also accepts { include: string[] } or { exclude: string[] } to opt specific
97
+ operations in/out of scoping. Use "Tag/operationId" format for precision (e.g. "EmployeeSettings/update")
98
+ or just "operationId" to match across all tags. Cannot specify both include and exclude.
96
99
  --mutationDefaultOnError Use OpenApiQueryConfig.onError as the default onError for mutation hooks (default: false)
97
100
  --workspaceContext Comma-separated list of path/ACL params that generated hooks may resolve from OpenApiWorkspaceContext
98
101
  --inlineEndpoints Inline endpoint implementations into generated query files (default: false)
package/dist/acl.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as ErrorHandler } from "./error-handling-CvW_FecB.mjs";
1
+ import { a as ErrorHandler } from "./error-handling-B4aYKmyL.mjs";
2
2
  import * as react from "react";
3
3
  import { PropsWithChildren } from "react";
4
4
  import * as react_jsx_runtime0 from "react/jsx-runtime";
package/dist/acl.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { r as SharedErrorHandler } from "./error-handling-DkPY7Asf.mjs";
1
+ import { i as SharedErrorHandler } from "./error-handling-nneQaE1_.mjs";
2
2
  import { n as OpenApiRouter, t as AuthContext } from "./auth.context-Bu5KW2sI.mjs";
3
3
  import { createContext, useCallback, useEffect, useState } from "react";
4
4
  import { jsx } from "react/jsx-runtime";
@@ -1,4 +1,4 @@
1
- import { t as GenerateOptions } from "./options-C6CNQ6tq.mjs";
1
+ import { t as GenerateOptions } from "./options-BPAjzilp.mjs";
2
2
 
3
3
  //#region src/generators/types/config.d.ts
4
4
  type OpenAPICodegenConfig = Partial<GenerateOptions>;
@@ -12,13 +12,28 @@ interface ErrorEntry<CodeT> {
12
12
  condition?: (error: unknown) => boolean;
13
13
  getMessage: (t: TFunction<string, undefined>, error: unknown) => string;
14
14
  }
15
- interface ErrorHandlerOptions<CodeT extends string> {
15
+ interface DomainErrorEntry {
16
+ code: string | number;
17
+ condition?: (error: unknown) => boolean;
18
+ getMessage: (t: TFunction<string, undefined>, error: unknown) => string;
19
+ }
20
+ declare class DomainErrorRegistry {
21
+ private static readonly entries;
22
+ static register(entry: DomainErrorEntry): void;
23
+ static register(entries: DomainErrorEntry[]): void;
24
+ static unregister(code: string | number): void;
25
+ static clear(): void;
26
+ static getEntry(code: string | number): DomainErrorEntry | undefined;
27
+ }
28
+ interface ErrorHandlerOptions<CodeT extends string | number> {
16
29
  entries: ErrorEntry<CodeT>[];
17
30
  t?: TFunction<string, undefined>;
18
31
  onRethrowError?: (error: unknown, exception: ApplicationException<CodeT | GeneralErrorCodes>) => void;
19
32
  }
20
- declare class ErrorHandler<CodeT extends string> {
33
+ declare class ErrorHandler<CodeT extends string | number> {
21
34
  entries: ErrorEntry<CodeT | GeneralErrorCodes>[];
35
+ private readonly userEntries;
36
+ private readonly generalEntries;
22
37
  private t;
23
38
  private onRethrowError?;
24
39
  constructor({
@@ -35,4 +50,4 @@ declare class ErrorHandler<CodeT extends string> {
35
50
  }
36
51
  declare const SharedErrorHandler: ErrorHandler<never>;
37
52
  //#endregion
38
- export { GeneralErrorCodes as a, ErrorHandlerOptions as i, ErrorEntry as n, SharedErrorHandler as o, ErrorHandler as r, ApplicationException as t };
53
+ export { ErrorHandler as a, SharedErrorHandler as c, ErrorEntry as i, DomainErrorEntry as n, ErrorHandlerOptions as o, DomainErrorRegistry as r, GeneralErrorCodes as s, ApplicationException as t };
@@ -53,6 +53,7 @@ let RestUtils;
53
53
  if (!e.response) return null;
54
54
  const data = e.response.data;
55
55
  if (typeof data?.code === "string") return data.code;
56
+ if (typeof data?.code === "number") return data.code;
56
57
  return null;
57
58
  };
58
59
  _RestUtils.doesServerErrorMessageContain = (e, text) => {
@@ -85,8 +86,26 @@ var ApplicationException = class extends Error {
85
86
  this.serverMessage = serverMessage;
86
87
  }
87
88
  };
89
+ var DomainErrorRegistry = class {
90
+ static entries = /* @__PURE__ */ new Map();
91
+ static register(entryOrEntries) {
92
+ const items = Array.isArray(entryOrEntries) ? entryOrEntries : [entryOrEntries];
93
+ for (const item of items) this.entries.set(item.code, item);
94
+ }
95
+ static unregister(code) {
96
+ this.entries.delete(code);
97
+ }
98
+ static clear() {
99
+ this.entries.clear();
100
+ }
101
+ static getEntry(code) {
102
+ return this.entries.get(code);
103
+ }
104
+ };
88
105
  var ErrorHandler = class {
89
106
  entries = [];
107
+ userEntries;
108
+ generalEntries;
90
109
  t;
91
110
  onRethrowError;
92
111
  constructor({ entries, t = defaultT, onRethrowError }) {
@@ -138,14 +157,15 @@ var ErrorHandler = class {
138
157
  return this.t("openapi.sharedErrors.unknownError");
139
158
  }
140
159
  };
141
- this.entries = [
142
- ...entries,
160
+ this.userEntries = [...entries];
161
+ this.generalEntries = [
143
162
  dataValidationError,
144
163
  internalError,
145
164
  networkError,
146
165
  canceledError,
147
166
  unknownError
148
167
  ];
168
+ this.entries = [...this.userEntries, ...this.generalEntries];
149
169
  }
150
170
  matchesEntry(error, entry, code) {
151
171
  if (entry.condition) return entry.condition(error);
@@ -156,9 +176,23 @@ var ErrorHandler = class {
156
176
  }
157
177
  rethrowError(error) {
158
178
  const code = RestUtils.extractServerResponseCode(error);
159
- const errorEntry = this.entries.find((entry) => this.matchesEntry(error, entry, code));
160
179
  const serverMessage = RestUtils.extractServerErrorMessage(error);
161
- const exception = new ApplicationException(errorEntry.getMessage(this.t, error), errorEntry.code, serverMessage);
180
+ const userEntry = this.userEntries.find((entry) => this.matchesEntry(error, entry, code));
181
+ if (userEntry) {
182
+ const exception = new ApplicationException(userEntry.getMessage(this.t, error), userEntry.code, serverMessage);
183
+ this.onRethrowError?.(error, exception);
184
+ throw exception;
185
+ }
186
+ if (code !== null) {
187
+ const registryEntry = DomainErrorRegistry.getEntry(code);
188
+ if (registryEntry && (!registryEntry.condition || registryEntry.condition(error))) {
189
+ const exception = new ApplicationException(registryEntry.getMessage(this.t, error), registryEntry.code, serverMessage);
190
+ this.onRethrowError?.(error, exception);
191
+ throw exception;
192
+ }
193
+ }
194
+ const generalEntry = this.generalEntries.find((entry) => this.matchesEntry(error, entry, code));
195
+ const exception = new ApplicationException(generalEntry.getMessage(this.t, error), generalEntry.code, serverMessage);
162
196
  this.onRethrowError?.(error, exception);
163
197
  throw exception;
164
198
  }
@@ -184,4 +218,4 @@ var ErrorHandler = class {
184
218
  const SharedErrorHandler = new ErrorHandler({ entries: [] });
185
219
 
186
220
  //#endregion
187
- export { ns as a, RestUtils as i, ErrorHandler as n, resources as o, SharedErrorHandler as r, ApplicationException as t };
221
+ export { RestUtils as a, SharedErrorHandler as i, DomainErrorRegistry as n, ns as o, ErrorHandler as r, resources as s, ApplicationException as t };
@@ -1,4 +1,4 @@
1
- import { S as Profiler, h as deepMerge, i as writeGenerateFileData, p as DEFAULT_GENERATE_OPTIONS, r as removeStaleGeneratedFiles, t as generateCodeFromOpenAPIDoc } from "./generateCodeFromOpenAPIDoc-BKIXvJIW.mjs";
1
+ import { S as Profiler, h as deepMerge, i as writeGenerateFileData, p as DEFAULT_GENERATE_OPTIONS, r as removeStaleGeneratedFiles, t as generateCodeFromOpenAPIDoc } from "./generateCodeFromOpenAPIDoc-mALUMd3q.mjs";
2
2
  import path from "path";
3
3
  import SwaggerParser from "@apidevtools/swagger-parser";
4
4
 
@@ -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);
@@ -915,6 +926,10 @@ const APP_REST_CLIENT_FILE = {
915
926
  fileName: "app-rest-client",
916
927
  extension: "ts"
917
928
  };
929
+ const DOMAIN_ERRORS_FILE = {
930
+ fileName: "domain-errors",
931
+ extension: "ts"
932
+ };
918
933
  const QUERY_OPTIONS_TYPES = {
919
934
  query: "AppQueryOptions",
920
935
  infiniteQuery: "AppInfiniteQueryOptions",
@@ -1393,96 +1408,6 @@ const DEFAULT_GENERATE_OPTIONS = {
1393
1408
  //#region src/generators/utils/array.utils.ts
1394
1409
  const getUniqueArray = (...arrs) => [...new Set(arrs.flat())];
1395
1410
 
1396
- //#endregion
1397
- //#region src/generators/utils/generate/generate.acl.utils.ts
1398
- const getAbilityFunctionName = (endpoint) => `canUse${capitalize(snakeToCamel(endpoint.operationName))}`;
1399
- const getImportedAbilityFunctionName = (endpoint, options) => {
1400
- return `${options.tsNamespaces ? `${getNamespaceName({
1401
- type: GenerateType.Acl,
1402
- tag: getEndpointTag(endpoint, options),
1403
- options
1404
- })}.` : ""}${getAbilityFunctionName(endpoint)}`;
1405
- };
1406
- const getAbilityAction = (endpoint) => endpoint.acl?.[0].action;
1407
- const getAbilitySubject = (endpoint) => endpoint.acl?.[0].subject;
1408
- const hasAbilityConditions = (endpoint) => !!getAbilityConditionsTypes(endpoint)?.length;
1409
- const getAbilityConditionsTypes = (endpoint) => endpoint.acl?.[0].conditionsTypes?.sort((a, b) => a.name.localeCompare(b.name));
1410
- const getAbilityDescription = (endpoint) => endpoint.acl?.[0]?.description;
1411
- const getAbilitySubjectTypes = (endpoint) => {
1412
- const abilitySubject = getAbilitySubject(endpoint);
1413
- const types = [`"${abilitySubject ?? ""}"`];
1414
- if (hasAbilityConditions(endpoint)) types.push(`ForcedSubject<"${abilitySubject}"> & { ${getAbilityConditionsTypes(endpoint)?.map((conditionType) => `${conditionType.name}${conditionType.required ? "" : "?"}: ${conditionType.type ?? ""}${conditionType.zodSchemaName ?? ""},`).join(" ")} }`);
1415
- return types;
1416
- };
1417
- function getAclData({ resolver, data, tag }) {
1418
- const endpoints = data.get(tag)?.endpoints.filter(({ acl }) => acl && acl.length > 0);
1419
- if (!endpoints || endpoints.length === 0) return;
1420
- return {
1421
- endpoints,
1422
- hasAdditionalAbilityImports: endpoints.some(({ acl }) => acl?.[0].conditions && Object.keys(acl[0].conditions).length > 0),
1423
- modelsImports: getModelsImports({
1424
- resolver,
1425
- tag,
1426
- zodSchemasAsTypes: getUniqueArray(endpoints.reduce((acc, endpoint) => {
1427
- const zodSchemas = endpoint.acl?.[0].conditionsTypes?.reduce((acc, propertyType) => [...acc, ...propertyType?.zodSchemaName ? [propertyType.zodSchemaName] : []], []);
1428
- return [...acc, ...zodSchemas ?? []];
1429
- }, []))
1430
- })
1431
- };
1432
- }
1433
- const getAppAbilitiesType = ({ resolver, data }) => {
1434
- const appAbilitiesTypeMap = /* @__PURE__ */ new Map();
1435
- const modelsImportsArr = [];
1436
- let hasAdditionalAbilityImports = false;
1437
- data.forEach((_, tag) => {
1438
- const aclData = getAclData({
1439
- resolver,
1440
- data,
1441
- tag
1442
- });
1443
- if (!aclData) return;
1444
- const { modelsImports: tagModelsImports, hasAdditionalAbilityImports: tagHasAdditionalAbilityImports, endpoints } = aclData;
1445
- modelsImportsArr.push(tagModelsImports);
1446
- hasAdditionalAbilityImports = hasAdditionalAbilityImports || tagHasAdditionalAbilityImports;
1447
- endpoints.forEach((endpoint) => {
1448
- const abilityAction = getAbilityAction(endpoint);
1449
- if (abilityAction) appAbilitiesTypeMap.set(abilityAction, new Set([...appAbilitiesTypeMap.get(abilityAction) ?? [], ...getAbilitySubjectTypes(endpoint)]));
1450
- });
1451
- });
1452
- const modelsImports = mergeImports(resolver.options, ...modelsImportsArr);
1453
- return {
1454
- appAbilitiesType: appAbilitiesTypeMap.size > 0 ? Object.fromEntries(Array.from(appAbilitiesTypeMap.entries()).map(([key, valueSet]) => [key, Array.from(valueSet)])) : void 0,
1455
- modelsImports,
1456
- hasAdditionalAbilityImports
1457
- };
1458
- };
1459
-
1460
- //#endregion
1461
- //#region src/generators/utils/generate/generate.query.utils.ts
1462
- const getQueryName = (endpoint, mutation) => {
1463
- const addMutationSuffix = isQuery(endpoint) && isMutation(endpoint) && mutation;
1464
- return `use${capitalize(snakeToCamel(endpoint.operationName))}${addMutationSuffix ? "Mutation" : ""}`;
1465
- };
1466
- const getInfiniteQueryName = (endpoint) => `use${capitalize(snakeToCamel(endpoint.operationName))}Infinite`;
1467
- const getQueryOptionsName = (endpoint) => `${snakeToCamel(endpoint.operationName)}QueryOptions`;
1468
- const getInfiniteQueryOptionsName = (endpoint) => `${snakeToCamel(endpoint.operationName)}InfiniteQueryOptions`;
1469
- const getPrefetchQueryName = (endpoint) => `prefetch${capitalize(snakeToCamel(endpoint.operationName))}`;
1470
- const getPrefetchInfiniteQueryName = (endpoint) => `prefetch${capitalize(snakeToCamel(endpoint.operationName))}Infinite`;
1471
- const getImportedQueryName = (endpoint, options) => {
1472
- return `${options.tsNamespaces ? `${getNamespaceName({
1473
- type: GenerateType.Queries,
1474
- tag: getEndpointTag(endpoint, options),
1475
- options
1476
- })}.` : ""}${getQueryName(endpoint)}`;
1477
- };
1478
- const getImportedInfiniteQueryName = (endpoint, options) => {
1479
- return `${options.tsNamespaces ? `${getNamespaceName({
1480
- type: GenerateType.Queries,
1481
- tag: getEndpointTag(endpoint, options),
1482
- options
1483
- })}.` : ""}${getInfiniteQueryName(endpoint)}`;
1484
- };
1485
-
1486
1411
  //#endregion
1487
1412
  //#region src/generators/core/openapi/iterateSchema.ts
1488
1413
  function iterateSchema(schema, options) {
@@ -1651,6 +1576,101 @@ function getZodSchemaPropertyDescriptions(resolver, data, tag) {
1651
1576
  return properties;
1652
1577
  }
1653
1578
 
1579
+ //#endregion
1580
+ //#region src/generators/utils/generate/generate.acl.utils.ts
1581
+ const getAbilityFunctionName = (endpoint) => `canUse${capitalize(snakeToCamel(endpoint.operationName))}`;
1582
+ const getImportedAbilityFunctionName = (endpoint, options) => {
1583
+ return `${options.tsNamespaces ? `${getNamespaceName({
1584
+ type: GenerateType.Acl,
1585
+ tag: getEndpointTag(endpoint, options),
1586
+ options
1587
+ })}.` : ""}${getAbilityFunctionName(endpoint)}`;
1588
+ };
1589
+ const getAbilityAction = (endpoint) => endpoint.acl?.[0].action;
1590
+ const getAbilitySubject = (endpoint) => endpoint.acl?.[0].subject;
1591
+ const hasAbilityConditions = (endpoint) => !!getAbilityConditionsTypes(endpoint)?.length;
1592
+ const getAbilityConditionsTypes = (endpoint) => endpoint.acl?.[0].conditionsTypes?.sort((a, b) => a.name.localeCompare(b.name));
1593
+ const getAbilityDescription = (endpoint) => endpoint.acl?.[0]?.description;
1594
+ const getAbilitySubjectTypes = (endpoint, resolver, tag) => {
1595
+ const abilitySubject = getAbilitySubject(endpoint);
1596
+ const types = [`"${abilitySubject ?? ""}"`];
1597
+ if (hasAbilityConditions(endpoint)) types.push(`ForcedSubject<"${abilitySubject}"> & { ${getAbilityConditionsTypes(endpoint)?.map((conditionType) => `${conditionType.name}${conditionType.required ? "" : "?"}: ${getAbilityConditionType(conditionType, resolver, tag)},`).join(" ")} }`);
1598
+ return types;
1599
+ };
1600
+ function getAbilityConditionType(conditionType, resolver, tag) {
1601
+ if (!conditionType.zodSchemaName) return conditionType.type ?? "";
1602
+ if (!resolver) return `${conditionType.type ?? ""}${conditionType.zodSchemaName}`;
1603
+ return getImportedZodSchemaInferedTypeName(resolver, conditionType.zodSchemaName, tag, tag);
1604
+ }
1605
+ function getAclData({ resolver, data, tag }) {
1606
+ const endpoints = data.get(tag)?.endpoints.filter(({ acl }) => acl && acl.length > 0);
1607
+ if (!endpoints || endpoints.length === 0) return;
1608
+ return {
1609
+ endpoints,
1610
+ hasAdditionalAbilityImports: endpoints.some(({ acl }) => acl?.[0].conditions && Object.keys(acl[0].conditions).length > 0),
1611
+ modelsImports: getModelsImports({
1612
+ resolver,
1613
+ tag,
1614
+ zodSchemasAsTypes: getUniqueArray(endpoints.reduce((acc, endpoint) => {
1615
+ const zodSchemas = endpoint.acl?.[0].conditionsTypes?.reduce((acc, propertyType) => [...acc, ...propertyType?.zodSchemaName ? [propertyType.zodSchemaName] : []], []);
1616
+ return [...acc, ...zodSchemas ?? []];
1617
+ }, []))
1618
+ })
1619
+ };
1620
+ }
1621
+ const getAppAbilitiesType = ({ resolver, data }) => {
1622
+ const appAbilitiesTypeMap = /* @__PURE__ */ new Map();
1623
+ const modelsImportsArr = [];
1624
+ let hasAdditionalAbilityImports = false;
1625
+ data.forEach((_, tag) => {
1626
+ const aclData = getAclData({
1627
+ resolver,
1628
+ data,
1629
+ tag
1630
+ });
1631
+ if (!aclData) return;
1632
+ const { modelsImports: tagModelsImports, hasAdditionalAbilityImports: tagHasAdditionalAbilityImports, endpoints } = aclData;
1633
+ modelsImportsArr.push(tagModelsImports);
1634
+ hasAdditionalAbilityImports = hasAdditionalAbilityImports || tagHasAdditionalAbilityImports;
1635
+ endpoints.forEach((endpoint) => {
1636
+ const abilityAction = getAbilityAction(endpoint);
1637
+ if (abilityAction) appAbilitiesTypeMap.set(abilityAction, new Set([...appAbilitiesTypeMap.get(abilityAction) ?? [], ...getAbilitySubjectTypes(endpoint, resolver, tag)]));
1638
+ });
1639
+ });
1640
+ const modelsImports = mergeImports(resolver.options, ...modelsImportsArr);
1641
+ return {
1642
+ appAbilitiesType: appAbilitiesTypeMap.size > 0 ? Object.fromEntries(Array.from(appAbilitiesTypeMap.entries()).map(([key, valueSet]) => [key, Array.from(valueSet)])) : void 0,
1643
+ modelsImports,
1644
+ hasAdditionalAbilityImports
1645
+ };
1646
+ };
1647
+
1648
+ //#endregion
1649
+ //#region src/generators/utils/generate/generate.query.utils.ts
1650
+ const getQueryName = (endpoint, mutation) => {
1651
+ const addMutationSuffix = isQuery(endpoint) && isMutation(endpoint) && mutation;
1652
+ return `use${capitalize(snakeToCamel(endpoint.operationName))}${addMutationSuffix ? "Mutation" : ""}`;
1653
+ };
1654
+ const getInfiniteQueryName = (endpoint) => `use${capitalize(snakeToCamel(endpoint.operationName))}Infinite`;
1655
+ const getQueryOptionsName = (endpoint) => `${snakeToCamel(endpoint.operationName)}QueryOptions`;
1656
+ const getInfiniteQueryOptionsName = (endpoint) => `${snakeToCamel(endpoint.operationName)}InfiniteQueryOptions`;
1657
+ const getPrefetchQueryName = (endpoint) => `prefetch${capitalize(snakeToCamel(endpoint.operationName))}`;
1658
+ const getPrefetchInfiniteQueryName = (endpoint) => `prefetch${capitalize(snakeToCamel(endpoint.operationName))}Infinite`;
1659
+ const getImportedQueryName = (endpoint, options) => {
1660
+ return `${options.tsNamespaces ? `${getNamespaceName({
1661
+ type: GenerateType.Queries,
1662
+ tag: getEndpointTag(endpoint, options),
1663
+ options
1664
+ })}.` : ""}${getQueryName(endpoint)}`;
1665
+ };
1666
+ const getImportedInfiniteQueryName = (endpoint, options) => {
1667
+ return `${options.tsNamespaces ? `${getNamespaceName({
1668
+ type: GenerateType.Queries,
1669
+ tag: getEndpointTag(endpoint, options),
1670
+ options
1671
+ })}.` : ""}${getInfiniteQueryName(endpoint)}`;
1672
+ };
1673
+
1654
1674
  //#endregion
1655
1675
  //#region src/generators/utils/generate/generate.imports.utils.ts
1656
1676
  function getModelsImports({ resolver, tag, zodSchemas = [], zodSchemasAsTypes = [] }) {
@@ -2092,7 +2112,9 @@ function getEndpointAclConditionPropertyType({ resolver, endpoint, acl, name })
2092
2112
  const matchingMediaType = Object.keys(bodyParameter?.bodyObject?.content ?? {}).find(isParamMediaTypeAllowed);
2093
2113
  if (matchingMediaType) {
2094
2114
  schema = bodyParameter?.bodyObject?.content?.[matchingMediaType]?.schema;
2115
+ required = bodyParameter?.bodyObject?.required;
2095
2116
  info = `${isQuery(endpoint) ? "query" : "mutation"} data`;
2117
+ if (pathSplits[index]?.startsWith("$")) index++;
2096
2118
  }
2097
2119
  }
2098
2120
  while (schema && index < pathSplits.length) {
@@ -2167,13 +2189,16 @@ function resolveEndpointZodSchema({ resolver, schema, meta, tag, fallbackName, c
2167
2189
  fallbackName,
2168
2190
  resolver,
2169
2191
  tag
2170
- }) : `${resolveZodSchemaName({
2171
- schema: schemaObject,
2172
- zodSchema,
2173
- fallbackName,
2174
- resolver,
2175
- tag
2176
- })}${zodChain}`;
2192
+ }) : (() => {
2193
+ const name = resolveZodSchemaName({
2194
+ schema: schemaObject,
2195
+ zodSchema,
2196
+ fallbackName,
2197
+ resolver,
2198
+ tag
2199
+ });
2200
+ return isNamedZodSchema(name) ? name : name + zodChain;
2201
+ })();
2177
2202
  entries.set(metaKey, resolved);
2178
2203
  return resolved;
2179
2204
  }
@@ -2224,9 +2249,9 @@ function getEndpointParameter({ resolver, param, operationName, isUniqueOperatio
2224
2249
  if (resolver.options.withDescription && schema) schema.description = (paramObj.description ?? "").trim();
2225
2250
  const fallbackName = getParamZodSchemaName(getZodSchemaOperationName(operationName, isUniqueOperationName, tag), paramObj.name);
2226
2251
  let parameterSortingEnumSchemaName = void 0;
2227
- if (isSortingParameterObject(paramObj)) {
2252
+ if (isSortingParameterObject(paramObj, schema, resolver)) {
2228
2253
  const enumZodSchemaName = getEnumZodSchemaName(fallbackName, resolver.options.enumSuffix, resolver.options.schemaSuffix);
2229
- const code = getEnumZodSchemaCodeFromEnumNames(paramObj["x-enumNames"]);
2254
+ const code = getEnumZodSchemaCodeFromEnumNames(getParameterEnumNames(paramObj, schema) ?? []);
2230
2255
  resolver.setZodSchema(enumZodSchemaName, code, tag);
2231
2256
  parameterSortingEnumSchemaName = enumZodSchemaName;
2232
2257
  }
@@ -2379,11 +2404,23 @@ function getEndpointsFromOpenAPIDoc(resolver) {
2379
2404
  endpoint.response = responseZodSchema;
2380
2405
  endpoint.responseObject = responseObj;
2381
2406
  endpoint.responseDescription = responseObj?.description;
2382
- } else if (statusCode !== "default" && !Number.isNaN(status) && isErrorStatus(status)) endpoint.errors.push({
2383
- zodSchema: responseZodSchema,
2384
- status,
2385
- description: responseObj?.description
2386
- });
2407
+ } else if (statusCode !== "default" && !Number.isNaN(status) && isErrorStatus(status)) {
2408
+ const rawSchema = schemaObject;
2409
+ const domainStr = rawSchema["x-domain-error-domain"];
2410
+ const domainName = rawSchema["x-domain-error-name"];
2411
+ const codeEnumArr = ((rawSchema?.properties)?.code)?.enum;
2412
+ const domainCode = Array.isArray(codeEnumArr) && codeEnumArr.length === 1 && typeof codeEnumArr[0] === "number" ? codeEnumArr[0] : void 0;
2413
+ endpoint.errors.push({
2414
+ zodSchema: responseZodSchema,
2415
+ status,
2416
+ description: responseObj?.description,
2417
+ ...typeof domainStr === "string" && domainCode !== void 0 ? { domainError: {
2418
+ domain: domainStr,
2419
+ code: domainCode,
2420
+ ...typeof domainName === "string" ? { name: domainName } : {}
2421
+ } } : {}
2422
+ });
2423
+ }
2387
2424
  } else {
2388
2425
  const status = Number(statusCode);
2389
2426
  const responseZodSchema = VOID_SCHEMA;
@@ -2579,6 +2616,7 @@ function resolveExtractedEnumZodSchemaTags(resolver) {
2579
2616
  //#endregion
2580
2617
  //#region src/generators/core/zod/enumExtraction/updateExtractedEnumZodSchemaData.ts
2581
2618
  function updateExtractedEnumZodSchemaData({ schema, nameSegments = [], includeSelf, ...params }) {
2619
+ if (!isReferenceObject(schema) && schema?.["x-domain-error-domain"]) return;
2582
2620
  if (includeSelf) handleExtractedEnumZodSchemaDataUpdate({
2583
2621
  schema,
2584
2622
  nameSegments,
@@ -3048,7 +3086,7 @@ function sortZodSchemasByTopology(resolver, zodSchemas) {
3048
3086
  function getDataFromOpenAPIDoc(openApiDoc, options, profiler) {
3049
3087
  const p = profiler ?? new Profiler(false);
3050
3088
  const resolver = p.runSync("data.resolver.init", () => new SchemaResolver(openApiDoc, options, p));
3051
- const endpoints = p.runSync("data.endpoints.extract", () => getEndpointsFromOpenAPIDoc(resolver, p));
3089
+ const endpoints = p.runSync("data.endpoints.extract", () => getEndpointsFromOpenAPIDoc(resolver));
3052
3090
  const zodSchemasFromDocSchemas = p.runSync("data.zod.extract", () => getZodSchemasFromOpenAPIDoc(resolver, p));
3053
3091
  let zodSchemas = {
3054
3092
  ...zodSchemasFromDocSchemas.zodSchemas,
@@ -3261,9 +3299,9 @@ function renderWorkspaceAclHook({ resolver, endpoint }) {
3261
3299
  const objectRequired = abilityConditionsTypes.some((propertyType) => propertyType.required && !workspaceConditionNameSet.has(propertyType.name));
3262
3300
  const objectParams = abilityConditionsTypes.map((propertyType) => {
3263
3301
  const isWorkspaceCondition = workspaceConditionNameSet.has(propertyType.name);
3264
- return `${propertyType.name}${propertyType.required && !isWorkspaceCondition ? "" : "?"}: ${(propertyType.type ?? "") + (propertyType.zodSchemaName ?? "")}, `;
3302
+ return `${propertyType.name}${propertyType.required && !isWorkspaceCondition ? "" : "?"}: ${renderConditionType(resolver, endpoint, propertyType)}, `;
3265
3303
  }).join("");
3266
- const contextType = abilityConditionsTypes.filter((propertyType) => workspaceConditionNameSet.has(propertyType.name)).map((propertyType) => `${propertyType.name}?: ${(propertyType.type ?? "") + (propertyType.zodSchemaName ?? "")}`).join("; ");
3304
+ const contextType = abilityConditionsTypes.filter((propertyType) => workspaceConditionNameSet.has(propertyType.name)).map((propertyType) => `${propertyType.name}?: ${renderConditionType(resolver, endpoint, propertyType)}`).join("; ");
3267
3305
  const contextBindings = workspaceConditionNames.map((name) => `${name}: ${name}Workspace`).join(", ");
3268
3306
  const lines = [];
3269
3307
  lines.push(`export const use${capitalize(getAbilityFunctionName(endpoint))} = (`);
@@ -3289,15 +3327,15 @@ function renderAbilityFunction({ resolver, endpoint }) {
3289
3327
  lines.push("/**");
3290
3328
  lines.push(` * Use for ${abilityQuery} ability. ${hasConditions ? "For global ability, omit the object parameter." : ""}${getAbilityDescription(endpoint) ? "" : ""}`);
3291
3329
  if (getAbilityDescription(endpoint)) lines.push(` * @description ${getAbilityDescription(endpoint)}`);
3292
- if (hasConditions) for (const propertyType of abilityConditionsTypes) lines.push(` * @param { ${(propertyType.type ?? "") + (propertyType.zodSchemaName ?? "")} } object.${propertyType.name} ${propertyType.name} from ${propertyType.info}`);
3330
+ if (hasConditions) for (const propertyType of abilityConditionsTypes) lines.push(` * @param { ${renderConditionType(resolver, endpoint, propertyType)} } object.${propertyType.name} ${propertyType.name} from ${propertyType.info}`);
3293
3331
  lines.push(` * @returns { AbilityTuple } An ability tuple indicating the user's ability to use ${abilityQuery}`);
3294
3332
  lines.push(" */");
3295
3333
  lines.push(`export const ${getAbilityFunctionName(endpoint)} = (`);
3296
- if (hasConditions) lines.push(` object?: { ${abilityConditionsTypes.map((propertyType) => `${propertyType.name}${propertyType.required ? "" : "?"}: ${(propertyType.type ?? "") + (propertyType.zodSchemaName ?? "")}, `).join("")} } `);
3334
+ if (hasConditions) lines.push(` object?: { ${abilityConditionsTypes.map((propertyType) => `${propertyType.name}${propertyType.required ? "" : "?"}: ${renderConditionType(resolver, endpoint, propertyType)}, `).join("")} } `);
3297
3335
  lines.push(") => [");
3298
3336
  lines.push(` "${getAbilityAction(endpoint)}",`);
3299
3337
  lines.push(` ${hasConditions ? `object ? subject("${getAbilitySubject(endpoint)}", object) : "${getAbilitySubject(endpoint)}"` : `"${getAbilitySubject(endpoint)}"`}`);
3300
- lines.push(`] as ${CASL_ABILITY_BINDING.abilityTuple}<"${getAbilityAction(endpoint)}", ${getAbilitySubjectTypes(endpoint).join(" | ")}>;`);
3338
+ lines.push(`] as ${CASL_ABILITY_BINDING.abilityTuple}<"${getAbilityAction(endpoint)}", ${getAbilitySubjectTypes(endpoint, resolver, getEndpointTag(endpoint, resolver.options)).join(" | ")}>;`);
3301
3339
  const workspaceAclHook = renderWorkspaceAclHook({
3302
3340
  resolver,
3303
3341
  endpoint
@@ -3308,6 +3346,9 @@ function renderAbilityFunction({ resolver, endpoint }) {
3308
3346
  }
3309
3347
  return lines.join("\n");
3310
3348
  }
3349
+ function renderConditionType(resolver, endpoint, propertyType) {
3350
+ return getAbilityConditionType(propertyType, resolver, getEndpointTag(endpoint, resolver.options));
3351
+ }
3311
3352
 
3312
3353
  //#endregion
3313
3354
  //#region src/generators/const/buildConfigs.const.ts
@@ -3520,7 +3561,7 @@ function getColumnsConfig(resolver, endpoint) {
3520
3561
  ...acc,
3521
3562
  [key]: true
3522
3563
  }), {});
3523
- const sortableEnumSchemaName = endpoint.parameters.find((param) => param.parameterObject && isSortingParameterObject(param.parameterObject))?.parameterSortingEnumSchemaName;
3564
+ const sortableEnumSchemaName = endpoint.parameters.find((param) => param.parameterSortingEnumSchemaName)?.parameterSortingEnumSchemaName;
3524
3565
  return {
3525
3566
  columns: {
3526
3567
  schema: getImportedZodSchemaName(resolver, zodSchema),
@@ -3835,7 +3876,7 @@ function generateEndpoints({ resolver, data, tag }) {
3835
3876
  const endpointConfig = renderEndpointConfig(resolver, endpoint, tag);
3836
3877
  lines.push(`export const ${getEndpointName(endpoint)} = (${endpointParams}${hasAxiosRequestConfig ? `${AXIOS_REQUEST_CONFIG_NAME}?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => {`);
3837
3878
  lines.push(` return ${APP_REST_CLIENT_NAME}.${endpoint.method}(`);
3838
- lines.push(` { resSchema: ${getImportedZodSchemaName(resolver, endpoint.response, tag)} },`);
3879
+ lines.push(` { resSchema: ${getImportedZodSchemaName(resolver, endpoint.response, resolver.options.modelsInCommon && resolver.options.splitByTags ? tag : void 0)} },`);
3839
3880
  lines.push(` \`${getEndpointPath(endpoint)}\`,`);
3840
3881
  if (endpointBody) lines.push(` ${generateParse ? renderEndpointParamParse(resolver, endpointBody, endpointBody.name, tag) : endpointBody.name},`);
3841
3882
  else if (hasUndefinedEndpointBody) lines.push(" undefined,");
@@ -3859,10 +3900,16 @@ function renderEndpointArgs$1(resolver, endpoint, options) {
3859
3900
  }
3860
3901
  function renderEndpointParamParse(resolver, param, paramName, modelNamespaceTag) {
3861
3902
  const addOptional = !(param.parameterObject ?? param.bodyObject)?.required && (Boolean(param.parameterSortingEnumSchemaName) || isNamedZodSchema(param.zodSchema));
3862
- 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()" : ""}`;
3903
+ 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()" : ""}`;
3863
3904
  const queryArgs = param.type === "Query" ? `, { type: "query", name: "${paramName}" }` : "";
3864
3905
  return `${ZOD_EXTENDED.namespace}.${ZOD_EXTENDED.exports.parse}(${schemaValue}, ${paramName}${queryArgs})`;
3865
3906
  }
3907
+ function getSortingPresenceChain$1(resolver, param) {
3908
+ const zodSchemaCode = resolver.getCodeByZodSchemaName(param.zodSchema) ?? param.zodSchema;
3909
+ if (zodSchemaCode.includes(".nullish()")) return ".nullish()";
3910
+ if (zodSchemaCode.includes(".nullable()")) return ".nullable()";
3911
+ return !(param.parameterObject ?? param.bodyObject)?.required ? ".optional()" : "";
3912
+ }
3866
3913
  function renderEndpointConfig(resolver, endpoint, modelNamespaceTag) {
3867
3914
  const endpointConfig = getEndpointConfig(endpoint);
3868
3915
  const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
@@ -4034,6 +4081,10 @@ function renderModelJsDocs({ name, zodSchema, tag, resolver }) {
4034
4081
  const endpointParamMappingCache = /* @__PURE__ */ new WeakMap();
4035
4082
  function generateQueries(params) {
4036
4083
  const { resolver, data, tag } = params;
4084
+ const mutationScopeOption = resolver.options.mutationScope;
4085
+ if (mutationScopeOption && typeof mutationScopeOption === "object") {
4086
+ if ("include" in mutationScopeOption && "exclude" in mutationScopeOption) throw new Error("mutationScope cannot specify both 'include' and 'exclude'");
4087
+ }
4037
4088
  const inlineEndpoints = shouldInlineEndpointsForTag(tag, resolver.options);
4038
4089
  const endpoints = data.get(tag)?.endpoints;
4039
4090
  if (!endpoints || endpoints.length === 0) return;
@@ -4393,10 +4444,16 @@ function renderInlineEndpoints({ resolver, endpoints, tag }) {
4393
4444
  }
4394
4445
  function renderInlineEndpointParamParse(resolver, param, paramName, modelNamespaceTag) {
4395
4446
  const addOptional = !(param.parameterObject ?? param.bodyObject)?.required && (Boolean(param.parameterSortingEnumSchemaName) || isNamedZodSchema(param.zodSchema));
4396
- 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()" : ""}`;
4447
+ 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()" : ""}`;
4397
4448
  const queryArgs = param.type === "Query" ? `, { type: "query", name: "${paramName}" }` : "";
4398
4449
  return `${ZOD_EXTENDED.namespace}.${ZOD_EXTENDED.exports.parse}(${schemaValue}, ${paramName}${queryArgs})`;
4399
4450
  }
4451
+ function getSortingPresenceChain(resolver, param) {
4452
+ const zodSchemaCode = resolver.getCodeByZodSchemaName(param.zodSchema) ?? param.zodSchema;
4453
+ if (zodSchemaCode.includes(".nullish()")) return ".nullish()";
4454
+ if (zodSchemaCode.includes(".nullable()")) return ".nullable()";
4455
+ return !(param.parameterObject ?? param.bodyObject)?.required ? ".optional()" : "";
4456
+ }
4400
4457
  function renderInlineEndpointConfig(resolver, endpoint, modelNamespaceTag) {
4401
4458
  const endpointConfig = getEndpointConfig(endpoint);
4402
4459
  const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
@@ -4448,7 +4505,7 @@ function renderInfiniteQueryOptions({ resolver, endpoint, inlineEndpoints }) {
4448
4505
  lines.push(` queryKey: keys.${getEndpointName(endpoint)}Infinite(${endpointArgsWithoutPage}),`);
4449
4506
  lines.push(` queryFn: ({ pageParam }: { pageParam: number }) => ${endpointFunction}(${endpointArgsWithPage}${hasAxiosRequestConfig ? `, ${AXIOS_REQUEST_CONFIG_NAME}` : ""}),`);
4450
4507
  lines.push(" initialPageParam: 1,");
4451
- lines.push(` getNextPageParam: ({ ${resolver.options.infiniteQueryResponseParamNames.page}, ${resolver.options.infiniteQueryResponseParamNames.totalItems}, ${resolver.options.infiniteQueryResponseParamNames.limit}: limitParam }) => {`);
4508
+ lines.push(` getNextPageParam: ({ ${resolver.options.infiniteQueryResponseParamNames.page}, ${resolver.options.infiniteQueryResponseParamNames.totalItems}, ${resolver.options.infiniteQueryResponseParamNames.limit}: limitParam }: Awaited<ReturnType<typeof ${endpointFunction}>>) => {`);
4452
4509
  lines.push(` const pageParam = ${resolver.options.infiniteQueryResponseParamNames.page} ?? 1;`);
4453
4510
  lines.push(` return pageParam * limitParam < ${resolver.options.infiniteQueryResponseParamNames.totalItems} ? pageParam + 1 : null;`);
4454
4511
  lines.push(" },");
@@ -4472,9 +4529,10 @@ function renderPrefetchInfiniteQuery({ resolver, endpoint }) {
4472
4529
  modelNamespaceTag: getEndpointTag(endpoint, resolver.options)
4473
4530
  });
4474
4531
  const endpointArgs = renderEndpointArgs(resolver, endpoint, { excludePageParam: true });
4532
+ const optionsArgs = `${endpointParams ? `{ ${endpointArgs} }` : ""}${hasAxiosRequestConfig ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""}`;
4475
4533
  const lines = [];
4476
4534
  lines.push(`export const ${getPrefetchInfiniteQueryName(endpoint)} = (queryClient: QueryClient, ${endpointParams ? `{ ${endpointArgs} }: { ${endpointParams} }, ` : ""}${hasAxiosRequestConfig ? `${AXIOS_REQUEST_CONFIG_NAME}: ${AXIOS_REQUEST_CONFIG_TYPE}, ` : ""}options?: Omit<Parameters<QueryClient["prefetchInfiniteQuery"]>[0], "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam">): void => {`);
4477
- lines.push(` void queryClient.prefetchInfiniteQuery({ ...${getInfiniteQueryOptionsName(endpoint)}(${endpointParams ? `{ ${endpointArgs} }` : ""}${hasAxiosRequestConfig ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""}), ...options });`);
4535
+ lines.push(` void queryClient.prefetchInfiniteQuery({ ...${getInfiniteQueryOptionsName(endpoint)}(${optionsArgs}), ...(options as {}) });`);
4478
4536
  lines.push("};");
4479
4537
  return lines.join("\n");
4480
4538
  }
@@ -4541,6 +4599,27 @@ function renderMutation({ resolver, endpoint, inlineEndpoints, precomputed }) {
4541
4599
  const destructuredVariables = precomputed?.destructuredVariables ?? getDestructuredVariables(resolver, endpoint, updateQueryEndpoints);
4542
4600
  const hasMutationFnBody = endpoint.mediaUpload || hasAclCheck || Object.keys(workspaceParamReplacements).length > 0;
4543
4601
  const mutationVariablesType = endpoint.mediaUpload ? `${endpointParams}${endpointParams ? "; " : ""}abortController?: AbortController; onUploadProgress?: (progress: { loaded: number; total: number }) => void` : endpointParams;
4602
+ const isPost = endpoint.method === "post";
4603
+ const mutationScopeOption = resolver.options.mutationScope;
4604
+ const operationId = getEndpointName(endpoint);
4605
+ const scopeMatchKey = `${tag}/${operationId}`;
4606
+ let scopeEnabled = false;
4607
+ if (!isPost && mutationScopeOption) {
4608
+ if (mutationScopeOption === true) scopeEnabled = true;
4609
+ else if (typeof mutationScopeOption === "object" && "include" in mutationScopeOption) scopeEnabled = mutationScopeOption.include.some((id) => id === operationId || id === scopeMatchKey);
4610
+ else if (typeof mutationScopeOption === "object" && "exclude" in mutationScopeOption) scopeEnabled = !mutationScopeOption.exclude.some((id) => id === operationId || id === scopeMatchKey);
4611
+ }
4612
+ const scopePathParams = scopeEnabled ? mapEndpointParamsToFunctionParams(resolver, endpoint, {}).filter((p) => p.paramType === "Path") : [];
4613
+ const isScoped = scopePathParams.length > 0;
4614
+ const nonPathEndpointParams = isScoped ? renderEndpointParams(resolver, endpoint, {
4615
+ includeFileParam: true,
4616
+ optionalPathParams: resolver.options.workspaceContext,
4617
+ modelNamespaceTag: tag,
4618
+ excludePathParams: true
4619
+ }) : endpointParams;
4620
+ const nonPathMutationVariablesType = isScoped ? endpoint.mediaUpload ? `${nonPathEndpointParams}${nonPathEndpointParams ? "; " : ""}abortController?: AbortController; onUploadProgress?: (progress: { loaded: number; total: number }) => void` : nonPathEndpointParams : mutationVariablesType;
4621
+ const pathParamFirstArg = isScoped ? `{ ${scopePathParams.map((p) => p.name).join(", ")} }: { ${scopePathParams.map((p) => `${p.name}: ${p.type}`).join("; ")} }, ` : "";
4622
+ const mutationOptionsTypeArg = isScoped ? nonPathMutationVariablesType ? `, { ${nonPathMutationVariablesType} }` : "" : `, { ${mutationVariablesType} }`;
4544
4623
  const lines = [];
4545
4624
  lines.push(renderQueryJsDocs({
4546
4625
  resolver,
@@ -4548,7 +4627,7 @@ function renderMutation({ resolver, endpoint, inlineEndpoints, precomputed }) {
4548
4627
  mode: "mutation",
4549
4628
  tag
4550
4629
  }));
4551
- lines.push(`export const ${getQueryName(endpoint, true)} = (options?: AppMutationOptions<typeof ${endpointFunction}, { ${mutationVariablesType} }>${hasMutationEffects ? ` & ${MUTATION_EFFECTS.optionsType}` : ""}${hasAxiosRequestConfig ? `, ${AXIOS_REQUEST_CONFIG_NAME}?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => {`);
4630
+ lines.push(`export const ${getQueryName(endpoint, true)} = (${pathParamFirstArg}options?: AppMutationOptions<typeof ${endpointFunction}${mutationOptionsTypeArg}>${hasMutationEffects ? ` & ${MUTATION_EFFECTS.optionsType}` : ""}${hasAxiosRequestConfig ? `, ${AXIOS_REQUEST_CONFIG_NAME}?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => {`);
4552
4631
  if (hasMutationDefaultOnError) lines.push(" const queryConfig = OpenApiQueryConfig.useConfig();");
4553
4632
  if (hasAclCheck) lines.push(` const { checkAcl } = ${ACL_CHECK_HOOK}();`);
4554
4633
  lines.push(...renderWorkspaceContextDestructure({
@@ -4556,10 +4635,16 @@ function renderMutation({ resolver, endpoint, inlineEndpoints, precomputed }) {
4556
4635
  paramTypes: workspaceParamTypes,
4557
4636
  indent: " "
4558
4637
  }));
4559
- if (hasMutationEffects) lines.push(` const { runMutationEffects } = useMutationEffects<typeof ${QUERY_MODULE_ENUM}.${tag}>({ currentModule: ${QUERIES_MODULE_NAME} });`);
4638
+ if (hasMutationEffects) lines.push(` const { runMutationEffects } = useMutationEffects<${QUERY_MODULE_ENUM}.${tag}>({ currentModule: ${QUERIES_MODULE_NAME} });`);
4560
4639
  lines.push("");
4561
4640
  lines.push(` return ${QUERY_HOOKS.mutation}({`);
4562
- const mutationFnArg = endpointParams ? `{ ${destructuredMutationArgs}${endpoint.mediaUpload ? `${destructuredMutationArgs ? ", " : ""}abortController, onUploadProgress` : ""} }` : "";
4641
+ const nonPathDestructuredArgs = isScoped ? renderEndpointArgs(resolver, endpoint, {
4642
+ includeFileParam: true,
4643
+ excludePathParams: true
4644
+ }) : destructuredMutationArgs;
4645
+ const effectiveParams = isScoped ? nonPathEndpointParams : endpointParams;
4646
+ const effectiveArgs = isScoped ? nonPathDestructuredArgs : destructuredMutationArgs;
4647
+ const mutationFnArg = effectiveParams || endpoint.mediaUpload ? `{ ${effectiveArgs}${endpoint.mediaUpload ? `${effectiveArgs ? ", " : ""}abortController, onUploadProgress` : ""} }` : "";
4563
4648
  lines.push(` mutationFn: ${endpoint.mediaUpload ? "async " : ""}(${mutationFnArg}) => ${hasMutationFnBody ? "{ " : ""}`);
4564
4649
  lines.push(...renderWorkspaceParamCoalescing({
4565
4650
  replacements: workspaceParamReplacements,
@@ -4596,12 +4681,18 @@ function renderMutation({ resolver, endpoint, inlineEndpoints, precomputed }) {
4596
4681
  } else lines.push(` ${hasMutationFnBody ? "return " : ""}${endpointFunction}(${resolvedEndpointArgs}${hasAxiosRequestConfig ? `${resolvedEndpointArgs ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""})`);
4597
4682
  if (hasMutationFnBody) lines.push(" },");
4598
4683
  else lines.push(",");
4684
+ if (isScoped) {
4685
+ const scopePathParamInterpolations = scopePathParams.map((p) => `:\${${p.name}}`).join("");
4686
+ lines.push(` scope: { id: \`${getEndpointName(endpoint)}${scopePathParamInterpolations}\` },`);
4687
+ }
4599
4688
  lines.push(" ...options,");
4600
4689
  if (hasMutationDefaultOnError) lines.push(" onError: options?.onError ?? queryConfig.onError,");
4601
4690
  if (hasMutationEffects) {
4602
4691
  lines.push(" onSuccess: async (resData, variables, onMutateResult, context) => {");
4603
4692
  if (updateQueryEndpoints.length > 0) {
4604
- if (destructuredVariables.length > 0) lines.push(` const { ${destructuredVariables.join(", ")} } = variables;`);
4693
+ const scopedPathParamNames = new Set(scopePathParams.map((p) => p.name));
4694
+ const variablesDestructure = destructuredVariables.filter((v) => !scopedPathParamNames.has(v));
4695
+ if (variablesDestructure.length > 0) lines.push(` const { ${variablesDestructure.join(", ")} } = variables;`);
4605
4696
  lines.push(...renderWorkspaceParamCoalescing({
4606
4697
  replacements: workspaceParamReplacements,
4607
4698
  indent: " "
@@ -4711,6 +4802,37 @@ export const ${APP_REST_CLIENT_NAME} = new RestClient({
4711
4802
  `;
4712
4803
  }
4713
4804
 
4805
+ //#endregion
4806
+ //#region src/generators/generate/generateDomainErrors.ts
4807
+ function domainToPascalCase(domain) {
4808
+ return domain.split(/[-_]/).map(capitalize).join("");
4809
+ }
4810
+ function generateDomainErrors({ data }) {
4811
+ const byDomain = /* @__PURE__ */ new Map();
4812
+ for (const { endpoints } of data.values()) for (const endpoint of endpoints) for (const error of endpoint.errors) {
4813
+ if (!error.domainError) continue;
4814
+ const { domain, code } = error.domainError;
4815
+ if (!byDomain.has(domain)) byDomain.set(domain, /* @__PURE__ */ new Map());
4816
+ const domainMap = byDomain.get(domain);
4817
+ if (!domainMap.has(code)) domainMap.set(code, {
4818
+ code,
4819
+ name: error.domainError.name,
4820
+ description: error.description
4821
+ });
4822
+ }
4823
+ if (byDomain.size === 0) return void 0;
4824
+ const blocks = [];
4825
+ for (const [domain, codes] of [...byDomain.entries()].sort(([a], [b]) => a.localeCompare(b))) {
4826
+ const pascalName = domainToPascalCase(domain);
4827
+ const entries = [...codes.values()].sort((a, b) => a.code - b.code).map(({ code, name, description }) => {
4828
+ return `${description ? ` /** ${description} */\n ` : " "}${name ?? `ERROR_${code}`}: ${code}`;
4829
+ }).join(",\n");
4830
+ blocks.push(`export const ${pascalName}DomainErrors = {\n${entries},\n} as const;`);
4831
+ blocks.push(`export type ${pascalName}DomainErrorCode = (typeof ${pascalName}DomainErrors)[keyof typeof ${pascalName}DomainErrors];`);
4832
+ }
4833
+ return blocks.join("\n\n") + "\n";
4834
+ }
4835
+
4714
4836
  //#endregion
4715
4837
  //#region src/generators/generate/generateQueryModules.ts
4716
4838
  function generateQueryModules({ resolver, data }) {
@@ -4765,6 +4887,20 @@ function getMutationEffectsFiles(data, resolver) {
4765
4887
  function getZodExtendedFiles(_data, _resolver) {
4766
4888
  return [];
4767
4889
  }
4890
+ function getDomainErrorsFiles(data, resolver) {
4891
+ const content = generateDomainErrors({
4892
+ resolver,
4893
+ data
4894
+ });
4895
+ if (!content) return [];
4896
+ return [{
4897
+ fileName: getOutputFileName({
4898
+ output: resolver.options.output,
4899
+ fileName: getFileNameWithExtension(DOMAIN_ERRORS_FILE)
4900
+ }),
4901
+ content
4902
+ }];
4903
+ }
4768
4904
  function getAppRestClientFiles(resolver) {
4769
4905
  if (resolver.options.restClientImportPath !== DEFAULT_GENERATE_OPTIONS.restClientImportPath) return [];
4770
4906
  return [{
@@ -4827,7 +4963,7 @@ function generateCodeFromOpenAPIDoc(openApiDoc, options, profiler) {
4827
4963
  }
4828
4964
  });
4829
4965
  });
4830
- if (!modelsOnly) generateFilesData.push(...p.runSync("render.AclShared", () => getAclFiles(data, resolver)), ...p.runSync("render.MutationEffects", () => getMutationEffectsFiles(data, resolver)), ...p.runSync("render.ZodExtended", () => getZodExtendedFiles(data, resolver)), ...p.runSync("render.Standalone", () => getAppRestClientFiles(resolver)));
4966
+ if (!modelsOnly) generateFilesData.push(...p.runSync("render.AclShared", () => getAclFiles(data, resolver)), ...p.runSync("render.MutationEffects", () => getMutationEffectsFiles(data, resolver)), ...p.runSync("render.ZodExtended", () => getZodExtendedFiles(data, resolver)), ...p.runSync("render.Standalone", () => getAppRestClientFiles(resolver)), ...p.runSync("render.DomainErrors", () => getDomainErrorsFiles(data, resolver)));
4831
4967
  return generateFilesData;
4832
4968
  }
4833
4969
 
@@ -1,4 +1,4 @@
1
- import { n as GenerateFileData, t as GenerateOptions } from "./options-C6CNQ6tq.mjs";
1
+ import { n as GenerateFileData, t as GenerateOptions } from "./options-BPAjzilp.mjs";
2
2
  import { OpenAPIV3 } from "openapi-types";
3
3
 
4
4
  //#region src/generators/types/metadata.d.ts
@@ -1,4 +1,4 @@
1
- import { _ as getNamespaceName, a as getDataFromOpenAPIDoc, b as isParamMediaTypeAllowed, c as getSchemaTsMetaType, d as getTagImportPath, f as getQueryName, g as invalidVariableNameCharactersToCamel, l as getTsTypeBase, o as isMutation, p as DEFAULT_GENERATE_OPTIONS, s as isQuery, t as generateCodeFromOpenAPIDoc, v as GenerateType, x as formatTag, y as isMediaTypeAllowed } from "./generateCodeFromOpenAPIDoc-BKIXvJIW.mjs";
1
+ import { _ as getNamespaceName, a as getDataFromOpenAPIDoc, b as isParamMediaTypeAllowed, c as getSchemaTsMetaType, d as getTagImportPath, f as getQueryName, g as invalidVariableNameCharactersToCamel, l as getTsTypeBase, o as isMutation, p as DEFAULT_GENERATE_OPTIONS, s as isQuery, t as generateCodeFromOpenAPIDoc, v as GenerateType, x as formatTag, y as isMediaTypeAllowed } from "./generateCodeFromOpenAPIDoc-mALUMd3q.mjs";
2
2
  import SwaggerParser from "@apidevtools/swagger-parser";
3
3
 
4
4
  //#region src/generators/core/getMetadataFromOpenAPIDoc.ts
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import { a as GeneralErrorCodes, i as ErrorHandlerOptions, n as ErrorEntry, o as SharedErrorHandler, r as ErrorHandler, t as ApplicationException } from "./error-handling-CvW_FecB.mjs";
2
- import "./options-C6CNQ6tq.mjs";
3
- import { t as OpenAPICodegenConfig } from "./config-CKmoJbQB.mjs";
1
+ import { a as ErrorHandler, c as SharedErrorHandler, i as ErrorEntry, n as DomainErrorEntry, o as ErrorHandlerOptions, r as DomainErrorRegistry, s as GeneralErrorCodes, t as ApplicationException } from "./error-handling-B4aYKmyL.mjs";
2
+ import "./options-BPAjzilp.mjs";
3
+ import { t as OpenAPICodegenConfig } from "./config-C1ME3Ay4.mjs";
4
4
  import { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosResponseHeaders, CreateAxiosDefaults } from "axios";
5
5
  import { z } from "zod";
6
6
  import "i18next";
@@ -65,7 +65,7 @@ declare class RestClient$1 implements RestClient {
65
65
  //#endregion
66
66
  //#region src/lib/rest/rest.utils.d.ts
67
67
  declare namespace RestUtils {
68
- const extractServerResponseCode: (e: unknown) => string | null;
68
+ const extractServerResponseCode: (e: unknown) => string | number | null;
69
69
  const doesServerErrorMessageContain: (e: AxiosError, text: string) => boolean;
70
70
  const extractServerErrorMessage: (e: unknown) => string | null;
71
71
  const extractContentDispositionFilename: (headers: AxiosResponseHeaders) => string | undefined;
@@ -110,7 +110,7 @@ interface MutationEffectsOptions<TQueryModule extends QueryModule = QueryModule>
110
110
  invalidateCurrentModule?: boolean;
111
111
  crossTabInvalidation?: boolean;
112
112
  invalidationMap?: InvalidationMap<TQueryModule>;
113
- invalidateModules?: TQueryModule[];
113
+ invalidateModules?: QueryModule[];
114
114
  invalidateKeys?: QueryKey[];
115
115
  preferUpdate?: boolean;
116
116
  }
@@ -228,4 +228,4 @@ declare const AuthGuard: ({
228
228
  children
229
229
  }: PropsWithChildren<AuthGuardProps>) => react.ReactNode;
230
230
  //#endregion
231
- export { type AppInfiniteQueryOptions, type AppMutationOptions, type AppQueryOptions, ApplicationException, AuthContext, AuthGuard, type AuthGuardProps, type ErrorEntry, ErrorHandler, type ErrorHandlerOptions, type GeneralErrorCodes, type RestClient as IRestClient, type InvalidationMap, type InvalidationMapFunc, type MutationEffectsOptions, OpenAPICodegenConfig, OpenApiQueryConfig, OpenApiRouter, OpenApiWorkspaceContext, type QueryModule, type RequestConfig, type RequestInfo, type Response, RestClient$1 as RestClient, RestInterceptor, RestUtils, SharedErrorHandler, ns, resources, useMutationEffects, useWorkspaceContext };
231
+ export { type AppInfiniteQueryOptions, type AppMutationOptions, type AppQueryOptions, ApplicationException, AuthContext, AuthGuard, type AuthGuardProps, type DomainErrorEntry, DomainErrorRegistry, type ErrorEntry, ErrorHandler, type ErrorHandlerOptions, type GeneralErrorCodes, type RestClient as IRestClient, type InvalidationMap, type InvalidationMapFunc, type MutationEffectsOptions, OpenAPICodegenConfig, OpenApiQueryConfig, OpenApiRouter, OpenApiWorkspaceContext, type QueryModule, type RequestConfig, type RequestInfo, type Response, RestClient$1 as RestClient, RestInterceptor, RestUtils, SharedErrorHandler, ns, resources, useMutationEffects, useWorkspaceContext };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as ns, i as RestUtils, n as ErrorHandler, o as resources, r as SharedErrorHandler, t as ApplicationException } from "./error-handling-DkPY7Asf.mjs";
1
+ import { a as RestUtils, i as SharedErrorHandler, n as DomainErrorRegistry, o as ns, r as ErrorHandler, s as resources, t as ApplicationException } from "./error-handling-nneQaE1_.mjs";
2
2
  import { n as OpenApiRouter, t as AuthContext } from "./auth.context-Bu5KW2sI.mjs";
3
3
  import axios from "axios";
4
4
  import { z } from "zod";
@@ -250,4 +250,4 @@ const AuthGuard = ({ type, redirectTo, children }) => {
250
250
  };
251
251
 
252
252
  //#endregion
253
- export { ApplicationException, AuthContext, AuthGuard, ErrorHandler, OpenApiQueryConfig, OpenApiRouter, OpenApiWorkspaceContext, RestClient, RestInterceptor, RestUtils, SharedErrorHandler, ns, resources, useMutationEffects, useWorkspaceContext };
253
+ export { ApplicationException, AuthContext, AuthGuard, DomainErrorRegistry, ErrorHandler, OpenApiQueryConfig, OpenApiRouter, OpenApiWorkspaceContext, RestClient, RestInterceptor, RestUtils, SharedErrorHandler, ns, resources, useMutationEffects, useWorkspaceContext };
@@ -42,7 +42,11 @@ interface QueriesGenerateOptions {
42
42
  mutationDefaultOnError?: boolean;
43
43
  workspaceContext?: string[];
44
44
  prefetchQueries?: boolean;
45
- mutationScope?: boolean;
45
+ mutationScope?: boolean | {
46
+ include: string[];
47
+ } | {
48
+ exclude: string[];
49
+ };
46
50
  }
47
51
  interface InfiniteQueriesGenerateOptions {
48
52
  infiniteQueries?: boolean;
package/dist/sh.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { C as VALIDATION_ERROR_TYPE_TITLE, S as Profiler, a as getDataFromOpenAPIDoc, m as groupByType, n as getOutputFileName, u as getTagFileName, v as GenerateType } from "./generateCodeFromOpenAPIDoc-BKIXvJIW.mjs";
3
- import { n as resolveConfig, t as runGenerate } from "./generate.runner-B0iop_CE.mjs";
2
+ import { C as VALIDATION_ERROR_TYPE_TITLE, S as Profiler, a as getDataFromOpenAPIDoc, m as groupByType, n as getOutputFileName, u as getTagFileName, v as GenerateType } from "./generateCodeFromOpenAPIDoc-mALUMd3q.mjs";
3
+ import { n as resolveConfig, t as runGenerate } from "./generate.runner-CeXyATq2.mjs";
4
4
  import { createRequire } from "node:module";
5
5
  import yargs from "yargs";
6
6
  import { hideBin } from "yargs/helpers";
@@ -39,7 +39,7 @@ function logBanner(message) {
39
39
  * Fetch the version from package.json
40
40
  */
41
41
  function getVersion() {
42
- return "3.0.0-rc.1";
42
+ return "3.0.0-rc.11";
43
43
  }
44
44
 
45
45
  //#endregion
package/dist/vite.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { r as GenerateFileFormatter } from "./options-C6CNQ6tq.mjs";
2
- import { t as OpenAPICodegenConfig } from "./config-CKmoJbQB.mjs";
1
+ import { r as GenerateFileFormatter } from "./options-BPAjzilp.mjs";
2
+ import { t as OpenAPICodegenConfig } from "./config-C1ME3Ay4.mjs";
3
3
  import { Plugin } from "vite";
4
4
 
5
5
  //#region src/vite/openapi-codegen.plugin.d.ts
package/dist/vite.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { S as Profiler } from "./generateCodeFromOpenAPIDoc-BKIXvJIW.mjs";
2
- import { t as runGenerate } from "./generate.runner-B0iop_CE.mjs";
1
+ import { S as Profiler } from "./generateCodeFromOpenAPIDoc-mALUMd3q.mjs";
2
+ import { t as runGenerate } from "./generate.runner-CeXyATq2.mjs";
3
3
  import path from "path";
4
4
 
5
5
  //#region src/vite/openapi-codegen.plugin.ts
package/dist/zod.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as ErrorHandler } from "./error-handling-CvW_FecB.mjs";
1
+ import { a as ErrorHandler } from "./error-handling-B4aYKmyL.mjs";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/zod.d.ts
package/dist/zod.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { r as SharedErrorHandler } from "./error-handling-DkPY7Asf.mjs";
1
+ import { i as SharedErrorHandler } from "./error-handling-nneQaE1_.mjs";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/zod.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@povio/openapi-codegen-cli",
3
- "version": "3.0.0-rc.1",
3
+ "version": "3.0.0-rc.11",
4
4
  "keywords": [
5
5
  "codegen",
6
6
  "openapi",