vovk-cli 0.0.1-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +20 -0
- package/README.md +1 -0
- package/dist/getProjectInfo/directoryExists.d.ts +1 -0
- package/dist/getProjectInfo/directoryExists.js +16 -0
- package/dist/getProjectInfo/getConfig.d.ts +7 -0
- package/dist/getProjectInfo/getConfig.js +29 -0
- package/dist/getProjectInfo/getCwdPath.d.ts +1 -0
- package/dist/getProjectInfo/getCwdPath.js +19 -0
- package/dist/getProjectInfo/getSrcRoot.d.ts +1 -0
- package/dist/getProjectInfo/getSrcRoot.js +19 -0
- package/dist/getProjectInfo/index.d.ts +48 -0
- package/dist/getProjectInfo/index.js +78 -0
- package/dist/getProjectInfo/readConfig.d.ts +3 -0
- package/dist/getProjectInfo/readConfig.js +73 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +104 -0
- package/dist/init.d.ts +2 -0
- package/dist/init.js +173 -0
- package/dist/locateSegments.d.ts +5 -0
- package/dist/locateSegments.js +58 -0
- package/dist/postinstall.d.ts +1 -0
- package/dist/postinstall.js +27 -0
- package/dist/server/createMetadataServer.d.ts +5 -0
- package/dist/server/createMetadataServer.js +31 -0
- package/dist/server/diffMetadata.d.ts +43 -0
- package/dist/server/diffMetadata.js +77 -0
- package/dist/server/ensureMetadataFiles.d.ts +3 -0
- package/dist/server/ensureMetadataFiles.js +100 -0
- package/dist/server/generateClient.d.ts +7 -0
- package/dist/server/generateClient.js +98 -0
- package/dist/server/index.d.ts +6 -0
- package/dist/server/index.js +285 -0
- package/dist/server/isMetadataEmpty.d.ts +2 -0
- package/dist/server/isMetadataEmpty.js +7 -0
- package/dist/server/logDiffResult.d.ts +3 -0
- package/dist/server/logDiffResult.js +84 -0
- package/dist/server/writeOneMetadataFile.d.ts +11 -0
- package/dist/server/writeOneMetadataFile.js +34 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.js +2 -0
- package/dist/utils/debounceWithArgs.d.ts +2 -0
- package/dist/utils/debounceWithArgs.js +20 -0
- package/dist/utils/fileExists.d.ts +1 -0
- package/dist/utils/fileExists.js +16 -0
- package/dist/utils/getAvailablePort.d.ts +10 -0
- package/dist/utils/getAvailablePort.js +47 -0
- package/package.json +43 -0
- package/src/getProjectInfo/directoryExists.ts +10 -0
- package/src/getProjectInfo/getConfig.ts +29 -0
- package/src/getProjectInfo/getCwdPath.ts +15 -0
- package/src/getProjectInfo/getSrcRoot.ts +14 -0
- package/src/getProjectInfo/index.ts +63 -0
- package/src/getProjectInfo/readConfig.ts +50 -0
- package/src/index.ts +112 -0
- package/src/init.ts +174 -0
- package/src/locateSegments.ts +40 -0
- package/src/postinstall.ts +27 -0
- package/src/server/createMetadataServer.ts +30 -0
- package/src/server/diffMetadata.ts +110 -0
- package/src/server/ensureMetadataFiles.ts +92 -0
- package/src/server/generateClient.ts +108 -0
- package/src/server/index.ts +306 -0
- package/src/server/isMetadataEmpty.ts +6 -0
- package/src/server/logDiffResult.ts +114 -0
- package/src/server/writeOneMetadataFile.ts +44 -0
- package/src/types.ts +58 -0
- package/src/utils/debounceWithArgs.ts +22 -0
- package/src/utils/fileExists.ts +10 -0
- package/src/utils/getAvailablePort.ts +50 -0
- package/test/data/segments/[[...vovk]]/route.ts +0 -0
- package/test/data/segments/bar/[[...custom]]/route.ts +0 -0
- package/test/data/segments/baz/[[...vovk]]/noroute.ts +0 -0
- package/test/data/segments/foo/[[...vovk]]/route.ts +0 -0
- package/test/data/segments/garply/waldo/route.ts +0 -0
- package/test/data/segments/grault/xxxx/[[...vovk]]/noroute.ts +0 -0
- package/test/data/segments/quux/corge/[[...vovk]]/route.ts +0 -0
- package/test/index.ts +3 -0
- package/test/metadata-diff.test.ts +300 -0
- package/test/metadata-write.test.ts +82 -0
- package/test/utils.test.ts +49 -0
- package/tsconfig.json +11 -0
- package/tsconfig.test.json +4 -0
package/src/types.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { LogLevelNames } from 'loglevel';
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
export type KnownAny = any;
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
export type VovkEnv = {
|
|
8
|
+
PORT?: string;
|
|
9
|
+
VOVK_ROUTE?: string;
|
|
10
|
+
VOVK_FETCHER?: string;
|
|
11
|
+
VOVK_PREFIX?: string;
|
|
12
|
+
VOVK_VALIDATE_ON_CLIENT?: string;
|
|
13
|
+
VOVK_PORT?: string;
|
|
14
|
+
VOVK_CLIENT_OUT?: string;
|
|
15
|
+
VOVK_METADATA_OUT?: string;
|
|
16
|
+
VOVK_MODULES_DIR?: string;
|
|
17
|
+
__VOVK_START_SERVER__?: string;
|
|
18
|
+
};
|
|
19
|
+
*/
|
|
20
|
+
export type VovkEnv = {
|
|
21
|
+
PORT?: string;
|
|
22
|
+
VOVK_CLIENT_OUT_DIR?: string;
|
|
23
|
+
VOVK_METADATA_OUT_DIR?: string;
|
|
24
|
+
VOVK_FETCHER?: string;
|
|
25
|
+
VOVK_VALIDATE_ON_CLIENT?: string;
|
|
26
|
+
VOVK_PORT?: string;
|
|
27
|
+
VOVK_MODULES_DIR?: string;
|
|
28
|
+
VOVK_VALIDATION_LIBRARY?: string;
|
|
29
|
+
VOVK_ORIGIN?: string;
|
|
30
|
+
VOVK_ROOT_ENTRY?: string;
|
|
31
|
+
VOVK_API_ENTRY_POINT?: string;
|
|
32
|
+
VOVK_ROOT_SEGMENT_MODULES_DIR_NAME?: string;
|
|
33
|
+
VOVK_LOG_LEVEL?: LogLevelNames;
|
|
34
|
+
__VOVK_START_SERVER_IN_STANDALONE_MODE__?: 'true';
|
|
35
|
+
};
|
|
36
|
+
/*
|
|
37
|
+
export type VovkConfig = {
|
|
38
|
+
clientOut?: string;
|
|
39
|
+
metadataOut?: string;
|
|
40
|
+
route?: string;
|
|
41
|
+
fetcher?: string;
|
|
42
|
+
prefix?: string;
|
|
43
|
+
validateOnClient?: string | null;
|
|
44
|
+
modulesDir?: string;
|
|
45
|
+
};
|
|
46
|
+
*/
|
|
47
|
+
export type VovkConfig = {
|
|
48
|
+
clientOutDir?: string;
|
|
49
|
+
metadataOutDir?: string;
|
|
50
|
+
fetcher?: string;
|
|
51
|
+
validateOnClient?: string | null;
|
|
52
|
+
modulesDir?: string;
|
|
53
|
+
validationLibrary?: string | null;
|
|
54
|
+
rootEntry?: string;
|
|
55
|
+
origin?: string;
|
|
56
|
+
rootSegmentModulesDirName?: string;
|
|
57
|
+
logLevel?: LogLevelNames;
|
|
58
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import debounce from 'lodash/debounce';
|
|
2
|
+
import { KnownAny } from '../types';
|
|
3
|
+
|
|
4
|
+
export default function debounceWithArgs<T extends (...args: KnownAny[]) => KnownAny>(
|
|
5
|
+
fn: T,
|
|
6
|
+
wait: number
|
|
7
|
+
): (...args: Parameters<T>) => void | Promise<void> {
|
|
8
|
+
const debouncedFunctions = new Map<string, ReturnType<typeof debounce>>();
|
|
9
|
+
|
|
10
|
+
return (...args: Parameters<T>) => {
|
|
11
|
+
const key = JSON.stringify(args);
|
|
12
|
+
|
|
13
|
+
if (!debouncedFunctions.has(key)) {
|
|
14
|
+
debouncedFunctions.set(key, debounce(fn, wait));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const debouncedFn = debouncedFunctions.get(key);
|
|
18
|
+
if (debouncedFn) {
|
|
19
|
+
debouncedFn(...args);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import net from 'net';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Checks if a port is available.
|
|
5
|
+
* @param {number} port - The port to check.
|
|
6
|
+
* @param {(isAvailable: boolean) => void} callback - The callback function.
|
|
7
|
+
*/
|
|
8
|
+
function checkPort(port: number, callback: (isAvailable: boolean) => void): void {
|
|
9
|
+
const server = net.createServer();
|
|
10
|
+
|
|
11
|
+
server.listen(port, () => {
|
|
12
|
+
server.close(() => {
|
|
13
|
+
callback(true); // Port is available
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
server.on('error', () => {
|
|
18
|
+
callback(false);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Finds an available port starting from a given port.
|
|
24
|
+
* @param {number} startPort - The port to start checking from.
|
|
25
|
+
* @param {number} maxAttempts - The maximum number of attempts to find an available port.
|
|
26
|
+
* @param {number} attempt - The current attempt number.
|
|
27
|
+
* @param {(failedPort: number, tryingPort: number) => void} onWarning - The callback function for warnings.
|
|
28
|
+
* @returns {Promise<string>}
|
|
29
|
+
*/
|
|
30
|
+
function getAvailablePort(
|
|
31
|
+
startPort: number,
|
|
32
|
+
maxAttempts: number,
|
|
33
|
+
attempt: number,
|
|
34
|
+
onWarning: (failedPort: number, tryingPort: number) => void
|
|
35
|
+
): Promise<string> {
|
|
36
|
+
return new Promise((resolve, reject) => {
|
|
37
|
+
checkPort(startPort, (isAvailable) => {
|
|
38
|
+
if (isAvailable) {
|
|
39
|
+
resolve(startPort.toString()); // Found an available port
|
|
40
|
+
} else if (attempt < maxAttempts) {
|
|
41
|
+
onWarning(startPort, startPort + 1);
|
|
42
|
+
getAvailablePort(startPort + 1, maxAttempts, attempt + 1, onWarning).then(resolve, reject);
|
|
43
|
+
} else {
|
|
44
|
+
reject('No available ports found');
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default getAvailablePort;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/test/index.ts
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { describe, test } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import diffMetadata from '../src/server/diffMetadata';
|
|
4
|
+
import { HttpMethod, type VovkMetadata } from 'vovk';
|
|
5
|
+
|
|
6
|
+
void describe('diffJson', async () => {
|
|
7
|
+
await test('Test case 1: No changes', () => {
|
|
8
|
+
const oldJson: VovkMetadata = {
|
|
9
|
+
emitMetadata: true,
|
|
10
|
+
segmentName: '',
|
|
11
|
+
workers: {
|
|
12
|
+
WorkerA: {
|
|
13
|
+
_workerName: 'WorkerA',
|
|
14
|
+
_handlers: { handlerA: {} },
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
controllers: {
|
|
18
|
+
ControllerA: {
|
|
19
|
+
_controllerName: 'ControllerA',
|
|
20
|
+
_handlers: {
|
|
21
|
+
handlerB: {
|
|
22
|
+
path: 'path',
|
|
23
|
+
httpMethod: HttpMethod.GET,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const newJson: VovkMetadata = { ...oldJson };
|
|
31
|
+
|
|
32
|
+
const diff = diffMetadata(oldJson, newJson);
|
|
33
|
+
|
|
34
|
+
assert.deepStrictEqual(diff, {
|
|
35
|
+
workers: {
|
|
36
|
+
added: [],
|
|
37
|
+
removed: [],
|
|
38
|
+
handlers: [],
|
|
39
|
+
},
|
|
40
|
+
controllers: {
|
|
41
|
+
added: [],
|
|
42
|
+
removed: [],
|
|
43
|
+
handlers: [],
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
await test('Test case 2: Workers and Controllers added and removed', () => {
|
|
49
|
+
const oldJson: VovkMetadata = {
|
|
50
|
+
emitMetadata: true,
|
|
51
|
+
segmentName: '',
|
|
52
|
+
workers: {
|
|
53
|
+
WorkerA: {
|
|
54
|
+
_workerName: 'WorkerA',
|
|
55
|
+
_handlers: { handlerA: {} },
|
|
56
|
+
},
|
|
57
|
+
WorkerB: {
|
|
58
|
+
_workerName: 'WorkerB',
|
|
59
|
+
_handlers: { handlerB: {} },
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
controllers: {
|
|
63
|
+
ControllerA: {
|
|
64
|
+
_controllerName: 'ControllerA',
|
|
65
|
+
_handlers: {
|
|
66
|
+
handlerC: {
|
|
67
|
+
path: 'path',
|
|
68
|
+
httpMethod: HttpMethod.GET,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const newJson: VovkMetadata = {
|
|
76
|
+
emitMetadata: true,
|
|
77
|
+
segmentName: '',
|
|
78
|
+
workers: {
|
|
79
|
+
WorkerB: {
|
|
80
|
+
_workerName: 'WorkerB',
|
|
81
|
+
_handlers: { handlerB: {} },
|
|
82
|
+
},
|
|
83
|
+
WorkerC: { _workerName: 'WorkerC', _handlers: { handlerD: {} } },
|
|
84
|
+
},
|
|
85
|
+
controllers: {
|
|
86
|
+
ControllerB: {
|
|
87
|
+
_controllerName: 'ControllerB',
|
|
88
|
+
_handlers: {
|
|
89
|
+
handlerE: {
|
|
90
|
+
path: 'path',
|
|
91
|
+
httpMethod: HttpMethod.GET,
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const diff = diffMetadata(oldJson, newJson);
|
|
99
|
+
|
|
100
|
+
assert.deepStrictEqual(diff, {
|
|
101
|
+
workers: {
|
|
102
|
+
added: ['WorkerC'],
|
|
103
|
+
removed: ['WorkerA'],
|
|
104
|
+
handlers: [],
|
|
105
|
+
},
|
|
106
|
+
controllers: {
|
|
107
|
+
added: ['ControllerB'],
|
|
108
|
+
removed: ['ControllerA'],
|
|
109
|
+
handlers: [],
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
await test('Test case 3: Handlers added, removed, and changed', () => {
|
|
115
|
+
const oldJson: VovkMetadata = {
|
|
116
|
+
emitMetadata: true,
|
|
117
|
+
segmentName: '',
|
|
118
|
+
workers: {
|
|
119
|
+
WorkerA: {
|
|
120
|
+
_workerName: 'WorkerA',
|
|
121
|
+
_handlers: { handlerA: {}, handlerB: {} },
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
controllers: {
|
|
125
|
+
ControllerA: {
|
|
126
|
+
_controllerName: 'ControllerA',
|
|
127
|
+
_handlers: {
|
|
128
|
+
handlerC: {
|
|
129
|
+
path: 'path',
|
|
130
|
+
httpMethod: HttpMethod.GET,
|
|
131
|
+
},
|
|
132
|
+
handlerD: {
|
|
133
|
+
path: 'path',
|
|
134
|
+
httpMethod: HttpMethod.GET,
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const newJson: VovkMetadata = {
|
|
142
|
+
emitMetadata: true,
|
|
143
|
+
segmentName: '',
|
|
144
|
+
workers: {
|
|
145
|
+
WorkerA: {
|
|
146
|
+
_workerName: 'WorkerA',
|
|
147
|
+
_handlers: {
|
|
148
|
+
handlerB: {}, // Unchanged
|
|
149
|
+
handlerE: {}, // Added
|
|
150
|
+
handlerA: { isGenerator: true }, // Changed
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
controllers: {
|
|
155
|
+
ControllerA: {
|
|
156
|
+
_controllerName: 'ControllerA',
|
|
157
|
+
_handlers: {
|
|
158
|
+
handlerD: {
|
|
159
|
+
path: 'path',
|
|
160
|
+
httpMethod: HttpMethod.GET,
|
|
161
|
+
},
|
|
162
|
+
handlerF: {
|
|
163
|
+
path: 'path',
|
|
164
|
+
httpMethod: HttpMethod.GET,
|
|
165
|
+
},
|
|
166
|
+
handlerC: {
|
|
167
|
+
path: 'newPath', // Changed
|
|
168
|
+
httpMethod: HttpMethod.GET,
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const diff = diffMetadata(oldJson, newJson);
|
|
176
|
+
|
|
177
|
+
assert.deepStrictEqual(diff, {
|
|
178
|
+
workers: {
|
|
179
|
+
added: [],
|
|
180
|
+
removed: [],
|
|
181
|
+
handlers: [
|
|
182
|
+
{
|
|
183
|
+
nameOfClass: 'WorkerA',
|
|
184
|
+
added: ['handlerE'],
|
|
185
|
+
removed: [],
|
|
186
|
+
changed: ['handlerA'],
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
controllers: {
|
|
191
|
+
added: [],
|
|
192
|
+
removed: [],
|
|
193
|
+
handlers: [
|
|
194
|
+
{
|
|
195
|
+
nameOfClass: 'ControllerA',
|
|
196
|
+
added: ['handlerF'],
|
|
197
|
+
removed: [],
|
|
198
|
+
changed: ['handlerC'],
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
await test('Test case 4: Complex changes', () => {
|
|
206
|
+
const oldJson: VovkMetadata = {
|
|
207
|
+
emitMetadata: true,
|
|
208
|
+
segmentName: '',
|
|
209
|
+
workers: {
|
|
210
|
+
WorkerA: {
|
|
211
|
+
_workerName: 'WorkerA',
|
|
212
|
+
_handlers: { handlerA: {}, handlerB: {} },
|
|
213
|
+
},
|
|
214
|
+
WorkerB: {
|
|
215
|
+
_workerName: 'WorkerB',
|
|
216
|
+
_handlers: { handlerC: {} },
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
controllers: {
|
|
220
|
+
ControllerA: {
|
|
221
|
+
_controllerName: 'ControllerA',
|
|
222
|
+
_handlers: {
|
|
223
|
+
handlerD: {
|
|
224
|
+
path: 'path',
|
|
225
|
+
httpMethod: HttpMethod.GET,
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
const newJson: VovkMetadata = {
|
|
233
|
+
emitMetadata: true,
|
|
234
|
+
segmentName: '',
|
|
235
|
+
workers: {
|
|
236
|
+
WorkerA: {
|
|
237
|
+
_workerName: 'WorkerA',
|
|
238
|
+
_handlers: { handlerB: {}, handlerE: {} },
|
|
239
|
+
},
|
|
240
|
+
WorkerC: {
|
|
241
|
+
_workerName: 'WorkerC',
|
|
242
|
+
_handlers: { handlerF: {} },
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
controllers: {
|
|
246
|
+
ControllerA: {
|
|
247
|
+
_controllerName: 'ControllerA',
|
|
248
|
+
_handlers: {
|
|
249
|
+
handlerD: {
|
|
250
|
+
path: 'path',
|
|
251
|
+
httpMethod: HttpMethod.GET,
|
|
252
|
+
},
|
|
253
|
+
handlerG: {
|
|
254
|
+
path: 'path',
|
|
255
|
+
httpMethod: HttpMethod.GET,
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
ControllerB: {
|
|
260
|
+
_controllerName: 'ControllerB',
|
|
261
|
+
_handlers: {
|
|
262
|
+
handlerH: {
|
|
263
|
+
path: 'path',
|
|
264
|
+
httpMethod: HttpMethod.GET,
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
const diff = diffMetadata(oldJson, newJson);
|
|
272
|
+
|
|
273
|
+
assert.deepStrictEqual(diff, {
|
|
274
|
+
workers: {
|
|
275
|
+
added: ['WorkerC'],
|
|
276
|
+
removed: ['WorkerB'],
|
|
277
|
+
handlers: [
|
|
278
|
+
{
|
|
279
|
+
nameOfClass: 'WorkerA',
|
|
280
|
+
added: ['handlerE'],
|
|
281
|
+
removed: ['handlerA'],
|
|
282
|
+
changed: [],
|
|
283
|
+
},
|
|
284
|
+
],
|
|
285
|
+
},
|
|
286
|
+
controllers: {
|
|
287
|
+
added: ['ControllerB'],
|
|
288
|
+
removed: [],
|
|
289
|
+
handlers: [
|
|
290
|
+
{
|
|
291
|
+
nameOfClass: 'ControllerA',
|
|
292
|
+
added: ['handlerG'],
|
|
293
|
+
removed: [],
|
|
294
|
+
changed: [],
|
|
295
|
+
},
|
|
296
|
+
],
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import { test, describe, beforeEach, afterEach } from 'node:test';
|
|
3
|
+
import fs from 'fs/promises';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import * as glob from 'glob';
|
|
6
|
+
import ensureMetadataFiles from '../src/server/ensureMetadataFiles';
|
|
7
|
+
|
|
8
|
+
const tmpDir = path.join(process.cwd(), 'tmp');
|
|
9
|
+
|
|
10
|
+
// Helper function to clear and create a temporary directory
|
|
11
|
+
async function setupTmpDir() {
|
|
12
|
+
await cleanupTmpDir();
|
|
13
|
+
await fs.mkdir(tmpDir, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function cleanupTmpDir() {
|
|
17
|
+
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
beforeEach(async () => {
|
|
21
|
+
await setupTmpDir();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
afterEach(async () => {
|
|
25
|
+
await cleanupTmpDir();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
void describe('Check if metadata files are created and removed correctly', async () => {
|
|
29
|
+
await test('ensureMetadataFiles creates and removes files correctly with nested segments', async () => {
|
|
30
|
+
const initialSegments = ['segment1', 'segment2', 'folder1/segment3', 'folder2/segment4'];
|
|
31
|
+
|
|
32
|
+
// Run the function with the initial segments
|
|
33
|
+
await ensureMetadataFiles(tmpDir, initialSegments, null);
|
|
34
|
+
|
|
35
|
+
// Check if files are created
|
|
36
|
+
let files = glob.sync('**/*.json', { cwd: tmpDir });
|
|
37
|
+
assert.deepStrictEqual(
|
|
38
|
+
files.sort(),
|
|
39
|
+
['segment1.json', 'segment2.json', 'folder1/segment3.json', 'folder2/segment4.json'].sort()
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// Check if index.js is created and has the correct content
|
|
43
|
+
const indexPath = path.join(tmpDir, 'index.js');
|
|
44
|
+
const expectedIndexContent = `module.exports['segment1'] = require('./segment1');
|
|
45
|
+
module.exports['segment2'] = require('./segment2');
|
|
46
|
+
module.exports['folder1/segment3'] = require('./folder1/segment3');
|
|
47
|
+
module.exports['folder2/segment4'] = require('./folder2/segment4');`;
|
|
48
|
+
|
|
49
|
+
const indexContent = await fs.readFile(indexPath, 'utf-8');
|
|
50
|
+
assert.strictEqual(indexContent.trim(), expectedIndexContent.trim());
|
|
51
|
+
|
|
52
|
+
// Update the segments list (segment2 and segment3 remain, segment1 and segment4 are removed, segment5 is added)
|
|
53
|
+
const updatedSegments = ['segment2', 'folder1/segment3', 'segment5'];
|
|
54
|
+
|
|
55
|
+
// Run the function with the updated segments
|
|
56
|
+
await ensureMetadataFiles(tmpDir, updatedSegments, null);
|
|
57
|
+
|
|
58
|
+
// Check if files are updated correctly
|
|
59
|
+
files = glob.sync('**/*.json', { cwd: tmpDir });
|
|
60
|
+
assert.deepStrictEqual(files.sort(), ['segment2.json', 'folder1/segment3.json', 'segment5.json'].sort());
|
|
61
|
+
|
|
62
|
+
// Check if old files are removed
|
|
63
|
+
const removedFiles = ['segment1.json', 'folder2/segment4.json'];
|
|
64
|
+
for (const file of removedFiles) {
|
|
65
|
+
try {
|
|
66
|
+
await fs.stat(path.join(tmpDir, file));
|
|
67
|
+
assert.fail(`${file} should have been deleted`);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
// eslint-disable-next-line no-undef
|
|
70
|
+
assert.strictEqual((error as NodeJS.ErrnoException).code, 'ENOENT');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Check if the updated index.js file is correct
|
|
75
|
+
const updatedExpectedIndexContent = `module.exports['segment2'] = require('./segment2');
|
|
76
|
+
module.exports['folder1/segment3'] = require('./folder1/segment3');
|
|
77
|
+
module.exports['segment5'] = require('./segment5');`;
|
|
78
|
+
|
|
79
|
+
const updatedIndexContent = await fs.readFile(indexPath, 'utf-8');
|
|
80
|
+
assert.strictEqual(updatedIndexContent.trim(), updatedExpectedIndexContent.trim());
|
|
81
|
+
});
|
|
82
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import assert from 'node:assert';
|
|
2
|
+
import test, { describe } from 'node:test';
|
|
3
|
+
import locateSegments from '../src/locateSegments';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
|
|
6
|
+
void describe('Bug-sensitive utils', async () => {
|
|
7
|
+
await test('locateSegment', async () => {
|
|
8
|
+
const rootDirectory = path.join(__dirname, 'data/segments');
|
|
9
|
+
const results = await locateSegments(rootDirectory);
|
|
10
|
+
|
|
11
|
+
const expectedResults = [
|
|
12
|
+
{
|
|
13
|
+
routeFilePath: path.join(__dirname, 'data/segments/[[...vovk]]/route.ts'),
|
|
14
|
+
segmentName: '',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
routeFilePath: path.join(__dirname, 'data/segments/bar/[[...custom]]/route.ts'),
|
|
18
|
+
segmentName: 'bar',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
routeFilePath: path.join(__dirname, 'data/segments/foo/[[...vovk]]/route.ts'),
|
|
22
|
+
segmentName: 'foo',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
routeFilePath: path.join(__dirname, 'data/segments/quux/corge/[[...vovk]]/route.ts'),
|
|
26
|
+
segmentName: 'quux/corge',
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
assert.strictEqual(
|
|
31
|
+
results.length,
|
|
32
|
+
expectedResults.length,
|
|
33
|
+
'The number of located segments should match the expected count.'
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
for (let i = 0; i < results.length; i++) {
|
|
37
|
+
assert.strictEqual(
|
|
38
|
+
results[i].routeFilePath,
|
|
39
|
+
expectedResults[i].routeFilePath,
|
|
40
|
+
`The routeFilePath at index ${i} should match.`
|
|
41
|
+
);
|
|
42
|
+
assert.strictEqual(
|
|
43
|
+
results[i].segmentName,
|
|
44
|
+
expectedResults[i].segmentName,
|
|
45
|
+
`The segmentName at index ${i} should match.`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
package/tsconfig.json
ADDED