vovk-cli 0.0.1-draft.103 → 0.0.1-draft.105
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/client-templates/main/main.cjs.ejs +5 -6
- package/client-templates/main/main.d.cts.ejs +4 -4
- package/client-templates/module/module.d.mts.ejs +4 -4
- package/client-templates/module/module.mjs.ejs +5 -6
- package/client-templates/ts/index.ts.ejs +6 -8
- package/dist/dev/{diffSchema.d.mts → diffSegmentSchema.d.mts} +3 -3
- package/dist/dev/{diffSchema.mjs → diffSegmentSchema.mjs} +1 -1
- package/dist/dev/ensureSchemaFiles.mjs +22 -10
- package/dist/dev/index.mjs +29 -23
- package/dist/dev/isSegmentSchemaEmpty.d.mts +2 -0
- package/dist/dev/isSegmentSchemaEmpty.mjs +4 -0
- package/dist/dev/logDiffResult.d.mts +1 -1
- package/dist/dev/logDiffResult.mjs +1 -1
- package/dist/dev/writeConfigJson.d.mts +2 -0
- package/dist/dev/writeConfigJson.mjs +15 -0
- package/dist/dev/writeOneSegmentSchemaFile.d.mts +12 -0
- package/dist/dev/{writeOneSchemaFile.mjs → writeOneSegmentSchemaFile.mjs} +9 -6
- package/dist/generate/getClientTemplates.d.mts +2 -2
- package/dist/generate/index.d.mts +4 -4
- package/dist/generate/index.mjs +6 -6
- package/dist/getProjectInfo/getConfig.d.mts +2 -2
- package/dist/getProjectInfo/getConfig.mjs +7 -0
- package/dist/getProjectInfo/getUserConfig.d.mts +1 -1
- package/dist/getProjectInfo/index.d.mts +3 -3
- package/dist/getProjectInfo/index.mjs +2 -2
- package/dist/index.d.mts +0 -2
- package/dist/index.mjs +5 -5
- package/dist/locateSegments.d.mts +1 -1
- package/dist/new/render.d.mts +2 -1
- package/dist/new/render.mjs +0 -8
- package/dist/types.d.mts +1 -53
- package/dist/utils/debounceWithArgs.d.mts +1 -1
- package/package.json +2 -2
- package/dist/dev/isSchemaEmpty.d.mts +0 -2
- package/dist/dev/isSchemaEmpty.mjs +0 -4
- package/dist/dev/writeOneSchemaFile.d.mts +0 -12
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
<%- `// auto-generated ${new Date().toISOString()}\n/* eslint-disable */` %>
|
|
2
2
|
const { default: fetcher } = require('<%= t.imports.fetcher %>');
|
|
3
3
|
const { default: createRPC } = require('<%= t.imports.createRPC %>');
|
|
4
|
-
const
|
|
4
|
+
const fullSchema = require('<%= t.imports.fullSchema %>');
|
|
5
5
|
const { default: validateOnClient = null } = <%- t.imports.validateOnClient ? `require('${t.imports.validateOnClient}')` : '{}'%>;
|
|
6
6
|
const apiRoot = '<%= t.apiRoot %>';
|
|
7
|
-
<% t.segments.forEach((segment) => {
|
|
8
|
-
Object.keys(
|
|
9
|
-
exports.<%=
|
|
10
|
-
|
|
11
|
-
'<%= segment.segmentName %>',
|
|
7
|
+
<% Object.values(t.fullSchema.segments).forEach((segment) => {
|
|
8
|
+
Object.keys(segment.controllers).forEach((controllerName) => { %>
|
|
9
|
+
exports.<%= controllerName %> = createRPC(
|
|
10
|
+
fullSchema, '<%= segment.segmentName %>', '<%= controllerName %>',
|
|
12
11
|
{ fetcher, validateOnClient, defaultOptions: { apiRoot } }
|
|
13
12
|
);
|
|
14
13
|
<% })
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
import type { VovkClientFetcher } from 'vovk';
|
|
4
4
|
import type fetcher from '<%= t.imports.fetcher %>';
|
|
5
5
|
import type createRPC from '<%= t.imports.createRPC %>';
|
|
6
|
-
<% t.segments.forEach((segment, i) => { if(Object.keys(
|
|
6
|
+
<% Object.values(t.fullSchema.segments).forEach((segment, i) => { if(Object.keys(segment.controllers).length) { %>
|
|
7
7
|
import type { Controllers as Controllers<%= i %> } from "<%= segment.segmentImportPath %>";
|
|
8
8
|
<% }}) %>
|
|
9
9
|
type Options = typeof fetcher extends VovkClientFetcher<infer U> ? U : never;
|
|
10
|
-
<% t.segments.forEach((segment, i) => {
|
|
11
|
-
Object.keys(
|
|
12
|
-
export const <%=
|
|
10
|
+
<% Object.values(t.fullSchema.segments).forEach((segment, i) => {
|
|
11
|
+
Object.keys(segment.controllers).forEach((controllerName) => { %>
|
|
12
|
+
export const <%= controllerName %>: ReturnType<typeof createRPC<Controllers<%= i %>["<%= controllerName %>"], Options>>;
|
|
13
13
|
<% })
|
|
14
14
|
}) %>
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
import type { VovkClientFetcher } from 'vovk';
|
|
4
4
|
import type fetcher from '<%= t.imports.module.fetcher %>';
|
|
5
5
|
import type createRPC from '<%= t.imports.module.createRPC %>';
|
|
6
|
-
<% t.segments.forEach((segment, i) => { if(Object.keys(
|
|
6
|
+
<% Object.values(t.fullSchema.segments).forEach((segment, i) => { if(Object.keys(segment.controllers).length) { %>
|
|
7
7
|
import type { Controllers as Controllers<%= i %> } from "<%= segment.segmentImportPath %>";
|
|
8
8
|
<% }}) %>
|
|
9
9
|
type Options = typeof fetcher extends VovkClientFetcher<infer U> ? U : never;
|
|
10
|
-
<% t.segments.forEach((segment, i) => {
|
|
11
|
-
Object.keys(
|
|
12
|
-
export const <%=
|
|
10
|
+
<% Object.values(t.fullSchema.segments).forEach((segment, i) => {
|
|
11
|
+
Object.keys(segment.controllers).forEach((controllerName) => { %>
|
|
12
|
+
export const <%= controllerName %>: ReturnType<typeof createRPC<Controllers<%= i %>["<%= controllerName %>"], Options>>;
|
|
13
13
|
<% })
|
|
14
14
|
}) %>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<%- `// auto-generated ${new Date().toISOString()}\n/* eslint-disable */` %>
|
|
2
2
|
import fetcherImport from '<%= t.imports.module.fetcher %>';
|
|
3
3
|
import createRPCImport from '<%= t.imports.module.createRPC %>';
|
|
4
|
-
import
|
|
4
|
+
import fullSchema from '<%= t.imports.module.fullSchema %>';
|
|
5
5
|
<% if (t.imports.module.validateOnClient) { %>
|
|
6
6
|
import validateOnClientImport from '<%= t.imports.module.validateOnClient %>';
|
|
7
7
|
const validateOnClient = validateOnClientImport.default || validateOnClientImport;
|
|
@@ -11,11 +11,10 @@ const validateOnClient = undefined;
|
|
|
11
11
|
const apiRoot = '<%= t.apiRoot %>';
|
|
12
12
|
const fetcher = fetcherImport.default || fetcherImport;
|
|
13
13
|
const createRPC = createRPCImport.default || createRPCImport;
|
|
14
|
-
<% t.segments.forEach((segment, i) => {
|
|
15
|
-
Object.keys(
|
|
16
|
-
export const <%=
|
|
17
|
-
|
|
18
|
-
'<%= segment.segmentName %>',
|
|
14
|
+
<% Object.values(t.fullSchema.segments).forEach((segment, i) => {
|
|
15
|
+
Object.keys(segment.controllers).forEach((controllerName) => { %>
|
|
16
|
+
export const <%= controllerName %> = createRPC(
|
|
17
|
+
fullSchema, '<%= segment.segmentName %>', '<%= controllerName %>',
|
|
19
18
|
{ fetcher, validateOnClient, defaultOptions: { apiRoot } }
|
|
20
19
|
);
|
|
21
20
|
<%
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import type { VovkClientFetcher } from 'vovk';
|
|
3
3
|
import fetcher from '<%= t.imports.fetcher %>';
|
|
4
4
|
import createRPC from '<%= t.imports.createRPC %>';
|
|
5
|
-
import
|
|
6
|
-
<% t.segments.forEach((segment, i) => { if(Object.keys(
|
|
5
|
+
import fullSchema from '<%= t.imports.fullSchema %>';
|
|
6
|
+
<% Object.values(t.fullSchema.segments).forEach((segment, i) => { if(Object.keys(segment.controllers).length) { %>
|
|
7
7
|
import type { Controllers as Controllers<%= i %> } from "<%= segment.segmentImportPath %>";
|
|
8
8
|
<% }}) %>
|
|
9
9
|
<% if (t.imports.validateOnClient) { %>
|
|
@@ -13,12 +13,10 @@ const validateOnClient = undefined;
|
|
|
13
13
|
<% } %>
|
|
14
14
|
type Options = typeof fetcher extends VovkClientFetcher<infer U> ? U : never;
|
|
15
15
|
const apiRoot = '<%= t.apiRoot %>';
|
|
16
|
-
|
|
17
|
-
<%
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
schema['<%= segment.segmentName %>'].controllers.<%= key %>,
|
|
21
|
-
'<%= segment.segmentName %>',
|
|
16
|
+
<% Object.values(t.fullSchema.segments).forEach((segment, i) => { %>
|
|
17
|
+
<% Object.keys(segment.controllers).forEach((controllerName) => { %>
|
|
18
|
+
export const <%= controllerName %> = createRPC<Controllers<%= i %>["<%= controllerName %>"], Options>(
|
|
19
|
+
fullSchema, '<%= segment.segmentName %>', '<%= controllerName %>',
|
|
22
20
|
{ fetcher, validateOnClient, defaultOptions: { apiRoot } }
|
|
23
21
|
);
|
|
24
22
|
<% }) %>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { VovkControllerSchema,
|
|
1
|
+
import type { VovkControllerSchema, VovkSegmentSchema } from 'vovk';
|
|
2
2
|
interface HandlersDiff {
|
|
3
3
|
nameOfClass: string;
|
|
4
4
|
added: string[];
|
|
@@ -14,7 +14,7 @@ export interface DiffResult {
|
|
|
14
14
|
controllers: ControllersDiff;
|
|
15
15
|
}
|
|
16
16
|
export declare function diffHandlers<T extends VovkControllerSchema['handlers']>(oldHandlers: T, newHandlers: T, nameOfClass: string): HandlersDiff;
|
|
17
|
-
export declare function diffControllers<T extends
|
|
17
|
+
export declare function diffControllers<T extends VovkSegmentSchema['controllers']>(oldItems: T, newItems: T): ControllersDiff;
|
|
18
18
|
/**
|
|
19
19
|
example output:
|
|
20
20
|
{
|
|
@@ -32,5 +32,5 @@ example output:
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
*/
|
|
35
|
-
export default function
|
|
35
|
+
export default function diffSegmentSchema(oldJson: VovkSegmentSchema, newJson: VovkSegmentSchema): DiffResult;
|
|
36
36
|
export {};
|
|
@@ -1,32 +1,43 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import debounce from 'lodash/debounce.js';
|
|
4
|
-
import writeOneSchemaFile, {
|
|
4
|
+
import writeOneSchemaFile, { SEGMENTS_SCHEMA_DIR_NAME, ROOT_SEGMENT_SCHEMA_NAME, } from './writeOneSegmentSchemaFile.mjs';
|
|
5
5
|
import formatLoggedSegmentName from '../utils/formatLoggedSegmentName.mjs';
|
|
6
|
+
import writeConfigJson from './writeConfigJson.mjs';
|
|
6
7
|
/**
|
|
7
8
|
* Ensure that the schema files are created to avoid any import errors.
|
|
8
9
|
*/
|
|
9
10
|
export default async function ensureSchemaFiles(projectInfo, schemaOutAbsolutePath, segmentNames) {
|
|
10
11
|
const now = Date.now();
|
|
11
12
|
let hasChanged = false;
|
|
12
|
-
const schemaJsonOutAbsolutePath = path.join(schemaOutAbsolutePath,
|
|
13
|
+
const schemaJsonOutAbsolutePath = path.join(schemaOutAbsolutePath, SEGMENTS_SCHEMA_DIR_NAME);
|
|
13
14
|
const jsContent = `// auto-generated ${new Date().toISOString()}
|
|
15
|
+
module.exports.config = require('./config.json');
|
|
16
|
+
module.exports.segments = {
|
|
14
17
|
${segmentNames
|
|
15
18
|
.map((segmentName) => {
|
|
16
|
-
return `
|
|
19
|
+
return ` '${segmentName}': require('./${SEGMENTS_SCHEMA_DIR_NAME}/${segmentName || ROOT_SEGMENT_SCHEMA_NAME}.json'),`;
|
|
17
20
|
})
|
|
18
|
-
.join('\n')}
|
|
21
|
+
.join('\n')}
|
|
22
|
+
}`;
|
|
19
23
|
const dTsContent = `// auto-generated ${new Date().toISOString()}
|
|
20
|
-
import type {
|
|
24
|
+
import type { VovkSegmentSchema, VovkStrictConfig } from 'vovk';
|
|
21
25
|
declare const fullSchema: {
|
|
22
|
-
|
|
26
|
+
config: Partial<VovkStrictConfig>;
|
|
27
|
+
segments: {
|
|
28
|
+
${segmentNames.map((segmentName) => ` '${segmentName}': VovkSegmentSchema;`).join('\n')}
|
|
29
|
+
};
|
|
23
30
|
};
|
|
24
31
|
export default fullSchema;`;
|
|
25
32
|
const tsContent = `// auto-generated ${new Date().toISOString()}
|
|
26
|
-
import type {
|
|
27
|
-
|
|
33
|
+
import type { VovkSegmentSchema, VovkStrictConfig } from 'vovk';
|
|
34
|
+
import config from './config.json';
|
|
35
|
+
${segmentNames.map((segmentName, i) => `import segment${i} from './${SEGMENTS_SCHEMA_DIR_NAME}/${segmentName || ROOT_SEGMENT_SCHEMA_NAME}.json';`).join('\n')}
|
|
28
36
|
const fullSchema = {
|
|
29
|
-
|
|
37
|
+
config: config as unknown as Partial<VovkStrictConfig>,
|
|
38
|
+
segments: {
|
|
39
|
+
${segmentNames.map((segmentName, i) => ` '${segmentName}': segment${i} as unknown as VovkSegmentSchema,`).join('\n')}
|
|
40
|
+
}
|
|
30
41
|
};
|
|
31
42
|
export default fullSchema;`;
|
|
32
43
|
const jsAbsolutePath = path.join(schemaOutAbsolutePath, 'main.cjs');
|
|
@@ -36,11 +47,12 @@ export default fullSchema;`;
|
|
|
36
47
|
const existingDTs = await fs.readFile(dTsAbsolutePath, 'utf-8').catch(() => null);
|
|
37
48
|
const existingTs = await fs.readFile(tsAbsolutePath, 'utf-8').catch(() => null);
|
|
38
49
|
await fs.mkdir(schemaJsonOutAbsolutePath, { recursive: true });
|
|
50
|
+
await writeConfigJson(schemaOutAbsolutePath, projectInfo);
|
|
39
51
|
// Create JSON files (if not exist) with name [segmentName].json (where segmentName can include /, which means the folder structure can be nested)
|
|
40
52
|
await Promise.all(segmentNames.map(async (segmentName) => {
|
|
41
53
|
const { isCreated } = await writeOneSchemaFile({
|
|
42
54
|
schemaOutAbsolutePath,
|
|
43
|
-
|
|
55
|
+
segmentSchema: {
|
|
44
56
|
emitSchema: false,
|
|
45
57
|
segmentName,
|
|
46
58
|
controllers: {},
|
package/dist/dev/index.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import capitalize from 'lodash/capitalize.js';
|
|
|
7
7
|
import debounce from 'lodash/debounce.js';
|
|
8
8
|
import once from 'lodash/once.js';
|
|
9
9
|
import { debouncedEnsureSchemaFiles } from './ensureSchemaFiles.mjs';
|
|
10
|
-
import
|
|
10
|
+
import writeOneSegmentSchemaFile from './writeOneSegmentSchemaFile.mjs';
|
|
11
11
|
import logDiffResult from './logDiffResult.mjs';
|
|
12
12
|
import ensureClient from '../generate/ensureClient.mjs';
|
|
13
13
|
import getProjectInfo from '../getProjectInfo/index.mjs';
|
|
@@ -15,11 +15,15 @@ import generate from '../generate/index.mjs';
|
|
|
15
15
|
import locateSegments from '../locateSegments.mjs';
|
|
16
16
|
import debounceWithArgs from '../utils/debounceWithArgs.mjs';
|
|
17
17
|
import formatLoggedSegmentName from '../utils/formatLoggedSegmentName.mjs';
|
|
18
|
-
import
|
|
18
|
+
import isSegmentSchemaEmpty from './isSegmentSchemaEmpty.mjs';
|
|
19
|
+
import writeConfigJson from './writeConfigJson.mjs';
|
|
19
20
|
export class VovkDev {
|
|
20
21
|
#projectInfo;
|
|
21
22
|
#segments = [];
|
|
22
|
-
#
|
|
23
|
+
#fullSchema = {
|
|
24
|
+
segments: {},
|
|
25
|
+
config: {},
|
|
26
|
+
};
|
|
23
27
|
#isWatching = false;
|
|
24
28
|
#modulesWatcher = null;
|
|
25
29
|
#segmentWatcher = null;
|
|
@@ -145,6 +149,7 @@ export class VovkDev {
|
|
|
145
149
|
new Promise((resolve) => this.#watchModules(() => resolve(0))),
|
|
146
150
|
new Promise((resolve) => this.#watchSegments(() => resolve(0))),
|
|
147
151
|
]);
|
|
152
|
+
const schemaOutAbsolutePath = path.join(cwd, this.#projectInfo.config.schemaOutDir);
|
|
148
153
|
if (isInitial) {
|
|
149
154
|
callback();
|
|
150
155
|
}
|
|
@@ -152,6 +157,7 @@ export class VovkDev {
|
|
|
152
157
|
log.info('Config file has been updated');
|
|
153
158
|
this.#generate();
|
|
154
159
|
}
|
|
160
|
+
await writeConfigJson(schemaOutAbsolutePath, this.#projectInfo);
|
|
155
161
|
isInitial = false;
|
|
156
162
|
}, 1000);
|
|
157
163
|
chokidar
|
|
@@ -203,11 +209,11 @@ export class VovkDev {
|
|
|
203
209
|
const importRegex = /import\s*{[^}]*\b(get|post|put|del|head|options)\b[^}]*}\s*from\s*['"]vovk['"]/;
|
|
204
210
|
if (importRegex.test(code) && namesOfClasses.length) {
|
|
205
211
|
const affectedSegments = this.#segments.filter((s) => {
|
|
206
|
-
const
|
|
207
|
-
if (!
|
|
212
|
+
const segmentSchema = this.#fullSchema.segments[s.segmentName];
|
|
213
|
+
if (!segmentSchema)
|
|
208
214
|
return false;
|
|
209
|
-
const controllersByOriginalName = keyBy(
|
|
210
|
-
return namesOfClasses.some((name) =>
|
|
215
|
+
const controllersByOriginalName = keyBy(segmentSchema.controllers, 'originalControllerName');
|
|
216
|
+
return namesOfClasses.some((name) => segmentSchema.controllers[name] || controllersByOriginalName[name]);
|
|
211
217
|
});
|
|
212
218
|
if (affectedSegments.length) {
|
|
213
219
|
log.debug(`A file with controller ${namesOfClasses.join(', ')} have been modified at path "${filePath}". Segment(s) affected: ${JSON.stringify(affectedSegments.map((s) => s.segmentName))}`);
|
|
@@ -237,14 +243,14 @@ export class VovkDev {
|
|
|
237
243
|
log.warn(`Schema request to ${formatLoggedSegmentName(segmentName)} failed with status code ${resp.status} but expected 200.${probableCause ? ` Probable cause: ${probableCause}` : ''}`);
|
|
238
244
|
return { isError: true };
|
|
239
245
|
}
|
|
240
|
-
let
|
|
246
|
+
let segmentSchema = null;
|
|
241
247
|
try {
|
|
242
|
-
({ schema } = (await resp.json()));
|
|
248
|
+
({ schema: segmentSchema } = (await resp.json()));
|
|
243
249
|
}
|
|
244
250
|
catch (error) {
|
|
245
251
|
log.error(`Error parsing schema for ${formatLoggedSegmentName(segmentName)}: ${error.message}`);
|
|
246
252
|
}
|
|
247
|
-
await this.#
|
|
253
|
+
await this.#handleSegmentSchema(segmentName, segmentSchema);
|
|
248
254
|
}
|
|
249
255
|
catch (error) {
|
|
250
256
|
log.error(`Error requesting schema for ${formatLoggedSegmentName(segmentName)} at ${endpoint}: ${error.message}`);
|
|
@@ -252,26 +258,26 @@ export class VovkDev {
|
|
|
252
258
|
}
|
|
253
259
|
return { isError: false };
|
|
254
260
|
}, 500);
|
|
255
|
-
#generate = debounce(() => generate({ projectInfo: this.#projectInfo, segments: this.#segments,
|
|
256
|
-
async #
|
|
261
|
+
#generate = debounce(() => generate({ projectInfo: this.#projectInfo, segments: this.#segments, fullSchema: this.#fullSchema }).then(this.#onFirstTimeGenerate), 1000);
|
|
262
|
+
async #handleSegmentSchema(segmentName, segmentSchema) {
|
|
257
263
|
const { log, config, cwd } = this.#projectInfo;
|
|
258
|
-
if (!
|
|
259
|
-
log.warn(
|
|
264
|
+
if (!segmentSchema) {
|
|
265
|
+
log.warn(`${formatLoggedSegmentName(segmentName)} schema is null`);
|
|
260
266
|
return;
|
|
261
267
|
}
|
|
262
|
-
log.debug(`Handling received schema from ${formatLoggedSegmentName(
|
|
268
|
+
log.debug(`Handling received schema from ${formatLoggedSegmentName(segmentName)}`);
|
|
263
269
|
const schemaOutAbsolutePath = path.join(cwd, config.schemaOutDir);
|
|
264
|
-
const segment = this.#segments.find((s) => s.segmentName ===
|
|
270
|
+
const segment = this.#segments.find((s) => s.segmentName === segmentName);
|
|
265
271
|
if (!segment) {
|
|
266
|
-
log.warn(
|
|
272
|
+
log.warn(`${formatLoggedSegmentName(segmentName)} not found`);
|
|
267
273
|
return;
|
|
268
274
|
}
|
|
269
|
-
this.#
|
|
270
|
-
if (
|
|
275
|
+
this.#fullSchema.segments[segmentName] = segmentSchema;
|
|
276
|
+
if (segmentSchema.emitSchema) {
|
|
271
277
|
const now = Date.now();
|
|
272
|
-
const { diffResult } = await
|
|
278
|
+
const { diffResult } = await writeOneSegmentSchemaFile({
|
|
273
279
|
schemaOutAbsolutePath,
|
|
274
|
-
|
|
280
|
+
segmentSchema,
|
|
275
281
|
skipIfExists: false,
|
|
276
282
|
});
|
|
277
283
|
const timeTook = Date.now() - now;
|
|
@@ -280,10 +286,10 @@ export class VovkDev {
|
|
|
280
286
|
log.info(`Schema for ${formatLoggedSegmentName(segment.segmentName)} has been updated in ${timeTook}ms`);
|
|
281
287
|
}
|
|
282
288
|
}
|
|
283
|
-
else if (
|
|
289
|
+
else if (segmentSchema && !isSegmentSchemaEmpty(segmentSchema)) {
|
|
284
290
|
log.error(`Non-empty schema provided for ${formatLoggedSegmentName(segment.segmentName)} but "emitSchema" is false`);
|
|
285
291
|
}
|
|
286
|
-
if (this.#segments.every((s) => this.#
|
|
292
|
+
if (this.#segments.every((s) => this.#fullSchema.segments[s.segmentName])) {
|
|
287
293
|
log.debug(`All segments with "emitSchema" have schema.`);
|
|
288
294
|
this.#generate();
|
|
289
295
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { DiffResult } from './
|
|
1
|
+
import type { DiffResult } from './diffSegmentSchema.mjs';
|
|
2
2
|
import type { ProjectInfo } from '../getProjectInfo/index.mjs';
|
|
3
3
|
export default function logDiffResult(segmentName: string, diffResult: DiffResult, projectInfo: ProjectInfo): void;
|
|
@@ -20,7 +20,7 @@ export default function logDiffResult(segmentName, diffResult, projectInfo) {
|
|
|
20
20
|
diffNormalized.push({ what: 'controllerHandler', type: 'changed', name: `${handler.nameOfClass}.${name}` });
|
|
21
21
|
});
|
|
22
22
|
});
|
|
23
|
-
const LIMIT = diffNormalized.length <
|
|
23
|
+
const LIMIT = diffNormalized.length < 17 ? diffNormalized.length : 15;
|
|
24
24
|
const addedText = chalk.green('added');
|
|
25
25
|
const removedText = chalk.red('removed');
|
|
26
26
|
const changedText = chalk.cyan('changed');
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import pick from 'lodash/pick.js';
|
|
4
|
+
export default async function writeConfigJson(schemaOutAbsolutePath, projectInfo) {
|
|
5
|
+
const configJsonPath = path.join(schemaOutAbsolutePath, 'config.json');
|
|
6
|
+
const configStr = JSON.stringify(projectInfo ? pick(projectInfo.config, projectInfo.config.emitConfig) : {}, null, 2);
|
|
7
|
+
const existingStr = await fs.readFile(configJsonPath, 'utf-8').catch(() => null);
|
|
8
|
+
if (existingStr !== configStr) {
|
|
9
|
+
await fs.writeFile(configJsonPath, configStr);
|
|
10
|
+
projectInfo?.log.info(`config.json written to ${configJsonPath}`);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
projectInfo?.log.debug(`config.json is up to date at ${configJsonPath}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { VovkSegmentSchema } from 'vovk';
|
|
2
|
+
import { type DiffResult } from './diffSegmentSchema.mjs';
|
|
3
|
+
export declare const ROOT_SEGMENT_SCHEMA_NAME = "_root";
|
|
4
|
+
export declare const SEGMENTS_SCHEMA_DIR_NAME = "segments";
|
|
5
|
+
export default function writeOneSegmentSchemaFile({ schemaOutAbsolutePath, segmentSchema, skipIfExists, }: {
|
|
6
|
+
schemaOutAbsolutePath: string;
|
|
7
|
+
segmentSchema: VovkSegmentSchema;
|
|
8
|
+
skipIfExists?: boolean;
|
|
9
|
+
}): Promise<{
|
|
10
|
+
isCreated: boolean;
|
|
11
|
+
diffResult: DiffResult | null;
|
|
12
|
+
}>;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
|
-
import
|
|
3
|
+
import diffSegmentSchema from './diffSegmentSchema.mjs';
|
|
4
4
|
import getFileSystemEntryType from '../utils/getFileSystemEntryType.mjs';
|
|
5
5
|
export const ROOT_SEGMENT_SCHEMA_NAME = '_root';
|
|
6
|
-
export const
|
|
7
|
-
export default async function
|
|
8
|
-
const segmentPath = path.join(schemaOutAbsolutePath,
|
|
6
|
+
export const SEGMENTS_SCHEMA_DIR_NAME = 'segments';
|
|
7
|
+
export default async function writeOneSegmentSchemaFile({ schemaOutAbsolutePath, segmentSchema, skipIfExists = false, }) {
|
|
8
|
+
const segmentPath = path.join(schemaOutAbsolutePath, SEGMENTS_SCHEMA_DIR_NAME, `${segmentSchema.segmentName || ROOT_SEGMENT_SCHEMA_NAME}.json`);
|
|
9
9
|
if (skipIfExists && (await getFileSystemEntryType(segmentPath))) {
|
|
10
10
|
try {
|
|
11
11
|
await fs.stat(segmentPath);
|
|
@@ -16,14 +16,17 @@ export default async function writeOneSchemaFile({ schemaOutAbsolutePath, schema
|
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
await fs.mkdir(path.dirname(segmentPath), { recursive: true });
|
|
19
|
-
const schemaStr = JSON.stringify(
|
|
19
|
+
const schemaStr = JSON.stringify(segmentSchema, null, 2);
|
|
20
20
|
const existing = await fs.readFile(segmentPath, 'utf-8').catch(() => null);
|
|
21
21
|
if (existing === schemaStr) {
|
|
22
22
|
return { isCreated: false, diffResult: null };
|
|
23
23
|
}
|
|
24
24
|
await fs.writeFile(segmentPath, schemaStr);
|
|
25
25
|
if (existing) {
|
|
26
|
-
return {
|
|
26
|
+
return {
|
|
27
|
+
isCreated: false,
|
|
28
|
+
diffResult: diffSegmentSchema(JSON.parse(existing), segmentSchema),
|
|
29
|
+
};
|
|
27
30
|
}
|
|
28
31
|
return { isCreated: true, diffResult: null };
|
|
29
32
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { VovkStrictConfig } from '
|
|
1
|
+
import type { VovkStrictConfig } from 'vovk';
|
|
2
2
|
interface ClientTemplate {
|
|
3
3
|
templateName: string;
|
|
4
4
|
templatePath: string;
|
|
5
5
|
outPath: string;
|
|
6
|
-
|
|
6
|
+
emitFullSchema?: string | boolean;
|
|
7
7
|
}
|
|
8
8
|
export default function getClientTemplates({ config, cwd, generateFrom, }: {
|
|
9
9
|
config: VovkStrictConfig;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { VovkFullSchema } from 'vovk';
|
|
2
2
|
import type { ProjectInfo } from '../getProjectInfo/index.mjs';
|
|
3
3
|
import type { Segment } from '../locateSegments.mjs';
|
|
4
4
|
import { GenerateOptions } from '../types.mjs';
|
|
5
|
-
export default function generate({ projectInfo, segments,
|
|
5
|
+
export default function generate({ projectInfo, segments, forceNothingWrittenLog, templates, prettify: prettifyClient, fullSchema, emitFullSchema, }: {
|
|
6
6
|
projectInfo: ProjectInfo;
|
|
7
7
|
segments: Segment[];
|
|
8
|
-
segmentsSchema: Record<string, VovkSchema>;
|
|
9
8
|
forceNothingWrittenLog?: boolean;
|
|
10
|
-
|
|
9
|
+
fullSchema: VovkFullSchema;
|
|
10
|
+
} & Pick<GenerateOptions, 'templates' | 'prettify' | 'emitFullSchema'>): Promise<{
|
|
11
11
|
written: boolean;
|
|
12
12
|
path: string;
|
|
13
13
|
}>;
|
package/dist/generate/index.mjs
CHANGED
|
@@ -6,7 +6,8 @@ import prettify from '../utils/prettify.mjs';
|
|
|
6
6
|
import getClientTemplates from './getClientTemplates.mjs';
|
|
7
7
|
import chalkHighlightThing from '../utils/chalkHighlightThing.mjs';
|
|
8
8
|
import uniq from 'lodash/uniq.js';
|
|
9
|
-
export default async function generate({ projectInfo, segments,
|
|
9
|
+
export default async function generate({ projectInfo, segments, forceNothingWrittenLog, templates, prettify: prettifyClient, fullSchema, emitFullSchema, }) {
|
|
10
|
+
const segmentsSchema = fullSchema.segments;
|
|
10
11
|
const generateFrom = templates ?? projectInfo.config.generateFrom;
|
|
11
12
|
const noClient = templates?.[0] === 'none';
|
|
12
13
|
const { config, cwd, log, clientImports, apiRoot } = projectInfo;
|
|
@@ -26,8 +27,7 @@ export default async function generate({ projectInfo, segments, segmentsSchema,
|
|
|
26
27
|
const t = {
|
|
27
28
|
apiRoot,
|
|
28
29
|
imports: clientImports,
|
|
29
|
-
|
|
30
|
-
fullSchema: segmentsSchema,
|
|
30
|
+
fullSchema,
|
|
31
31
|
};
|
|
32
32
|
// Process each template in parallel
|
|
33
33
|
const processedTemplates = noClient
|
|
@@ -59,11 +59,11 @@ export default async function generate({ projectInfo, segments, segmentsSchema,
|
|
|
59
59
|
const usedTemplateNames = uniq(processedTemplates.filter(({ needsWriting }) => needsWriting).map(({ templateName }) => templateName));
|
|
60
60
|
let fullSchemaNames = [];
|
|
61
61
|
const DEFAULT_NAME = 'full-schema.json';
|
|
62
|
-
if (
|
|
62
|
+
if (emitFullSchema) {
|
|
63
63
|
fullSchemaNames.push(typeof fullSchema === 'string' ? fullSchema : DEFAULT_NAME);
|
|
64
64
|
fullSchemaNames.push(...templateFiles
|
|
65
|
-
.filter(({
|
|
66
|
-
.map(({
|
|
65
|
+
.filter(({ emitFullSchema }) => emitFullSchema)
|
|
66
|
+
.map(({ emitFullSchema }) => (typeof emitFullSchema === 'string' ? emitFullSchema : DEFAULT_NAME)));
|
|
67
67
|
}
|
|
68
68
|
fullSchemaNames = uniq(fullSchemaNames);
|
|
69
69
|
if (fullSchemaNames.length || usedTemplateNames.length > 0) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { VovkStrictConfig } from '
|
|
1
|
+
import type { VovkStrictConfig } from 'vovk';
|
|
2
2
|
export default function getConfig({ clientOutDir, cwd }: {
|
|
3
3
|
clientOutDir?: string;
|
|
4
4
|
cwd: string;
|
|
@@ -6,6 +6,6 @@ export default function getConfig({ clientOutDir, cwd }: {
|
|
|
6
6
|
config: VovkStrictConfig;
|
|
7
7
|
srcRoot: string;
|
|
8
8
|
configAbsolutePaths: string[];
|
|
9
|
-
userConfig: import("
|
|
9
|
+
userConfig: import("vovk").VovkConfig | null;
|
|
10
10
|
error: Error | undefined;
|
|
11
11
|
}>;
|
|
@@ -10,6 +10,7 @@ export default async function getConfig({ clientOutDir, cwd }) {
|
|
|
10
10
|
const createRPCImport = env.VOVK_CREATE_RPC_PATH ?? conf.createRPCImport ?? 'vovk/dist/client/createRPC.js';
|
|
11
11
|
const defaultClientTemplates = ['ts', 'module', 'main'];
|
|
12
12
|
const config = {
|
|
13
|
+
emitConfig: [],
|
|
13
14
|
modulesDir: env.VOVK_MODULES_DIR ?? conf.modulesDir ?? './' + [srcRoot, 'modules'].filter(Boolean).join('/'),
|
|
14
15
|
validateOnClientImport: typeof validateOnClientImport === 'string' ? [validateOnClientImport] : validateOnClientImport,
|
|
15
16
|
fetcherImport: typeof fetcherImport === 'string' ? [fetcherImport] : fetcherImport,
|
|
@@ -31,5 +32,11 @@ export default async function getConfig({ clientOutDir, cwd }) {
|
|
|
31
32
|
...conf.templates,
|
|
32
33
|
},
|
|
33
34
|
};
|
|
35
|
+
if (typeof conf.emitConfig === 'undefined' || conf.emitConfig === true) {
|
|
36
|
+
config.emitConfig = Object.keys(config);
|
|
37
|
+
}
|
|
38
|
+
else if (Array.isArray(conf.emitConfig)) {
|
|
39
|
+
config.emitConfig = conf.emitConfig;
|
|
40
|
+
}
|
|
34
41
|
return { config, srcRoot, configAbsolutePaths, userConfig, error };
|
|
35
42
|
}
|
|
@@ -9,14 +9,14 @@ export default function getProjectInfo({ port: givenPort, clientOutDir, cwd, }?:
|
|
|
9
9
|
apiRoot: string;
|
|
10
10
|
apiDir: string;
|
|
11
11
|
srcRoot: string;
|
|
12
|
-
config: import("
|
|
12
|
+
config: import("vovk").VovkStrictConfig;
|
|
13
13
|
clientImports: {
|
|
14
|
-
|
|
14
|
+
fullSchema: string;
|
|
15
15
|
fetcher: string;
|
|
16
16
|
createRPC: string;
|
|
17
17
|
validateOnClient: string | null;
|
|
18
18
|
module: {
|
|
19
|
-
|
|
19
|
+
fullSchema: string;
|
|
20
20
|
fetcher: string;
|
|
21
21
|
createRPC: string;
|
|
22
22
|
validateOnClient: string | null;
|
|
@@ -19,12 +19,12 @@ export default async function getProjectInfo({ port: givenPort, clientOutDir, cw
|
|
|
19
19
|
}
|
|
20
20
|
const getImportPath = (p) => (p.startsWith('.') ? path.relative(config.clientOutDir, p) : p);
|
|
21
21
|
const clientImports = {
|
|
22
|
-
|
|
22
|
+
fullSchema: schemaOutImportPath,
|
|
23
23
|
fetcher: getImportPath(config.fetcherImport[0]),
|
|
24
24
|
createRPC: getImportPath(config.createRPCImport[0]),
|
|
25
25
|
validateOnClient: config.validateOnClientImport ? getImportPath(config.validateOnClientImport[0]) : null,
|
|
26
26
|
module: {
|
|
27
|
-
|
|
27
|
+
fullSchema: schemaOutImportPath,
|
|
28
28
|
fetcher: getImportPath(config.fetcherImport[1] ?? config.fetcherImport[0]),
|
|
29
29
|
createRPC: getImportPath(config.createRPCImport[1] ?? config.createRPCImport[0]),
|
|
30
30
|
validateOnClient: config.validateOnClientImport
|
package/dist/index.d.mts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -75,24 +75,24 @@ program
|
|
|
75
75
|
.description('Generate RPC client from schema')
|
|
76
76
|
.option('--out, --client-out-dir <path>', 'path to output directory')
|
|
77
77
|
.option('--template, --templates <templates...>', 'client code templates ("ts", "compiled", "python", "none", a custom path)')
|
|
78
|
-
.option('--full-schema [fileName]', 'generate client with full schema')
|
|
78
|
+
.option('--emit-full-schema, --full-schema [fileName]', 'generate client with full schema')
|
|
79
79
|
.option('--prettify', 'prettify output files')
|
|
80
80
|
.action(async (options) => {
|
|
81
|
-
const { clientOutDir, templates, prettify,
|
|
81
|
+
const { clientOutDir, templates, prettify, emitFullSchema } = options;
|
|
82
82
|
const projectInfo = await getProjectInfo({ clientOutDir });
|
|
83
83
|
const { cwd, config, apiDir } = projectInfo;
|
|
84
84
|
const segments = await locateSegments({ dir: apiDir, config });
|
|
85
85
|
const schemaOutAbsolutePath = path.join(cwd, config.schemaOutDir);
|
|
86
86
|
const schemaImportUrl = pathToFileURL(path.join(schemaOutAbsolutePath, 'main.cjs')).href;
|
|
87
|
-
const { default:
|
|
87
|
+
const { default: fullSchema } = (await import(schemaImportUrl));
|
|
88
88
|
await generate({
|
|
89
89
|
projectInfo,
|
|
90
90
|
segments,
|
|
91
|
-
|
|
91
|
+
fullSchema,
|
|
92
92
|
templates,
|
|
93
93
|
prettify,
|
|
94
|
-
fullSchema,
|
|
95
94
|
forceNothingWrittenLog: true,
|
|
95
|
+
emitFullSchema,
|
|
96
96
|
});
|
|
97
97
|
});
|
|
98
98
|
program
|
package/dist/new/render.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { VovkConfig
|
|
1
|
+
import type { VovkConfig } from 'vovk';
|
|
2
|
+
import type { VovkModuleRenderResult } from '../types.mjs';
|
|
2
3
|
export default function render(codeTemplate: string, { config, withService, segmentName, moduleName, empty, templateFileName, }: {
|
|
3
4
|
cwd: string;
|
|
4
5
|
config: VovkConfig;
|
package/dist/new/render.mjs
CHANGED
|
@@ -8,14 +8,6 @@ export default async function render(codeTemplate, { config, withService, segmen
|
|
|
8
8
|
const getModuleDirName = (givenSegmentName, givenModuleName) => [config.modulesDir, givenSegmentName || config.rootSegmentModulesDirName, _.camelCase(givenModuleName)]
|
|
9
9
|
.filter(Boolean)
|
|
10
10
|
.join('/');
|
|
11
|
-
/*
|
|
12
|
-
<% var modulePascalName = _.upperFirst(_.camelCase(moduleName)); %>
|
|
13
|
-
<% var modulePascalNamePlural = pluralize(modulePascalName); %>
|
|
14
|
-
<% var controllerName = modulePascalName + 'Controller'; %>
|
|
15
|
-
<% var compiledName = modulePascalName + 'RPC'; %>
|
|
16
|
-
<% var serviceName = modulePascalName + 'Service'; %>
|
|
17
|
-
<% var prefix = pluralize(_.kebabCase(moduleName).toLowerCase()); %>
|
|
18
|
-
*/
|
|
19
11
|
const theThing = _.camelCase(moduleName);
|
|
20
12
|
const TheThing = _.upperFirst(theThing);
|
|
21
13
|
const the_thing = _.snakeCase(moduleName);
|
package/dist/types.d.mts
CHANGED
|
@@ -1,55 +1,4 @@
|
|
|
1
1
|
import type { LogLevelNames } from 'loglevel';
|
|
2
|
-
export type KnownAny = any;
|
|
3
|
-
export type VovkEnv = {
|
|
4
|
-
PORT?: string;
|
|
5
|
-
VOVK_CLIENT_OUT_DIR?: string;
|
|
6
|
-
VOVK_SCHEMA_OUT_DIR?: string;
|
|
7
|
-
VOVK_FETCHER_PATH?: string;
|
|
8
|
-
VOVK_VALIDATE_ON_CLIENT_PATH?: string;
|
|
9
|
-
VOVK_CREATE_RPC_PATH?: string;
|
|
10
|
-
VOVK_MODULES_DIR?: string;
|
|
11
|
-
VOVK_ORIGIN?: string;
|
|
12
|
-
VOVK_ROOT_ENTRY?: string;
|
|
13
|
-
VOVK_API_ENTRY_POINT?: string;
|
|
14
|
-
VOVK_ROOT_SEGMENT_MODULES_DIR_NAME?: string;
|
|
15
|
-
VOVK_LOG_LEVEL?: LogLevelNames;
|
|
16
|
-
VOVK_PRETTIFY_CLIENT?: string;
|
|
17
|
-
VOVK_DEV_HTTPS?: string;
|
|
18
|
-
__VOVK_START_WATCHER_IN_STANDALONE_MODE__?: 'true';
|
|
19
|
-
__VOVK_EXIT__?: 'true' | 'false';
|
|
20
|
-
};
|
|
21
|
-
type GenerateFrom = (string | {
|
|
22
|
-
templatePath: string;
|
|
23
|
-
outDir?: string;
|
|
24
|
-
templateName?: string;
|
|
25
|
-
fullSchema?: string | boolean;
|
|
26
|
-
})[];
|
|
27
|
-
export type VovkConfig = {
|
|
28
|
-
clientOutDir?: string;
|
|
29
|
-
schemaOutDir?: string;
|
|
30
|
-
fetcherImport?: string | string[];
|
|
31
|
-
validateOnClientImport?: string | string[] | null;
|
|
32
|
-
createRPCImport?: string | string[];
|
|
33
|
-
modulesDir?: string;
|
|
34
|
-
rootEntry?: string;
|
|
35
|
-
origin?: string;
|
|
36
|
-
rootSegmentModulesDirName?: string;
|
|
37
|
-
logLevel?: LogLevelNames;
|
|
38
|
-
prettifyClient?: boolean;
|
|
39
|
-
devHttps?: boolean;
|
|
40
|
-
generateFrom?: GenerateFrom | ((value: GenerateFrom) => GenerateFrom);
|
|
41
|
-
templates?: {
|
|
42
|
-
service?: string;
|
|
43
|
-
controller?: string;
|
|
44
|
-
[key: string]: string | undefined;
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
|
-
export type VovkStrictConfig = Required<Omit<VovkConfig, 'validateOnClientImport' | 'fetcherImport' | 'createRPCImport' | 'generateFrom'>> & {
|
|
48
|
-
validateOnClientImport: string[] | null;
|
|
49
|
-
fetcherImport: string[];
|
|
50
|
-
createRPCImport: string[];
|
|
51
|
-
generateFrom: GenerateFrom;
|
|
52
|
-
};
|
|
53
2
|
export type VovkModuleRenderResult = {
|
|
54
3
|
fileName: string;
|
|
55
4
|
dir: string;
|
|
@@ -65,7 +14,7 @@ export interface GenerateOptions {
|
|
|
65
14
|
clientOutDir?: string;
|
|
66
15
|
templates?: string[];
|
|
67
16
|
prettify?: boolean;
|
|
68
|
-
|
|
17
|
+
emitFullSchema?: string | boolean;
|
|
69
18
|
}
|
|
70
19
|
export interface InitOptions {
|
|
71
20
|
yes?: boolean;
|
|
@@ -91,4 +40,3 @@ export interface NewOptions {
|
|
|
91
40
|
noSegmentUpdate?: boolean;
|
|
92
41
|
empty?: boolean;
|
|
93
42
|
}
|
|
94
|
-
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { KnownAny } from '
|
|
1
|
+
import type { KnownAny } from 'vovk';
|
|
2
2
|
export default function debounceWithArgs<Callback extends (...args: KnownAny[]) => KnownAny>(callback: Callback, wait: number): (...args: Parameters<Callback>) => Promise<Awaited<ReturnType<Callback>>>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vovk-cli",
|
|
3
|
-
"version": "0.0.1-draft.
|
|
3
|
+
"version": "0.0.1-draft.105",
|
|
4
4
|
"bin": {
|
|
5
5
|
"vovk": "./dist/index.mjs"
|
|
6
6
|
},
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
},
|
|
37
37
|
"homepage": "https://vovk.dev",
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"vovk": "^3.0.0-draft.
|
|
39
|
+
"vovk": "^3.0.0-draft.90"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@inquirer/prompts": "^7.3.1",
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { VovkSchema } from 'vovk';
|
|
2
|
-
import { type DiffResult } from './diffSchema.mjs';
|
|
3
|
-
export declare const ROOT_SEGMENT_SCHEMA_NAME = "_root";
|
|
4
|
-
export declare const JSON_DIR_NAME = "json";
|
|
5
|
-
export default function writeOneSchemaFile({ schemaOutAbsolutePath, schema, skipIfExists, }: {
|
|
6
|
-
schemaOutAbsolutePath: string;
|
|
7
|
-
schema: VovkSchema;
|
|
8
|
-
skipIfExists?: boolean;
|
|
9
|
-
}): Promise<{
|
|
10
|
-
isCreated: boolean;
|
|
11
|
-
diffResult: DiffResult | null;
|
|
12
|
-
}>;
|