vovk-cli 0.0.1-draft.29 → 0.0.1-draft.290
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/LICENSE +1 -1
- package/README.md +29 -1
- package/client-templates/cjs/index.cjs.ejs +14 -0
- package/client-templates/cjs/index.d.cts.ejs +22 -0
- package/client-templates/mixins/mixins.d.ts.ejs +64 -0
- package/client-templates/mixins/mixins.json.ejs +1 -0
- package/client-templates/mjs/index.d.mts.ejs +22 -0
- package/client-templates/mjs/index.mjs.ejs +20 -0
- package/client-templates/packageJson/package.json.ejs +1 -0
- package/client-templates/readme/README.md.ejs +37 -0
- package/client-templates/schemaCjs/schema.cjs.ejs +26 -0
- package/client-templates/schemaCjs/schema.d.cts.ejs +10 -0
- package/client-templates/schemaJson/schema.json.ejs +1 -0
- package/client-templates/schemaTs/schema.ts.ejs +35 -0
- package/client-templates/ts/index.ts.ejs +30 -0
- package/dist/bundle/index.d.mts +8 -0
- package/dist/bundle/index.mjs +90 -0
- package/dist/dev/diffSegmentSchema.d.mts +36 -0
- package/dist/dev/{diffSchema.mjs → diffSegmentSchema.mjs} +3 -11
- package/dist/dev/ensureSchemaFiles.d.mts +3 -0
- package/dist/dev/ensureSchemaFiles.mjs +15 -31
- package/dist/dev/index.d.mts +5 -2
- package/dist/dev/index.mjs +173 -77
- package/dist/dev/logDiffResult.d.mts +1 -1
- package/dist/dev/logDiffResult.mjs +6 -43
- package/dist/dev/writeMetaJson.d.mts +2 -0
- package/dist/dev/writeMetaJson.mjs +17 -0
- package/dist/dev/writeOneSegmentSchemaFile.d.mts +12 -0
- package/dist/dev/{writeOneSchemaFile.mjs → writeOneSegmentSchemaFile.mjs} +10 -6
- package/dist/generate/ensureClient.d.mts +3 -0
- package/dist/generate/ensureClient.mjs +32 -0
- package/dist/generate/generate.d.mts +15 -0
- package/dist/generate/generate.mjs +285 -0
- package/dist/generate/getClientTemplateFiles.d.mts +20 -0
- package/dist/generate/getClientTemplateFiles.mjs +89 -0
- package/dist/generate/getProjectFullSchema.d.mts +3 -0
- package/dist/generate/getProjectFullSchema.mjs +64 -0
- package/dist/generate/getTemplateClientImports.d.mts +18 -0
- package/dist/generate/getTemplateClientImports.mjs +38 -0
- package/dist/generate/index.d.mts +33 -0
- package/dist/generate/index.mjs +185 -0
- package/dist/generate/mergePackages.d.mts +7 -0
- package/dist/generate/mergePackages.mjs +55 -0
- package/dist/generate/writeOneClientFile.d.mts +35 -0
- package/dist/generate/writeOneClientFile.mjs +114 -0
- package/dist/getProjectInfo/getConfig/getConfigAbsolutePaths.d.mts +5 -0
- package/dist/getProjectInfo/{getConfigAbsolutePaths.mjs → getConfig/getConfigAbsolutePaths.mjs} +4 -1
- package/dist/getProjectInfo/{getRelativeSrcRoot.d.mts → getConfig/getRelativeSrcRoot.d.mts} +1 -1
- package/dist/getProjectInfo/{getRelativeSrcRoot.mjs → getConfig/getRelativeSrcRoot.mjs} +2 -2
- package/dist/getProjectInfo/getConfig/getTemplateDefs.d.mts +16 -0
- package/dist/getProjectInfo/getConfig/getTemplateDefs.mjs +98 -0
- package/dist/getProjectInfo/{getUserConfig.d.mts → getConfig/getUserConfig.d.mts} +3 -2
- package/dist/getProjectInfo/{getUserConfig.mjs → getConfig/getUserConfig.mjs} +6 -4
- package/dist/getProjectInfo/{importUncachedModule.mjs → getConfig/importUncachedModule.mjs} +1 -5
- package/dist/getProjectInfo/{importUncachedModuleWorker.mjs → getConfig/importUncachedModuleWorker.mjs} +0 -1
- package/dist/getProjectInfo/getConfig/index.d.mts +119 -0
- package/dist/getProjectInfo/getConfig/index.mjs +94 -0
- package/dist/getProjectInfo/index.d.mts +11 -9
- package/dist/getProjectInfo/index.mjs +19 -22
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +98 -40
- package/dist/init/createConfig.d.mts +2 -2
- package/dist/init/createConfig.mjs +18 -12
- package/dist/init/getTemplateFilesFromPackage.mjs +10 -5
- package/dist/init/index.d.mts +2 -2
- package/dist/init/index.mjs +90 -60
- package/dist/init/installDependencies.mjs +4 -2
- package/dist/init/logUpdateDependenciesError.d.mts +3 -1
- package/dist/init/logUpdateDependenciesError.mjs +7 -1
- package/dist/init/updateDependenciesWithoutInstalling.mjs +39 -9
- package/dist/init/updateNPMScripts.d.mts +3 -1
- package/dist/init/updateNPMScripts.mjs +10 -7
- package/dist/init/updateTypeScriptConfig.d.mts +4 -1
- package/dist/init/updateTypeScriptConfig.mjs +11 -7
- package/dist/initProgram.d.mts +1 -1
- package/dist/initProgram.mjs +17 -16
- package/dist/locateSegments.d.mts +8 -1
- package/dist/locateSegments.mjs +14 -4
- package/dist/new/addClassToSegmentCode.d.mts +1 -2
- package/dist/new/addClassToSegmentCode.mjs +3 -3
- package/dist/new/addCommonTerms.mjs +1 -0
- package/dist/new/index.d.mts +1 -1
- package/dist/new/index.mjs +3 -2
- package/dist/new/newModule.d.mts +2 -1
- package/dist/new/newModule.mjs +18 -16
- package/dist/new/newSegment.d.mts +2 -1
- package/dist/new/newSegment.mjs +19 -10
- package/dist/new/render.d.mts +7 -3
- package/dist/new/render.mjs +29 -8
- package/dist/types.d.mts +50 -41
- package/dist/utils/compileJSONSchemaToTypeScriptType.d.mts +5 -0
- package/dist/utils/compileJSONSchemaToTypeScriptType.mjs +9 -0
- package/dist/utils/compileTs.d.mts +12 -0
- package/dist/utils/compileTs.mjs +261 -0
- package/dist/utils/debounceWithArgs.d.mts +2 -2
- package/dist/utils/debounceWithArgs.mjs +24 -9
- package/dist/utils/formatLoggedSegmentName.d.mts +3 -1
- package/dist/utils/formatLoggedSegmentName.mjs +3 -2
- package/dist/utils/getAvailablePort.mjs +1 -1
- package/dist/utils/getPackageJson.d.mts +3 -0
- package/dist/utils/getPackageJson.mjs +22 -0
- package/dist/utils/getPublicModuleNameFromPath.d.mts +4 -0
- package/dist/utils/getPublicModuleNameFromPath.mjs +9 -0
- package/dist/utils/normalizeOpenAPIMixins.d.mts +7 -0
- package/dist/utils/normalizeOpenAPIMixins.mjs +66 -0
- package/dist/utils/pickSegmentFullSchema.d.mts +3 -0
- package/dist/utils/pickSegmentFullSchema.mjs +15 -0
- package/dist/utils/removeUnlistedDirectories.d.mts +10 -0
- package/dist/utils/removeUnlistedDirectories.mjs +61 -0
- package/dist/utils/resolveAbsoluteModulePath.d.mts +2 -0
- package/dist/utils/resolveAbsoluteModulePath.mjs +32 -0
- package/module-templates/controller.ts.ejs +56 -0
- package/module-templates/service.ts.ejs +28 -0
- package/package.json +41 -22
- package/dist/dev/diffSchema.d.mts +0 -43
- package/dist/dev/ensureClient.d.mts +0 -5
- package/dist/dev/ensureClient.mjs +0 -31
- package/dist/dev/isMetadataEmpty.d.mts +0 -2
- package/dist/dev/isMetadataEmpty.mjs +0 -4
- package/dist/dev/writeOneSchemaFile.d.mts +0 -11
- package/dist/generateClient.d.mts +0 -7
- package/dist/generateClient.mjs +0 -97
- package/dist/getProjectInfo/getConfig.d.mts +0 -11
- package/dist/getProjectInfo/getConfig.mjs +0 -29
- package/dist/getProjectInfo/getConfigAbsolutePaths.d.mts +0 -4
- package/dist/postinstall.d.mts +0 -1
- package/dist/postinstall.mjs +0 -24
- package/templates/controller.ejs +0 -51
- package/templates/service.ejs +0 -27
- package/templates/worker.ejs +0 -24
- /package/dist/getProjectInfo/{importUncachedModule.d.mts → getConfig/importUncachedModule.d.mts} +0 -0
- /package/dist/getProjectInfo/{importUncachedModuleWorker.d.mts → getConfig/importUncachedModuleWorker.d.mts} +0 -0
package/dist/init/index.mjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { confirm, select } from '@inquirer/prompts';
|
|
1
|
+
import { confirm, select, checkbox } from '@inquirer/prompts';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import fs from 'node:fs/promises';
|
|
4
|
-
import getConfigPaths from '../getProjectInfo/getConfigAbsolutePaths.mjs';
|
|
5
4
|
import chalk from 'chalk';
|
|
5
|
+
import NPMCliPackageJson from '@npmcli/package-json';
|
|
6
|
+
import getConfigPaths from '../getProjectInfo/getConfig/getConfigAbsolutePaths.mjs';
|
|
6
7
|
import getFileSystemEntryType from '../utils/getFileSystemEntryType.mjs';
|
|
7
8
|
import installDependencies, { getPackageManager } from './installDependencies.mjs';
|
|
8
9
|
import getLogger from '../utils/getLogger.mjs';
|
|
9
10
|
import createConfig from './createConfig.mjs';
|
|
10
|
-
import updateNPMScripts from './updateNPMScripts.mjs';
|
|
11
|
+
import updateNPMScripts, { getDevScript } from './updateNPMScripts.mjs';
|
|
11
12
|
import checkTSConfigForExperimentalDecorators from './checkTSConfigForExperimentalDecorators.mjs';
|
|
12
13
|
import updateTypeScriptConfig from './updateTypeScriptConfig.mjs';
|
|
13
14
|
import updateDependenciesWithoutInstalling from './updateDependenciesWithoutInstalling.mjs';
|
|
@@ -16,27 +17,34 @@ import chalkHighlightThing from '../utils/chalkHighlightThing.mjs';
|
|
|
16
17
|
export class Init {
|
|
17
18
|
root;
|
|
18
19
|
log;
|
|
19
|
-
async #init({ configPaths, }, { useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary,
|
|
20
|
+
async #init({ configPaths, pkgJson, }, { useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary, reactQuery, lang, dryRun, channel, }) {
|
|
20
21
|
const { log, root } = this;
|
|
21
|
-
const dependencies = ['vovk'];
|
|
22
|
+
const dependencies = ['vovk', 'vovk-client', 'vovk-ajv', 'openapi3-ts'];
|
|
22
23
|
const devDependencies = ['vovk-cli'];
|
|
24
|
+
if (lang?.includes('py')) {
|
|
25
|
+
devDependencies.push('vovk-python');
|
|
26
|
+
}
|
|
27
|
+
if (lang?.includes('rs')) {
|
|
28
|
+
devDependencies.push('vovk-rust');
|
|
29
|
+
}
|
|
23
30
|
// delete older config files
|
|
24
31
|
if (configPaths.length) {
|
|
25
32
|
await Promise.all(configPaths.map((configPath) => fs.rm(configPath)));
|
|
26
33
|
log.debug(`Deleted existing config file${configPaths.length > 1 ? 's' : ''} at ${configPaths.join(', ')}`);
|
|
27
34
|
}
|
|
28
35
|
if (validationLibrary) {
|
|
29
|
-
dependencies.push(validationLibrary
|
|
30
|
-
dependencies.push(...({
|
|
36
|
+
dependencies.push(validationLibrary, ...({
|
|
31
37
|
'vovk-zod': ['zod'],
|
|
32
|
-
'vovk-
|
|
33
|
-
'vovk-dto': ['class-validator', 'class-transformer'],
|
|
38
|
+
'vovk-dto': ['class-validator', 'class-transformer', 'dto-mapped-types', 'reflect-metadata'],
|
|
34
39
|
}[validationLibrary] ?? []));
|
|
35
40
|
}
|
|
41
|
+
if (reactQuery) {
|
|
42
|
+
dependencies.push('vovk-react-query', '@tanstack/react-query');
|
|
43
|
+
}
|
|
36
44
|
if (updateScripts) {
|
|
37
45
|
try {
|
|
38
46
|
if (!dryRun)
|
|
39
|
-
await updateNPMScripts(root, updateScripts);
|
|
47
|
+
await updateNPMScripts(pkgJson, root, updateScripts);
|
|
40
48
|
log.info('Updated scripts at package.json');
|
|
41
49
|
}
|
|
42
50
|
catch (error) {
|
|
@@ -48,9 +56,17 @@ export class Init {
|
|
|
48
56
|
}
|
|
49
57
|
if (updateTsConfig) {
|
|
50
58
|
try {
|
|
59
|
+
const compilerOptions = {
|
|
60
|
+
experimentalDecorators: true,
|
|
61
|
+
};
|
|
62
|
+
if (validationLibrary === 'vovk-dto') {
|
|
63
|
+
compilerOptions.emitDecoratorMetadata = true;
|
|
64
|
+
}
|
|
51
65
|
if (!dryRun)
|
|
52
|
-
await updateTypeScriptConfig(root);
|
|
53
|
-
log.info(
|
|
66
|
+
await updateTypeScriptConfig(root, compilerOptions);
|
|
67
|
+
log.info(`Added ${Object.keys(compilerOptions)
|
|
68
|
+
.map((k) => `"${k}"`)
|
|
69
|
+
.join(' and ')} to tsconfig.json`);
|
|
54
70
|
}
|
|
55
71
|
catch (error) {
|
|
56
72
|
log.error(`Failed to update tsconfig.json: ${error.message}`);
|
|
@@ -70,7 +86,17 @@ export class Init {
|
|
|
70
86
|
}
|
|
71
87
|
catch (e) {
|
|
72
88
|
const error = e;
|
|
73
|
-
logUpdateDependenciesError({
|
|
89
|
+
logUpdateDependenciesError({
|
|
90
|
+
log,
|
|
91
|
+
error,
|
|
92
|
+
useNpm,
|
|
93
|
+
useYarn,
|
|
94
|
+
usePnpm,
|
|
95
|
+
useBun,
|
|
96
|
+
dependencies,
|
|
97
|
+
devDependencies,
|
|
98
|
+
channel,
|
|
99
|
+
});
|
|
74
100
|
}
|
|
75
101
|
if (depsUpdated) {
|
|
76
102
|
const packageManager = getPackageManager({ useNpm, useYarn, usePnpm, useBun });
|
|
@@ -92,7 +118,7 @@ export class Init {
|
|
|
92
118
|
log.info('Dependencies installed successfully');
|
|
93
119
|
}
|
|
94
120
|
catch (error) {
|
|
95
|
-
log.warn(`Failed to install dependencies
|
|
121
|
+
log.warn(`Failed to install dependencies. ${error.message}. Please, install them manually with ${chalkHighlightThing(packageManager + ' install')}`);
|
|
96
122
|
}
|
|
97
123
|
}
|
|
98
124
|
}
|
|
@@ -101,23 +127,24 @@ export class Init {
|
|
|
101
127
|
const { configAbsolutePath } = await createConfig({
|
|
102
128
|
root,
|
|
103
129
|
log,
|
|
104
|
-
options: { validationLibrary,
|
|
130
|
+
options: { validationLibrary, reactQuery, channel, lang, dryRun },
|
|
105
131
|
});
|
|
106
|
-
log.info('Config created successfully at ' + configAbsolutePath);
|
|
132
|
+
log.info('Config created successfully at ' + chalkHighlightThing(configAbsolutePath));
|
|
107
133
|
}
|
|
108
134
|
catch (error) {
|
|
109
135
|
log.error(`Failed to create config: ${error.message}`);
|
|
110
136
|
}
|
|
111
137
|
}
|
|
112
|
-
async main(prefix, { yes, logLevel, useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary,
|
|
138
|
+
async main(prefix, { yes, logLevel, useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary, reactQuery, lang, dryRun, channel, }) {
|
|
113
139
|
const cwd = process.cwd();
|
|
114
140
|
const root = path.resolve(cwd, prefix);
|
|
115
141
|
const log = getLogger(logLevel);
|
|
142
|
+
const pkgJson = await NPMCliPackageJson.load(root);
|
|
116
143
|
this.root = root;
|
|
117
144
|
this.log = log;
|
|
118
145
|
const configPaths = await getConfigPaths({ cwd, relativePath: prefix });
|
|
119
146
|
if (yes) {
|
|
120
|
-
return this.#init({ configPaths }, {
|
|
147
|
+
return this.#init({ configPaths, pkgJson }, {
|
|
121
148
|
useNpm: useNpm ?? (!useYarn && !usePnpm && !useBun),
|
|
122
149
|
useYarn: useYarn ?? false,
|
|
123
150
|
usePnpm: usePnpm ?? false,
|
|
@@ -126,9 +153,10 @@ export class Init {
|
|
|
126
153
|
updateTsConfig: updateTsConfig ?? true,
|
|
127
154
|
updateScripts: updateScripts ?? 'implicit',
|
|
128
155
|
validationLibrary: validationLibrary?.toLocaleLowerCase() === 'none' ? null : (validationLibrary ?? 'vovk-zod'),
|
|
129
|
-
|
|
156
|
+
reactQuery: reactQuery ?? true,
|
|
130
157
|
dryRun: dryRun ?? false,
|
|
131
158
|
channel: channel ?? 'latest',
|
|
159
|
+
lang: lang ?? [],
|
|
132
160
|
});
|
|
133
161
|
}
|
|
134
162
|
if (!(await getFileSystemEntryType(path.join(root, 'package.json')))) {
|
|
@@ -156,64 +184,65 @@ export class Init {
|
|
|
156
184
|
value: 'vovk-zod',
|
|
157
185
|
description: 'Use Zod for data validation',
|
|
158
186
|
},
|
|
159
|
-
{
|
|
160
|
-
name: 'vovk-yup',
|
|
161
|
-
value: 'vovk-yup',
|
|
162
|
-
description: 'Use Yup for data validation',
|
|
163
|
-
},
|
|
164
187
|
{
|
|
165
188
|
name: 'vovk-dto',
|
|
166
189
|
value: 'vovk-dto',
|
|
167
|
-
description: 'Use class-validator
|
|
190
|
+
description: 'Use class-validator for data validation. Also installs class-transformer, dto-mapped-types and reflect-metadata',
|
|
168
191
|
},
|
|
169
192
|
{ name: 'None', value: null, description: 'Install validation library later' },
|
|
170
193
|
],
|
|
171
194
|
})));
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
value: undefined,
|
|
198
|
-
description: 'Add the NPM scripts manually',
|
|
199
|
-
},
|
|
200
|
-
],
|
|
201
|
-
}));
|
|
195
|
+
updateScripts ??= await select({
|
|
196
|
+
message: 'Do you want to update "dev" NPM script at package.json?',
|
|
197
|
+
default: 'implicit',
|
|
198
|
+
choices: [
|
|
199
|
+
{
|
|
200
|
+
name: 'Yes, use "concurrently" implicitly',
|
|
201
|
+
value: 'implicit',
|
|
202
|
+
description: `The script will use "concurrently" API to run "next dev" and "vovk dev" commands together and automatically find an available port ${chalk.whiteBright.bold(`"${getDevScript(pkgJson, 'implicit')}"`)}`,
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: 'Yes, use "concurrently" explicitly',
|
|
206
|
+
value: 'explicit',
|
|
207
|
+
description: `The script will use pre-defined PORT variable and run "next dev" and "vovk dev" as "concurrently" CLI arguments ${chalk.whiteBright.bold(`"${getDevScript(pkgJson, 'explicit')}"`)}`,
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: 'No',
|
|
211
|
+
value: undefined,
|
|
212
|
+
description: 'Add the NPM scripts manually',
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
});
|
|
216
|
+
reactQuery ??= await confirm({
|
|
217
|
+
default: false,
|
|
218
|
+
message: 'Do you want to use @tanstack/react-query for data fetching at React components?',
|
|
219
|
+
});
|
|
202
220
|
if (typeof updateTsConfig === 'undefined') {
|
|
203
221
|
let shouldAsk = false;
|
|
204
222
|
try {
|
|
205
|
-
shouldAsk = !(await checkTSConfigForExperimentalDecorators(root));
|
|
223
|
+
shouldAsk = !(await checkTSConfigForExperimentalDecorators(root)); // TODO also check for emitDecoratorMetadata when vovk-dto is used
|
|
206
224
|
}
|
|
207
225
|
catch (error) {
|
|
208
|
-
log.error(`Failed to check tsconfig.json for experimentalDecorators: ${error.message}`);
|
|
226
|
+
log.error(`Failed to check tsconfig.json for "experimentalDecorators": ${error.message}`);
|
|
209
227
|
}
|
|
210
228
|
if (shouldAsk) {
|
|
229
|
+
const keys = ['experimentalDecorators'];
|
|
230
|
+
if (validationLibrary === 'vovk-dto') {
|
|
231
|
+
keys.push('emitDecoratorMetadata');
|
|
232
|
+
}
|
|
211
233
|
updateTsConfig = await confirm({
|
|
212
|
-
message:
|
|
234
|
+
message: `Do you want to add ${keys.map((k) => `"${k}"`).join(' and ')} to tsconfig.json?`,
|
|
213
235
|
});
|
|
214
236
|
}
|
|
215
237
|
}
|
|
216
|
-
await
|
|
238
|
+
lang ??= await checkbox({
|
|
239
|
+
message: 'Do you want to generate RPC client for other languages besides TypeScript?',
|
|
240
|
+
choices: [
|
|
241
|
+
{ name: 'Python', value: 'py' },
|
|
242
|
+
{ name: 'Rust', value: 'rs' },
|
|
243
|
+
],
|
|
244
|
+
});
|
|
245
|
+
await this.#init({ configPaths, pkgJson }, {
|
|
217
246
|
useNpm: useNpm ?? (!useYarn && !usePnpm && !useBun),
|
|
218
247
|
useYarn: useYarn ?? false,
|
|
219
248
|
usePnpm: usePnpm ?? false,
|
|
@@ -222,7 +251,8 @@ export class Init {
|
|
|
222
251
|
updateTsConfig,
|
|
223
252
|
updateScripts,
|
|
224
253
|
validationLibrary,
|
|
225
|
-
|
|
254
|
+
reactQuery,
|
|
255
|
+
lang,
|
|
226
256
|
dryRun,
|
|
227
257
|
channel,
|
|
228
258
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
+
import chalkHighlightThing from '../utils/chalkHighlightThing.mjs';
|
|
2
3
|
export function getPackageManager(options) {
|
|
3
4
|
if (options.useNpm)
|
|
4
5
|
return 'npm';
|
|
@@ -12,9 +13,10 @@ export function getPackageManager(options) {
|
|
|
12
13
|
}
|
|
13
14
|
export default async function installDependencies({ log, cwd, options, }) {
|
|
14
15
|
const packageManager = getPackageManager(options);
|
|
15
|
-
log.info(`Installing dependencies at ${cwd} using ${packageManager}...`);
|
|
16
|
+
log.info(`Installing dependencies at ${chalkHighlightThing(cwd)} using ${chalkHighlightThing(packageManager)}...`);
|
|
16
17
|
await new Promise((resolve, reject) => {
|
|
17
|
-
const
|
|
18
|
+
const args = packageManager === 'yarn' ? ['install', '--non-interactive'] : ['install'];
|
|
19
|
+
const child = spawn(packageManager, args, { cwd, stdio: 'inherit' });
|
|
18
20
|
child.on('close', (code) => {
|
|
19
21
|
if (code === 0) {
|
|
20
22
|
resolve();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { InitOptions } from '../types.mjs';
|
|
1
2
|
import type getLogger from '../utils/getLogger.mjs';
|
|
2
|
-
export default function logUpdateDependenciesError({ useNpm, useYarn, usePnpm, useBun, log, dependencies, devDependencies, error, }: {
|
|
3
|
+
export default function logUpdateDependenciesError({ useNpm, useYarn, usePnpm, useBun, log, dependencies, devDependencies, error, channel, }: {
|
|
3
4
|
useNpm?: boolean;
|
|
4
5
|
useYarn?: boolean;
|
|
5
6
|
usePnpm?: boolean;
|
|
@@ -8,4 +9,5 @@ export default function logUpdateDependenciesError({ useNpm, useYarn, usePnpm, u
|
|
|
8
9
|
dependencies: string[];
|
|
9
10
|
devDependencies: string[];
|
|
10
11
|
error: Error;
|
|
12
|
+
channel: InitOptions['channel'];
|
|
11
13
|
}): void;
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import chalkHighlightThing from '../utils/chalkHighlightThing.mjs';
|
|
2
2
|
import { getPackageManager } from './installDependencies.mjs';
|
|
3
|
-
export default function logUpdateDependenciesError({ useNpm, useYarn, usePnpm, useBun, log, dependencies, devDependencies, error, }) {
|
|
3
|
+
export default function logUpdateDependenciesError({ useNpm, useYarn, usePnpm, useBun, log, dependencies, devDependencies, error, channel, }) {
|
|
4
4
|
const packageManager = getPackageManager({ useNpm, useYarn, usePnpm, useBun });
|
|
5
5
|
const installCommands = [];
|
|
6
|
+
const addChannel = (packageName) => {
|
|
7
|
+
const isVovk = packageName.startsWith('vovk') && packageName !== 'dto-mapped-types';
|
|
8
|
+
return isVovk ? (!channel || channel !== 'latest' ? `${packageName}@${channel}` : packageName) : packageName;
|
|
9
|
+
};
|
|
10
|
+
dependencies = dependencies.map(addChannel);
|
|
11
|
+
devDependencies = devDependencies.map(addChannel);
|
|
6
12
|
if (dependencies.length > 0) {
|
|
7
13
|
let depInstallCmd = '';
|
|
8
14
|
switch (packageManager) {
|
|
@@ -2,22 +2,52 @@ import fs from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import getNPMPackageMetadata from '../utils/getNPMPackageMetadata.mjs';
|
|
5
|
-
async function updateDeps({ packageJson, packageNames, channel, key, }) {
|
|
5
|
+
async function updateDeps({ packageJson, packageNames, channel, key, log, }) {
|
|
6
6
|
return Promise.all(packageNames.map(async (packageName) => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
let name;
|
|
8
|
+
let version;
|
|
9
|
+
if (packageName.startsWith('@')) {
|
|
10
|
+
// Handle scoped packages (@org/name@version)
|
|
11
|
+
const lastAtIndex = packageName.lastIndexOf('@');
|
|
12
|
+
if (lastAtIndex > 0) {
|
|
13
|
+
name = packageName.substring(0, lastAtIndex);
|
|
14
|
+
version = packageName.substring(lastAtIndex + 1);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
name = packageName;
|
|
18
|
+
version = undefined;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
// Handle regular packages (name@version)
|
|
23
|
+
const parts = packageName.split('@');
|
|
24
|
+
name = parts[0];
|
|
25
|
+
version = parts[1];
|
|
26
|
+
}
|
|
27
|
+
if (version) {
|
|
28
|
+
packageJson[key] ??= {};
|
|
29
|
+
packageJson[key][name] = version;
|
|
30
|
+
return;
|
|
12
31
|
}
|
|
13
|
-
|
|
32
|
+
let metadata;
|
|
33
|
+
try {
|
|
34
|
+
metadata = await getNPMPackageMetadata(name);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
log.error(`Failed to fetch metadata for package ${name}@${channel ?? 'latest'}: ${error}`);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const isVovk = name.startsWith('vovk') && name !== 'dto-mapped-types';
|
|
41
|
+
const latestVersion = metadata['dist-tags'][isVovk ? (channel ?? 'latest') : 'latest'];
|
|
42
|
+
packageJson[key] ??= {};
|
|
43
|
+
packageJson[key][name] = `^${latestVersion}`;
|
|
14
44
|
}));
|
|
15
45
|
}
|
|
16
46
|
export default async function updateDependenciesWithoutInstalling({ log, dir, dependencyNames, devDependencyNames, channel, }) {
|
|
17
47
|
const packageJsonPath = path.join(dir, 'package.json');
|
|
18
48
|
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));
|
|
19
|
-
await updateDeps({ packageJson, packageNames: dependencyNames, channel, key: 'dependencies' });
|
|
20
|
-
await updateDeps({ packageJson, packageNames: devDependencyNames, channel, key: 'devDependencies' });
|
|
49
|
+
await updateDeps({ packageJson, packageNames: dependencyNames, channel, log, key: 'dependencies' });
|
|
50
|
+
await updateDeps({ packageJson, packageNames: devDependencyNames, channel, log, key: 'devDependencies' });
|
|
21
51
|
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
22
52
|
log.info('Added dependencies to package.json:');
|
|
23
53
|
for (const dependency of dependencyNames) {
|
|
@@ -1 +1,3 @@
|
|
|
1
|
-
|
|
1
|
+
import NPMCliPackageJson from '@npmcli/package-json';
|
|
2
|
+
export declare function getDevScript(pkgJson: NPMCliPackageJson, updateScriptsMode: 'implicit' | 'explicit'): string;
|
|
3
|
+
export default function updateNPMScripts(pkgJson: NPMCliPackageJson, root: string, updateScriptsMode: 'implicit' | 'explicit'): Promise<void>;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const
|
|
1
|
+
export function getDevScript(pkgJson, updateScriptsMode) {
|
|
2
|
+
const nextDev = pkgJson.content.scripts?.dev ?? 'next dev';
|
|
3
|
+
const nextDevFlags = nextDev.replace('next dev', '').trim();
|
|
4
|
+
return updateScriptsMode === 'explicit'
|
|
5
|
+
? `PORT=3000 concurrently '${nextDev}' 'vovk dev' --kill-others`
|
|
6
|
+
: `vovk dev --next-dev${nextDevFlags ? ` -- ${nextDevFlags}` : ''}`;
|
|
7
|
+
}
|
|
8
|
+
export default async function updateNPMScripts(pkgJson, root, updateScriptsMode) {
|
|
4
9
|
pkgJson.update({
|
|
5
10
|
scripts: {
|
|
6
|
-
|
|
7
|
-
dev: updateScriptsMode
|
|
8
|
-
? "PORT=3000 concurrently 'next dev' 'vovk dev' --kill-others"
|
|
9
|
-
: 'vovk dev --next-dev',
|
|
11
|
+
...pkgJson.content.scripts,
|
|
12
|
+
dev: getDevScript(pkgJson, updateScriptsMode),
|
|
10
13
|
},
|
|
11
14
|
});
|
|
12
15
|
await pkgJson.save();
|
|
@@ -2,14 +2,18 @@ import path from 'node:path';
|
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
3
|
import * as jsonc from 'jsonc-parser';
|
|
4
4
|
import prettify from '../utils/prettify.mjs';
|
|
5
|
-
export default async function updateTypeScriptConfig(root) {
|
|
5
|
+
export default async function updateTypeScriptConfig(root, compilerOptions) {
|
|
6
6
|
const tsconfigPath = path.join(root, 'tsconfig.json');
|
|
7
7
|
const tsconfigContent = await fs.readFile(tsconfigPath, 'utf8');
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
let updatedContent = tsconfigContent;
|
|
9
|
+
// Apply each compiler option
|
|
10
|
+
for (const [key, value] of Object.entries(compilerOptions)) {
|
|
11
|
+
const edits = jsonc.modify(updatedContent, ['compilerOptions', key], value, {
|
|
12
|
+
formattingOptions: {},
|
|
13
|
+
});
|
|
14
|
+
updatedContent = jsonc.applyEdits(updatedContent, edits);
|
|
15
|
+
}
|
|
16
|
+
// Prettify the final content
|
|
17
|
+
updatedContent = await prettify(updatedContent, tsconfigPath);
|
|
14
18
|
await fs.writeFile(tsconfigPath, updatedContent, 'utf8');
|
|
15
19
|
}
|
package/dist/initProgram.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
export
|
|
2
|
+
export declare function initProgram(program: Command): Command;
|
package/dist/initProgram.mjs
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { Init } from './init/index.mjs';
|
|
2
2
|
// reused at vovk-init
|
|
3
|
-
export
|
|
3
|
+
export function initProgram(program) {
|
|
4
4
|
return program
|
|
5
|
-
.argument('[prefix]', '
|
|
6
|
-
.description('Initialize Vovk project')
|
|
7
|
-
.option('-y, --yes', '
|
|
8
|
-
.option('--log-level <level>', '
|
|
9
|
-
.option('--use-npm', '
|
|
10
|
-
.option('--use-yarn', '
|
|
11
|
-
.option('--use-pnpm', '
|
|
12
|
-
.option('--use-bun', '
|
|
13
|
-
.option('--skip-install', '
|
|
14
|
-
.option('--update-ts-config', '
|
|
15
|
-
.option('--update-scripts <mode>', '
|
|
16
|
-
.option('--
|
|
17
|
-
.option('--
|
|
18
|
-
.option('--
|
|
19
|
-
.option('--
|
|
5
|
+
.argument('[prefix]', 'directory to initialize project in', '.')
|
|
6
|
+
.description('Initialize Vovk.ts project')
|
|
7
|
+
.option('-y, --yes', 'skip all prompts and use default values')
|
|
8
|
+
.option('--log-level <level>', 'set log level', 'info')
|
|
9
|
+
.option('--use-npm', 'use npm as package manager')
|
|
10
|
+
.option('--use-yarn', 'use yarn as package manager')
|
|
11
|
+
.option('--use-pnpm', 'use pnpm as package manager')
|
|
12
|
+
.option('--use-bun', 'use bun as package manager')
|
|
13
|
+
.option('--skip-install', 'skip installing dependencies')
|
|
14
|
+
.option('--update-ts-config', 'update tsconfig.json')
|
|
15
|
+
.option('--update-scripts <mode>', 'update package.json scripts ("implicit" or "explicit")')
|
|
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-dto" or another); set to "none" to skip')
|
|
18
|
+
.option('--react-query', 'use @tanstack/react-query for data fetching inside components')
|
|
19
|
+
.option('--channel <channel>', 'channel to use for fetching packages', 'latest')
|
|
20
|
+
.option('--dry-run', 'do not write files to disk')
|
|
20
21
|
.action((prefix = '.', options) => new Init().main(prefix, options));
|
|
21
22
|
}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
import type { VovkStrictConfig } from 'vovk';
|
|
2
|
+
import type { ProjectInfo } from './getProjectInfo/index.mjs';
|
|
1
3
|
export type Segment = {
|
|
2
4
|
routeFilePath: string;
|
|
3
5
|
segmentName: string;
|
|
4
6
|
};
|
|
5
|
-
export
|
|
7
|
+
export declare function locateSegments({ dir, rootDir, config, log, }: {
|
|
8
|
+
dir: string | null;
|
|
9
|
+
rootDir?: string;
|
|
10
|
+
config: VovkStrictConfig | null;
|
|
11
|
+
log: ProjectInfo['log'];
|
|
12
|
+
}): Promise<Segment[]>;
|
package/dist/locateSegments.mjs
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import getFileSystemEntryType from './utils/getFileSystemEntryType.mjs';
|
|
4
|
-
export
|
|
4
|
+
export async function locateSegments({ dir, rootDir, config, log, }) {
|
|
5
5
|
let results = [];
|
|
6
|
+
if (!dir)
|
|
7
|
+
return results; // If dir is null, return empty results because this isn't a Next.js app
|
|
8
|
+
rootDir = rootDir ?? dir;
|
|
9
|
+
let list = [];
|
|
6
10
|
// Read the contents of the directory
|
|
7
|
-
|
|
11
|
+
try {
|
|
12
|
+
list = (await fs.readdir(dir)).toSorted();
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// do nothing
|
|
16
|
+
return results;
|
|
17
|
+
}
|
|
8
18
|
// Iterate through each item in the directory
|
|
9
19
|
for (const file of list) {
|
|
10
20
|
const filePath = path.join(dir, file);
|
|
@@ -16,12 +26,12 @@ export default async function locateSegments(dir, rootDir = dir) {
|
|
|
16
26
|
const routeFilePath = path.join(filePath, 'route.ts');
|
|
17
27
|
if (await getFileSystemEntryType(routeFilePath)) {
|
|
18
28
|
// Calculate the basePath relative to the root directory
|
|
19
|
-
const segmentName = path.relative(rootDir, dir);
|
|
29
|
+
const segmentName = path.relative(rootDir, dir).replace(/\\/g, '/'); // windows fix
|
|
20
30
|
results.push({ routeFilePath, segmentName });
|
|
21
31
|
}
|
|
22
32
|
}
|
|
23
33
|
// Recursively search inside subdirectories
|
|
24
|
-
const subDirResults = await locateSegments(filePath, rootDir);
|
|
34
|
+
const subDirResults = await locateSegments({ dir: filePath, rootDir, config, log });
|
|
25
35
|
results = results.concat(subDirResults);
|
|
26
36
|
}
|
|
27
37
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export default function addClassToSegmentCode(segmentSourceCode: string, { sourceName, compiledName,
|
|
1
|
+
export default function addClassToSegmentCode(segmentSourceCode: string, { sourceName, compiledName, importPath, }: {
|
|
2
2
|
sourceName: string;
|
|
3
3
|
compiledName: string;
|
|
4
|
-
type: 'worker' | 'controller';
|
|
5
4
|
importPath: string;
|
|
6
5
|
}): string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Project, QuoteKind, SyntaxKind } from 'ts-morph';
|
|
2
|
-
export default function addClassToSegmentCode(segmentSourceCode, { sourceName, compiledName,
|
|
2
|
+
export default function addClassToSegmentCode(segmentSourceCode, { sourceName, compiledName, importPath, }) {
|
|
3
3
|
const project = new Project({
|
|
4
4
|
manipulationSettings: {
|
|
5
5
|
quoteKind: QuoteKind.Single,
|
|
@@ -16,8 +16,8 @@ export default function addClassToSegmentCode(segmentSourceCode, { sourceName, c
|
|
|
16
16
|
moduleSpecifier: importPath,
|
|
17
17
|
});
|
|
18
18
|
}
|
|
19
|
-
// Get the variable declaration for controllers
|
|
20
|
-
const variableDeclaration = sourceFile.getVariableDeclaration(
|
|
19
|
+
// Get the variable declaration for controllers
|
|
20
|
+
const variableDeclaration = sourceFile.getVariableDeclaration('controllers');
|
|
21
21
|
if (variableDeclaration) {
|
|
22
22
|
const initializer = variableDeclaration.getInitializer();
|
|
23
23
|
if (initializer && initializer.getKind() === SyntaxKind.ObjectLiteralExpression) {
|
package/dist/new/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { NewOptions } from '../types.mjs';
|
|
2
|
-
export
|
|
2
|
+
export declare function newComponents(components: string[], { dryRun, dir, templates, overwrite, noSegmentUpdate, empty, static: isStaticSegment }: NewOptions): Promise<void>;
|
package/dist/new/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import newModule from './newModule.mjs';
|
|
2
2
|
import newSegment from './newSegment.mjs';
|
|
3
|
-
export
|
|
3
|
+
export async function newComponents(components, { dryRun, dir, templates, overwrite, noSegmentUpdate, empty, static: isStaticSegment }) {
|
|
4
4
|
if (components[0] === 'segment' || components[0] === 'segments') {
|
|
5
5
|
// vovk new segment [segmentName]
|
|
6
6
|
let segmentNames = components
|
|
@@ -10,7 +10,7 @@ export default async function newComponents(components, { dryRun, dir, templates
|
|
|
10
10
|
segmentNames = [''];
|
|
11
11
|
}
|
|
12
12
|
for (const segmentName of segmentNames) {
|
|
13
|
-
await newSegment({ segmentName, overwrite, dryRun });
|
|
13
|
+
await newSegment({ segmentName, isStaticSegment, overwrite, dryRun });
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
else {
|
|
@@ -31,6 +31,7 @@ export default async function newComponents(components, { dryRun, dir, templates
|
|
|
31
31
|
overwrite,
|
|
32
32
|
noSegmentUpdate,
|
|
33
33
|
dryRun,
|
|
34
|
+
empty,
|
|
34
35
|
});
|
|
35
36
|
}
|
|
36
37
|
}
|
package/dist/new/newModule.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export default function newModule({ what, moduleNameWithOptionalSegment, dryRun, dir: dirFlag, templates: templatesFlag, noSegmentUpdate, overwrite, }: {
|
|
1
|
+
export default function newModule({ what, moduleNameWithOptionalSegment, dryRun, dir: dirFlag, templates: templatesFlag, noSegmentUpdate, overwrite, empty, }: {
|
|
2
2
|
what: string[];
|
|
3
3
|
moduleNameWithOptionalSegment: string;
|
|
4
4
|
dryRun?: boolean;
|
|
@@ -6,4 +6,5 @@ export default function newModule({ what, moduleNameWithOptionalSegment, dryRun,
|
|
|
6
6
|
templates?: string[];
|
|
7
7
|
noSegmentUpdate?: boolean;
|
|
8
8
|
overwrite?: boolean;
|
|
9
|
+
empty?: boolean;
|
|
9
10
|
}): Promise<void>;
|