vovk 0.2.3-beta.112 → 0.2.3-beta.114
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/cli/{generateClient.js → generateClient.mjs} +14 -14
- package/cli/{getVars.js → getVars.mjs} +4 -6
- package/cli/{index.js → index.mjs} +12 -30
- package/cli/lib/{getAvailablePort.js → getAvailablePort.mjs} +2 -4
- package/cli/lib/{getReturnPath.js → getReturnPath.mjs} +1 -3
- package/cli/lib/{isEqual.js → isEqual.mjs} +2 -4
- package/cli/lib/{parallel.js → parallel.mjs} +2 -4
- package/cli/lib/{parseCommandLineArgs.js → parseCommandLineArgs.mjs} +1 -3
- package/cli/{postinstall.js → postinstall.mjs} +2 -2
- package/cli/{server.js → server.mjs} +34 -34
- package/package.json +7 -6
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import getReturnPath from './lib/getReturnPath.mjs';
|
|
5
5
|
|
|
6
|
-
/** @type {(moduleName: string) => boolean} */
|
|
7
|
-
function
|
|
6
|
+
/** @type {(moduleName: string) => Promise<boolean>} */
|
|
7
|
+
async function canImport(moduleName) {
|
|
8
8
|
try {
|
|
9
|
-
|
|
10
|
-
return true; // The module exists and can be
|
|
9
|
+
await import(moduleName);
|
|
10
|
+
return true; // The module exists and can be imported
|
|
11
11
|
} catch (e) {
|
|
12
|
-
return false; // The module does not exist
|
|
12
|
+
return false; // The module does not exist or cannot be imported
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -18,7 +18,7 @@ function canRequire(moduleName) {
|
|
|
18
18
|
* TODO: Check fetcher for existence
|
|
19
19
|
* @type {(rcPath: import('../src').VovkEnv) => Promise<{ written: boolean; path: string }>}
|
|
20
20
|
*/
|
|
21
|
-
async function generateClient({ ...env }) {
|
|
21
|
+
export default async function generateClient({ ...env }) {
|
|
22
22
|
const outDir = env.VOVK_CLIENT_OUT;
|
|
23
23
|
const returnDir = getReturnPath(outDir, process.cwd());
|
|
24
24
|
const jsonPath = path.join(returnDir, '.vovk.json');
|
|
@@ -26,20 +26,22 @@ async function generateClient({ ...env }) {
|
|
|
26
26
|
const fetcherPath = env.VOVK_FETCHER.startsWith('.') ? path.join(returnDir, env.VOVK_FETCHER) : env.VOVK_FETCHER;
|
|
27
27
|
|
|
28
28
|
if (!env.VOVK_VALIDATE_ON_CLIENT) {
|
|
29
|
-
env.VOVK_VALIDATE_ON_CLIENT =
|
|
29
|
+
env.VOVK_VALIDATE_ON_CLIENT = (await canImport('vovk-zod/zodValidateOnClient'))
|
|
30
|
+
? 'vovk-zod/zodValidateOnClient'
|
|
31
|
+
: '';
|
|
30
32
|
}
|
|
31
33
|
const validatePath = env.VOVK_VALIDATE_ON_CLIENT.startsWith('.')
|
|
32
34
|
? path.join(returnDir, env.VOVK_VALIDATE_ON_CLIENT)
|
|
33
35
|
: env.VOVK_VALIDATE_ON_CLIENT;
|
|
34
36
|
const localValidatePath = env.VOVK_VALIDATE_ON_CLIENT.startsWith('.') ? path.join('..', validatePath) : validatePath;
|
|
35
37
|
|
|
36
|
-
if (env.VOVK_VALIDATE_ON_CLIENT && !
|
|
38
|
+
if (env.VOVK_VALIDATE_ON_CLIENT && !(await canImport(localValidatePath))) {
|
|
37
39
|
throw new Error(
|
|
38
40
|
`Unble to generate Vovk Client: cannot find "validateOnClient" module '${env.VOVK_VALIDATE_ON_CLIENT}'. Check your vovk.config.js file`
|
|
39
41
|
);
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
if (!
|
|
44
|
+
if (!(await canImport(localJsonPath))) {
|
|
43
45
|
throw new Error(`Unble to generate Vovk Client: cannot find ".vovk.json" file '${jsonPath}'.`);
|
|
44
46
|
}
|
|
45
47
|
|
|
@@ -116,5 +118,3 @@ type Options = typeof fetcher extends VovkClientFetcher<infer U> ? U : never;
|
|
|
116
118
|
|
|
117
119
|
return { written: true, path: outDir };
|
|
118
120
|
}
|
|
119
|
-
|
|
120
|
-
module.exports = generateClient;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import path from 'path';
|
|
4
4
|
|
|
5
5
|
/** @type {import('../src').VovkEnv} */
|
|
6
6
|
let vars;
|
|
7
|
-
/** @type {(rcPath: string, options?: { VOVK_CLIENT_OUT?: string; PORT?: string; }) => import('../src').VovkEnv} */
|
|
8
|
-
function getVars(configPath, options = {}) {
|
|
7
|
+
/** @type {(rcPath: string, options?: { VOVK_CLIENT_OUT?: string; PORT?: string; }) => Promise<import('../src').VovkEnv>} */
|
|
8
|
+
export default async function getVars(configPath, options = {}) {
|
|
9
9
|
if (vars) return vars;
|
|
10
10
|
/** @type {Required<import('../src').VovkConfig>} */
|
|
11
11
|
const vovkConfig = {
|
|
@@ -19,7 +19,7 @@ function getVars(configPath, options = {}) {
|
|
|
19
19
|
try {
|
|
20
20
|
// make PORT available to the config file
|
|
21
21
|
process.env.PORT = options.PORT || process.env.PORT || '3000';
|
|
22
|
-
Object.assign(vovkConfig,
|
|
22
|
+
Object.assign(vovkConfig, await import(configPath));
|
|
23
23
|
} catch {
|
|
24
24
|
// noop
|
|
25
25
|
}
|
|
@@ -43,5 +43,3 @@ function getVars(configPath, options = {}) {
|
|
|
43
43
|
|
|
44
44
|
return vars;
|
|
45
45
|
}
|
|
46
|
-
|
|
47
|
-
module.exports = getVars;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// @ts-check
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import generateClient from './generateClient.mjs';
|
|
5
|
+
import parallel from './lib/parallel.mjs';
|
|
6
|
+
import getAvailablePort from './lib/getAvailablePort.mjs';
|
|
7
|
+
import getVars from './getVars.mjs';
|
|
8
|
+
import parseCommandLineArgs from './lib/parseCommandLineArgs.mjs';
|
|
9
9
|
|
|
10
10
|
const { command, flags, restArgs } = parseCommandLineArgs();
|
|
11
11
|
const {
|
|
12
12
|
config = path.join(process.cwd(), 'vovk.config.js'), // Path to vovk.config.js
|
|
13
|
+
// TODO not documented
|
|
13
14
|
project = process.cwd(), // Path to Next.js project
|
|
14
15
|
clientOut = path.join(process.cwd(), './node_modules/.vovk'), // Path to output directory
|
|
15
16
|
} = flags;
|
|
@@ -22,7 +23,7 @@ if (command === 'dev') {
|
|
|
22
23
|
throw new Error(' 🐺 Failed to find available Next port');
|
|
23
24
|
}));
|
|
24
25
|
|
|
25
|
-
const env = getVars(config, { VOVK_CLIENT_OUT: clientOut, PORT });
|
|
26
|
+
const env = await getVars(config, { VOVK_CLIENT_OUT: clientOut, PORT });
|
|
26
27
|
|
|
27
28
|
let VOVK_PORT = parseInt(env.VOVK_PORT);
|
|
28
29
|
|
|
@@ -42,36 +43,17 @@ if (command === 'dev') {
|
|
|
42
43
|
).catch((e) => console.error(e));
|
|
43
44
|
console.info(' 🐺 All processes have ended');
|
|
44
45
|
})();
|
|
45
|
-
} else if (command === '
|
|
46
|
+
} else if (command === 'generate') {
|
|
46
47
|
void (async () => {
|
|
47
|
-
const env = getVars(config, { VOVK_CLIENT_OUT: clientOut });
|
|
48
|
-
|
|
49
|
-
let VOVK_PORT = parseInt(env.VOVK_PORT);
|
|
48
|
+
const env = await getVars(config, { VOVK_CLIENT_OUT: clientOut });
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
void generateClient(env).then(({ path }) => {
|
|
51
|
+
console.info(` 🐺 Client generated in ${path}`);
|
|
53
52
|
});
|
|
54
|
-
await parallel(
|
|
55
|
-
[
|
|
56
|
-
{
|
|
57
|
-
command: `node ${__dirname}/server.js --once`,
|
|
58
|
-
name: 'Vovk',
|
|
59
|
-
},
|
|
60
|
-
{ command: `cd ${project} && npx next build ${restArgs}`, name: 'Next' },
|
|
61
|
-
],
|
|
62
|
-
env
|
|
63
|
-
).catch((e) => console.error(e));
|
|
64
53
|
})();
|
|
65
|
-
} else if (command === 'generate') {
|
|
66
|
-
const env = getVars(config, { VOVK_CLIENT_OUT: clientOut });
|
|
67
|
-
|
|
68
|
-
void generateClient(env).then(({ path }) => {
|
|
69
|
-
console.info(` 🐺 Client generated in ${path}`);
|
|
70
|
-
});
|
|
71
54
|
} else if (command === 'help') {
|
|
72
55
|
console.info(` 🐺 Vovk CLI
|
|
73
56
|
dev - Start development server
|
|
74
|
-
build - Build Next.js project
|
|
75
57
|
generate - Generate client
|
|
76
58
|
help - Show this help message`);
|
|
77
59
|
} else {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import net from 'net';
|
|
2
2
|
|
|
3
3
|
function checkPort(port, callback) {
|
|
4
4
|
const server = net.createServer();
|
|
@@ -15,7 +15,7 @@ function checkPort(port, callback) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/** @type {(startPort: number, maxAttempts: number, attempt?: number) => Promise<string>} */
|
|
18
|
-
function getAvailablePort(startPort, maxAttempts, attempt = 1) {
|
|
18
|
+
export default function getAvailablePort(startPort, maxAttempts, attempt = 1) {
|
|
19
19
|
return new Promise((resolve, reject) => {
|
|
20
20
|
checkPort(startPort, (isAvailable) => {
|
|
21
21
|
if (isAvailable) {
|
|
@@ -28,5 +28,3 @@ function getAvailablePort(startPort, maxAttempts, attempt = 1) {
|
|
|
28
28
|
});
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
|
-
|
|
32
|
-
module.exports = getAvailablePort;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
/** @type {(fromPath: string, toPath: string) => string} */
|
|
3
|
-
function getReturnPath(fromPath, toPath) {
|
|
3
|
+
export default function getReturnPath(fromPath, toPath) {
|
|
4
4
|
// Split the paths into components
|
|
5
5
|
const fromParts = fromPath.replace(/^\.?\/|\/$/g, '').split('/');
|
|
6
6
|
const toParts = toPath.replace(/^\.?\/|\/$/g, '').split('/');
|
|
@@ -24,5 +24,3 @@ function getReturnPath(fromPath, toPath) {
|
|
|
24
24
|
|
|
25
25
|
return result;
|
|
26
26
|
}
|
|
27
|
-
|
|
28
|
-
module.exports = getReturnPath;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
/** @type {(obj1: any, obj2: any) => boolean} */
|
|
3
|
-
|
|
3
|
+
export default function isEqual(obj1, obj2) {
|
|
4
4
|
if (obj1 === obj2) {
|
|
5
5
|
return true;
|
|
6
6
|
}
|
|
@@ -23,6 +23,4 @@ const isEqual = (obj1, obj2) => {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
return true;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
module.exports = isEqual;
|
|
26
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
|
|
2
|
+
import { spawn } from 'child_process';
|
|
3
3
|
|
|
4
4
|
/** @type {(commands: { command: string; name: string; }[], env: import('../../src').VovkEnv) => Promise<void>} */
|
|
5
|
-
function parallel(commands, env) {
|
|
5
|
+
export default function parallel(commands, env) {
|
|
6
6
|
return new Promise((resolve, reject) => {
|
|
7
7
|
/** @type {{ name: string; process: import('child_process').ChildProcess; }[]} */
|
|
8
8
|
let processes = [];
|
|
@@ -46,5 +46,3 @@ function parallel(commands, env) {
|
|
|
46
46
|
}
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
module.exports = parallel;
|
|
@@ -7,7 +7,7 @@ function toCamelCase(str) {
|
|
|
7
7
|
|
|
8
8
|
/** @typedef {{ config?: string; project?: string; clientOut?: string }} Flags */
|
|
9
9
|
/** @typedef {'dev' | 'build' | 'generate' | 'help'} Command */
|
|
10
|
-
function parseCommandLineArgs() {
|
|
10
|
+
export default function parseCommandLineArgs() {
|
|
11
11
|
const args = process.argv.slice(2); // Slice off node and script path
|
|
12
12
|
let command = /** @type {Command} */ null;
|
|
13
13
|
/** @type {Flags} */
|
|
@@ -37,5 +37,3 @@ function parseCommandLineArgs() {
|
|
|
37
37
|
|
|
38
38
|
return { command, flags, restArgs };
|
|
39
39
|
}
|
|
40
|
-
|
|
41
|
-
module.exports = parseCommandLineArgs;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import path from 'path';
|
|
4
4
|
|
|
5
5
|
/** @type {(path: string) => Promise<boolean>} */
|
|
6
6
|
const fileExists = async (path) => !!(await fs.stat(path).catch(() => false));
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import http from 'http';
|
|
3
|
+
import fs from 'fs/promises';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import parseCommandLineArgs from './lib/parseCommandLineArgs.mjs';
|
|
6
|
+
import generateClient from './generateClient.mjs';
|
|
7
|
+
import getVars from './getVars.mjs';
|
|
8
|
+
import isEqual from './lib/isEqual.mjs';
|
|
9
9
|
|
|
10
10
|
const { flags } = parseCommandLineArgs();
|
|
11
11
|
|
|
12
|
-
const {
|
|
12
|
+
const { config } = /** @type {{ config: string }} */ (flags);
|
|
13
13
|
|
|
14
14
|
const metadataPath = path.join(__dirname, '../../../.vovk.json');
|
|
15
15
|
|
|
@@ -36,26 +36,32 @@ let pingInterval;
|
|
|
36
36
|
/** @type {import('../src').VovkEnv} */
|
|
37
37
|
let vars;
|
|
38
38
|
|
|
39
|
+
/** @type {() => Promise<void>} */
|
|
40
|
+
const ping = async () => {
|
|
41
|
+
vars = vars ?? (await getVars(config));
|
|
42
|
+
let prefix = vars.VOVK_PREFIX;
|
|
43
|
+
prefix = prefix.startsWith('http://')
|
|
44
|
+
? prefix
|
|
45
|
+
: `http://localhost:${process.env.PORT}/${prefix.startsWith('/') ? prefix.slice(1) : prefix}`;
|
|
46
|
+
const endpoint = `${prefix.endsWith('/') ? prefix.slice(0, -1) : prefix}/__ping`;
|
|
47
|
+
// Create the HTTP GET request
|
|
48
|
+
const req = http.get(endpoint, () => {
|
|
49
|
+
// noop
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Error handling for the request
|
|
53
|
+
req.on('error', (err) => {
|
|
54
|
+
console.error(`🐺 ❌ Error during HTTP request made to ${endpoint}:`, err.message);
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// make initial ping
|
|
59
|
+
setTimeout(() => void ping(), 1000 * 3);
|
|
60
|
+
|
|
39
61
|
/** @type {() => void} */
|
|
40
|
-
const
|
|
62
|
+
const constantlyPing = () => {
|
|
41
63
|
clearInterval(pingInterval);
|
|
42
|
-
pingInterval = setInterval(() =>
|
|
43
|
-
vars = vars ?? getVars(config);
|
|
44
|
-
let prefix = vars.VOVK_PREFIX;
|
|
45
|
-
prefix = prefix.startsWith('http://')
|
|
46
|
-
? prefix
|
|
47
|
-
: `http://localhost:${process.env.PORT}/${prefix.startsWith('/') ? prefix.slice(1) : prefix}`;
|
|
48
|
-
const endpoint = `${prefix.endsWith('/') ? prefix.slice(0, -1) : prefix}/__ping`;
|
|
49
|
-
// Create the HTTP GET request
|
|
50
|
-
const req = http.get(endpoint, () => {
|
|
51
|
-
// noop
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// Error handling for the request
|
|
55
|
-
req.on('error', (err) => {
|
|
56
|
-
console.error(`🐺 ❌ Error during HTTP request made to ${endpoint}:`, err.message);
|
|
57
|
-
});
|
|
58
|
-
}, 1000 * 3);
|
|
64
|
+
pingInterval = setInterval(() => void ping(), 1000 * 3);
|
|
59
65
|
};
|
|
60
66
|
|
|
61
67
|
const server = http.createServer((req, res) => {
|
|
@@ -72,7 +78,7 @@ const server = http.createServer((req, res) => {
|
|
|
72
78
|
/** @type {{ metadata?: import('../src') }} */
|
|
73
79
|
const { metadata } = JSON.parse(body); // Parse the JSON data
|
|
74
80
|
const metadataWritten = metadata ? await writeMetadata(metadata) : { written: false, path: metadataPath };
|
|
75
|
-
vars = vars ?? getVars(config);
|
|
81
|
+
vars = vars ?? (await getVars(config));
|
|
76
82
|
const codeWritten = await generateClient(vars);
|
|
77
83
|
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
78
84
|
res.end('JSON data received and file created');
|
|
@@ -84,18 +90,12 @@ const server = http.createServer((req, res) => {
|
|
|
84
90
|
console.info(` 🐺 Client generated in ${codeWritten.path}`);
|
|
85
91
|
}
|
|
86
92
|
|
|
87
|
-
|
|
88
|
-
startPinging();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (once && metadata) server.close();
|
|
93
|
+
constantlyPing();
|
|
92
94
|
} catch (e) {
|
|
93
95
|
const err = /** @type {Error} */ (e);
|
|
94
96
|
res.writeHead(400, { 'Content-Type': 'text/plain' });
|
|
95
97
|
res.end(err?.message ?? 'Error');
|
|
96
98
|
console.error(' 🐺 ❌ ' + err?.message);
|
|
97
|
-
|
|
98
|
-
if (once) server.close();
|
|
99
99
|
}
|
|
100
100
|
});
|
|
101
101
|
} else {
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vovk",
|
|
3
|
-
"version": "0.2.3-beta.
|
|
3
|
+
"version": "0.2.3-beta.114",
|
|
4
4
|
"description": "Structural add-on for Next.js",
|
|
5
|
-
"bin": "./cli/index.
|
|
5
|
+
"bin": "./cli/index.mjs",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"postinstall": "node ./cli/postinstall.js",
|
|
8
8
|
"upgrade": "npx npm-check-updates -u && npm i",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"minor": "npm t && npm version minor && npm run build && npm publish ./dist && git push && git push --tags",
|
|
23
23
|
"BREAKING-major": "npm t && npm version major && npm run build && npm publish ./dist && git push && git push --tags",
|
|
24
24
|
"beta": "npm t && npm version prerelease --preid=beta && npm run build && npm publish ./dist --tag beta && git push && git push --tags",
|
|
25
|
+
"beta-notest": "npm version prerelease --preid=beta && npm run build && npm publish ./dist --tag beta && git push && git push --tags",
|
|
25
26
|
"beta-patch": "npm t && npm version prepatch --preid=beta && npm run build && npm publish ./dist --tag beta && git push && git push --tags",
|
|
26
27
|
"beta-minor": "npm t && npm version preminor --preid=beta && npm run build && npm publish ./dist --tag beta && git push && git push --tags",
|
|
27
28
|
"BREAKING-beta-major": "npm t && npm version premajor --preid=beta && npm run build && npm publish ./dist --tag beta && git push && git push --tags"
|
|
@@ -51,16 +52,16 @@
|
|
|
51
52
|
"@types/jest": "^29.5.12",
|
|
52
53
|
"@types/lodash": "^4.14.202",
|
|
53
54
|
"@types/supertest": "^6.0.2",
|
|
54
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
|
55
|
-
"@typescript-eslint/parser": "^6.
|
|
55
|
+
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
|
56
|
+
"@typescript-eslint/parser": "^6.21.0",
|
|
56
57
|
"eslint": "^8.56.0",
|
|
57
58
|
"eslint-config-prettier": "^9.1.0",
|
|
58
59
|
"eslint-plugin-prettier": "^5.1.3",
|
|
59
60
|
"jest": "^29.7.0",
|
|
60
61
|
"lodash": "^4.17.21",
|
|
61
62
|
"next": "^14.1.0",
|
|
62
|
-
"prettier": "^3.2.
|
|
63
|
-
"puppeteer": "^
|
|
63
|
+
"prettier": "^3.2.5",
|
|
64
|
+
"puppeteer": "^22.0.0",
|
|
64
65
|
"supertest": "^6.3.4",
|
|
65
66
|
"ts-jest": "^29.1.2",
|
|
66
67
|
"typescript": "^5.3.3",
|