vovk-cli 0.1.3 → 0.3.0-beta.0
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/CHANGELOG.md +38 -0
- package/client-templates/{schemaTs → schema-ts}/schema.ts.ejs +1 -1
- package/client-templates/{tsBase → ts-base}/index.ts.ejs +1 -1
- package/dist/bundle/index.d.mts +1 -1
- package/dist/bundle/index.mjs +67 -45
- package/dist/dev/{diffSegmentSchema.d.mts → diff-segment-schema.d.mts} +0 -17
- package/dist/dev/{diffSegmentSchema.mjs → diff-segment-schema.mjs} +1 -17
- package/dist/dev/{ensureSchemaFiles.d.mts → ensure-schema-files.d.mts} +1 -1
- package/dist/dev/{ensureSchemaFiles.mjs → ensure-schema-files.mjs} +30 -12
- package/dist/dev/index.mjs +23 -17
- package/dist/dev/log-diff-result.d.mts +3 -0
- package/dist/dev/{logDiffResult.mjs → log-diff-result.mjs} +2 -2
- package/dist/dev/{writeMetaJson.d.mts → write-meta-json.d.mts} +1 -1
- package/dist/dev/{writeMetaJson.mjs → write-meta-json.mjs} +3 -3
- package/dist/dev/{writeOneSegmentSchemaFile.d.mts → write-one-segment-schema-file.d.mts} +1 -1
- package/dist/dev/{writeOneSegmentSchemaFile.mjs → write-one-segment-schema-file.mjs} +8 -3
- package/dist/generate/ensure-client.d.mts +3 -0
- package/dist/generate/{ensureClient.mjs → ensure-client.mjs} +1 -1
- package/dist/generate/generate.d.mts +2 -2
- package/dist/generate/generate.mjs +41 -28
- package/dist/generate/{getClientTemplateFiles.d.mts → get-client-template-files.d.mts} +1 -1
- package/dist/generate/{getClientTemplateFiles.mjs → get-client-template-files.mjs} +8 -4
- package/dist/generate/{getProjectFullSchema.d.mts → get-project-full-schema.d.mts} +1 -1
- package/dist/generate/{getProjectFullSchema.mjs → get-project-full-schema.mjs} +3 -3
- package/dist/generate/{getTemplateClientImports.mjs → get-template-client-imports.mjs} +2 -2
- package/dist/generate/index.d.mts +2 -2
- package/dist/generate/index.mjs +46 -34
- package/dist/generate/{writeOneClientFile.d.mts → write-one-client-file.d.mts} +5 -5
- package/dist/generate/{writeOneClientFile.mjs → write-one-client-file.mjs} +10 -8
- package/dist/{getProjectInfo/getConfig/getRelativeSrcRoot.mjs → get-project-info/get-config/get-relative-src-root.mjs} +1 -1
- package/dist/get-project-info/get-config/get-template-defs.d.mts +22 -0
- package/dist/{getProjectInfo/getConfig/getTemplateDefs.mjs → get-project-info/get-config/get-template-defs.mjs} +35 -61
- package/dist/{getProjectInfo/getConfig/getUserConfig.mjs → get-project-info/get-config/get-user-config.mjs} +2 -2
- package/dist/{getProjectInfo/getConfig → get-project-info/get-config}/index.d.mts +2 -2
- package/dist/{getProjectInfo/getConfig → get-project-info/get-config}/index.mjs +17 -12
- package/dist/{getProjectInfo/getMetaSchema.d.mts → get-project-info/get-meta-schema.d.mts} +1 -1
- package/dist/{getProjectInfo → get-project-info}/index.mjs +3 -3
- package/dist/index.mjs +25 -16
- package/dist/init/{createConfig.d.mts → create-config.d.mts} +1 -1
- package/dist/init/{createConfig.mjs → create-config.mjs} +6 -6
- package/dist/init/index.d.mts +1 -1
- package/dist/init/index.mjs +54 -22
- package/dist/init/{installDependencies.d.mts → install-dependencies.d.mts} +2 -1
- package/dist/init/{installDependencies.mjs → install-dependencies.mjs} +11 -3
- package/dist/init/{logUpdateDependenciesError.d.mts → log-update-dependencies-error.d.mts} +2 -2
- package/dist/init/{logUpdateDependenciesError.mjs → log-update-dependencies-error.mjs} +1 -1
- package/dist/init/{updateDependenciesWithoutInstalling.d.mts → update-dependencies-without-installing.d.mts} +1 -1
- package/dist/init/{updateDependenciesWithoutInstalling.mjs → update-dependencies-without-installing.mjs} +1 -2
- package/dist/init/update-gitignore.d.mts +2 -0
- package/dist/init/update-gitignore.mjs +20 -0
- package/dist/new/index.d.mts +1 -1
- package/dist/new/index.mjs +2 -2
- package/dist/new/{newModule.d.mts → new-module.d.mts} +1 -1
- package/dist/new/{newModule.mjs → new-module.mjs} +15 -9
- package/dist/new/{newSegment.d.mts → new-segment.d.mts} +1 -1
- package/dist/new/{newSegment.mjs → new-segment.mjs} +11 -6
- package/dist/new/render.mjs +3 -3
- package/dist/types.d.mts +1 -1
- package/dist/utils/{compileJSONSchemaToTypeScriptType.mjs → compile-json-schema-to-typescript-type.mjs} +1 -1
- package/dist/utils/{formatLoggedSegmentName.mjs → format-logged-segment-name.mjs} +1 -1
- package/dist/utils/{generateFnName.d.mts → generate-fn-name.d.mts} +0 -9
- package/dist/utils/{generateFnName.mjs → generate-fn-name.mjs} +2 -9
- package/dist/utils/generated-banner.d.mts +1 -0
- package/dist/utils/generated-banner.mjs +3 -0
- package/dist/utils/get-available-port.d.mts +1 -0
- package/dist/utils/{getAvailablePort.mjs → get-available-port.mjs} +2 -14
- package/dist/utils/get-file-system-entry-type.d.mts +6 -0
- package/dist/utils/{getFileSystemEntryType.mjs → get-file-system-entry-type.mjs} +5 -5
- package/dist/utils/{getPackageJson.d.mts → get-package-json.d.mts} +1 -1
- package/dist/utils/{getPackageJson.mjs → get-package-json.mjs} +1 -1
- package/dist/utils/{locateSegments.d.mts → locate-segments.d.mts} +1 -1
- package/dist/utils/{locateSegments.mjs → locate-segments.mjs} +1 -1
- package/dist/utils/{normalizeOpenAPIMixin.d.mts → normalize-openapi-mixin.d.mts} +2 -2
- package/dist/utils/{normalizeOpenAPIMixin.mjs → normalize-openapi-mixin.mjs} +20 -5
- package/dist/utils/prettify.d.mts +4 -0
- package/dist/utils/prettify.mjs +39 -3
- package/dist/utils/remove-unlisted-directories.d.mts +1 -0
- package/dist/utils/remove-unlisted-directories.mjs +99 -0
- package/dist/utils/{resolveAbsoluteModulePath.mjs → resolve-absolute-module-path.mjs} +2 -3
- package/dist/utils/{updateConfigProperty.mjs → update-config-property.mjs} +1 -1
- package/module-templates/arktype/controller.ts.ejs +2 -2
- package/module-templates/type/controller.ts.ejs +2 -2
- package/module-templates/type/service.ts.ejs +2 -2
- package/module-templates/valibot/controller.ts.ejs +2 -2
- package/module-templates/zod/controller.ts.ejs +2 -2
- package/package.json +23 -30
- package/client-templates/jsBase/index.d.ts.ejs +0 -21
- package/client-templates/jsBase/index.js.ejs +0 -18
- package/client-templates/openapiJs/openapi.d.ts.ejs +0 -4
- package/client-templates/openapiJs/openapi.js.ejs +0 -4
- package/client-templates/schemaJs/schema.d.ts.ejs +0 -10
- package/client-templates/schemaJs/schema.js.ejs +0 -29
- package/dist/dev/logDiffResult.d.mts +0 -3
- package/dist/generate/ensureClient.d.mts +0 -3
- package/dist/getProjectInfo/getConfig/getTemplateDefs.d.mts +0 -25
- package/dist/utils/getAvailablePort.d.mts +0 -9
- package/dist/utils/getFileSystemEntryType.d.mts +0 -5
- package/dist/utils/removeUnlistedDirectories.d.mts +0 -9
- package/dist/utils/removeUnlistedDirectories.mjs +0 -60
- package/client-templates/{openapiJson → openapi-json}/openapi.json.ejs +0 -0
- package/client-templates/{openapiTs → openapi-ts}/openapi.ts.ejs +0 -0
- package/client-templates/{packageJson → package-json}/package.json.ejs +0 -0
- package/client-templates/{schemaJson → schema-json}/schema.json.ejs +0 -0
- package/dist/generate/{getTemplateClientImports.d.mts → get-template-client-imports.d.mts} +0 -0
- package/dist/{getProjectInfo/getConfig/getConfigAbsolutePaths.d.mts → get-project-info/get-config/get-config-absolute-paths.d.mts} +0 -0
- package/dist/{getProjectInfo/getConfig/getConfigAbsolutePaths.mjs → get-project-info/get-config/get-config-absolute-paths.mjs} +0 -0
- package/dist/{getProjectInfo/getConfig/getRelativeSrcRoot.d.mts → get-project-info/get-config/get-relative-src-root.d.mts} +0 -0
- package/dist/{getProjectInfo/getConfig/getUserConfig.d.mts → get-project-info/get-config/get-user-config.d.mts} +0 -0
- package/dist/{getProjectInfo/getMetaSchema.mjs → get-project-info/get-meta-schema.mjs} +1 -1
- package/dist/{getProjectInfo → get-project-info}/index.d.mts +0 -0
- package/dist/init/{checkTSConfigForExperimentalDecorators.d.mts → check-tsconfig-for-experimental-decorators.d.mts} +0 -0
- package/dist/init/{checkTSConfigForExperimentalDecorators.mjs → check-tsconfig-for-experimental-decorators.mjs} +1 -1
- package/dist/init/{updateNPMScripts.d.mts → update-npm-scripts.d.mts} +0 -0
- package/dist/init/{updateNPMScripts.mjs → update-npm-scripts.mjs} +0 -0
- package/dist/init/{updateTypeScriptConfig.d.mts → update-typescript-config.d.mts} +0 -0
- package/dist/init/{updateTypeScriptConfig.mjs → update-typescript-config.mjs} +1 -1
- package/dist/new/{addClassToSegmentCode.d.mts → add-class-to-segment-code.d.mts} +0 -0
- package/dist/new/{addClassToSegmentCode.mjs → add-class-to-segment-code.mjs} +0 -0
- package/dist/new/{addCommonTerms.d.mts → add-common-terms.d.mts} +0 -0
- package/dist/new/{addCommonTerms.mjs → add-common-terms.mjs} +0 -0
- package/dist/utils/{chalkHighlightThing.d.mts → chalk-highlight-thing.d.mts} +0 -0
- package/dist/utils/{chalkHighlightThing.mjs → chalk-highlight-thing.mjs} +0 -0
- package/dist/utils/{compileJSONSchemaToTypeScriptType.d.mts → compile-json-schema-to-typescript-type.d.mts} +1 -1
- package/dist/utils/{compileTs.d.mts → compile-ts.d.mts} +0 -0
- package/dist/utils/{compileTs.mjs → compile-ts.mjs} +1 -1
- /package/dist/utils/{debounceWithArgs.d.mts → debounce-with-args.d.mts} +0 -0
- /package/dist/utils/{debounceWithArgs.mjs → debounce-with-args.mjs} +0 -0
- /package/dist/utils/{formatLoggedSegmentName.d.mts → format-logged-segment-name.d.mts} +0 -0
- /package/dist/utils/{getLogger.d.mts → get-logger.d.mts} +0 -0
- /package/dist/utils/{getLogger.mjs → get-logger.mjs} +0 -0
- /package/dist/utils/{getNPMPackageMetadata.d.mts → get-npm-package-metadata.d.mts} +0 -0
- /package/dist/utils/{getNPMPackageMetadata.mjs → get-npm-package-metadata.mjs} +0 -0
- /package/dist/utils/{getPublicModuleNameFromPath.d.mts → get-public-module-name-from-path.d.mts} +0 -0
- /package/dist/utils/{getPublicModuleNameFromPath.mjs → get-public-module-name-from-path.mjs} +0 -0
- /package/dist/utils/{pickSegmentFullSchema.d.mts → pick-segment-full-schema.d.mts} +0 -0
- /package/dist/utils/{pickSegmentFullSchema.mjs → pick-segment-full-schema.mjs} +0 -0
- /package/dist/utils/{resolveAbsoluteModulePath.d.mts → resolve-absolute-module-path.d.mts} +0 -0
- /package/dist/utils/{updateConfigProperty.d.mts → update-config-property.d.mts} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { glob } from 'glob';
|
|
3
|
-
import { resolveAbsoluteModulePath } from '../utils/resolveAbsoluteModulePath.mjs';
|
|
4
|
-
import { getFileSystemEntryType, FileSystemEntryType } from '../utils/getFileSystemEntryType.mjs';
|
|
5
|
-
import { getPublicModuleNameFromPath } from '../utils/getPublicModuleNameFromPath.mjs';
|
|
6
|
-
import omit from 'lodash/omit.js';
|
|
7
3
|
import merge from 'lodash/merge.js';
|
|
4
|
+
import omit from 'lodash/omit.js';
|
|
5
|
+
import { FileSystemEntryType, getFileSystemEntryType } from '../utils/get-file-system-entry-type.mjs';
|
|
6
|
+
import { getPublicModuleNameFromPath } from '../utils/get-public-module-name-from-path.mjs';
|
|
7
|
+
import { resolveAbsoluteModulePath } from '../utils/resolve-absolute-module-path.mjs';
|
|
8
8
|
export async function getClientTemplateFiles({ config, cwd, log, configKey, cliGenerateOptions, }) {
|
|
9
9
|
const usedTemplateDefs = {};
|
|
10
10
|
const fromTemplates = configKey === 'composedClient'
|
|
@@ -18,6 +18,10 @@ export async function getClientTemplateFiles({ config, cwd, log, configKey, cliG
|
|
|
18
18
|
const configOutDir = config[configKey].outDir;
|
|
19
19
|
for (const templateName of fromTemplates) {
|
|
20
20
|
if (!(templateName in config.clientTemplateDefs)) {
|
|
21
|
+
// js family removed in v4
|
|
22
|
+
if (['js', 'jsBase', 'schemaJs', 'openapiJs'].includes(templateName)) {
|
|
23
|
+
throw new Error(`The "${templateName}" template was removed in v4. Use "ts" instead.`);
|
|
24
|
+
}
|
|
21
25
|
throw new Error(`Unknown template name: ${templateName}`);
|
|
22
26
|
}
|
|
23
27
|
usedTemplateDefs[templateName] = config.clientTemplateDefs[templateName];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { VovkSchema } from 'vovk';
|
|
2
|
-
import type { ProjectInfo } from '../getProjectInfo/index.mjs';
|
|
3
2
|
import { type VovkStrictConfig } from 'vovk/internal';
|
|
3
|
+
import type { ProjectInfo } from '../get-project-info/index.mjs';
|
|
4
4
|
export declare function getProjectFullSchema({ schemaOutAbsolutePath, isNextInstalled, log, config, }: {
|
|
5
5
|
schemaOutAbsolutePath: string;
|
|
6
6
|
isNextInstalled: boolean;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { access, readFile } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { glob } from 'glob';
|
|
4
|
-
import { META_FILE_NAME, ROOT_SEGMENT_FILE_NAME } from '../dev/writeOneSegmentSchemaFile.mjs';
|
|
5
|
-
import { getMetaSchema } from '../getProjectInfo/getMetaSchema.mjs';
|
|
6
4
|
import { deepExtend, VovkSchemaIdEnum } from 'vovk/internal';
|
|
5
|
+
import { META_FILE_NAME, ROOT_SEGMENT_FILE_NAME } from '../dev/write-one-segment-schema-file.mjs';
|
|
6
|
+
import { getMetaSchema } from '../get-project-info/get-meta-schema.mjs';
|
|
7
7
|
export async function getProjectFullSchema({ schemaOutAbsolutePath, isNextInstalled, log, config, }) {
|
|
8
8
|
const result = {
|
|
9
9
|
$schema: VovkSchemaIdEnum.SCHEMA,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { resolveGeneratorConfigValues } from 'vovk/internal';
|
|
3
|
-
import { ROOT_SEGMENT_FILE_NAME } from '../dev/
|
|
3
|
+
import { ROOT_SEGMENT_FILE_NAME } from '../dev/write-one-segment-schema-file.mjs';
|
|
4
4
|
export function getTemplateClientImports({ config, fullSchema, outCwdRelativeDir, segmentName, isBundle, outputConfigs, }) {
|
|
5
5
|
const { imports: configImports } = resolveGeneratorConfigValues({
|
|
6
6
|
config,
|
|
@@ -12,7 +12,7 @@ export function getTemplateClientImports({ config, fullSchema, outCwdRelativeDir
|
|
|
12
12
|
const imports = {
|
|
13
13
|
fetcher: configImports?.fetcher ?? 'vovk/fetcher',
|
|
14
14
|
validateOnClient: configImports?.validateOnClient ?? null,
|
|
15
|
-
createRPC: configImports?.createRPC ?? 'vovk/
|
|
15
|
+
createRPC: configImports?.createRPC ?? 'vovk/create-rpc',
|
|
16
16
|
};
|
|
17
17
|
const getImportPath = (p, s = '') => p.startsWith('.') ? path.relative(path.join(outCwdRelativeDir, s), p) : p;
|
|
18
18
|
const clientImports = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { VovkSchema } from 'vovk';
|
|
2
|
+
import type { ProjectInfo } from '../get-project-info/index.mjs';
|
|
2
3
|
import type { GenerateOptions } from '../types.mjs';
|
|
3
|
-
import type { ProjectInfo } from '../getProjectInfo/index.mjs';
|
|
4
4
|
export declare class VovkGenerate {
|
|
5
5
|
#private;
|
|
6
6
|
constructor({ cliGenerateOptions, projectInfo, forceNothingWrittenLog, }: {
|
|
@@ -8,7 +8,7 @@ export declare class VovkGenerate {
|
|
|
8
8
|
projectInfo: ProjectInfo;
|
|
9
9
|
forceNothingWrittenLog?: boolean;
|
|
10
10
|
});
|
|
11
|
-
start(): void;
|
|
11
|
+
start(): Promise<void> | undefined;
|
|
12
12
|
generate(): Promise<void>;
|
|
13
13
|
getFullSchema(): Promise<VovkSchema>;
|
|
14
14
|
watch({ throttleDelay }: {
|
package/dist/generate/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import * as chokidar from 'chokidar';
|
|
3
|
-
import {
|
|
3
|
+
import { chalkHighlightThing } from '../utils/chalk-highlight-thing.mjs';
|
|
4
|
+
import { locateSegments } from '../utils/locate-segments.mjs';
|
|
4
5
|
import { generate } from './generate.mjs';
|
|
5
|
-
import {
|
|
6
|
-
import { chalkHighlightThing } from '../utils/chalkHighlightThing.mjs';
|
|
6
|
+
import { getProjectFullSchema } from './get-project-full-schema.mjs';
|
|
7
7
|
const THROTTLE_DELAY = 5000;
|
|
8
8
|
export class VovkGenerate {
|
|
9
9
|
#cliGenerateOptions;
|
|
@@ -19,10 +19,10 @@ export class VovkGenerate {
|
|
|
19
19
|
if (watch) {
|
|
20
20
|
const throttleDelay = typeof watch === 'boolean' ? THROTTLE_DELAY : parseFloat(watch) * 1e3 || THROTTLE_DELAY;
|
|
21
21
|
this.watch({ throttleDelay });
|
|
22
|
+
return;
|
|
22
23
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
24
|
+
// return the promise so one-shot generate errors reach the CLI error handler
|
|
25
|
+
return this.generate();
|
|
26
26
|
}
|
|
27
27
|
async generate() {
|
|
28
28
|
const fullSchema = await this.getFullSchema();
|
|
@@ -63,6 +63,17 @@ export class VovkGenerate {
|
|
|
63
63
|
watchSchema({ schemaPath, throttleDelay }) {
|
|
64
64
|
const { log } = this.#projectInfo;
|
|
65
65
|
let lastGenerationTime = 0;
|
|
66
|
+
let pendingTimer = null;
|
|
67
|
+
const generateCode = async () => {
|
|
68
|
+
try {
|
|
69
|
+
lastGenerationTime = Date.now();
|
|
70
|
+
await this.generate();
|
|
71
|
+
log.debug(`Regenerated from schema changes`);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
log.error(`Failed to regenerate from schema: ${error instanceof Error ? error.message : String(error)}`);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
66
77
|
chokidar
|
|
67
78
|
.watch(schemaPath, {
|
|
68
79
|
persistent: true,
|
|
@@ -72,20 +83,15 @@ export class VovkGenerate {
|
|
|
72
83
|
if (event === 'change' || event === 'add' || event === 'ready' || event === 'unlink') {
|
|
73
84
|
log.debug(`Schema file ${event}: ${path}`);
|
|
74
85
|
const now = Date.now();
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
// Generate immediately if it's been a while since the last generation
|
|
87
|
-
if (shouldGenerateImmediately) {
|
|
88
|
-
generateCode();
|
|
86
|
+
// generate immediately outside the throttle window, otherwise defer to the end of it
|
|
87
|
+
if (now - lastGenerationTime > throttleDelay) {
|
|
88
|
+
void generateCode();
|
|
89
|
+
}
|
|
90
|
+
else if (!pendingTimer) {
|
|
91
|
+
pendingTimer = setTimeout(() => {
|
|
92
|
+
pendingTimer = null;
|
|
93
|
+
void generateCode();
|
|
94
|
+
}, throttleDelay - (now - lastGenerationTime));
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
97
|
});
|
|
@@ -111,6 +117,17 @@ export class VovkGenerate {
|
|
|
111
117
|
watchOpenApiSpecLocal({ openApiSpecPaths, throttleDelay }) {
|
|
112
118
|
const { log, cwd } = this.#projectInfo;
|
|
113
119
|
let lastGenerationTime = 0;
|
|
120
|
+
let pendingTimer = null;
|
|
121
|
+
const generateCode = async () => {
|
|
122
|
+
try {
|
|
123
|
+
lastGenerationTime = Date.now();
|
|
124
|
+
await this.generate();
|
|
125
|
+
log.debug(`Regenerated from OpenAPI spec changes`);
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
log.error(`Failed to regenerate from OpenAPI spec: ${error instanceof Error ? error.message : String(error)}`);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
114
131
|
chokidar
|
|
115
132
|
.watch(openApiSpecPaths, {
|
|
116
133
|
cwd,
|
|
@@ -121,20 +138,15 @@ export class VovkGenerate {
|
|
|
121
138
|
if (event === 'change' || event === 'add' || event === 'ready' || event === 'unlink') {
|
|
122
139
|
log.debug(`OpenAPI spec file changed: ${path}`);
|
|
123
140
|
const now = Date.now();
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
// Generate immediately if it's been a while since the last generation
|
|
136
|
-
if (shouldGenerateImmediately) {
|
|
137
|
-
generateCode();
|
|
141
|
+
// generate immediately outside the throttle window, otherwise defer to the end of it
|
|
142
|
+
if (now - lastGenerationTime > throttleDelay) {
|
|
143
|
+
void generateCode();
|
|
144
|
+
}
|
|
145
|
+
else if (!pendingTimer) {
|
|
146
|
+
pendingTimer = setTimeout(() => {
|
|
147
|
+
pendingTimer = null;
|
|
148
|
+
void generateCode();
|
|
149
|
+
}, throttleDelay - (now - lastGenerationTime));
|
|
138
150
|
}
|
|
139
151
|
}
|
|
140
152
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import type { OpenAPIObject } from 'openapi3-ts/oas31';
|
|
2
|
+
import type { PackageJson } from 'type-fest';
|
|
1
3
|
import type { VovkSchema } from 'vovk';
|
|
2
4
|
import { type VovkReadmeConfig, type VovkSamplesConfig, type VovkStrictConfig } from 'vovk/internal';
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
5
|
-
import type {
|
|
6
|
-
import type { ClientTemplateFile } from './getClientTemplateFiles.mjs';
|
|
7
|
-
import type { Segment } from '../utils/locateSegments.mjs';
|
|
5
|
+
import type { ProjectInfo } from '../get-project-info/index.mjs';
|
|
6
|
+
import type { Segment } from '../utils/locate-segments.mjs';
|
|
7
|
+
import type { ClientTemplateFile } from './get-client-template-files.mjs';
|
|
8
8
|
export declare function normalizeOutTemplatePath(out: string, packageJson: PackageJson): string;
|
|
9
9
|
export declare function writeOneClientFile({ cwd, projectInfo, clientTemplateFile, fullSchema, prettifyClient, segmentName, templateContent, matterResult: { data, content }, openAPIObject, package: packageJson, readme, samples, reExports, isEnsuringClient, outCwdRelativeDir, templateDef, locatedSegments, isNodeNextResolution, hasMixins, isVovkProject, vovkCliPackage, isBundle, origin, configKey, cliSchemaPath, projectConfig, }: {
|
|
10
10
|
cwd: string;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import TOML from '@iarna/toml';
|
|
3
4
|
import ejs from 'ejs';
|
|
4
5
|
import _ from 'lodash';
|
|
5
|
-
import * as YAML from 'yaml';
|
|
6
|
-
import TOML from '@iarna/toml';
|
|
7
6
|
import { createCodeSamples, reattachMixinDefs, VovkSchemaIdEnum, } from 'vovk/internal';
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import { chalkHighlightThing } from '../utils/
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
7
|
+
import * as YAML from 'yaml';
|
|
8
|
+
import { ROOT_SEGMENT_FILE_NAME } from '../dev/write-one-segment-schema-file.mjs';
|
|
9
|
+
import { chalkHighlightThing } from '../utils/chalk-highlight-thing.mjs';
|
|
10
|
+
import { compileJSONSchemaToTypeScriptType } from '../utils/compile-json-schema-to-typescript-type.mjs';
|
|
11
|
+
import { GENERATED_BANNER_PREFIX } from '../utils/generated-banner.mjs';
|
|
12
|
+
import { prettify, warnIfPrettierMissing } from '../utils/prettify.mjs';
|
|
13
|
+
import { getTemplateClientImports } from './get-template-client-imports.mjs';
|
|
13
14
|
export function normalizeOutTemplatePath(out, packageJson) {
|
|
14
15
|
return out.replace('[package_name]', packageJson.name?.replace(/-/g, '_') ?? 'my_package_name');
|
|
15
16
|
}
|
|
@@ -27,7 +28,7 @@ templateContent, matterResult: { data, content }, openAPIObject, package: packag
|
|
|
27
28
|
// Feel free to report an issue at https://github.com/finom/vovk/issues`;
|
|
28
29
|
placeholder = outPath.endsWith('.py') ? placeholder.replace(/\/\//g, '#') : placeholder;
|
|
29
30
|
const getFirstLineBanner = (type = 'c') => {
|
|
30
|
-
const text =
|
|
31
|
+
const text = `${GENERATED_BANNER_PREFIX} v${vovkCliPackage.version} at ${new Date().toISOString()}`;
|
|
31
32
|
switch (type) {
|
|
32
33
|
case 'html':
|
|
33
34
|
return `<!-- ${text} -->`;
|
|
@@ -130,6 +131,7 @@ templateContent, matterResult: { data, content }, openAPIObject, package: packag
|
|
|
130
131
|
: templateContent;
|
|
131
132
|
// Optionally prettify
|
|
132
133
|
if (prettifyClient) {
|
|
134
|
+
await warnIfPrettierMissing(log);
|
|
133
135
|
rendered = await prettify(rendered, outPath);
|
|
134
136
|
}
|
|
135
137
|
if (isEnsuringClient) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import {
|
|
2
|
+
import { FileSystemEntryType, getFileSystemEntryType } from '../../utils/get-file-system-entry-type.mjs';
|
|
3
3
|
export async function getRelativeSrcRoot({ cwd }) {
|
|
4
4
|
// Next.js Docs: src/app or src/pages will be ignored if app or pages are present in the root directory.
|
|
5
5
|
if ((await getFileSystemEntryType(path.join(cwd, 'app'))) === FileSystemEntryType.DIRECTORY) {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { VovkStrictConfig } from 'vovk/internal';
|
|
2
|
+
export declare const BuiltInTemplateName: {
|
|
3
|
+
readonly tsBase: "tsBase";
|
|
4
|
+
readonly ts: "ts";
|
|
5
|
+
readonly schemaTs: "schemaTs";
|
|
6
|
+
readonly schemaJson: "schemaJson";
|
|
7
|
+
readonly openapiTs: "openapiTs";
|
|
8
|
+
readonly openapiJson: "openapiJson";
|
|
9
|
+
readonly readme: "readme";
|
|
10
|
+
readonly packageJson: "packageJson";
|
|
11
|
+
readonly mixins: "mixins";
|
|
12
|
+
readonly rsSrc: "rsSrc";
|
|
13
|
+
readonly rsPkg: "rsPkg";
|
|
14
|
+
readonly rsReadme: "rsReadme";
|
|
15
|
+
readonly rs: "rs";
|
|
16
|
+
readonly pySrc: "pySrc";
|
|
17
|
+
readonly pyPkg: "pyPkg";
|
|
18
|
+
readonly pyReadme: "pyReadme";
|
|
19
|
+
readonly py: "py";
|
|
20
|
+
};
|
|
21
|
+
export type BuiltInTemplateName = (typeof BuiltInTemplateName)[keyof typeof BuiltInTemplateName];
|
|
22
|
+
export declare function getTemplateDefs(userTemplateDefs?: VovkStrictConfig['clientTemplateDefs']): VovkStrictConfig['clientTemplateDefs'];
|
|
@@ -1,105 +1,79 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// ts
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
BuiltInTemplateName["ts"] = "ts";
|
|
7
|
-
BuiltInTemplateName["js"] = "js";
|
|
1
|
+
// const object instead of enum, node 26 runs ts with erasable syntax only
|
|
2
|
+
export const BuiltInTemplateName = {
|
|
3
|
+
// ts
|
|
4
|
+
tsBase: 'tsBase',
|
|
5
|
+
ts: 'ts',
|
|
8
6
|
// schema
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
BuiltInTemplateName["schemaJson"] = "schemaJson";
|
|
7
|
+
schemaTs: 'schemaTs',
|
|
8
|
+
schemaJson: 'schemaJson',
|
|
12
9
|
// openapi
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
BuiltInTemplateName["openapiJson"] = "openapiJson";
|
|
10
|
+
openapiTs: 'openapiTs',
|
|
11
|
+
openapiJson: 'openapiJson',
|
|
16
12
|
// misc
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
readme: 'readme',
|
|
14
|
+
packageJson: 'packageJson',
|
|
15
|
+
mixins: 'mixins',
|
|
20
16
|
// other languages (packages installed separately)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
17
|
+
rsSrc: 'rsSrc',
|
|
18
|
+
rsPkg: 'rsPkg',
|
|
19
|
+
rsReadme: 'rsReadme',
|
|
20
|
+
rs: 'rs',
|
|
21
|
+
pySrc: 'pySrc',
|
|
22
|
+
pyPkg: 'pyPkg',
|
|
23
|
+
pyReadme: 'pyReadme',
|
|
24
|
+
py: 'py',
|
|
25
|
+
};
|
|
30
26
|
export function getTemplateDefs(userTemplateDefs = {}) {
|
|
31
27
|
const defs = {};
|
|
32
28
|
const builtInDefs = {
|
|
33
29
|
[BuiltInTemplateName.openapiTs]: {
|
|
34
|
-
templatePath:
|
|
35
|
-
requires: {
|
|
36
|
-
[BuiltInTemplateName.openapiJson]: './',
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
[BuiltInTemplateName.openapiJs]: {
|
|
40
|
-
templatePath: `vovk-cli/client-templates/${BuiltInTemplateName.openapiJs}/`,
|
|
30
|
+
templatePath: 'vovk-cli/client-templates/openapi-ts/',
|
|
41
31
|
requires: {
|
|
42
32
|
[BuiltInTemplateName.openapiJson]: './',
|
|
43
33
|
},
|
|
44
34
|
},
|
|
45
35
|
[BuiltInTemplateName.openapiJson]: {
|
|
46
|
-
templatePath:
|
|
36
|
+
templatePath: 'vovk-cli/client-templates/openapi-json/',
|
|
47
37
|
},
|
|
48
38
|
[BuiltInTemplateName.tsBase]: {
|
|
49
|
-
templatePath:
|
|
39
|
+
templatePath: 'vovk-cli/client-templates/ts-base/',
|
|
50
40
|
requires: {
|
|
51
41
|
[BuiltInTemplateName.schemaTs]: './',
|
|
52
42
|
[BuiltInTemplateName.mixins]: './', // used conditionally if OpenAPI mixins are used
|
|
53
43
|
},
|
|
54
44
|
},
|
|
55
|
-
[BuiltInTemplateName.jsBase]: {
|
|
56
|
-
templatePath: `vovk-cli/client-templates/${BuiltInTemplateName.jsBase}/`,
|
|
57
|
-
requires: {
|
|
58
|
-
[BuiltInTemplateName.schemaJs]: './',
|
|
59
|
-
[BuiltInTemplateName.mixins]: './', // used conditionally if OpenAPI mixins are used
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
45
|
[BuiltInTemplateName.ts]: {
|
|
63
46
|
requires: {
|
|
64
47
|
[BuiltInTemplateName.tsBase]: './',
|
|
65
48
|
[BuiltInTemplateName.openapiTs]: './',
|
|
66
49
|
},
|
|
67
50
|
},
|
|
68
|
-
[BuiltInTemplateName.js]: {
|
|
69
|
-
requires: {
|
|
70
|
-
[BuiltInTemplateName.jsBase]: './',
|
|
71
|
-
[BuiltInTemplateName.openapiJs]: './',
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
51
|
[BuiltInTemplateName.schemaTs]: {
|
|
75
|
-
templatePath:
|
|
76
|
-
},
|
|
77
|
-
[BuiltInTemplateName.schemaJs]: {
|
|
78
|
-
templatePath: `vovk-cli/client-templates/${BuiltInTemplateName.schemaJs}/`,
|
|
52
|
+
templatePath: 'vovk-cli/client-templates/schema-ts/',
|
|
79
53
|
},
|
|
80
54
|
[BuiltInTemplateName.schemaJson]: {
|
|
81
|
-
templatePath:
|
|
55
|
+
templatePath: 'vovk-cli/client-templates/schema-json/',
|
|
82
56
|
},
|
|
83
57
|
[BuiltInTemplateName.readme]: {
|
|
84
|
-
templatePath:
|
|
58
|
+
templatePath: 'vovk-cli/client-templates/readme/',
|
|
85
59
|
},
|
|
86
60
|
[BuiltInTemplateName.packageJson]: {
|
|
87
|
-
templatePath:
|
|
61
|
+
templatePath: 'vovk-cli/client-templates/package-json/',
|
|
88
62
|
},
|
|
89
63
|
[BuiltInTemplateName.mixins]: {
|
|
90
|
-
templatePath:
|
|
64
|
+
templatePath: 'vovk-cli/client-templates/mixins/',
|
|
91
65
|
},
|
|
92
66
|
[BuiltInTemplateName.rsSrc]: {
|
|
93
|
-
templatePath:
|
|
67
|
+
templatePath: 'vovk-rust/client-templates/rs-src/',
|
|
94
68
|
requires: {
|
|
95
69
|
[BuiltInTemplateName.schemaJson]: './',
|
|
96
70
|
},
|
|
97
71
|
},
|
|
98
72
|
[BuiltInTemplateName.rsPkg]: {
|
|
99
|
-
templatePath:
|
|
73
|
+
templatePath: 'vovk-rust/client-templates/rs-pkg/',
|
|
100
74
|
},
|
|
101
75
|
[BuiltInTemplateName.rsReadme]: {
|
|
102
|
-
templatePath:
|
|
76
|
+
templatePath: 'vovk-rust/client-templates/rs-readme/',
|
|
103
77
|
},
|
|
104
78
|
[BuiltInTemplateName.rs]: {
|
|
105
79
|
composedClient: {
|
|
@@ -112,16 +86,16 @@ export function getTemplateDefs(userTemplateDefs = {}) {
|
|
|
112
86
|
},
|
|
113
87
|
},
|
|
114
88
|
[BuiltInTemplateName.pySrc]: {
|
|
115
|
-
templatePath:
|
|
89
|
+
templatePath: 'vovk-python/client-templates/py-src/',
|
|
116
90
|
requires: {
|
|
117
91
|
[BuiltInTemplateName.schemaJson]: './',
|
|
118
92
|
},
|
|
119
93
|
},
|
|
120
94
|
[BuiltInTemplateName.pyPkg]: {
|
|
121
|
-
templatePath:
|
|
95
|
+
templatePath: 'vovk-python/client-templates/py-pkg/',
|
|
122
96
|
},
|
|
123
97
|
[BuiltInTemplateName.pyReadme]: {
|
|
124
|
-
templatePath:
|
|
98
|
+
templatePath: 'vovk-python/client-templates/py-readme/',
|
|
125
99
|
},
|
|
126
100
|
[BuiltInTemplateName.py]: {
|
|
127
101
|
composedClient: {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { pathToFileURL } from 'node:url';
|
|
2
1
|
import { readFile } from 'node:fs/promises';
|
|
3
2
|
import { createRequire } from 'node:module';
|
|
4
3
|
import { dirname, extname } from 'node:path';
|
|
4
|
+
import { pathToFileURL } from 'node:url';
|
|
5
5
|
import vm from 'node:vm';
|
|
6
|
-
import { getConfigAbsolutePaths } from './
|
|
6
|
+
import { getConfigAbsolutePaths } from './get-config-absolute-paths.mjs';
|
|
7
7
|
const isVMModulesEnabled = typeof vm.SourceTextModule !== 'undefined';
|
|
8
8
|
export async function getUserConfig({ configPath: givenConfigPath, cwd, }) {
|
|
9
9
|
const configAbsolutePaths = await getConfigAbsolutePaths({ configPath: givenConfigPath, cwd });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import type { LogLevelNames } from 'loglevel';
|
|
1
2
|
import type { VovkConfig } from 'vovk';
|
|
2
3
|
import { type VovkStrictConfig } from 'vovk/internal';
|
|
3
|
-
import
|
|
4
|
-
import { getLogger } from '../../utils/getLogger.mjs';
|
|
4
|
+
import { getLogger } from '../../utils/get-logger.mjs';
|
|
5
5
|
export declare function getConfig({ configPath, cwd, logLevel, }: {
|
|
6
6
|
configPath?: string;
|
|
7
7
|
cwd: string;
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { VovkSchemaIdEnum } from 'vovk/internal';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
3
|
+
import { chalkHighlightThing } from '../../utils/chalk-highlight-thing.mjs';
|
|
4
|
+
import { getLogger } from '../../utils/get-logger.mjs';
|
|
5
|
+
import { normalizeOpenAPIMixin } from '../../utils/normalize-openapi-mixin.mjs';
|
|
6
|
+
import { getRelativeSrcRoot } from './get-relative-src-root.mjs';
|
|
7
|
+
import { BuiltInTemplateName, getTemplateDefs } from './get-template-defs.mjs';
|
|
8
|
+
import { getUserConfig } from './get-user-config.mjs';
|
|
9
9
|
export async function getConfig({ configPath, cwd, logLevel, }) {
|
|
10
10
|
const { configAbsolutePaths, error, userConfig } = await getUserConfig({
|
|
11
11
|
configPath,
|
|
12
12
|
cwd,
|
|
13
13
|
});
|
|
14
|
+
// a config that exists but fails to load must not be silently replaced by defaults
|
|
15
|
+
if (!userConfig && configAbsolutePaths.length) {
|
|
16
|
+
throw new Error(`Failed to load config file at ${chalkHighlightThing(configAbsolutePaths[0])}. ${error?.message ?? 'Unknown error'}`);
|
|
17
|
+
}
|
|
14
18
|
const conf = userConfig ?? {};
|
|
15
19
|
logLevel = logLevel ?? conf.logLevel ?? 'info';
|
|
16
20
|
const log = getLogger(logLevel);
|
|
@@ -24,9 +28,9 @@ export async function getConfig({ configPath, cwd, logLevel, }) {
|
|
|
24
28
|
composedClient: {
|
|
25
29
|
...conf.composedClient,
|
|
26
30
|
enabled: conf.composedClient?.enabled ?? true,
|
|
27
|
-
fromTemplates: conf.composedClient?.fromTemplates ?? [BuiltInTemplateName.
|
|
28
|
-
outDir: conf.composedClient?.outDir ?? '
|
|
29
|
-
prettifyClient: conf.composedClient?.prettifyClient ??
|
|
31
|
+
fromTemplates: conf.composedClient?.fromTemplates ?? [BuiltInTemplateName.ts],
|
|
32
|
+
outDir: conf.composedClient?.outDir ?? path.join(srcRoot ?? '.', 'client'),
|
|
33
|
+
prettifyClient: conf.composedClient?.prettifyClient ?? true,
|
|
30
34
|
},
|
|
31
35
|
segmentedClient: {
|
|
32
36
|
...conf.segmentedClient,
|
|
@@ -45,9 +49,10 @@ export async function getConfig({ configPath, cwd, logLevel, }) {
|
|
|
45
49
|
},
|
|
46
50
|
outputConfig: {},
|
|
47
51
|
build: conf.bundle?.build ??
|
|
48
|
-
|
|
52
|
+
// isMissingBuild lets the bundle command fail fast before doing any work
|
|
53
|
+
Object.assign(() => {
|
|
49
54
|
throw new Error('No bundle.build function specified');
|
|
50
|
-
}),
|
|
55
|
+
}, { isMissingBuild: true }),
|
|
51
56
|
...conf.bundle,
|
|
52
57
|
},
|
|
53
58
|
modulesDir: conf.modulesDir ?? path.join(srcRoot ?? '.', 'modules'),
|
|
@@ -86,7 +91,7 @@ export async function getConfig({ configPath, cwd, logLevel, }) {
|
|
|
86
91
|
config.exposeConfigKeys = conf.exposeConfigKeys;
|
|
87
92
|
} // else it's false and exposeConfigKeys already is []
|
|
88
93
|
if (!userConfig) {
|
|
89
|
-
log.warn(`
|
|
94
|
+
log.warn(`No config file found at ${chalkHighlightThing(`${cwd}/`)}. Using default values.`);
|
|
90
95
|
}
|
|
91
96
|
return { config, srcRoot, configAbsolutePaths, userConfig, log };
|
|
92
97
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import { getConfig } from './getConfig/index.mjs';
|
|
3
|
-
import { getPackageJson } from '../utils/getPackageJson.mjs';
|
|
4
1
|
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { getPackageJson } from '../utils/get-package-json.mjs';
|
|
4
|
+
import { getConfig } from './get-config/index.mjs';
|
|
5
5
|
export async function getProjectInfo({ port: givenPort, cwd = process.cwd(), configPath, srcRootRequired = true, logLevel, } = {
|
|
6
6
|
logLevel: 'info',
|
|
7
7
|
}) {
|