vovk-cli 0.0.1-draft.340 → 0.0.1-draft.341

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.
@@ -1,7 +1,7 @@
1
1
  <%- t.getFirstLineBanner() %>
2
2
  const { createRPC } = require('<%= t.commonImports.createRPC %>');
3
3
  const { schema } = require('./schema.cjs');
4
- const openapi = require('./openapi.cjs');
4
+ const { openapi } = require('./openapi.cjs');
5
5
  const { validateOnClient = null } = <%- t.imports.validateOnClient ? `require('${t.imports.validateOnClient}')` : '{}'%>;
6
6
  <% Object.values(t.schema.segments).filter((segment) => segment.emitSchema).forEach((segment) => { %>
7
7
  <% Object.entries(t.segmentMeta[segment.segmentName].reExports).forEach(([reExportWhatCommaDivisible, reExportFrom]) => {
@@ -12,7 +12,7 @@ exports['<%= reExportWhat.split(/\s+as\s+/)[1] ?? reExportWhat %>'] = require('<
12
12
  <% Object.keys(segment.controllers).forEach((rpcModuleName) => { %>
13
13
  exports.<%= rpcModuleName %> = createRPC(
14
14
  schema, '<%= segment.segmentName %>', '<%= rpcModuleName %>', require('<%= t.segmentImports[segment.segmentName].fetcher %>').fetcher,
15
- { validateOnClient: <%= t.segmentImports[segment.segmentName].validateOnClient ? `require('${t.segmentImports[segment.segmentName].validateOnClient}').validateOnClient` : 'undefined' %>, <%- typeof t.segmentMeta[segment.segmentName].segmentNameOverride === 'string' ? `segmentNameOverride: '${t.segmentMeta[segment.segmentName].segmentNameOverride}', ` : '' %><%- segment.segmentType === 'mixin' ? '' : `apiRoot: '${t.segmentMeta[segment.segmentName].forceApiRoot ?? t.apiRoot}'` %> }
15
+ { validateOnClient: <%- t.segmentImports[segment.segmentName].validateOnClient ? `require('${t.segmentImports[segment.segmentName].validateOnClient}').validateOnClient` : 'undefined' %>, <%- typeof t.segmentMeta[segment.segmentName].segmentNameOverride === 'string' ? `segmentNameOverride: '${t.segmentMeta[segment.segmentName].segmentNameOverride}', ` : '' %><%- segment.segmentType === 'mixin' ? '' : `apiRoot: '${t.segmentMeta[segment.segmentName].forceApiRoot ?? t.apiRoot}'` %> }
16
16
  );
17
17
  <% })
18
18
  }) %>
@@ -2,7 +2,7 @@
2
2
  import type { VovkClientFetcher } from 'vovk';
3
3
  import { createRPC } from '<%= t.commonImports.module.createRPC %>';
4
4
  import { schema } from './schema<%= t.nodeNextResolutionExt.ts %>';
5
- import { openapi } from './openapi<%= t.nodeNextResolutionExt.cjs %>';
5
+ import { openapi } from './openapi<%= t.nodeNextResolutionExt.ts %>';
6
6
  <% Object.values(t.schema.segments).filter((segment) => segment.emitSchema).forEach((segment, i) => { if(segment.segmentType !== 'mixin') { %>
7
7
  import type { Controllers as Controllers<%= i %> } from "<%= t.segmentMeta[segment.segmentName].segmentImportPath %>";
8
8
  <% }
@@ -30,6 +30,7 @@ export async function bundle({ projectInfo, fullSchema, cliBundleOptions, }) {
30
30
  fullSchema,
31
31
  locatedSegments,
32
32
  cliGenerateOptions: {
33
+ schemaPath: cliBundleOptions?.schemaPath,
33
34
  origin: cliBundleOptions?.origin,
34
35
  openapiSpec: cliBundleOptions?.openapiSpec,
35
36
  openapiGetModuleName: cliBundleOptions?.openapiGetModuleName,
@@ -63,6 +64,16 @@ export async function bundle({ projectInfo, fullSchema, cliBundleOptions, }) {
63
64
  tsconfig,
64
65
  });
65
66
  log.debug(`Bundled schema.ts to ${chalkHighlightThing(outDirAbsolute)}`);
67
+ await build({
68
+ entry: path.join(tsFullClientOutAbsoluteDirInput, './openapi.ts'),
69
+ dts: true,
70
+ format: ['cjs'],
71
+ fixedExtension: true,
72
+ outDir: outDirAbsolute,
73
+ clean: false,
74
+ tsconfig,
75
+ });
76
+ log.debug(`Bundled openapi.ts to ${chalkHighlightThing(outDirAbsolute)}`);
66
77
  const requiresGroup = groupBy(Object.entries(bundleConfig.requires), ([, relativePath]) => relativePath);
67
78
  for (const [relativePath, group] of Object.entries(requiresGroup)) {
68
79
  await generate({
@@ -72,6 +83,7 @@ export async function bundle({ projectInfo, fullSchema, cliBundleOptions, }) {
72
83
  fullSchema,
73
84
  locatedSegments,
74
85
  cliGenerateOptions: {
86
+ schemaPath: cliBundleOptions?.schemaPath,
75
87
  origin: cliBundleOptions?.origin,
76
88
  composedFrom: group.map(([templateName]) => templateName),
77
89
  composedOut: path.resolve(outDirAbsolute, relativePath),
@@ -94,7 +94,9 @@ export async function generate({ isEnsuringClient = false, isBundle = false, pro
94
94
  .map((segment) => ({ ...segment }))),
95
95
  };
96
96
  const { config, cwd, log, srcRoot, vovkCliPackage } = projectInfo;
97
- Object.entries(config.generatorConfig.segments ?? {}).forEach(([segmentName, segmentConfig]) => {
97
+ Object.entries(config.generatorConfig.segments ?? {})
98
+ .filter(([, segmentConfig]) => segmentConfig.openAPIMixin)
99
+ .forEach(([segmentName, segmentConfig]) => {
98
100
  fullSchema.segments = {
99
101
  ...fullSchema.segments,
100
102
  [segmentName]: openAPIToVovkSchema({ ...segmentConfig.openAPIMixin, segmentName }).segments[segmentName],
@@ -172,6 +174,7 @@ export async function generate({ isEnsuringClient = false, isBundle = false, pro
172
174
  isBundle,
173
175
  origin: cliGenerateOptions?.origin ?? origin,
174
176
  configKey: 'composedClient',
177
+ cliSchemaPath: cliGenerateOptions?.schemaPath ?? null,
175
178
  });
176
179
  const outAbsoluteDir = path.resolve(cwd, outCwdRelativeDir);
177
180
  return {
@@ -253,6 +256,7 @@ export async function generate({ isEnsuringClient = false, isBundle = false, pro
253
256
  isBundle,
254
257
  origin: cliGenerateOptions?.origin ?? origin,
255
258
  configKey: 'segmentedClient',
259
+ cliSchemaPath: cliGenerateOptions?.schemaPath ?? null,
256
260
  });
257
261
  return {
258
262
  written,
@@ -2,7 +2,17 @@ import path from 'node:path';
2
2
  import { getGeneratorConfig } from 'vovk';
3
3
  import { ROOT_SEGMENT_FILE_NAME } from '../dev/writeOneSegmentSchemaFile.mjs';
4
4
  export default function getTemplateClientImports({ fullSchema, outCwdRelativeDir, segmentName, isBundle, }) {
5
- const { imports } = getGeneratorConfig({ schema: fullSchema, segmentName, isBundle });
5
+ const { imports: configImports } = getGeneratorConfig({ schema: fullSchema, segmentName, isBundle });
6
+ const validateOnClientImport = configImports?.validateOnClient ?? null;
7
+ const fetcherImport = configImports?.fetcher ?? 'vovk';
8
+ const createRPCImport = configImports?.createRPC ?? 'vovk';
9
+ const imports = {
10
+ fetcher: typeof fetcherImport === 'string' ? [fetcherImport] : fetcherImport,
11
+ validateOnClient: typeof validateOnClientImport === 'string'
12
+ ? [validateOnClientImport]
13
+ : (validateOnClientImport ?? null),
14
+ createRPC: typeof createRPCImport === 'string' ? [createRPCImport] : createRPCImport,
15
+ };
6
16
  const getImportPath = (p, s = '') => p.startsWith('.') ? path.relative(path.join(outCwdRelativeDir, s), p) : p;
7
17
  const clientImports = {
8
18
  composedClient: {
@@ -5,7 +5,7 @@ import type { ClientTemplateFile } from './getClientTemplateFiles.mjs';
5
5
  import type { Segment } from '../locateSegments.mjs';
6
6
  import { OpenAPIObject } from 'openapi3-ts/oas31';
7
7
  export declare function normalizeOutTemplatePath(out: string, packageJson: PackageJson): string;
8
- export default function writeOneClientFile({ cwd, projectInfo, clientTemplateFile, fullSchema, prettifyClient, segmentName, templateContent, matterResult: { data, content }, openapi, package: packageJson, readme, snippets, isEnsuringClient, outCwdRelativeDir, locatedSegments, isNodeNextResolution, hasMixins, isVovkProject, vovkCliPackage, isBundle, origin, configKey, }: {
8
+ export default function writeOneClientFile({ cwd, projectInfo, clientTemplateFile, fullSchema, prettifyClient, segmentName, templateContent, matterResult: { data, content }, openapi, package: packageJson, readme, snippets, isEnsuringClient, outCwdRelativeDir, locatedSegments, isNodeNextResolution, hasMixins, isVovkProject, vovkCliPackage, isBundle, origin, configKey, cliSchemaPath, }: {
9
9
  cwd: string;
10
10
  projectInfo: ProjectInfo;
11
11
  clientTemplateFile: ClientTemplateFile;
@@ -34,6 +34,7 @@ export default function writeOneClientFile({ cwd, projectInfo, clientTemplateFil
34
34
  isBundle: boolean;
35
35
  origin: string | null;
36
36
  configKey: 'composedClient' | 'segmentedClient';
37
+ cliSchemaPath: string | null;
37
38
  }): Promise<{
38
39
  written: boolean;
39
40
  }>;
@@ -16,7 +16,7 @@ export default async function writeOneClientFile({ cwd, projectInfo, clientTempl
16
16
  // imports,
17
17
  templateContent, matterResult: { data, content }, openapi, package: packageJson, readme, snippets, isEnsuringClient, outCwdRelativeDir,
18
18
  // templateDef,
19
- locatedSegments, isNodeNextResolution, hasMixins, isVovkProject, vovkCliPackage, isBundle, origin, configKey, }) {
19
+ locatedSegments, isNodeNextResolution, hasMixins, isVovkProject, vovkCliPackage, isBundle, origin, configKey, cliSchemaPath, }) {
20
20
  const { config, apiRoot } = projectInfo;
21
21
  const { templateFilePath, relativeDir } = clientTemplateFile;
22
22
  const locatedSegmentsByName = _.keyBy(locatedSegments, 'segmentName');
@@ -64,8 +64,8 @@ locatedSegments, isNodeNextResolution, hasMixins, isVovkProject, vovkCliPackage,
64
64
  mjs: isNodeNextResolution ? '.mjs' : '',
65
65
  },
66
66
  schemaOutDir: typeof segmentName === 'string'
67
- ? path.relative(path.join(outCwdRelativeDir, segmentName || ROOT_SEGMENT_FILE_NAME), config.schemaOutDir)
68
- : path.relative(outCwdRelativeDir, config.schemaOutDir),
67
+ ? path.relative(path.join(outCwdRelativeDir, segmentName || ROOT_SEGMENT_FILE_NAME), cliSchemaPath ?? config.schemaOutDir)
68
+ : path.relative(outCwdRelativeDir, cliSchemaPath ?? config.schemaOutDir),
69
69
  commonImports: getTemplateClientImports({ fullSchema, isBundle, outCwdRelativeDir, segmentName })['composedClient'],
70
70
  segmentImports: Object.fromEntries(Object.values(fullSchema.segments).map(({ segmentName: sName }) => {
71
71
  const clientImports = getTemplateClientImports({ fullSchema, segmentName: sName, isBundle, outCwdRelativeDir });
@@ -17,16 +17,6 @@ export default async function getConfig({ configPath, cwd, logLevel, }) {
17
17
  const env = process.env;
18
18
  const clientTemplateDefs = getTemplateDefs(conf.clientTemplateDefs);
19
19
  const srcRoot = await getRelativeSrcRoot({ cwd });
20
- const validateOnClientImport = conf.generatorConfig?.imports?.validateOnClient ?? null;
21
- const fetcherImport = conf.generatorConfig?.imports?.fetcher ?? 'vovk';
22
- const createRPCImport = conf.generatorConfig?.imports?.createRPC ?? 'vovk';
23
- const imports = {
24
- fetcher: typeof fetcherImport === 'string' ? [fetcherImport] : fetcherImport,
25
- validateOnClient: typeof validateOnClientImport === 'string'
26
- ? [validateOnClientImport]
27
- : (validateOnClientImport ?? null),
28
- createRPC: typeof createRPCImport === 'string' ? [createRPCImport] : createRPCImport,
29
- };
30
20
  const config = {
31
21
  $schema: VovkSchemaIdEnum.CONFIG,
32
22
  clientTemplateDefs,
@@ -51,7 +41,6 @@ export default async function getConfig({ configPath, cwd, logLevel, }) {
51
41
  requires: {
52
42
  [BuiltInTemplateName.readme]: '.',
53
43
  [BuiltInTemplateName.packageJson]: '.',
54
- [BuiltInTemplateName.openapiJson]: '.',
55
44
  },
56
45
  generatorConfig: {},
57
46
  ...conf.bundle,
@@ -74,7 +63,6 @@ export default async function getConfig({ configPath, cwd, logLevel, }) {
74
63
  libs: conf.libs ?? {},
75
64
  generatorConfig: {
76
65
  ...conf.generatorConfig,
77
- imports,
78
66
  origin: (env.VOVK_ORIGIN ?? conf?.generatorConfig?.origin ?? '').replace(/\/$/, ''), // Remove trailing slash
79
67
  segments: Object.fromEntries(await Promise.all(Object.entries(conf.generatorConfig?.segments ?? {}).map(async ([key, value]) => [
80
68
  key,
@@ -23,7 +23,7 @@ export default function getMetaSchema({ config, package: packageJson, }) {
23
23
  import: './openapi.cjs',
24
24
  require: './openapi.cjs',
25
25
  types: './openapi.d.cts',
26
- }
26
+ },
27
27
  },
28
28
  },
29
29
  ...{
package/dist/index.mjs CHANGED
@@ -123,8 +123,8 @@ program
123
123
  .option('--exclude, --exclude-segments <segments...>', 'exclude segments')
124
124
  .option('--prebundle-out-dir, --prebundle-out <path>', 'path to output directory for prebundle')
125
125
  .option('--keep-prebundle-dir', 'do not delete prebundle directory after bundling')
126
- .option('--config <config>', 'path to config file')
127
- .option('--schema <path>', 'path to schema folder (default: .vovk-schema)')
126
+ .option('--schema, --schema-path <path>', 'path to schema folder (default: .vovk-schema)')
127
+ .option('--config, --config-path <config>', 'path to config file')
128
128
  .option('--origin <url>', 'set the origin URL for the generated client')
129
129
  .option('--tsconfig <path>', 'path to tsconfig.json for bundling by tsdown')
130
130
  .option('--openapi, --openapi-spec <openapi_path_or_urls...>', 'use OpenAPI schema instead of Vovk schema')
@@ -134,7 +134,7 @@ program
134
134
  .option('--log-level <level>', 'set the log level')
135
135
  .action(async (cliBundleOptions) => {
136
136
  const projectInfo = await getProjectInfo({
137
- configPath: cliBundleOptions.config,
137
+ configPath: cliBundleOptions.configPath,
138
138
  srcRootRequired: false,
139
139
  logLevel: cliBundleOptions.logLevel,
140
140
  });
@@ -1,4 +1,4 @@
1
- export declare function createStandardSchemaValidatorFile({ cwd, validationLibrary, }: {
2
- cwd: string;
1
+ export declare function createStandardSchemaValidatorFile({ root, validationLibrary, }: {
2
+ root: string;
3
3
  validationLibrary: 'arktype' | 'valibot';
4
4
  }): Promise<void>;
@@ -1,6 +1,6 @@
1
1
  import fs from 'fs/promises';
2
- import getRelativeSrcRoot from '../getProjectInfo/getConfig/getRelativeSrcRoot.mjs';
3
2
  import path from 'path';
3
+ import getRelativeSrcRoot from '../getProjectInfo/getConfig/getRelativeSrcRoot.mjs';
4
4
  function getCode(validationLibrary) {
5
5
  if (validationLibrary === 'valibot') {
6
6
  return `
@@ -29,10 +29,11 @@ export default withArk;
29
29
  }
30
30
  throw new Error(`Unknown validation library: ${validationLibrary}`);
31
31
  }
32
- export async function createStandardSchemaValidatorFile({ cwd, validationLibrary, }) {
32
+ export async function createStandardSchemaValidatorFile({ root, validationLibrary, }) {
33
33
  const code = getCode(validationLibrary);
34
- const srcRoot = (await getRelativeSrcRoot({ cwd })) ?? '.';
35
- const libDir = path.join(cwd, srcRoot, 'lib');
34
+ const srcRoot = (await getRelativeSrcRoot({ cwd: root })) ?? '.';
35
+ const libDir = path.resolve(root, srcRoot, 'lib');
36
+ const filePath = path.join(libDir, `${validationLibrary === 'arktype' ? 'withArk' : 'withValibot'}.ts`);
36
37
  await fs.mkdir(libDir, { recursive: true });
37
- await fs.writeFile(path.join(libDir, `${validationLibrary === 'arktype' ? 'withArk' : 'withValibot'}.ts`), code);
38
+ await fs.writeFile(filePath, code);
38
39
  }
@@ -18,7 +18,7 @@ import { createStandardSchemaValidatorFile } from './createStandardSchemaValidat
18
18
  export class Init {
19
19
  root;
20
20
  log;
21
- async #init({ configPaths, pkgJson, cwd = process.cwd(), }, { useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary, lang, dryRun, channel, }) {
21
+ async #init({ configPaths, pkgJson, }, { useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary, lang, dryRun, channel, }) {
22
22
  const { log, root } = this;
23
23
  const dependencies = ['vovk', 'vovk-client', 'openapi3-ts', 'vovk-ajv', 'ajv'];
24
24
  const devDependencies = ['vovk-cli'];
@@ -132,7 +132,7 @@ export class Init {
132
132
  }
133
133
  if (validationLibrary === 'valibot' || validationLibrary === 'arktype') {
134
134
  createStandardSchemaValidatorFile({
135
- cwd,
135
+ root,
136
136
  validationLibrary,
137
137
  });
138
138
  }
@@ -202,21 +202,21 @@ export class Init {
202
202
  value: 'class-validator',
203
203
  description: 'Use class-validator for data validation',
204
204
  },
205
- {
206
- name: 'Valibot',
207
- value: 'valibot',
208
- description: 'Use valibot for data validation.',
209
- },
210
205
  {
211
206
  name: 'ArkType',
212
207
  value: 'arktype',
213
- description: 'Use arktype for data validation.',
208
+ description: 'Use ArkType for data validation.',
209
+ },
210
+ {
211
+ name: 'Valibot',
212
+ value: 'valibot',
213
+ description: 'Use Valibot for data validation.',
214
214
  },
215
215
  { name: 'None', value: null, description: 'Install validation library later' },
216
216
  ],
217
217
  })));
218
218
  updateScripts ??= await select({
219
- message: 'Do you want to update "dev" and "build" NPM scripts at package.json?',
219
+ message: 'Do you want to update "dev" and add "prebuild" NPM scripts at package.json?',
220
220
  default: 'implicit',
221
221
  choices: [
222
222
  {
package/dist/types.d.mts CHANGED
@@ -40,7 +40,8 @@ export interface GenerateOptions {
40
40
  logLevel?: LogLevelNames;
41
41
  }
42
42
  export interface BundleOptions extends Partial<Pick<VovkStrictConfig['bundle'], 'prebundleOutDir' | 'keepPrebundleDir' | 'includeSegments' | 'excludeSegments'>> {
43
- config?: string;
43
+ configPath?: string;
44
+ schemaPath?: string;
44
45
  schema?: string;
45
46
  outDir?: string;
46
47
  origin?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vovk-cli",
3
- "version": "0.0.1-draft.340",
3
+ "version": "0.0.1-draft.341",
4
4
  "bin": {
5
5
  "vovk": "./dist/index.mjs"
6
6
  },
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "homepage": "https://vovk.dev",
37
37
  "peerDependencies": {
38
- "vovk": "^3.0.0-draft.405"
38
+ "vovk": "^3.0.0-draft.406"
39
39
  },
40
40
  "optionalDependencies": {
41
41
  "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.31"