vovk-cli 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -177,6 +177,7 @@ program
177
177
  .option('--use-pnpm', 'use pnpm as package manager')
178
178
  .option('--use-bun', 'use bun as package manager')
179
179
  .option('--skip-install', 'skip installing dependencies')
180
+ .option('--update-ts-config', 'update tsconfig.json')
180
181
  .option('--update-scripts <mode>', 'update package.json scripts ("implicit" or "explicit")')
181
182
  .option('--bundle', 'set up "tsdown" bundler')
182
183
  .option('--lang <languages...>', 'generate client for other programming languages by default ("py" for Python and "rs" for Rust are supported)')
@@ -4,5 +4,5 @@ export declare class Init {
4
4
  #private;
5
5
  root: string;
6
6
  log: ReturnType<typeof getLogger>;
7
- main({ prefix, yes, logLevel, useNpm, useYarn, usePnpm, useBun, skipInstall, updateScripts, validationLibrary, bundle, lang, dryRun, channel, }: InitOptions): Promise<void>;
7
+ main({ prefix, yes, logLevel, useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary, bundle, lang, dryRun, channel, }: InitOptions): Promise<void>;
8
8
  }
@@ -9,15 +9,17 @@ import { installDependencies, getPackageManager } from './installDependencies.mj
9
9
  import { getLogger } from '../utils/getLogger.mjs';
10
10
  import { createConfig } from './createConfig.mjs';
11
11
  import { updateNPMScripts, getDevScript } from './updateNPMScripts.mjs';
12
+ import { checkTSConfigForExperimentalDecorators } from './checkTSConfigForExperimentalDecorators.mjs';
13
+ import { updateTypeScriptConfig } from './updateTypeScriptConfig.mjs';
12
14
  import { updateDependenciesWithoutInstalling } from './updateDependenciesWithoutInstalling.mjs';
13
15
  import { logUpdateDependenciesError } from './logUpdateDependenciesError.mjs';
14
16
  import { chalkHighlightThing } from '../utils/chalkHighlightThing.mjs';
15
17
  export class Init {
16
18
  root;
17
19
  log;
18
- async #init({ configPaths, pkgJson, }, { useNpm, useYarn, usePnpm, useBun, skipInstall, updateScripts, validationLibrary, bundle, lang, dryRun, channel, }) {
20
+ async #init({ configPaths, pkgJson, }, { useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary, bundle, lang, dryRun, channel, }) {
19
21
  const { log, root } = this;
20
- const dependencies = ['vovk', 'vovk-client', 'vovk-ajv', 'openapi3-ts'];
22
+ const dependencies = ['vovk', 'vovk-client', 'vovk-ajv'];
21
23
  const devDependencies = ['vovk-cli'];
22
24
  if (lang?.includes('py')) {
23
25
  devDependencies.push('vovk-python');
@@ -54,6 +56,21 @@ export class Init {
54
56
  devDependencies.push('concurrently');
55
57
  }
56
58
  }
59
+ if (updateTsConfig) {
60
+ try {
61
+ const compilerOptions = {
62
+ experimentalDecorators: true,
63
+ };
64
+ if (!dryRun)
65
+ await updateTypeScriptConfig(root, compilerOptions);
66
+ log.info(`Added ${Object.keys(compilerOptions)
67
+ .map((k) => `"${k}"`)
68
+ .join(' and ')} to tsconfig.json`);
69
+ }
70
+ catch (error) {
71
+ log.error(`Failed to update tsconfig.json: ${error.message}`);
72
+ }
73
+ }
57
74
  if (!dryRun && pkgJson) {
58
75
  let depsUpdated = false;
59
76
  const packageManager = getPackageManager({ useNpm, useYarn, usePnpm, useBun, pkgJson });
@@ -110,7 +127,7 @@ export class Init {
110
127
  log.error(`Failed to create config: ${error.message}. Please, refer to the documentation at https://vovk.dev/config`);
111
128
  }
112
129
  }
113
- async main({ prefix, yes, logLevel, useNpm, useYarn, usePnpm, useBun, skipInstall, updateScripts, validationLibrary, bundle, lang, dryRun, channel, }) {
130
+ async main({ prefix, yes, logLevel, useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary, bundle, lang, dryRun, channel, }) {
114
131
  const cwd = process.cwd();
115
132
  const root = path.resolve(cwd, prefix ?? '.');
116
133
  const log = getLogger(logLevel ?? 'info');
@@ -126,9 +143,10 @@ export class Init {
126
143
  usePnpm: usePnpm ?? false,
127
144
  useBun: useBun ?? false,
128
145
  skipInstall: skipInstall ?? false,
146
+ updateTsConfig: updateTsConfig ?? true,
129
147
  updateScripts: updateScripts ?? 'implicit',
130
148
  validationLibrary: validationLibrary?.toLocaleLowerCase() === 'none' ? null : (validationLibrary ?? 'zod'),
131
- bundle: bundle ?? true,
149
+ bundle: bundle ?? false,
132
150
  dryRun: dryRun ?? false,
133
151
  channel: channel ?? 'latest',
134
152
  lang: lang ?? [],
@@ -173,9 +191,24 @@ export class Init {
173
191
  { name: 'None', value: null, description: 'Install validation library later' },
174
192
  ],
175
193
  })));
194
+ if (typeof updateTsConfig === 'undefined' && pkgJson) {
195
+ let shouldAsk = false;
196
+ try {
197
+ shouldAsk = !(await checkTSConfigForExperimentalDecorators(root));
198
+ }
199
+ catch (error) {
200
+ log.error(`Failed to check tsconfig.json for "experimentalDecorators": ${error.message}`);
201
+ }
202
+ if (shouldAsk) {
203
+ const keys = ['experimentalDecorators'];
204
+ updateTsConfig = await confirm({
205
+ message: `Do you want to add ${keys.map((k) => `"${k}"`).join(' and ')} to tsconfig.json? (recommended)`,
206
+ });
207
+ }
208
+ }
176
209
  bundle ??= await confirm({
177
210
  message: 'Do you want to set up "tsdown" to bundle TypeScript client (experimental)?',
178
- default: true,
211
+ default: false,
179
212
  });
180
213
  updateScripts ??= !pkgJson
181
214
  ? undefined
@@ -213,6 +246,7 @@ export class Init {
213
246
  usePnpm: usePnpm ?? false,
214
247
  useBun: useBun ?? false,
215
248
  skipInstall: skipInstall ?? false,
249
+ updateTsConfig,
216
250
  updateScripts,
217
251
  validationLibrary,
218
252
  bundle,
@@ -2,12 +2,23 @@ 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, log, }) {
5
+ /** Root of the monorepo packages directory (…/packages) resolved from the compiled CLI location (dist/init/). */
6
+ const packagesRoot = path.resolve(import.meta.dirname, '../../..');
7
+ /** Vovk package names that have a matching local directory under packages/. */
8
+ const localPackageDirs = {
9
+ vovk: 'vovk',
10
+ 'vovk-cli': 'vovk-cli',
11
+ 'vovk-client': 'vovk-client',
12
+ 'vovk-ajv': 'vovk-ajv',
13
+ 'vovk-python': 'vovk-python',
14
+ 'vovk-rust': 'vovk-rust',
15
+ };
16
+ async function updateDeps({ packageJson, packageNames, channel, key, log, dir, }) {
17
+ const useLocal = process.env.NODE_ENV === 'test';
6
18
  return Promise.all(packageNames.map(async (packageName) => {
7
19
  let name;
8
20
  let version;
9
21
  if (packageName.startsWith('@')) {
10
- // Handle scoped packages (@org/name@version)
11
22
  const lastAtIndex = packageName.lastIndexOf('@');
12
23
  if (lastAtIndex > 0) {
13
24
  name = packageName.substring(0, lastAtIndex);
@@ -19,11 +30,17 @@ async function updateDeps({ packageJson, packageNames, channel, key, log, }) {
19
30
  }
20
31
  }
21
32
  else {
22
- // Handle regular packages (name@version)
23
33
  const parts = packageName.split('@');
24
34
  name = parts[0];
25
35
  version = parts[1];
26
36
  }
37
+ // In test mode, use file: paths for local vovk packages
38
+ if (useLocal && name in localPackageDirs) {
39
+ const rel = path.relative(dir, path.join(packagesRoot, localPackageDirs[name]));
40
+ packageJson[key] ??= {};
41
+ packageJson[key][name] = `file:${rel}`;
42
+ return;
43
+ }
27
44
  if (version) {
28
45
  packageJson[key] ??= {};
29
46
  packageJson[key][name] = version;
@@ -46,8 +63,8 @@ async function updateDeps({ packageJson, packageNames, channel, key, log, }) {
46
63
  export async function updateDependenciesWithoutInstalling({ log, dir, dependencyNames, devDependencyNames, channel, }) {
47
64
  const packageJsonPath = path.join(dir, 'package.json');
48
65
  const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));
49
- await updateDeps({ packageJson, packageNames: dependencyNames, channel, log, key: 'dependencies' });
50
- await updateDeps({ packageJson, packageNames: devDependencyNames, channel, log, key: 'devDependencies' });
66
+ await updateDeps({ packageJson, packageNames: dependencyNames, channel, log, key: 'dependencies', dir });
67
+ await updateDeps({ packageJson, packageNames: devDependencyNames, channel, log, key: 'devDependencies', dir });
51
68
  await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2));
52
69
  log.info('Added dependencies to package.json:');
53
70
  for (const dependency of dependencyNames) {
package/dist/types.d.mts CHANGED
@@ -61,6 +61,7 @@ export interface InitOptions {
61
61
  usePnpm?: boolean;
62
62
  useBun?: boolean;
63
63
  skipInstall?: boolean;
64
+ updateTsConfig?: boolean;
64
65
  updateScripts?: 'implicit' | 'explicit';
65
66
  bundle?: boolean;
66
67
  validationLibrary?: 'zod' | 'valibot' | 'arktype' | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vovk-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "CLI tool for managing Vovk.ts projects",
5
5
  "files": [
6
6
  "dist",
@@ -18,8 +18,8 @@
18
18
  "build": "rm -rf dist tsconfig.build.tsbuildinfo && tsc -P tsconfig.build.json",
19
19
  "postbuild": "chmod +x ./dist/index.mjs",
20
20
  "pre-test": "npm run build && npm run clear-test-cache",
21
- "test-only": "npm run pre-test && node --experimental-transform-types --experimental-strip-types --experimental-vm-modules --test --test-only test/spec/**/*.mts",
22
- "test": "npm run pre-test && node --experimental-transform-types --experimental-strip-types --experimental-vm-modules --test --test-concurrency=1 test/spec/**/*.mts",
21
+ "test-only": "npm run pre-test && NODE_ENV=test node --experimental-transform-types --experimental-strip-types --experimental-vm-modules --test --test-only test/spec/**/*.mts",
22
+ "test": "npm run pre-test && NODE_ENV=test node --experimental-transform-types --experimental-strip-types --experimental-vm-modules --test --test-concurrency=1 test/spec/**/*.mts",
23
23
  "tsc": "tsc --noEmit",
24
24
  "ncu": "npm-check-updates -u -x commander,node-pty",
25
25
  "npm-publish": "npm publish",
@@ -42,11 +42,7 @@
42
42
  },
43
43
  "homepage": "https://vovk.dev",
44
44
  "peerDependencies": {
45
- "vovk": ">=3.0.0-beta.1",
46
- "vovk-ajv": ">=0.0.0-beta.1",
47
- "vovk-client": ">=0.0.4-beta.25",
48
- "vovk-python": ">=0.0.1-beta.14",
49
- "vovk-rust": ">=0.0.1-beta.16"
45
+ "vovk": ">=3.0.0"
50
46
  },
51
47
  "optionalDependencies": {
52
48
  "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.7"
@@ -71,7 +67,6 @@
71
67
  "jsonc-parser": "^3.3.1",
72
68
  "lodash": "^4.17.23",
73
69
  "loglevel": "^1.9.2",
74
- "openapi3-ts": "^4.5.0",
75
70
  "pluralize": "^8.0.0",
76
71
  "prettier": "^3.8.1",
77
72
  "tar-stream": "^3.1.8",
@@ -91,6 +86,7 @@
91
86
  "create-next-app": "^16.1.6",
92
87
  "http-server": "^14.1.1",
93
88
  "node-pty": "0.10.1",
89
+ "openapi3-ts": "^4.5.0",
94
90
  "tsdown": "^0.19.0",
95
91
  "zod": "^4.3.6"
96
92
  }