@7nohe/openapi-react-query-codegen 2.0.0 → 2.2.0
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/dist/common.mjs +6 -13
- package/dist/constants.mjs +1 -1
- package/dist/createExports.mjs +11 -9
- package/dist/createImports.mjs +6 -6
- package/dist/createUseMutation.mjs +11 -5
- package/dist/createUseQuery.mjs +16 -6
- package/dist/generate.mjs +41 -23
- package/dist/service.mjs +45 -26
- package/package.json +8 -8
package/dist/common.mjs
CHANGED
|
@@ -192,22 +192,15 @@ function mutationKeyFn(mutationKey) {
|
|
|
192
192
|
], false);
|
|
193
193
|
}
|
|
194
194
|
export function getRequestParamFromMethod(method, pageParam, modelNames = []) {
|
|
195
|
-
|
|
195
|
+
const sdkParams = getVariableArrowFunctionParameters(method);
|
|
196
|
+
if (!sdkParams.length) {
|
|
196
197
|
return null;
|
|
197
198
|
}
|
|
198
199
|
const methodName = getNameFromVariable(method);
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
.map((refParam) => ({
|
|
204
|
-
name: refParam.name,
|
|
205
|
-
// TODO: Client<Request, Response, unknown, RequestOptions> -> Client<Request, Response, unknown>
|
|
206
|
-
typeName: getShortType(refParam.type?.getText() ?? ""),
|
|
207
|
-
optional: refParam.optional,
|
|
208
|
-
}));
|
|
209
|
-
});
|
|
210
|
-
const areAllPropertiesOptional = params.every((param) => param.optional);
|
|
200
|
+
// Use the SDK function's parameter optionality as the authoritative check.
|
|
201
|
+
// Generic types like Options<XData, ThrowOnError> may not resolve correctly
|
|
202
|
+
// via extractPropertiesFromObjectParam for type alias properties (path, url).
|
|
203
|
+
const areAllPropertiesOptional = sdkParams[0].isOptional();
|
|
211
204
|
return ts.factory.createParameterDeclaration(undefined, undefined, ts.factory.createIdentifier("clientOptions"), undefined, ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Options"), [
|
|
212
205
|
ts.factory.createTypeReferenceNode(modelNames.includes(`${capitalizeFirstLetter(methodName)}Data`)
|
|
213
206
|
? `${capitalizeFirstLetter(methodName)}Data`
|
package/dist/constants.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const defaultOutputPath = "openapi";
|
|
2
2
|
export const queriesOutputPath = "queries";
|
|
3
3
|
export const requestsOutputPath = "requests";
|
|
4
|
-
export const serviceFileName = "
|
|
4
|
+
export const serviceFileName = "sdk.gen";
|
|
5
5
|
export const modelsFileName = "types.gen";
|
|
6
6
|
export const OpenApiRqFiles = {
|
|
7
7
|
queries: "queries",
|
package/dist/createExports.mjs
CHANGED
|
@@ -24,14 +24,16 @@ export const createExports = ({ service, client, project, pageParam, nextPagePar
|
|
|
24
24
|
if (ts.isTypeAliasDeclaration(node) && methodDataNames[key] !== undefined) {
|
|
25
25
|
// get the type alias declaration
|
|
26
26
|
const typeAliasDeclaration = node.type;
|
|
27
|
-
if (
|
|
28
|
-
const query = typeAliasDeclaration.members.find((m) => m.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
if (ts.isTypeLiteralNode(typeAliasDeclaration)) {
|
|
28
|
+
const query = typeAliasDeclaration.members.find((m) => ts.isPropertySignature(m) && m.name?.getText() === "query");
|
|
29
|
+
if (query) {
|
|
30
|
+
const queryType = query.type;
|
|
31
|
+
const members = queryType && ts.isTypeLiteralNode(queryType)
|
|
32
|
+
? queryType.members
|
|
33
|
+
: undefined;
|
|
34
|
+
if (members?.map((m) => m.name?.getText()).includes(pageParam)) {
|
|
35
|
+
paginatableMethods.push(methodDataNames[key]);
|
|
36
|
+
}
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
}
|
|
@@ -82,7 +84,7 @@ export const createExports = ({ service, client, project, pageParam, nextPagePar
|
|
|
82
84
|
const mainExports = [...mainQueries, ...mainMutations];
|
|
83
85
|
const infiniteQueriesExports = allQueries
|
|
84
86
|
.flatMap(({ infiniteQueryHook }) => [infiniteQueryHook])
|
|
85
|
-
.filter(
|
|
87
|
+
.filter((x) => x != null);
|
|
86
88
|
const suspenseQueries = allQueries.flatMap(({ suspenseQueryHook }) => [
|
|
87
89
|
suspenseQueryHook,
|
|
88
90
|
]);
|
package/dist/createImports.mjs
CHANGED
|
@@ -16,13 +16,13 @@ export const createImports = ({ project, client, }) => {
|
|
|
16
16
|
? Array.from(modelsFile.getExportedDeclarations().keys())
|
|
17
17
|
: [];
|
|
18
18
|
const serviceExports = Array.from(serviceFile.getExportedDeclarations().keys());
|
|
19
|
-
|
|
19
|
+
// Filter out type-only exports (e.g. Options) to avoid duplicate imports,
|
|
20
|
+
// since Options is already imported separately from the client module.
|
|
21
|
+
const serviceNames = serviceExports.filter((name) => name !== "Options");
|
|
20
22
|
const imports = [
|
|
21
|
-
ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(
|
|
22
|
-
ts.factory.createImportSpecifier(
|
|
23
|
-
])), ts.factory.createStringLiteral(
|
|
24
|
-
? "@hey-api/client-axios"
|
|
25
|
-
: "@hey-api/client-fetch"), undefined),
|
|
23
|
+
ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(true, undefined, ts.factory.createNamedImports([
|
|
24
|
+
ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("Options")),
|
|
25
|
+
])), ts.factory.createStringLiteral(join("../requests", serviceFileName)), undefined),
|
|
26
26
|
ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports([
|
|
27
27
|
ts.factory.createImportSpecifier(true, undefined, ts.factory.createIdentifier("QueryClient")),
|
|
28
28
|
ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier("useQuery")),
|
|
@@ -23,11 +23,17 @@ export const createUseMutation = ({ functionDescription: { method, jsDoc }, mode
|
|
|
23
23
|
const responseDataType = ts.factory.createTypeParameterDeclaration(undefined, TData, undefined, ts.factory.createTypeReferenceNode(BuildCommonTypeName(mutationResult.name)));
|
|
24
24
|
// @hey-api/client-axios -> `TError = AxiosError<AddPetError>`
|
|
25
25
|
// @hey-api/client-fetch -> `TError = AddPetError`
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
const errorTypeName = `${capitalizeFirstLetter(methodName)}Error`;
|
|
27
|
+
const hasErrorType = modelNames.includes(errorTypeName);
|
|
28
|
+
const responseErrorType = ts.factory.createTypeParameterDeclaration(undefined, TError, undefined, hasErrorType
|
|
29
|
+
? client === "@hey-api/client-axios"
|
|
30
|
+
? ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("AxiosError"), [
|
|
31
|
+
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(errorTypeName)),
|
|
32
|
+
])
|
|
33
|
+
: ts.factory.createTypeReferenceNode(errorTypeName)
|
|
34
|
+
: client === "@hey-api/client-axios"
|
|
35
|
+
? ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("AxiosError"), [ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)])
|
|
36
|
+
: ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword));
|
|
31
37
|
const methodParameters = getVariableArrowFunctionParameters(method).length !== 0
|
|
32
38
|
? ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Options"), [
|
|
33
39
|
ts.factory.createTypeReferenceNode(modelNames.includes(`${capitalizeFirstLetter(methodName)}Data`)
|
package/dist/createUseQuery.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
2
|
import { BuildCommonTypeName, EqualsOrGreaterThanToken, TData, TError, capitalizeFirstLetter, createQueryKeyExport, createQueryKeyFnExport, getNameFromVariable, getQueryKeyFnName, getRequestParamFromMethod, getVariableArrowFunctionParameters, queryKeyConstraint, queryKeyGenericType, } from "./common.mjs";
|
|
3
3
|
import { addJSDocToNode } from "./util.mjs";
|
|
4
|
-
const createApiResponseType = ({ methodName, client, }) => {
|
|
4
|
+
const createApiResponseType = ({ methodName, client, modelNames, }) => {
|
|
5
5
|
/** Awaited<ReturnType<typeof myClass.myMethod>> */
|
|
6
6
|
const awaitedResponseDataType = ts.factory.createIndexedAccessTypeNode(ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Awaited"), [
|
|
7
7
|
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("ReturnType"), [
|
|
@@ -17,11 +17,17 @@ const createApiResponseType = ({ methodName, client, }) => {
|
|
|
17
17
|
const suspenseResponseDataType = ts.factory.createTypeParameterDeclaration(undefined, TData.text, undefined, ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("NonNullable"), [
|
|
18
18
|
ts.factory.createTypeReferenceNode(BuildCommonTypeName(apiResponse.name)),
|
|
19
19
|
]));
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
const errorTypeName = `${capitalizeFirstLetter(methodName)}Error`;
|
|
21
|
+
const hasErrorType = modelNames.includes(errorTypeName);
|
|
22
|
+
const responseErrorType = ts.factory.createTypeParameterDeclaration(undefined, TError.text, undefined, hasErrorType
|
|
23
|
+
? client === "@hey-api/client-axios"
|
|
24
|
+
? ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("AxiosError"), [
|
|
25
|
+
ts.factory.createTypeReferenceNode(ts.factory.createIdentifier(errorTypeName)),
|
|
26
|
+
])
|
|
27
|
+
: ts.factory.createTypeReferenceNode(errorTypeName)
|
|
28
|
+
: client === "@hey-api/client-axios"
|
|
29
|
+
? ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("AxiosError"), [ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)])
|
|
30
|
+
: ts.factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword));
|
|
25
31
|
return {
|
|
26
32
|
/**
|
|
27
33
|
* DefaultResponseDataType
|
|
@@ -87,6 +93,9 @@ function createQueryHook({ queryString, suffix, responseDataType, responseErrorT
|
|
|
87
93
|
}
|
|
88
94
|
const isInfiniteQuery = queryString === "useInfiniteQuery";
|
|
89
95
|
const isSuspenseQuery = queryString === "useSuspenseQuery";
|
|
96
|
+
// ts.TypeParameterDeclaration.default is ts.TypeNode | undefined.
|
|
97
|
+
// We know it's a TypeReferenceNode with an Identifier typeName because we created it
|
|
98
|
+
// via ts.factory in createApiResponseType, but TypeScript cannot infer the specific subtype.
|
|
90
99
|
const responseDataTypeRef = responseDataType.default;
|
|
91
100
|
const responseDataTypeIdentifier = responseDataTypeRef.typeName;
|
|
92
101
|
const hookExport = ts.factory.createVariableStatement([ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList([
|
|
@@ -169,6 +178,7 @@ export const createUseQuery = ({ functionDescription: { method, jsDoc }, client,
|
|
|
169
178
|
const { apiResponse: defaultApiResponse, responseDataType, suspenseResponseDataType, responseErrorType, } = createApiResponseType({
|
|
170
179
|
methodName,
|
|
171
180
|
client,
|
|
181
|
+
modelNames,
|
|
172
182
|
});
|
|
173
183
|
const requestParam = getRequestParamFromMethod(method, undefined, modelNames);
|
|
174
184
|
const infiniteRequestParam = getRequestParamFromMethod(method, pageParam, modelNames);
|
package/dist/generate.mjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { writeFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
1
3
|
import { createClient } from "@hey-api/openapi-ts";
|
|
2
4
|
import { buildQueriesOutputPath, buildRequestsOutputPath, formatOptions, } from "./common.mjs";
|
|
3
5
|
import { createSource } from "./createSource.mjs";
|
|
@@ -6,34 +8,50 @@ import { print } from "./print.mjs";
|
|
|
6
8
|
export async function generate(options, version) {
|
|
7
9
|
const openApiOutputPath = buildRequestsOutputPath(options.output);
|
|
8
10
|
const formattedOptions = formatOptions(options);
|
|
11
|
+
// Map CLI options to new plugins system
|
|
12
|
+
const clientPlugin = formattedOptions.client === "@hey-api/client-axios"
|
|
13
|
+
? "@hey-api/client-axios"
|
|
14
|
+
: "@hey-api/client-fetch";
|
|
15
|
+
const typescriptPlugin = formattedOptions.enums
|
|
16
|
+
? {
|
|
17
|
+
name: "@hey-api/typescript",
|
|
18
|
+
enums: formattedOptions.enums,
|
|
19
|
+
}
|
|
20
|
+
: "@hey-api/typescript";
|
|
21
|
+
const sdkPlugin = formattedOptions.noOperationId
|
|
22
|
+
? {
|
|
23
|
+
name: "@hey-api/sdk",
|
|
24
|
+
// `operationId: false` was deprecated in favor of `operations.nesting`
|
|
25
|
+
operations: {
|
|
26
|
+
nesting: "id",
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
: "@hey-api/sdk";
|
|
30
|
+
const plugins = [
|
|
31
|
+
clientPlugin,
|
|
32
|
+
typescriptPlugin,
|
|
33
|
+
sdkPlugin,
|
|
34
|
+
];
|
|
35
|
+
// Conditionally add schemas plugin
|
|
36
|
+
if (!formattedOptions.noSchemas) {
|
|
37
|
+
plugins.push(formattedOptions.schemaType
|
|
38
|
+
? {
|
|
39
|
+
name: "@hey-api/schemas",
|
|
40
|
+
type: formattedOptions.schemaType,
|
|
41
|
+
}
|
|
42
|
+
: "@hey-api/schemas");
|
|
43
|
+
}
|
|
9
44
|
const config = {
|
|
10
|
-
client: formattedOptions.client,
|
|
11
|
-
debug: formattedOptions.debug,
|
|
12
45
|
dryRun: false,
|
|
13
|
-
exportCore: true,
|
|
14
|
-
output: {
|
|
15
|
-
format: formattedOptions.format,
|
|
16
|
-
lint: formattedOptions.lint,
|
|
17
|
-
path: openApiOutputPath,
|
|
18
|
-
},
|
|
19
46
|
input: formattedOptions.input,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
type: formattedOptions.schemaType,
|
|
23
|
-
},
|
|
24
|
-
services: {
|
|
25
|
-
export: true,
|
|
26
|
-
asClass: false,
|
|
27
|
-
operationId: !formattedOptions.noOperationId,
|
|
28
|
-
},
|
|
29
|
-
types: {
|
|
30
|
-
dates: formattedOptions.useDateType,
|
|
31
|
-
export: true,
|
|
32
|
-
enums: formattedOptions.enums,
|
|
33
|
-
},
|
|
34
|
-
useOptions: true,
|
|
47
|
+
output: openApiOutputPath,
|
|
48
|
+
plugins,
|
|
35
49
|
};
|
|
36
50
|
await createClient(config);
|
|
51
|
+
// Generate backward-compatible services.gen.ts shim
|
|
52
|
+
// client.gen.ts has the `client` instance; sdk.gen.ts has SDK functions
|
|
53
|
+
const shimContent = `// This file is auto-generated for backward compatibility\nexport * from './client.gen.js';\nexport * from './sdk.gen.js';\n`;
|
|
54
|
+
await writeFile(path.join(openApiOutputPath, "services.gen.ts"), shimContent);
|
|
37
55
|
const source = await createSource({
|
|
38
56
|
outputPath: openApiOutputPath,
|
|
39
57
|
client: formattedOptions.client,
|
package/dist/service.mjs
CHANGED
|
@@ -15,36 +15,55 @@ export async function getServices(project) {
|
|
|
15
15
|
}
|
|
16
16
|
export function getMethodsFromService(node) {
|
|
17
17
|
const variableStatements = node.getVariableStatements();
|
|
18
|
-
//
|
|
19
|
-
|
|
18
|
+
// Filter to only exported variable statements that contain arrow functions
|
|
19
|
+
const exportedStatements = variableStatements.filter((statement) => {
|
|
20
|
+
if (!statement.isExported())
|
|
21
|
+
return false;
|
|
22
|
+
const declarations = statement.getDeclarations();
|
|
23
|
+
return declarations.some((decl) => {
|
|
24
|
+
const initializer = decl.getInitializer();
|
|
25
|
+
return initializer && ts.isArrowFunction(initializer.compilerNode);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
return exportedStatements.flatMap((variableStatement) => {
|
|
20
29
|
const declarations = variableStatement.getDeclarations();
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
throw new Error("Variable declaration not found");
|
|
24
|
-
}
|
|
30
|
+
// Filter to only arrow function declarations within the statement
|
|
31
|
+
const arrowDeclarations = declarations.filter((declaration) => {
|
|
25
32
|
const initializer = declaration.getInitializer();
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
return initializer && ts.isArrowFunction(initializer.compilerNode);
|
|
34
|
+
});
|
|
35
|
+
return arrowDeclarations.map((declaration) => {
|
|
36
|
+
const initializer = declaration.getInitializerOrThrow();
|
|
37
|
+
const compilerNode = initializer.compilerNode;
|
|
38
|
+
const arrowBody = compilerNode.body;
|
|
39
|
+
// Find the call expression - either from block's return statement or direct expression
|
|
40
|
+
let callExpression;
|
|
41
|
+
let methodBlockNode;
|
|
42
|
+
if (ts.isBlock(arrowBody)) {
|
|
43
|
+
// Old style: arrow function with block body
|
|
44
|
+
methodBlockNode = arrowBody;
|
|
45
|
+
const returnStatement = arrowBody.statements.find(ts.isReturnStatement);
|
|
46
|
+
if (!returnStatement) {
|
|
47
|
+
throw new Error("Return statement not found");
|
|
48
|
+
}
|
|
49
|
+
if (!returnStatement.expression) {
|
|
50
|
+
throw new Error("Call expression not found");
|
|
51
|
+
}
|
|
52
|
+
callExpression = returnStatement.expression;
|
|
35
53
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
54
|
+
else {
|
|
55
|
+
// New style: arrow function with expression body (no block)
|
|
56
|
+
// The body is a call expression like: (options?.client ?? client).post<...>({...})
|
|
57
|
+
callExpression = arrowBody;
|
|
39
58
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (
|
|
43
|
-
|
|
59
|
+
// Navigate to find the HTTP method name (get, post, put, delete, etc.)
|
|
60
|
+
let httpMethodName;
|
|
61
|
+
if (ts.isCallExpression(callExpression)) {
|
|
62
|
+
const expr = callExpression.expression;
|
|
63
|
+
if (ts.isPropertyAccessExpression(expr)) {
|
|
64
|
+
httpMethodName = expr.name.text;
|
|
65
|
+
}
|
|
44
66
|
}
|
|
45
|
-
const callExpression = foundCallExpression;
|
|
46
|
-
const propertyAccessExpression = callExpression.expression;
|
|
47
|
-
const httpMethodName = propertyAccessExpression.name.getText();
|
|
48
67
|
if (!httpMethodName) {
|
|
49
68
|
throw new Error("httpMethodName not found");
|
|
50
69
|
}
|
|
@@ -56,7 +75,7 @@ export function getMethodsFromService(node) {
|
|
|
56
75
|
}
|
|
57
76
|
return [tsNode];
|
|
58
77
|
};
|
|
59
|
-
const children = getAllChildren(
|
|
78
|
+
const children = getAllChildren(variableStatement.compilerNode);
|
|
60
79
|
// get all JSDoc comments
|
|
61
80
|
// this should be an array of 1 or 0
|
|
62
81
|
const jsDocs = children
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@7nohe/openapi-react-query-codegen",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "OpenAPI React Query Codegen",
|
|
5
5
|
"bin": {
|
|
6
6
|
"openapi-rq": "dist/cli.mjs"
|
|
@@ -39,29 +39,29 @@
|
|
|
39
39
|
"license": "MIT",
|
|
40
40
|
"author": "Daiki Urata (@7nohe)",
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@hey-api/
|
|
43
|
-
"@hey-api/openapi-ts": "0.53.8",
|
|
42
|
+
"@hey-api/openapi-ts": "0.99.0",
|
|
44
43
|
"cross-spawn": "^7.0.3"
|
|
45
44
|
},
|
|
46
45
|
"devDependencies": {
|
|
47
46
|
"@biomejs/biome": "^1.9.3",
|
|
48
47
|
"@types/cross-spawn": "^6.0.6",
|
|
49
48
|
"@types/node": "^22.7.4",
|
|
49
|
+
"@types/semver": "^7.7.1",
|
|
50
50
|
"@vitest/coverage-v8": "^1.5.0",
|
|
51
51
|
"commander": "^12.0.0",
|
|
52
52
|
"lefthook": "^1.6.10",
|
|
53
53
|
"rimraf": "^5.0.5",
|
|
54
|
-
"ts-morph": "^
|
|
55
|
-
"typescript": "^
|
|
54
|
+
"ts-morph": "^28.0.0",
|
|
55
|
+
"typescript": "^6.0.3",
|
|
56
56
|
"vitest": "^1.5.0"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"commander": "12.x",
|
|
60
|
-
"ts-morph": "
|
|
61
|
-
"typescript": "5.x"
|
|
60
|
+
"ts-morph": "28.x",
|
|
61
|
+
"typescript": "5.x || 6.x"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
|
-
"node": ">=
|
|
64
|
+
"node": ">=22.18.0",
|
|
65
65
|
"pnpm": ">=9"
|
|
66
66
|
},
|
|
67
67
|
"scripts": {
|