vovk-cli 0.0.1-draft.277 → 0.0.1-draft.279
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/client-templates/cjs/index.cjs.ejs +1 -1
- package/client-templates/mjs/index.mjs.ejs +1 -1
- package/client-templates/readme/README.md.ejs +2 -1
- package/client-templates/ts/index.ts.ejs +1 -1
- package/dist/bundle/index.mjs +2 -0
- package/dist/generate/generate.d.mts +5 -2
- package/dist/generate/generate.mjs +40 -23
- package/dist/generate/getClientTemplateFiles.d.mts +1 -3
- package/dist/generate/getClientTemplateFiles.mjs +3 -3
- package/dist/generate/mergePackages.d.mts +3 -5
- package/dist/generate/mergePackages.mjs +2 -25
- package/dist/generate/writeOneClientFile.d.mts +2 -1
- package/dist/generate/writeOneClientFile.mjs +3 -2
- package/dist/getProjectInfo/getConfig/index.d.mts +19 -2
- package/dist/getProjectInfo/getConfig/index.mjs +9 -5
- package/dist/getProjectInfo/index.d.mts +1 -0
- package/dist/getProjectInfo/index.mjs +3 -0
- package/dist/init/createConfig.mjs +2 -2
- package/dist/init/index.mjs +2 -8
- package/dist/initProgram.mjs +1 -1
- package/dist/utils/getPackageJson.d.mts +3 -0
- package/dist/utils/getPackageJson.mjs +22 -0
- package/dist/utils/normalizeOpenAPIMixins.d.mts +3 -1
- package/dist/utils/normalizeOpenAPIMixins.mjs +22 -5
- package/package.json +2 -2
|
@@ -7,7 +7,7 @@ const { validateOnClient = null } = <%- t.imports.validateOnClient ? `require('$
|
|
|
7
7
|
Object.keys(segment.controllers).forEach((rpcModuleName) => { %>
|
|
8
8
|
exports.<%= rpcModuleName %> = createRPC(
|
|
9
9
|
schema, '<%= segment.segmentName %>', '<%= rpcModuleName %>', fetcher,
|
|
10
|
-
{ validateOnClient, <%- typeof t.segmentMeta[segment.segmentName].segmentNameOverride === 'string' ? `segmentNameOverride: '${t.segmentMeta[segment.segmentName].segmentNameOverride}', ` : '' %><%- segment.segmentType === 'mixin' ? '' : `apiRoot: '${segment.
|
|
10
|
+
{ validateOnClient, <%- typeof t.segmentMeta[segment.segmentName].segmentNameOverride === 'string' ? `segmentNameOverride: '${t.segmentMeta[segment.segmentName].segmentNameOverride}', ` : '' %><%- segment.segmentType === 'mixin' ? '' : `apiRoot: '${t.segmentMeta[segment.segmentName].forceApiRoot ?? t.apiRoot}'` %> }
|
|
11
11
|
);
|
|
12
12
|
<% })
|
|
13
13
|
}) %>
|
|
@@ -11,7 +11,7 @@ Object.values(t.schema.segments).filter((segment) => segment.emitSchema).forEach
|
|
|
11
11
|
Object.keys(segment.controllers).forEach((rpcModuleName) => { %>
|
|
12
12
|
export const <%= rpcModuleName %> = createRPC(
|
|
13
13
|
schema, '<%= segment.segmentName %>', '<%= rpcModuleName %>', fetcher,
|
|
14
|
-
{ validateOnClient, <%- typeof t.segmentMeta[segment.segmentName].segmentNameOverride === 'string' ? `segmentNameOverride: '${t.segmentMeta[segment.segmentName].segmentNameOverride}', ` : '' %><%- segment.segmentType === 'mixin' ? '' : `apiRoot: '${segment.
|
|
14
|
+
{ validateOnClient, <%- typeof t.segmentMeta[segment.segmentName].segmentNameOverride === 'string' ? `segmentNameOverride: '${t.segmentMeta[segment.segmentName].segmentNameOverride}', ` : '' %><%- segment.segmentType === 'mixin' ? '' : `apiRoot: '${t.segmentMeta[segment.segmentName].forceApiRoot ?? t.apiRoot}'` %> }
|
|
15
15
|
);
|
|
16
16
|
<%
|
|
17
17
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
<%= t.readme.banner %>
|
|
2
2
|
|
|
3
|
+
# <%= t.package.name %> v<%= t.package.version %> 
|
|
3
4
|
|
|
4
5
|
<%- t.package.description ? `> ${t.package.description}` : '' %>
|
|
5
6
|
|
|
@@ -20,7 +20,7 @@ type Options = typeof fetcher extends VovkClientFetcher<infer U> ? U : never;
|
|
|
20
20
|
Object.keys(segment.controllers).forEach((rpcModuleName) => { %>
|
|
21
21
|
export const <%= rpcModuleName %> = createRPC<<%= segment.segmentType === 'mixin' ? `MixinControllers` : `Controllers${i}` %>["<%= rpcModuleName %>"], Options>(
|
|
22
22
|
schema, '<%= segment.segmentName %>', '<%= rpcModuleName %>', fetcher,
|
|
23
|
-
{ validateOnClient, <%- typeof t.segmentMeta[segment.segmentName].segmentNameOverride === 'string' ? `segmentNameOverride: '${t.segmentMeta[segment.segmentName].segmentNameOverride}', ` : '' %><%- segment.segmentType === 'mixin' ? '' : `apiRoot: '${segment.
|
|
23
|
+
{ validateOnClient, <%- typeof t.segmentMeta[segment.segmentName].segmentNameOverride === 'string' ? `segmentNameOverride: '${t.segmentMeta[segment.segmentName].segmentNameOverride}', ` : '' %><%- segment.segmentType === 'mixin' ? '' : `apiRoot: '${t.segmentMeta[segment.segmentName].forceApiRoot ?? t.apiRoot}'` %> }
|
|
24
24
|
);
|
|
25
25
|
<% })
|
|
26
26
|
}) %>
|
package/dist/bundle/index.mjs
CHANGED
|
@@ -27,6 +27,8 @@ export async function bundle({ projectInfo, fullSchema, cliBundleOptions, }) {
|
|
|
27
27
|
forceNothingWrittenLog: true,
|
|
28
28
|
fullSchema,
|
|
29
29
|
locatedSegments,
|
|
30
|
+
package: bundleConfig.package,
|
|
31
|
+
readme: bundleConfig.readme,
|
|
30
32
|
cliGenerateOptions: {
|
|
31
33
|
openapiSpec: cliBundleOptions?.openapiSpec,
|
|
32
34
|
openapiGetModuleName: cliBundleOptions?.openapiGetModuleName,
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { type VovkSchema } from 'vovk';
|
|
1
|
+
import { type VovkSchema, type VovkStrictConfig } from 'vovk';
|
|
2
|
+
import type { PackageJson } from 'type-fest';
|
|
2
3
|
import type { ProjectInfo } from '../getProjectInfo/index.mjs';
|
|
3
4
|
import type { GenerateOptions } from '../types.mjs';
|
|
4
5
|
import type { Segment } from '../locateSegments.mjs';
|
|
5
|
-
export declare function generate({ isEnsuringClient, projectInfo, forceNothingWrittenLog, fullSchema, locatedSegments, cliGenerateOptions, }: {
|
|
6
|
+
export declare function generate({ isEnsuringClient, projectInfo, forceNothingWrittenLog, fullSchema, locatedSegments, cliGenerateOptions, package: argPackageJson, readme: argReadme, }: {
|
|
6
7
|
isEnsuringClient?: boolean;
|
|
7
8
|
projectInfo: ProjectInfo;
|
|
8
9
|
forceNothingWrittenLog?: boolean;
|
|
9
10
|
fullSchema: VovkSchema;
|
|
10
11
|
locatedSegments: Segment[];
|
|
11
12
|
cliGenerateOptions?: GenerateOptions;
|
|
13
|
+
package?: PackageJson;
|
|
14
|
+
readme?: VovkStrictConfig['bundle']['readme'];
|
|
12
15
|
}): Promise<void>;
|
|
@@ -13,6 +13,7 @@ import writeOneClientFile from './writeOneClientFile.mjs';
|
|
|
13
13
|
import { ROOT_SEGMENT_FILE_NAME } from '../dev/writeOneSegmentSchemaFile.mjs';
|
|
14
14
|
import { getTsconfig } from 'get-tsconfig';
|
|
15
15
|
import { normalizeOpenAPIMixins } from '../utils/normalizeOpenAPIMixins.mjs';
|
|
16
|
+
import { BuiltInTemplateName } from '../getProjectInfo/getConfig/getTemplateDefs.mjs';
|
|
16
17
|
const getIncludedSegmentNames = (config, fullSchema, configKey, cliGenerateOptions) => {
|
|
17
18
|
const segments = Object.values(fullSchema.segments);
|
|
18
19
|
const includeSegments = cliGenerateOptions?.[configKey === 'segmentedClient' ? 'segmentedIncludeSegments' : 'composedIncludeSegments'] ??
|
|
@@ -41,18 +42,26 @@ function logClientGenerationResults({ results, log, isEnsuringClient = false, fo
|
|
|
41
42
|
const writtenResults = results.filter(({ written }) => written);
|
|
42
43
|
const duration = Date.now() - startTime;
|
|
43
44
|
const groupedByDir = _.groupBy(writtenResults, ({ outAbsoluteDir }) => outAbsoluteDir);
|
|
45
|
+
const logOrDebug = forceNothingWrittenLog ? log.info : log.debug;
|
|
44
46
|
if (writtenResults.length) {
|
|
45
47
|
for (const [outAbsoluteDir, dirResults] of Object.entries(groupedByDir)) {
|
|
46
48
|
const templateNames = _.uniq(dirResults.map(({ templateName }) => templateName));
|
|
47
49
|
log.info(`${clientType} client${isEnsuringClient ? ' placeholder' : ''} is generated to ${chalkHighlightThing(outAbsoluteDir)} from template${templateNames.length !== 1 ? 's' : ''} ${chalkHighlightThing(templateNames.map((s) => `"${s}"`).join(', '))} in ${duration}ms`);
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
|
-
else if (
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const templateNames = _.uniq(dirResults.map(({ templateName }) => templateName));
|
|
54
|
-
logOrDebug(`${clientType} client that was generated to ${chalkHighlightThing(outAbsoluteDir)} from template${templateNames.length !== 1 ? 's' : ''} ${chalkHighlightThing(templateNames.map((s) => `"${s}"`).join(', '))} is up to date and doesn't need to be regenerated (${duration}ms)`);
|
|
52
|
+
else if (fromTemplates.length) {
|
|
53
|
+
if (!writtenResults.length) {
|
|
54
|
+
logOrDebug(`${clientType} client${isEnsuringClient ? ' placeholder' : ''} is up to date (${duration}ms)`);
|
|
55
55
|
}
|
|
56
|
+
else if (!isEnsuringClient) {
|
|
57
|
+
for (const [outAbsoluteDir, dirResults] of Object.entries(groupedByDir)) {
|
|
58
|
+
const templateNames = _.uniq(dirResults.map(({ templateName }) => templateName));
|
|
59
|
+
logOrDebug(`${clientType} client that was generated to ${chalkHighlightThing(outAbsoluteDir)} from template${templateNames.length !== 1 ? 's' : ''} ${chalkHighlightThing(templateNames.map((s) => `"${s}"`).join(', '))} is up to date and doesn't need to be regenerated (${duration}ms)`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
logOrDebug(`${clientType} client${isEnsuringClient ? ' placeholder' : ''} is not generated because no files were written (${duration}ms)`);
|
|
56
65
|
}
|
|
57
66
|
}
|
|
58
67
|
const cliOptionsToOpenAPIMixins = ({ openapiGetMethodName, openapiGetModuleName, openapiRootUrl, openapiSpec, openapiMixinName, }) => {
|
|
@@ -62,7 +71,7 @@ const cliOptionsToOpenAPIMixins = ({ openapiGetMethodName, openapiGetModuleName,
|
|
|
62
71
|
apiRoot: openapiRootUrl?.[i] ?? '/',
|
|
63
72
|
getModuleName: openapiGetModuleName?.[i] ?? undefined,
|
|
64
73
|
getMethodName: openapiGetMethodName?.[i] ?? 'auto',
|
|
65
|
-
mixinName: openapiMixinName?.[i]
|
|
74
|
+
mixinName: openapiMixinName?.[i],
|
|
66
75
|
};
|
|
67
76
|
}) || []).map(({ source, apiRoot, getModuleName, getMethodName, mixinName }) => [
|
|
68
77
|
mixinName,
|
|
@@ -75,25 +84,22 @@ const cliOptionsToOpenAPIMixins = ({ openapiGetMethodName, openapiGetModuleName,
|
|
|
75
84
|
},
|
|
76
85
|
]));
|
|
77
86
|
};
|
|
78
|
-
export async function generate({ isEnsuringClient = false, projectInfo, forceNothingWrittenLog, fullSchema, locatedSegments, cliGenerateOptions, }) {
|
|
87
|
+
export async function generate({ isEnsuringClient = false, projectInfo, forceNothingWrittenLog, fullSchema, locatedSegments, cliGenerateOptions, package: argPackageJson, readme: argReadme, }) {
|
|
79
88
|
fullSchema = {
|
|
80
89
|
...fullSchema,
|
|
81
90
|
// sort segments by name to avoid unnecessary rendering
|
|
82
91
|
segments: Object.fromEntries(Object.entries(fullSchema.segments).sort(([a], [b]) => a.localeCompare(b))),
|
|
83
92
|
};
|
|
84
|
-
const { config, cwd, log, srcRoot } = projectInfo;
|
|
93
|
+
const { config, cwd, log, srcRoot, packageJson: rootPackageJson } = projectInfo;
|
|
85
94
|
const allOpenAPIMixins = {
|
|
86
95
|
...config.openApiMixins,
|
|
87
96
|
...cliOptionsToOpenAPIMixins(cliGenerateOptions ?? {}),
|
|
88
97
|
};
|
|
89
|
-
/** @deprecated */
|
|
90
|
-
let hasMixins = false;
|
|
91
98
|
if (Object.keys(allOpenAPIMixins).length) {
|
|
92
|
-
const mixins = Object.fromEntries(Object.entries(await normalizeOpenAPIMixins({ mixinModules: allOpenAPIMixins })).map(([mixinName, conf]) => [
|
|
99
|
+
const mixins = Object.fromEntries(Object.entries(await normalizeOpenAPIMixins({ mixinModules: allOpenAPIMixins, log })).map(([mixinName, conf]) => [
|
|
93
100
|
mixinName,
|
|
94
101
|
openAPIToVovkSchema({ ...conf, mixinName }).segments[mixinName],
|
|
95
102
|
]));
|
|
96
|
-
hasMixins = true;
|
|
97
103
|
fullSchema = {
|
|
98
104
|
...fullSchema,
|
|
99
105
|
segments: {
|
|
@@ -119,7 +125,6 @@ export async function generate({ isEnsuringClient = false, projectInfo, forceNot
|
|
|
119
125
|
config,
|
|
120
126
|
cwd,
|
|
121
127
|
log,
|
|
122
|
-
hasMixins,
|
|
123
128
|
cliGenerateOptions,
|
|
124
129
|
configKey: 'composedClient',
|
|
125
130
|
});
|
|
@@ -136,21 +141,27 @@ export async function generate({ isEnsuringClient = false, projectInfo, forceNot
|
|
|
136
141
|
});
|
|
137
142
|
const packageJson = await mergePackages({
|
|
138
143
|
log,
|
|
139
|
-
|
|
140
|
-
config,
|
|
141
|
-
packages: [config.composedClient.package, templateDef.composedClient?.package],
|
|
144
|
+
rootPackageJson,
|
|
145
|
+
packages: [config.composedClient.package, templateDef.composedClient?.package, argPackageJson],
|
|
142
146
|
});
|
|
147
|
+
const readme = Object.assign({}, config.composedClient.readme, templateDef.composedClient?.readme, argReadme);
|
|
148
|
+
const composedFullSchema = pickSegmentFullSchema(fullSchema, segmentNames);
|
|
149
|
+
const hasMixins = Object.values(composedFullSchema.segments).some((segment) => segment.segmentType === 'mixin');
|
|
150
|
+
if (templateName === BuiltInTemplateName.mixins && !hasMixins) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
143
153
|
const { written } = await writeOneClientFile({
|
|
144
154
|
cwd,
|
|
145
155
|
projectInfo,
|
|
146
156
|
clientTemplateFile,
|
|
147
|
-
fullSchema:
|
|
157
|
+
fullSchema: composedFullSchema,
|
|
148
158
|
prettifyClient: config.prettifyClient,
|
|
149
159
|
segmentName: null,
|
|
150
160
|
imports: clientImports.composedClient,
|
|
151
161
|
templateContent,
|
|
152
162
|
matterResult,
|
|
153
163
|
package: packageJson,
|
|
164
|
+
readme,
|
|
154
165
|
isEnsuringClient,
|
|
155
166
|
outCwdRelativeDir,
|
|
156
167
|
origin: config.origin ?? templateDef?.origin ?? null,
|
|
@@ -169,7 +180,7 @@ export async function generate({ isEnsuringClient = false, projectInfo, forceNot
|
|
|
169
180
|
}));
|
|
170
181
|
if (composedClientTemplateFiles.length) {
|
|
171
182
|
logClientGenerationResults({
|
|
172
|
-
results: composedClientResults,
|
|
183
|
+
results: composedClientResults.filter((result) => !!result),
|
|
173
184
|
log,
|
|
174
185
|
isEnsuringClient,
|
|
175
186
|
forceNothingWrittenLog,
|
|
@@ -189,7 +200,6 @@ export async function generate({ isEnsuringClient = false, projectInfo, forceNot
|
|
|
189
200
|
config,
|
|
190
201
|
cwd,
|
|
191
202
|
log,
|
|
192
|
-
hasMixins,
|
|
193
203
|
cliGenerateOptions,
|
|
194
204
|
configKey: 'segmentedClient',
|
|
195
205
|
});
|
|
@@ -206,25 +216,32 @@ export async function generate({ isEnsuringClient = false, projectInfo, forceNot
|
|
|
206
216
|
outCwdRelativeDir,
|
|
207
217
|
});
|
|
208
218
|
const packageJson = await mergePackages({
|
|
209
|
-
cwd,
|
|
210
|
-
config,
|
|
211
219
|
log,
|
|
220
|
+
rootPackageJson,
|
|
212
221
|
packages: [
|
|
213
222
|
config.segmentedClient.packages?.[segmentName],
|
|
214
223
|
templateDef.segmentedClient?.packages?.[segmentName],
|
|
224
|
+
argPackageJson,
|
|
215
225
|
],
|
|
216
226
|
});
|
|
227
|
+
const readme = Object.assign({}, config.segmentedClient.readmes?.[segmentName], templateDef.segmentedClient?.readmes?.[segmentName], argReadme);
|
|
228
|
+
const segmentedFullSchema = pickSegmentFullSchema(fullSchema, [segmentName]);
|
|
229
|
+
const hasMixins = Object.values(segmentedFullSchema.segments).some((segment) => segment.segmentType === 'mixin');
|
|
230
|
+
if (templateName === BuiltInTemplateName.mixins && !hasMixins) {
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
217
233
|
const { written } = await writeOneClientFile({
|
|
218
234
|
cwd,
|
|
219
235
|
projectInfo,
|
|
220
236
|
clientTemplateFile,
|
|
221
|
-
fullSchema:
|
|
237
|
+
fullSchema: segmentedFullSchema,
|
|
222
238
|
prettifyClient: config.prettifyClient,
|
|
223
239
|
segmentName,
|
|
224
240
|
imports: clientImports.segmentedClient[segmentName],
|
|
225
241
|
templateContent,
|
|
226
242
|
matterResult,
|
|
227
243
|
package: packageJson,
|
|
244
|
+
readme,
|
|
228
245
|
isEnsuringClient,
|
|
229
246
|
outCwdRelativeDir,
|
|
230
247
|
origin: config.origin ?? templateDef?.origin ?? null,
|
|
@@ -243,7 +260,7 @@ export async function generate({ isEnsuringClient = false, projectInfo, forceNot
|
|
|
243
260
|
// Remove unlisted directories in the output directory
|
|
244
261
|
await removeUnlistedDirectories(outAbsoluteDir, segmentNames.map((s) => s || ROOT_SEGMENT_FILE_NAME));
|
|
245
262
|
return {
|
|
246
|
-
written: results.some(({ written }) => written),
|
|
263
|
+
written: results.filter((result) => !!result).some(({ written }) => written),
|
|
247
264
|
templateName,
|
|
248
265
|
outAbsoluteDir,
|
|
249
266
|
};
|
|
@@ -8,14 +8,12 @@ export interface ClientTemplateFile {
|
|
|
8
8
|
outCwdRelativeDir: string;
|
|
9
9
|
templateDef: VovkStrictConfig['clientTemplateDefs'][string];
|
|
10
10
|
}
|
|
11
|
-
export default function getClientTemplateFiles({ config, cwd, log, configKey, cliGenerateOptions,
|
|
11
|
+
export default function getClientTemplateFiles({ config, cwd, log, configKey, cliGenerateOptions, }: {
|
|
12
12
|
config: VovkStrictConfig;
|
|
13
13
|
cwd: string;
|
|
14
14
|
log: ProjectInfo['log'];
|
|
15
15
|
configKey: 'composedClient' | 'segmentedClient';
|
|
16
16
|
cliGenerateOptions?: GenerateOptions;
|
|
17
|
-
/** @deprecated */
|
|
18
|
-
hasMixins: boolean;
|
|
19
17
|
}): Promise<{
|
|
20
18
|
fromTemplates: string[];
|
|
21
19
|
templateFiles: ClientTemplateFile[];
|
|
@@ -4,7 +4,7 @@ import resolveAbsoluteModulePath from '../utils/resolveAbsoluteModulePath.mjs';
|
|
|
4
4
|
import getFileSystemEntryType, { FileSystemEntryType } from '../utils/getFileSystemEntryType.mjs';
|
|
5
5
|
import getPublicModuleNameFromPath from '../utils/getPublicModuleNameFromPath.mjs';
|
|
6
6
|
import { BuiltInTemplateName } from '../getProjectInfo/getConfig/getTemplateDefs.mjs';
|
|
7
|
-
export default async function getClientTemplateFiles({ config, cwd, log, configKey, cliGenerateOptions,
|
|
7
|
+
export default async function getClientTemplateFiles({ config, cwd, log, configKey, cliGenerateOptions, }) {
|
|
8
8
|
const usedTemplateDefs = {};
|
|
9
9
|
const fromTemplates = configKey === 'composedClient'
|
|
10
10
|
? cliGenerateOptions?.composedFrom || cliGenerateOptions?.segmentedFrom
|
|
@@ -14,13 +14,13 @@ export default async function getClientTemplateFiles({ config, cwd, log, configK
|
|
|
14
14
|
? (cliGenerateOptions?.segmentedFrom ?? [])
|
|
15
15
|
: config.segmentedClient.fromTemplates;
|
|
16
16
|
const cliOutDir = configKey === 'composedClient' ? cliGenerateOptions?.composedOut : cliGenerateOptions?.segmentedOut;
|
|
17
|
-
const configOutDir = configKey
|
|
17
|
+
const configOutDir = config[configKey].outDir;
|
|
18
18
|
for (const templateName of fromTemplates) {
|
|
19
19
|
if (!(templateName in config.clientTemplateDefs)) {
|
|
20
20
|
throw new Error(`Unknown template name: ${templateName}`);
|
|
21
21
|
}
|
|
22
22
|
let usedDef = config.clientTemplateDefs[templateName];
|
|
23
|
-
if (usedDef.isTsClient
|
|
23
|
+
if (usedDef.isTsClient) {
|
|
24
24
|
usedDef = {
|
|
25
25
|
...usedDef,
|
|
26
26
|
requires: {
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import type { PackageJson } from 'type-fest';
|
|
2
|
-
import type { VovkStrictConfig } from 'vovk';
|
|
3
2
|
import type { ProjectInfo } from '../getProjectInfo/index.mjs';
|
|
4
|
-
export default function mergePackages({
|
|
5
|
-
|
|
6
|
-
config: VovkStrictConfig;
|
|
7
|
-
log: ProjectInfo['log'];
|
|
3
|
+
export default function mergePackages({ rootPackageJson, packages, }: {
|
|
4
|
+
rootPackageJson: PackageJson;
|
|
8
5
|
packages: (PackageJson | undefined)[];
|
|
6
|
+
log: ProjectInfo['log'];
|
|
9
7
|
}): Promise<PackageJson>;
|
|
@@ -1,26 +1,4 @@
|
|
|
1
1
|
import pick from 'lodash/pick.js';
|
|
2
|
-
import fs from 'node:fs/promises';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
let cachedPromise;
|
|
5
|
-
function getPackageJson(cwd, log) {
|
|
6
|
-
const pkgPath = path.join(cwd, 'package.json');
|
|
7
|
-
// If we have a cached promise, return it
|
|
8
|
-
if (cachedPromise) {
|
|
9
|
-
return cachedPromise;
|
|
10
|
-
}
|
|
11
|
-
const promise = fs
|
|
12
|
-
.readFile(pkgPath, 'utf8')
|
|
13
|
-
.then((content) => JSON.parse(content))
|
|
14
|
-
.catch(() => {
|
|
15
|
-
cachedPromise = undefined;
|
|
16
|
-
log.warn(`Failed to read package.json at ${pkgPath}. Using a fallback.`);
|
|
17
|
-
return {
|
|
18
|
-
name: 'unknown',
|
|
19
|
-
};
|
|
20
|
-
});
|
|
21
|
-
cachedPromise = promise;
|
|
22
|
-
return promise;
|
|
23
|
-
}
|
|
24
2
|
function mergeTwoPackageJsons(base, additional) {
|
|
25
3
|
const merged = { ...base, ...additional };
|
|
26
4
|
// TODO: Add deep merge for all properties
|
|
@@ -38,8 +16,7 @@ function mergeTwoPackageJsons(base, additional) {
|
|
|
38
16
|
}
|
|
39
17
|
return merged;
|
|
40
18
|
}
|
|
41
|
-
export default async function mergePackages({
|
|
42
|
-
const fullPackageJson = await getPackageJson(cwd, log);
|
|
19
|
+
export default async function mergePackages({ rootPackageJson, packages, }) {
|
|
43
20
|
const defaultPackageJson = {
|
|
44
21
|
main: './index.cjs',
|
|
45
22
|
module: './index.mjs',
|
|
@@ -56,7 +33,7 @@ export default async function mergePackages({ cwd, packages, log, }) {
|
|
|
56
33
|
},
|
|
57
34
|
},
|
|
58
35
|
};
|
|
59
|
-
const pickedPackageJson = pick(
|
|
36
|
+
const pickedPackageJson = pick(rootPackageJson, [
|
|
60
37
|
'name',
|
|
61
38
|
'version',
|
|
62
39
|
'description',
|
|
@@ -4,7 +4,7 @@ import type { ProjectInfo } from '../getProjectInfo/index.mjs';
|
|
|
4
4
|
import type { ClientTemplateFile } from './getClientTemplateFiles.mjs';
|
|
5
5
|
import type { ClientImports } from './getTemplateClientImports.mjs';
|
|
6
6
|
import type { Segment } from '../locateSegments.mjs';
|
|
7
|
-
export default function writeOneClientFile({ cwd, projectInfo, clientTemplateFile, fullSchema, prettifyClient, segmentName, imports, templateContent, matterResult: { data, content }, package: packageJson, isEnsuringClient, outCwdRelativeDir, origin, templateDef, locatedSegments, isNodeNextResolution, hasMixins, isVovkProject, }: {
|
|
7
|
+
export default function writeOneClientFile({ cwd, projectInfo, clientTemplateFile, fullSchema, prettifyClient, segmentName, imports, templateContent, matterResult: { data, content }, package: packageJson, readme, isEnsuringClient, outCwdRelativeDir, origin, templateDef, locatedSegments, isNodeNextResolution, hasMixins, isVovkProject, }: {
|
|
8
8
|
cwd: string;
|
|
9
9
|
projectInfo: ProjectInfo;
|
|
10
10
|
clientTemplateFile: ClientTemplateFile;
|
|
@@ -20,6 +20,7 @@ export default function writeOneClientFile({ cwd, projectInfo, clientTemplateFil
|
|
|
20
20
|
content: string;
|
|
21
21
|
};
|
|
22
22
|
package: PackageJson;
|
|
23
|
+
readme: VovkStrictConfig['bundle']['readme'];
|
|
23
24
|
isEnsuringClient: boolean;
|
|
24
25
|
outCwdRelativeDir: string;
|
|
25
26
|
origin: string | null;
|
|
@@ -8,7 +8,7 @@ import TOML from '@iarna/toml';
|
|
|
8
8
|
import prettify from '../utils/prettify.mjs';
|
|
9
9
|
import { ROOT_SEGMENT_FILE_NAME } from '../dev/writeOneSegmentSchemaFile.mjs';
|
|
10
10
|
import { compileJSONSchemaToTypeScriptType } from '../utils/compileJSONSchemaToTypeScriptType.mjs';
|
|
11
|
-
export default async function writeOneClientFile({ cwd, projectInfo, clientTemplateFile, fullSchema, prettifyClient, segmentName, imports, templateContent, matterResult: { data, content }, package: packageJson, isEnsuringClient, outCwdRelativeDir, origin, templateDef, locatedSegments, isNodeNextResolution, hasMixins, isVovkProject, }) {
|
|
11
|
+
export default async function writeOneClientFile({ cwd, projectInfo, clientTemplateFile, fullSchema, prettifyClient, segmentName, imports, templateContent, matterResult: { data, content }, package: packageJson, readme, isEnsuringClient, outCwdRelativeDir, origin, templateDef, locatedSegments, isNodeNextResolution, hasMixins, isVovkProject, }) {
|
|
12
12
|
const { config, apiRoot } = projectInfo;
|
|
13
13
|
const { templateFilePath, relativeDir } = clientTemplateFile;
|
|
14
14
|
const locatedSegmentsByName = _.keyBy(locatedSegments, 'segmentName');
|
|
@@ -23,6 +23,7 @@ export default async function writeOneClientFile({ cwd, projectInfo, clientTempl
|
|
|
23
23
|
hasMixins,
|
|
24
24
|
isVovkProject,
|
|
25
25
|
package: packageJson,
|
|
26
|
+
readme,
|
|
26
27
|
ROOT_SEGMENT_FILE_NAME,
|
|
27
28
|
apiRoot: origin ? `${origin}/${config.rootEntry}` : apiRoot,
|
|
28
29
|
imports,
|
|
@@ -53,7 +54,7 @@ export default async function writeOneClientFile({ cwd, projectInfo, clientTempl
|
|
|
53
54
|
return [
|
|
54
55
|
sName,
|
|
55
56
|
{
|
|
56
|
-
|
|
57
|
+
forceApiRoot: forceApiRoot ??
|
|
57
58
|
(segmentConfigOrigin || segmentConfigRootEntry
|
|
58
59
|
? `${segmentConfigOrigin ?? origin}/${segmentConfigRootEntry ?? config.rootEntry}`
|
|
59
60
|
: null),
|
|
@@ -22,6 +22,9 @@ export default function getConfig({ configPath, cwd }: {
|
|
|
22
22
|
includeSegments?: never;
|
|
23
23
|
})) & {
|
|
24
24
|
package?: import("type-fest").PackageJson;
|
|
25
|
+
readme?: {
|
|
26
|
+
banner?: string;
|
|
27
|
+
};
|
|
25
28
|
};
|
|
26
29
|
segmentedClient?: ({
|
|
27
30
|
enabled?: boolean;
|
|
@@ -35,6 +38,9 @@ export default function getConfig({ configPath, cwd }: {
|
|
|
35
38
|
includeSegments?: never;
|
|
36
39
|
})) & {
|
|
37
40
|
packages?: Record<string, import("type-fest").PackageJson>;
|
|
41
|
+
readmes?: Record<string, {
|
|
42
|
+
banner?: string;
|
|
43
|
+
}>;
|
|
38
44
|
};
|
|
39
45
|
bundle?: {
|
|
40
46
|
outDir?: string;
|
|
@@ -42,6 +48,10 @@ export default function getConfig({ configPath, cwd }: {
|
|
|
42
48
|
tsClientOutDir?: string;
|
|
43
49
|
dontDeleteTsClientOutDirAfter?: boolean;
|
|
44
50
|
sourcemap?: boolean;
|
|
51
|
+
package?: import("type-fest").PackageJson;
|
|
52
|
+
readme?: {
|
|
53
|
+
banner?: string;
|
|
54
|
+
};
|
|
45
55
|
} & ({
|
|
46
56
|
excludeSegments?: never;
|
|
47
57
|
includeSegments?: string[];
|
|
@@ -67,7 +77,10 @@ export default function getConfig({ configPath, cwd }: {
|
|
|
67
77
|
controller?: string;
|
|
68
78
|
[key: string]: string | undefined;
|
|
69
79
|
};
|
|
70
|
-
libs?:
|
|
80
|
+
libs?: {
|
|
81
|
+
ajv: import("vovk").KnownAny;
|
|
82
|
+
[key: string]: import("vovk").KnownAny;
|
|
83
|
+
};
|
|
71
84
|
segmentConfig?: false | {
|
|
72
85
|
[x: string]: {
|
|
73
86
|
origin?: string;
|
|
@@ -81,10 +94,14 @@ export default function getConfig({ configPath, cwd }: {
|
|
|
81
94
|
file: string;
|
|
82
95
|
} | {
|
|
83
96
|
url: string;
|
|
84
|
-
|
|
97
|
+
fallback?: string;
|
|
85
98
|
} | {
|
|
86
99
|
object: import("openapi3-ts/oas31").OpenAPIObject;
|
|
87
100
|
};
|
|
101
|
+
package?: import("type-fest").PackageJson;
|
|
102
|
+
readme?: {
|
|
103
|
+
banner?: string;
|
|
104
|
+
};
|
|
88
105
|
apiRoot?: string;
|
|
89
106
|
getModuleName?: "nestjs-operation-id" | (string & {}) | "api" | import("vovk/mjs/types").GetOpenAPINameFn;
|
|
90
107
|
getMethodName?: "nestjs-operation-id" | "camel-case-operation-id" | "auto" | import("vovk/mjs/types").GetOpenAPINameFn;
|
|
@@ -43,7 +43,6 @@ export default async function getConfig({ configPath, cwd }) {
|
|
|
43
43
|
outDir: conf.segmentedClient?.outDir ?? path.join(srcRoot ?? '.', 'client'),
|
|
44
44
|
},
|
|
45
45
|
bundle: {
|
|
46
|
-
...conf.bundle,
|
|
47
46
|
outDir: conf.bundle?.outDir ?? 'dist',
|
|
48
47
|
tsClientOutDir: conf.bundle?.tsClientOutDir ?? 'tmp_ts_rpc',
|
|
49
48
|
dontDeleteTsClientOutDirAfter: conf.bundle?.dontDeleteTsClientOutDirAfter ?? false,
|
|
@@ -52,6 +51,9 @@ export default async function getConfig({ configPath, cwd }) {
|
|
|
52
51
|
[BuiltInTemplateName.readme]: '.',
|
|
53
52
|
[BuiltInTemplateName.packageJson]: '.',
|
|
54
53
|
},
|
|
54
|
+
package: {},
|
|
55
|
+
readme: {},
|
|
56
|
+
...conf.bundle,
|
|
55
57
|
},
|
|
56
58
|
modulesDir: conf.modulesDir ?? path.join(srcRoot ?? '.', 'modules'),
|
|
57
59
|
schemaOutDir: env.VOVK_SCHEMA_OUT_DIR ?? conf.schemaOutDir ?? './.vovk-schema',
|
|
@@ -68,10 +70,7 @@ export default async function getConfig({ configPath, cwd }) {
|
|
|
68
70
|
},
|
|
69
71
|
libs: conf.libs ?? {},
|
|
70
72
|
segmentConfig: conf.segmentConfig ?? {},
|
|
71
|
-
openApiMixins:
|
|
72
|
-
mixinModules: conf.openApiMixins ?? {},
|
|
73
|
-
cwd,
|
|
74
|
-
}),
|
|
73
|
+
openApiMixins: {},
|
|
75
74
|
};
|
|
76
75
|
if (typeof conf.emitConfig === 'undefined') {
|
|
77
76
|
config.emitConfig = ['$schema', 'libs'];
|
|
@@ -83,6 +82,11 @@ export default async function getConfig({ configPath, cwd }) {
|
|
|
83
82
|
config.emitConfig = conf.emitConfig;
|
|
84
83
|
} // else it's false and emitConfig already is []
|
|
85
84
|
const log = getLogger(config.logLevel);
|
|
85
|
+
config.openApiMixins = await normalizeOpenAPIMixins({
|
|
86
|
+
mixinModules: conf.openApiMixins ?? {},
|
|
87
|
+
cwd,
|
|
88
|
+
log,
|
|
89
|
+
});
|
|
86
90
|
if (!userConfig) {
|
|
87
91
|
log.warn(`Unable to load config at ${chalkHighlightThing(cwd)}. Using default values. ${error ?? ''}`);
|
|
88
92
|
}
|
|
@@ -11,6 +11,7 @@ export default function getProjectInfo({ port: givenPort, cwd, configPath, srcRo
|
|
|
11
11
|
apiDirAbsolutePath: string | null;
|
|
12
12
|
srcRoot: string | null;
|
|
13
13
|
config: import("vovk").VovkStrictConfig;
|
|
14
|
+
packageJson: import("type-fest").PackageJson;
|
|
14
15
|
log: {
|
|
15
16
|
info: (msg: string) => void;
|
|
16
17
|
warn: (msg: string) => void;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import getConfig from './getConfig/index.mjs';
|
|
3
|
+
import { getPackageJson } from '../utils/getPackageJson.mjs';
|
|
3
4
|
export default async function getProjectInfo({ port: givenPort, cwd = process.cwd(), configPath, srcRootRequired = true, } = {}) {
|
|
4
5
|
const port = givenPort?.toString() ?? process.env.PORT ?? '3000';
|
|
5
6
|
// Make PORT available to the config file at getConfig
|
|
@@ -8,6 +9,7 @@ export default async function getProjectInfo({ port: givenPort, cwd = process.cw
|
|
|
8
9
|
configPath,
|
|
9
10
|
cwd,
|
|
10
11
|
});
|
|
12
|
+
const packageJson = await getPackageJson(cwd, log);
|
|
11
13
|
if (srcRootRequired && !srcRoot) {
|
|
12
14
|
throw new Error(`Could not find app router directory at ${cwd}. Check Next.js docs for more info.`);
|
|
13
15
|
}
|
|
@@ -23,6 +25,7 @@ export default async function getProjectInfo({ port: givenPort, cwd = process.cw
|
|
|
23
25
|
apiDirAbsolutePath,
|
|
24
26
|
srcRoot,
|
|
25
27
|
config,
|
|
28
|
+
packageJson,
|
|
26
29
|
log,
|
|
27
30
|
};
|
|
28
31
|
}
|
|
@@ -15,9 +15,9 @@ export default async function createConfig({ root, log, options: { validationLib
|
|
|
15
15
|
controller: 'vovk-cli/module-templates/controller.ts.ejs',
|
|
16
16
|
service: 'vovk-cli/module-templates/service.ts.ejs',
|
|
17
17
|
};
|
|
18
|
+
config.imports ??= {};
|
|
19
|
+
config.imports.validateOnClient = validationLibrary === 'vovk-dto' ? 'vovk-dto/validateOnClient' : 'vovk-ajv';
|
|
18
20
|
if (validationLibrary) {
|
|
19
|
-
config.imports ??= {};
|
|
20
|
-
config.imports.validateOnClient = 'vovk-ajv';
|
|
21
21
|
try {
|
|
22
22
|
const validationTemplates = await getTemplateFilesFromPackage(validationLibrary, channel);
|
|
23
23
|
Object.assign(moduleTemplates, validationTemplates);
|
package/dist/init/index.mjs
CHANGED
|
@@ -19,7 +19,7 @@ export class Init {
|
|
|
19
19
|
log;
|
|
20
20
|
async #init({ configPaths, pkgJson, }, { useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary, reactQuery, lang, dryRun, channel, }) {
|
|
21
21
|
const { log, root } = this;
|
|
22
|
-
const dependencies = ['vovk', 'vovk-client'];
|
|
22
|
+
const dependencies = ['vovk', 'vovk-client', 'vovk-ajv', 'openapi3-ts'];
|
|
23
23
|
const devDependencies = ['vovk-cli'];
|
|
24
24
|
if (lang?.includes('py')) {
|
|
25
25
|
dependencies.push('vovk-python');
|
|
@@ -33,9 +33,8 @@ export class Init {
|
|
|
33
33
|
log.debug(`Deleted existing config file${configPaths.length > 1 ? 's' : ''} at ${configPaths.join(', ')}`);
|
|
34
34
|
}
|
|
35
35
|
if (validationLibrary) {
|
|
36
|
-
dependencies.push(validationLibrary,
|
|
36
|
+
dependencies.push(validationLibrary, ...({
|
|
37
37
|
'vovk-zod': ['zod'],
|
|
38
|
-
'vovk-yup': ['yup'],
|
|
39
38
|
'vovk-dto': ['class-validator', 'class-transformer', 'dto-mapped-types', 'reflect-metadata'],
|
|
40
39
|
}[validationLibrary] ?? []));
|
|
41
40
|
}
|
|
@@ -185,11 +184,6 @@ export class Init {
|
|
|
185
184
|
value: 'vovk-zod',
|
|
186
185
|
description: 'Use Zod for data validation',
|
|
187
186
|
},
|
|
188
|
-
{
|
|
189
|
-
name: 'vovk-yup',
|
|
190
|
-
value: 'vovk-yup',
|
|
191
|
-
description: 'Use Yup for data validation',
|
|
192
|
-
},
|
|
193
187
|
{
|
|
194
188
|
name: 'vovk-dto',
|
|
195
189
|
value: 'vovk-dto',
|
package/dist/initProgram.mjs
CHANGED
|
@@ -14,7 +14,7 @@ export function initProgram(program) {
|
|
|
14
14
|
.option('--update-ts-config', 'update tsconfig.json')
|
|
15
15
|
.option('--update-scripts <mode>', 'update package.json scripts ("implicit" or "explicit")')
|
|
16
16
|
.option('--lang <languages...>', 'generate client for other programming languages by default ("py" for Python and "rs" for Rust are supported)')
|
|
17
|
-
.option('--validation-library <library>', 'validation library to use ("vovk-zod", "vovk-
|
|
17
|
+
.option('--validation-library <library>', 'validation library to use ("vovk-zod", "vovk-dto" or another); set to "none" to skip')
|
|
18
18
|
.option('--react-query', 'use @tanstack/react-query for data fetching inside components')
|
|
19
19
|
.option('--channel <channel>', 'channel to use for fetching packages', 'latest')
|
|
20
20
|
.option('--dry-run', 'do not write files to disk')
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
let cachedPromise;
|
|
4
|
+
export function getPackageJson(cwd, log) {
|
|
5
|
+
const pkgPath = path.join(cwd, 'package.json');
|
|
6
|
+
// If we have a cached promise, return it
|
|
7
|
+
if (cachedPromise) {
|
|
8
|
+
return cachedPromise;
|
|
9
|
+
}
|
|
10
|
+
const promise = fs
|
|
11
|
+
.readFile(pkgPath, 'utf8')
|
|
12
|
+
.then((content) => JSON.parse(content))
|
|
13
|
+
.catch(() => {
|
|
14
|
+
cachedPromise = undefined;
|
|
15
|
+
log.warn(`Failed to read package.json at ${pkgPath}. Using a fallback.`);
|
|
16
|
+
return {
|
|
17
|
+
name: 'unknown',
|
|
18
|
+
};
|
|
19
|
+
});
|
|
20
|
+
cachedPromise = promise;
|
|
21
|
+
return promise;
|
|
22
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { VovkStrictConfig, type VovkConfig } from 'vovk';
|
|
2
|
-
|
|
2
|
+
import type { ProjectInfo } from '../getProjectInfo/index.mjs';
|
|
3
|
+
export declare function normalizeOpenAPIMixins({ mixinModules, log, cwd, }: {
|
|
3
4
|
mixinModules: NonNullable<VovkConfig['openApiMixins']>;
|
|
5
|
+
log: ProjectInfo['log'];
|
|
4
6
|
cwd?: string;
|
|
5
7
|
}): Promise<VovkStrictConfig['openApiMixins']>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import * as YAML from 'yaml';
|
|
4
|
+
import chalkHighlightThing from './chalkHighlightThing.mjs';
|
|
4
5
|
async function getOpenApiSpecLocal(openApiSpecFilePath, cwd) {
|
|
5
6
|
const openApiSpecAbsolutePath = path.resolve(cwd, openApiSpecFilePath);
|
|
6
7
|
const fileName = path.basename(openApiSpecAbsolutePath);
|
|
@@ -10,20 +11,36 @@ async function getOpenApiSpecLocal(openApiSpecFilePath, cwd) {
|
|
|
10
11
|
const openApiSpecContent = await fs.readFile(openApiSpecAbsolutePath, 'utf8');
|
|
11
12
|
return (fileName.endsWith('.json') ? JSON.parse(openApiSpecContent) : YAML.parse(openApiSpecContent));
|
|
12
13
|
}
|
|
13
|
-
async function getOpenApiSpecRemote(
|
|
14
|
-
const resp = await fetch(
|
|
14
|
+
async function getOpenApiSpecRemote({ cwd, url, fallback, log, }) {
|
|
15
|
+
const resp = await fetch(url);
|
|
15
16
|
const text = await resp.text();
|
|
16
17
|
if (!resp.ok) {
|
|
17
|
-
|
|
18
|
+
if (fallback) {
|
|
19
|
+
log.warn(`Failed to fetch OpenAPI spec from ${chalkHighlightThing(url)}: ${resp.status} ${resp.statusText}. Falling back to ${chalkHighlightThing(fallback)}`);
|
|
20
|
+
return getOpenApiSpecLocal(fallback, cwd);
|
|
21
|
+
}
|
|
22
|
+
throw new Error(`Failed to fetch OpenAPI spec from ${chalkHighlightThing(url)}: ${resp.status} ${resp.statusText}`);
|
|
23
|
+
}
|
|
24
|
+
if (fallback) {
|
|
25
|
+
const fallbackAbsolutePath = path.resolve(cwd, fallback);
|
|
26
|
+
const existingFallback = await fs.readFile(fallbackAbsolutePath, 'utf8').catch(() => null);
|
|
27
|
+
if (existingFallback !== text) {
|
|
28
|
+
await fs.mkdir(path.dirname(fallbackAbsolutePath), { recursive: true });
|
|
29
|
+
await fs.writeFile(fallbackAbsolutePath, text);
|
|
30
|
+
log.info(`Saved OpenAPI spec to fallback file ${chalkHighlightThing(fallbackAbsolutePath)}`);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
log.debug(`OpenAPI spec at ${chalkHighlightThing(url)} is unchanged. Skipping write to fallback file ${chalkHighlightThing(fallbackAbsolutePath)}`);
|
|
34
|
+
}
|
|
18
35
|
}
|
|
19
36
|
return (text.trim().startsWith('{') || text.trim().startsWith('[') ? JSON.parse(text) : YAML.parse(text));
|
|
20
37
|
}
|
|
21
|
-
export async function normalizeOpenAPIMixins({ mixinModules, cwd = process.cwd(), }) {
|
|
38
|
+
export async function normalizeOpenAPIMixins({ mixinModules, log, cwd = process.cwd(), }) {
|
|
22
39
|
if (mixinModules) {
|
|
23
40
|
const modules = await Promise.all(Object.entries(mixinModules).map(async ([mixinName, { source, apiRoot, getModuleName, getMethodName, errorMessageKey }]) => {
|
|
24
41
|
let openAPIObject;
|
|
25
42
|
if ('url' in source) {
|
|
26
|
-
openAPIObject = await getOpenApiSpecRemote(source.url);
|
|
43
|
+
openAPIObject = await getOpenApiSpecRemote({ url: source.url, fallback: source.fallback, log, cwd });
|
|
27
44
|
}
|
|
28
45
|
else if ('file' in source) {
|
|
29
46
|
openAPIObject = await getOpenApiSpecLocal(source.file, cwd);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vovk-cli",
|
|
3
|
-
"version": "0.0.1-draft.
|
|
3
|
+
"version": "0.0.1-draft.279",
|
|
4
4
|
"bin": {
|
|
5
5
|
"vovk": "./dist/index.mjs"
|
|
6
6
|
},
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"homepage": "https://vovk.dev",
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"vovk": "^3.0.0-draft.
|
|
38
|
+
"vovk": "^3.0.0-draft.315"
|
|
39
39
|
},
|
|
40
40
|
"optionalDependencies": {
|
|
41
41
|
"vovk-python": "^0.0.1-draft.41"
|