vovk-cli 0.0.1-draft.3 → 0.0.1-draft.300

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.
Files changed (152) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +29 -1
  3. package/client-templates/cjs/index.cjs.ejs +19 -0
  4. package/client-templates/cjs/index.d.cts.ejs +25 -0
  5. package/client-templates/mixins/mixins.d.ts.ejs +64 -0
  6. package/client-templates/mixins/mixins.json.ejs +1 -0
  7. package/client-templates/mjs/index.d.mts.ejs +25 -0
  8. package/client-templates/mjs/index.mjs.ejs +23 -0
  9. package/client-templates/packageJson/package.json.ejs +1 -0
  10. package/client-templates/readme/README.md.ejs +38 -0
  11. package/client-templates/schemaCjs/schema.cjs.ejs +26 -0
  12. package/client-templates/schemaCjs/schema.d.cts.ejs +10 -0
  13. package/client-templates/schemaJson/schema.json.ejs +1 -0
  14. package/client-templates/schemaTs/schema.ts.ejs +35 -0
  15. package/client-templates/ts/index.ts.ejs +33 -0
  16. package/dist/bundle/index.d.mts +8 -0
  17. package/dist/bundle/index.mjs +90 -0
  18. package/dist/dev/diffSegmentSchema.d.mts +36 -0
  19. package/dist/{watcher/diffSchema.mjs → dev/diffSegmentSchema.mjs} +4 -12
  20. package/dist/{watcher → dev}/ensureSchemaFiles.d.mts +3 -0
  21. package/dist/{watcher → dev}/ensureSchemaFiles.mjs +17 -21
  22. package/dist/dev/index.d.mts +9 -0
  23. package/dist/dev/index.mjs +388 -0
  24. package/dist/dev/logDiffResult.d.mts +3 -0
  25. package/dist/dev/logDiffResult.mjs +57 -0
  26. package/dist/dev/writeMetaJson.d.mts +2 -0
  27. package/dist/dev/writeMetaJson.mjs +17 -0
  28. package/dist/dev/writeOneSegmentSchemaFile.d.mts +12 -0
  29. package/dist/dev/writeOneSegmentSchemaFile.mjs +32 -0
  30. package/dist/generate/ensureClient.d.mts +3 -0
  31. package/dist/generate/ensureClient.mjs +32 -0
  32. package/dist/generate/generate.d.mts +15 -0
  33. package/dist/generate/generate.mjs +291 -0
  34. package/dist/generate/getClientTemplateFiles.d.mts +20 -0
  35. package/dist/generate/getClientTemplateFiles.mjs +89 -0
  36. package/dist/generate/getProjectFullSchema.d.mts +7 -0
  37. package/dist/generate/getProjectFullSchema.mjs +65 -0
  38. package/dist/generate/getTemplateClientImports.d.mts +18 -0
  39. package/dist/generate/getTemplateClientImports.mjs +38 -0
  40. package/dist/generate/index.d.mts +33 -0
  41. package/dist/generate/index.mjs +189 -0
  42. package/dist/generate/mergePackages.d.mts +7 -0
  43. package/dist/generate/mergePackages.mjs +55 -0
  44. package/dist/generate/writeOneClientFile.d.mts +36 -0
  45. package/dist/generate/writeOneClientFile.mjs +120 -0
  46. package/dist/getProjectInfo/getConfig/getConfigAbsolutePaths.d.mts +5 -0
  47. package/dist/getProjectInfo/{getConfigAbsolutePaths.mjs → getConfig/getConfigAbsolutePaths.mjs} +6 -3
  48. package/dist/getProjectInfo/{getRelativeSrcRoot.d.mts → getConfig/getRelativeSrcRoot.d.mts} +1 -1
  49. package/dist/getProjectInfo/getConfig/getRelativeSrcRoot.mjs +12 -0
  50. package/dist/getProjectInfo/getConfig/getTemplateDefs.d.mts +16 -0
  51. package/dist/getProjectInfo/getConfig/getTemplateDefs.mjs +98 -0
  52. package/dist/getProjectInfo/{getUserConfig.d.mts → getConfig/getUserConfig.d.mts} +3 -2
  53. package/dist/getProjectInfo/{getUserConfig.mjs → getConfig/getUserConfig.mjs} +7 -5
  54. package/dist/getProjectInfo/{importUncachedModule.mjs → getConfig/importUncachedModule.mjs} +1 -5
  55. package/dist/getProjectInfo/{importUncachedModuleWorker.mjs → getConfig/importUncachedModuleWorker.mjs} +0 -1
  56. package/dist/getProjectInfo/getConfig/index.d.mts +120 -0
  57. package/dist/getProjectInfo/getConfig/index.mjs +94 -0
  58. package/dist/getProjectInfo/index.d.mts +12 -9
  59. package/dist/getProjectInfo/index.mjs +22 -23
  60. package/dist/index.d.mts +2 -24
  61. package/dist/index.mjs +106 -69
  62. package/dist/init/checkTSConfigForExperimentalDecorators.mjs +2 -2
  63. package/dist/init/createConfig.d.mts +3 -4
  64. package/dist/init/createConfig.mjs +22 -16
  65. package/dist/init/getTemplateFilesFromPackage.d.mts +2 -1
  66. package/dist/init/getTemplateFilesFromPackage.mjs +13 -9
  67. package/dist/init/index.d.mts +2 -3
  68. package/dist/init/index.mjs +119 -138
  69. package/dist/init/installDependencies.d.mts +4 -1
  70. package/dist/init/installDependencies.mjs +6 -4
  71. package/dist/init/logUpdateDependenciesError.d.mts +13 -0
  72. package/dist/init/logUpdateDependenciesError.mjs +51 -0
  73. package/dist/init/updateDependenciesWithoutInstalling.d.mts +3 -2
  74. package/dist/init/updateDependenciesWithoutInstalling.mjs +50 -15
  75. package/dist/init/updateNPMScripts.d.mts +3 -1
  76. package/dist/init/updateNPMScripts.mjs +10 -7
  77. package/dist/init/updateTypeScriptConfig.d.mts +4 -1
  78. package/dist/init/updateTypeScriptConfig.mjs +13 -9
  79. package/dist/initProgram.d.mts +2 -0
  80. package/dist/initProgram.mjs +22 -0
  81. package/dist/locateSegments.d.mts +8 -1
  82. package/dist/locateSegments.mjs +16 -6
  83. package/dist/new/addClassToSegmentCode.d.mts +1 -2
  84. package/dist/new/addClassToSegmentCode.mjs +9 -5
  85. package/dist/new/addCommonTerms.mjs +1 -0
  86. package/dist/new/index.d.mts +2 -2
  87. package/dist/new/index.mjs +14 -3
  88. package/dist/new/newModule.d.mts +7 -2
  89. package/dist/new/newModule.mjs +61 -35
  90. package/dist/new/newSegment.d.mts +4 -2
  91. package/dist/new/newSegment.mjs +22 -13
  92. package/dist/new/render.d.mts +9 -9
  93. package/dist/new/render.mjs +38 -13
  94. package/dist/types.d.mts +73 -28
  95. package/dist/utils/compileJSONSchemaToTypeScriptType.d.mts +5 -0
  96. package/dist/utils/compileJSONSchemaToTypeScriptType.mjs +9 -0
  97. package/dist/utils/compileTs.d.mts +12 -0
  98. package/dist/utils/compileTs.mjs +261 -0
  99. package/dist/utils/debounceWithArgs.d.mts +2 -2
  100. package/dist/utils/debounceWithArgs.mjs +24 -9
  101. package/dist/utils/formatLoggedSegmentName.d.mts +3 -1
  102. package/dist/utils/formatLoggedSegmentName.mjs +4 -3
  103. package/dist/utils/getAvailablePort.mjs +3 -2
  104. package/dist/utils/getFileSystemEntryType.mjs +1 -1
  105. package/dist/utils/getPackageJson.d.mts +3 -0
  106. package/dist/utils/getPackageJson.mjs +22 -0
  107. package/dist/utils/getPublicModuleNameFromPath.d.mts +4 -0
  108. package/dist/utils/getPublicModuleNameFromPath.mjs +9 -0
  109. package/dist/utils/normalizeOpenAPIMixins.d.mts +7 -0
  110. package/dist/utils/normalizeOpenAPIMixins.mjs +67 -0
  111. package/dist/utils/pickSegmentFullSchema.d.mts +3 -0
  112. package/dist/utils/pickSegmentFullSchema.mjs +15 -0
  113. package/dist/utils/removeUnlistedDirectories.d.mts +10 -0
  114. package/dist/utils/removeUnlistedDirectories.mjs +61 -0
  115. package/dist/utils/resolveAbsoluteModulePath.d.mts +2 -0
  116. package/dist/utils/resolveAbsoluteModulePath.mjs +32 -0
  117. package/module-templates/controller.ts.ejs +56 -0
  118. package/module-templates/service.ts.ejs +28 -0
  119. package/package.json +42 -21
  120. package/dist/generateClient.d.mts +0 -7
  121. package/dist/generateClient.mjs +0 -97
  122. package/dist/getProjectInfo/directoryExists.d.mts +0 -1
  123. package/dist/getProjectInfo/directoryExists.mjs +0 -10
  124. package/dist/getProjectInfo/getConfig.d.mts +0 -11
  125. package/dist/getProjectInfo/getConfig.mjs +0 -29
  126. package/dist/getProjectInfo/getConfigAbsolutePaths.d.mts +0 -4
  127. package/dist/getProjectInfo/getRelativeSrcRoot.mjs +0 -12
  128. package/dist/postinstall.d.mts +0 -1
  129. package/dist/postinstall.mjs +0 -22
  130. package/dist/watcher/diffSchema.d.mts +0 -43
  131. package/dist/watcher/index.d.mts +0 -6
  132. package/dist/watcher/index.mjs +0 -295
  133. package/dist/watcher/isMetadataEmpty.d.mts +0 -2
  134. package/dist/watcher/isMetadataEmpty.mjs +0 -4
  135. package/dist/watcher/logDiffResult.d.mts +0 -3
  136. package/dist/watcher/logDiffResult.mjs +0 -90
  137. package/dist/watcher/writeOneSchemaFile.d.mts +0 -11
  138. package/dist/watcher/writeOneSchemaFile.mjs +0 -27
  139. package/templates/controller.ejs +0 -50
  140. package/templates/service.ejs +0 -7
  141. package/templates/worker.ejs +0 -1
  142. package/templates_old/MyThingController.c.only.template.ts +0 -32
  143. package/templates_old/MyThingController.c.template.ts +0 -34
  144. package/templates_old/MyThingService.s.template.ts +0 -18
  145. package/templates_old/controller.ejs +0 -85
  146. package/templates_old/service.ejs +0 -9
  147. package/templates_old/worker.ejs +0 -9
  148. package/templates_old/zod/MyThingController.c.only.template.ts +0 -32
  149. package/templates_old/zod/MyThingController.c.template.ts +0 -39
  150. package/templates_old/zod/MyThingService.s.template.ts +0 -18
  151. /package/dist/getProjectInfo/{importUncachedModule.d.mts → getConfig/importUncachedModule.d.mts} +0 -0
  152. /package/dist/getProjectInfo/{importUncachedModuleWorker.d.mts → getConfig/importUncachedModuleWorker.d.mts} +0 -0
@@ -0,0 +1,61 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import getFileSystemEntryType, { FileSystemEntryType } from './getFileSystemEntryType.mjs';
4
+ /**
5
+ * Removes all directories in a folder that aren't in the provided allowlist
6
+ * Supports nested directory paths like 'foo/bar/baz'
7
+ *
8
+ * @param folderPath - The path to the folder to process
9
+ * @param allowedDirs - Array of relative directory paths to keep
10
+ * @returns Promise that resolves when all operations are complete
11
+ */
12
+ async function removeUnlistedDirectories(folderPath, allowedDirs) {
13
+ // Normalize all allowed paths to use the system-specific separator
14
+ const normalizedAllowedDirs = allowedDirs.map((dir) => dir.split('/').join(path.sep));
15
+ // Process the directory tree recursively
16
+ await processDirectory(folderPath, '', normalizedAllowedDirs);
17
+ }
18
+ /**
19
+ * Recursively processes directories to determine which should be kept or removed
20
+ *
21
+ * @param basePath - The absolute base path being processed
22
+ * @param relativePath - The current relative path from the base
23
+ * @param allowedDirs - Normalized list of allowed directory paths
24
+ */
25
+ async function processDirectory(basePath, relativePath, allowedDirs) {
26
+ const currentDirPath = path.join(basePath, relativePath);
27
+ // check if the current path is a directory
28
+ const type = await getFileSystemEntryType(currentDirPath);
29
+ if (type !== FileSystemEntryType.DIRECTORY) {
30
+ // If it's not a directory, return early
31
+ return;
32
+ }
33
+ // Read all entries in the current directory
34
+ const entries = await fs.readdir(currentDirPath, { withFileTypes: true });
35
+ // Process only directories
36
+ const dirEntries = entries.filter((entry) => entry.isDirectory());
37
+ // Check each directory
38
+ for (const dir of dirEntries) {
39
+ // Calculate the new relative path
40
+ const newRelativePath = relativePath ? path.join(relativePath, dir.name) : dir.name;
41
+ // Check if this directory or any of its subdirectories should be kept
42
+ const shouldKeep = allowedDirs.some((allowedDir) => {
43
+ // Direct match
44
+ if (allowedDir === newRelativePath)
45
+ return true;
46
+ // Check if it's a parent path of an allowed directory
47
+ // e.g. "foo" is a parent of "foo/bar/baz"
48
+ return allowedDir.startsWith(newRelativePath + path.sep);
49
+ });
50
+ if (shouldKeep) {
51
+ // Recursively process this directory's contents
52
+ await processDirectory(basePath, newRelativePath, allowedDirs);
53
+ }
54
+ else {
55
+ // Remove this directory since it's not in the allowed list
56
+ const fullPath = path.join(basePath, newRelativePath);
57
+ await fs.rm(fullPath, { recursive: true, force: true });
58
+ }
59
+ }
60
+ }
61
+ export default removeUnlistedDirectories;
@@ -0,0 +1,2 @@
1
+ export declare function getPathUpToModule(moduleName: string, fullPath: string): string;
2
+ export default function resolveAbsoluteModulePath(modulePath: string, cwd: string): string;
@@ -0,0 +1,32 @@
1
+ import path from 'node:path';
2
+ import { createRequire } from 'node:module';
3
+ import getPublicModuleNameFromPath from './getPublicModuleNameFromPath.mjs';
4
+ // Returns the path up to and including the last occurrence of the given module name
5
+ export function getPathUpToModule(moduleName, fullPath) {
6
+ const idx = fullPath.lastIndexOf(moduleName);
7
+ if (idx === -1)
8
+ return moduleName;
9
+ return fullPath.slice(0, idx + moduleName.length);
10
+ }
11
+ export default function resolveAbsoluteModulePath(modulePath, cwd) {
12
+ // If it's an absolute path or starts with '.' (relative), resolve it directly
13
+ if (modulePath.startsWith('/') || modulePath.startsWith('.')) {
14
+ return path.resolve(cwd, modulePath);
15
+ }
16
+ // For npm package names, use Node's module resolution algorithm
17
+ try {
18
+ const { moduleName, restPath } = getPublicModuleNameFromPath(modulePath);
19
+ if (!moduleName) {
20
+ throw new Error(`Invalid module path: ${modulePath}`);
21
+ }
22
+ const require = createRequire(import.meta.url);
23
+ const resolved = require.resolve(moduleName);
24
+ return path.resolve(getPathUpToModule(moduleName, path.dirname(resolved)), restPath);
25
+ }
26
+ catch (e) {
27
+ // eslint-disable-next-line no-console
28
+ console.error(`Error resolving module path: ${modulePath}`, e);
29
+ // If resolution fails, fall back to the original behavior
30
+ return path.resolve(cwd, './node_modules', modulePath);
31
+ }
32
+ }
@@ -0,0 +1,56 @@
1
+ <% const vars = {
2
+ rpcModuleName: t.TheThing + 'Controller',
3
+ ServiceName: t.TheThing + 'Service',
4
+ }; %>
5
+ ---
6
+ dir: <%= t.defaultDir %>
7
+ fileName: <%= vars.rpcModuleName + '.ts' %>
8
+ sourceName: <%= vars.rpcModuleName %>
9
+ compiledName: <%= t.TheThing + 'RPC' %>
10
+ ---
11
+
12
+ import { prefix, get, put, post, del, openapi, type VovkRequest } from 'vovk';
13
+ <% if(t.withService) { %>
14
+ import <%= vars.ServiceName %> from './<%= vars.ServiceName %><%= t.nodeNextResolutionExt.ts %>';
15
+ <% } %>
16
+
17
+ @prefix('<%= t['the-things'] %>')
18
+ export default class <%= vars.rpcModuleName %> {
19
+ @openapi({
20
+ summary: 'Get <%= t.TheThings %>',
21
+ })
22
+ @get()
23
+ static get<%= t.TheThings %> = async (req: VovkRequest<null, { search: string }>) => {
24
+ const search = req.nextUrl.searchParams.get('search');
25
+ <% if(t.withService) { %>
26
+ return <%= vars.ServiceName %>.get<%= t.TheThings %>(search);
27
+ <% } else { %>
28
+ return { results: [], search };
29
+ <% } %>
30
+ }
31
+
32
+ @openapi({
33
+ summary: 'Update <%= t.TheThing %>',
34
+ })
35
+ @put('{id}')
36
+ static update<%= t.TheThing %> = async (req: VovkRequest<{ foo: 'bar' | 'baz' }, { q: string }>, params: { id: string }) => {
37
+ const { id } = params;
38
+ const body = await req.json();
39
+ const q = req.nextUrl.searchParams.get('q');
40
+ <% if(t.withService) { %>
41
+ return <%= vars.ServiceName %>.update<%= t.TheThing %>(id, q, body);
42
+ <% } else { %>
43
+ return { id, body, q };
44
+ <% } %>
45
+ };
46
+
47
+ @post()
48
+ static create<%= t.TheThing %> = () => {
49
+ // ...
50
+ };
51
+
52
+ @del(':id')
53
+ static delete<%= t.TheThing %> = () => {
54
+ // ...
55
+ };
56
+ }
@@ -0,0 +1,28 @@
1
+ <% const vars = {
2
+ rpcModuleName: t.TheThing + 'Controller',
3
+ ServiceName: t.TheThing + 'Service',
4
+ }; %>
5
+ ---
6
+ dir: <%= t.defaultDir %>
7
+ fileName: <%= vars.ServiceName + '.ts' %>
8
+ sourceName: <%= vars.ServiceName %>
9
+ ---
10
+
11
+ import type { VovkBody, VovkQuery } from 'vovk';
12
+ import type <%= vars.rpcModuleName %> from './<%= vars.rpcModuleName %><%= t.nodeNextResolutionExt.ts %>';
13
+
14
+ export default class <%= vars.ServiceName %> {
15
+ static get<%= t.TheThings %> = (search: VovkQuery<typeof <%= vars.rpcModuleName %>.get<%= t.TheThings %>>['search']) => {
16
+ return { results: [], search };
17
+ };
18
+
19
+ static update<%= t.TheThing %> = (
20
+ id: string,
21
+ q: VovkQuery<typeof <%= vars.rpcModuleName %>.update<%= t.TheThing %>>['q'],
22
+ body: VovkBody<typeof <%= vars.rpcModuleName %>.update<%= t.TheThing %>>
23
+ ) => {
24
+ return { id, q, body };
25
+ };
26
+
27
+ // ...
28
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vovk-cli",
3
- "version": "0.0.1-draft.3",
3
+ "version": "0.0.1-draft.300",
4
4
  "bin": {
5
5
  "vovk": "./dist/index.mjs"
6
6
  },
@@ -10,10 +10,12 @@
10
10
  "prefix": ".",
11
11
  "scripts": {
12
12
  "build": "rm -rf dist tsconfig.build.tsbuildinfo && tsc -P tsconfig.build.json",
13
- "build-test": "rm -rf test_dist && tsc -P tsconfig.test.json",
14
- "test": "npm run build && chmod +x ./dist/index.mjs && npm run build-test && node --test --test-only test_dist/test/**/*.mjs",
15
- "test_": "npm run build && chmod +x ./dist/index.mjs && NODE_OPTIONS=\"--loader ts-node/esm\" TS_NODE_PROJECT=./tsconfig.test.json node --test --test-only test/**.mts",
16
- "ncu": "npm-check-updates -u",
13
+ "postbuild": "chmod +x ./dist/index.mjs",
14
+ "pre-test": "npm run build",
15
+ "test-only": "npm run pre-test && node --experimental-transform-types --experimental-strip-types --test --test-only test/spec/**/*.mts",
16
+ "test": "npm run pre-test && node --experimental-transform-types --experimental-strip-types --test --test-concurrency=1 test/spec/**/*.mts",
17
+ "tsc": "tsc --noEmit",
18
+ "ncu": "npm-check-updates -u -x commander",
17
19
  "npm-publish": "npm publish"
18
20
  },
19
21
  "repository": {
@@ -26,44 +28,63 @@
26
28
  "cli",
27
29
  "vovk"
28
30
  ],
29
- "author": "Andrii Gubanov",
31
+ "author": "Andrey Gubanov",
30
32
  "license": "MIT",
31
33
  "bugs": {
32
34
  "url": "https://github.com/finom/vovk/issues"
33
35
  },
34
36
  "homepage": "https://vovk.dev",
35
37
  "peerDependencies": {
36
- "vovk": "^3.0.0-draft.3"
38
+ "vovk": "^3.0.0-draft.339"
39
+ },
40
+ "optionalDependencies": {
41
+ "vovk-python": "^0.0.1-draft.54"
37
42
  },
38
43
  "dependencies": {
39
- "@inquirer/prompts": "^7.0.0",
40
- "@npmcli/package-json": "^6.0.1",
41
- "chalk": "^5.3.0",
42
- "chokidar": "^4.0.1",
43
- "commander": "^12.1.0",
44
- "concurrently": "^9.0.1",
45
- "dotenv": "^16.4.5",
44
+ "@iarna/toml": "^2.2.5",
45
+ "@inquirer/prompts": "^7.6.0",
46
+ "@npmcli/package-json": "^6.2.0",
47
+ "@rollup/plugin-commonjs": "^28.0.6",
48
+ "@rollup/plugin-json": "^6.1.0",
49
+ "@rollup/plugin-node-resolve": "^16.0.1",
50
+ "@rollup/plugin-typescript": "^12.1.4",
51
+ "@types/json-schema": "^7.0.15",
52
+ "chalk": "^5.4.1",
53
+ "chokidar": "^4.0.3",
54
+ "clone-deep": "^4.0.1",
55
+ "commander": "^13.1.0",
56
+ "concurrently": "^9.2.0",
57
+ "dotenv": "^17.2.0",
46
58
  "ejs": "^3.1.10",
59
+ "get-tsconfig": "^4.10.1",
60
+ "glob": "^11.0.3",
47
61
  "gray-matter": "^4.0.3",
48
- "inflection": "^3.0.0",
62
+ "inflection": "^3.0.2",
49
63
  "jsonc-parser": "^3.3.1",
50
64
  "lodash": "^4.17.21",
51
65
  "loglevel": "^1.9.2",
66
+ "openapi3-ts": "^4.5.0",
52
67
  "pluralize": "^8.0.0",
53
- "prettier": "^3.3.3",
68
+ "prettier": "^3.6.2",
69
+ "rollup": "^4.44.2",
54
70
  "tar-stream": "^3.1.7",
55
- "ts-morph": "^24.0.0",
56
- "undici": "^6.20.1"
71
+ "ts-morph": "^26.0.0",
72
+ "tsdown": "^0.12.9",
73
+ "type-fest": "^4.41.0",
74
+ "undici": "^7.11.0",
75
+ "vovk-openapi": "^0.0.1-draft.112",
76
+ "yaml": "^2.8.0"
57
77
  },
58
78
  "devDependencies": {
59
79
  "@types/concat-stream": "^2.0.3",
60
80
  "@types/ejs": "^3.1.5",
81
+ "@types/js-yaml": "^4.0.9",
61
82
  "@types/npmcli__package-json": "^4.0.4",
62
83
  "@types/pluralize": "^0.0.33",
63
- "@types/tar-stream": "^3.1.3",
84
+ "@types/tar-stream": "^3.1.4",
64
85
  "concat-stream": "^2.0.0",
65
- "create-next-app": "^15.0.1",
86
+ "create-next-app": "^15.3.5",
66
87
  "node-pty": "^1.0.0",
67
- "type-fest": "^4.26.1"
88
+ "zod": "^4.0.5"
68
89
  }
69
90
  }
@@ -1,7 +0,0 @@
1
- import type { ProjectInfo } from './getProjectInfo/index.mjs';
2
- import type { Segment } from './locateSegments.mjs';
3
- import type { VovkSchema } from 'vovk';
4
- export default function generateClient(projectInfo: ProjectInfo, segments: Segment[], segmentsSchema: Record<string, VovkSchema>): Promise<{
5
- written: boolean;
6
- path: string;
7
- }>;
@@ -1,97 +0,0 @@
1
- import path from 'path';
2
- import fs from 'fs/promises';
3
- import formatLoggedSegmentName from './utils/formatLoggedSegmentName.mjs';
4
- import prettify from './utils/prettify.mjs';
5
- export default async function generateClient(projectInfo, segments, segmentsSchema) {
6
- const { config, cwd, log, validateOnClientImportPath, apiEntryPoint, fetcherClientImportPath, schemaOutImportPath } = projectInfo;
7
- const now = Date.now();
8
- const clientoOutDirAbsolutePath = path.join(cwd, config.clientOutDir);
9
- let dts = `// auto-generated
10
- /* eslint-disable */
11
- import type { clientizeController } from 'vovk/client';
12
- import type { promisifyWorker } from 'vovk/worker';
13
- import type { VovkClientFetcher } from 'vovk/client';
14
- import type fetcher from '${fetcherClientImportPath}';
15
-
16
- `;
17
- let js = `// auto-generated
18
- /* eslint-disable */
19
- const { clientizeController } = require('vovk/client');
20
- const { promisifyWorker } = require('vovk/worker');
21
- const { default: fetcher } = require('${fetcherClientImportPath}');
22
- const schema = require('${schemaOutImportPath}');
23
- `;
24
- let ts = `// auto-generated
25
- /* eslint-disable */
26
- import { clientizeController } from 'vovk/client';
27
- import { promisifyWorker } from 'vovk/worker';
28
- import type { VovkClientFetcher } from 'vovk/client';
29
- import fetcher from '${fetcherClientImportPath}';
30
- import schema from '${schemaOutImportPath}';
31
-
32
- `;
33
- for (let i = 0; i < segments.length; i++) {
34
- const { routeFilePath, segmentName } = segments[i];
35
- const schema = segmentsSchema[segmentName];
36
- if (!schema) {
37
- throw new Error(`Unable to generate client. No schema found for ${formatLoggedSegmentName(segmentName)}`);
38
- }
39
- if (!schema.emitSchema)
40
- continue;
41
- const importRouteFilePath = path.relative(config.clientOutDir, routeFilePath);
42
- dts += `import type { Controllers as Controllers${i}, Workers as Workers${i} } from "${importRouteFilePath}";\n`;
43
- ts += `import type { Controllers as Controllers${i}, Workers as Workers${i} } from "${importRouteFilePath}";\n`;
44
- }
45
- dts += `
46
- type Options = typeof fetcher extends VovkClientFetcher<infer U> ? U : never;
47
- `;
48
- ts += `
49
- ${validateOnClientImportPath ? `import validateOnClient from '${validateOnClientImportPath}';\n` : '\nconst validateOnClient = undefined;'}
50
- type Options = typeof fetcher extends VovkClientFetcher<infer U> ? U : never;
51
- const prefix = '${apiEntryPoint}';
52
- `;
53
- js += `
54
- const { default: validateOnClient = null } = ${validateOnClientImportPath ? `require('${validateOnClientImportPath}')` : '{}'};
55
- const prefix = '${apiEntryPoint}';
56
- `;
57
- for (let i = 0; i < segments.length; i++) {
58
- const { segmentName } = segments[i];
59
- const schema = segmentsSchema[segmentName];
60
- if (!schema) {
61
- throw new Error(`Unable to generate client. No schema found for ${formatLoggedSegmentName(segmentName)}`);
62
- }
63
- if (!schema.emitSchema)
64
- continue;
65
- for (const key of Object.keys(schema.controllers)) {
66
- dts += `export const ${key}: ReturnType<typeof clientizeController<Controllers${i}["${key}"], Options>>;\n`;
67
- js += `exports.${key} = clientizeController(schema['${segmentName}'].controllers.${key}, '${segmentName}', { fetcher, validateOnClient, defaultOptions: { prefix } });\n`;
68
- ts += `export const ${key} = clientizeController<Controllers${i}["${key}"], Options>(schema['${segmentName}'].controllers.${key}, '${segmentName}', { fetcher, validateOnClient, defaultOptions: { prefix } });\n`;
69
- }
70
- for (const key of Object.keys(schema.workers)) {
71
- dts += `export const ${key}: ReturnType<typeof promisifyWorker<Workers${i}["${key}"]>>;\n`;
72
- js += `exports.${key} = promisifyWorker(null, schema['${segmentName}'].workers.${key});\n`;
73
- ts += `export const ${key} = promisifyWorker<Workers${i}["${key}"]>(null, schema['${segmentName}'].workers.${key});\n`;
74
- }
75
- }
76
- const localJsAbsolutePath = path.join(clientoOutDirAbsolutePath, 'client.js');
77
- const localDtsAbsolutePath = path.join(clientoOutDirAbsolutePath, 'client.d.ts');
78
- const localTsAbsolutePath = path.join(clientoOutDirAbsolutePath, 'index.ts');
79
- const existingJs = await fs.readFile(localJsAbsolutePath, 'utf-8').catch(() => '');
80
- const existingDts = await fs.readFile(localDtsAbsolutePath, 'utf-8').catch(() => '');
81
- const existingTs = await fs.readFile(localTsAbsolutePath, 'utf-8').catch(() => '');
82
- if (config.prettifyClient) {
83
- js = await prettify(js, localJsAbsolutePath);
84
- dts = await prettify(dts, localDtsAbsolutePath);
85
- ts = await prettify(ts, localTsAbsolutePath);
86
- }
87
- if (existingJs === js && existingDts === dts && existingTs === ts) {
88
- log.debug(`Client is up to date and doesn't need to be regenerated (${Date.now() - now}ms)`);
89
- return { written: false, path: clientoOutDirAbsolutePath };
90
- }
91
- await fs.mkdir(clientoOutDirAbsolutePath, { recursive: true });
92
- await fs.writeFile(localJsAbsolutePath, js);
93
- await fs.writeFile(localDtsAbsolutePath, dts);
94
- await fs.writeFile(localTsAbsolutePath, ts);
95
- log.info(`Client generated in ${Date.now() - now}ms`);
96
- return { written: true, path: clientoOutDirAbsolutePath };
97
- }
@@ -1 +0,0 @@
1
- export default function directoryExists(dir: string): Promise<boolean>;
@@ -1,10 +0,0 @@
1
- import fs from 'fs/promises';
2
- export default async function directoryExists(dir) {
3
- try {
4
- const stats = await fs.stat(dir);
5
- return stats.isDirectory();
6
- }
7
- catch (error) {
8
- return false;
9
- }
10
- }
@@ -1,11 +0,0 @@
1
- import type { VovkConfig } from '../types.mjs';
2
- export default function getConfig({ clientOutDir, cwd }: {
3
- clientOutDir?: string;
4
- cwd: string;
5
- }): Promise<{
6
- config: Required<VovkConfig>;
7
- srcRoot: string;
8
- configAbsolutePaths: string[];
9
- userConfig: VovkConfig | null;
10
- error: Error | undefined;
11
- }>;
@@ -1,29 +0,0 @@
1
- import getUserConfig from './getUserConfig.mjs';
2
- import getRelativeSrcRoot from './getRelativeSrcRoot.mjs';
3
- export default async function getConfig({ clientOutDir, cwd }) {
4
- const env = process.env;
5
- const { configAbsolutePaths, error, userConfig } = await getUserConfig({ cwd });
6
- const conf = userConfig ?? {};
7
- const srcRoot = await getRelativeSrcRoot({ cwd });
8
- const config = {
9
- modulesDir: env.VOVK_MODULES_DIR ?? conf.modulesDir ?? './' + [srcRoot, 'modules'].filter(Boolean).join('/'),
10
- validateOnClient: env.VOVK_VALIDATE_ON_CLIENT ?? conf.validateOnClient ?? null,
11
- validationLibrary: env.VOVK_VALIDATION_LIBRARY ?? conf.validationLibrary ?? null,
12
- fetcher: env.VOVK_FETCHER ?? conf.fetcher ?? 'vovk/client/defaultFetcher',
13
- schemaOutDir: env.VOVK_SCHEMA_OUT_DIR ?? conf.schemaOutDir ?? './.vovk-schema',
14
- clientOutDir: clientOutDir ?? env.VOVK_CLIENT_OUT_DIR ?? conf.clientOutDir ?? './node_modules/.vovk-client',
15
- origin: (env.VOVK_ORIGIN ?? conf.origin ?? '').replace(/\/$/, ''), // Remove trailing slash
16
- rootEntry: env.VOVK_ROOT_ENTRY ?? conf.rootEntry ?? 'api',
17
- rootSegmentModulesDirName: env.VOVK_ROOT_SEGMENT_MODULES_DIR_NAME ?? conf.rootSegmentModulesDirName ?? '',
18
- logLevel: env.VOVK_LOG_LEVEL ?? conf.logLevel ?? 'debug', // TODO: change to 'warn' when v3 is ready
19
- prettifyClient: (env.VOVK_PRETTIFY_CLIENT ? !!env.VOVK_PRETTIFY_CLIENT : null) ?? conf.prettifyClient ?? false,
20
- devHttps: (env.VOVK_DEV_HTTPS ? !!env.VOVK_DEV_HTTPS : null) ?? conf.devHttps ?? false,
21
- templates: {
22
- service: 'vovk-cli/templates/service.ejs',
23
- controller: 'vovk-cli/templates/controller.ejs',
24
- worker: 'vovk-cli/templates/worker.ejs',
25
- ...conf.templates,
26
- },
27
- };
28
- return { config, srcRoot, configAbsolutePaths, userConfig, error };
29
- }
@@ -1,4 +0,0 @@
1
- export default function getConfigAbsolutePaths({ cwd, relativePath, }: {
2
- cwd: string;
3
- relativePath?: string;
4
- }): Promise<string[]>;
@@ -1,12 +0,0 @@
1
- import path from 'path';
2
- import directoryExists from './directoryExists.mjs';
3
- export default async function getRelativeSrcRoot({ cwd }) {
4
- // Next.js Docs: src/app or src/pages will be ignored if app or pages are present in the root directory.
5
- if (await directoryExists(path.join(cwd, 'app'))) {
6
- return '.';
7
- }
8
- else if (await directoryExists(path.join(cwd, 'src/app'))) {
9
- return './src';
10
- }
11
- throw new Error(`${cwd} Could not find app router directory. Check Next.js docs for more info.`);
12
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,22 +0,0 @@
1
- import { promises as fs } from 'fs';
2
- import path from 'path';
3
- /**
4
- * Checks if a file exists at the given path.
5
- * @param {string} filePath - The path to the file.
6
- * @returns {Promise<boolean>} - A promise that resolves to true if the file exists, false otherwise.
7
- */
8
- const getFileSystemEntryType = async (filePath) => !!(await fs.stat(filePath).catch(() => false));
9
- async function postinstall() {
10
- const vovk = path.join(import.meta.dirname, '../../.vovk');
11
- const js = path.join(vovk, 'client.js');
12
- const ts = path.join(vovk, 'client.d.ts');
13
- const index = path.join(vovk, 'index.ts');
14
- if ((await getFileSystemEntryType(js)) || (await getFileSystemEntryType(ts)) || (await getFileSystemEntryType(index))) {
15
- return;
16
- }
17
- await fs.mkdir(vovk, { recursive: true });
18
- await fs.writeFile(js, '/* postinstall */');
19
- await fs.writeFile(ts, '/* postinstall */');
20
- await fs.writeFile(index, '/* postinstall */');
21
- }
22
- void postinstall();
@@ -1,43 +0,0 @@
1
- import type { VovkSchema } from 'vovk';
2
- import { _VovkControllerSchema, _VovkWorkerSchema } from 'vovk/types';
3
- interface HandlersDiff {
4
- nameOfClass: string;
5
- added: string[];
6
- removed: string[];
7
- changed: string[];
8
- }
9
- interface WorkersOrControllersDiff {
10
- added: string[];
11
- removed: string[];
12
- handlers: HandlersDiff[];
13
- }
14
- export interface DiffResult {
15
- workers: WorkersOrControllersDiff;
16
- controllers: WorkersOrControllersDiff;
17
- }
18
- export declare function diffHandlers<T extends _VovkWorkerSchema['_handlers'] | _VovkControllerSchema['_handlers']>(oldHandlers: T, newHandlers: T, nameOfClass: string): HandlersDiff;
19
- export declare function diffWorkersOrControllers<T extends VovkSchema['controllers'] | VovkSchema['workers']>(oldItems: T, newItems: T): WorkersOrControllersDiff;
20
- /**
21
- example output:
22
- {
23
- workers: {
24
- added: ["WorkerC"],
25
- removed: ["WorkerA"],
26
- handlers: []
27
- },
28
- controllers: {
29
- added: ["ControllerC"],
30
- removed: ["ControllerB"],
31
- handlers: [
32
- {
33
- nameOfClass: "ControllerA",
34
- added: ["handlerF"],
35
- removed: [],
36
- changed: ["handlerD"]
37
- }
38
- ]
39
- }
40
- }
41
- */
42
- export default function diffSchema(oldJson: VovkSchema, newJson: VovkSchema): DiffResult;
43
- export {};
@@ -1,6 +0,0 @@
1
- export declare class VovkCLIWatcher {
2
- #private;
3
- start({ clientOutDir }?: {
4
- clientOutDir?: string;
5
- }): Promise<void>;
6
- }