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

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-BOWjt2I0.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) {
@@ -2224,9 +2246,9 @@ function getEndpointParameter({ resolver, param, operationName, isUniqueOperatio
2224
2246
  if (resolver.options.withDescription && schema) schema.description = (paramObj.description ?? "").trim();
2225
2247
  const fallbackName = getParamZodSchemaName(getZodSchemaOperationName(operationName, isUniqueOperationName, tag), paramObj.name);
2226
2248
  let parameterSortingEnumSchemaName = void 0;
2227
- if (isSortingParameterObject(paramObj)) {
2249
+ if (isSortingParameterObject(paramObj, schema, resolver)) {
2228
2250
  const enumZodSchemaName = getEnumZodSchemaName(fallbackName, resolver.options.enumSuffix, resolver.options.schemaSuffix);
2229
- const code = getEnumZodSchemaCodeFromEnumNames(paramObj["x-enumNames"]);
2251
+ const code = getEnumZodSchemaCodeFromEnumNames(getParameterEnumNames(paramObj, schema) ?? []);
2230
2252
  resolver.setZodSchema(enumZodSchemaName, code, tag);
2231
2253
  parameterSortingEnumSchemaName = enumZodSchemaName;
2232
2254
  }
@@ -2379,11 +2401,23 @@ function getEndpointsFromOpenAPIDoc(resolver) {
2379
2401
  endpoint.response = responseZodSchema;
2380
2402
  endpoint.responseObject = responseObj;
2381
2403
  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
- });
2404
+ } else if (statusCode !== "default" && !Number.isNaN(status) && isErrorStatus(status)) {
2405
+ const rawSchema = schemaObject;
2406
+ const domainStr = rawSchema["x-domain-error-domain"];
2407
+ const domainName = rawSchema["x-domain-error-name"];
2408
+ const codeEnumArr = ((rawSchema?.properties)?.code)?.enum;
2409
+ const domainCode = Array.isArray(codeEnumArr) && codeEnumArr.length === 1 && typeof codeEnumArr[0] === "number" ? codeEnumArr[0] : void 0;
2410
+ endpoint.errors.push({
2411
+ zodSchema: responseZodSchema,
2412
+ status,
2413
+ description: responseObj?.description,
2414
+ ...typeof domainStr === "string" && domainCode !== void 0 ? { domainError: {
2415
+ domain: domainStr,
2416
+ code: domainCode,
2417
+ ...typeof domainName === "string" ? { name: domainName } : {}
2418
+ } } : {}
2419
+ });
2420
+ }
2387
2421
  } else {
2388
2422
  const status = Number(statusCode);
2389
2423
  const responseZodSchema = VOID_SCHEMA;
@@ -2579,6 +2613,7 @@ function resolveExtractedEnumZodSchemaTags(resolver) {
2579
2613
  //#endregion
2580
2614
  //#region src/generators/core/zod/enumExtraction/updateExtractedEnumZodSchemaData.ts
2581
2615
  function updateExtractedEnumZodSchemaData({ schema, nameSegments = [], includeSelf, ...params }) {
2616
+ if (!isReferenceObject(schema) && schema?.["x-domain-error-domain"]) return;
2582
2617
  if (includeSelf) handleExtractedEnumZodSchemaDataUpdate({
2583
2618
  schema,
2584
2619
  nameSegments,
@@ -3048,7 +3083,7 @@ function sortZodSchemasByTopology(resolver, zodSchemas) {
3048
3083
  function getDataFromOpenAPIDoc(openApiDoc, options, profiler) {
3049
3084
  const p = profiler ?? new Profiler(false);
3050
3085
  const resolver = p.runSync("data.resolver.init", () => new SchemaResolver(openApiDoc, options, p));
3051
- const endpoints = p.runSync("data.endpoints.extract", () => getEndpointsFromOpenAPIDoc(resolver, p));
3086
+ const endpoints = p.runSync("data.endpoints.extract", () => getEndpointsFromOpenAPIDoc(resolver));
3052
3087
  const zodSchemasFromDocSchemas = p.runSync("data.zod.extract", () => getZodSchemasFromOpenAPIDoc(resolver, p));
3053
3088
  let zodSchemas = {
3054
3089
  ...zodSchemasFromDocSchemas.zodSchemas,
@@ -3261,9 +3296,9 @@ function renderWorkspaceAclHook({ resolver, endpoint }) {
3261
3296
  const objectRequired = abilityConditionsTypes.some((propertyType) => propertyType.required && !workspaceConditionNameSet.has(propertyType.name));
3262
3297
  const objectParams = abilityConditionsTypes.map((propertyType) => {
3263
3298
  const isWorkspaceCondition = workspaceConditionNameSet.has(propertyType.name);
3264
- return `${propertyType.name}${propertyType.required && !isWorkspaceCondition ? "" : "?"}: ${(propertyType.type ?? "") + (propertyType.zodSchemaName ?? "")}, `;
3299
+ return `${propertyType.name}${propertyType.required && !isWorkspaceCondition ? "" : "?"}: ${renderConditionType(resolver, endpoint, propertyType)}, `;
3265
3300
  }).join("");
3266
- const contextType = abilityConditionsTypes.filter((propertyType) => workspaceConditionNameSet.has(propertyType.name)).map((propertyType) => `${propertyType.name}?: ${(propertyType.type ?? "") + (propertyType.zodSchemaName ?? "")}`).join("; ");
3301
+ const contextType = abilityConditionsTypes.filter((propertyType) => workspaceConditionNameSet.has(propertyType.name)).map((propertyType) => `${propertyType.name}?: ${renderConditionType(resolver, endpoint, propertyType)}`).join("; ");
3267
3302
  const contextBindings = workspaceConditionNames.map((name) => `${name}: ${name}Workspace`).join(", ");
3268
3303
  const lines = [];
3269
3304
  lines.push(`export const use${capitalize(getAbilityFunctionName(endpoint))} = (`);
@@ -3289,15 +3324,15 @@ function renderAbilityFunction({ resolver, endpoint }) {
3289
3324
  lines.push("/**");
3290
3325
  lines.push(` * Use for ${abilityQuery} ability. ${hasConditions ? "For global ability, omit the object parameter." : ""}${getAbilityDescription(endpoint) ? "" : ""}`);
3291
3326
  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}`);
3327
+ if (hasConditions) for (const propertyType of abilityConditionsTypes) lines.push(` * @param { ${renderConditionType(resolver, endpoint, propertyType)} } object.${propertyType.name} ${propertyType.name} from ${propertyType.info}`);
3293
3328
  lines.push(` * @returns { AbilityTuple } An ability tuple indicating the user's ability to use ${abilityQuery}`);
3294
3329
  lines.push(" */");
3295
3330
  lines.push(`export const ${getAbilityFunctionName(endpoint)} = (`);
3296
- if (hasConditions) lines.push(` object?: { ${abilityConditionsTypes.map((propertyType) => `${propertyType.name}${propertyType.required ? "" : "?"}: ${(propertyType.type ?? "") + (propertyType.zodSchemaName ?? "")}, `).join("")} } `);
3331
+ if (hasConditions) lines.push(` object?: { ${abilityConditionsTypes.map((propertyType) => `${propertyType.name}${propertyType.required ? "" : "?"}: ${renderConditionType(resolver, endpoint, propertyType)}, `).join("")} } `);
3297
3332
  lines.push(") => [");
3298
3333
  lines.push(` "${getAbilityAction(endpoint)}",`);
3299
3334
  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(" | ")}>;`);
3335
+ lines.push(`] as ${CASL_ABILITY_BINDING.abilityTuple}<"${getAbilityAction(endpoint)}", ${getAbilitySubjectTypes(endpoint, resolver, getEndpointTag(endpoint, resolver.options)).join(" | ")}>;`);
3301
3336
  const workspaceAclHook = renderWorkspaceAclHook({
3302
3337
  resolver,
3303
3338
  endpoint
@@ -3308,6 +3343,9 @@ function renderAbilityFunction({ resolver, endpoint }) {
3308
3343
  }
3309
3344
  return lines.join("\n");
3310
3345
  }
3346
+ function renderConditionType(resolver, endpoint, propertyType) {
3347
+ return getAbilityConditionType(propertyType, resolver, getEndpointTag(endpoint, resolver.options));
3348
+ }
3311
3349
 
3312
3350
  //#endregion
3313
3351
  //#region src/generators/const/buildConfigs.const.ts
@@ -3520,7 +3558,7 @@ function getColumnsConfig(resolver, endpoint) {
3520
3558
  ...acc,
3521
3559
  [key]: true
3522
3560
  }), {});
3523
- const sortableEnumSchemaName = endpoint.parameters.find((param) => param.parameterObject && isSortingParameterObject(param.parameterObject))?.parameterSortingEnumSchemaName;
3561
+ const sortableEnumSchemaName = endpoint.parameters.find((param) => param.parameterSortingEnumSchemaName)?.parameterSortingEnumSchemaName;
3524
3562
  return {
3525
3563
  columns: {
3526
3564
  schema: getImportedZodSchemaName(resolver, zodSchema),
@@ -3835,7 +3873,7 @@ function generateEndpoints({ resolver, data, tag }) {
3835
3873
  const endpointConfig = renderEndpointConfig(resolver, endpoint, tag);
3836
3874
  lines.push(`export const ${getEndpointName(endpoint)} = (${endpointParams}${hasAxiosRequestConfig ? `${AXIOS_REQUEST_CONFIG_NAME}?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => {`);
3837
3875
  lines.push(` return ${APP_REST_CLIENT_NAME}.${endpoint.method}(`);
3838
- lines.push(` { resSchema: ${getImportedZodSchemaName(resolver, endpoint.response, tag)} },`);
3876
+ lines.push(` { resSchema: ${getImportedZodSchemaName(resolver, endpoint.response, resolver.options.modelsInCommon && resolver.options.splitByTags ? tag : void 0)} },`);
3839
3877
  lines.push(` \`${getEndpointPath(endpoint)}\`,`);
3840
3878
  if (endpointBody) lines.push(` ${generateParse ? renderEndpointParamParse(resolver, endpointBody, endpointBody.name, tag) : endpointBody.name},`);
3841
3879
  else if (hasUndefinedEndpointBody) lines.push(" undefined,");
@@ -3859,10 +3897,16 @@ function renderEndpointArgs$1(resolver, endpoint, options) {
3859
3897
  }
3860
3898
  function renderEndpointParamParse(resolver, param, paramName, modelNamespaceTag) {
3861
3899
  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()" : ""}`;
3900
+ 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
3901
  const queryArgs = param.type === "Query" ? `, { type: "query", name: "${paramName}" }` : "";
3864
3902
  return `${ZOD_EXTENDED.namespace}.${ZOD_EXTENDED.exports.parse}(${schemaValue}, ${paramName}${queryArgs})`;
3865
3903
  }
3904
+ function getSortingPresenceChain$1(resolver, param) {
3905
+ const zodSchemaCode = resolver.getCodeByZodSchemaName(param.zodSchema) ?? param.zodSchema;
3906
+ if (zodSchemaCode.includes(".nullish()")) return ".nullish()";
3907
+ if (zodSchemaCode.includes(".nullable()")) return ".nullable()";
3908
+ return !(param.parameterObject ?? param.bodyObject)?.required ? ".optional()" : "";
3909
+ }
3866
3910
  function renderEndpointConfig(resolver, endpoint, modelNamespaceTag) {
3867
3911
  const endpointConfig = getEndpointConfig(endpoint);
3868
3912
  const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
@@ -4034,6 +4078,10 @@ function renderModelJsDocs({ name, zodSchema, tag, resolver }) {
4034
4078
  const endpointParamMappingCache = /* @__PURE__ */ new WeakMap();
4035
4079
  function generateQueries(params) {
4036
4080
  const { resolver, data, tag } = params;
4081
+ const mutationScopeOption = resolver.options.mutationScope;
4082
+ if (mutationScopeOption && typeof mutationScopeOption === "object") {
4083
+ if ("include" in mutationScopeOption && "exclude" in mutationScopeOption) throw new Error("mutationScope cannot specify both 'include' and 'exclude'");
4084
+ }
4037
4085
  const inlineEndpoints = shouldInlineEndpointsForTag(tag, resolver.options);
4038
4086
  const endpoints = data.get(tag)?.endpoints;
4039
4087
  if (!endpoints || endpoints.length === 0) return;
@@ -4393,10 +4441,16 @@ function renderInlineEndpoints({ resolver, endpoints, tag }) {
4393
4441
  }
4394
4442
  function renderInlineEndpointParamParse(resolver, param, paramName, modelNamespaceTag) {
4395
4443
  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()" : ""}`;
4444
+ 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
4445
  const queryArgs = param.type === "Query" ? `, { type: "query", name: "${paramName}" }` : "";
4398
4446
  return `${ZOD_EXTENDED.namespace}.${ZOD_EXTENDED.exports.parse}(${schemaValue}, ${paramName}${queryArgs})`;
4399
4447
  }
4448
+ function getSortingPresenceChain(resolver, param) {
4449
+ const zodSchemaCode = resolver.getCodeByZodSchemaName(param.zodSchema) ?? param.zodSchema;
4450
+ if (zodSchemaCode.includes(".nullish()")) return ".nullish()";
4451
+ if (zodSchemaCode.includes(".nullable()")) return ".nullable()";
4452
+ return !(param.parameterObject ?? param.bodyObject)?.required ? ".optional()" : "";
4453
+ }
4400
4454
  function renderInlineEndpointConfig(resolver, endpoint, modelNamespaceTag) {
4401
4455
  const endpointConfig = getEndpointConfig(endpoint);
4402
4456
  const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
@@ -4448,7 +4502,7 @@ function renderInfiniteQueryOptions({ resolver, endpoint, inlineEndpoints }) {
4448
4502
  lines.push(` queryKey: keys.${getEndpointName(endpoint)}Infinite(${endpointArgsWithoutPage}),`);
4449
4503
  lines.push(` queryFn: ({ pageParam }: { pageParam: number }) => ${endpointFunction}(${endpointArgsWithPage}${hasAxiosRequestConfig ? `, ${AXIOS_REQUEST_CONFIG_NAME}` : ""}),`);
4450
4504
  lines.push(" initialPageParam: 1,");
4451
- lines.push(` getNextPageParam: ({ ${resolver.options.infiniteQueryResponseParamNames.page}, ${resolver.options.infiniteQueryResponseParamNames.totalItems}, ${resolver.options.infiniteQueryResponseParamNames.limit}: limitParam }) => {`);
4505
+ lines.push(` getNextPageParam: ({ ${resolver.options.infiniteQueryResponseParamNames.page}, ${resolver.options.infiniteQueryResponseParamNames.totalItems}, ${resolver.options.infiniteQueryResponseParamNames.limit}: limitParam }: Awaited<ReturnType<typeof ${endpointFunction}>>) => {`);
4452
4506
  lines.push(` const pageParam = ${resolver.options.infiniteQueryResponseParamNames.page} ?? 1;`);
4453
4507
  lines.push(` return pageParam * limitParam < ${resolver.options.infiniteQueryResponseParamNames.totalItems} ? pageParam + 1 : null;`);
4454
4508
  lines.push(" },");
@@ -4472,9 +4526,10 @@ function renderPrefetchInfiniteQuery({ resolver, endpoint }) {
4472
4526
  modelNamespaceTag: getEndpointTag(endpoint, resolver.options)
4473
4527
  });
4474
4528
  const endpointArgs = renderEndpointArgs(resolver, endpoint, { excludePageParam: true });
4529
+ const optionsArgs = `${endpointParams ? `{ ${endpointArgs} }` : ""}${hasAxiosRequestConfig ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""}`;
4475
4530
  const lines = [];
4476
4531
  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 });`);
4532
+ lines.push(` void queryClient.prefetchInfiniteQuery({ ...${getInfiniteQueryOptionsName(endpoint)}(${optionsArgs}), ...(options as {}) });`);
4478
4533
  lines.push("};");
4479
4534
  return lines.join("\n");
4480
4535
  }
@@ -4541,6 +4596,27 @@ function renderMutation({ resolver, endpoint, inlineEndpoints, precomputed }) {
4541
4596
  const destructuredVariables = precomputed?.destructuredVariables ?? getDestructuredVariables(resolver, endpoint, updateQueryEndpoints);
4542
4597
  const hasMutationFnBody = endpoint.mediaUpload || hasAclCheck || Object.keys(workspaceParamReplacements).length > 0;
4543
4598
  const mutationVariablesType = endpoint.mediaUpload ? `${endpointParams}${endpointParams ? "; " : ""}abortController?: AbortController; onUploadProgress?: (progress: { loaded: number; total: number }) => void` : endpointParams;
4599
+ const isPost = endpoint.method === "post";
4600
+ const mutationScopeOption = resolver.options.mutationScope;
4601
+ const operationId = getEndpointName(endpoint);
4602
+ const scopeMatchKey = `${tag}/${operationId}`;
4603
+ let scopeEnabled = false;
4604
+ if (!isPost && mutationScopeOption) {
4605
+ if (mutationScopeOption === true) scopeEnabled = true;
4606
+ else if (typeof mutationScopeOption === "object" && "include" in mutationScopeOption) scopeEnabled = mutationScopeOption.include.some((id) => id === operationId || id === scopeMatchKey);
4607
+ else if (typeof mutationScopeOption === "object" && "exclude" in mutationScopeOption) scopeEnabled = !mutationScopeOption.exclude.some((id) => id === operationId || id === scopeMatchKey);
4608
+ }
4609
+ const scopePathParams = scopeEnabled ? mapEndpointParamsToFunctionParams(resolver, endpoint, {}).filter((p) => p.paramType === "Path") : [];
4610
+ const isScoped = scopePathParams.length > 0;
4611
+ const nonPathEndpointParams = isScoped ? renderEndpointParams(resolver, endpoint, {
4612
+ includeFileParam: true,
4613
+ optionalPathParams: resolver.options.workspaceContext,
4614
+ modelNamespaceTag: tag,
4615
+ excludePathParams: true
4616
+ }) : endpointParams;
4617
+ const nonPathMutationVariablesType = isScoped ? endpoint.mediaUpload ? `${nonPathEndpointParams}${nonPathEndpointParams ? "; " : ""}abortController?: AbortController; onUploadProgress?: (progress: { loaded: number; total: number }) => void` : nonPathEndpointParams : mutationVariablesType;
4618
+ const pathParamFirstArg = isScoped ? `{ ${scopePathParams.map((p) => p.name).join(", ")} }: { ${scopePathParams.map((p) => `${p.name}: ${p.type}`).join("; ")} }, ` : "";
4619
+ const mutationOptionsTypeArg = isScoped ? nonPathMutationVariablesType ? `, { ${nonPathMutationVariablesType} }` : "" : `, { ${mutationVariablesType} }`;
4544
4620
  const lines = [];
4545
4621
  lines.push(renderQueryJsDocs({
4546
4622
  resolver,
@@ -4548,7 +4624,7 @@ function renderMutation({ resolver, endpoint, inlineEndpoints, precomputed }) {
4548
4624
  mode: "mutation",
4549
4625
  tag
4550
4626
  }));
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}` : ""}) => {`);
4627
+ 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
4628
  if (hasMutationDefaultOnError) lines.push(" const queryConfig = OpenApiQueryConfig.useConfig();");
4553
4629
  if (hasAclCheck) lines.push(` const { checkAcl } = ${ACL_CHECK_HOOK}();`);
4554
4630
  lines.push(...renderWorkspaceContextDestructure({
@@ -4556,10 +4632,16 @@ function renderMutation({ resolver, endpoint, inlineEndpoints, precomputed }) {
4556
4632
  paramTypes: workspaceParamTypes,
4557
4633
  indent: " "
4558
4634
  }));
4559
- if (hasMutationEffects) lines.push(` const { runMutationEffects } = useMutationEffects<typeof ${QUERY_MODULE_ENUM}.${tag}>({ currentModule: ${QUERIES_MODULE_NAME} });`);
4635
+ if (hasMutationEffects) lines.push(` const { runMutationEffects } = useMutationEffects<${QUERY_MODULE_ENUM}.${tag}>({ currentModule: ${QUERIES_MODULE_NAME} });`);
4560
4636
  lines.push("");
4561
4637
  lines.push(` return ${QUERY_HOOKS.mutation}({`);
4562
- const mutationFnArg = endpointParams ? `{ ${destructuredMutationArgs}${endpoint.mediaUpload ? `${destructuredMutationArgs ? ", " : ""}abortController, onUploadProgress` : ""} }` : "";
4638
+ const nonPathDestructuredArgs = isScoped ? renderEndpointArgs(resolver, endpoint, {
4639
+ includeFileParam: true,
4640
+ excludePathParams: true
4641
+ }) : destructuredMutationArgs;
4642
+ const effectiveParams = isScoped ? nonPathEndpointParams : endpointParams;
4643
+ const effectiveArgs = isScoped ? nonPathDestructuredArgs : destructuredMutationArgs;
4644
+ const mutationFnArg = effectiveParams || endpoint.mediaUpload ? `{ ${effectiveArgs}${endpoint.mediaUpload ? `${effectiveArgs ? ", " : ""}abortController, onUploadProgress` : ""} }` : "";
4563
4645
  lines.push(` mutationFn: ${endpoint.mediaUpload ? "async " : ""}(${mutationFnArg}) => ${hasMutationFnBody ? "{ " : ""}`);
4564
4646
  lines.push(...renderWorkspaceParamCoalescing({
4565
4647
  replacements: workspaceParamReplacements,
@@ -4596,12 +4678,18 @@ function renderMutation({ resolver, endpoint, inlineEndpoints, precomputed }) {
4596
4678
  } else lines.push(` ${hasMutationFnBody ? "return " : ""}${endpointFunction}(${resolvedEndpointArgs}${hasAxiosRequestConfig ? `${resolvedEndpointArgs ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""})`);
4597
4679
  if (hasMutationFnBody) lines.push(" },");
4598
4680
  else lines.push(",");
4681
+ if (isScoped) {
4682
+ const scopePathParamInterpolations = scopePathParams.map((p) => `:\${${p.name}}`).join("");
4683
+ lines.push(` scope: { id: \`${getEndpointName(endpoint)}${scopePathParamInterpolations}\` },`);
4684
+ }
4599
4685
  lines.push(" ...options,");
4600
4686
  if (hasMutationDefaultOnError) lines.push(" onError: options?.onError ?? queryConfig.onError,");
4601
4687
  if (hasMutationEffects) {
4602
4688
  lines.push(" onSuccess: async (resData, variables, onMutateResult, context) => {");
4603
4689
  if (updateQueryEndpoints.length > 0) {
4604
- if (destructuredVariables.length > 0) lines.push(` const { ${destructuredVariables.join(", ")} } = variables;`);
4690
+ const scopedPathParamNames = new Set(scopePathParams.map((p) => p.name));
4691
+ const variablesDestructure = destructuredVariables.filter((v) => !scopedPathParamNames.has(v));
4692
+ if (variablesDestructure.length > 0) lines.push(` const { ${variablesDestructure.join(", ")} } = variables;`);
4605
4693
  lines.push(...renderWorkspaceParamCoalescing({
4606
4694
  replacements: workspaceParamReplacements,
4607
4695
  indent: " "
@@ -4711,6 +4799,37 @@ export const ${APP_REST_CLIENT_NAME} = new RestClient({
4711
4799
  `;
4712
4800
  }
4713
4801
 
4802
+ //#endregion
4803
+ //#region src/generators/generate/generateDomainErrors.ts
4804
+ function domainToPascalCase(domain) {
4805
+ return domain.split(/[-_]/).map(capitalize).join("");
4806
+ }
4807
+ function generateDomainErrors({ data }) {
4808
+ const byDomain = /* @__PURE__ */ new Map();
4809
+ for (const { endpoints } of data.values()) for (const endpoint of endpoints) for (const error of endpoint.errors) {
4810
+ if (!error.domainError) continue;
4811
+ const { domain, code } = error.domainError;
4812
+ if (!byDomain.has(domain)) byDomain.set(domain, /* @__PURE__ */ new Map());
4813
+ const domainMap = byDomain.get(domain);
4814
+ if (!domainMap.has(code)) domainMap.set(code, {
4815
+ code,
4816
+ name: error.domainError.name,
4817
+ description: error.description
4818
+ });
4819
+ }
4820
+ if (byDomain.size === 0) return void 0;
4821
+ const blocks = [];
4822
+ for (const [domain, codes] of [...byDomain.entries()].sort(([a], [b]) => a.localeCompare(b))) {
4823
+ const pascalName = domainToPascalCase(domain);
4824
+ const entries = [...codes.values()].sort((a, b) => a.code - b.code).map(({ code, name, description }) => {
4825
+ return `${description ? ` /** ${description} */\n ` : " "}${name ?? `ERROR_${code}`}: ${code}`;
4826
+ }).join(",\n");
4827
+ blocks.push(`export const ${pascalName}DomainErrors = {\n${entries},\n} as const;`);
4828
+ blocks.push(`export type ${pascalName}DomainErrorCode = (typeof ${pascalName}DomainErrors)[keyof typeof ${pascalName}DomainErrors];`);
4829
+ }
4830
+ return blocks.join("\n\n") + "\n";
4831
+ }
4832
+
4714
4833
  //#endregion
4715
4834
  //#region src/generators/generate/generateQueryModules.ts
4716
4835
  function generateQueryModules({ resolver, data }) {
@@ -4765,6 +4884,20 @@ function getMutationEffectsFiles(data, resolver) {
4765
4884
  function getZodExtendedFiles(_data, _resolver) {
4766
4885
  return [];
4767
4886
  }
4887
+ function getDomainErrorsFiles(data, resolver) {
4888
+ const content = generateDomainErrors({
4889
+ resolver,
4890
+ data
4891
+ });
4892
+ if (!content) return [];
4893
+ return [{
4894
+ fileName: getOutputFileName({
4895
+ output: resolver.options.output,
4896
+ fileName: getFileNameWithExtension(DOMAIN_ERRORS_FILE)
4897
+ }),
4898
+ content
4899
+ }];
4900
+ }
4768
4901
  function getAppRestClientFiles(resolver) {
4769
4902
  if (resolver.options.restClientImportPath !== DEFAULT_GENERATE_OPTIONS.restClientImportPath) return [];
4770
4903
  return [{
@@ -4827,7 +4960,7 @@ function generateCodeFromOpenAPIDoc(openApiDoc, options, profiler) {
4827
4960
  }
4828
4961
  });
4829
4962
  });
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)));
4963
+ 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
4964
  return generateFilesData;
4832
4965
  }
4833
4966
 
@@ -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-BOWjt2I0.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-BOWjt2I0.mjs";
3
+ import { n as resolveConfig, t as runGenerate } from "./generate.runner-C-MWypBE.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.10";
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-BOWjt2I0.mjs";
2
+ import { t as runGenerate } from "./generate.runner-C-MWypBE.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.10",
4
4
  "keywords": [
5
5
  "codegen",
6
6
  "openapi",