@povio/openapi-codegen-cli 3.0.0-rc.14 → 3.0.0-rc.16
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 +41 -0
- package/dist/acl.d.mts +1 -1
- package/dist/acl.mjs +14 -6
- package/dist/{config-C1ME3Ay4.d.mts → config-CrZa_Jbm.d.mts} +1 -1
- package/dist/{generate.runner-FyKVhmec.mjs → generate.runner-bJnq9ZZJ.mjs} +1 -1
- package/dist/{generateCodeFromOpenAPIDoc-BtabB7FW.mjs → generateCodeFromOpenAPIDoc-x7KFQcSq.mjs} +75 -36
- package/dist/generator.d.mts +1 -1
- package/dist/generator.mjs +1 -1
- package/dist/index.d.mts +12 -6
- package/dist/index.mjs +24 -11
- package/dist/metro.d.mts +32 -0
- package/dist/metro.mjs +86 -0
- package/dist/openapi-codegen.runner-NNdDG0V4.mjs +42 -0
- package/dist/sh.mjs +3 -3
- package/dist/vite.d.mts +7 -4
- package/dist/vite.mjs +9 -23
- package/dist/zod.d.mts +1 -1
- package/package.json +6 -2
- /package/dist/{error-handling-B4aYKmyL.d.mts → error-handling-oM5YJYYH.d.mts} +0 -0
- /package/dist/{options-BPAjzilp.d.mts → options-BZOw7Hx4.d.mts} +0 -0
package/README.md
CHANGED
|
@@ -215,6 +215,16 @@ import { ErrorHandler, OpenApiQueryConfig } from "@povio/openapi-codegen-cli";
|
|
|
215
215
|
</OpenApiQueryConfig.Provider>;
|
|
216
216
|
```
|
|
217
217
|
|
|
218
|
+
### Runtime response validation
|
|
219
|
+
|
|
220
|
+
Use `OpenApiQueryConfig.Provider` to allow generated GET query hooks to return invalid response data while still logging the response Zod error to the console. Non-GET requests still throw on invalid response data.
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
<OpenApiQueryConfig.Provider allowInvalidResponseData={import.meta.env.DEV}>
|
|
224
|
+
<App />
|
|
225
|
+
</OpenApiQueryConfig.Provider>
|
|
226
|
+
```
|
|
227
|
+
|
|
218
228
|
### OpenApiWorkspaceContext (Path + ACL defaults)
|
|
219
229
|
|
|
220
230
|
Set `workspaceContext` to a list of param names in codegen config (or pass `--workspaceContext officeId,projectId`) and wrap your app subtree with `OpenApiWorkspaceContext.Provider` if generated hooks frequently repeat workspace-scoped params.
|
|
@@ -277,6 +287,37 @@ export default defineConfig({
|
|
|
277
287
|
The plugin runs on both `vite serve` and `vite build`, and watches local OpenAPI files in dev mode.
|
|
278
288
|
If you provide `formatGeneratedFile`, the plugin formats each generated file in memory before comparing and writing it, which helps avoid unnecessary HMR when the formatted output is unchanged.
|
|
279
289
|
|
|
290
|
+
### Metro Plugin
|
|
291
|
+
|
|
292
|
+
You can run codegen directly from React Native Metro config:
|
|
293
|
+
|
|
294
|
+
```ts
|
|
295
|
+
import { fileURLToPath } from "url";
|
|
296
|
+
import { getDefaultConfig } from "@react-native/metro-config";
|
|
297
|
+
import { withOpenApiCodegen } from "@povio/openapi-codegen-cli/metro";
|
|
298
|
+
|
|
299
|
+
const root = fileURLToPath(new URL("./", import.meta.url));
|
|
300
|
+
const config = getDefaultConfig(root);
|
|
301
|
+
|
|
302
|
+
export default withOpenApiCodegen(
|
|
303
|
+
config,
|
|
304
|
+
{
|
|
305
|
+
input: "./openapi.yaml",
|
|
306
|
+
output: "./src/data",
|
|
307
|
+
inlineEndpoints: true,
|
|
308
|
+
incremental: true,
|
|
309
|
+
formatGeneratedFile: async ({ fileName, content }) => {
|
|
310
|
+
void fileName;
|
|
311
|
+
return content;
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
{ root },
|
|
315
|
+
);
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
The Metro wrapper runs generation when the config is loaded, waits for it before Metro transforms or serves the first request, and watches local OpenAPI files while the dev server is running.
|
|
319
|
+
If you provide `formatGeneratedFile`, it behaves the same way as the Vite plugin.
|
|
320
|
+
|
|
280
321
|
### Enums
|
|
281
322
|
|
|
282
323
|
If you're using Enums in your backend DTOs with `@Expose()` and `@IsEnum`, they may still not appear correctly in the OpenAPI schema unless you also provide both `enum` **and** `enumName` to `@ApiProperty`.
|
package/dist/acl.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as ErrorHandler } from "./error-handling-
|
|
1
|
+
import { a as ErrorHandler } from "./error-handling-oM5YJYYH.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
|
@@ -11,14 +11,17 @@ let AbilityContext;
|
|
|
11
11
|
(function(_AbilityContext) {
|
|
12
12
|
const createAppAbilityBuilder = () => new AbilityBuilder(createMongoAbility);
|
|
13
13
|
const initialAppAbility = createAppAbilityBuilder().build();
|
|
14
|
-
const Context = createContext(
|
|
14
|
+
const Context = createContext(initialAppAbility);
|
|
15
15
|
const { Consumer } = Context;
|
|
16
16
|
_AbilityContext.Consumer = Consumer;
|
|
17
17
|
_AbilityContext.Provider = ({ children }) => {
|
|
18
18
|
const [ability, setAbility] = useState(initialAppAbility);
|
|
19
19
|
const { user } = AuthContext.useAuth();
|
|
20
20
|
useEffect(() => {
|
|
21
|
-
if (!user || !("aclRules" in user))
|
|
21
|
+
if (!user || !("aclRules" in user)) {
|
|
22
|
+
setAbility(initialAppAbility);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
22
25
|
const { can, build } = createAppAbilityBuilder();
|
|
23
26
|
const packedRules = user.aclRules;
|
|
24
27
|
unpackRules(packedRules).forEach(({ action, subject, conditions }) => {
|
|
@@ -41,10 +44,15 @@ let AbilityContext;
|
|
|
41
44
|
const createAclGuard = () => ({ canUse, redirectTo = "/", children }) => {
|
|
42
45
|
const ability = AbilityContext.useAbility();
|
|
43
46
|
const { replace } = OpenApiRouter.useRouter();
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
47
|
+
const shouldRedirect = !ability.can(canUse[0], canUse[1]);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (shouldRedirect) replace(redirectTo);
|
|
50
|
+
}, [
|
|
51
|
+
redirectTo,
|
|
52
|
+
replace,
|
|
53
|
+
shouldRedirect
|
|
54
|
+
]);
|
|
55
|
+
if (shouldRedirect) return null;
|
|
48
56
|
return children;
|
|
49
57
|
};
|
|
50
58
|
|
|
@@ -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-
|
|
1
|
+
import { S as Profiler, h as deepMerge, i as writeGenerateFileData, p as DEFAULT_GENERATE_OPTIONS, r as removeStaleGeneratedFiles, t as generateCodeFromOpenAPIDoc } from "./generateCodeFromOpenAPIDoc-x7KFQcSq.mjs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
import SwaggerParser from "@apidevtools/swagger-parser";
|
|
4
4
|
|
package/dist/{generateCodeFromOpenAPIDoc-BtabB7FW.mjs → generateCodeFromOpenAPIDoc-x7KFQcSq.mjs}
RENAMED
|
@@ -3834,10 +3834,11 @@ function generateEndpoints({ resolver, data, tag }) {
|
|
|
3834
3834
|
from: getAppRestClientImportPath(resolver.options)
|
|
3835
3835
|
};
|
|
3836
3836
|
const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
|
|
3837
|
-
const
|
|
3837
|
+
const hasGetEndpoints = endpoints.some((endpoint) => endpoint.method === "get");
|
|
3838
|
+
const hasAxiosImport = hasAxiosRequestConfig || hasGetEndpoints;
|
|
3838
3839
|
const axiosImport = {
|
|
3839
3840
|
bindings: [],
|
|
3840
|
-
typeBindings:
|
|
3841
|
+
typeBindings: hasAxiosImport ? [AXIOS_REQUEST_CONFIG_TYPE] : [],
|
|
3841
3842
|
from: AXIOS_IMPORT.from
|
|
3842
3843
|
};
|
|
3843
3844
|
const generateParse = resolver.options.parseRequestParams;
|
|
@@ -3875,9 +3876,10 @@ function generateEndpoints({ resolver, data, tag }) {
|
|
|
3875
3876
|
const endpointBody = getEndpointBody$1(endpoint);
|
|
3876
3877
|
const hasUndefinedEndpointBody = requiresBody(endpoint) && !endpointBody && hasEndpointConfig(endpoint, resolver);
|
|
3877
3878
|
const endpointConfig = renderEndpointConfig(resolver, endpoint, tag);
|
|
3878
|
-
|
|
3879
|
+
const hasRequestConfigParam = hasAxiosRequestConfig || endpoint.method === "get";
|
|
3880
|
+
lines.push(`export const ${getEndpointName(endpoint)} = (${endpointParams}${hasRequestConfigParam ? `${AXIOS_REQUEST_CONFIG_NAME}?: ${getRequestConfigType$1()}` : ""}) => {`);
|
|
3879
3881
|
lines.push(` return ${APP_REST_CLIENT_NAME}.${endpoint.method}(`);
|
|
3880
|
-
lines.push(`
|
|
3882
|
+
lines.push(` ${renderRequestInfo(resolver, endpoint, tag)},`);
|
|
3881
3883
|
lines.push(` \`${getEndpointPath(endpoint)}\`,`);
|
|
3882
3884
|
if (endpointBody) lines.push(` ${generateParse ? renderEndpointParamParse(resolver, endpointBody, endpointBody.name, tag) : endpointBody.name},`);
|
|
3883
3885
|
else if (hasUndefinedEndpointBody) lines.push(" undefined,");
|
|
@@ -3888,6 +3890,12 @@ function generateEndpoints({ resolver, data, tag }) {
|
|
|
3888
3890
|
if (resolver.options.tsNamespaces) lines.push("}");
|
|
3889
3891
|
return lines.join("\n").trimEnd() + "\n";
|
|
3890
3892
|
}
|
|
3893
|
+
function renderRequestInfo(resolver, endpoint, tag) {
|
|
3894
|
+
return `{ resSchema: ${getImportedZodSchemaName(resolver, endpoint.response, resolver.options.modelsInCommon && resolver.options.splitByTags ? tag : void 0)} }`;
|
|
3895
|
+
}
|
|
3896
|
+
function getRequestConfigType$1() {
|
|
3897
|
+
return `${AXIOS_REQUEST_CONFIG_TYPE} & { allowInvalidResponseData?: boolean }`;
|
|
3898
|
+
}
|
|
3891
3899
|
function renderImport$2(importData) {
|
|
3892
3900
|
const namedImports = [...importData.bindings, ...(importData.typeBindings ?? []).map((binding) => importData.typeOnly ? binding : `type ${binding}`)];
|
|
3893
3901
|
const names = [...importData.defaultImport ? [importData.defaultImport] : [], ...namedImports.length > 0 ? [`{ ${namedImports.join(", ")} }`] : []].join(", ");
|
|
@@ -3913,12 +3921,12 @@ function getSortingPresenceChain$1(resolver, param) {
|
|
|
3913
3921
|
}
|
|
3914
3922
|
function renderEndpointConfig(resolver, endpoint, modelNamespaceTag) {
|
|
3915
3923
|
const endpointConfig = getEndpointConfig(endpoint);
|
|
3916
|
-
const
|
|
3924
|
+
const hasRequestConfigParam = resolver.options.axiosRequestConfig || endpoint.method === "get";
|
|
3917
3925
|
const needsBlobConfig = endpoint.mediaDownload || endpoint.response === "z.instanceof(Blob)";
|
|
3918
|
-
if (Object.keys(endpointConfig).length === 0 && !needsBlobConfig) return
|
|
3926
|
+
if (Object.keys(endpointConfig).length === 0 && !needsBlobConfig) return hasRequestConfigParam ? AXIOS_REQUEST_CONFIG_NAME : "";
|
|
3919
3927
|
const lines = [];
|
|
3920
3928
|
lines.push("{");
|
|
3921
|
-
if (
|
|
3929
|
+
if (hasRequestConfigParam) lines.push(` ...${AXIOS_REQUEST_CONFIG_NAME},`);
|
|
3922
3930
|
if (endpointConfig.params) {
|
|
3923
3931
|
lines.push(" params: {");
|
|
3924
3932
|
for (const param of endpointConfig.params) {
|
|
@@ -4093,11 +4101,12 @@ function generateQueries(params) {
|
|
|
4093
4101
|
const endpointGroups = groupEndpoints(endpoints, resolver);
|
|
4094
4102
|
const hasAxiosRequestConfig = resolver.options.axiosRequestConfig;
|
|
4095
4103
|
const hasAxiosDefaultImport = endpoints.some(({ mediaUpload }) => mediaUpload);
|
|
4096
|
-
const
|
|
4104
|
+
const hasGetEndpoints = endpoints.some((endpoint) => endpoint.method === "get");
|
|
4105
|
+
const hasAxiosImport = hasAxiosRequestConfig || hasAxiosDefaultImport || hasGetEndpoints;
|
|
4097
4106
|
const axiosImport = {
|
|
4098
4107
|
defaultImport: hasAxiosDefaultImport ? AXIOS_DEFAULT_IMPORT_NAME : void 0,
|
|
4099
4108
|
bindings: [],
|
|
4100
|
-
typeBindings:
|
|
4109
|
+
typeBindings: hasAxiosImport ? [AXIOS_REQUEST_CONFIG_TYPE] : [],
|
|
4101
4110
|
from: AXIOS_IMPORT.from
|
|
4102
4111
|
};
|
|
4103
4112
|
const { queryEndpoints, infiniteQueryEndpoints, mutationEndpoints, aclEndpoints } = endpointGroups;
|
|
@@ -4128,7 +4137,7 @@ function generateQueries(params) {
|
|
|
4128
4137
|
from: ACL_PACKAGE_IMPORT_PATH
|
|
4129
4138
|
};
|
|
4130
4139
|
const queryTypesImport = {
|
|
4131
|
-
bindings: [...hasMutationDefaultOnError ? ["OpenApiQueryConfig"] : []],
|
|
4140
|
+
bindings: [...queryEndpoints.length > 0 || infiniteQueryEndpoints.length > 0 || hasMutationDefaultOnError ? ["OpenApiQueryConfig"] : []],
|
|
4132
4141
|
typeBindings: [
|
|
4133
4142
|
...queryEndpoints.length > 0 ? [QUERY_OPTIONS_TYPES.query] : [],
|
|
4134
4143
|
...resolver.options.infiniteQueries && infiniteQueryEndpoints.length > 0 ? [QUERY_OPTIONS_TYPES.infiniteQuery] : [],
|
|
@@ -4431,9 +4440,10 @@ function renderInlineEndpoints({ resolver, endpoints, tag }) {
|
|
|
4431
4440
|
const endpointBody = getEndpointBody$1(endpoint);
|
|
4432
4441
|
const hasUndefinedEndpointBody = requiresBody(endpoint) && !endpointBody && hasEndpointConfig(endpoint, resolver);
|
|
4433
4442
|
const endpointConfig = renderInlineEndpointConfig(resolver, endpoint, tag);
|
|
4434
|
-
|
|
4443
|
+
const hasRequestConfigParam = resolver.options.axiosRequestConfig || endpoint.method === "get";
|
|
4444
|
+
lines.push(`const ${getEndpointName(endpoint)} = (${endpointParams}${hasRequestConfigParam ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}?: ${getRequestConfigType()}` : ""}) => {`);
|
|
4435
4445
|
lines.push(` return ${APP_REST_CLIENT_NAME}.${endpoint.method}(`);
|
|
4436
|
-
lines.push(`
|
|
4446
|
+
lines.push(` ${renderInlineRequestInfo(resolver, endpoint, tag)},`);
|
|
4437
4447
|
lines.push(` \`${getEndpointPath(endpoint)}\`,`);
|
|
4438
4448
|
if (endpointBody) lines.push(` ${resolver.options.parseRequestParams ? renderInlineEndpointParamParse(resolver, endpointBody, endpointBody.name, tag) : endpointBody.name},`);
|
|
4439
4449
|
else if (hasUndefinedEndpointBody) lines.push(" undefined,");
|
|
@@ -4444,6 +4454,12 @@ function renderInlineEndpoints({ resolver, endpoints, tag }) {
|
|
|
4444
4454
|
}
|
|
4445
4455
|
return lines;
|
|
4446
4456
|
}
|
|
4457
|
+
function renderInlineRequestInfo(resolver, endpoint, tag) {
|
|
4458
|
+
return `{ resSchema: ${getImportedZodSchemaName(resolver, endpoint.response, tag)} }`;
|
|
4459
|
+
}
|
|
4460
|
+
function getRequestConfigType() {
|
|
4461
|
+
return `${AXIOS_REQUEST_CONFIG_TYPE} & { allowInvalidResponseData?: boolean }`;
|
|
4462
|
+
}
|
|
4447
4463
|
function renderInlineEndpointParamParse(resolver, param, paramName, modelNamespaceTag) {
|
|
4448
4464
|
const addOptional = !(param.parameterObject ?? param.bodyObject)?.required && (Boolean(param.parameterSortingEnumSchemaName) || isNamedZodSchema(param.zodSchema));
|
|
4449
4465
|
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()" : ""}`;
|
|
@@ -4458,12 +4474,12 @@ function getSortingPresenceChain(resolver, param) {
|
|
|
4458
4474
|
}
|
|
4459
4475
|
function renderInlineEndpointConfig(resolver, endpoint, modelNamespaceTag) {
|
|
4460
4476
|
const endpointConfig = getEndpointConfig(endpoint);
|
|
4461
|
-
const
|
|
4477
|
+
const hasRequestConfigParam = resolver.options.axiosRequestConfig || endpoint.method === "get";
|
|
4462
4478
|
const needsBlobConfig = endpoint.mediaDownload || endpoint.response === "z.instanceof(Blob)";
|
|
4463
|
-
if (Object.keys(endpointConfig).length === 0 && !needsBlobConfig) return
|
|
4479
|
+
if (Object.keys(endpointConfig).length === 0 && !needsBlobConfig) return hasRequestConfigParam ? AXIOS_REQUEST_CONFIG_NAME : "";
|
|
4464
4480
|
const lines = [];
|
|
4465
4481
|
lines.push("{");
|
|
4466
|
-
if (
|
|
4482
|
+
if (hasRequestConfigParam) lines.push(` ...${AXIOS_REQUEST_CONFIG_NAME},`);
|
|
4467
4483
|
if (endpointConfig.params) {
|
|
4468
4484
|
lines.push(" params: {");
|
|
4469
4485
|
for (const param of endpointConfig.params) {
|
|
@@ -4483,19 +4499,19 @@ function renderInlineEndpointConfig(resolver, endpoint, modelNamespaceTag) {
|
|
|
4483
4499
|
return lines.join("\n");
|
|
4484
4500
|
}
|
|
4485
4501
|
function renderQueryOptions({ resolver, endpoint, inlineEndpoints }) {
|
|
4486
|
-
const
|
|
4502
|
+
const hasRequestConfigParam = resolver.options.axiosRequestConfig || endpoint.method === "get";
|
|
4487
4503
|
const endpointParams = renderEndpointParams(resolver, endpoint, { modelNamespaceTag: getEndpointTag(endpoint, resolver.options) });
|
|
4488
4504
|
const endpointArgs = renderEndpointArgs(resolver, endpoint, {});
|
|
4489
4505
|
const endpointFunction = inlineEndpoints ? getEndpointName(endpoint) : getImportedEndpointName(endpoint, resolver.options);
|
|
4490
4506
|
const lines = [];
|
|
4491
|
-
lines.push(`const ${getQueryOptionsName(endpoint)} = (${endpointParams ? `{ ${endpointArgs} }: { ${endpointParams} }` : ""}${
|
|
4507
|
+
lines.push(`const ${getQueryOptionsName(endpoint)} = (${endpointParams ? `{ ${endpointArgs} }: { ${endpointParams} }` : ""}${hasRequestConfigParam ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}?: ${getRequestConfigType()}` : ""}) => ({`);
|
|
4492
4508
|
lines.push(` queryKey: keys.${getEndpointName(endpoint)}(${endpointArgs}),`);
|
|
4493
|
-
lines.push(` queryFn: () => ${endpointFunction}(${endpointArgs}${
|
|
4509
|
+
lines.push(` queryFn: () => ${endpointFunction}(${endpointArgs}${hasRequestConfigParam ? `${endpointArgs ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""}),`);
|
|
4494
4510
|
lines.push("});");
|
|
4495
4511
|
return lines.join("\n");
|
|
4496
4512
|
}
|
|
4497
4513
|
function renderInfiniteQueryOptions({ resolver, endpoint, inlineEndpoints }) {
|
|
4498
|
-
const
|
|
4514
|
+
const hasRequestConfigParam = resolver.options.axiosRequestConfig || endpoint.method === "get";
|
|
4499
4515
|
const endpointParams = renderEndpointParams(resolver, endpoint, {
|
|
4500
4516
|
excludePageParam: true,
|
|
4501
4517
|
modelNamespaceTag: getEndpointTag(endpoint, resolver.options)
|
|
@@ -4504,9 +4520,9 @@ function renderInfiniteQueryOptions({ resolver, endpoint, inlineEndpoints }) {
|
|
|
4504
4520
|
const endpointArgsWithPage = renderEndpointArgs(resolver, endpoint, { replacePageParam: true });
|
|
4505
4521
|
const endpointFunction = inlineEndpoints ? getEndpointName(endpoint) : getImportedEndpointName(endpoint, resolver.options);
|
|
4506
4522
|
const lines = [];
|
|
4507
|
-
lines.push(`const ${getInfiniteQueryOptionsName(endpoint)} = (${endpointParams ? `{ ${endpointArgsWithoutPage} }: { ${endpointParams} }` : ""}${
|
|
4523
|
+
lines.push(`const ${getInfiniteQueryOptionsName(endpoint)} = (${endpointParams ? `{ ${endpointArgsWithoutPage} }: { ${endpointParams} }` : ""}${hasRequestConfigParam ? `${endpointParams ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}?: ${getRequestConfigType()}` : ""}) => ({`);
|
|
4508
4524
|
lines.push(` queryKey: keys.${getEndpointName(endpoint)}Infinite(${endpointArgsWithoutPage}),`);
|
|
4509
|
-
lines.push(` queryFn: ({ pageParam }: { pageParam: number }) => ${endpointFunction}(${endpointArgsWithPage}${
|
|
4525
|
+
lines.push(` queryFn: ({ pageParam }: { pageParam: number }) => ${endpointFunction}(${endpointArgsWithPage}${hasRequestConfigParam ? `, ${AXIOS_REQUEST_CONFIG_NAME}` : ""}),`);
|
|
4510
4526
|
lines.push(" initialPageParam: 1,");
|
|
4511
4527
|
lines.push(` getNextPageParam: ({ ${resolver.options.infiniteQueryResponseParamNames.page}, ${resolver.options.infiniteQueryResponseParamNames.totalItems}, ${resolver.options.infiniteQueryResponseParamNames.limit}: limitParam }: Awaited<ReturnType<typeof ${endpointFunction}>>) => {`);
|
|
4512
4528
|
lines.push(` const pageParam = ${resolver.options.infiniteQueryResponseParamNames.page} ?? 1;`);
|
|
@@ -4553,7 +4569,8 @@ function renderQuery({ resolver, endpoint, inlineEndpoints }) {
|
|
|
4553
4569
|
});
|
|
4554
4570
|
const queryOptionsName = getQueryOptionsName(endpoint);
|
|
4555
4571
|
const hasQueryFnOverride = hasAclCheck;
|
|
4556
|
-
const
|
|
4572
|
+
const requestConfig = `{ ${hasAxiosRequestConfig ? `...${AXIOS_REQUEST_CONFIG_NAME}, ` : ""}allowInvalidResponseData: queryConfig.allowInvalidResponseData }`;
|
|
4573
|
+
const queryOptionsArgs = `${resolvedEndpointArgs ? `{ ${resolvedEndpointArgs} }, ` : ""}${requestConfig}`;
|
|
4557
4574
|
const lines = [];
|
|
4558
4575
|
lines.push(renderQueryJsDocs({
|
|
4559
4576
|
resolver,
|
|
@@ -4562,7 +4579,11 @@ function renderQuery({ resolver, endpoint, inlineEndpoints }) {
|
|
|
4562
4579
|
tag
|
|
4563
4580
|
}));
|
|
4564
4581
|
lines.push(`export const ${getQueryName(endpoint)} = <TData>(${endpointParams ? `{ ${endpointArgs} }: { ${endpointParams} }, ` : ""}options?: AppQueryOptions<typeof ${inlineEndpoints ? getEndpointName(endpoint) : getImportedEndpointName(endpoint, resolver.options)}, TData>${hasAxiosRequestConfig ? `, ${AXIOS_REQUEST_CONFIG_NAME}?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => {`);
|
|
4565
|
-
|
|
4582
|
+
lines.push(" const queryConfig = OpenApiQueryConfig.useConfig();");
|
|
4583
|
+
if (hasAclCheck) {
|
|
4584
|
+
lines.push(` const { checkAcl } = ${ACL_CHECK_HOOK}();`);
|
|
4585
|
+
lines.push(" const { skipAcl, ...queryOptions } = options ?? {};");
|
|
4586
|
+
}
|
|
4566
4587
|
lines.push(...renderWorkspaceParamResolutions({
|
|
4567
4588
|
replacements: workspaceParamReplacements,
|
|
4568
4589
|
paramTypes: workspaceParamTypes,
|
|
@@ -4573,11 +4594,15 @@ function renderQuery({ resolver, endpoint, inlineEndpoints }) {
|
|
|
4573
4594
|
lines.push(` ...${queryOptionsName}(${queryOptionsArgs}),`);
|
|
4574
4595
|
if (hasQueryFnOverride) {
|
|
4575
4596
|
lines.push(" queryFn: async () => {");
|
|
4576
|
-
if (hasAclCheck)
|
|
4597
|
+
if (hasAclCheck) {
|
|
4598
|
+
lines.push(" if (!skipAcl) {");
|
|
4599
|
+
lines.push(renderAclCheckCall(resolver, endpoint, workspaceParamReplacements, " "));
|
|
4600
|
+
lines.push(" }");
|
|
4601
|
+
}
|
|
4577
4602
|
lines.push(` return ${queryOptionsName}(${queryOptionsArgs}).queryFn();`);
|
|
4578
4603
|
lines.push(" },");
|
|
4579
4604
|
}
|
|
4580
|
-
lines.push("
|
|
4605
|
+
lines.push(` ...${hasAclCheck ? "queryOptions" : "options"},`);
|
|
4581
4606
|
lines.push(" });");
|
|
4582
4607
|
lines.push("};");
|
|
4583
4608
|
return lines.join("\n");
|
|
@@ -4632,7 +4657,10 @@ function renderMutation({ resolver, endpoint, inlineEndpoints, precomputed }) {
|
|
|
4632
4657
|
}));
|
|
4633
4658
|
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}` : ""}) => {`);
|
|
4634
4659
|
if (hasMutationDefaultOnError) lines.push(" const queryConfig = OpenApiQueryConfig.useConfig();");
|
|
4635
|
-
if (hasAclCheck)
|
|
4660
|
+
if (hasAclCheck) {
|
|
4661
|
+
lines.push(` const { checkAcl } = ${ACL_CHECK_HOOK}();`);
|
|
4662
|
+
lines.push(" const { skipAcl, ...queryOptions } = options ?? {};");
|
|
4663
|
+
}
|
|
4636
4664
|
lines.push(...renderWorkspaceContextDestructure({
|
|
4637
4665
|
replacements: workspaceParamReplacements,
|
|
4638
4666
|
paramTypes: workspaceParamTypes,
|
|
@@ -4653,7 +4681,11 @@ function renderMutation({ resolver, endpoint, inlineEndpoints, precomputed }) {
|
|
|
4653
4681
|
replacements: workspaceParamReplacements,
|
|
4654
4682
|
indent: " "
|
|
4655
4683
|
}));
|
|
4656
|
-
if (hasAclCheck)
|
|
4684
|
+
if (hasAclCheck) {
|
|
4685
|
+
lines.push(" if (!skipAcl) {");
|
|
4686
|
+
lines.push(renderAclCheckCall(resolver, endpoint, workspaceParamReplacements, " "));
|
|
4687
|
+
lines.push(" }");
|
|
4688
|
+
}
|
|
4657
4689
|
if (endpoint.mediaUpload) {
|
|
4658
4690
|
lines.push(` const uploadInstructions = await ${endpointFunction}(${resolvedEndpointArgs}${hasAxiosRequestConfig ? `${resolvedEndpointArgs ? ", " : ""}${AXIOS_REQUEST_CONFIG_NAME}` : ""});`);
|
|
4659
4691
|
lines.push(" ");
|
|
@@ -4688,8 +4720,8 @@ function renderMutation({ resolver, endpoint, inlineEndpoints, precomputed }) {
|
|
|
4688
4720
|
const scopePathParamInterpolations = scopePathParams.map((p) => `:\${${p.name}}`).join("");
|
|
4689
4721
|
lines.push(` scope: { id: \`${getEndpointName(endpoint)}${scopePathParamInterpolations}\` },`);
|
|
4690
4722
|
}
|
|
4691
|
-
lines.push("
|
|
4692
|
-
if (hasMutationDefaultOnError) lines.push(
|
|
4723
|
+
lines.push(` ...${hasAclCheck ? "queryOptions" : "options"},`);
|
|
4724
|
+
if (hasMutationDefaultOnError) lines.push(` onError: ${hasAclCheck ? "queryOptions" : "options"}?.onError ?? queryConfig.onError,`);
|
|
4693
4725
|
if (hasMutationEffects) {
|
|
4694
4726
|
lines.push(" onSuccess: async (resData, variables, onMutateResult, context) => {");
|
|
4695
4727
|
if (updateQueryEndpoints.length > 0) {
|
|
@@ -4701,9 +4733,9 @@ function renderMutation({ resolver, endpoint, inlineEndpoints, precomputed }) {
|
|
|
4701
4733
|
indent: " "
|
|
4702
4734
|
}));
|
|
4703
4735
|
lines.push(` const updateKeys = [${updateQueryEndpoints.map((e) => `keys.${getEndpointName(e)}(${renderEndpointArgs(resolver, e, { includeOnlyRequiredParams: true }, workspaceParamReplacements)})`).join(", ")}];`);
|
|
4704
|
-
lines.push(` await runMutationEffects(resData, variables, options, updateKeys);`);
|
|
4705
|
-
} else lines.push(
|
|
4706
|
-
lines.push("
|
|
4736
|
+
lines.push(` await runMutationEffects(resData, variables, ${hasAclCheck ? "queryOptions" : "options"}, updateKeys);`);
|
|
4737
|
+
} else lines.push(` await runMutationEffects(resData, variables, ${hasAclCheck ? "queryOptions" : "options"});`);
|
|
4738
|
+
lines.push(` ${hasAclCheck ? "queryOptions" : "options"}?.onSuccess?.(resData, variables, onMutateResult, context);`);
|
|
4707
4739
|
lines.push(" },");
|
|
4708
4740
|
}
|
|
4709
4741
|
lines.push(" });");
|
|
@@ -4761,7 +4793,8 @@ function renderInfiniteQuery({ resolver, endpoint, inlineEndpoints }) {
|
|
|
4761
4793
|
const endpointArgsWithoutPage = renderEndpointArgs(resolver, endpoint, { excludePageParam: true });
|
|
4762
4794
|
const resolvedEndpointArgsWithoutPage = renderEndpointObjectArgs(resolver, endpoint, { excludePageParam: true }, workspaceParamReplacements);
|
|
4763
4795
|
const queryOptionsName = getInfiniteQueryOptionsName(endpoint);
|
|
4764
|
-
const
|
|
4796
|
+
const requestConfig = `{ ${hasAxiosRequestConfig ? `...${AXIOS_REQUEST_CONFIG_NAME}, ` : ""}allowInvalidResponseData: queryConfig.allowInvalidResponseData }`;
|
|
4797
|
+
const queryOptionsArgs = `${resolvedEndpointArgsWithoutPage ? `{ ${resolvedEndpointArgsWithoutPage} }, ` : ""}${requestConfig}`;
|
|
4765
4798
|
const hasQueryFnOverride = hasAclCheck;
|
|
4766
4799
|
const lines = [];
|
|
4767
4800
|
lines.push(renderQueryJsDocs({
|
|
@@ -4771,7 +4804,11 @@ function renderInfiniteQuery({ resolver, endpoint, inlineEndpoints }) {
|
|
|
4771
4804
|
tag
|
|
4772
4805
|
}));
|
|
4773
4806
|
lines.push(`export const ${getInfiniteQueryName(endpoint)} = <TData>(${endpointParams ? `{ ${endpointArgsWithoutPage} }: { ${endpointParams} }, ` : ""}options?: AppInfiniteQueryOptions<typeof ${inlineEndpoints ? getEndpointName(endpoint) : getImportedEndpointName(endpoint, resolver.options)}, TData>${hasAxiosRequestConfig ? `, ${AXIOS_REQUEST_CONFIG_NAME}?: ${AXIOS_REQUEST_CONFIG_TYPE}` : ""}) => {`);
|
|
4774
|
-
|
|
4807
|
+
lines.push(" const queryConfig = OpenApiQueryConfig.useConfig();");
|
|
4808
|
+
if (hasAclCheck) {
|
|
4809
|
+
lines.push(` const { checkAcl } = ${ACL_CHECK_HOOK}();`);
|
|
4810
|
+
lines.push(" const { skipAcl, ...queryOptions } = options ?? {};");
|
|
4811
|
+
}
|
|
4775
4812
|
lines.push(...renderWorkspaceParamResolutions({
|
|
4776
4813
|
replacements: workspaceParamReplacements,
|
|
4777
4814
|
paramTypes: workspaceParamTypes,
|
|
@@ -4782,11 +4819,13 @@ function renderInfiniteQuery({ resolver, endpoint, inlineEndpoints }) {
|
|
|
4782
4819
|
lines.push(` ...${queryOptionsName}(${queryOptionsArgs}),`);
|
|
4783
4820
|
if (hasQueryFnOverride) {
|
|
4784
4821
|
lines.push(" queryFn: async ({ pageParam }) => {");
|
|
4785
|
-
lines.push(
|
|
4822
|
+
lines.push(" if (!skipAcl) {");
|
|
4823
|
+
lines.push(renderAclCheckCall(resolver, endpoint, workspaceParamReplacements, " "));
|
|
4824
|
+
lines.push(" }");
|
|
4786
4825
|
lines.push(` return ${queryOptionsName}(${queryOptionsArgs}).queryFn({ pageParam });`);
|
|
4787
4826
|
lines.push(" },");
|
|
4788
4827
|
}
|
|
4789
|
-
lines.push("
|
|
4828
|
+
lines.push(` ...${hasAclCheck ? "queryOptions" : "options"},`);
|
|
4790
4829
|
lines.push(" });");
|
|
4791
4830
|
lines.push("};");
|
|
4792
4831
|
return lines.join("\n");
|
package/dist/generator.d.mts
CHANGED
package/dist/generator.mjs
CHANGED
|
@@ -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-
|
|
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-x7KFQcSq.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 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-
|
|
2
|
-
import "./options-
|
|
3
|
-
import { t as OpenAPICodegenConfig } from "./config-
|
|
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-oM5YJYYH.mjs";
|
|
2
|
+
import "./options-BZOw7Hx4.mjs";
|
|
3
|
+
import { t as OpenAPICodegenConfig } from "./config-CrZa_Jbm.mjs";
|
|
4
4
|
import { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosResponseHeaders, CreateAxiosDefaults } from "axios";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import "i18next";
|
|
@@ -26,6 +26,7 @@ interface RequestInfo<ZOutput, ECodes extends string> {
|
|
|
26
26
|
}
|
|
27
27
|
interface RequestConfig<IsRawRes extends boolean = false> {
|
|
28
28
|
rawResponse?: IsRawRes;
|
|
29
|
+
allowInvalidResponseData?: boolean;
|
|
29
30
|
}
|
|
30
31
|
type Response<ZOutput, IsRawRes extends boolean = false> = IsRawRes extends true ? AxiosResponse<ZOutput> : ZOutput;
|
|
31
32
|
interface RestClient {
|
|
@@ -76,9 +77,12 @@ type Function = (...args: any) => any;
|
|
|
76
77
|
type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N;
|
|
77
78
|
type IsAny<T> = IfAny<T, true, never>;
|
|
78
79
|
type IsUnknown<T, Y, N = T> = IsAny<T> extends never ? (unknown extends T ? Y : N) : N;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
interface OpenApiAclCheckOptions {
|
|
81
|
+
skipAcl?: boolean;
|
|
82
|
+
}
|
|
83
|
+
type AppQueryOptions<TFunction extends Function, TData = Awaited<ReturnType<TFunction>>, TErrorCodes = GeneralErrorCodes> = Omit<UseQueryOptions<Awaited<ReturnType<TFunction>>, ApplicationException<TErrorCodes>, IsUnknown<TData, Awaited<ReturnType<TFunction>>>>, "queryKey" | "queryFn"> & OpenApiAclCheckOptions;
|
|
84
|
+
type AppMutationOptions<TFunction extends Function, TVariables = void, TData = Awaited<ReturnType<TFunction>>, TErrorCodes = GeneralErrorCodes> = Omit<UseMutationOptions<TData, ApplicationException<TErrorCodes>, TVariables>, "mutationKey" | "mutationFn"> & OpenApiAclCheckOptions;
|
|
85
|
+
type AppInfiniteQueryOptions<TFunction extends Function, TData = InfiniteData<Awaited<ReturnType<TFunction>>>, TErrorCodes = GeneralErrorCodes, TQueryKey extends QueryKey = QueryKey, TPageParam = number> = Omit<UseInfiniteQueryOptions<Awaited<ReturnType<TFunction>>, ApplicationException<TErrorCodes>, IsUnknown<TData, InfiniteData<Awaited<ReturnType<TFunction>>>>, TQueryKey, TPageParam>, "queryKey" | "queryFn" | "initialPageParam" | "getNextPageParam"> & OpenApiAclCheckOptions;
|
|
82
86
|
//#endregion
|
|
83
87
|
//#region src/lib/config/queryConfig.context.d.ts
|
|
84
88
|
type QueryModule = string | number | symbol;
|
|
@@ -90,6 +94,7 @@ declare namespace OpenApiQueryConfig {
|
|
|
90
94
|
invalidateCurrentModule?: boolean;
|
|
91
95
|
invalidationMap?: InvalidationMap<TQueryModule>;
|
|
92
96
|
crossTabInvalidation?: boolean;
|
|
97
|
+
allowInvalidResponseData?: boolean;
|
|
93
98
|
onError?: (error: unknown) => void;
|
|
94
99
|
}
|
|
95
100
|
type ProviderProps<TQueryModule extends QueryModule = QueryModule> = Type<TQueryModule>;
|
|
@@ -98,6 +103,7 @@ declare namespace OpenApiQueryConfig {
|
|
|
98
103
|
invalidateCurrentModule,
|
|
99
104
|
invalidationMap,
|
|
100
105
|
crossTabInvalidation,
|
|
106
|
+
allowInvalidResponseData,
|
|
101
107
|
onError,
|
|
102
108
|
children
|
|
103
109
|
}: PropsWithChildren<ProviderProps<TQueryModule>>): react_jsx_runtime0.JSX.Element;
|
package/dist/index.mjs
CHANGED
|
@@ -66,10 +66,18 @@ var RestClient = class {
|
|
|
66
66
|
async makeRequest(requestInfo, requestConfig) {
|
|
67
67
|
const errorStack = (/* @__PURE__ */ new Error()).stack;
|
|
68
68
|
try {
|
|
69
|
-
const { rawResponse, ...config } = requestConfig;
|
|
69
|
+
const { rawResponse, allowInvalidResponseData, ...config } = requestConfig;
|
|
70
70
|
const res = await this.client(config);
|
|
71
71
|
const responseData = res.status === 204 && res.data === "" ? void 0 : res.data;
|
|
72
|
-
const
|
|
72
|
+
const parseResult = requestInfo.resSchema.safeParse(responseData);
|
|
73
|
+
let resData;
|
|
74
|
+
if (parseResult.success) resData = parseResult.data;
|
|
75
|
+
else if (allowInvalidResponseData && config.method === "get") {
|
|
76
|
+
parseResult.error.name = "BE Response schema mismatch - ZodError";
|
|
77
|
+
parseResult.error.stack = [parseResult.error.stack, ...errorStack?.split("\n").slice(2) ?? []].join("\n");
|
|
78
|
+
console.error(parseResult.error);
|
|
79
|
+
resData = res.data;
|
|
80
|
+
} else throw parseResult.error;
|
|
73
81
|
return rawResponse ? {
|
|
74
82
|
...res,
|
|
75
83
|
data: resData
|
|
@@ -114,18 +122,20 @@ var RestInterceptor = class {
|
|
|
114
122
|
let OpenApiQueryConfig;
|
|
115
123
|
(function(_OpenApiQueryConfig) {
|
|
116
124
|
const Context = createContext({});
|
|
117
|
-
function Provider({ preferUpdate, invalidateCurrentModule, invalidationMap, crossTabInvalidation, onError, children }) {
|
|
125
|
+
function Provider({ preferUpdate, invalidateCurrentModule, invalidationMap, crossTabInvalidation, allowInvalidResponseData, onError, children }) {
|
|
118
126
|
const value = useMemo(() => ({
|
|
119
127
|
preferUpdate,
|
|
120
128
|
invalidateCurrentModule,
|
|
121
129
|
invalidationMap,
|
|
122
130
|
crossTabInvalidation,
|
|
131
|
+
allowInvalidResponseData,
|
|
123
132
|
onError
|
|
124
133
|
}), [
|
|
125
134
|
preferUpdate,
|
|
126
135
|
invalidateCurrentModule,
|
|
127
136
|
invalidationMap,
|
|
128
137
|
crossTabInvalidation,
|
|
138
|
+
allowInvalidResponseData,
|
|
129
139
|
onError
|
|
130
140
|
]);
|
|
131
141
|
return /* @__PURE__ */ jsx(Context.Provider, {
|
|
@@ -238,15 +248,18 @@ const AuthGuard = ({ type, redirectTo, children }) => {
|
|
|
238
248
|
useEffect(() => {
|
|
239
249
|
setHasMounted(true);
|
|
240
250
|
}, []);
|
|
251
|
+
const privateRedirectTo = redirectTo || routes?.unauthenticated || "/";
|
|
252
|
+
const publicRedirectTo = redirectTo || routes?.authenticated || "/";
|
|
253
|
+
const redirectTarget = type === "private" && !isAuthenticated ? privateRedirectTo : type === "public-only" && isAuthenticated ? publicRedirectTo : null;
|
|
254
|
+
useEffect(() => {
|
|
255
|
+
if (hasMounted && redirectTarget) replace(redirectTarget);
|
|
256
|
+
}, [
|
|
257
|
+
hasMounted,
|
|
258
|
+
redirectTarget,
|
|
259
|
+
replace
|
|
260
|
+
]);
|
|
241
261
|
if (!hasMounted) return loadingState;
|
|
242
|
-
if (
|
|
243
|
-
replace(redirectTo || routes?.unauthenticated || "/");
|
|
244
|
-
return null;
|
|
245
|
-
}
|
|
246
|
-
if (type === "public-only" && isAuthenticated) {
|
|
247
|
-
replace(redirectTo || routes?.authenticated || "/");
|
|
248
|
-
return null;
|
|
249
|
-
}
|
|
262
|
+
if (redirectTarget) return null;
|
|
250
263
|
return children;
|
|
251
264
|
};
|
|
252
265
|
|
package/dist/metro.d.mts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { r as GenerateFileFormatter } from "./options-BZOw7Hx4.mjs";
|
|
2
|
+
import { t as OpenAPICodegenConfig } from "./config-CrZa_Jbm.mjs";
|
|
3
|
+
import { IncomingMessage, ServerResponse } from "http";
|
|
4
|
+
|
|
5
|
+
//#region src/metro/openapi-codegen.plugin.d.ts
|
|
6
|
+
type OpenApiCodegenMetroConfig = OpenAPICodegenConfig & {
|
|
7
|
+
formatGeneratedFile?: GenerateFileFormatter;
|
|
8
|
+
};
|
|
9
|
+
type OpenApiCodegenMetroOptions = {
|
|
10
|
+
root?: string;
|
|
11
|
+
watchOpenApiInput?: boolean;
|
|
12
|
+
};
|
|
13
|
+
type MetroNextFunction = (error?: unknown) => void;
|
|
14
|
+
type MetroMiddleware = (request: IncomingMessage, response: ServerResponse, next: MetroNextFunction) => unknown;
|
|
15
|
+
type MetroServer = unknown;
|
|
16
|
+
type MetroConfig = {
|
|
17
|
+
projectRoot?: string;
|
|
18
|
+
server?: {
|
|
19
|
+
enhanceMiddleware?: (middleware: MetroMiddleware, server: MetroServer) => MetroMiddleware;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
};
|
|
22
|
+
transformer?: {
|
|
23
|
+
getTransformOptions?: (...args: unknown[]) => unknown;
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
};
|
|
26
|
+
watchFolders?: readonly string[];
|
|
27
|
+
[key: string]: unknown;
|
|
28
|
+
};
|
|
29
|
+
declare function withOpenApiCodegen<TMetroConfig extends MetroConfig>(metroConfig: Promise<TMetroConfig>, codegenConfig: OpenApiCodegenMetroConfig, options?: OpenApiCodegenMetroOptions): Promise<TMetroConfig>;
|
|
30
|
+
declare function withOpenApiCodegen<TMetroConfig extends MetroConfig>(metroConfig: TMetroConfig, codegenConfig: OpenApiCodegenMetroConfig, options?: OpenApiCodegenMetroOptions): TMetroConfig;
|
|
31
|
+
//#endregion
|
|
32
|
+
export { type MetroConfig, type MetroMiddleware, type OpenAPICodegenConfig, type OpenApiCodegenMetroConfig, type OpenApiCodegenMetroOptions, withOpenApiCodegen };
|
package/dist/metro.mjs
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import "./generateCodeFromOpenAPIDoc-x7KFQcSq.mjs";
|
|
2
|
+
import "./generate.runner-bJnq9ZZJ.mjs";
|
|
3
|
+
import { t as createOpenApiCodegenRunner } from "./openapi-codegen.runner-NNdDG0V4.mjs";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
|
|
7
|
+
//#region src/metro/openapi-codegen.plugin.ts
|
|
8
|
+
function withOpenApiCodegen(metroConfig, codegenConfig, options = {}) {
|
|
9
|
+
if (isPromiseLike(metroConfig)) return metroConfig.then((resolvedConfig) => withResolvedOpenApiCodegen(resolvedConfig, codegenConfig, options));
|
|
10
|
+
return withResolvedOpenApiCodegen(metroConfig, codegenConfig, options);
|
|
11
|
+
}
|
|
12
|
+
function withResolvedOpenApiCodegen(metroConfig, codegenConfig, options) {
|
|
13
|
+
const root = path.resolve(options.root ?? metroConfig.projectRoot ?? process.cwd());
|
|
14
|
+
const codegen = createOpenApiCodegenRunner(codegenConfig);
|
|
15
|
+
const originalEnhanceMiddleware = metroConfig.server?.enhanceMiddleware;
|
|
16
|
+
const originalGetTransformOptions = metroConfig.transformer?.getTransformOptions;
|
|
17
|
+
let startupSucceeded = false;
|
|
18
|
+
let inflightGenerate;
|
|
19
|
+
let inputWatcher;
|
|
20
|
+
const requestStartupGenerate = () => {
|
|
21
|
+
if (startupSucceeded) return Promise.resolve();
|
|
22
|
+
if (inflightGenerate) return inflightGenerate;
|
|
23
|
+
const attempt = codegen.enqueueGenerate(root).then(() => {
|
|
24
|
+
startupSucceeded = true;
|
|
25
|
+
inflightGenerate = void 0;
|
|
26
|
+
}, (error) => {
|
|
27
|
+
inflightGenerate = void 0;
|
|
28
|
+
throw error;
|
|
29
|
+
});
|
|
30
|
+
inflightGenerate = attempt;
|
|
31
|
+
return attempt;
|
|
32
|
+
};
|
|
33
|
+
const ensureInputWatcher = () => {
|
|
34
|
+
if (options.watchOpenApiInput === false || inputWatcher) return;
|
|
35
|
+
const inputPath = codegen.getLocalInputPath(root);
|
|
36
|
+
if (!inputPath) return;
|
|
37
|
+
try {
|
|
38
|
+
inputWatcher = fs.watch(inputPath, { persistent: false }, () => {
|
|
39
|
+
startupSucceeded = false;
|
|
40
|
+
requestStartupGenerate().catch(reportGenerateError);
|
|
41
|
+
});
|
|
42
|
+
inputWatcher.on("error", reportWatcherError);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
reportWatcherError(error);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const wrappedConfig = {
|
|
48
|
+
...metroConfig,
|
|
49
|
+
server: {
|
|
50
|
+
...metroConfig.server,
|
|
51
|
+
enhanceMiddleware(middleware, server) {
|
|
52
|
+
ensureInputWatcher();
|
|
53
|
+
const enhancedMiddleware = originalEnhanceMiddleware ? originalEnhanceMiddleware(middleware, server) : middleware;
|
|
54
|
+
return async (request, response, next) => {
|
|
55
|
+
try {
|
|
56
|
+
await requestStartupGenerate();
|
|
57
|
+
return await enhancedMiddleware(request, response, next);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
next(error);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
transformer: {
|
|
65
|
+
...metroConfig.transformer,
|
|
66
|
+
async getTransformOptions(...args) {
|
|
67
|
+
await requestStartupGenerate();
|
|
68
|
+
return originalGetTransformOptions ? originalGetTransformOptions(...args) : void 0;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
if (options.root || metroConfig.projectRoot) wrappedConfig.projectRoot = root;
|
|
73
|
+
return wrappedConfig;
|
|
74
|
+
}
|
|
75
|
+
function isPromiseLike(value) {
|
|
76
|
+
return typeof value.then === "function";
|
|
77
|
+
}
|
|
78
|
+
function reportGenerateError(error) {
|
|
79
|
+
console.error("[openapi-codegen] Failed to generate OpenAPI client from Metro config.", error);
|
|
80
|
+
}
|
|
81
|
+
function reportWatcherError(error) {
|
|
82
|
+
console.error("[openapi-codegen] Failed to watch OpenAPI input from Metro config.", error);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
//#endregion
|
|
86
|
+
export { withOpenApiCodegen };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { S as Profiler } from "./generateCodeFromOpenAPIDoc-x7KFQcSq.mjs";
|
|
2
|
+
import { t as runGenerate } from "./generate.runner-bJnq9ZZJ.mjs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
|
|
5
|
+
//#region src/plugins/openapi-codegen.runner.ts
|
|
6
|
+
function createOpenApiCodegenRunner(config) {
|
|
7
|
+
let queue = Promise.resolve();
|
|
8
|
+
const { formatGeneratedFile, ...fileConfig } = config;
|
|
9
|
+
const enqueueGenerate = (root) => {
|
|
10
|
+
const run = queue.catch(() => void 0).then(async () => {
|
|
11
|
+
const profiler = new Profiler(process.env.OPENAPI_CODEGEN_PROFILE === "1");
|
|
12
|
+
await runGenerate({
|
|
13
|
+
fileConfig: normalizeOpenApiCodegenPaths(fileConfig, root),
|
|
14
|
+
formatGeneratedFile,
|
|
15
|
+
profiler
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
queue = run.then(() => void 0, () => void 0);
|
|
19
|
+
return run;
|
|
20
|
+
};
|
|
21
|
+
return {
|
|
22
|
+
enqueueGenerate,
|
|
23
|
+
getLocalInputPath: (root) => getLocalInputPath(config.input, root),
|
|
24
|
+
isLocalInput: isLocalOpenApiInput(config.input)
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function normalizeOpenApiCodegenPaths(config, root) {
|
|
28
|
+
const normalized = { ...config };
|
|
29
|
+
if (typeof normalized.output === "string" && !path.isAbsolute(normalized.output)) normalized.output = path.resolve(root, normalized.output);
|
|
30
|
+
if (typeof normalized.input === "string" && !path.isAbsolute(normalized.input) && isLocalOpenApiInput(normalized.input)) normalized.input = path.resolve(root, normalized.input);
|
|
31
|
+
return normalized;
|
|
32
|
+
}
|
|
33
|
+
function getLocalInputPath(input, root) {
|
|
34
|
+
if (!isLocalOpenApiInput(input)) return;
|
|
35
|
+
return path.resolve(root, input);
|
|
36
|
+
}
|
|
37
|
+
function isLocalOpenApiInput(input) {
|
|
38
|
+
return typeof input === "string" && !/^https?:\/\//i.test(input);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
//#endregion
|
|
42
|
+
export { createOpenApiCodegenRunner as t };
|
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-
|
|
3
|
-
import { n as resolveConfig, t as runGenerate } from "./generate.runner-
|
|
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-x7KFQcSq.mjs";
|
|
3
|
+
import { n as resolveConfig, t as runGenerate } from "./generate.runner-bJnq9ZZJ.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.
|
|
42
|
+
return "3.0.0-rc.16";
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
//#endregion
|
package/dist/vite.d.mts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { r as GenerateFileFormatter } from "./options-
|
|
2
|
-
import { t as OpenAPICodegenConfig } from "./config-
|
|
1
|
+
import { r as GenerateFileFormatter } from "./options-BZOw7Hx4.mjs";
|
|
2
|
+
import { t as OpenAPICodegenConfig } from "./config-CrZa_Jbm.mjs";
|
|
3
3
|
import { Plugin } from "vite";
|
|
4
4
|
|
|
5
|
-
//#region src/
|
|
6
|
-
type
|
|
5
|
+
//#region src/plugins/openapi-codegen.runner.d.ts
|
|
6
|
+
type OpenApiCodegenPluginConfig = OpenAPICodegenConfig & {
|
|
7
7
|
formatGeneratedFile?: GenerateFileFormatter;
|
|
8
8
|
};
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/vite/openapi-codegen.plugin.d.ts
|
|
11
|
+
type OpenApiCodegenViteConfig = OpenApiCodegenPluginConfig;
|
|
9
12
|
declare function openApiCodegen(config: OpenApiCodegenViteConfig): Plugin;
|
|
10
13
|
//#endregion
|
|
11
14
|
export { type OpenAPICodegenConfig, type OpenApiCodegenViteConfig, openApiCodegen };
|
package/dist/vite.mjs
CHANGED
|
@@ -1,28 +1,20 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import "./generateCodeFromOpenAPIDoc-x7KFQcSq.mjs";
|
|
2
|
+
import "./generate.runner-bJnq9ZZJ.mjs";
|
|
3
|
+
import { t as createOpenApiCodegenRunner } from "./openapi-codegen.runner-NNdDG0V4.mjs";
|
|
3
4
|
import path from "path";
|
|
4
5
|
|
|
5
6
|
//#region src/vite/openapi-codegen.plugin.ts
|
|
6
7
|
function openApiCodegen(config) {
|
|
7
8
|
let resolvedViteConfig;
|
|
8
|
-
|
|
9
|
-
const isLocalInput = typeof config.input === "string" && !/^https?:\/\//i.test(config.input);
|
|
10
|
-
const { formatGeneratedFile, ...normalizedConfig } = config;
|
|
9
|
+
const codegen = createOpenApiCodegenRunner(config);
|
|
11
10
|
const enqueueGenerate = () => {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
await runGenerate({
|
|
16
|
-
fileConfig: normalizePaths(normalizedConfig, currentConfig.root),
|
|
17
|
-
formatGeneratedFile,
|
|
18
|
-
profiler: new Profiler(process.env.OPENAPI_CODEGEN_PROFILE === "1")
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
return queue;
|
|
11
|
+
const currentConfig = resolvedViteConfig;
|
|
12
|
+
if (!currentConfig) return Promise.resolve();
|
|
13
|
+
return codegen.enqueueGenerate(currentConfig.root);
|
|
22
14
|
};
|
|
23
15
|
const setupWatcher = (server) => {
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
const openApiPath = codegen.getLocalInputPath(server.config.root);
|
|
17
|
+
if (!openApiPath) return;
|
|
26
18
|
server.watcher.add(openApiPath);
|
|
27
19
|
server.watcher.on("change", (changedPath) => {
|
|
28
20
|
if (path.resolve(changedPath) === openApiPath) enqueueGenerate();
|
|
@@ -42,12 +34,6 @@ function openApiCodegen(config) {
|
|
|
42
34
|
}
|
|
43
35
|
};
|
|
44
36
|
}
|
|
45
|
-
function normalizePaths(config, root) {
|
|
46
|
-
const normalized = { ...config };
|
|
47
|
-
if (typeof normalized.output === "string" && !path.isAbsolute(normalized.output)) normalized.output = path.resolve(root, normalized.output);
|
|
48
|
-
if (typeof normalized.input === "string" && !path.isAbsolute(normalized.input) && !/^https?:\/\//i.test(normalized.input)) normalized.input = path.resolve(root, normalized.input);
|
|
49
|
-
return normalized;
|
|
50
|
-
}
|
|
51
37
|
|
|
52
38
|
//#endregion
|
|
53
39
|
export { openApiCodegen };
|
package/dist/zod.d.mts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@povio/openapi-codegen-cli",
|
|
3
|
-
"version": "3.0.0-rc.14",
|
|
4
3
|
"keywords": [
|
|
5
4
|
"codegen",
|
|
6
5
|
"openapi",
|
|
@@ -35,6 +34,10 @@
|
|
|
35
34
|
"types": "./dist/vite.d.mts",
|
|
36
35
|
"import": "./dist/vite.mjs"
|
|
37
36
|
},
|
|
37
|
+
"./metro": {
|
|
38
|
+
"types": "./dist/metro.d.mts",
|
|
39
|
+
"import": "./dist/metro.mjs"
|
|
40
|
+
},
|
|
38
41
|
"./generator": {
|
|
39
42
|
"types": "./dist/generator.d.mts",
|
|
40
43
|
"import": "./dist/generator.mjs"
|
|
@@ -127,5 +130,6 @@
|
|
|
127
130
|
"node": ">= 14",
|
|
128
131
|
"pnpm": ">= 9"
|
|
129
132
|
},
|
|
130
|
-
"packageManager": "pnpm@10.4.0"
|
|
133
|
+
"packageManager": "pnpm@10.4.0",
|
|
134
|
+
"version": "3.0.0-rc.16"
|
|
131
135
|
}
|
|
File without changes
|
|
File without changes
|