@nitwel/sandbox 1.0.6 → 1.0.8
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/dist/cli.js +1 -0
- package/dist/config.d.ts +7 -7
- package/dist/config.js +1 -2
- package/dist/sandbox.d.ts +3 -0
- package/dist/sandbox.js +17 -10
- package/dist/steps/api.d.ts +2 -2
- package/dist/steps/api.js +7 -7
- package/dist/steps/app.d.ts +3 -0
- package/dist/steps/app.js +44 -0
- package/dist/steps/docker.js +2 -2
- package/dist/steps/schema.js +2 -2
- package/package.json +9 -9
package/dist/cli.js
CHANGED
|
@@ -5,6 +5,7 @@ program
|
|
|
5
5
|
.option('-b, --build', 'Rebuild directus from source')
|
|
6
6
|
.option('-d, --dev', 'Start directus in developer mode. Not compatible with build')
|
|
7
7
|
.option('-w, --watch', 'Restart the api when changes are made')
|
|
8
|
+
.option('-a, --app [port]', 'Spin up the app in dev mode')
|
|
8
9
|
.option('--inspect', 'Start the api with debugger', true)
|
|
9
10
|
.option('-p, --port <port>', 'Port to start the api on')
|
|
10
11
|
.option('-v, --version <version>', 'Which version of the database to use')
|
package/dist/config.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ declare const maildev: {
|
|
|
31
31
|
};
|
|
32
32
|
declare const baseConfig: {
|
|
33
33
|
readonly maria: {
|
|
34
|
-
readonly TZ: "
|
|
34
|
+
readonly TZ: "UTC";
|
|
35
35
|
readonly ADMIN_EMAIL: "admin@example.com";
|
|
36
36
|
readonly PROJECT_OWNER: "admin@example.com";
|
|
37
37
|
readonly ADMIN_PASSWORD: "pw";
|
|
@@ -66,7 +66,7 @@ declare const baseConfig: {
|
|
|
66
66
|
readonly DB_VERSION: "11";
|
|
67
67
|
};
|
|
68
68
|
readonly postgres: {
|
|
69
|
-
readonly TZ: "
|
|
69
|
+
readonly TZ: "UTC";
|
|
70
70
|
readonly ADMIN_EMAIL: "admin@example.com";
|
|
71
71
|
readonly PROJECT_OWNER: "admin@example.com";
|
|
72
72
|
readonly ADMIN_PASSWORD: "pw";
|
|
@@ -101,7 +101,7 @@ declare const baseConfig: {
|
|
|
101
101
|
readonly DB_VERSION: "18-3.6-alpine";
|
|
102
102
|
};
|
|
103
103
|
readonly sqlite: {
|
|
104
|
-
readonly TZ: "
|
|
104
|
+
readonly TZ: "UTC";
|
|
105
105
|
readonly ADMIN_EMAIL: "admin@example.com";
|
|
106
106
|
readonly PROJECT_OWNER: "admin@example.com";
|
|
107
107
|
readonly ADMIN_PASSWORD: "pw";
|
|
@@ -131,7 +131,7 @@ declare const baseConfig: {
|
|
|
131
131
|
readonly DB_FILENAME: "./test.db";
|
|
132
132
|
};
|
|
133
133
|
readonly cockroachdb: {
|
|
134
|
-
readonly TZ: "
|
|
134
|
+
readonly TZ: "UTC";
|
|
135
135
|
readonly ADMIN_EMAIL: "admin@example.com";
|
|
136
136
|
readonly PROJECT_OWNER: "admin@example.com";
|
|
137
137
|
readonly ADMIN_PASSWORD: "pw";
|
|
@@ -167,7 +167,7 @@ declare const baseConfig: {
|
|
|
167
167
|
readonly COCKROACH_UI: "$PORT";
|
|
168
168
|
};
|
|
169
169
|
readonly mssql: {
|
|
170
|
-
readonly TZ: "
|
|
170
|
+
readonly TZ: "UTC";
|
|
171
171
|
readonly ADMIN_EMAIL: "admin@example.com";
|
|
172
172
|
readonly PROJECT_OWNER: "admin@example.com";
|
|
173
173
|
readonly ADMIN_PASSWORD: "pw";
|
|
@@ -202,7 +202,7 @@ declare const baseConfig: {
|
|
|
202
202
|
readonly DB_VERSION: "2022-latest";
|
|
203
203
|
};
|
|
204
204
|
readonly mysql: {
|
|
205
|
-
readonly TZ: "
|
|
205
|
+
readonly TZ: "UTC";
|
|
206
206
|
readonly ADMIN_EMAIL: "admin@example.com";
|
|
207
207
|
readonly PROJECT_OWNER: "admin@example.com";
|
|
208
208
|
readonly ADMIN_PASSWORD: "pw";
|
|
@@ -237,7 +237,7 @@ declare const baseConfig: {
|
|
|
237
237
|
readonly DB_VERSION: "8.4";
|
|
238
238
|
};
|
|
239
239
|
readonly oracle: {
|
|
240
|
-
readonly TZ: "
|
|
240
|
+
readonly TZ: "UTC";
|
|
241
241
|
readonly ADMIN_EMAIL: "admin@example.com";
|
|
242
242
|
readonly PROJECT_OWNER: "admin@example.com";
|
|
243
243
|
readonly ADMIN_PASSWORD: "pw";
|
package/dist/config.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { join } from 'path';
|
|
2
2
|
import { directusFolder } from './find-directus.js';
|
|
3
|
-
const isWindows = ['win32', 'win64'].includes(process.platform);
|
|
4
3
|
const directusConfig = {
|
|
5
|
-
TZ:
|
|
4
|
+
TZ: 'UTC',
|
|
6
5
|
ADMIN_EMAIL: 'admin@example.com',
|
|
7
6
|
PROJECT_OWNER: 'admin@example.com',
|
|
8
7
|
ADMIN_PASSWORD: 'pw',
|
package/dist/sandbox.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export type Options = {
|
|
|
13
13
|
watch: boolean;
|
|
14
14
|
/** Port to start the api on */
|
|
15
15
|
port: Port;
|
|
16
|
+
/** Spin up the app in dev mode */
|
|
17
|
+
app: boolean | number;
|
|
16
18
|
/** Which version of the database to use */
|
|
17
19
|
version: string | undefined;
|
|
18
20
|
/** Configure the behavior of the spun up docker container */
|
|
@@ -70,6 +72,7 @@ export type Sandbox = {
|
|
|
70
72
|
logger: Logger;
|
|
71
73
|
};
|
|
72
74
|
export declare const apiFolder: string;
|
|
75
|
+
export declare const appFolder: string;
|
|
73
76
|
export declare const databases: Database[];
|
|
74
77
|
export type SandboxesOptions = {
|
|
75
78
|
database: Database;
|
package/dist/sandbox.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {} from 'child_process';
|
|
2
|
-
import { merge } from 'lodash-es';
|
|
3
2
|
import { join } from 'path';
|
|
4
|
-
import { getEnv } from './config.js';
|
|
5
|
-
import { createLogger } from './logger.js';
|
|
6
|
-
import { buildDirectus, bootstrap, dockerDown, dockerUp, loadSchema, saveSchema, startDirectus, } from './steps/index.js';
|
|
7
3
|
import chalk from 'chalk';
|
|
8
4
|
import getPort from 'get-port';
|
|
5
|
+
import { merge } from 'lodash-es';
|
|
6
|
+
import { getEnv } from './config.js';
|
|
9
7
|
import { directusFolder } from './find-directus.js';
|
|
8
|
+
import { createLogger } from './logger.js';
|
|
9
|
+
import { startApp } from './steps/app.js';
|
|
10
|
+
import { bootstrap, buildApi, dockerDown, dockerUp, loadSchema, saveSchema, startApi } from './steps/index.js';
|
|
10
11
|
async function getOptions(options) {
|
|
11
12
|
if (options?.schema === true)
|
|
12
13
|
options.schema = 'snapshot.json';
|
|
@@ -16,6 +17,7 @@ async function getOptions(options) {
|
|
|
16
17
|
dev: false,
|
|
17
18
|
watch: false,
|
|
18
19
|
port,
|
|
20
|
+
app: false,
|
|
19
21
|
version: undefined,
|
|
20
22
|
docker: {
|
|
21
23
|
keep: false,
|
|
@@ -40,6 +42,7 @@ async function getOptions(options) {
|
|
|
40
42
|
}, options);
|
|
41
43
|
}
|
|
42
44
|
export const apiFolder = join(directusFolder, 'api');
|
|
45
|
+
export const appFolder = join(directusFolder, 'app');
|
|
43
46
|
export const databases = [
|
|
44
47
|
'maria',
|
|
45
48
|
'cockroachdb',
|
|
@@ -60,7 +63,7 @@ export async function sandboxes(sandboxes, options) {
|
|
|
60
63
|
try {
|
|
61
64
|
// Rebuild directus
|
|
62
65
|
if (opts.build && !opts.dev) {
|
|
63
|
-
build = await
|
|
66
|
+
build = await buildApi(opts, logger, restartApis);
|
|
64
67
|
}
|
|
65
68
|
await Promise.all(sandboxes.map(async ({ database, options }, index) => {
|
|
66
69
|
const opts = await getOptions(options);
|
|
@@ -73,7 +76,7 @@ export async function sandboxes(sandboxes, options) {
|
|
|
73
76
|
await bootstrap(env, logger);
|
|
74
77
|
if (opts.schema)
|
|
75
78
|
await loadSchema(opts.schema, env, logger);
|
|
76
|
-
apis.push({ processes: await
|
|
79
|
+
apis.push({ processes: await startApi(opts, env, logger), index, opts, env, logger });
|
|
77
80
|
}
|
|
78
81
|
catch (e) {
|
|
79
82
|
logger.error(String(e));
|
|
@@ -87,7 +90,7 @@ export async function sandboxes(sandboxes, options) {
|
|
|
87
90
|
}
|
|
88
91
|
async function restartApis() {
|
|
89
92
|
apis.forEach((api) => api.processes.forEach((process) => process.kill()));
|
|
90
|
-
apis = await Promise.all(apis.map(async (api) => ({ ...api, processes: await
|
|
93
|
+
apis = await Promise.all(apis.map(async (api) => ({ ...api, processes: await startApi(api.opts, api.env, api.logger) })));
|
|
91
94
|
}
|
|
92
95
|
async function stop() {
|
|
93
96
|
build?.kill();
|
|
@@ -104,19 +107,22 @@ export async function sandbox(database, options) {
|
|
|
104
107
|
const env = await getEnv(database, opts);
|
|
105
108
|
const logger = opts.prefix ? createLogger(env, opts, opts.prefix) : createLogger(env, opts);
|
|
106
109
|
let apis = [];
|
|
110
|
+
let app;
|
|
107
111
|
let project;
|
|
108
112
|
let build;
|
|
109
113
|
let interval;
|
|
110
114
|
try {
|
|
111
115
|
// Rebuild directus
|
|
112
116
|
if (opts.build && !opts.dev) {
|
|
113
|
-
build = await
|
|
117
|
+
build = await buildApi(opts, logger, restartApi);
|
|
114
118
|
}
|
|
115
119
|
project = await dockerUp(database, opts, env, logger);
|
|
116
120
|
await bootstrap(env, logger);
|
|
117
121
|
if (opts.schema)
|
|
118
122
|
await loadSchema(opts.schema, env, logger);
|
|
119
|
-
apis = await
|
|
123
|
+
apis = await startApi(opts, env, logger);
|
|
124
|
+
if (opts.app !== false)
|
|
125
|
+
app = await startApp(opts, env, logger);
|
|
120
126
|
if (opts.export)
|
|
121
127
|
interval = await saveSchema(env);
|
|
122
128
|
}
|
|
@@ -127,7 +133,7 @@ export async function sandbox(database, options) {
|
|
|
127
133
|
}
|
|
128
134
|
async function restartApi() {
|
|
129
135
|
apis.forEach((api) => api.kill());
|
|
130
|
-
apis = await
|
|
136
|
+
apis = await startApi(opts, env, logger);
|
|
131
137
|
}
|
|
132
138
|
async function stop() {
|
|
133
139
|
const start = performance.now();
|
|
@@ -135,6 +141,7 @@ export async function sandbox(database, options) {
|
|
|
135
141
|
clearInterval(interval);
|
|
136
142
|
build?.kill();
|
|
137
143
|
apis.forEach((api) => api.kill());
|
|
144
|
+
app?.kill();
|
|
138
145
|
if (project && !opts.docker.keep)
|
|
139
146
|
await dockerDown(project, env, logger);
|
|
140
147
|
const time = chalk.gray(`(${Math.round(performance.now() - start)}ms)`);
|
package/dist/steps/api.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Env } from '../config.js';
|
|
2
2
|
import { type Logger } from '../logger.js';
|
|
3
3
|
import { type Options } from '../sandbox.js';
|
|
4
|
-
export declare function
|
|
4
|
+
export declare function buildApi(opts: Options, logger: Logger, onRebuild: () => void): Promise<import("child_process").ChildProcessWithoutNullStreams | undefined>;
|
|
5
5
|
export declare function bootstrap(env: Env, logger: Logger): Promise<void>;
|
|
6
|
-
export declare function
|
|
6
|
+
export declare function startApi(opts: Options, env: Env, logger: Logger): Promise<import("child_process").ChildProcessWithoutNullStreams[]>;
|
package/dist/steps/api.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
2
|
import { join } from 'path';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { detect } from 'detect-port';
|
|
3
5
|
import {} from '../config.js';
|
|
4
6
|
import {} from '../logger.js';
|
|
5
7
|
import { apiFolder } from '../sandbox.js';
|
|
6
|
-
|
|
7
|
-
import { detect } from 'detect-port';
|
|
8
|
-
export async function buildDirectus(opts, logger, onRebuild) {
|
|
8
|
+
export async function buildApi(opts, logger, onRebuild) {
|
|
9
9
|
const start = performance.now();
|
|
10
10
|
logger.info('Rebuilding Directus');
|
|
11
11
|
let timeout;
|
|
@@ -66,7 +66,7 @@ export async function bootstrap(env, logger) {
|
|
|
66
66
|
const time = chalk.gray(`(${Math.round(performance.now() - start)}ms)`);
|
|
67
67
|
logger.info(`Completed Bootstraping Database ${time}`);
|
|
68
68
|
}
|
|
69
|
-
export async function
|
|
69
|
+
export async function startApi(opts, env, logger) {
|
|
70
70
|
const apiCount = Math.max(1, Number(opts.instances));
|
|
71
71
|
const apiPorts = [...Array(apiCount).keys()].flatMap((i) => Number(env.PORT) + i * (opts.inspect ? 2 : 1));
|
|
72
72
|
const allPorts = apiPorts.flatMap((port) => (opts.inspect ? [port, port + 1] : [port]));
|
|
@@ -78,12 +78,12 @@ export async function startDirectus(opts, env, logger) {
|
|
|
78
78
|
}
|
|
79
79
|
return await Promise.all(apiPorts.map((port) => {
|
|
80
80
|
const newLogger = apiCount > 1 ? logger.addGroup(`API ${port}`) : logger;
|
|
81
|
-
return
|
|
81
|
+
return startApiInstance(opts, { ...env, PORT: String(port) }, newLogger);
|
|
82
82
|
}));
|
|
83
83
|
}
|
|
84
|
-
async function
|
|
84
|
+
async function startApiInstance(opts, env, logger) {
|
|
85
85
|
const start = performance.now();
|
|
86
|
-
logger.info('Starting
|
|
86
|
+
logger.info('Starting Server');
|
|
87
87
|
const debuggerPort = Number(env.PORT) + 1;
|
|
88
88
|
let api;
|
|
89
89
|
let timeout;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { appFolder } from '../sandbox.js';
|
|
4
|
+
export async function startApp(opts, env, logger) {
|
|
5
|
+
const start = performance.now();
|
|
6
|
+
logger.info('Starting App');
|
|
7
|
+
let timeout;
|
|
8
|
+
const port = typeof opts.app !== 'boolean' ? opts.app : 8080;
|
|
9
|
+
const app = spawn('pnpm', ['vite', '--host', '--clearScreen false', `--port ${port}`], {
|
|
10
|
+
cwd: appFolder,
|
|
11
|
+
shell: true,
|
|
12
|
+
});
|
|
13
|
+
logger.pipe(app.stdout, 'debug');
|
|
14
|
+
app.on('error', (err) => {
|
|
15
|
+
logger.error(err.toString());
|
|
16
|
+
});
|
|
17
|
+
app.on('close', (code) => {
|
|
18
|
+
if (code === null || code === 0)
|
|
19
|
+
return;
|
|
20
|
+
const error = new Error(`Api stopped with error code ${code}`);
|
|
21
|
+
clearTimeout(timeout);
|
|
22
|
+
logger.error(error.toString());
|
|
23
|
+
throw error;
|
|
24
|
+
});
|
|
25
|
+
logger.pipe(app.stderr, 'error');
|
|
26
|
+
await new Promise((resolve, reject) => {
|
|
27
|
+
app.stdout.on('data', (data) => {
|
|
28
|
+
const msg = String(data);
|
|
29
|
+
if (msg.includes(`ready in`)) {
|
|
30
|
+
resolve(undefined);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
logger.debug(msg);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
// In case the api takes too long to start
|
|
37
|
+
timeout = setTimeout(() => {
|
|
38
|
+
reject(new Error('timeout starting app'));
|
|
39
|
+
}, 60_000);
|
|
40
|
+
});
|
|
41
|
+
const time = chalk.gray(`(${Math.round(performance.now() - start)}ms)`);
|
|
42
|
+
logger.info(`App started at http://${env.HOST}:${port} ${time}`);
|
|
43
|
+
return app;
|
|
44
|
+
}
|
package/dist/steps/docker.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
2
|
import { dirname, join } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import chalk from 'chalk';
|
|
3
5
|
import {} from '../config.js';
|
|
4
6
|
import {} from '../logger.js';
|
|
5
|
-
import chalk from 'chalk';
|
|
6
|
-
import { fileURLToPath } from 'url';
|
|
7
7
|
const fileName = fileURLToPath(import.meta.url);
|
|
8
8
|
const folderName = dirname(fileName);
|
|
9
9
|
export async function dockerUp(database, opts, env, logger) {
|
package/dist/steps/schema.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
2
|
import { writeFile } from 'fs/promises';
|
|
3
|
-
import { camelCase, upperFirst } from 'lodash-es';
|
|
4
3
|
import { join, resolve } from 'path';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { camelCase, upperFirst } from 'lodash-es';
|
|
5
6
|
import {} from '../config.js';
|
|
6
7
|
import {} from '../logger.js';
|
|
7
8
|
import { getRelationInfo } from '../relation.js';
|
|
8
9
|
import { apiFolder } from '../sandbox.js';
|
|
9
|
-
import chalk from 'chalk';
|
|
10
10
|
export async function loadSchema(schema_file, env, logger) {
|
|
11
11
|
const start = performance.now();
|
|
12
12
|
logger.info('Applying Schema');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nitwel/sandbox",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Toolkit for spinning up directus test environments",
|
|
5
5
|
"homepage": "https://directus.io",
|
|
6
6
|
"exports": {
|
|
@@ -25,25 +25,25 @@
|
|
|
25
25
|
"@directus/utils": "13.0.9",
|
|
26
26
|
"@types/lodash-es": "4.17.12",
|
|
27
27
|
"@types/node": "22.13.14",
|
|
28
|
-
"chalk": "5.
|
|
29
|
-
"commander": "14.0.
|
|
28
|
+
"chalk": "5.6.2",
|
|
29
|
+
"commander": "14.0.2",
|
|
30
30
|
"copyfiles": "2.4.1",
|
|
31
31
|
"detect-port": "2.1.0",
|
|
32
32
|
"get-port": "7.1.0",
|
|
33
33
|
"lodash-es": "4.17.21",
|
|
34
|
-
"tsdown": "0.
|
|
35
|
-
"tsx": "4.20.
|
|
34
|
+
"tsdown": "0.15.11",
|
|
35
|
+
"tsx": "4.20.6",
|
|
36
36
|
"typedoc": "0.28.12",
|
|
37
37
|
"typedoc-plugin-markdown": "4.8.1",
|
|
38
|
-
"typescript": "5.
|
|
39
|
-
"@directus/types": "
|
|
38
|
+
"typescript": "5.9.3",
|
|
39
|
+
"@directus/types": "14.0.0"
|
|
40
40
|
},
|
|
41
41
|
"engines": {
|
|
42
42
|
"node": ">=12.20.0"
|
|
43
43
|
},
|
|
44
44
|
"optionalDependencies": {
|
|
45
|
-
"mysql2": "3.
|
|
46
|
-
"oracledb": "6.
|
|
45
|
+
"mysql2": "3.15.3",
|
|
46
|
+
"oracledb": "6.10.0",
|
|
47
47
|
"pg": "8.16.3",
|
|
48
48
|
"sqlite3": "5.1.7",
|
|
49
49
|
"tedious": "18.6.1"
|