vovk-cli 0.0.1-draft.7 → 0.0.1-draft.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -1
- package/client-templates/main/main.cjs.ejs +15 -0
- package/client-templates/main/main.d.cts.ejs +14 -0
- package/client-templates/module/module.d.mts.ejs +14 -0
- package/client-templates/module/module.mjs.ejs +24 -0
- package/client-templates/python/__init__.py +276 -0
- package/client-templates/ts/index.ts.ejs +25 -0
- package/dist/dev/diffSchema.d.mts +36 -0
- package/dist/{watcher → dev}/diffSchema.mjs +3 -11
- package/dist/{watcher → dev}/ensureSchemaFiles.d.mts +3 -0
- package/dist/{watcher → dev}/ensureSchemaFiles.mjs +26 -15
- package/dist/dev/index.d.mts +6 -0
- package/dist/{watcher → dev}/index.mjs +129 -62
- package/dist/{watcher → dev}/isMetadataEmpty.mjs +1 -1
- package/dist/{watcher → dev}/logDiffResult.d.mts +2 -2
- package/dist/dev/logDiffResult.mjs +57 -0
- package/dist/{watcher → dev}/writeOneSchemaFile.d.mts +1 -1
- package/dist/{watcher → dev}/writeOneSchemaFile.mjs +2 -2
- package/dist/generate/ensureClient.d.mts +5 -0
- package/dist/generate/ensureClient.mjs +27 -0
- package/dist/generate/getClientTemplates.d.mts +14 -0
- package/dist/generate/getClientTemplates.mjs +28 -0
- package/dist/generate/index.d.mts +13 -0
- package/dist/generate/index.mjs +80 -0
- package/dist/getProjectInfo/getConfig.d.mts +3 -3
- package/dist/getProjectInfo/getConfig.mjs +8 -5
- package/dist/getProjectInfo/getConfigAbsolutePaths.mjs +2 -2
- package/dist/getProjectInfo/getRelativeSrcRoot.mjs +1 -1
- package/dist/getProjectInfo/getUserConfig.mjs +3 -1
- package/dist/getProjectInfo/importUncachedModule.mjs +0 -1
- package/dist/getProjectInfo/importUncachedModuleWorker.mjs +0 -1
- package/dist/getProjectInfo/index.d.mts +14 -5
- package/dist/getProjectInfo/index.mjs +21 -13
- package/dist/index.d.mts +1 -27
- package/dist/index.mjs +59 -65
- package/dist/init/checkTSConfigForExperimentalDecorators.mjs +2 -2
- package/dist/init/createConfig.d.mts +3 -4
- package/dist/init/createConfig.mjs +9 -8
- package/dist/init/getTemplateFilesFromPackage.d.mts +2 -1
- package/dist/init/getTemplateFilesFromPackage.mjs +4 -5
- package/dist/init/index.d.mts +2 -3
- package/dist/init/index.mjs +61 -97
- package/dist/init/installDependencies.d.mts +4 -1
- package/dist/init/installDependencies.mjs +2 -2
- package/dist/init/logUpdateDependenciesError.d.mts +11 -0
- package/dist/init/logUpdateDependenciesError.mjs +45 -0
- package/dist/init/updateDependenciesWithoutInstalling.d.mts +3 -2
- package/dist/init/updateDependenciesWithoutInstalling.mjs +13 -8
- package/dist/init/updateNPMScripts.d.mts +3 -1
- package/dist/init/updateNPMScripts.mjs +10 -6
- package/dist/init/updateTypeScriptConfig.mjs +2 -2
- package/dist/initProgram.d.mts +2 -0
- package/dist/initProgram.mjs +22 -0
- package/dist/locateSegments.d.mts +7 -1
- package/dist/locateSegments.mjs +9 -6
- package/dist/new/addClassToSegmentCode.d.mts +1 -2
- package/dist/new/addClassToSegmentCode.mjs +9 -5
- package/dist/new/addCommonTerms.mjs +1 -0
- package/dist/new/index.d.mts +2 -2
- package/dist/new/index.mjs +3 -3
- package/dist/new/newModule.d.mts +3 -3
- package/dist/new/newModule.mjs +38 -27
- package/dist/new/newSegment.mjs +8 -6
- package/dist/new/render.mjs +2 -5
- package/dist/postinstall.mjs +16 -19
- package/dist/types.d.mts +48 -9
- package/dist/utils/debounceWithArgs.d.mts +1 -1
- package/dist/utils/debounceWithArgs.mjs +24 -9
- package/dist/utils/formatLoggedSegmentName.mjs +1 -1
- package/dist/utils/getAvailablePort.mjs +3 -2
- package/dist/utils/getFileSystemEntryType.mjs +1 -1
- package/package.json +21 -18
- package/templates/controller.ejs +12 -11
- package/templates/service.ejs +6 -6
- package/dist/generateClient.d.mts +0 -7
- package/dist/generateClient.mjs +0 -97
- package/dist/watcher/diffSchema.d.mts +0 -43
- package/dist/watcher/index.d.mts +0 -6
- package/dist/watcher/logDiffResult.mjs +0 -90
- package/templates/worker.ejs +0 -1
- /package/dist/{watcher → dev}/isMetadataEmpty.d.mts +0 -0
package/dist/init/index.mjs
CHANGED
|
@@ -1,81 +1,26 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/*
|
|
3
|
-
npx vovk-cli init
|
|
4
|
-
- Check if the project is already initialized
|
|
5
|
-
- Do you want to reinitialize the project?
|
|
6
|
-
- Yes
|
|
7
|
-
- No (exit)
|
|
8
|
-
- Check for package.json, if not found, show error and exit
|
|
9
|
-
- Check for tsconfig.json, if not found, show error and exit
|
|
10
|
-
- Check Next.js installed
|
|
11
|
-
- Choose validation library: add to the installation list
|
|
12
|
-
- vovk-zod
|
|
13
|
-
- Further installation notes: install zod
|
|
14
|
-
- vovk-yup
|
|
15
|
-
- Further installation notes: install yup
|
|
16
|
-
- vovk-dto
|
|
17
|
-
- Further installation notes: install class-validator and class-transformer
|
|
18
|
-
- None
|
|
19
|
-
- If validation library is not None,
|
|
20
|
-
- Do you want to enable client validation?
|
|
21
|
-
- Yes
|
|
22
|
-
- Add client validation to the config
|
|
23
|
-
- No
|
|
24
|
-
- Do you want to update NPM scripts?
|
|
25
|
-
- Yes
|
|
26
|
-
- Update NPM scripts
|
|
27
|
-
- No
|
|
28
|
-
- Do you want to use explicit concurrently?
|
|
29
|
-
- Yes (recommended)
|
|
30
|
-
- Add concurrently to the installation list
|
|
31
|
-
- No
|
|
32
|
-
- if experimentalDecorators is not found in tsconfig.json,
|
|
33
|
-
- Do you want to add experimentalDecorators to tsconfig.json?
|
|
34
|
-
- Yes
|
|
35
|
-
- Add experimentalDecorators to tsconfig.json
|
|
36
|
-
- No
|
|
37
|
-
- Do you want to create route file with example service and controller? (NO NEED)
|
|
38
|
-
- Yes
|
|
39
|
-
- Create route file with example controller
|
|
40
|
-
- No, I will create it myself
|
|
41
|
-
- End
|
|
42
|
-
- If there are any packages to install, install them
|
|
43
|
-
- Show installation notes
|
|
44
|
-
- If there are any files to create, create
|
|
45
|
-
- If there are any config files to update, update
|
|
46
|
-
- If example route file is NOT created, show example route file and controller
|
|
47
|
-
- Show how to run the project
|
|
48
|
-
- If npm scripts are updated
|
|
49
|
-
- npm run dev
|
|
50
|
-
- If npm scripts are NOT updated
|
|
51
|
-
- If concurrently is installed
|
|
52
|
-
- concurrently "vovk dev" "next dev"
|
|
53
|
-
- If concurrently is NOT installed
|
|
54
|
-
- vovk dev --next-dev
|
|
55
|
-
- Open http://localhost:3000/api/hello-world
|
|
56
|
-
- Show how to make a request to the example route
|
|
57
|
-
- Show success message
|
|
58
|
-
*/
|
|
59
1
|
import { confirm, select } from '@inquirer/prompts';
|
|
60
|
-
import path from 'path';
|
|
61
|
-
import fs from 'fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import fs from 'node:fs/promises';
|
|
62
4
|
import getConfigPaths from '../getProjectInfo/getConfigAbsolutePaths.mjs';
|
|
63
5
|
import chalk from 'chalk';
|
|
64
6
|
import getFileSystemEntryType from '../utils/getFileSystemEntryType.mjs';
|
|
65
|
-
import installDependencies from './installDependencies.mjs';
|
|
7
|
+
import installDependencies, { getPackageManager } from './installDependencies.mjs';
|
|
66
8
|
import getLogger from '../utils/getLogger.mjs';
|
|
67
9
|
import createConfig from './createConfig.mjs';
|
|
68
|
-
import updateNPMScripts from './updateNPMScripts.mjs';
|
|
10
|
+
import updateNPMScripts, { getDevScript } from './updateNPMScripts.mjs';
|
|
69
11
|
import checkTSConfigForExperimentalDecorators from './checkTSConfigForExperimentalDecorators.mjs';
|
|
70
12
|
import updateTypeScriptConfig from './updateTypeScriptConfig.mjs';
|
|
71
13
|
import updateDependenciesWithoutInstalling from './updateDependenciesWithoutInstalling.mjs';
|
|
14
|
+
import logUpdateDependenciesError from './logUpdateDependenciesError.mjs';
|
|
15
|
+
import chalkHighlightThing from '../utils/chalkHighlightThing.mjs';
|
|
16
|
+
import NPMCliPackageJson from '@npmcli/package-json';
|
|
72
17
|
export class Init {
|
|
73
18
|
root;
|
|
74
19
|
log;
|
|
75
|
-
async #init({ configPaths, }, { useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary, validateOnClient, dryRun, channel, }) {
|
|
20
|
+
async #init({ configPaths, pkgJson, }, { useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary, validateOnClient, reactQuery, dryRun, channel, }) {
|
|
76
21
|
const { log, root } = this;
|
|
77
|
-
const dependencies = ['vovk'];
|
|
78
|
-
const devDependencies = ['vovk-cli'];
|
|
22
|
+
const dependencies = ['vovk', 'vovk-client'];
|
|
23
|
+
const devDependencies = ['vovk-cli', 'openapi3-ts'];
|
|
79
24
|
// delete older config files
|
|
80
25
|
if (configPaths.length) {
|
|
81
26
|
await Promise.all(configPaths.map((configPath) => fs.rm(configPath)));
|
|
@@ -86,13 +31,17 @@ export class Init {
|
|
|
86
31
|
dependencies.push(...({
|
|
87
32
|
'vovk-zod': ['zod'],
|
|
88
33
|
'vovk-yup': ['yup'],
|
|
89
|
-
'vovk-dto': ['class-validator', 'class-transformer'],
|
|
34
|
+
'vovk-dto': ['class-validator', 'class-transformer', 'vovk-mapped-types', 'reflect-metadata'],
|
|
90
35
|
}[validationLibrary] ?? []));
|
|
91
36
|
}
|
|
37
|
+
if (reactQuery) {
|
|
38
|
+
dependencies.push('vovk-react-query');
|
|
39
|
+
dependencies.push('@tanstack/react-query');
|
|
40
|
+
}
|
|
92
41
|
if (updateScripts) {
|
|
93
42
|
try {
|
|
94
43
|
if (!dryRun)
|
|
95
|
-
await updateNPMScripts(root, updateScripts);
|
|
44
|
+
await updateNPMScripts(pkgJson, root, updateScripts);
|
|
96
45
|
log.info('Updated scripts at package.json');
|
|
97
46
|
}
|
|
98
47
|
catch (error) {
|
|
@@ -113,6 +62,7 @@ export class Init {
|
|
|
113
62
|
}
|
|
114
63
|
}
|
|
115
64
|
if (!dryRun) {
|
|
65
|
+
let depsUpdated = false;
|
|
116
66
|
try {
|
|
117
67
|
await updateDependenciesWithoutInstalling({
|
|
118
68
|
log,
|
|
@@ -121,27 +71,34 @@ export class Init {
|
|
|
121
71
|
devDependencyNames: devDependencies,
|
|
122
72
|
channel: channel ?? 'latest',
|
|
123
73
|
});
|
|
124
|
-
|
|
74
|
+
depsUpdated = true;
|
|
125
75
|
}
|
|
126
|
-
catch (
|
|
127
|
-
|
|
76
|
+
catch (e) {
|
|
77
|
+
const error = e;
|
|
78
|
+
logUpdateDependenciesError({ log, error, useNpm, useYarn, usePnpm, useBun, dependencies, devDependencies });
|
|
128
79
|
}
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
cwd: root,
|
|
134
|
-
options: {
|
|
135
|
-
useNpm,
|
|
136
|
-
useYarn,
|
|
137
|
-
usePnpm,
|
|
138
|
-
useBun,
|
|
139
|
-
},
|
|
140
|
-
});
|
|
141
|
-
log.info('Dependencies installed successfully');
|
|
80
|
+
if (depsUpdated) {
|
|
81
|
+
const packageManager = getPackageManager({ useNpm, useYarn, usePnpm, useBun });
|
|
82
|
+
if (skipInstall) {
|
|
83
|
+
log.info(`Installation skipped. Please, install them manually with ${chalkHighlightThing(packageManager + ' install')}`);
|
|
142
84
|
}
|
|
143
|
-
|
|
144
|
-
|
|
85
|
+
else {
|
|
86
|
+
try {
|
|
87
|
+
await installDependencies({
|
|
88
|
+
log,
|
|
89
|
+
cwd: root,
|
|
90
|
+
options: {
|
|
91
|
+
useNpm,
|
|
92
|
+
useYarn,
|
|
93
|
+
usePnpm,
|
|
94
|
+
useBun,
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
log.info('Dependencies installed successfully');
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
log.warn(`Failed to install dependencies: ${error.message}. Please, install them manually with ${chalkHighlightThing(packageManager + ' install')}`);
|
|
101
|
+
}
|
|
145
102
|
}
|
|
146
103
|
}
|
|
147
104
|
}
|
|
@@ -149,8 +106,7 @@ export class Init {
|
|
|
149
106
|
const { configAbsolutePath } = await createConfig({
|
|
150
107
|
root,
|
|
151
108
|
log,
|
|
152
|
-
options: { validationLibrary, validateOnClient },
|
|
153
|
-
dryRun,
|
|
109
|
+
options: { validationLibrary, validateOnClient, reactQuery, channel, dryRun },
|
|
154
110
|
});
|
|
155
111
|
log.info('Config created successfully at ' + configAbsolutePath);
|
|
156
112
|
}
|
|
@@ -158,15 +114,16 @@ export class Init {
|
|
|
158
114
|
log.error(`Failed to create config: ${error.message}`);
|
|
159
115
|
}
|
|
160
116
|
}
|
|
161
|
-
async main(prefix, { yes, logLevel, useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary, validateOnClient, dryRun, channel, }) {
|
|
117
|
+
async main(prefix, { yes, logLevel, useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary, validateOnClient, reactQuery, dryRun, channel, }) {
|
|
162
118
|
const cwd = process.cwd();
|
|
163
119
|
const root = path.resolve(cwd, prefix);
|
|
164
120
|
const log = getLogger(logLevel);
|
|
121
|
+
const pkgJson = await NPMCliPackageJson.load(root);
|
|
165
122
|
this.root = root;
|
|
166
123
|
this.log = log;
|
|
167
124
|
const configPaths = await getConfigPaths({ cwd, relativePath: prefix });
|
|
168
125
|
if (yes) {
|
|
169
|
-
return this.#init({ configPaths }, {
|
|
126
|
+
return this.#init({ configPaths, pkgJson }, {
|
|
170
127
|
useNpm: useNpm ?? (!useYarn && !usePnpm && !useBun),
|
|
171
128
|
useYarn: useYarn ?? false,
|
|
172
129
|
usePnpm: usePnpm ?? false,
|
|
@@ -176,6 +133,7 @@ export class Init {
|
|
|
176
133
|
updateScripts: updateScripts ?? 'implicit',
|
|
177
134
|
validationLibrary: validationLibrary?.toLocaleLowerCase() === 'none' ? null : (validationLibrary ?? 'vovk-zod'),
|
|
178
135
|
validateOnClient: validateOnClient ?? true,
|
|
136
|
+
reactQuery: reactQuery ?? true,
|
|
179
137
|
dryRun: dryRun ?? false,
|
|
180
138
|
channel: channel ?? 'latest',
|
|
181
139
|
});
|
|
@@ -213,7 +171,7 @@ export class Init {
|
|
|
213
171
|
{
|
|
214
172
|
name: 'vovk-dto',
|
|
215
173
|
value: 'vovk-dto',
|
|
216
|
-
description: 'Use class-validator
|
|
174
|
+
description: 'Use class-validator for data validation. Also installs class-transformer, vovk-mapped-types and reflect-metadata',
|
|
217
175
|
},
|
|
218
176
|
{ name: 'None', value: null, description: 'Install validation library later' },
|
|
219
177
|
],
|
|
@@ -228,41 +186,46 @@ export class Init {
|
|
|
228
186
|
updateScripts =
|
|
229
187
|
updateScripts ??
|
|
230
188
|
(await select({
|
|
231
|
-
message: 'Do you want to update package.json by adding "generate" and "dev" scripts?',
|
|
189
|
+
message: 'Do you want to update package.json by adding "generate" and updating "dev" NPM scripts?',
|
|
232
190
|
default: 'implicit',
|
|
233
191
|
choices: [
|
|
234
192
|
{
|
|
235
193
|
name: 'Yes, use "concurrently" implicitly',
|
|
236
|
-
description: `The "dev" script will use "concurrently" API internally in order to run "next dev" and "vovk dev" together and automatically look for an available port ${chalk.whiteBright.bold(`"vovk dev --next-dev"`)}`,
|
|
237
194
|
value: 'implicit',
|
|
195
|
+
description: `The "dev" 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')}"`)}`,
|
|
238
196
|
},
|
|
239
197
|
{
|
|
240
198
|
name: 'Yes, use "concurrently" explicitly',
|
|
241
199
|
value: 'explicit',
|
|
242
|
-
description: `The "dev" script will use pre-defined PORT variable and run "next dev" and "vovk dev" as "concurrently" CLI arguments ${chalk.whiteBright.bold(`"
|
|
200
|
+
description: `The "dev" script will use pre-defined PORT variable and run "next dev" and "vovk dev" as "concurrently" CLI arguments ${chalk.whiteBright.bold(`"${getDevScript(pkgJson, 'explicit')}"`)}`,
|
|
243
201
|
},
|
|
244
202
|
{
|
|
245
203
|
name: 'No',
|
|
246
204
|
value: undefined,
|
|
247
|
-
description: 'Add the scripts manually',
|
|
205
|
+
description: 'Add the NPM scripts manually',
|
|
248
206
|
},
|
|
249
207
|
],
|
|
250
208
|
}));
|
|
209
|
+
reactQuery =
|
|
210
|
+
reactQuery ??
|
|
211
|
+
(await confirm({
|
|
212
|
+
message: 'Do you want to use @tanstack/react-query for data fetching at React components?',
|
|
213
|
+
}));
|
|
251
214
|
if (typeof updateTsConfig === 'undefined') {
|
|
252
215
|
let shouldAsk = false;
|
|
253
216
|
try {
|
|
254
217
|
shouldAsk = !(await checkTSConfigForExperimentalDecorators(root));
|
|
255
218
|
}
|
|
256
219
|
catch (error) {
|
|
257
|
-
log.error(`Failed to check tsconfig.json for experimentalDecorators: ${error.message}`);
|
|
220
|
+
log.error(`Failed to check tsconfig.json for "experimentalDecorators": ${error.message}`);
|
|
258
221
|
}
|
|
259
222
|
if (shouldAsk) {
|
|
260
223
|
updateTsConfig = await confirm({
|
|
261
|
-
message: 'Do you want to add experimentalDecorators to tsconfig.json?',
|
|
224
|
+
message: 'Do you want to add "experimentalDecorators" option to tsconfig.json?',
|
|
262
225
|
});
|
|
263
226
|
}
|
|
264
227
|
}
|
|
265
|
-
await this.#init({ configPaths }, {
|
|
228
|
+
await this.#init({ configPaths, pkgJson }, {
|
|
266
229
|
useNpm: useNpm ?? (!useYarn && !usePnpm && !useBun),
|
|
267
230
|
useYarn: useYarn ?? false,
|
|
268
231
|
usePnpm: usePnpm ?? false,
|
|
@@ -272,6 +235,7 @@ export class Init {
|
|
|
272
235
|
updateScripts,
|
|
273
236
|
validationLibrary,
|
|
274
237
|
validateOnClient,
|
|
238
|
+
reactQuery,
|
|
275
239
|
dryRun,
|
|
276
240
|
channel,
|
|
277
241
|
});
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { InitOptions } from '../index.mjs';
|
|
2
1
|
import getLogger from '../utils/getLogger.mjs';
|
|
2
|
+
import type { InitOptions } from '../types.mjs';
|
|
3
|
+
type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun';
|
|
4
|
+
export declare function getPackageManager(options: Pick<InitOptions, 'useNpm' | 'useYarn' | 'usePnpm' | 'useBun'>): PackageManager;
|
|
3
5
|
export default function installDependencies({ log, cwd, options, }: {
|
|
4
6
|
log: ReturnType<typeof getLogger>;
|
|
5
7
|
cwd: string;
|
|
6
8
|
options: Pick<InitOptions, 'useNpm' | 'useYarn' | 'usePnpm' | 'useBun'>;
|
|
7
9
|
}): Promise<void>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type getLogger from '../utils/getLogger.mjs';
|
|
2
|
+
export default function logUpdateDependenciesError({ useNpm, useYarn, usePnpm, useBun, log, dependencies, devDependencies, error, }: {
|
|
3
|
+
useNpm?: boolean;
|
|
4
|
+
useYarn?: boolean;
|
|
5
|
+
usePnpm?: boolean;
|
|
6
|
+
useBun?: boolean;
|
|
7
|
+
log: ReturnType<typeof getLogger>;
|
|
8
|
+
dependencies: string[];
|
|
9
|
+
devDependencies: string[];
|
|
10
|
+
error: Error;
|
|
11
|
+
}): void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import chalkHighlightThing from '../utils/chalkHighlightThing.mjs';
|
|
2
|
+
import { getPackageManager } from './installDependencies.mjs';
|
|
3
|
+
export default function logUpdateDependenciesError({ useNpm, useYarn, usePnpm, useBun, log, dependencies, devDependencies, error, }) {
|
|
4
|
+
const packageManager = getPackageManager({ useNpm, useYarn, usePnpm, useBun });
|
|
5
|
+
const installCommands = [];
|
|
6
|
+
if (dependencies.length > 0) {
|
|
7
|
+
let depInstallCmd = '';
|
|
8
|
+
switch (packageManager) {
|
|
9
|
+
case 'npm':
|
|
10
|
+
depInstallCmd = `npm install ${dependencies.join(' ')}`;
|
|
11
|
+
break;
|
|
12
|
+
case 'yarn':
|
|
13
|
+
depInstallCmd = `yarn add ${dependencies.join(' ')}`;
|
|
14
|
+
break;
|
|
15
|
+
case 'pnpm':
|
|
16
|
+
depInstallCmd = `pnpm add ${dependencies.join(' ')}`;
|
|
17
|
+
break;
|
|
18
|
+
case 'bun':
|
|
19
|
+
depInstallCmd = `bun add ${dependencies.join(' ')}`;
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
installCommands.push(depInstallCmd);
|
|
23
|
+
}
|
|
24
|
+
if (devDependencies.length > 0) {
|
|
25
|
+
let devDepInstallCmd = '';
|
|
26
|
+
switch (packageManager) {
|
|
27
|
+
case 'npm':
|
|
28
|
+
devDepInstallCmd = `npm install -D ${devDependencies.join(' ')}`;
|
|
29
|
+
break;
|
|
30
|
+
case 'yarn':
|
|
31
|
+
devDepInstallCmd = `yarn add --dev ${devDependencies.join(' ')}`;
|
|
32
|
+
break;
|
|
33
|
+
case 'pnpm':
|
|
34
|
+
devDepInstallCmd = `pnpm add -D ${devDependencies.join(' ')}`;
|
|
35
|
+
break;
|
|
36
|
+
case 'bun':
|
|
37
|
+
devDepInstallCmd = `bun add -d ${devDependencies.join(' ')}`;
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
installCommands.push(devDepInstallCmd);
|
|
41
|
+
}
|
|
42
|
+
const installCmd = installCommands.join(' && ');
|
|
43
|
+
// Log the error with the appropriate manual installation instructions
|
|
44
|
+
log.warn(`Failed to update dependencies: ${error.message}. Please, install them manually with ${chalkHighlightThing(installCmd)}`);
|
|
45
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import getLogger from '../utils/getLogger.mjs';
|
|
1
|
+
import type getLogger from '../utils/getLogger.mjs';
|
|
2
|
+
import { InitOptions } from '../types.mjs';
|
|
2
3
|
export default function updateDependenciesWithoutInstalling({ log, dir, dependencyNames, devDependencyNames, channel, }: {
|
|
3
4
|
log: ReturnType<typeof getLogger>;
|
|
4
5
|
dir: string;
|
|
5
6
|
dependencyNames: string[];
|
|
6
7
|
devDependencyNames: string[];
|
|
7
|
-
channel: '
|
|
8
|
+
channel: InitOptions['channel'];
|
|
8
9
|
}): Promise<void>;
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import chalk from 'chalk';
|
|
2
4
|
import getNPMPackageMetadata from '../utils/getNPMPackageMetadata.mjs';
|
|
3
|
-
import path from 'path';
|
|
4
5
|
async function updateDeps({ packageJson, packageNames, channel, key, }) {
|
|
5
6
|
return Promise.all(packageNames.map(async (packageName) => {
|
|
6
|
-
if (packageJson[key]?.[packageName])
|
|
7
|
-
return; // Skip if already present
|
|
8
7
|
const metadata = await getNPMPackageMetadata(packageName);
|
|
9
|
-
const isVovk = packageName.startsWith('vovk');
|
|
10
|
-
const latestVersion = metadata['dist-tags'][isVovk ? channel : 'latest'];
|
|
8
|
+
const isVovk = packageName.startsWith('vovk') && packageName !== 'vovk-mapped-types';
|
|
9
|
+
const latestVersion = metadata['dist-tags'][isVovk ? (channel ?? 'latest') : 'latest'];
|
|
11
10
|
if (!packageJson[key]) {
|
|
12
11
|
packageJson[key] = {};
|
|
13
12
|
}
|
|
@@ -18,8 +17,14 @@ export default async function updateDependenciesWithoutInstalling({ log, dir, de
|
|
|
18
17
|
const packageJsonPath = path.join(dir, 'package.json');
|
|
19
18
|
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));
|
|
20
19
|
await updateDeps({ packageJson, packageNames: dependencyNames, channel, key: 'dependencies' });
|
|
21
|
-
log.debug('Updated dependencies in package.json');
|
|
22
20
|
await updateDeps({ packageJson, packageNames: devDependencyNames, channel, key: 'devDependencies' });
|
|
23
|
-
log.debug('Updated devDependencies in package.json');
|
|
24
21
|
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
22
|
+
log.info('Added dependencies to package.json:');
|
|
23
|
+
for (const dependency of dependencyNames) {
|
|
24
|
+
log.raw.info(` - ${chalk.cyan(dependency)}`);
|
|
25
|
+
}
|
|
26
|
+
log.info('Added devDependencies to package.json:');
|
|
27
|
+
for (const dependency of devDependencyNames) {
|
|
28
|
+
log.raw.info(` - ${chalk.cyan(dependency)}`);
|
|
29
|
+
}
|
|
25
30
|
}
|
|
@@ -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,16 @@
|
|
|
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: {
|
|
11
|
+
...pkgJson.content.scripts,
|
|
6
12
|
generate: 'vovk generate',
|
|
7
|
-
dev: updateScriptsMode
|
|
8
|
-
? "PORT=3000 concurrently 'vovk dev' 'next dev' --kill-others"
|
|
9
|
-
: 'vovk dev --next-dev',
|
|
13
|
+
dev: getDevScript(pkgJson, updateScriptsMode),
|
|
10
14
|
},
|
|
11
15
|
});
|
|
12
16
|
await pkgJson.save();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import fs from 'fs/promises';
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
3
|
import * as jsonc from 'jsonc-parser';
|
|
4
4
|
import prettify from '../utils/prettify.mjs';
|
|
5
5
|
export default async function updateTypeScriptConfig(root) {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Init } from './init/index.mjs';
|
|
2
|
+
// reused at vovk-init
|
|
3
|
+
export default function initProgram(program) {
|
|
4
|
+
return program
|
|
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('--validation-library <library>', 'validation library to use ("vovk-zod", "vovk-yup", "vovk-dto" or another); set to "none" to skip')
|
|
17
|
+
.option('--validate-on-client', 'path to validateOnClient file')
|
|
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')
|
|
21
|
+
.action((prefix = '.', options) => new Init().main(prefix, options));
|
|
22
|
+
}
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
+
import type { VovkConfig } from './types.mjs';
|
|
1
2
|
export type Segment = {
|
|
2
3
|
routeFilePath: string;
|
|
3
4
|
segmentName: string;
|
|
5
|
+
segmentImportPath: string;
|
|
4
6
|
};
|
|
5
|
-
export default function locateSegments(dir
|
|
7
|
+
export default function locateSegments({ dir, rootDir, config, }: {
|
|
8
|
+
dir: string;
|
|
9
|
+
rootDir?: string;
|
|
10
|
+
config: Required<VovkConfig> | null;
|
|
11
|
+
}): Promise<Segment[]>;
|
package/dist/locateSegments.mjs
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
3
|
import getFileSystemEntryType from './utils/getFileSystemEntryType.mjs';
|
|
4
|
-
|
|
4
|
+
// config: null is used for testing
|
|
5
|
+
export default async function locateSegments({ dir, rootDir, config, }) {
|
|
5
6
|
let results = [];
|
|
7
|
+
rootDir = rootDir ?? dir;
|
|
6
8
|
// Read the contents of the directory
|
|
7
9
|
const list = await fs.readdir(dir);
|
|
8
10
|
// Iterate through each item in the directory
|
|
@@ -16,12 +18,13 @@ export default async function locateSegments(dir, rootDir = dir) {
|
|
|
16
18
|
const routeFilePath = path.join(filePath, 'route.ts');
|
|
17
19
|
if (await getFileSystemEntryType(routeFilePath)) {
|
|
18
20
|
// Calculate the basePath relative to the root directory
|
|
19
|
-
const segmentName = path.relative(rootDir, dir);
|
|
20
|
-
|
|
21
|
+
const segmentName = path.relative(rootDir, dir).replace(/\\/g, '/'); // windows fix
|
|
22
|
+
const segmentImportPath = path.relative(config?.clientOutDir ?? '.__', routeFilePath);
|
|
23
|
+
results.push({ routeFilePath, segmentName, segmentImportPath });
|
|
21
24
|
}
|
|
22
25
|
}
|
|
23
26
|
// Recursively search inside subdirectories
|
|
24
|
-
const subDirResults = await locateSegments(filePath, rootDir);
|
|
27
|
+
const subDirResults = await locateSegments({ dir: filePath, rootDir, config });
|
|
25
28
|
results = results.concat(subDirResults);
|
|
26
29
|
}
|
|
27
30
|
}
|
|
@@ -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,6 +1,10 @@
|
|
|
1
|
-
import { Project, SyntaxKind } from 'ts-morph';
|
|
2
|
-
export default function addClassToSegmentCode(segmentSourceCode, { sourceName, compiledName,
|
|
3
|
-
const project = new Project(
|
|
1
|
+
import { Project, QuoteKind, SyntaxKind } from 'ts-morph';
|
|
2
|
+
export default function addClassToSegmentCode(segmentSourceCode, { sourceName, compiledName, importPath, }) {
|
|
3
|
+
const project = new Project({
|
|
4
|
+
manipulationSettings: {
|
|
5
|
+
quoteKind: QuoteKind.Single,
|
|
6
|
+
},
|
|
7
|
+
});
|
|
4
8
|
const sourceFile = project.createSourceFile('route.ts', segmentSourceCode, { overwrite: true });
|
|
5
9
|
// Add the import if it doesn't exist
|
|
6
10
|
let importDeclaration = sourceFile.getImportDeclaration((imp) => {
|
|
@@ -12,8 +16,8 @@ export default function addClassToSegmentCode(segmentSourceCode, { sourceName, c
|
|
|
12
16
|
moduleSpecifier: importPath,
|
|
13
17
|
});
|
|
14
18
|
}
|
|
15
|
-
// Get the variable declaration for controllers
|
|
16
|
-
const variableDeclaration = sourceFile.getVariableDeclaration(
|
|
19
|
+
// Get the variable declaration for controllers
|
|
20
|
+
const variableDeclaration = sourceFile.getVariableDeclaration('controllers');
|
|
17
21
|
if (variableDeclaration) {
|
|
18
22
|
const initializer = variableDeclaration.getInitializer();
|
|
19
23
|
if (initializer && initializer.getKind() === SyntaxKind.ObjectLiteralExpression) {
|
package/dist/new/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { NewOptions } from '../
|
|
2
|
-
export default function newComponents(components: string[], { dryRun,
|
|
1
|
+
import type { NewOptions } from '../types.mjs';
|
|
2
|
+
export default function newComponents(components: string[], { dryRun, dir, templates, overwrite, noSegmentUpdate }: 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 default async function newComponents(components, { dryRun,
|
|
3
|
+
export default async function newComponents(components, { dryRun, dir, templates, overwrite, noSegmentUpdate }) {
|
|
4
4
|
if (components[0] === 'segment' || components[0] === 'segments') {
|
|
5
5
|
// vovk new segment [segmentName]
|
|
6
6
|
let segmentNames = components
|
|
@@ -26,8 +26,8 @@ export default async function newComponents(components, { dryRun, dirName, templ
|
|
|
26
26
|
await newModule({
|
|
27
27
|
what,
|
|
28
28
|
moduleNameWithOptionalSegment,
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
dir,
|
|
30
|
+
templates,
|
|
31
31
|
overwrite,
|
|
32
32
|
noSegmentUpdate,
|
|
33
33
|
dryRun,
|
package/dist/new/newModule.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export default function newModule({ what, moduleNameWithOptionalSegment, dryRun,
|
|
1
|
+
export default function newModule({ what, moduleNameWithOptionalSegment, dryRun, dir: dirFlag, templates: templatesFlag, noSegmentUpdate, overwrite, }: {
|
|
2
2
|
what: string[];
|
|
3
3
|
moduleNameWithOptionalSegment: string;
|
|
4
4
|
dryRun?: boolean;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
dir?: string;
|
|
6
|
+
templates?: string[];
|
|
7
7
|
noSegmentUpdate?: boolean;
|
|
8
8
|
overwrite?: boolean;
|
|
9
9
|
}): Promise<void>;
|