vovk-cli 0.0.1-draft.13 → 0.0.1-draft.130

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.
Files changed (88) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +29 -1
  3. package/client-templates/fullSchema/fullSchema.cjs.ejs +13 -0
  4. package/client-templates/fullSchema/fullSchema.d.cts.ejs +11 -0
  5. package/client-templates/main/main.cjs.ejs +15 -0
  6. package/client-templates/main/main.d.cts.ejs +15 -0
  7. package/client-templates/module/module.d.mts.ejs +15 -0
  8. package/client-templates/module/module.mjs.ejs +21 -0
  9. package/client-templates/ts/index.ts.ejs +24 -0
  10. package/dist/dev/diffSegmentSchema.d.mts +36 -0
  11. package/dist/{watcher/diffSchema.mjs → dev/diffSegmentSchema.mjs} +4 -12
  12. package/dist/{watcher → dev}/ensureSchemaFiles.d.mts +3 -0
  13. package/dist/{watcher → dev}/ensureSchemaFiles.mjs +12 -30
  14. package/dist/dev/index.d.mts +6 -0
  15. package/dist/{watcher → dev}/index.mjs +143 -72
  16. package/dist/dev/isSegmentSchemaEmpty.d.mts +2 -0
  17. package/dist/dev/isSegmentSchemaEmpty.mjs +4 -0
  18. package/dist/{watcher → dev}/logDiffResult.d.mts +1 -1
  19. package/dist/dev/logDiffResult.mjs +57 -0
  20. package/dist/dev/writeConfigJson.d.mts +2 -0
  21. package/dist/dev/writeConfigJson.mjs +15 -0
  22. package/dist/dev/writeOneSegmentSchemaFile.d.mts +12 -0
  23. package/dist/{watcher/writeOneSchemaFile.mjs → dev/writeOneSegmentSchemaFile.mjs} +10 -6
  24. package/dist/generate/ensureClient.d.mts +4 -0
  25. package/dist/generate/ensureClient.mjs +41 -0
  26. package/dist/generate/getClientTemplates.d.mts +24 -0
  27. package/dist/generate/getClientTemplates.mjs +86 -0
  28. package/dist/generate/getFullSchemaFromJSON.d.mts +3 -0
  29. package/dist/generate/getFullSchemaFromJSON.mjs +53 -0
  30. package/dist/generate/index.d.mts +13 -0
  31. package/dist/generate/index.mjs +115 -0
  32. package/dist/getProjectInfo/getConfig.d.mts +5 -4
  33. package/dist/getProjectInfo/getConfig.mjs +26 -7
  34. package/dist/getProjectInfo/getConfigAbsolutePaths.d.mts +2 -1
  35. package/dist/getProjectInfo/getConfigAbsolutePaths.mjs +4 -1
  36. package/dist/getProjectInfo/getUserConfig.d.mts +3 -2
  37. package/dist/getProjectInfo/getUserConfig.mjs +5 -3
  38. package/dist/getProjectInfo/importUncachedModule.mjs +0 -1
  39. package/dist/getProjectInfo/importUncachedModuleWorker.mjs +0 -1
  40. package/dist/getProjectInfo/index.d.mts +14 -6
  41. package/dist/getProjectInfo/index.mjs +22 -14
  42. package/dist/index.d.mts +0 -5
  43. package/dist/index.mjs +56 -63
  44. package/dist/init/createConfig.d.mts +2 -3
  45. package/dist/init/createConfig.mjs +11 -7
  46. package/dist/init/getTemplateFilesFromPackage.d.mts +2 -1
  47. package/dist/init/getTemplateFilesFromPackage.mjs +2 -3
  48. package/dist/init/index.d.mts +1 -1
  49. package/dist/init/index.mjs +29 -28
  50. package/dist/init/updateDependenciesWithoutInstalling.mjs +3 -5
  51. package/dist/init/updateNPMScripts.d.mts +3 -1
  52. package/dist/init/updateNPMScripts.mjs +10 -7
  53. package/dist/initProgram.d.mts +2 -0
  54. package/dist/initProgram.mjs +21 -0
  55. package/dist/locateSegments.d.mts +7 -1
  56. package/dist/locateSegments.mjs +7 -4
  57. package/dist/new/addClassToSegmentCode.d.mts +1 -2
  58. package/dist/new/addClassToSegmentCode.mjs +3 -3
  59. package/dist/new/addCommonTerms.mjs +1 -0
  60. package/dist/new/index.d.mts +1 -1
  61. package/dist/new/index.mjs +2 -1
  62. package/dist/new/newModule.d.mts +2 -1
  63. package/dist/new/newModule.mjs +14 -16
  64. package/dist/new/newSegment.mjs +6 -4
  65. package/dist/new/render.d.mts +6 -3
  66. package/dist/new/render.mjs +25 -13
  67. package/dist/types.d.mts +9 -42
  68. package/dist/utils/debounceWithArgs.d.mts +2 -2
  69. package/dist/utils/debounceWithArgs.mjs +24 -9
  70. package/dist/utils/getAvailablePort.mjs +1 -1
  71. package/dist/utils/resolveAbsoluteModulePath.d.mts +1 -0
  72. package/dist/utils/resolveAbsoluteModulePath.mjs +6 -0
  73. package/package.json +25 -21
  74. package/templates/controller.ejs +20 -21
  75. package/templates/service.ejs +12 -12
  76. package/dist/generateClient.d.mts +0 -7
  77. package/dist/generateClient.mjs +0 -97
  78. package/dist/postinstall.d.mts +0 -1
  79. package/dist/postinstall.mjs +0 -24
  80. package/dist/watcher/diffSchema.d.mts +0 -43
  81. package/dist/watcher/ensureClient.d.mts +0 -5
  82. package/dist/watcher/ensureClient.mjs +0 -31
  83. package/dist/watcher/index.d.mts +0 -6
  84. package/dist/watcher/isMetadataEmpty.d.mts +0 -2
  85. package/dist/watcher/isMetadataEmpty.mjs +0 -4
  86. package/dist/watcher/logDiffResult.mjs +0 -94
  87. package/dist/watcher/writeOneSchemaFile.d.mts +0 -11
  88. package/templates/worker.ejs +0 -24
@@ -1,4 +1,4 @@
1
- export default function newModule({ what, moduleNameWithOptionalSegment, dryRun, dir: dirNameFlag, 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>;
@@ -8,6 +8,7 @@ import chalkHighlightThing from '../utils/chalkHighlightThing.mjs';
8
8
  import formatLoggedSegmentName from '../utils/formatLoggedSegmentName.mjs';
9
9
  import getFileSystemEntryType from '../utils/getFileSystemEntryType.mjs';
10
10
  import prettify from '../utils/prettify.mjs';
11
+ import resolveAbsoluteModulePath from '../utils/resolveAbsoluteModulePath.mjs';
11
12
  function splitByLast(str, delimiter = '/') {
12
13
  const index = str.lastIndexOf(delimiter);
13
14
  if (index === -1) {
@@ -18,19 +19,17 @@ function splitByLast(str, delimiter = '/') {
18
19
  const after = str.substring(index + delimiter.length);
19
20
  return [before, after];
20
21
  }
21
- export default async function newModule({ what, moduleNameWithOptionalSegment, dryRun, dir: dirNameFlag, templates: templatesFlag, noSegmentUpdate, overwrite, }) {
22
+ export default async function newModule({ what, moduleNameWithOptionalSegment, dryRun, dir: dirFlag, templates: templatesFlag, noSegmentUpdate, overwrite, empty, }) {
22
23
  const { config, log, apiDir, cwd } = await getProjectInfo();
23
24
  let templates = config.templates;
24
25
  const [segmentName, moduleName] = splitByLast(moduleNameWithOptionalSegment);
25
- // replace c by controller, s by service, w by worker, everything else keeps the same
26
+ // replace c by controller, s by service, everything else keeps the same
26
27
  what = what.map((s) => {
27
28
  switch (s) {
28
29
  case 'c':
29
30
  return 'controller';
30
31
  case 's':
31
32
  return 'service';
32
- case 'w':
33
- return 'worker';
34
33
  default:
35
34
  return s;
36
35
  }
@@ -49,32 +48,32 @@ export default async function newModule({ what, moduleNameWithOptionalSegment, d
49
48
  throw new Error(`Template for "${type}" not found`);
50
49
  }
51
50
  }
52
- const segments = await locateSegments(apiDir);
51
+ const segments = await locateSegments({ dir: apiDir, config });
53
52
  const segment = segments.find((s) => s.segmentName === segmentName);
54
53
  if (!segment) {
55
54
  throw new Error(`Unable to create module. Segment "${segmentName}" not found. Run "vovk new segment ${segmentName}" to create it`);
56
55
  }
57
56
  for (const type of what) {
58
57
  const templatePath = templates[type];
59
- const templateAbsolutePath = templatePath.startsWith('/') || templatePath.startsWith('.')
60
- ? path.resolve(cwd, templatePath)
61
- : path.resolve(cwd, './node_modules', templatePath);
58
+ const templateAbsolutePath = resolveAbsoluteModulePath(templatePath, cwd);
62
59
  const templateCode = await fs.readFile(templateAbsolutePath, 'utf-8');
63
- const { dirName: renderedDirName, fileName, sourceName, compiledName, code, } = await render(templateCode, {
60
+ const { dir: renderedDir, fileName, sourceName, compiledName, code, } = await render(templateCode, {
64
61
  cwd,
65
62
  config,
66
63
  withService: what.includes('service'),
67
64
  segmentName,
68
65
  moduleName,
66
+ empty,
67
+ templateFileName: templateAbsolutePath,
69
68
  });
70
- const dirName = dirNameFlag || renderedDirName;
71
- if (!dirName) {
72
- throw new Error(`The template for "${type}" does not provide a dirName`);
69
+ const dir = dirFlag || renderedDir;
70
+ if (!dir) {
71
+ throw new Error(`The template for "${type}" does not provide a dir`);
73
72
  }
74
73
  if (!fileName) {
75
74
  throw new Error(`The template for "${type}" does not provide a fileName`);
76
75
  }
77
- const absoluteModuleDir = path.join(cwd, dirName);
76
+ const absoluteModuleDir = path.join(cwd, dir);
78
77
  const absoluteModulePath = path.join(absoluteModuleDir, fileName);
79
78
  const prettiedCode = await prettify(code, absoluteModulePath);
80
79
  if (!dryRun) {
@@ -87,12 +86,12 @@ export default async function newModule({ what, moduleNameWithOptionalSegment, d
87
86
  log.info(`Created ${chalkHighlightThing(fileName)} using ${chalkHighlightThing(`"${type}"`)} template for ${formatLoggedSegmentName(segmentName)}`);
88
87
  }
89
88
  }
90
- if (type === 'controller' || type === 'worker') {
89
+ if (type === 'controller') {
91
90
  if (!sourceName) {
92
91
  throw new Error(`The template for "${type}" does not provide a sourceName`);
93
92
  }
94
93
  if (!compiledName) {
95
- throw new Error('The template for "${type}" does not provide a compiledName');
94
+ throw new Error(`The template for "${type}" does not provide a compiledName`);
96
95
  }
97
96
  const { routeFilePath } = segment;
98
97
  const segmentSourceCode = await fs.readFile(routeFilePath, 'utf-8');
@@ -101,7 +100,6 @@ export default async function newModule({ what, moduleNameWithOptionalSegment, d
101
100
  const newSegmentCode = await prettify(addClassToSegmentCode(segmentSourceCode, {
102
101
  sourceName,
103
102
  compiledName,
104
- type,
105
103
  importPath,
106
104
  }), routeFilePath);
107
105
  if (!dryRun) {
@@ -5,6 +5,7 @@ import getFileSystemEntryType from '../utils/getFileSystemEntryType.mjs';
5
5
  import chalkHighlightThing from '../utils/chalkHighlightThing.mjs';
6
6
  import formatLoggedSegmentName from '../utils/formatLoggedSegmentName.mjs';
7
7
  import prettify from '../utils/prettify.mjs';
8
+ import chalk from 'chalk';
8
9
  export default async function newSegment({ segmentName, overwrite, dryRun, }) {
9
10
  const { apiDir, cwd, log } = await getProjectInfo();
10
11
  const absoluteSegmentRoutePath = path.join(cwd, apiDir, segmentName, '[[...vovk]]/route.ts');
@@ -13,15 +14,14 @@ export default async function newSegment({ segmentName, overwrite, dryRun, }) {
13
14
  }
14
15
  const code = await prettify(`import { initVovk } from 'vovk';
15
16
 
17
+ export const runtime = 'edge';
18
+
16
19
  const controllers = {};
17
- const workers = {};
18
20
 
19
21
  export type Controllers = typeof controllers;
20
- export type Workers = typeof workers;
21
22
 
22
23
  export const { GET, POST, PATCH, PUT, HEAD, OPTIONS, DELETE } = initVovk({
23
24
  ${segmentName ? ` segmentName: '${segmentName}',\n` : ''} emitSchema: true,
24
- workers,
25
25
  controllers,
26
26
  });
27
27
  `, absoluteSegmentRoutePath);
@@ -29,5 +29,7 @@ ${segmentName ? ` segmentName: '${segmentName}',\n` : ''} emitSchema: true,
29
29
  await fs.mkdir(path.dirname(absoluteSegmentRoutePath), { recursive: true });
30
30
  await fs.writeFile(absoluteSegmentRoutePath, code);
31
31
  }
32
- log.info(`${formatLoggedSegmentName(segmentName, { upperFirst: true })} created at ${absoluteSegmentRoutePath}. Run ${chalkHighlightThing(`vovk new controller ${[segmentName, 'someName'].filter(Boolean).join('/')}`)} to create a new controller`);
32
+ log.info(`${formatLoggedSegmentName(segmentName, { upperFirst: true })} created at ${absoluteSegmentRoutePath}.`);
33
+ const dir = chalk.cyanBright([segmentName, 'thing'].filter(Boolean).join('/'));
34
+ log.info(`Run ${chalkHighlightThing(`npx vovk new service controller ${dir}`)} to create a new controller with a service at modules/${dir} folder for this segment`);
33
35
  }
@@ -1,8 +1,11 @@
1
- import type { VovkConfig, VovkModuleRenderResult } from '../types.mjs';
2
- export default function render(codeTemplate: string, { config, withService, segmentName, moduleName, }: {
1
+ import type { VovkStrictConfig } from 'vovk';
2
+ import type { VovkModuleRenderResult } from '../types.mjs';
3
+ export default function render(codeTemplate: string, { config, withService, segmentName, moduleName, empty, templateFileName, }: {
3
4
  cwd: string;
4
- config: VovkConfig;
5
+ config: VovkStrictConfig;
5
6
  withService: boolean;
6
7
  segmentName: string;
7
8
  moduleName: string;
9
+ empty?: boolean;
10
+ templateFileName: string;
8
11
  }): Promise<VovkModuleRenderResult>;
@@ -4,30 +4,42 @@ import _ from 'lodash';
4
4
  import pluralize from 'pluralize';
5
5
  import addCommonTerms from './addCommonTerms.mjs';
6
6
  addCommonTerms();
7
- export default async function render(codeTemplate, { config, withService, segmentName, moduleName, }) {
7
+ export default async function render(codeTemplate, { config, withService, segmentName, moduleName, empty, templateFileName, }) {
8
8
  const getModuleDirName = (givenSegmentName, givenModuleName) => [config.modulesDir, givenSegmentName || config.rootSegmentModulesDirName, _.camelCase(givenModuleName)]
9
9
  .filter(Boolean)
10
10
  .join('/');
11
- const templateVars = {
12
- // input
11
+ const theThing = _.camelCase(moduleName);
12
+ const TheThing = _.upperFirst(theThing);
13
+ const the_thing = _.snakeCase(moduleName);
14
+ const THE_THING = _.toUpper(the_thing);
15
+ const the__thing = _.kebabCase(moduleName);
16
+ const t = {
17
+ // module name variations
18
+ moduleName,
19
+ theThing,
20
+ theThings: pluralize(theThing),
21
+ TheThing,
22
+ TheThings: pluralize(TheThing),
23
+ the_thing,
24
+ the_things: pluralize(the_thing),
25
+ THE_THING,
26
+ THE_THINGS: pluralize(THE_THING),
27
+ 'the-thing': the__thing,
28
+ 'the-things': pluralize(the__thing),
29
+ // data
13
30
  config,
14
31
  withService,
15
32
  segmentName,
16
- moduleName,
17
- // utils
18
- getModuleDirName,
33
+ defaultDir: getModuleDirName(segmentName, theThing),
19
34
  // libraries
20
35
  _, // lodash
21
36
  pluralize,
22
37
  };
23
- // first, render the front matter because it can use ejs variables
24
- const parsed = matter((await ejs.render(codeTemplate, templateVars, { async: true })).trim());
25
- const { dirName, fileName, sourceName, compiledName } = parsed.data;
26
- const code = parsed.content;
27
- // const templateContent = parsed.content; TODO
28
- // const code = await ejs.render(templateContent, templateVars, { async: true });
38
+ const parsed = matter((await ejs.render(codeTemplate, { t }, { async: true, filename: templateFileName })).trim());
39
+ const { dir, fileName, sourceName, compiledName } = parsed.data;
40
+ const code = empty ? (sourceName ? `export default class ${sourceName} {}` : '') : parsed.content;
29
41
  return {
30
- dirName,
42
+ dir,
31
43
  fileName,
32
44
  sourceName,
33
45
  compiledName,
package/dist/types.d.mts CHANGED
@@ -1,55 +1,21 @@
1
1
  import type { LogLevelNames } from 'loglevel';
2
- export type KnownAny = any;
3
- export type VovkEnv = {
4
- PORT?: string;
5
- VOVK_CLIENT_OUT_DIR?: string;
6
- VOVK_SCHEMA_OUT_DIR?: string;
7
- VOVK_FETCHER?: string;
8
- VOVK_VALIDATE_ON_CLIENT?: string;
9
- VOVK_MODULES_DIR?: string;
10
- VOVK_VALIDATION_LIBRARY?: string;
11
- VOVK_ORIGIN?: string;
12
- VOVK_ROOT_ENTRY?: string;
13
- VOVK_API_ENTRY_POINT?: string;
14
- VOVK_ROOT_SEGMENT_MODULES_DIR_NAME?: string;
15
- VOVK_LOG_LEVEL?: LogLevelNames;
16
- VOVK_PRETTIFY_CLIENT?: string;
17
- VOVK_DEV_HTTPS?: string;
18
- __VOVK_START_WATCHER_IN_STANDALONE_MODE__?: 'true';
19
- };
20
- export type VovkConfig = {
21
- clientOutDir?: string;
22
- schemaOutDir?: string;
23
- fetcher?: string;
24
- validateOnClient?: string | null;
25
- modulesDir?: string;
26
- validationLibrary?: string | null;
27
- rootEntry?: string;
28
- origin?: string;
29
- rootSegmentModulesDirName?: string;
30
- logLevel?: LogLevelNames;
31
- prettifyClient?: boolean;
32
- devHttps?: boolean;
33
- templates?: {
34
- service?: string;
35
- controller?: string;
36
- worker?: string;
37
- [key: string]: string | undefined;
38
- };
39
- };
40
2
  export type VovkModuleRenderResult = {
41
3
  fileName: string;
42
- dirName: string;
4
+ dir: string;
43
5
  sourceName?: string;
44
6
  compiledName?: string;
45
7
  code: string;
46
8
  };
47
9
  export interface DevOptions {
48
- clientOut?: string;
49
10
  nextDev?: boolean;
11
+ exit?: boolean;
50
12
  }
51
13
  export interface GenerateOptions {
52
- clientOut?: string;
14
+ clientOutDir?: string;
15
+ templates?: string[];
16
+ prettify?: boolean;
17
+ emitFullSchema?: string | boolean;
18
+ config?: string;
53
19
  }
54
20
  export interface InitOptions {
55
21
  yes?: boolean;
@@ -62,7 +28,7 @@ export interface InitOptions {
62
28
  updateTsConfig?: boolean;
63
29
  updateScripts?: 'implicit' | 'explicit';
64
30
  validationLibrary?: string | null;
65
- validateOnClient?: boolean;
31
+ reactQuery?: boolean;
66
32
  dryRun?: boolean;
67
33
  channel?: 'latest' | 'beta' | 'draft';
68
34
  }
@@ -72,4 +38,5 @@ export interface NewOptions {
72
38
  dir?: string;
73
39
  overwrite?: boolean;
74
40
  noSegmentUpdate?: boolean;
41
+ empty?: boolean;
75
42
  }
@@ -1,2 +1,2 @@
1
- import { KnownAny } from '../types.mjs';
2
- export default function debounceWithArgs<T extends (...args: KnownAny[]) => KnownAny>(fn: T, wait: number): (...args: Parameters<T>) => void | Promise<void>;
1
+ import type { KnownAny } from 'vovk';
2
+ export default function debounceWithArgs<Callback extends (...args: KnownAny[]) => KnownAny>(callback: Callback, wait: number): (...args: Parameters<Callback>) => Promise<Awaited<ReturnType<Callback>>>;
@@ -1,14 +1,29 @@
1
- import debounce from 'lodash/debounce.js';
2
- export default function debounceWithArgs(fn, wait) {
3
- const debouncedFunctions = new Map();
1
+ export default function debounceWithArgs(callback, wait) {
2
+ // Stores timeouts keyed by the stringified arguments
3
+ const timeouts = new Map();
4
4
  return (...args) => {
5
+ // Convert arguments to a JSON string (or any other stable key generation)
5
6
  const key = JSON.stringify(args);
6
- if (!debouncedFunctions.has(key)) {
7
- debouncedFunctions.set(key, debounce(fn, wait));
8
- }
9
- const debouncedFn = debouncedFunctions.get(key);
10
- if (debouncedFn) {
11
- debouncedFn(...args);
7
+ // Clear any existing timer for this specific key
8
+ if (timeouts.has(key)) {
9
+ clearTimeout(timeouts.get(key));
12
10
  }
11
+ // Return a promise that resolves/rejects after the debounce delay
12
+ return new Promise((resolve, reject) => {
13
+ const timeoutId = setTimeout(async () => {
14
+ try {
15
+ const result = await callback(...args);
16
+ resolve(result);
17
+ }
18
+ catch (error) {
19
+ reject(error);
20
+ }
21
+ finally {
22
+ // Remove the entry once the callback is invoked
23
+ timeouts.delete(key);
24
+ }
25
+ }, wait);
26
+ timeouts.set(key, timeoutId);
27
+ });
13
28
  };
14
29
  }
@@ -1,5 +1,5 @@
1
1
  import net from 'node:net';
2
- // TODO check comments
2
+ // Created with AI
3
3
  /**
4
4
  * Checks if a port is available.
5
5
  * @param {number} port - The port to check.
@@ -0,0 +1 @@
1
+ export default function resolveAbsoluteModulePath(modulePath: string, cwd: string): string;
@@ -0,0 +1,6 @@
1
+ import path from 'node:path';
2
+ export default function resolveAbsoluteModulePath(modulePath, cwd) {
3
+ return modulePath.startsWith('/') || modulePath.startsWith('.')
4
+ ? path.resolve(cwd, modulePath)
5
+ : path.resolve(cwd, './node_modules', modulePath);
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vovk-cli",
3
- "version": "0.0.1-draft.13",
3
+ "version": "0.0.1-draft.130",
4
4
  "bin": {
5
5
  "vovk": "./dist/index.mjs"
6
6
  },
@@ -10,12 +10,12 @@
10
10
  "prefix": ".",
11
11
  "scripts": {
12
12
  "build": "rm -rf dist tsconfig.build.tsbuildinfo && tsc -P tsconfig.build.json",
13
- "build-test": "rm -rf test_dist && tsc -P tsconfig.test.json",
14
- "pre-test": "npm run build && chmod +x ./dist/index.mjs && npm run build-test",
15
- "test-only": "npm run pre-test && node --test --test-only test_dist/test/**/*.mjs",
16
- "test": "npm run pre-test && node --test --test-concurrency=1 test_dist/test/**/*.mjs",
13
+ "postbuild": "chmod +x ./dist/index.mjs",
14
+ "pre-test": "npm run build",
15
+ "test-only": "npm run pre-test && node --experimental-transform-types --experimental-strip-types --test --test-only test/spec/**/*.mts",
16
+ "test": "npm run pre-test && node --experimental-transform-types --experimental-strip-types --test --test-concurrency=1 test/spec/**/*.mts",
17
17
  "tsc": "tsc --noEmit",
18
- "ncu": "npm-check-updates -u",
18
+ "ncu": "npm-check-updates -u -x commander",
19
19
  "npm-publish": "npm publish"
20
20
  },
21
21
  "repository": {
@@ -28,34 +28,38 @@
28
28
  "cli",
29
29
  "vovk"
30
30
  ],
31
- "author": "Andrii Gubanov",
31
+ "author": "Andrey Gubanov",
32
32
  "license": "MIT",
33
33
  "bugs": {
34
34
  "url": "https://github.com/finom/vovk/issues"
35
35
  },
36
36
  "homepage": "https://vovk.dev",
37
37
  "peerDependencies": {
38
- "vovk": "^3.0.0-draft.13"
38
+ "vovk": "^3.0.0-draft.109"
39
+ },
40
+ "optionalDependencies": {
41
+ "vovk-python-client": "*"
39
42
  },
40
43
  "dependencies": {
41
- "@inquirer/prompts": "^7.0.1",
42
- "@npmcli/package-json": "^6.0.1",
43
- "chalk": "^5.3.0",
44
- "chokidar": "^4.0.1",
45
- "commander": "^12.1.0",
46
- "concurrently": "^9.0.1",
47
- "dotenv": "^16.4.5",
44
+ "@inquirer/prompts": "^7.3.1",
45
+ "@npmcli/package-json": "^6.1.1",
46
+ "chalk": "^5.4.1",
47
+ "chokidar": "^4.0.3",
48
+ "commander": "^13.1.0",
49
+ "concurrently": "^9.1.2",
50
+ "dotenv": "^16.4.7",
48
51
  "ejs": "^3.1.10",
52
+ "glob": "^11.0.1",
49
53
  "gray-matter": "^4.0.3",
50
- "inflection": "^3.0.0",
54
+ "inflection": "^3.0.2",
51
55
  "jsonc-parser": "^3.3.1",
52
56
  "lodash": "^4.17.21",
53
57
  "loglevel": "^1.9.2",
54
58
  "pluralize": "^8.0.0",
55
- "prettier": "^3.3.3",
59
+ "prettier": "^3.4.2",
56
60
  "tar-stream": "^3.1.7",
57
- "ts-morph": "^24.0.0",
58
- "undici": "^6.20.1"
61
+ "ts-morph": "^25.0.0",
62
+ "undici": "^7.3.0"
59
63
  },
60
64
  "devDependencies": {
61
65
  "@types/concat-stream": "^2.0.3",
@@ -64,8 +68,8 @@
64
68
  "@types/pluralize": "^0.0.33",
65
69
  "@types/tar-stream": "^3.1.3",
66
70
  "concat-stream": "^2.0.0",
67
- "create-next-app": "^15.0.2",
71
+ "create-next-app": "^15.1.6",
68
72
  "node-pty": "^1.0.0",
69
- "type-fest": "^4.26.1"
73
+ "type-fest": "^4.33.0"
70
74
  }
71
75
  }
@@ -1,51 +1,50 @@
1
- <% var modulePascalName = _.upperFirst(_.camelCase(moduleName)); %>
2
- <% var modulePascalNamePlural = pluralize(modulePascalName); %>
3
- <% var controllerName = modulePascalName + 'Controller'; %>
4
- <% var compiledName = modulePascalName + 'RPC'; %>
5
- <% var serviceName = modulePascalName + 'Service'; %>
1
+ <% const vars = {
2
+ ControllerName: t.TheThing + 'Controller',
3
+ ServiceName: t.TheThing + 'Service',
4
+ }; %>
6
5
  ---
7
- dirName: <%= getModuleDirName(segmentName, moduleName) %>
8
- fileName: <%= controllerName + '.ts' %>
9
- sourceName: <%= controllerName %>
10
- compiledName: <%= compiledName %>
6
+ dir: <%= t.defaultDir %>
7
+ fileName: <%= vars.ControllerName + '.ts' %>
8
+ sourceName: <%= vars.ControllerName %>
9
+ compiledName: <%= t.TheThing + 'RPC' %>
11
10
  ---
12
11
 
13
12
  import { prefix, get, put, post, del, type VovkRequest } from 'vovk';
14
- <% if(withService) { %>
15
- import <%= serviceName %> from './<%= serviceName %>';
13
+ <% if(t.withService) { %>
14
+ import <%= vars.ServiceName %> from './<%= vars.ServiceName %>';
16
15
  <% } %>
17
16
 
18
- @prefix('<%= _.kebabCase(moduleName).toLowerCase() %>')
19
- export default class <%= controllerName %> {
17
+ @prefix('<%= t['the-things'] %>')
18
+ export default class <%= vars.ControllerName %> {
20
19
  @get()
21
- static get<%= modulePascalNamePlural %> = async (req: VovkRequest<null, { search: string }>) => {
20
+ static get<%= t.TheThings %> = async (req: VovkRequest<null, { search: string }>) => {
22
21
  const search = req.nextUrl.searchParams.get('search');
23
- <% if(withService) { %>
24
- return <%= serviceName %>.get<%= modulePascalNamePlural %>(search);
22
+ <% if(t.withService) { %>
23
+ return <%= vars.ServiceName %>.get<%= t.TheThings %>(search);
25
24
  <% } else { %>
26
25
  return { results: [], search };
27
26
  <% } %>
28
27
  }
29
28
 
30
29
  @put(':id')
31
- static update<%= modulePascalName %> = async (req: VovkRequest<{ foo: 'bar' | 'baz' }, { q: string }>, params: { id: string }) => {
30
+ static update<%= t.TheThing %> = async (req: VovkRequest<{ foo: 'bar' | 'baz' }, { q: string }>, params: { id: string }) => {
32
31
  const { id } = params;
33
32
  const body = await req.json();
34
33
  const q = req.nextUrl.searchParams.get('q');
35
- <% if(withService) { %>
36
- return <%= serviceName %>.update<%= modulePascalName %>(id, q, body);
34
+ <% if(t.withService) { %>
35
+ return <%= vars.ServiceName %>.update<%= t.TheThing %>(id, q, body);
37
36
  <% } else { %>
38
37
  return { id, body, q };
39
38
  <% } %>
40
39
  };
41
40
 
42
41
  @post()
43
- static create<%= modulePascalName %> = () => {
42
+ static create<%= t.TheThing %> = () => {
44
43
  // ...
45
44
  };
46
45
 
47
46
  @del(':id')
48
- static delete<%= modulePascalName %> = () => {
47
+ static delete<%= t.TheThing %> = () => {
49
48
  // ...
50
49
  };
51
50
  }
@@ -1,24 +1,24 @@
1
- <% var modulePascalName = _.upperFirst(_.camelCase(moduleName)); %>
2
- <% var modulePascalNamePlural = pluralize(modulePascalName); %>
3
- <% var serviceName = modulePascalName + 'Service'; %>
4
- <% var controllerName = modulePascalName + 'Controller'; %>
1
+ <% const vars = {
2
+ ControllerName: t.TheThing + 'Controller',
3
+ ServiceName: t.TheThing + 'Service',
4
+ }; %>
5
5
  ---
6
- dirName: <%= getModuleDirName(segmentName, moduleName) %>
7
- fileName: <%= serviceName + '.ts' %>
6
+ dir: <%= t.defaultDir %>
7
+ fileName: <%= vars.ServiceName + '.ts' %>
8
8
  ---
9
9
 
10
10
  import type { VovkControllerBody, VovkControllerQuery } from 'vovk';
11
- import type <%= controllerName %> from './<%= controllerName %>';
11
+ import type <%= vars.ControllerName %> from './<%= vars.ControllerName %>';
12
12
 
13
- export default class <%= serviceName %> {
14
- static get<%= modulePascalNamePlural %> = (search: VovkControllerQuery<typeof <%= controllerName %>.get<%= modulePascalNamePlural %>>['search']) => {
13
+ export default class <%= vars.ServiceName %> {
14
+ static get<%= t.TheThings %> = (search: VovkControllerQuery<typeof <%= vars.ControllerName %>.get<%= t.TheThings %>>['search']) => {
15
15
  return { results: [], search };
16
16
  };
17
17
 
18
- static update<%= modulePascalName %> = (
18
+ static update<%= t.TheThing %> = (
19
19
  id: string,
20
- q: VovkControllerQuery<typeof <%= controllerName %>.update<%= modulePascalName %>>['q'],
21
- body: VovkControllerBody<typeof <%= controllerName %>.update<%= modulePascalName %>>
20
+ q: VovkControllerQuery<typeof <%= vars.ControllerName %>.update<%= t.TheThing %>>['q'],
21
+ body: VovkControllerBody<typeof <%= vars.ControllerName %>.update<%= t.TheThing %>>
22
22
  ) => {
23
23
  return { id, q, body };
24
24
  };
@@ -1,7 +0,0 @@
1
- import type { VovkSchema } from 'vovk';
2
- import type { ProjectInfo } from './getProjectInfo/index.mjs';
3
- import type { Segment } from './locateSegments.mjs';
4
- export default function generateClient(projectInfo: ProjectInfo, segments: Segment[], segmentsSchema: Record<string, VovkSchema>): Promise<{
5
- written: boolean;
6
- path: string;
7
- }>;