vovk-cli 0.0.1-draft.393 → 0.0.1-draft.395

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
@@ -7,7 +7,7 @@
7
7
  </picture>
8
8
  </a>
9
9
  <br>
10
- <strong>Back-end for <a href="https://nextjs.org/">Next.js</a></strong>
10
+ <strong>Back-end for Next.js</strong>
11
11
  </p>
12
12
 
13
13
  ---
@@ -5,7 +5,8 @@ import { schema } from './schema<%= t.nodeNextResolutionExt.ts %>';
5
5
  <% if(t.isBundle) { %>
6
6
  import { openapi } from './openapi<%= t.nodeNextResolutionExt.ts %>';
7
7
  <% } else { %>
8
- // TODO: This is a temporary fix https://github.com/rolldown/tsdown/issues/528#issuecomment-3476284358
8
+ // import { openapi } from './openapi<%= t.nodeNextResolutionExt.ts %>';
9
+ // TODO: This is a temporary fix for https://github.com/rolldown/tsdown/issues/528#issuecomment-3476284358
9
10
  import openapi from './openapi.json' with { type: "json" };
10
11
  <% } %>
11
12
  <% Object.values(t.schema.segments).filter((segment) => segment.emitSchema).forEach((segment, i) => { if(segment.segmentType !== 'mixin') { %>
@@ -17,7 +18,7 @@ import type { Controllers as MixinControllers, Mixins } from "./mixins.d.ts";
17
18
  <% } %>
18
19
  <% Object.entries(t.reExports).forEach(([reExportWhat, reExportFrom]) => { %>
19
20
  export { <%= reExportWhat %> } from '<%= reExportFrom %>';
20
- <% }) %>
21
+ <% }) %>
21
22
  <% Object.values(t.schema.segments).filter((segment) => segment.emitSchema).forEach((segment, i) => {
22
23
  Object.keys(segment.controllers).forEach((rpcModuleName) => {
23
24
  const apiRoot = t.segmentMeta[segment.segmentName].forceApiRoot ?? t.apiRoot; %>
@@ -31,6 +31,8 @@ export async function bundle({ projectInfo, fullSchema, cliBundleOptions, }) {
31
31
  openapiGetModuleName: cliBundleOptions?.openapiGetModuleName,
32
32
  openapiGetMethodName: cliBundleOptions?.openapiGetMethodName,
33
33
  openapiRootUrl: cliBundleOptions?.openapiRootUrl,
34
+ openapiMixinName: cliBundleOptions?.openapiMixinName,
35
+ openapiFallback: cliBundleOptions?.openapiFallback,
34
36
  composedFrom: [BuiltInTemplateName.ts],
35
37
  composedOut: prebundleOutDirAbsolute,
36
38
  composedOnly: true,
@@ -285,7 +285,7 @@ export class VovkDev {
285
285
  segments: this.#schemaSegments,
286
286
  meta: getMetaSchema({
287
287
  config: this.#projectInfo.config,
288
- useEmitConfig: false,
288
+ useexposeConfigKeys: false,
289
289
  }),
290
290
  };
291
291
  return generate({
@@ -7,7 +7,7 @@ export default async function writeMetaJson(schemaOutAbsolutePath, projectInfo)
7
7
  const metaJsonPath = path.join(schemaOutAbsolutePath, META_FILE_NAME + '.json');
8
8
  const metaStr = JSON.stringify(getMetaSchema({
9
9
  config: projectInfo.config,
10
- useEmitConfig: true,
10
+ useexposeConfigKeys: true,
11
11
  }), null, 2);
12
12
  const existingStr = await fs.readFile(metaJsonPath, 'utf-8').catch(() => null);
13
13
  if (existingStr !== metaStr) {
@@ -21,7 +21,7 @@ export default async function ensureClient(projectInfo, locatedSegments) {
21
21
  fullSchema: {
22
22
  $schema: VovkSchemaIdEnum.SCHEMA,
23
23
  segments: getEmptySegmentRecordSchema(locatedSegments.map(({ segmentName }) => segmentName)),
24
- meta: getMetaSchema({ config: projectInfo.config, useEmitConfig: false }),
24
+ meta: getMetaSchema({ config: projectInfo.config, useexposeConfigKeys: false }),
25
25
  },
26
26
  locatedSegments,
27
27
  });
@@ -11,7 +11,7 @@ export async function getProjectFullSchema({ schemaOutAbsolutePath, isNextInstal
11
11
  segments: {},
12
12
  meta: getMetaSchema({
13
13
  config,
14
- useEmitConfig: false,
14
+ useexposeConfigKeys: false,
15
15
  }),
16
16
  };
17
17
  const isEmptyLogOrWarn = isNextInstalled ? log.warn : log.debug;
@@ -4,7 +4,6 @@ import { ROOT_SEGMENT_FILE_NAME } from '../dev/writeOneSegmentSchemaFile.mjs';
4
4
  export default function getTemplateClientImports({ config, fullSchema, outCwdRelativeDir, segmentName, isBundle, outputConfigs, }) {
5
5
  const { imports: configImports } = resolveGeneratorConfigValues({
6
6
  config,
7
- schema: fullSchema,
8
7
  segmentName,
9
8
  isBundle,
10
9
  projectPackageJson: undefined,
@@ -61,7 +61,7 @@ templateContent, matterResult: { data, content }, openAPIObject, package: packag
61
61
  YAML,
62
62
  TOML,
63
63
  getFirstLineBanner,
64
- publicMeta: getMetaSchema({ config: projectConfig, useEmitConfig: true }),
64
+ publicMeta: getMetaSchema({ config: projectConfig, useexposeConfigKeys: true }),
65
65
  nodeNextResolutionExt: {
66
66
  ts: isNodeNextResolution ? '.ts' : '',
67
67
  js: isNodeNextResolution ? '.js' : '',
@@ -10,13 +10,13 @@ export default function getConfig({ configPath, cwd, logLevel, }: {
10
10
  configAbsolutePaths: string[];
11
11
  userConfig: {
12
12
  $schema?: typeof VovkSchemaIdEnum.CONFIG | (string & {});
13
- emitConfig?: boolean | (keyof VovkStrictConfig | (string & {}))[];
13
+ exposeConfigKeys?: boolean | (keyof VovkStrictConfig | (string & {}))[];
14
14
  schemaOutDir?: string;
15
15
  modulesDir?: string;
16
16
  rootEntry?: string;
17
17
  logLevel?: "error" | "trace" | "debug" | "info" | "warn" | (string & {});
18
18
  libs?: {
19
- ajv: import("vovk").KnownAny;
19
+ ajv?: import("vovk").KnownAny;
20
20
  [key: string]: import("vovk").KnownAny;
21
21
  };
22
22
  devHttps?: boolean;
@@ -20,7 +20,7 @@ export default async function getConfig({ configPath, cwd, logLevel, }) {
20
20
  const config = {
21
21
  $schema: VovkSchemaIdEnum.CONFIG,
22
22
  clientTemplateDefs,
23
- emitConfig: [],
23
+ exposeConfigKeys: [],
24
24
  composedClient: {
25
25
  ...conf.composedClient,
26
26
  enabled: conf.composedClient?.enabled ?? true,
@@ -76,15 +76,15 @@ export default async function getConfig({ configPath, cwd, logLevel, }) {
76
76
  ]))),
77
77
  },
78
78
  };
79
- if (typeof conf.emitConfig === 'undefined') {
80
- config.emitConfig = ['libs'];
79
+ if (typeof conf.exposeConfigKeys === 'undefined') {
80
+ config.exposeConfigKeys = ['libs'];
81
81
  }
82
- else if (conf.emitConfig === true) {
83
- config.emitConfig = Object.keys(config);
82
+ else if (conf.exposeConfigKeys === true) {
83
+ config.exposeConfigKeys = Object.keys(config);
84
84
  }
85
- else if (Array.isArray(conf.emitConfig)) {
86
- config.emitConfig = conf.emitConfig;
87
- } // else it's false and emitConfig already is []
85
+ else if (Array.isArray(conf.exposeConfigKeys)) {
86
+ config.exposeConfigKeys = conf.exposeConfigKeys;
87
+ } // else it's false and exposeConfigKeys already is []
88
88
  if (!userConfig) {
89
89
  log.warn(`Unable to load config at ${chalkHighlightThing(cwd)}. Using default values. ${error ?? ''}`);
90
90
  }
@@ -1,7 +1,7 @@
1
1
  import { VovkSchemaIdEnum, type VovkStrictConfig } from 'vovk';
2
- export default function getMetaSchema({ config, useEmitConfig }: {
2
+ export default function getMetaSchema({ config, useexposeConfigKeys, }: {
3
3
  config: VovkStrictConfig;
4
- useEmitConfig: boolean;
4
+ useexposeConfigKeys: boolean;
5
5
  }): {
6
6
  config: VovkStrictConfig;
7
7
  $schema: VovkSchemaIdEnum;
@@ -2,11 +2,11 @@ import { VovkSchemaIdEnum } from 'vovk';
2
2
  import pick from 'lodash/pick.js';
3
3
  import mapValues from 'lodash/mapValues.js';
4
4
  import omit from 'lodash/omit.js';
5
- export default function getMetaSchema({ config, useEmitConfig }) {
5
+ export default function getMetaSchema({ config, useexposeConfigKeys, }) {
6
6
  return {
7
7
  $schema: VovkSchemaIdEnum.META,
8
8
  ...{
9
- config: useEmitConfig
9
+ config: useexposeConfigKeys
10
10
  ? (config
11
11
  ? pick({
12
12
  ...config,
@@ -19,7 +19,7 @@ export default function getMetaSchema({ config, useEmitConfig }) {
19
19
  : undefined,
20
20
  }
21
21
  : undefined,
22
- }, [...config.emitConfig, '$schema'])
22
+ }, [...config.exposeConfigKeys, '$schema'])
23
23
  : {})
24
24
  : config,
25
25
  },
package/dist/index.mjs CHANGED
@@ -94,13 +94,13 @@ program
94
94
  .option('--schema, --schema-path <path>', 'path to schema folder (default: ./.vovk-schema)')
95
95
  .option('--config, --config-path <config>', 'path to config file')
96
96
  .option('--origin <url>', 'set the origin URL for the generated client')
97
- .option('--watch [s]', 'watch for changes in schema or openapi spec and regenerate client; accepts a number in seconds to throttle the watcher or make an HTTP request to the OpenAPI spec URL')
98
- .option('--openapi, --openapi-spec <openapi_path_or_urls...>', 'use OpenAPI schema for client generation')
99
- .option('--openapi-module-name, --openapi-get-module-name <names...>', 'module names corresponding to the index of --openapi option')
100
- .option('--openapi-method-name, --openapi-get-method-name <names...>', 'method names corresponding to the index of --openapi option')
97
+ .option('--watch [s]', 'watch for changes in schema or openapi spec and regenerate client; accepts a number in seconds to throttle the watcher or make an HTTP request to the OpenAPI spec URLs')
98
+ .option('--openapi, --openapi-spec <openapi_path_or_urls...>', 'use OpenAPI mixins for client generation')
99
+ .option('--openapi-module-name, --openapi-get-module-name <names...>', 'module name strategies corresponding to the index of --openapi option')
100
+ .option('--openapi-method-name, --openapi-get-method-name <names...>', 'method name strategies corresponding to the index of --openapi option')
101
101
  .option('--openapi-root-url <urls...>', 'root URLs corresponding to the index of --openapi option')
102
102
  .option('--openapi-mixin-name <names...>', 'mixin names corresponding to the index of --openapi option')
103
- .option('--openapi-fallback <paths...>', 'save OpenAPI spec and use it as a fallback if URL is not available')
103
+ .option('--openapi-fallback <paths...>', 'save OpenAPI spec corresponding to the index of --openapi option to a local file and use it as a fallback if URL is not available')
104
104
  .option('--log-level <level>', 'set the log level')
105
105
  .action(async (cliGenerateOptions) => {
106
106
  const projectInfo = await getProjectInfo({
@@ -126,10 +126,12 @@ program
126
126
  .option('--schema, --schema-path <path>', 'path to schema folder (default: .vovk-schema)')
127
127
  .option('--config, --config-path <config>', 'path to config file')
128
128
  .option('--origin <url>', 'set the origin URL for the generated client')
129
- .option('--openapi, --openapi-spec <openapi_path_or_urls...>', 'use OpenAPI schema instead of Vovk schema')
130
- .option('--openapi-get-module-name <names...>', 'module names corresponding to the index of --openapi option')
131
- .option('--openapi-get-method-name <names...>', 'method names corresponding to the index of --openapi option')
129
+ .option('--openapi, --openapi-spec <openapi_path_or_urls...>', 'use OpenAPI mixins for client generation')
130
+ .option('--openapi-module-name, --openapi-get-module-name <names...>', 'module name strategies corresponding to the index of --openapi option')
131
+ .option('--openapi-method-name, --openapi-get-method-name <names...>', 'method name strategies corresponding to the index of --openapi option')
132
132
  .option('--openapi-root-url <urls...>', 'root URLs corresponding to the index of --openapi option')
133
+ .option('--openapi-mixin-name <names...>', 'mixin names corresponding to the index of --openapi option')
134
+ .option('--openapi-fallback <paths...>', 'save OpenAPI spec corresponding to the index of --openapi option to a local file and use it as a fallback if URL is not available')
133
135
  .option('--log-level <level>', 'set the log level')
134
136
  .action(async (cliBundleOptions) => {
135
137
  const projectInfo = await getProjectInfo({
@@ -139,7 +141,7 @@ program
139
141
  });
140
142
  const { cwd, config, log, isNextInstalled } = projectInfo;
141
143
  const fullSchema = await getProjectFullSchema({
142
- schemaOutAbsolutePath: path.resolve(cwd, cliBundleOptions?.schema ?? config.schemaOutDir),
144
+ schemaOutAbsolutePath: path.resolve(cwd, cliBundleOptions?.schemaPath ?? config.schemaOutDir),
143
145
  log,
144
146
  isNextInstalled,
145
147
  config,
@@ -81,6 +81,7 @@ export class Init {
81
81
  }
82
82
  if (!dryRun && pkgJson) {
83
83
  let depsUpdated = false;
84
+ const packageManager = getPackageManager({ useNpm, useYarn, usePnpm, useBun, pkgJson });
84
85
  try {
85
86
  await updateDependenciesWithoutInstalling({
86
87
  log,
@@ -96,17 +97,13 @@ export class Init {
96
97
  logUpdateDependenciesError({
97
98
  log,
98
99
  error,
99
- useNpm,
100
- useYarn,
101
- usePnpm,
102
- useBun,
100
+ packageManager,
103
101
  dependencies,
104
102
  devDependencies,
105
103
  channel,
106
104
  });
107
105
  }
108
106
  if (depsUpdated) {
109
- const packageManager = getPackageManager({ useNpm, useYarn, usePnpm, useBun });
110
107
  if (skipInstall) {
111
108
  log.info(`Installation skipped. Please, install them manually with ${chalkHighlightThing(packageManager + ' install')}`);
112
109
  }
@@ -115,12 +112,7 @@ export class Init {
115
112
  await installDependencies({
116
113
  log,
117
114
  cwd: root,
118
- options: {
119
- useNpm,
120
- useYarn,
121
- usePnpm,
122
- useBun,
123
- },
115
+ packageManager,
124
116
  });
125
117
  log.info('Dependencies installed successfully');
126
118
  }
@@ -1,10 +1,12 @@
1
+ import NPMCliPackageJson from '@npmcli/package-json';
1
2
  import getLogger from '../utils/getLogger.mjs';
2
3
  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;
5
- export default function installDependencies({ log, cwd, options, }: {
4
+ export type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun';
5
+ export declare function getPackageManager(options: Pick<InitOptions, 'useNpm' | 'useYarn' | 'usePnpm' | 'useBun'> & {
6
+ pkgJson: NPMCliPackageJson;
7
+ }): PackageManager;
8
+ export default function installDependencies({ log, cwd, packageManager, }: {
6
9
  log: ReturnType<typeof getLogger>;
7
10
  cwd: string;
8
- options: Pick<InitOptions, 'useNpm' | 'useYarn' | 'usePnpm' | 'useBun'>;
11
+ packageManager: PackageManager;
9
12
  }): Promise<void>;
10
- export {};
@@ -9,10 +9,10 @@ export function getPackageManager(options) {
9
9
  return 'pnpm';
10
10
  if (options.useBun)
11
11
  return 'bun';
12
- return 'npm'; // Default to npm if no options are true
12
+ const packageManager = options.pkgJson.content?.['packageManager'];
13
+ return packageManager ? packageManager.split('@')[0] : 'npm'; // Default to npm if no options are true
13
14
  }
14
- export default async function installDependencies({ log, cwd, options, }) {
15
- const packageManager = getPackageManager(options);
15
+ export default async function installDependencies({ log, cwd, packageManager, }) {
16
16
  log.info(`Installing dependencies at ${chalkHighlightThing(cwd)} using ${chalkHighlightThing(packageManager)}...`);
17
17
  await new Promise((resolve, reject) => {
18
18
  const args = packageManager === 'yarn' ? ['install', '--non-interactive'] : ['install'];
@@ -1,10 +1,8 @@
1
1
  import type { InitOptions } from '../types.mjs';
2
2
  import type getLogger from '../utils/getLogger.mjs';
3
- export default function logUpdateDependenciesError({ useNpm, useYarn, usePnpm, useBun, log, dependencies, devDependencies, error, channel, }: {
4
- useNpm?: boolean;
5
- useYarn?: boolean;
6
- usePnpm?: boolean;
7
- useBun?: boolean;
3
+ import type { PackageManager } from './installDependencies.mjs';
4
+ export default function logUpdateDependenciesError({ packageManager, log, dependencies, devDependencies, error, channel, }: {
5
+ packageManager: PackageManager;
8
6
  log: ReturnType<typeof getLogger>;
9
7
  dependencies: string[];
10
8
  devDependencies: string[];
@@ -1,7 +1,5 @@
1
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, channel, }) {
4
- const packageManager = getPackageManager({ useNpm, useYarn, usePnpm, useBun });
2
+ export default function logUpdateDependenciesError({ packageManager, log, dependencies, devDependencies, error, channel, }) {
5
3
  const installCommands = [];
6
4
  const addChannel = (packageName) => {
7
5
  const isVovk = packageName.startsWith('vovk') && packageName !== 'dto-mapped-types';
@@ -21,7 +21,7 @@ function splitByLast(str, delimiter = '/') {
21
21
  return [before, after];
22
22
  }
23
23
  export default async function newModule({ projectInfo, what, moduleNameWithOptionalSegment, dryRun, outDir: outDirFlag, templates: templatesFlag, noSegmentUpdate, overwrite, empty, }) {
24
- const { config, log, cwd, apiDirAbsolutePath } = projectInfo;
24
+ const { config, log, cwd, apiDirAbsolutePath, srcRoot } = projectInfo;
25
25
  const segments = await locateSegments({ dir: apiDirAbsolutePath, config, log });
26
26
  const isNodeNextResolution = ['node16', 'nodenext'].includes((await getTsconfig(cwd)?.config?.compilerOptions?.moduleResolution?.toLowerCase()) ?? '');
27
27
  let templates = config.moduleTemplates;
@@ -61,6 +61,7 @@ export default async function newModule({ projectInfo, what, moduleNameWithOptio
61
61
  const templateCode = await fs.readFile(templateAbsolutePath, 'utf-8');
62
62
  const { outDir: renderedOutDir, fileName, sourceName, compiledName, code, } = await render(templateCode, {
63
63
  cwd,
64
+ srcRoot,
64
65
  config,
65
66
  withService: what.includes('service'),
66
67
  segmentName,
@@ -1,6 +1,6 @@
1
1
  import type { VovkStrictConfig } from 'vovk';
2
2
  import type { VovkModuleRenderResult } from '../types.mjs';
3
- export default function render(codeTemplate: string, { config, withService, segmentName, moduleName, empty, templateFileName, isNodeNextResolution, }: {
3
+ export default function render(codeTemplate: string, { cwd, config, withService, segmentName, moduleName, empty, templateFileName, isNodeNextResolution, srcRoot, }: {
4
4
  cwd: string;
5
5
  config: VovkStrictConfig;
6
6
  withService: boolean;
@@ -9,4 +9,5 @@ export default function render(codeTemplate: string, { config, withService, segm
9
9
  empty?: boolean;
10
10
  templateFileName: string;
11
11
  isNodeNextResolution: boolean;
12
+ srcRoot: string | null;
12
13
  }): Promise<VovkModuleRenderResult>;
@@ -3,11 +3,13 @@ import matter from 'gray-matter';
3
3
  import _ from 'lodash';
4
4
  import pluralize from 'pluralize';
5
5
  import addCommonTerms from './addCommonTerms.mjs';
6
+ import path from 'node:path';
6
7
  addCommonTerms();
7
- export default async function render(codeTemplate, { config, withService, segmentName, moduleName, empty, templateFileName, isNodeNextResolution, }) {
8
- const getModuleDirName = (givenSegmentName, givenModuleName) => [config.modulesDir, givenSegmentName || config.rootSegmentModulesDirName, _.camelCase(givenModuleName)]
8
+ export default async function render(codeTemplate, { cwd, config, withService, segmentName, moduleName, empty, templateFileName, isNodeNextResolution, srcRoot, }) {
9
+ const defaultOutDir = [config.modulesDir, segmentName || config.rootSegmentModulesDirName, _.camelCase(moduleName)]
9
10
  .filter(Boolean)
10
11
  .join('/');
12
+ const relativePathToSourceRoot = path.relative(path.resolve(cwd, defaultOutDir), path.join(cwd, srcRoot ?? '.')) || '.';
11
13
  const theThing = _.camelCase(moduleName);
12
14
  const TheThing = _.upperFirst(theThing);
13
15
  const the_thing = _.snakeCase(moduleName);
@@ -36,7 +38,8 @@ export default async function render(codeTemplate, { config, withService, segmen
36
38
  cjs: isNodeNextResolution ? '.cjs' : '',
37
39
  mjs: isNodeNextResolution ? '.mjs' : '',
38
40
  },
39
- defaultOutDir: getModuleDirName(segmentName, theThing),
41
+ defaultOutDir,
42
+ relativePathToSourceRoot,
40
43
  // libraries
41
44
  _, // lodash
42
45
  pluralize,
package/dist/types.d.mts CHANGED
@@ -43,7 +43,6 @@ export interface BundleOptions extends Partial<Pick<VovkStrictConfig['bundle'],
43
43
  bundler?: 'tsdown' | 'ncc';
44
44
  configPath?: string;
45
45
  schemaPath?: string;
46
- schema?: string;
47
46
  outDir?: string;
48
47
  origin?: string;
49
48
  openapiSpec?: string[];
@@ -51,6 +50,7 @@ export interface BundleOptions extends Partial<Pick<VovkStrictConfig['bundle'],
51
50
  openapiGetMethodName?: string[];
52
51
  openapiRootUrl?: string[];
53
52
  openapiMixinName?: string[];
53
+ openapiFallback?: string[];
54
54
  logLevel?: LogLevelNames;
55
55
  }
56
56
  export interface InitOptions {
@@ -11,7 +11,7 @@ compiledName: <%= t.TheThing + 'RPC' %>
11
11
 
12
12
  import { prefix, get, put, post, del, operation } from 'vovk';
13
13
  import { type } from 'arktype';
14
- import withArk from '@/lib/withArk<%= t.nodeNextResolutionExt.ts %>';
14
+ import withArk from '<%= t.relativePathToSourceRoot %>/lib/withArk<%= t.nodeNextResolutionExt.ts %>';
15
15
  <% if(t.withService) { %>
16
16
  import <%= vars.ServiceName %> from './<%= vars.ServiceName %><%= t.nodeNextResolutionExt.ts %>';
17
17
  <% } %>
@@ -32,6 +32,21 @@ export default class <%= vars.ModuleName %> {
32
32
  }
33
33
  });
34
34
 
35
+ @operation({
36
+ summary: 'Get single <%= t.TheThing %>',
37
+ })
38
+ @get('{id}')
39
+ static getSingle<%= t.TheThing %> = withArk({
40
+ params: type({ id: type('string') }),
41
+ handle(_req, { id }) {
42
+ <% if(t.withService) { %>
43
+ return <%= vars.ServiceName %>.getSingle<%= t.TheThing %>(id);
44
+ <% } else { %>
45
+ return { message: 'TODO: get single <%= t.theThing %>', id };
46
+ <% } %>
47
+ }
48
+ });
49
+
35
50
  @operation({
36
51
  summary: 'Update <%= t.TheThing %>',
37
52
  })
@@ -39,8 +54,7 @@ export default class <%= vars.ModuleName %> {
39
54
  static update<%= t.TheThing %> = withArk({
40
55
  body: type({ todo: type('true') }),
41
56
  params: type({ id: type('string') }),
42
- async handle(req, params) {
43
- const { id } = params;
57
+ async handle(req, { id }) {
44
58
  const body = await req.json();
45
59
  <% if(t.withService) { %>
46
60
  return <%= vars.ServiceName %>.update<%= t.TheThing %>(id, body);
@@ -26,7 +26,19 @@ export default class <%= vars.ControllerName %> {
26
26
  <% } else { %>
27
27
  return { message: 'TODO: get <%= t.theThings %>' };
28
28
  <% } %>
29
- }
29
+ };
30
+
31
+ @operation({
32
+ summary: 'Get single <%= t.TheThing %>',
33
+ })
34
+ @get('{id}')
35
+ static getSingle<%= t.TheThing %> = (_req: VovkRequest, { id }: { id: string }) => {
36
+ <% if(t.withService) { %>
37
+ return <%= vars.ServiceName %>.getSingle<%= t.TheThing %>(id);
38
+ <% } else { %>
39
+ return { message: 'TODO: get single <%= t.theThing %>', id };
40
+ <% } %>
41
+ };
30
42
 
31
43
  @operation({
32
44
  summary: 'Update <%= t.TheThing %>',
@@ -16,6 +16,12 @@ export default class <%= vars.ServiceName %> {
16
16
  return { message: 'TODO: get <%= t.theThings %>' };
17
17
  };
18
18
 
19
+ static getSingle<%= t.TheThing %> = (
20
+ id: VovkParams<typeof <%= vars.ControllerName %>.getSingle<%= t.TheThing %>>['id']
21
+ ) => {
22
+ return { message: 'TODO: get single <%= t.theThing %>', id };
23
+ }
24
+
19
25
  static update<%= t.TheThing %> = (
20
26
  id: VovkParams<typeof <%= vars.ControllerName %>.update<%= t.TheThing %>>['id'],
21
27
  body: VovkBody<typeof <%= vars.ControllerName %>.update<%= t.TheThing %>>
@@ -11,7 +11,7 @@ compiledName: <%= t.TheThing + 'RPC' %>
11
11
 
12
12
  import { prefix, get, put, post, del, operation } from 'vovk';
13
13
  import * as v from 'valibot';
14
- import withValibot from '@/lib/withValibot<%= t.nodeNextResolutionExt.ts %>';
14
+ import withValibot from '<%= t.relativePathToSourceRoot %>/lib/withValibot<%= t.nodeNextResolutionExt.ts %>';
15
15
  <% if(t.withService) { %>
16
16
  import <%= vars.ServiceName %> from './<%= vars.ServiceName %><%= t.nodeNextResolutionExt.ts %>';
17
17
  <% } %>
@@ -32,6 +32,21 @@ export default class <%= vars.ModuleName %> {
32
32
  }
33
33
  });
34
34
 
35
+ @operation({
36
+ summary: 'Get single <%= t.TheThing %>',
37
+ })
38
+ @get('{id}')
39
+ static getSingle<%= t.TheThing %> = withValibot({
40
+ params: v.object({ id: v.string() }),
41
+ handle(_req, { id }) {
42
+ <% if(t.withService) { %>
43
+ return <%= vars.ServiceName %>.getSingle<%= t.TheThing %>(id);
44
+ <% } else { %>
45
+ return { message: `TODO: get single <%= t.theThing %>`, id };
46
+ <% } %>
47
+ }
48
+ });
49
+
35
50
  @operation({
36
51
  summary: 'Update <%= t.TheThing %>',
37
52
  })
@@ -39,8 +54,7 @@ export default class <%= vars.ModuleName %> {
39
54
  static update<%= t.TheThing %> = withValibot({
40
55
  body: v.object({ todo: v.literal(true) }),
41
56
  params: v.object({ id: v.string() }),
42
- async handle(req, params) {
43
- const { id } = params;
57
+ async handle(req, { id }) {
44
58
  const body = await req.json();
45
59
  <% if(t.withService) { %>
46
60
  return <%= vars.ServiceName %>.update<%= t.TheThing %>(id, body);
@@ -66,8 +80,7 @@ export default class <%= vars.ModuleName %> {
66
80
  @del('{id}')
67
81
  static delete<%= t.TheThing %> = withValibot({
68
82
  params: v.object({ id: v.string() }),
69
- handle(_req, params) {
70
- const { id } = params;
83
+ handle(_req, { id }) {
71
84
  <% if(t.withService) { %>
72
85
  return <%= vars.ServiceName %>.delete<%= t.TheThing %>(id);
73
86
  <% } else { %>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vovk-cli",
3
- "version": "0.0.1-draft.393",
3
+ "version": "0.0.1-draft.395",
4
4
  "bin": {
5
5
  "vovk": "./dist/index.mjs"
6
6
  },
@@ -35,11 +35,11 @@
35
35
  },
36
36
  "homepage": "https://vovk.dev",
37
37
  "peerDependencies": {
38
- "vovk": "^3.0.0-draft.469",
39
- "vovk-ajv": "^0.0.0-draft.112",
40
- "vovk-client": "^0.0.4-draft.139",
41
- "vovk-python": "^0.0.1-draft.81",
42
- "vovk-rust": "^0.0.1-draft.67"
38
+ "vovk": "^3.0.0-draft.471",
39
+ "vovk-ajv": "^0.0.0-draft.113",
40
+ "vovk-client": "^0.0.4-draft.140",
41
+ "vovk-python": "^0.0.1-draft.82",
42
+ "vovk-rust": "^0.0.1-draft.68"
43
43
  },
44
44
  "optionalDependencies": {
45
45
  "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.44"
@@ -83,7 +83,7 @@
83
83
  "create-next-app": "^15.5.4",
84
84
  "http-server": "^14.1.1",
85
85
  "node-pty": "^1.0.0",
86
- "tsdown": "^0.15.9",
86
+ "tsdown": "^0.16.0",
87
87
  "zod": "^4.1.11"
88
88
  }
89
89
  }