vovk-cli 0.0.1-draft.278 → 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/readme/README.md.ejs +2 -1
- package/dist/bundle/index.mjs +2 -0
- package/dist/generate/generate.d.mts +5 -2
- package/dist/generate/generate.mjs +24 -13
- 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 +2 -1
- package/dist/getProjectInfo/getConfig/index.d.mts +13 -0
- package/dist/getProjectInfo/getConfig/index.mjs +3 -1
- 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/package.json +2 -2
|
@@ -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
|
|
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>;
|
|
@@ -42,18 +42,26 @@ function logClientGenerationResults({ results, log, isEnsuringClient = false, fo
|
|
|
42
42
|
const writtenResults = results.filter(({ written }) => written);
|
|
43
43
|
const duration = Date.now() - startTime;
|
|
44
44
|
const groupedByDir = _.groupBy(writtenResults, ({ outAbsoluteDir }) => outAbsoluteDir);
|
|
45
|
+
const logOrDebug = forceNothingWrittenLog ? log.info : log.debug;
|
|
45
46
|
if (writtenResults.length) {
|
|
46
47
|
for (const [outAbsoluteDir, dirResults] of Object.entries(groupedByDir)) {
|
|
47
48
|
const templateNames = _.uniq(dirResults.map(({ templateName }) => templateName));
|
|
48
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`);
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
|
-
else if (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const templateNames = _.uniq(dirResults.map(({ templateName }) => templateName));
|
|
55
|
-
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)`);
|
|
56
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)`);
|
|
57
65
|
}
|
|
58
66
|
}
|
|
59
67
|
const cliOptionsToOpenAPIMixins = ({ openapiGetMethodName, openapiGetModuleName, openapiRootUrl, openapiSpec, openapiMixinName, }) => {
|
|
@@ -63,7 +71,7 @@ const cliOptionsToOpenAPIMixins = ({ openapiGetMethodName, openapiGetModuleName,
|
|
|
63
71
|
apiRoot: openapiRootUrl?.[i] ?? '/',
|
|
64
72
|
getModuleName: openapiGetModuleName?.[i] ?? undefined,
|
|
65
73
|
getMethodName: openapiGetMethodName?.[i] ?? 'auto',
|
|
66
|
-
mixinName: openapiMixinName?.[i]
|
|
74
|
+
mixinName: openapiMixinName?.[i],
|
|
67
75
|
};
|
|
68
76
|
}) || []).map(({ source, apiRoot, getModuleName, getMethodName, mixinName }) => [
|
|
69
77
|
mixinName,
|
|
@@ -76,13 +84,13 @@ const cliOptionsToOpenAPIMixins = ({ openapiGetMethodName, openapiGetModuleName,
|
|
|
76
84
|
},
|
|
77
85
|
]));
|
|
78
86
|
};
|
|
79
|
-
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, }) {
|
|
80
88
|
fullSchema = {
|
|
81
89
|
...fullSchema,
|
|
82
90
|
// sort segments by name to avoid unnecessary rendering
|
|
83
91
|
segments: Object.fromEntries(Object.entries(fullSchema.segments).sort(([a], [b]) => a.localeCompare(b))),
|
|
84
92
|
};
|
|
85
|
-
const { config, cwd, log, srcRoot } = projectInfo;
|
|
93
|
+
const { config, cwd, log, srcRoot, packageJson: rootPackageJson } = projectInfo;
|
|
86
94
|
const allOpenAPIMixins = {
|
|
87
95
|
...config.openApiMixins,
|
|
88
96
|
...cliOptionsToOpenAPIMixins(cliGenerateOptions ?? {}),
|
|
@@ -133,10 +141,10 @@ export async function generate({ isEnsuringClient = false, projectInfo, forceNot
|
|
|
133
141
|
});
|
|
134
142
|
const packageJson = await mergePackages({
|
|
135
143
|
log,
|
|
136
|
-
|
|
137
|
-
config,
|
|
138
|
-
packages: [config.composedClient.package, templateDef.composedClient?.package],
|
|
144
|
+
rootPackageJson,
|
|
145
|
+
packages: [config.composedClient.package, templateDef.composedClient?.package, argPackageJson],
|
|
139
146
|
});
|
|
147
|
+
const readme = Object.assign({}, config.composedClient.readme, templateDef.composedClient?.readme, argReadme);
|
|
140
148
|
const composedFullSchema = pickSegmentFullSchema(fullSchema, segmentNames);
|
|
141
149
|
const hasMixins = Object.values(composedFullSchema.segments).some((segment) => segment.segmentType === 'mixin');
|
|
142
150
|
if (templateName === BuiltInTemplateName.mixins && !hasMixins) {
|
|
@@ -153,6 +161,7 @@ export async function generate({ isEnsuringClient = false, projectInfo, forceNot
|
|
|
153
161
|
templateContent,
|
|
154
162
|
matterResult,
|
|
155
163
|
package: packageJson,
|
|
164
|
+
readme,
|
|
156
165
|
isEnsuringClient,
|
|
157
166
|
outCwdRelativeDir,
|
|
158
167
|
origin: config.origin ?? templateDef?.origin ?? null,
|
|
@@ -207,14 +216,15 @@ export async function generate({ isEnsuringClient = false, projectInfo, forceNot
|
|
|
207
216
|
outCwdRelativeDir,
|
|
208
217
|
});
|
|
209
218
|
const packageJson = await mergePackages({
|
|
210
|
-
cwd,
|
|
211
|
-
config,
|
|
212
219
|
log,
|
|
220
|
+
rootPackageJson,
|
|
213
221
|
packages: [
|
|
214
222
|
config.segmentedClient.packages?.[segmentName],
|
|
215
223
|
templateDef.segmentedClient?.packages?.[segmentName],
|
|
224
|
+
argPackageJson,
|
|
216
225
|
],
|
|
217
226
|
});
|
|
227
|
+
const readme = Object.assign({}, config.segmentedClient.readmes?.[segmentName], templateDef.segmentedClient?.readmes?.[segmentName], argReadme);
|
|
218
228
|
const segmentedFullSchema = pickSegmentFullSchema(fullSchema, [segmentName]);
|
|
219
229
|
const hasMixins = Object.values(segmentedFullSchema.segments).some((segment) => segment.segmentType === 'mixin');
|
|
220
230
|
if (templateName === BuiltInTemplateName.mixins && !hasMixins) {
|
|
@@ -231,6 +241,7 @@ export async function generate({ isEnsuringClient = false, projectInfo, forceNot
|
|
|
231
241
|
templateContent,
|
|
232
242
|
matterResult,
|
|
233
243
|
package: packageJson,
|
|
244
|
+
readme,
|
|
234
245
|
isEnsuringClient,
|
|
235
246
|
outCwdRelativeDir,
|
|
236
247
|
origin: config.origin ?? templateDef?.origin ?? null,
|
|
@@ -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,
|
|
@@ -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[];
|
|
@@ -89,6 +99,9 @@ export default function getConfig({ configPath, cwd }: {
|
|
|
89
99
|
object: import("openapi3-ts/oas31").OpenAPIObject;
|
|
90
100
|
};
|
|
91
101
|
package?: import("type-fest").PackageJson;
|
|
102
|
+
readme?: {
|
|
103
|
+
banner?: string;
|
|
104
|
+
};
|
|
92
105
|
apiRoot?: string;
|
|
93
106
|
getModuleName?: "nestjs-operation-id" | (string & {}) | "api" | import("vovk/mjs/types").GetOpenAPINameFn;
|
|
94
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',
|
|
@@ -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
|
+
}
|
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"
|