vovk-cli 0.0.1-draft.278 → 0.0.1-draft.279

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,5 +1,6 @@
1
- # <%= t.package.name %> v<%= t.package.version %> ![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white)
1
+ <%= t.readme.banner %>
2
2
 
3
+ # <%= t.package.name %> v<%= t.package.version %> ![TypeScript](https://badgen.net/badge/-/TypeScript?icon=typescript&label&labelColor=blue&color=555555)
3
4
 
4
5
  <%- t.package.description ? `> ${t.package.description}` : '' %>
5
6
 
@@ -27,6 +27,8 @@ export async function bundle({ projectInfo, fullSchema, cliBundleOptions, }) {
27
27
  forceNothingWrittenLog: true,
28
28
  fullSchema,
29
29
  locatedSegments,
30
+ package: bundleConfig.package,
31
+ readme: bundleConfig.readme,
30
32
  cliGenerateOptions: {
31
33
  openapiSpec: cliBundleOptions?.openapiSpec,
32
34
  openapiGetModuleName: cliBundleOptions?.openapiGetModuleName,
@@ -1,12 +1,15 @@
1
- import { type VovkSchema } from 'vovk';
1
+ import { type VovkSchema, type VovkStrictConfig } from 'vovk';
2
+ import type { PackageJson } from 'type-fest';
2
3
  import type { ProjectInfo } from '../getProjectInfo/index.mjs';
3
4
  import type { GenerateOptions } from '../types.mjs';
4
5
  import type { Segment } from '../locateSegments.mjs';
5
- export declare function generate({ isEnsuringClient, projectInfo, forceNothingWrittenLog, fullSchema, locatedSegments, cliGenerateOptions, }: {
6
+ export declare function generate({ isEnsuringClient, projectInfo, forceNothingWrittenLog, fullSchema, locatedSegments, cliGenerateOptions, package: argPackageJson, readme: argReadme, }: {
6
7
  isEnsuringClient?: boolean;
7
8
  projectInfo: ProjectInfo;
8
9
  forceNothingWrittenLog?: boolean;
9
10
  fullSchema: VovkSchema;
10
11
  locatedSegments: Segment[];
11
12
  cliGenerateOptions?: GenerateOptions;
13
+ package?: PackageJson;
14
+ readme?: VovkStrictConfig['bundle']['readme'];
12
15
  }): Promise<void>;
@@ -42,18 +42,26 @@ function logClientGenerationResults({ results, log, isEnsuringClient = false, fo
42
42
  const writtenResults = results.filter(({ written }) => written);
43
43
  const duration = Date.now() - startTime;
44
44
  const groupedByDir = _.groupBy(writtenResults, ({ outAbsoluteDir }) => outAbsoluteDir);
45
+ const logOrDebug = forceNothingWrittenLog ? log.info : log.debug;
45
46
  if (writtenResults.length) {
46
47
  for (const [outAbsoluteDir, dirResults] of Object.entries(groupedByDir)) {
47
48
  const templateNames = _.uniq(dirResults.map(({ templateName }) => templateName));
48
49
  log.info(`${clientType} client${isEnsuringClient ? ' placeholder' : ''} is generated to ${chalkHighlightThing(outAbsoluteDir)} from template${templateNames.length !== 1 ? 's' : ''} ${chalkHighlightThing(templateNames.map((s) => `"${s}"`).join(', '))} in ${duration}ms`);
49
50
  }
50
51
  }
51
- else if (!isEnsuringClient && fromTemplates.length) {
52
- const logOrDebug = forceNothingWrittenLog ? log.info : log.debug;
53
- for (const [outAbsoluteDir, dirResults] of Object.entries(groupedByDir)) {
54
- const templateNames = _.uniq(dirResults.map(({ templateName }) => templateName));
55
- logOrDebug(`${clientType} client that was generated to ${chalkHighlightThing(outAbsoluteDir)} from template${templateNames.length !== 1 ? 's' : ''} ${chalkHighlightThing(templateNames.map((s) => `"${s}"`).join(', '))} is up to date and doesn't need to be regenerated (${duration}ms)`);
52
+ else if (fromTemplates.length) {
53
+ if (!writtenResults.length) {
54
+ logOrDebug(`${clientType} client${isEnsuringClient ? ' placeholder' : ''} is up to date (${duration}ms)`);
56
55
  }
56
+ else if (!isEnsuringClient) {
57
+ for (const [outAbsoluteDir, dirResults] of Object.entries(groupedByDir)) {
58
+ const templateNames = _.uniq(dirResults.map(({ templateName }) => templateName));
59
+ logOrDebug(`${clientType} client that was generated to ${chalkHighlightThing(outAbsoluteDir)} from template${templateNames.length !== 1 ? 's' : ''} ${chalkHighlightThing(templateNames.map((s) => `"${s}"`).join(', '))} is up to date and doesn't need to be regenerated (${duration}ms)`);
60
+ }
61
+ }
62
+ }
63
+ else {
64
+ logOrDebug(`${clientType} client${isEnsuringClient ? ' placeholder' : ''} is not generated because no files were written (${duration}ms)`);
57
65
  }
58
66
  }
59
67
  const cliOptionsToOpenAPIMixins = ({ openapiGetMethodName, openapiGetModuleName, openapiRootUrl, openapiSpec, openapiMixinName, }) => {
@@ -63,7 +71,7 @@ const cliOptionsToOpenAPIMixins = ({ openapiGetMethodName, openapiGetModuleName,
63
71
  apiRoot: openapiRootUrl?.[i] ?? '/',
64
72
  getModuleName: openapiGetModuleName?.[i] ?? undefined,
65
73
  getMethodName: openapiGetMethodName?.[i] ?? 'auto',
66
- mixinName: openapiMixinName?.[i] ?? `mixin${i + 1}`, // TODO merge mixins with the same name
74
+ mixinName: openapiMixinName?.[i],
67
75
  };
68
76
  }) || []).map(({ source, apiRoot, getModuleName, getMethodName, mixinName }) => [
69
77
  mixinName,
@@ -76,13 +84,13 @@ const cliOptionsToOpenAPIMixins = ({ openapiGetMethodName, openapiGetModuleName,
76
84
  },
77
85
  ]));
78
86
  };
79
- export async function generate({ isEnsuringClient = false, projectInfo, forceNothingWrittenLog, fullSchema, locatedSegments, cliGenerateOptions, }) {
87
+ export async function generate({ isEnsuringClient = false, projectInfo, forceNothingWrittenLog, fullSchema, locatedSegments, cliGenerateOptions, package: argPackageJson, readme: argReadme, }) {
80
88
  fullSchema = {
81
89
  ...fullSchema,
82
90
  // sort segments by name to avoid unnecessary rendering
83
91
  segments: Object.fromEntries(Object.entries(fullSchema.segments).sort(([a], [b]) => a.localeCompare(b))),
84
92
  };
85
- const { config, cwd, log, srcRoot } = projectInfo;
93
+ const { config, cwd, log, srcRoot, packageJson: rootPackageJson } = projectInfo;
86
94
  const allOpenAPIMixins = {
87
95
  ...config.openApiMixins,
88
96
  ...cliOptionsToOpenAPIMixins(cliGenerateOptions ?? {}),
@@ -133,10 +141,10 @@ export async function generate({ isEnsuringClient = false, projectInfo, forceNot
133
141
  });
134
142
  const packageJson = await mergePackages({
135
143
  log,
136
- cwd,
137
- config,
138
- packages: [config.composedClient.package, templateDef.composedClient?.package],
144
+ rootPackageJson,
145
+ packages: [config.composedClient.package, templateDef.composedClient?.package, argPackageJson],
139
146
  });
147
+ const readme = Object.assign({}, config.composedClient.readme, templateDef.composedClient?.readme, argReadme);
140
148
  const composedFullSchema = pickSegmentFullSchema(fullSchema, segmentNames);
141
149
  const hasMixins = Object.values(composedFullSchema.segments).some((segment) => segment.segmentType === 'mixin');
142
150
  if (templateName === BuiltInTemplateName.mixins && !hasMixins) {
@@ -153,6 +161,7 @@ export async function generate({ isEnsuringClient = false, projectInfo, forceNot
153
161
  templateContent,
154
162
  matterResult,
155
163
  package: packageJson,
164
+ readme,
156
165
  isEnsuringClient,
157
166
  outCwdRelativeDir,
158
167
  origin: config.origin ?? templateDef?.origin ?? null,
@@ -207,14 +216,15 @@ export async function generate({ isEnsuringClient = false, projectInfo, forceNot
207
216
  outCwdRelativeDir,
208
217
  });
209
218
  const packageJson = await mergePackages({
210
- cwd,
211
- config,
212
219
  log,
220
+ rootPackageJson,
213
221
  packages: [
214
222
  config.segmentedClient.packages?.[segmentName],
215
223
  templateDef.segmentedClient?.packages?.[segmentName],
224
+ argPackageJson,
216
225
  ],
217
226
  });
227
+ const readme = Object.assign({}, config.segmentedClient.readmes?.[segmentName], templateDef.segmentedClient?.readmes?.[segmentName], argReadme);
218
228
  const segmentedFullSchema = pickSegmentFullSchema(fullSchema, [segmentName]);
219
229
  const hasMixins = Object.values(segmentedFullSchema.segments).some((segment) => segment.segmentType === 'mixin');
220
230
  if (templateName === BuiltInTemplateName.mixins && !hasMixins) {
@@ -231,6 +241,7 @@ export async function generate({ isEnsuringClient = false, projectInfo, forceNot
231
241
  templateContent,
232
242
  matterResult,
233
243
  package: packageJson,
244
+ readme,
234
245
  isEnsuringClient,
235
246
  outCwdRelativeDir,
236
247
  origin: config.origin ?? templateDef?.origin ?? null,
@@ -1,9 +1,7 @@
1
1
  import type { PackageJson } from 'type-fest';
2
- import type { VovkStrictConfig } from 'vovk';
3
2
  import type { ProjectInfo } from '../getProjectInfo/index.mjs';
4
- export default function mergePackages({ cwd, packages, log, }: {
5
- cwd: string;
6
- config: VovkStrictConfig;
7
- log: ProjectInfo['log'];
3
+ export default function mergePackages({ rootPackageJson, packages, }: {
4
+ rootPackageJson: PackageJson;
8
5
  packages: (PackageJson | undefined)[];
6
+ log: ProjectInfo['log'];
9
7
  }): Promise<PackageJson>;
@@ -1,26 +1,4 @@
1
1
  import pick from 'lodash/pick.js';
2
- import fs from 'node:fs/promises';
3
- import path from 'node:path';
4
- let cachedPromise;
5
- function getPackageJson(cwd, log) {
6
- const pkgPath = path.join(cwd, 'package.json');
7
- // If we have a cached promise, return it
8
- if (cachedPromise) {
9
- return cachedPromise;
10
- }
11
- const promise = fs
12
- .readFile(pkgPath, 'utf8')
13
- .then((content) => JSON.parse(content))
14
- .catch(() => {
15
- cachedPromise = undefined;
16
- log.warn(`Failed to read package.json at ${pkgPath}. Using a fallback.`);
17
- return {
18
- name: 'unknown',
19
- };
20
- });
21
- cachedPromise = promise;
22
- return promise;
23
- }
24
2
  function mergeTwoPackageJsons(base, additional) {
25
3
  const merged = { ...base, ...additional };
26
4
  // TODO: Add deep merge for all properties
@@ -38,8 +16,7 @@ function mergeTwoPackageJsons(base, additional) {
38
16
  }
39
17
  return merged;
40
18
  }
41
- export default async function mergePackages({ cwd, packages, log, }) {
42
- const fullPackageJson = await getPackageJson(cwd, log);
19
+ export default async function mergePackages({ rootPackageJson, packages, }) {
43
20
  const defaultPackageJson = {
44
21
  main: './index.cjs',
45
22
  module: './index.mjs',
@@ -56,7 +33,7 @@ export default async function mergePackages({ cwd, packages, log, }) {
56
33
  },
57
34
  },
58
35
  };
59
- const pickedPackageJson = pick(fullPackageJson, [
36
+ const pickedPackageJson = pick(rootPackageJson, [
60
37
  'name',
61
38
  'version',
62
39
  'description',
@@ -4,7 +4,7 @@ import type { ProjectInfo } from '../getProjectInfo/index.mjs';
4
4
  import type { ClientTemplateFile } from './getClientTemplateFiles.mjs';
5
5
  import type { ClientImports } from './getTemplateClientImports.mjs';
6
6
  import type { Segment } from '../locateSegments.mjs';
7
- export default function writeOneClientFile({ cwd, projectInfo, clientTemplateFile, fullSchema, prettifyClient, segmentName, imports, templateContent, matterResult: { data, content }, package: packageJson, isEnsuringClient, outCwdRelativeDir, origin, templateDef, locatedSegments, isNodeNextResolution, hasMixins, isVovkProject, }: {
7
+ export default function writeOneClientFile({ cwd, projectInfo, clientTemplateFile, fullSchema, prettifyClient, segmentName, imports, templateContent, matterResult: { data, content }, package: packageJson, readme, isEnsuringClient, outCwdRelativeDir, origin, templateDef, locatedSegments, isNodeNextResolution, hasMixins, isVovkProject, }: {
8
8
  cwd: string;
9
9
  projectInfo: ProjectInfo;
10
10
  clientTemplateFile: ClientTemplateFile;
@@ -20,6 +20,7 @@ export default function writeOneClientFile({ cwd, projectInfo, clientTemplateFil
20
20
  content: string;
21
21
  };
22
22
  package: PackageJson;
23
+ readme: VovkStrictConfig['bundle']['readme'];
23
24
  isEnsuringClient: boolean;
24
25
  outCwdRelativeDir: string;
25
26
  origin: string | null;
@@ -8,7 +8,7 @@ import TOML from '@iarna/toml';
8
8
  import prettify from '../utils/prettify.mjs';
9
9
  import { ROOT_SEGMENT_FILE_NAME } from '../dev/writeOneSegmentSchemaFile.mjs';
10
10
  import { compileJSONSchemaToTypeScriptType } from '../utils/compileJSONSchemaToTypeScriptType.mjs';
11
- export default async function writeOneClientFile({ cwd, projectInfo, clientTemplateFile, fullSchema, prettifyClient, segmentName, imports, templateContent, matterResult: { data, content }, package: packageJson, isEnsuringClient, outCwdRelativeDir, origin, templateDef, locatedSegments, isNodeNextResolution, hasMixins, isVovkProject, }) {
11
+ export default async function writeOneClientFile({ cwd, projectInfo, clientTemplateFile, fullSchema, prettifyClient, segmentName, imports, templateContent, matterResult: { data, content }, package: packageJson, readme, isEnsuringClient, outCwdRelativeDir, origin, templateDef, locatedSegments, isNodeNextResolution, hasMixins, isVovkProject, }) {
12
12
  const { config, apiRoot } = projectInfo;
13
13
  const { templateFilePath, relativeDir } = clientTemplateFile;
14
14
  const locatedSegmentsByName = _.keyBy(locatedSegments, 'segmentName');
@@ -23,6 +23,7 @@ export default async function writeOneClientFile({ cwd, projectInfo, clientTempl
23
23
  hasMixins,
24
24
  isVovkProject,
25
25
  package: packageJson,
26
+ readme,
26
27
  ROOT_SEGMENT_FILE_NAME,
27
28
  apiRoot: origin ? `${origin}/${config.rootEntry}` : apiRoot,
28
29
  imports,
@@ -22,6 +22,9 @@ export default function getConfig({ configPath, cwd }: {
22
22
  includeSegments?: never;
23
23
  })) & {
24
24
  package?: import("type-fest").PackageJson;
25
+ readme?: {
26
+ banner?: string;
27
+ };
25
28
  };
26
29
  segmentedClient?: ({
27
30
  enabled?: boolean;
@@ -35,6 +38,9 @@ export default function getConfig({ configPath, cwd }: {
35
38
  includeSegments?: never;
36
39
  })) & {
37
40
  packages?: Record<string, import("type-fest").PackageJson>;
41
+ readmes?: Record<string, {
42
+ banner?: string;
43
+ }>;
38
44
  };
39
45
  bundle?: {
40
46
  outDir?: string;
@@ -42,6 +48,10 @@ export default function getConfig({ configPath, cwd }: {
42
48
  tsClientOutDir?: string;
43
49
  dontDeleteTsClientOutDirAfter?: boolean;
44
50
  sourcemap?: boolean;
51
+ package?: import("type-fest").PackageJson;
52
+ readme?: {
53
+ banner?: string;
54
+ };
45
55
  } & ({
46
56
  excludeSegments?: never;
47
57
  includeSegments?: string[];
@@ -89,6 +99,9 @@ export default function getConfig({ configPath, cwd }: {
89
99
  object: import("openapi3-ts/oas31").OpenAPIObject;
90
100
  };
91
101
  package?: import("type-fest").PackageJson;
102
+ readme?: {
103
+ banner?: string;
104
+ };
92
105
  apiRoot?: string;
93
106
  getModuleName?: "nestjs-operation-id" | (string & {}) | "api" | import("vovk/mjs/types").GetOpenAPINameFn;
94
107
  getMethodName?: "nestjs-operation-id" | "camel-case-operation-id" | "auto" | import("vovk/mjs/types").GetOpenAPINameFn;
@@ -43,7 +43,6 @@ export default async function getConfig({ configPath, cwd }) {
43
43
  outDir: conf.segmentedClient?.outDir ?? path.join(srcRoot ?? '.', 'client'),
44
44
  },
45
45
  bundle: {
46
- ...conf.bundle,
47
46
  outDir: conf.bundle?.outDir ?? 'dist',
48
47
  tsClientOutDir: conf.bundle?.tsClientOutDir ?? 'tmp_ts_rpc',
49
48
  dontDeleteTsClientOutDirAfter: conf.bundle?.dontDeleteTsClientOutDirAfter ?? false,
@@ -52,6 +51,9 @@ export default async function getConfig({ configPath, cwd }) {
52
51
  [BuiltInTemplateName.readme]: '.',
53
52
  [BuiltInTemplateName.packageJson]: '.',
54
53
  },
54
+ package: {},
55
+ readme: {},
56
+ ...conf.bundle,
55
57
  },
56
58
  modulesDir: conf.modulesDir ?? path.join(srcRoot ?? '.', 'modules'),
57
59
  schemaOutDir: env.VOVK_SCHEMA_OUT_DIR ?? conf.schemaOutDir ?? './.vovk-schema',
@@ -11,6 +11,7 @@ export default function getProjectInfo({ port: givenPort, cwd, configPath, srcRo
11
11
  apiDirAbsolutePath: string | null;
12
12
  srcRoot: string | null;
13
13
  config: import("vovk").VovkStrictConfig;
14
+ packageJson: import("type-fest").PackageJson;
14
15
  log: {
15
16
  info: (msg: string) => void;
16
17
  warn: (msg: string) => void;
@@ -1,5 +1,6 @@
1
1
  import path from 'node:path';
2
2
  import getConfig from './getConfig/index.mjs';
3
+ import { getPackageJson } from '../utils/getPackageJson.mjs';
3
4
  export default async function getProjectInfo({ port: givenPort, cwd = process.cwd(), configPath, srcRootRequired = true, } = {}) {
4
5
  const port = givenPort?.toString() ?? process.env.PORT ?? '3000';
5
6
  // Make PORT available to the config file at getConfig
@@ -8,6 +9,7 @@ export default async function getProjectInfo({ port: givenPort, cwd = process.cw
8
9
  configPath,
9
10
  cwd,
10
11
  });
12
+ const packageJson = await getPackageJson(cwd, log);
11
13
  if (srcRootRequired && !srcRoot) {
12
14
  throw new Error(`Could not find app router directory at ${cwd}. Check Next.js docs for more info.`);
13
15
  }
@@ -23,6 +25,7 @@ export default async function getProjectInfo({ port: givenPort, cwd = process.cw
23
25
  apiDirAbsolutePath,
24
26
  srcRoot,
25
27
  config,
28
+ packageJson,
26
29
  log,
27
30
  };
28
31
  }
@@ -15,9 +15,9 @@ export default async function createConfig({ root, log, options: { validationLib
15
15
  controller: 'vovk-cli/module-templates/controller.ts.ejs',
16
16
  service: 'vovk-cli/module-templates/service.ts.ejs',
17
17
  };
18
+ config.imports ??= {};
19
+ config.imports.validateOnClient = validationLibrary === 'vovk-dto' ? 'vovk-dto/validateOnClient' : 'vovk-ajv';
18
20
  if (validationLibrary) {
19
- config.imports ??= {};
20
- config.imports.validateOnClient = 'vovk-ajv';
21
21
  try {
22
22
  const validationTemplates = await getTemplateFilesFromPackage(validationLibrary, channel);
23
23
  Object.assign(moduleTemplates, validationTemplates);
@@ -19,7 +19,7 @@ export class Init {
19
19
  log;
20
20
  async #init({ configPaths, pkgJson, }, { useNpm, useYarn, usePnpm, useBun, skipInstall, updateTsConfig, updateScripts, validationLibrary, reactQuery, lang, dryRun, channel, }) {
21
21
  const { log, root } = this;
22
- const dependencies = ['vovk', 'vovk-client'];
22
+ const dependencies = ['vovk', 'vovk-client', 'vovk-ajv', 'openapi3-ts'];
23
23
  const devDependencies = ['vovk-cli'];
24
24
  if (lang?.includes('py')) {
25
25
  dependencies.push('vovk-python');
@@ -33,9 +33,8 @@ export class Init {
33
33
  log.debug(`Deleted existing config file${configPaths.length > 1 ? 's' : ''} at ${configPaths.join(', ')}`);
34
34
  }
35
35
  if (validationLibrary) {
36
- dependencies.push(validationLibrary, 'vovk-ajv', ...({
36
+ dependencies.push(validationLibrary, ...({
37
37
  'vovk-zod': ['zod'],
38
- 'vovk-yup': ['yup'],
39
38
  'vovk-dto': ['class-validator', 'class-transformer', 'dto-mapped-types', 'reflect-metadata'],
40
39
  }[validationLibrary] ?? []));
41
40
  }
@@ -185,11 +184,6 @@ export class Init {
185
184
  value: 'vovk-zod',
186
185
  description: 'Use Zod for data validation',
187
186
  },
188
- {
189
- name: 'vovk-yup',
190
- value: 'vovk-yup',
191
- description: 'Use Yup for data validation',
192
- },
193
187
  {
194
188
  name: 'vovk-dto',
195
189
  value: 'vovk-dto',
@@ -14,7 +14,7 @@ export function initProgram(program) {
14
14
  .option('--update-ts-config', 'update tsconfig.json')
15
15
  .option('--update-scripts <mode>', 'update package.json scripts ("implicit" or "explicit")')
16
16
  .option('--lang <languages...>', 'generate client for other programming languages by default ("py" for Python and "rs" for Rust are supported)')
17
- .option('--validation-library <library>', 'validation library to use ("vovk-zod", "vovk-yup", "vovk-dto" or another); set to "none" to skip')
17
+ .option('--validation-library <library>', 'validation library to use ("vovk-zod", "vovk-dto" or another); set to "none" to skip')
18
18
  .option('--react-query', 'use @tanstack/react-query for data fetching inside components')
19
19
  .option('--channel <channel>', 'channel to use for fetching packages', 'latest')
20
20
  .option('--dry-run', 'do not write files to disk')
@@ -0,0 +1,3 @@
1
+ import { PackageJson } from 'type-fest';
2
+ import type { ProjectInfo } from '../getProjectInfo/index.mjs';
3
+ export declare function getPackageJson(cwd: string, log: ProjectInfo['log']): Promise<PackageJson>;
@@ -0,0 +1,22 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ let cachedPromise;
4
+ export function getPackageJson(cwd, log) {
5
+ const pkgPath = path.join(cwd, 'package.json');
6
+ // If we have a cached promise, return it
7
+ if (cachedPromise) {
8
+ return cachedPromise;
9
+ }
10
+ const promise = fs
11
+ .readFile(pkgPath, 'utf8')
12
+ .then((content) => JSON.parse(content))
13
+ .catch(() => {
14
+ cachedPromise = undefined;
15
+ log.warn(`Failed to read package.json at ${pkgPath}. Using a fallback.`);
16
+ return {
17
+ name: 'unknown',
18
+ };
19
+ });
20
+ cachedPromise = promise;
21
+ return promise;
22
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vovk-cli",
3
- "version": "0.0.1-draft.278",
3
+ "version": "0.0.1-draft.279",
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.298"
38
+ "vovk": "^3.0.0-draft.315"
39
39
  },
40
40
  "optionalDependencies": {
41
41
  "vovk-python": "^0.0.1-draft.41"