vovk-cli 0.0.1-beta.2 → 0.0.1-beta.4

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 (42) hide show
  1. package/LICENSE +23 -0
  2. package/dist/getProjectInfo/index.d.mts +0 -1
  3. package/dist/getProjectInfo/index.mjs +1 -3
  4. package/dist/server/generateClient.mjs +2 -2
  5. package/dist/server/index.mjs +2 -2
  6. package/package.json +3 -2
  7. package/.eslintrc.mjs +0 -20
  8. package/src/getProjectInfo/directoryExists.mts +0 -10
  9. package/src/getProjectInfo/getConfig.mts +0 -29
  10. package/src/getProjectInfo/getCwdPath.mts +0 -15
  11. package/src/getProjectInfo/getSrcRoot.mts +0 -14
  12. package/src/getProjectInfo/index.mts +0 -59
  13. package/src/getProjectInfo/readConfig.mts +0 -44
  14. package/src/index.mts +0 -113
  15. package/src/init.mts +0 -174
  16. package/src/locateSegments.mts +0 -40
  17. package/src/postinstall.mts +0 -27
  18. package/src/server/createMetadataServer.mts +0 -30
  19. package/src/server/diffMetadata.mts +0 -110
  20. package/src/server/ensureMetadataFiles.mts +0 -92
  21. package/src/server/generateClient.mts +0 -108
  22. package/src/server/index.mts +0 -307
  23. package/src/server/isMetadataEmpty.mts +0 -6
  24. package/src/server/logDiffResult.mts +0 -114
  25. package/src/server/writeOneMetadataFile.mts +0 -44
  26. package/src/types.mts +0 -58
  27. package/src/utils/debounceWithArgs.mts +0 -22
  28. package/src/utils/fileExists.mts +0 -10
  29. package/src/utils/getAvailablePort.mts +0 -50
  30. package/test/data/segments/[[...vovk]]/route.ts +0 -0
  31. package/test/data/segments/bar/[[...custom]]/route.ts +0 -0
  32. package/test/data/segments/baz/[[...vovk]]/noroute.ts +0 -0
  33. package/test/data/segments/foo/[[...vovk]]/route.ts +0 -0
  34. package/test/data/segments/garply/waldo/route.ts +0 -0
  35. package/test/data/segments/grault/xxxx/[[...vovk]]/noroute.ts +0 -0
  36. package/test/data/segments/quux/corge/[[...vovk]]/route.ts +0 -0
  37. package/test/index.ts +0 -3
  38. package/test/metadata-diff.test.mts +0 -300
  39. package/test/metadata-write.test.mts +0 -82
  40. package/test/utils.test.mts +0 -49
  41. package/tsconfig.json +0 -17
  42. package/tsconfig.test.json +0 -4
package/LICENSE ADDED
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023-present Andrii Gubanov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+
@@ -8,7 +8,6 @@ export default function getProjectInfo({ port: givenPort, clientOutDir, }?: {
8
8
  port: string;
9
9
  vovkPort: string;
10
10
  apiEntryPoint: string;
11
- apiPrefix: string;
12
11
  apiDir: string;
13
12
  srcRoot: string;
14
13
  metadataOutFullPath: string;
@@ -10,8 +10,7 @@ export default async function getProjectInfo({ port: givenPort, clientOutDir, }
10
10
  const cwd = process.cwd();
11
11
  const { config, srcRoot } = await getConfig({ clientOutDir });
12
12
  const vovkPort = env.VOVK_PORT || (parseInt(port) + 6969).toString();
13
- const apiEntryPoint = `${config.origin}/${config.rootEntry}`; // ??? TODO
14
- const apiPrefix = `${config.origin}/${config.rootEntry}`; // ??? TODO
13
+ const apiEntryPoint = `${config.origin ?? ''}/${config.rootEntry}`;
15
14
  const apiDir = path.join(srcRoot, 'app', config.rootEntry);
16
15
  const metadataOutFullPath = path.join(cwd, config.metadataOutDir);
17
16
  const metadataOutImportPath = path.relative(config.clientOutDir, metadataOutFullPath);
@@ -32,7 +31,6 @@ export default async function getProjectInfo({ port: givenPort, clientOutDir, }
32
31
  port,
33
32
  vovkPort,
34
33
  apiEntryPoint,
35
- apiPrefix,
36
34
  apiDir,
37
35
  srcRoot,
38
36
  metadataOutFullPath,
@@ -48,11 +48,11 @@ type Options = typeof fetcher extends VovkClientFetcher<infer U> ? U : never;
48
48
  ts += `
49
49
  ${validatePath ? `import validateOnClient from '${validatePath}';\n` : '\nconst validateOnClient = undefined;'}
50
50
  type Options = typeof fetcher extends VovkClientFetcher<infer U> ? U : never;
51
- const prefix = '${projectInfo.apiPrefix}';
51
+ const prefix = '${projectInfo.apiEntryPoint}';
52
52
  `;
53
53
  js += `
54
54
  const { default: validateOnClient = null } = ${validatePath ? `require('${validatePath}')` : '{}'};
55
- const prefix = '${projectInfo.apiPrefix}';
55
+ const prefix = '${projectInfo.apiEntryPoint}';
56
56
  `;
57
57
  for (let i = 0; i < segments.length; i++) {
58
58
  const { segmentName } = segments[i];
@@ -183,8 +183,8 @@ export class VovkCLIServer {
183
183
  }
184
184
  };
185
185
  #ping = debounceWithArgs((segmentName) => {
186
- const { apiEntryPoint, log } = this.#projectInfo;
187
- const endpoint = `${apiEntryPoint}/${segmentName ? `${segmentName}/` : ''}_vovk-ping_`;
186
+ const { apiEntryPoint, log, port } = this.#projectInfo;
187
+ const endpoint = `${apiEntryPoint.startsWith('http') ? apiEntryPoint : `http://localhost:${port}${apiEntryPoint}`}/${segmentName ? `${segmentName}/` : ''}_vovk-ping_`;
188
188
  log.debug(`Pinging segment "${segmentName}" at ${endpoint}`);
189
189
  const req = http.get(endpoint, (resp) => {
190
190
  if (resp.statusCode !== 200) {
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "vovk-cli",
3
- "version": "0.0.1-beta.2",
3
+ "version": "0.0.1-beta.4",
4
4
  "bin": {
5
5
  "vovk": "./dist/index.mjs"
6
6
  },
7
7
  "type": "module",
8
8
  "types": "./dist/index.d.mts",
9
+ "prefix": ".",
9
10
  "scripts": {
10
11
  "build": "rm -rf dist tsconfig.tsbuildinfo && tsc",
11
12
  "test": "ts-node test/index.mts",
@@ -29,7 +30,7 @@
29
30
  },
30
31
  "homepage": "https://vovk.dev",
31
32
  "peerDependencies": {
32
- "vovk": "^3.0.0-beta.0"
33
+ "vovk": "^3.0.0-beta.8"
33
34
  },
34
35
  "dependencies": {
35
36
  "@inquirer/prompts": "^5.3.8",
package/.eslintrc.mjs DELETED
@@ -1,20 +0,0 @@
1
- export default {
2
- extends: '../../.eslintrc.js',
3
- rules: {
4
- '@typescript-eslint/no-unsafe-argument': 'off',
5
- '@typescript-eslint/no-unsafe-assignment': 'off',
6
- '@typescript-eslint/no-var-requires': 'off',
7
- '@typescript-eslint/no-unsafe-call': 'off',
8
- '@typescript-eslint/no-unsafe-member-access': 'off',
9
- '@typescript-eslint/no-unsafe-return': 'off',
10
- 'no-console': 'error',
11
- },
12
- parserOptions: {
13
- ecmaVersion: 2022,
14
- sourceType: 'module',
15
- project: './tsconfig.test.json',
16
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
17
- tsconfigRootDir: __dirname,
18
- createDefaultProgram: true,
19
- },
20
- };
@@ -1,10 +0,0 @@
1
- import fs from 'fs/promises';
2
-
3
- export default async function directoryExists(dir: string) {
4
- try {
5
- const stats = await fs.stat(dir);
6
- return stats.isDirectory();
7
- } catch (error) {
8
- return false;
9
- }
10
- }
@@ -1,29 +0,0 @@
1
- import readConfig from './readConfig.mjs';
2
- import type { VovkConfig, VovkEnv } from '../types.mjs';
3
- import getCwdPath from './getCwdPath.mjs';
4
- import getSrcRoot from './getSrcRoot.mjs';
5
- import path from 'path';
6
-
7
- export default async function getConfig({ clientOutDir }: { clientOutDir?: string }) {
8
- const env = process.env as VovkEnv;
9
- const userConfig = await readConfig();
10
- const srcRoot = await getSrcRoot();
11
- const cwd = process.cwd();
12
- const config: Required<VovkConfig> = {
13
- modulesDir: path.join(
14
- cwd,
15
- env.VOVK_MODULES_DIR ?? userConfig.modulesDir ?? './' + [srcRoot, 'modules'].filter(Boolean).join('/')
16
- ),
17
- validateOnClient: getCwdPath(env.VOVK_VALIDATE_ON_CLIENT ?? userConfig.validateOnClient ?? null),
18
- validationLibrary: getCwdPath(env.VOVK_VALIDATION_LIBRARY ?? userConfig.validationLibrary ?? null),
19
- fetcher: getCwdPath(env.VOVK_FETCHER ?? userConfig.fetcher ?? 'vovk/client/defaultFetcher'),
20
- metadataOutDir: env.VOVK_METADATA_OUT_DIR ?? userConfig.metadataOutDir ?? './.vovk-schema',
21
- clientOutDir: clientOutDir ?? env.VOVK_CLIENT_OUT_DIR ?? userConfig.clientOutDir ?? './node_modules/.vovk',
22
- origin: (env.VOVK_ORIGIN ?? userConfig.origin ?? '').replace(/\/$/, ''), // Remove trailing slash
23
- rootEntry: env.VOVK_ROOT_ENTRY ?? userConfig.rootEntry ?? 'api',
24
- rootSegmentModulesDirName: env.VOVK_ROOT_SEGMENT_MODULES_DIR_NAME ?? userConfig.rootSegmentModulesDirName ?? '',
25
- logLevel: env.VOVK_LOG_LEVEL ?? userConfig.logLevel ?? 'debug', // TODO: change to 'warn' when v3 is ready
26
- };
27
-
28
- return { config, srcRoot };
29
- }
@@ -1,15 +0,0 @@
1
- import path from 'path';
2
-
3
- // TODO Rename
4
- export default function getCwdPath<T extends string | null>(inputPath: T, baseDir = process.cwd()): T {
5
- if (inputPath === null) {
6
- return null as T;
7
- }
8
- // Check if the path is absolute
9
- if (path.isAbsolute(inputPath) || inputPath.startsWith('./') || inputPath.startsWith('../')) {
10
- return path.resolve(baseDir, inputPath) as T;
11
- }
12
-
13
- // If it's a module or absolute path, keep it as is
14
- return inputPath;
15
- }
@@ -1,14 +0,0 @@
1
- import path from 'path';
2
- import directoryExists from './directoryExists.mjs';
3
-
4
- export default async function getSrcRoot() {
5
- const cwd = process.cwd();
6
- // Next.js Docs: src/app or src/pages will be ignored if app or pages are present in the root directory.
7
- if (await directoryExists(path.join(cwd, 'app'))) {
8
- return cwd;
9
- } else if (await directoryExists(path.join(cwd, 'src/app'))) {
10
- return path.join(cwd, 'src');
11
- }
12
-
13
- throw new Error(`Could not find app router directory. Check Next.js docs for more info.`);
14
- }
@@ -1,59 +0,0 @@
1
- import type { VovkEnv } from '../types.mjs';
2
- import path from 'path';
3
- import loglevel from 'loglevel';
4
- import chalk from 'chalk';
5
- import getConfig from './getConfig.mjs';
6
-
7
- export type ProjectInfo = Awaited<ReturnType<typeof getProjectInfo>>;
8
-
9
- export default async function getProjectInfo({
10
- port: givenPort,
11
- clientOutDir,
12
- }: { port?: number; clientOutDir?: string } = {}) {
13
- const env = process.env as VovkEnv;
14
- const port = givenPort?.toString() ?? process.env.PORT ?? '3000';
15
-
16
- // Make PORT available to the config file at getConfig
17
- process.env.PORT = port;
18
-
19
- const cwd = process.cwd();
20
- const { config, srcRoot } = await getConfig({ clientOutDir });
21
- const vovkPort = env.VOVK_PORT || (parseInt(port) + 6969).toString();
22
- const apiEntryPoint = `${config.origin}/${config.rootEntry}`; // ??? TODO
23
- const apiPrefix = `${config.origin}/${config.rootEntry}`; // ??? TODO
24
- const apiDir = path.join(srcRoot, 'app', config.rootEntry);
25
-
26
- const metadataOutFullPath = path.join(cwd, config.metadataOutDir);
27
- const metadataOutImportPath = path.relative(config.clientOutDir, metadataOutFullPath);
28
- const fetcherClientImportPath = config.fetcher.startsWith('.')
29
- ? path.relative(config.clientOutDir, config.fetcher)
30
- : config.fetcher;
31
-
32
- const clientOutFullPath = path.join(cwd, config.clientOutDir);
33
-
34
- const log = {
35
- info: (msg: string) => loglevel.info(chalk.blueBright(`🐺 ${msg}`)),
36
- warn: (msg: string) => loglevel.warn(chalk.yellowBright(`🐺 ${msg}`)),
37
- error: (msg: string) => loglevel.error(chalk.redBright(`🐺 ${msg}`)),
38
- debug: (msg: string) => loglevel.debug(chalk.gray(`🐺 ${msg}`)),
39
- raw: loglevel,
40
- };
41
-
42
- loglevel.setLevel(config.logLevel);
43
-
44
- return {
45
- cwd,
46
- port,
47
- vovkPort,
48
- apiEntryPoint,
49
- apiPrefix,
50
- apiDir,
51
- srcRoot,
52
- metadataOutFullPath,
53
- metadataOutImportPath,
54
- clientOutFullPath,
55
- fetcherClientImportPath,
56
- config,
57
- log,
58
- };
59
- }
@@ -1,44 +0,0 @@
1
- import { promises as fs } from 'fs';
2
- import path from 'path';
3
- import type { VovkConfig } from '../types.mjs';
4
-
5
- async function findConfigPath(): Promise<string | null> {
6
- const rootDir = process.cwd();
7
- const baseName = 'vovk.config';
8
- const extensions = ['cjs', 'mjs', 'js'];
9
-
10
- for (const ext of extensions) {
11
- const filePath = path.join(rootDir, `${baseName}.${ext}`);
12
- try {
13
- await fs.stat(filePath);
14
- return filePath; // Return the path if the file exists
15
- } catch {
16
- // If the file doesn't exist, an error is thrown. Catch it and continue checking.
17
- }
18
- }
19
-
20
- return null; // Return null if no config file was found
21
- }
22
-
23
- async function readConfig(): Promise<VovkConfig> {
24
- const configPath = await findConfigPath();
25
- let config: VovkConfig = {};
26
-
27
- if (!configPath) {
28
- return config;
29
- }
30
-
31
- try {
32
- if (configPath.endsWith('.cjs') || configPath.endsWith('.js')) {
33
- const cacheBuster = Date.now();
34
- ({ default: config } = (await import(`${configPath}?cache=${cacheBuster}`)) as { default: VovkConfig });
35
- }
36
- } catch (e) {
37
- // eslint-disable-next-line no-console
38
- console.error('🐺 ❌ Error reading config file:', (e as Error).message);
39
- }
40
-
41
- return config;
42
- }
43
-
44
- export default readConfig;
package/src/index.mts DELETED
@@ -1,113 +0,0 @@
1
- #!/usr/bin/env node
2
- import { Command } from 'commander';
3
- import concurrently from 'concurrently';
4
- import getAvailablePort from './utils/getAvailablePort.mjs';
5
- import { VovkCLIServer } from './server/index.mjs';
6
- import getProjectInfo from './getProjectInfo/index.mjs';
7
- import generateClient from './server/generateClient.mjs';
8
- import locateSegments from './locateSegments.mjs';
9
- import { VovkConfig, VovkEnv } from './types.mjs';
10
- import { VovkMetadata } from 'vovk';
11
- import path from 'path';
12
- import { readFileSync } from 'fs';
13
-
14
- export type { VovkConfig, VovkEnv };
15
-
16
- interface DevOptions {
17
- project: string;
18
- clientOut?: string;
19
- nextDev: boolean;
20
- }
21
-
22
- interface GenerateOptions {
23
- clientOut?: string;
24
- }
25
-
26
- const program = new Command();
27
-
28
- const packageJSON = JSON.parse(readFileSync(path.join(import.meta.dirname, '../package.json'), 'utf-8')) as {
29
- version: string;
30
- };
31
-
32
- program.name('vovk').description('Vovk CLI').version(packageJSON.version);
33
-
34
- program
35
- .command('dev')
36
- .description('Start development server (optional flag --next-dev to start Vovk Server with Next.js)')
37
- .option('--project <path>', 'Path to Next.js project', process.cwd())
38
- .option('--client-out <path>', 'Path to client output directory')
39
- .option('--next-dev', 'Start Vovk Server and Next.js with automatic port allocation', false)
40
- .allowUnknownOption(true)
41
- .action(async (options: DevOptions, command: Command) => {
42
- const portAttempts = 30;
43
- const PORT = !options.nextDev
44
- ? process.env.PORT
45
- : process.env.PORT ||
46
- (await getAvailablePort(3000, portAttempts, 0, (failedPort, tryingPort) =>
47
- // eslint-disable-next-line no-console
48
- console.warn(`🐺 Next.js Port ${failedPort} is in use, trying ${tryingPort} instead.`)
49
- ).catch(() => {
50
- throw new Error(`🐺 ❌ Failed to find available Next port after ${portAttempts} attempts`);
51
- }));
52
-
53
- if (!PORT) {
54
- throw new Error('🐺 ❌ PORT env variable is required');
55
- }
56
-
57
- if (options.nextDev) {
58
- const { result } = concurrently(
59
- [
60
- {
61
- command: `node ${import.meta.dirname}/server/index.mjs`,
62
- name: 'Vovk.ts Metadata Server',
63
- env: Object.assign(
64
- { PORT, __VOVK_START_SERVER_IN_STANDALONE_MODE__: 'true' as const },
65
- options.clientOut ? { VOVK_CLIENT_OUT_DIR: options.clientOut } : {}
66
- ),
67
- },
68
- {
69
- command: `cd ${options.project} && npx next dev ${command.args.join(' ')}`,
70
- name: 'Next.js Development Server',
71
- env: { PORT },
72
- },
73
- ],
74
- {
75
- killOthers: ['failure', 'success'],
76
- prefix: 'none',
77
- }
78
- );
79
- try {
80
- await result;
81
- } finally {
82
- // eslint-disable-next-line no-console
83
- console.log('🐺 Exiting...');
84
- }
85
- } else {
86
- void new VovkCLIServer().startServer({ clientOutDir: options.clientOut });
87
- }
88
- });
89
-
90
- program
91
- .command('generate')
92
- .description('Generate client')
93
- .option('--client-out <path>', 'Path to output directory')
94
- .action(async (options: GenerateOptions) => {
95
- const projectInfo = await getProjectInfo({ clientOutDir: options.clientOut });
96
- const segments = await locateSegments(projectInfo.apiDir);
97
- const metadata = (await import(path.join(projectInfo.metadataOutFullPath, 'index.js'))) as {
98
- default: Record<string, VovkMetadata>;
99
- };
100
-
101
- await generateClient(projectInfo, segments, metadata.default);
102
- });
103
-
104
- program
105
- .command('help')
106
- .description('Show help message')
107
- .action(() => program.help());
108
-
109
- program.parse(process.argv);
110
-
111
- if (!process.argv.slice(2).length) {
112
- program.outputHelp();
113
- }
package/src/init.mts DELETED
@@ -1,174 +0,0 @@
1
- #!/usr/bin/env node
2
- /*
3
- npx vovk-cli init
4
- - Check if the project is already initialized
5
- - Do you want to reinitialize the project?
6
- - Yes
7
- - No (exit)
8
- - Check for package.json, if not found, show error and exit
9
- - Check for tsconfig.json, if not found, show error and exit
10
- - Check Next.js installed
11
- - Choose validation library: add to the installation list
12
- - vovk-zod
13
- - Further installation notes: install zod
14
- - vovk-yup
15
- - Further installation notes: install yup
16
- - vovk-dto
17
- - Further installation notes: install class-validator and class-transformer
18
- - None
19
- - If validation library is not None,
20
- - Do you want to enable client validation?
21
- - Yes
22
- - Add client validation to the config
23
- - No
24
- - Do you want to use concurrently? (NO NEED, USE CONCURRENTLY BY DEFAULT)
25
- - Yes (recommended)
26
- - Add concurrently to the installation list
27
- - No
28
- - Do you want to update NPM scripts?
29
- - Yes
30
- - Update NPM scripts
31
- - No
32
- - if experimentalDecorators is not found in tsconfig.json,
33
- - Do you want to add experimentalDecorators to tsconfig.json?
34
- - Yes
35
- - Add experimentalDecorators to tsconfig.json
36
- - No
37
- - Do you want to create route file with example service and controller? (NO NEED)
38
- - Yes
39
- - Create route file with example controller
40
- - No, I will create it myself
41
- - End
42
- - If there are any packages to install, install them
43
- - Show installation notes
44
- - If there are any files to create, create
45
- - If there are any config files to update, update
46
- - If example route file is NOT created, show example route file and controller
47
- - Show how to run the project
48
- - If npm scripts are updated
49
- - npm run dev
50
- - If npm scripts are NOT updated
51
- - If concurrently is installed
52
- - concurrently "vovk dev" "next dev"
53
- - If concurrently is NOT installed
54
- - vovk dev --next-dev
55
- - Open http://localhost:3000/api/hello-world
56
- - Show how to make a request to the example route
57
- - Show success message
58
- */
59
-
60
- import { confirm } from '@inquirer/prompts';
61
- // Or
62
- // import confirm from '@inquirer/confirm';
63
-
64
- // eslint-disable-next-line no-console
65
- void confirm({ message: 'Continue?' }).then(console.info);
66
-
67
- /*
68
- const wizard = [
69
- {
70
- description: 'Check if the project is already initialized',
71
- type: 'check',
72
- choices: {
73
- type: 'choice',
74
- choices: [
75
- {
76
- label: 'Yes',
77
- action: 'continue',
78
- },
79
- {
80
- label: 'No',
81
- action: 'exit',
82
- exitMessage: 'Exiting...',
83
- },
84
- ],
85
- },
86
- },
87
- {
88
- description: 'Check for package.json',
89
- type: 'check',
90
- handleCheck: () => {
91
- // Check if the project is already initialized
92
- },
93
- yes: {
94
- action: 'continue',
95
- },
96
- no: {
97
- action: 'exit',
98
- exitMessage: 'Exiting...',
99
- },
100
- },
101
- {
102
- description: 'Check for tsconfig.json',
103
- type: 'check',
104
- handleCheck: () => {
105
- // Check for package.json
106
- },
107
- yes: {
108
- action: 'continue',
109
- },
110
- no: {
111
- action: 'exit',
112
- exitMessage: 'Exiting...',
113
- },
114
- },
115
- {
116
- description: 'Check Next.js installed with app router',
117
- type: 'check',
118
- handleCheck: () => {
119
- // Check for tsconfig.json
120
- },
121
- yes: {
122
- action: 'continue',
123
- },
124
- no: {
125
- action: 'exit',
126
- exitMessage: 'Exiting...',
127
- },
128
- },
129
- {
130
- description: 'Choose validation library',
131
- type: 'install',
132
- choices: {
133
- type: 'choice',
134
- choices: [
135
- {
136
- package: 'vovk-zod',
137
- action: 'install',
138
- notes: 'Further installation notes: install zod',
139
- },
140
- {
141
- package: 'vovk-yup',
142
- action: 'install',
143
- notes: 'Further installation notes: install yup',
144
- },
145
- {
146
- package: 'vovk-dto',
147
- action: 'install',
148
- notes: 'Further installation notes: install class-validator and class-transformer',
149
- },
150
- {
151
- package: null,
152
- action: 'continue',
153
- },
154
- ],
155
- },
156
- },
157
- {
158
- description: 'Do you want to enable client validation?',
159
- type: 'choice',
160
- choices: [
161
- {
162
- label: 'Yes',
163
- action: 'updateConfig',
164
- },
165
- {
166
- label: 'No',
167
- action: 'updateConfig',
168
- },
169
- ],
170
- },
171
- ];
172
-
173
- // export default console.info(wizard);
174
- */
@@ -1,40 +0,0 @@
1
- import { promises as fs } from 'fs';
2
- import * as path from 'path';
3
- import fileExists from './utils/fileExists.mjs';
4
-
5
- export type Segment = {
6
- routeFilePath: string;
7
- segmentName: string;
8
- };
9
-
10
- export default async function locateSegments(dir: string, rootDir = dir): Promise<Segment[]> {
11
- let results: Segment[] = [];
12
-
13
- // Read the contents of the directory
14
- const list = await fs.readdir(dir);
15
-
16
- // Iterate through each item in the directory
17
- for (const file of list) {
18
- const filePath = path.join(dir, file);
19
- const stat = await fs.stat(filePath);
20
-
21
- if (stat.isDirectory()) {
22
- // Check if the directory name matches the pattern [[...something]]
23
- if (file.startsWith('[[...') && file.endsWith(']]')) {
24
- // Check if there's a route.ts file inside this directory
25
- const routeFilePath = path.join(filePath, 'route.ts');
26
- if (await fileExists(routeFilePath)) {
27
- // Calculate the basePath relative to the root directory
28
- const segmentName = path.relative(rootDir, dir);
29
- results.push({ routeFilePath, segmentName });
30
- }
31
- }
32
-
33
- // Recursively search inside subdirectories
34
- const subDirResults = await locateSegments(filePath, rootDir);
35
- results = results.concat(subDirResults);
36
- }
37
- }
38
-
39
- return results;
40
- }
@@ -1,27 +0,0 @@
1
- import { promises as fs } from 'fs';
2
- import path from 'path';
3
-
4
- /**
5
- * Checks if a file exists at the given path.
6
- * @param {string} filePath - The path to the file.
7
- * @returns {Promise<boolean>} - A promise that resolves to true if the file exists, false otherwise.
8
- */
9
- const fileExists = async (filePath: string): Promise<boolean> => !!(await fs.stat(filePath).catch(() => false));
10
-
11
- async function postinstall(): Promise<void> {
12
- const vovk = path.join(import.meta.dirname, '../../.vovk');
13
- const js = path.join(vovk, 'client.js');
14
- const ts = path.join(vovk, 'client.d.ts');
15
- const index = path.join(vovk, 'index.ts');
16
-
17
- if ((await fileExists(js)) || (await fileExists(ts)) || (await fileExists(index))) {
18
- return;
19
- }
20
-
21
- await fs.mkdir(vovk, { recursive: true });
22
- await fs.writeFile(js, '/* postinstall */');
23
- await fs.writeFile(ts, '/* postinstall */');
24
- await fs.writeFile(index, '/* postinstall */');
25
- }
26
-
27
- void postinstall();