vovk-cli 0.0.1-draft.47 → 0.0.1-draft.48

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 CHANGED
@@ -24,6 +24,6 @@ npm install -D vovk-cli
24
24
  - [vovk dev](https://vovk.dev/cli/vovk-dev) - starts the development script that watches the changes in controllers and regenerates the schema and client.
25
25
  - [vovk generate](https://vovk.dev/cli/vovk-generate) - generates the client based on the schema.
26
26
  - [vovk init](https://vovk.dev/cli/vovk-init) - initializes the Vovk.ts project.
27
- - [vovk new](https://vovk.dev/cli/vovk-new) - generates a new controller, service, worker or a custom module.
27
+ - [vovk new](https://vovk.dev/cli/vovk-new) - generates a new controller, service or a custom module.
28
28
 
29
29
  For more information, please visit the [CLI documentation](https://vovk.dev/cli) or use `npx vovk-cli --help` to get the list of available commands and options.
@@ -1,24 +1,15 @@
1
1
 
2
2
  <%- '// auto-generated\n/* eslint-disable */' %>
3
- import type { createRPC, createWPC, VovkClientFetcher } from 'vovk';
3
+ import type { VovkClientFetcher } from 'vovk';
4
4
  import type fetcher from '<%= fetcherClientImportPath %>';
5
- <% segments.forEach((segment, i) => {
6
- const hasWorkers = !!Object.keys(segmentsSchema[segment.segmentName].workers).length;
7
- %>
8
- import type { Controllers as Controllers<%= i %><% if(hasWorkers) { %>, Workers as Workers<%= i %> <% } %> } from "<%= segment.segmentImportPath %>";
9
- <% }) %>
5
+ import type createRPC from '<%= createRPCImportPath %>';
6
+ <% segments.forEach((segment, i) => { if(Object.keys(segmentsSchema[segment.segmentName].controllers).length) { %>
7
+ import type { Controllers as Controllers<%= i %> } from "<%= segment.segmentImportPath %>";
8
+ <% }}) %>
10
9
  type Options = typeof fetcher extends VovkClientFetcher<infer U> ? U : never;
11
10
 
12
- <% segments.forEach((segment, i) => {
13
- const segSchema = segmentsSchema[segment.segmentName];
14
- if (!segSchema || !segSchema.emitSchema) return;
15
- const controllers = Object.keys(segSchema.controllers);
16
- const workers = Object.keys(segSchema.workers);
17
- %>
18
- <% controllers.forEach((key) => { %>
11
+ <% segments.forEach((segment, i) => { %>
12
+ <% Object.keys(segmentsSchema[segment.segmentName].controllers).forEach((key) => { %>
19
13
  export const <%= key %>: ReturnType<typeof createRPC<Controllers<%= i %>["<%= key %>"], Options>>;
20
14
  <% }) %>
21
- <% workers.forEach((key) => { %>
22
- export const <%= key %>: ReturnType<typeof createWPC<Workers<%= i %>["<%= key %>"]>>;
23
- <% }) %>
24
15
  <% }) %>
@@ -1,25 +1,16 @@
1
1
  <%- '// auto-generated\n/* eslint-disable */' %>
2
- const { createRPC, createWPC } = require('vovk');
3
2
  const { default: fetcher } = require('<%= fetcherClientImportPath %>');
3
+ const { default: createRPC } = require('<%= createRPCImportPath %>');
4
4
  const schema = require('<%= schemaOutImportPath %>');
5
5
 
6
6
  const { default: validateOnClient = null } = <%- validateOnClientImportPath ? `require('${validateOnClientImportPath}')` : '{}'%>;
7
7
  const apiRoot = '<%= apiRoot %>';
8
-
9
- <% segments.forEach((segment) => {
10
- const segSchema = segmentsSchema[segment.segmentName];
11
- if (!segSchema || !segSchema.emitSchema) return;
12
- const controllers = Object.keys(segSchema.controllers);
13
- const workers = Object.keys(segSchema.workers);
14
- %>
15
- <% controllers.forEach((key) => { %>
8
+ <% segments.forEach((segment) => { %>
9
+ <% Object.keys(segmentsSchema[segment.segmentName].controllers).forEach((key) => { %>
16
10
  exports.<%= key %> = createRPC(
17
11
  schema['<%= segment.segmentName %>'].controllers.<%= key %>,
18
12
  '<%= segment.segmentName %>',
19
13
  { fetcher, validateOnClient, defaultOptions: { apiRoot } }
20
14
  );
21
15
  <% }) %>
22
- <% workers.forEach((key) => { %>
23
- exports.<%= key %> = createWPC(schema['<%= segment.segmentName %>'].workers.<%= key %>);
24
- <% }) %>
25
16
  <% }) %>
@@ -1,12 +1,11 @@
1
1
  <%- '// auto-generated\n/* eslint-disable */' %>
2
- import { createRPC, createWPC, type VovkClientFetcher } from 'vovk';
2
+ import type { VovkClientFetcher } from 'vovk';
3
3
  import fetcher from '<%= fetcherClientImportPath %>';
4
+ import createRPC from '<%= createRPCImportPath %>';
4
5
  import schema from '<%= schemaOutImportPath %>';
5
- <% segments.forEach((segment, i) => {
6
- const hasWorkers = !!Object.keys(segmentsSchema[segment.segmentName].workers).length;
7
- %>
8
- import type { Controllers as Controllers<%= i %><% if(hasWorkers) { %>, Workers as Workers<%= i %> <% } %> } from "<%= segment.segmentImportPath %>";
9
- <% }) %>
6
+ <% segments.forEach((segment, i) => { if(Object.keys(segmentsSchema[segment.segmentName].controllers).length) { %>
7
+ import type { Controllers as Controllers<%= i %> } from "<%= segment.segmentImportPath %>";
8
+ <% }}) %>
10
9
  <% if (validateOnClientImportPath) { %>
11
10
  import validateOnClient from '<%= validateOnClientImportPath %>';
12
11
  <% } else { %>
@@ -15,22 +14,12 @@ const validateOnClient = undefined;
15
14
  type Options = typeof fetcher extends VovkClientFetcher<infer U> ? U : never;
16
15
  const apiRoot = '<%= apiRoot %>';
17
16
 
18
- <% segments.forEach((segment, i) => {
19
- const segSchema = segmentsSchema[segment.segmentName];
20
- if (!segSchema || !segSchema.emitSchema) return;
21
- const hasWorkers = !!Object.keys(segmentsSchema[segment.segmentName].workers).length;
22
- %>
23
- <% Object.keys(segSchema.controllers).forEach((key) => { %>
17
+ <% segments.forEach((segment, i) => { %>
18
+ <% Object.keys(segmentsSchema[segment.segmentName].controllers).forEach((key) => { %>
24
19
  export const <%= key %> = createRPC<Controllers<%= i %>["<%= key %>"], Options>(
25
20
  schema['<%= segment.segmentName %>'].controllers.<%= key %>,
26
21
  '<%= segment.segmentName %>',
27
22
  { fetcher, validateOnClient, defaultOptions: { apiRoot } }
28
- );
29
- <% }) %>
30
-
31
- <% Object.keys(segSchema.workers).forEach((key) => { %>
32
- export const <%= key %> = createWPC<Workers<%= i %>["<%= key %>"]>(
33
- schema['<%= segment.segmentName %>'].workers.<%= key %>
34
23
  );
35
24
  <% }) %>
36
25
  <% }) %>
@@ -1,29 +1,23 @@
1
- import type { VovkControllerSchema, VovkWorkerSchema, VovkSchema } from 'vovk';
1
+ import type { VovkControllerSchema, VovkSchema } from 'vovk';
2
2
  interface HandlersDiff {
3
3
  nameOfClass: string;
4
4
  added: string[];
5
5
  removed: string[];
6
6
  changed: string[];
7
7
  }
8
- interface WorkersOrControllersDiff {
8
+ interface ControllersDiff {
9
9
  added: string[];
10
10
  removed: string[];
11
11
  handlers: HandlersDiff[];
12
12
  }
13
13
  export interface DiffResult {
14
- workers: WorkersOrControllersDiff;
15
- controllers: WorkersOrControllersDiff;
14
+ controllers: ControllersDiff;
16
15
  }
17
- export declare function diffHandlers<T extends VovkWorkerSchema['handlers'] | VovkControllerSchema['handlers']>(oldHandlers: T, newHandlers: T, nameOfClass: string): HandlersDiff;
18
- export declare function diffWorkersOrControllers<T extends VovkSchema['controllers'] | VovkSchema['workers']>(oldItems: T, newItems: T): WorkersOrControllersDiff;
16
+ export declare function diffHandlers<T extends VovkControllerSchema['handlers']>(oldHandlers: T, newHandlers: T, nameOfClass: string): HandlersDiff;
17
+ export declare function diffControllers<T extends VovkSchema['controllers']>(oldItems: T, newItems: T): ControllersDiff;
19
18
  /**
20
19
  example output:
21
20
  {
22
- workers: {
23
- added: ["WorkerC"],
24
- removed: ["WorkerA"],
25
- handlers: []
26
- },
27
21
  controllers: {
28
22
  added: ["ControllerC"],
29
23
  removed: ["ControllerB"],
@@ -18,7 +18,7 @@ export function diffHandlers(oldHandlers, newHandlers, nameOfClass) {
18
18
  }
19
19
  return { nameOfClass, added, removed, changed };
20
20
  }
21
- export function diffWorkersOrControllers(oldItems, newItems) {
21
+ export function diffControllers(oldItems, newItems) {
22
22
  const added = [];
23
23
  const removed = [];
24
24
  const handlersDiff = [];
@@ -43,11 +43,6 @@ export function diffWorkersOrControllers(oldItems, newItems) {
43
43
  /**
44
44
  example output:
45
45
  {
46
- workers: {
47
- added: ["WorkerC"],
48
- removed: ["WorkerA"],
49
- handlers: []
50
- },
51
46
  controllers: {
52
47
  added: ["ControllerC"],
53
48
  removed: ["ControllerB"],
@@ -63,10 +58,7 @@ example output:
63
58
  }
64
59
  */
65
60
  export default function diffSchema(oldJson, newJson) {
66
- const workersDiff = diffWorkersOrControllers(oldJson.workers ?? {}, newJson.workers ?? {});
67
- const controllersDiff = diffWorkersOrControllers(oldJson.controllers ?? {}, newJson.controllers ?? {});
68
61
  return {
69
- workers: workersDiff,
70
- controllers: controllersDiff,
62
+ controllers: diffControllers(oldJson.controllers ?? {}, newJson.controllers ?? {}),
71
63
  };
72
64
  }
@@ -41,7 +41,6 @@ export default segmentSchema;`;
41
41
  emitSchema: false,
42
42
  segmentName,
43
43
  controllers: {},
44
- workers: {},
45
44
  },
46
45
  skipIfExists: true,
47
46
  });
@@ -199,21 +199,17 @@ export class VovkDev {
199
199
  }
200
200
  const nameOfClasReg = /\bclass\s+([A-Za-z_]\w*)(?:\s*<[^>]*>)?\s*\{/g;
201
201
  const namesOfClasses = [...code.matchAll(nameOfClasReg)].map((match) => match[1]);
202
- const importRegex = /import\s*{[^}]*\b(get|post|put|del|head|options|worker)\b[^}]*}\s*from\s*['"]vovk['"]/;
202
+ const importRegex = /import\s*{[^}]*\b(get|post|put|del|head|options)\b[^}]*}\s*from\s*['"]vovk['"]/;
203
203
  if (importRegex.test(code) && namesOfClasses.length) {
204
204
  const affectedSegments = this.#segments.filter((s) => {
205
205
  const schema = this.#schemas[s.segmentName];
206
206
  if (!schema)
207
207
  return false;
208
208
  const controllersByOriginalName = keyBy(schema.controllers, 'originalControllerName');
209
- const workersByOriginalName = keyBy(schema.workers, 'originalWorkerName');
210
- return namesOfClasses.some((name) => schema.controllers[name] ||
211
- schema.workers[name] ||
212
- controllersByOriginalName[name] ||
213
- workersByOriginalName[name]);
209
+ return namesOfClasses.some((name) => schema.controllers[name] || controllersByOriginalName[name]);
214
210
  });
215
211
  if (affectedSegments.length) {
216
- log.debug(`A file with controller or worker ${namesOfClasses.join(', ')} have been modified at path "${filePath}". Segment(s) affected: ${JSON.stringify(affectedSegments.map((s) => s.segmentName))}`);
212
+ log.debug(`A file with controller ${namesOfClasses.join(', ')} have been modified at path "${filePath}". Segment(s) affected: ${JSON.stringify(affectedSegments.map((s) => s.segmentName))}`);
217
213
  for (const segment of affectedSegments) {
218
214
  await this.#requestSchema(segment.segmentName);
219
215
  }
@@ -223,7 +219,7 @@ export class VovkDev {
223
219
  }
224
220
  }
225
221
  else {
226
- log.debug(`The file does not contain any controller or worker`);
222
+ log.debug(`The file does not contain any controller`);
227
223
  }
228
224
  };
229
225
  #requestSchema = debounceWithArgs(async (segmentName) => {
@@ -283,7 +279,7 @@ export class VovkDev {
283
279
  log.info(`Schema for ${formatLoggedSegmentName(segment.segmentName)} has been updated in ${timeTook}ms`);
284
280
  }
285
281
  }
286
- else if (schema && (!isEmpty(schema.controllers) || !isEmpty(schema.workers))) {
282
+ else if (schema && !isEmpty(schema.controllers)) {
287
283
  log.error(`Non-empty schema provided for ${formatLoggedSegmentName(segment.segmentName)} but "emitSchema" is false`);
288
284
  }
289
285
  if (this.#segments.every((s) => this.#schemas[s.segmentName])) {
@@ -1,4 +1,4 @@
1
1
  import isEmpty from 'lodash/isEmpty.js';
2
2
  export default function isSchemaEmpty(schema) {
3
- return isEmpty(schema.controllers) && isEmpty(schema.workers);
3
+ return isEmpty(schema.controllers);
4
4
  }
@@ -3,23 +3,6 @@ import formatLoggedSegmentName from '../utils/formatLoggedSegmentName.mjs';
3
3
  import chalkHighlightThing from '../utils/chalkHighlightThing.mjs';
4
4
  export default function logDiffResult(segmentName, diffResult, projectInfo) {
5
5
  const diffNormalized = [];
6
- diffResult.workers.added.forEach((name) => {
7
- diffNormalized.push({ what: 'worker', type: 'added', name });
8
- });
9
- diffResult.workers.removed.forEach((name) => {
10
- diffNormalized.push({ what: 'worker', type: 'removed', name });
11
- });
12
- diffResult.workers.handlers.forEach((handler) => {
13
- handler.added.forEach((name) => {
14
- diffNormalized.push({ what: 'workerHandler', type: 'added', name: `${handler.nameOfClass}.${name}` });
15
- });
16
- handler.removed.forEach((name) => {
17
- diffNormalized.push({ what: 'workerHandler', type: 'removed', name: `${handler.nameOfClass}.${name}` });
18
- });
19
- handler.changed.forEach((name) => {
20
- diffNormalized.push({ what: 'workerHandler', type: 'changed', name: `${handler.nameOfClass}.${name}` });
21
- });
22
- });
23
6
  diffResult.controllers.added.forEach((name) => {
24
7
  diffNormalized.push({ what: 'controller', type: 'added', name });
25
8
  });
@@ -43,16 +26,6 @@ export default function logDiffResult(segmentName, diffResult, projectInfo) {
43
26
  const changedText = chalk.cyan('changed');
44
27
  for (const diffNormalizedItem of diffNormalized.slice(0, LIMIT)) {
45
28
  switch (diffNormalizedItem.what) {
46
- case 'worker':
47
- switch (diffNormalizedItem.type) {
48
- case 'added':
49
- projectInfo.log.info(`Schema for WPC ${chalkHighlightThing(diffNormalizedItem.name)} has been ${addedText} at ${formatLoggedSegmentName(segmentName)}`);
50
- break;
51
- case 'removed':
52
- projectInfo.log.info(`Schema for WPC ${chalkHighlightThing(diffNormalizedItem.name)} has been ${removedText} from ${formatLoggedSegmentName(segmentName)}`);
53
- break;
54
- }
55
- break;
56
29
  case 'controller':
57
30
  switch (diffNormalizedItem.type) {
58
31
  case 'added':
@@ -63,16 +36,6 @@ export default function logDiffResult(segmentName, diffResult, projectInfo) {
63
36
  break;
64
37
  }
65
38
  break;
66
- case 'workerHandler':
67
- switch (diffNormalizedItem.type) {
68
- case 'added':
69
- projectInfo.log.info(`Schema for WPC method ${chalkHighlightThing(diffNormalizedItem.name)} has been ${addedText} at ${formatLoggedSegmentName(segmentName)}`);
70
- break;
71
- case 'removed':
72
- projectInfo.log.info(`Schema for WPC method ${chalkHighlightThing(diffNormalizedItem.name)} has been ${removedText} from ${formatLoggedSegmentName(segmentName)}`);
73
- break;
74
- }
75
- break;
76
39
  case 'controllerHandler':
77
40
  switch (diffNormalizedItem.type) {
78
41
  case 'added':
@@ -7,7 +7,7 @@ import getClientTemplates from './getClientTemplates.mjs';
7
7
  export default async function generate({ projectInfo, segments, segmentsSchema, templates, prettify: prettifyClient, fullSchema, }) {
8
8
  templates = templates ?? projectInfo.config.experimental_clientGenerateTemplateNames;
9
9
  const noClient = templates?.[0] === 'none';
10
- const { config, cwd, log, validateOnClientImportPath, apiRoot, fetcherClientImportPath, schemaOutImportPath } = projectInfo;
10
+ const { config, cwd, log, validateOnClientImportPath, apiRoot, fetcherClientImportPath, createRPCImportPath, schemaOutImportPath, } = projectInfo;
11
11
  const clientOutDirAbsolutePath = path.resolve(cwd, config.clientOutDir);
12
12
  const templateFiles = getClientTemplates({ config, cwd, templateNames: templates });
13
13
  // Ensure that each segment has a matching schema if it needs to be emitted:
@@ -27,6 +27,7 @@ export default async function generate({ projectInfo, segments, segmentsSchema,
27
27
  fetcherClientImportPath,
28
28
  schemaOutImportPath,
29
29
  validateOnClientImportPath,
30
+ createRPCImportPath,
30
31
  segments,
31
32
  segmentsSchema,
32
33
  };
@@ -7,9 +7,9 @@ export default async function getConfig({ clientOutDir, cwd }) {
7
7
  const srcRoot = await getRelativeSrcRoot({ cwd });
8
8
  const config = {
9
9
  modulesDir: env.VOVK_MODULES_DIR ?? conf.modulesDir ?? './' + [srcRoot, 'modules'].filter(Boolean).join('/'),
10
- validateOnClient: env.VOVK_VALIDATE_ON_CLIENT ?? conf.validateOnClient ?? null,
11
- validationLibrary: env.VOVK_VALIDATION_LIBRARY ?? conf.validationLibrary ?? null,
12
- fetcher: env.VOVK_FETCHER ?? conf.fetcher ?? 'vovk/dist/client/defaultFetcher',
10
+ validateOnClientPath: env.VOVK_VALIDATE_ON_CLIENT_PATH ?? conf.validateOnClientPath ?? null,
11
+ fetcherPath: env.VOVK_FETCHER_PATH ?? conf.fetcherPath ?? 'vovk/dist/client/defaultFetcher',
12
+ createRPCPath: env.VOVK_CREATE_RPC_PATH ?? conf.createRPCPath ?? 'vovk/dist/client/createRPC',
13
13
  schemaOutDir: env.VOVK_SCHEMA_OUT_DIR ?? conf.schemaOutDir ?? './.vovk-schema',
14
14
  clientOutDir: clientOutDir ?? env.VOVK_CLIENT_OUT_DIR ?? conf.clientOutDir ?? './node_modules/.vovk-client',
15
15
  origin: (env.VOVK_ORIGIN ?? conf.origin ?? '').replace(/\/$/, ''), // Remove trailing slash
@@ -22,7 +22,6 @@ export default async function getConfig({ clientOutDir, cwd }) {
22
22
  templates: {
23
23
  service: 'vovk-cli/templates/service.ejs',
24
24
  controller: 'vovk-cli/templates/controller.ejs',
25
- worker: 'vovk-cli/templates/worker.ejs',
26
25
  ...conf.templates,
27
26
  },
28
27
  };
@@ -11,6 +11,7 @@ export default function getProjectInfo({ port: givenPort, clientOutDir, cwd, }?:
11
11
  srcRoot: string;
12
12
  schemaOutImportPath: string;
13
13
  fetcherClientImportPath: string;
14
+ createRPCImportPath: string;
14
15
  validateOnClientImportPath: string | null;
15
16
  config: Required<import("../types.mjs").VovkConfig>;
16
17
  log: {
@@ -9,12 +9,15 @@ export default async function getProjectInfo({ port: givenPort, clientOutDir, cw
9
9
  const apiRoot = `${config.origin ?? ''}/${config.rootEntry}`;
10
10
  const apiDir = path.join(srcRoot, 'app', config.rootEntry);
11
11
  const schemaOutImportPath = path.relative(config.clientOutDir, config.schemaOutDir).replace(/\\/g, '/'); // windows fix
12
- const fetcherClientImportPath = config.fetcher.startsWith('.')
13
- ? path.relative(config.clientOutDir, config.fetcher)
14
- : config.fetcher;
15
- const validateOnClientImportPath = config.validateOnClient?.startsWith('.')
16
- ? path.relative(config.clientOutDir, config.validateOnClient)
17
- : config.validateOnClient;
12
+ const fetcherClientImportPath = config.fetcherPath.startsWith('.')
13
+ ? path.relative(config.clientOutDir, config.fetcherPath)
14
+ : config.fetcherPath;
15
+ const createRPCImportPath = config.createRPCPath.startsWith('.')
16
+ ? path.relative(config.clientOutDir, config.createRPCPath)
17
+ : config.createRPCPath;
18
+ const validateOnClientImportPath = config.validateOnClientPath?.startsWith('.')
19
+ ? path.relative(config.clientOutDir, config.validateOnClientPath)
20
+ : config.validateOnClientPath;
18
21
  const log = getLogger(config.logLevel);
19
22
  if (configAbsolutePaths.length > 1) {
20
23
  log.warn(`Multiple config files found. Using the first one: ${configAbsolutePaths[0]}`);
@@ -30,6 +33,7 @@ export default async function getProjectInfo({ port: givenPort, clientOutDir, cw
30
33
  srcRoot,
31
34
  schemaOutImportPath,
32
35
  fetcherClientImportPath,
36
+ createRPCImportPath,
33
37
  validateOnClientImportPath,
34
38
  config,
35
39
  log,
package/dist/index.mjs CHANGED
@@ -19,9 +19,9 @@ initProgram(program.command('init'));
19
19
  program
20
20
  .command('dev')
21
21
  .alias('d')
22
- .description('Start schema watcher (optional flag --next-dev to start it with Next.js)')
23
- .option('--next-dev', 'Start schema watcher and Next.js with automatic port allocation')
24
- .option('--exit', 'Kill the processe when schema and client is generated')
22
+ .description('start schema watcher (optional flag --next-dev to start it with Next.js)')
23
+ .option('--next-dev', 'start schema watcher and Next.js with automatic port allocation')
24
+ .option('--exit', 'kill the processe when schema and client is generated')
25
25
  .allowUnknownOption(true)
26
26
  .action(async (options, command) => {
27
27
  const { nextDev, exit = false } = options;
@@ -31,8 +31,8 @@ program
31
31
  : process.env.PORT ||
32
32
  (await getAvailablePort(3000, portAttempts, 0, (failedPort, tryingPort) =>
33
33
  // eslint-disable-next-line no-console
34
- console.warn(`🐺 Next.js Port ${failedPort} is in use, trying ${tryingPort} instead.`)).catch(() => {
35
- throw new Error(`🐺 ❌ Failed to find available Next port after ${portAttempts} attempts`);
34
+ console.warn(`🐺 Port ${failedPort} is in use, trying ${tryingPort} instead.`)).catch(() => {
35
+ throw new Error(`🐺 ❌ Failed to find an available port after ${portAttempts} attempts`);
36
36
  }));
37
37
  if (!PORT) {
38
38
  throw new Error('🐺 ❌ PORT env variable is required');
@@ -73,10 +73,10 @@ program
73
73
  .command('generate')
74
74
  .alias('g')
75
75
  .description('Generate client')
76
- .option('--out, --client-out-dir <path>', 'Path to output directory')
77
- .option('--template, --templates <templates...>', 'Client code templates ("ts", "compiled", "python", "none", a custom path)')
78
- .option('--full-schema [fileName]', 'Generate client with full schema')
79
- .option('--prettify', 'Prettify output files')
76
+ .option('--out, --client-out-dir <path>', 'path to output directory')
77
+ .option('--template, --templates <templates...>', 'client code templates ("ts", "compiled", "python", "none", a custom path)')
78
+ .option('--full-schema [fileName]', 'generate client with full schema')
79
+ .option('--prettify', 'prettify output files')
80
80
  .action(async (options) => {
81
81
  const { clientOutDir, templates, prettify, fullSchema } = options;
82
82
  const projectInfo = await getProjectInfo({ clientOutDir });
@@ -90,12 +90,12 @@ program
90
90
  program
91
91
  .command('new [components...]')
92
92
  .alias('n')
93
- .description('Create new components. "vovk new [...components] [segmentName/]moduleName" to create a new module or "vovk new segment [segmentName]" to create a new segment')
94
- .option('-o, --overwrite', 'Overwrite existing files')
95
- .option('--template, --templates <templates...>', 'Override config template. Accepts an array of strings that correspond the order of the components')
96
- .option('--dir <dirname>', 'Override dirName in template file. Relative to the root of the project')
97
- .option('--no-segment-update', 'Do not update segment files when creating a new module')
98
- .option('--dry-run', 'Do not write files to disk')
93
+ .description('create new components. "vovk new [...components] [segmentName/]moduleName" to create a new module or "vovk new segment [segmentName]" to create a new segment')
94
+ .option('-o, --overwrite', 'overwrite existing files')
95
+ .option('--template, --templates <templates...>', 'override config template; accepts an array of strings that correspond the order of the components')
96
+ .option('--dir <dirname>', 'override dirName in template file; relative to the root of the project')
97
+ .option('--no-segment-update', 'do not update segment files when creating a new module')
98
+ .option('--dry-run', 'do not write files to disk')
99
99
  .action((components, options) => newComponents(components, options));
100
100
  program
101
101
  .command('help')
@@ -14,12 +14,10 @@ export default async function createConfig({ root, log, options: { validationLib
14
14
  const templates = {
15
15
  controller: 'vovk-cli/templates/controller.ejs',
16
16
  service: 'vovk-cli/templates/service.ejs',
17
- worker: 'vovk-cli/templates/worker.ejs',
18
17
  };
19
18
  if (validationLibrary) {
20
- config.validationLibrary = validationLibrary;
21
19
  if (validateOnClient) {
22
- config.validateOnClient = `${validationLibrary}/validateOnClient`;
20
+ config.validateOnClientPath = `${validationLibrary}/validateOnClient`;
23
21
  }
24
22
  try {
25
23
  const validationTemplates = await getTemplateFilesFromPackage(validationLibrary, channel);
@@ -1,6 +1,5 @@
1
- export default function addClassToSegmentCode(segmentSourceCode: string, { sourceName, compiledName, type, importPath, }: {
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, type, importPath, }) {
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 or workers
20
- const variableDeclaration = sourceFile.getVariableDeclaration(`${type}s`);
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) {
@@ -22,15 +22,13 @@ export default async function newModule({ what, moduleNameWithOptionalSegment, d
22
22
  const { config, log, apiDir, cwd } = await getProjectInfo();
23
23
  let templates = config.templates;
24
24
  const [segmentName, moduleName] = splitByLast(moduleNameWithOptionalSegment);
25
- // replace c by controller, s by service, w by worker, everything else keeps the same
25
+ // replace c by controller, s by service, everything else keeps the same
26
26
  what = what.map((s) => {
27
27
  switch (s) {
28
28
  case 'c':
29
29
  return 'controller';
30
30
  case 's':
31
31
  return 'service';
32
- case 'w':
33
- return 'worker';
34
32
  default:
35
33
  return s;
36
34
  }
@@ -87,12 +85,12 @@ export default async function newModule({ what, moduleNameWithOptionalSegment, d
87
85
  log.info(`Created ${chalkHighlightThing(fileName)} using ${chalkHighlightThing(`"${type}"`)} template for ${formatLoggedSegmentName(segmentName)}`);
88
86
  }
89
87
  }
90
- if (type === 'controller' || type === 'worker') {
88
+ if (type === 'controller') {
91
89
  if (!sourceName) {
92
90
  throw new Error(`The template for "${type}" does not provide a sourceName`);
93
91
  }
94
92
  if (!compiledName) {
95
- throw new Error('The template for "${type}" does not provide a compiledName');
93
+ throw new Error(`The template for "${type}" does not provide a compiledName`);
96
94
  }
97
95
  const { routeFilePath } = segment;
98
96
  const segmentSourceCode = await fs.readFile(routeFilePath, 'utf-8');
@@ -101,7 +99,6 @@ export default async function newModule({ what, moduleNameWithOptionalSegment, d
101
99
  const newSegmentCode = await prettify(addClassToSegmentCode(segmentSourceCode, {
102
100
  sourceName,
103
101
  compiledName,
104
- type,
105
102
  importPath,
106
103
  }), routeFilePath);
107
104
  if (!dryRun) {
@@ -16,14 +16,11 @@ export default async function newSegment({ segmentName, overwrite, dryRun, }) {
16
16
  export const runtime = 'edge';
17
17
 
18
18
  const controllers = {};
19
- const workers = {};
20
19
 
21
20
  export type Controllers = typeof controllers;
22
- export type Workers = typeof workers;
23
21
 
24
22
  export const { GET, POST, PATCH, PUT, HEAD, OPTIONS, DELETE } = initVovk({
25
23
  ${segmentName ? ` segmentName: '${segmentName}',\n` : ''} emitSchema: true,
26
- workers,
27
24
  controllers,
28
25
  });
29
26
  `, absoluteSegmentRoutePath);
@@ -31,5 +28,6 @@ ${segmentName ? ` segmentName: '${segmentName}',\n` : ''} emitSchema: true,
31
28
  await fs.mkdir(path.dirname(absoluteSegmentRoutePath), { recursive: true });
32
29
  await fs.writeFile(absoluteSegmentRoutePath, code);
33
30
  }
34
- log.info(`${formatLoggedSegmentName(segmentName, { upperFirst: true })} created at ${absoluteSegmentRoutePath}. Run ${chalkHighlightThing(`npx vovk n s c ${[segmentName, 'thing'].filter(Boolean).join('/')}`)} to create a new controller with service.`);
31
+ log.info(`${formatLoggedSegmentName(segmentName, { upperFirst: true })} created at ${absoluteSegmentRoutePath}.`);
32
+ log.info(`Run ${chalkHighlightThing(`npx vovk new service controller ${[segmentName, 'thing'].filter(Boolean).join('/')}`)} to create a new controller with a service at /modules/thing/ folder.`);
35
33
  }
package/dist/types.d.mts CHANGED
@@ -4,10 +4,10 @@ export type VovkEnv = {
4
4
  PORT?: string;
5
5
  VOVK_CLIENT_OUT_DIR?: string;
6
6
  VOVK_SCHEMA_OUT_DIR?: string;
7
- VOVK_FETCHER?: string;
8
- VOVK_VALIDATE_ON_CLIENT?: string;
7
+ VOVK_FETCHER_PATH?: string;
8
+ VOVK_VALIDATE_ON_CLIENT_PATH?: string;
9
+ VOVK_CREATE_RPC_PATH?: string;
9
10
  VOVK_MODULES_DIR?: string;
10
- VOVK_VALIDATION_LIBRARY?: string;
11
11
  VOVK_ORIGIN?: string;
12
12
  VOVK_ROOT_ENTRY?: string;
13
13
  VOVK_API_ENTRY_POINT?: string;
@@ -21,10 +21,10 @@ export type VovkEnv = {
21
21
  export type VovkConfig = {
22
22
  clientOutDir?: string;
23
23
  schemaOutDir?: string;
24
- fetcher?: string;
25
- validateOnClient?: string | null;
24
+ fetcherPath?: string;
25
+ validateOnClientPath?: string | null;
26
+ createRPCPath?: string;
26
27
  modulesDir?: string;
27
- validationLibrary?: string | null;
28
28
  rootEntry?: string;
29
29
  origin?: string;
30
30
  rootSegmentModulesDirName?: string;
@@ -35,7 +35,6 @@ export type VovkConfig = {
35
35
  templates?: {
36
36
  service?: string;
37
37
  controller?: string;
38
- worker?: string;
39
38
  [key: string]: string | undefined;
40
39
  };
41
40
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vovk-cli",
3
- "version": "0.0.1-draft.47",
3
+ "version": "0.0.1-draft.48",
4
4
  "bin": {
5
5
  "vovk": "./dist/index.mjs"
6
6
  },
@@ -36,10 +36,10 @@
36
36
  },
37
37
  "homepage": "https://vovk.dev",
38
38
  "peerDependencies": {
39
- "vovk": "^3.0.0-draft.53"
39
+ "vovk": "^3.0.0-draft.57"
40
40
  },
41
41
  "dependencies": {
42
- "@inquirer/prompts": "^7.2.3",
42
+ "@inquirer/prompts": "^7.3.1",
43
43
  "@npmcli/package-json": "^6.1.1",
44
44
  "chalk": "^5.4.1",
45
45
  "chokidar": "^4.0.3",
@@ -1,24 +0,0 @@
1
- <% var modulePascalName = _.upperFirst(_.camelCase(moduleName)); %>
2
- <% var modulePascalNamePlural = pluralize(modulePascalName); %>
3
- <% var workerName = modulePascalName + 'Worker'; %>
4
- <% var compiledName = modulePascalName + 'WPC'; %>
5
- ---
6
- dir: <%= getModuleDirName(segmentName, moduleName) %>
7
- fileName: <%= workerName + '.ts' %>
8
- sourceName: <%= workerName %>
9
- compiledName: <%= compiledName %>
10
- ---
11
- import { worker } from 'vovk';
12
-
13
- @worker()
14
- export default class <%= workerName %> {
15
- static heavyComputation = () => {
16
- return 'Hello, World';
17
- };
18
-
19
- static heavyComputationGenerator = function* () {
20
- for(const str of ['Hello', 'World'] as const) {
21
- yield str;
22
- }
23
- };
24
- }