@webstir-io/webstir-backend 0.1.15 → 0.1.16
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/README.md +106 -79
- package/dist/add.d.ts +59 -0
- package/dist/add.js +626 -0
- package/dist/build/artifacts.d.ts +115 -1
- package/dist/build/artifacts.js +4 -4
- package/dist/build/entries.js +1 -1
- package/dist/build/pipeline.d.ts +33 -1
- package/dist/build/pipeline.js +307 -65
- package/dist/cache/diff.js +9 -8
- package/dist/cache/reporters.js +1 -1
- package/dist/deploy-cli.d.ts +2 -0
- package/dist/deploy-cli.js +86 -0
- package/dist/diagnostics/summary.js +2 -2
- package/dist/index.d.ts +6 -0
- package/dist/index.js +4 -0
- package/dist/manifest/pipeline.js +103 -32
- package/dist/provider.js +35 -17
- package/dist/runtime/bun.d.ts +51 -0
- package/dist/runtime/bun.js +499 -0
- package/dist/runtime/core.d.ts +141 -0
- package/dist/runtime/core.js +316 -0
- package/dist/runtime/deploy-backend.d.ts +20 -0
- package/dist/runtime/deploy-backend.js +175 -0
- package/dist/runtime/deploy-shared.d.ts +43 -0
- package/dist/runtime/deploy-shared.js +75 -0
- package/dist/runtime/deploy-static.d.ts +2 -0
- package/dist/runtime/deploy-static.js +161 -0
- package/dist/runtime/deploy.d.ts +3 -0
- package/dist/runtime/deploy.js +91 -0
- package/dist/runtime/forms.d.ts +73 -0
- package/dist/runtime/forms.js +236 -0
- package/dist/runtime/request-hooks.d.ts +47 -0
- package/dist/runtime/request-hooks.js +102 -0
- package/dist/runtime/session-metadata.d.ts +13 -0
- package/dist/runtime/session-metadata.js +98 -0
- package/dist/runtime/session-runtime.d.ts +28 -0
- package/dist/runtime/session-runtime.js +180 -0
- package/dist/runtime/session.d.ts +83 -0
- package/dist/runtime/session.js +396 -0
- package/dist/runtime/views.d.ts +74 -0
- package/dist/runtime/views.js +221 -0
- package/dist/scaffold/assets.js +25 -21
- package/dist/testing/context.js +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +100 -56
- package/dist/utils/bun.d.ts +2 -0
- package/dist/utils/bun.js +13 -0
- package/dist/watch.d.ts +13 -1
- package/dist/watch.js +345 -97
- package/dist/workspace.d.ts +8 -0
- package/dist/workspace.js +44 -3
- package/package.json +49 -14
- package/scripts/publish.sh +2 -92
- package/scripts/smoke.mjs +282 -107
- package/scripts/update-contract.sh +12 -10
- package/src/add.ts +964 -0
- package/src/build/artifacts.ts +49 -46
- package/src/build/entries.ts +12 -12
- package/src/build/pipeline.ts +779 -403
- package/src/cache/diff.ts +111 -105
- package/src/cache/reporters.ts +26 -26
- package/src/deploy-cli.ts +111 -0
- package/src/diagnostics/summary.ts +28 -22
- package/src/index.ts +11 -0
- package/src/manifest/pipeline.ts +328 -215
- package/src/provider.ts +115 -98
- package/src/runtime/bun.ts +793 -0
- package/src/runtime/core.ts +598 -0
- package/src/runtime/deploy-backend.ts +239 -0
- package/src/runtime/deploy-shared.ts +136 -0
- package/src/runtime/deploy-static.ts +191 -0
- package/src/runtime/deploy.ts +143 -0
- package/src/runtime/forms.ts +364 -0
- package/src/runtime/request-hooks.ts +165 -0
- package/src/runtime/session-metadata.ts +135 -0
- package/src/runtime/session-runtime.ts +267 -0
- package/src/runtime/session.ts +642 -0
- package/src/runtime/views.ts +385 -0
- package/src/scaffold/assets.ts +77 -73
- package/src/testing/context.js +8 -9
- package/src/testing/context.ts +9 -9
- package/src/testing/index.d.ts +14 -3
- package/src/testing/index.js +254 -175
- package/src/testing/index.ts +298 -195
- package/src/testing/types.d.ts +18 -19
- package/src/testing/types.ts +18 -18
- package/src/utils/bun.ts +26 -0
- package/src/watch.ts +503 -99
- package/src/workspace.ts +59 -3
- package/templates/backend/.env.example +15 -0
- package/templates/backend/auth/adapter.ts +335 -36
- package/templates/backend/db/connection.ts +190 -65
- package/templates/backend/db/migrate.ts +149 -43
- package/templates/backend/db/types.d.ts +1 -1
- package/templates/backend/env.ts +132 -20
- package/templates/backend/functions/hello/index.ts +1 -2
- package/templates/backend/index.ts +15 -508
- package/templates/backend/jobs/nightly/index.ts +1 -1
- package/templates/backend/jobs/runtime.ts +24 -11
- package/templates/backend/jobs/scheduler.ts +208 -46
- package/templates/backend/module.ts +227 -13
- package/templates/backend/observability/logger.ts +2 -12
- package/templates/backend/observability/metrics.ts +8 -5
- package/templates/backend/session/sqlite.ts +152 -0
- package/templates/backend/session/store.ts +45 -0
- package/templates/backend/tsconfig.json +1 -1
- package/tests/add.test.js +327 -0
- package/tests/authAdapter.test.js +315 -0
- package/tests/bundlerParity.test.js +217 -0
- package/tests/cacheReporter.test.js +10 -10
- package/tests/dbConnection.test.js +209 -0
- package/tests/deploy.test.js +357 -0
- package/tests/envLoader.test.js +271 -17
- package/tests/integration.test.js +2432 -3
- package/tests/jobsScheduler.test.js +253 -0
- package/tests/manifest.test.js +287 -12
- package/tests/migrationRunner.test.js +249 -0
- package/tests/sessionScaffoldStore.test.js +752 -0
- package/tests/sessionStore.test.js +490 -0
- package/tests/testing.test.js +252 -0
- package/tests/watch.test.js +192 -32
- package/tsconfig.json +3 -10
- package/templates/backend/server/fastify.ts +0 -288
package/tests/envLoader.test.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { test } from 'node:test';
|
|
2
2
|
import assert from 'node:assert/strict';
|
|
3
|
+
import crypto from 'node:crypto';
|
|
3
4
|
import fs from 'node:fs/promises';
|
|
4
5
|
import os from 'node:os';
|
|
5
6
|
import path from 'node:path';
|
|
@@ -17,31 +18,50 @@ async function copyFile(src, dest) {
|
|
|
17
18
|
await fs.copyFile(src, dest);
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
function
|
|
21
|
-
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
22
|
-
const pkgRoot = path.resolve(here, '..');
|
|
23
|
-
return path.join(pkgRoot, 'node_modules', '.bin');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
test('env loader reads .env files and surfaces typed config', async () => {
|
|
27
|
-
const workspace = await createTempWorkspace();
|
|
21
|
+
async function seedBackendWorkspace(workspace, name) {
|
|
28
22
|
const assets = await backendProvider.getScaffoldAssets();
|
|
29
23
|
for (const asset of assets) {
|
|
30
24
|
await copyFile(asset.sourcePath, path.join(workspace, asset.targetPath));
|
|
31
25
|
}
|
|
26
|
+
|
|
32
27
|
await fs.writeFile(
|
|
33
28
|
path.join(workspace, 'package.json'),
|
|
34
29
|
JSON.stringify(
|
|
35
30
|
{
|
|
36
|
-
name
|
|
31
|
+
name,
|
|
37
32
|
version: '0.0.0',
|
|
38
|
-
type: 'module'
|
|
33
|
+
type: 'module',
|
|
39
34
|
},
|
|
40
35
|
null,
|
|
41
|
-
2
|
|
36
|
+
2,
|
|
42
37
|
),
|
|
43
|
-
'utf8'
|
|
38
|
+
'utf8',
|
|
44
39
|
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getLocalBinPath() {
|
|
43
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
44
|
+
const pkgRoot = path.resolve(here, '..');
|
|
45
|
+
return path.join(pkgRoot, 'node_modules', '.bin');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function snapshotEnv(keys) {
|
|
49
|
+
return Object.fromEntries(keys.map((key) => [key, process.env[key]]));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function restoreEnv(snapshot) {
|
|
53
|
+
for (const [key, value] of Object.entries(snapshot)) {
|
|
54
|
+
if (value === undefined) {
|
|
55
|
+
delete process.env[key];
|
|
56
|
+
} else {
|
|
57
|
+
process.env[key] = value;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
test('env loader reads .env files and surfaces typed config', async () => {
|
|
63
|
+
const workspace = await createTempWorkspace();
|
|
64
|
+
await seedBackendWorkspace(workspace, '@demo/env-loader');
|
|
45
65
|
|
|
46
66
|
const envContents = `NODE_ENV=development\nPORT=5055\nAPI_BASE_URL=https://api.example.com\n`;
|
|
47
67
|
await fs.writeFile(path.join(workspace, '.env'), envContents, 'utf8');
|
|
@@ -50,15 +70,249 @@ test('env loader reads .env files and surfaces typed config', async () => {
|
|
|
50
70
|
WEBSTIR_MODULE_MODE: 'build',
|
|
51
71
|
WEBSTIR_BACKEND_TYPECHECK: 'skip',
|
|
52
72
|
NODE_OPTIONS: '--experimental-transform-types',
|
|
53
|
-
PATH: `${getLocalBinPath()}${path.delimiter}${process.env.PATH ?? ''}
|
|
73
|
+
PATH: `${getLocalBinPath()}${path.delimiter}${process.env.PATH ?? ''}`,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
await backendProvider.build({ workspaceRoot: workspace, env, incremental: false });
|
|
77
|
+
|
|
78
|
+
const builtEnvModule = path.join(workspace, 'build', 'backend', 'env.js');
|
|
79
|
+
const previousEnv = snapshotEnv(['NODE_ENV', 'PORT', 'API_BASE_URL']);
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
delete process.env.NODE_ENV;
|
|
83
|
+
delete process.env.PORT;
|
|
84
|
+
delete process.env.API_BASE_URL;
|
|
85
|
+
|
|
86
|
+
const mod = await import(pathToFileURL(builtEnvModule).href);
|
|
87
|
+
const loaded = mod.loadEnv();
|
|
88
|
+
|
|
89
|
+
assert.equal(loaded.PORT, 5055);
|
|
90
|
+
assert.equal(loaded.API_BASE_URL, 'https://api.example.com');
|
|
91
|
+
} finally {
|
|
92
|
+
restoreEnv(previousEnv);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('env loader generates a non-literal session secret fallback when unset', async () => {
|
|
97
|
+
const workspace = await createTempWorkspace('webstir-backend-env-session-');
|
|
98
|
+
await seedBackendWorkspace(workspace, '@demo/env-loader-session');
|
|
99
|
+
|
|
100
|
+
const env = {
|
|
101
|
+
WEBSTIR_MODULE_MODE: 'build',
|
|
102
|
+
WEBSTIR_BACKEND_TYPECHECK: 'skip',
|
|
103
|
+
NODE_OPTIONS: '--experimental-transform-types',
|
|
104
|
+
PATH: `${getLocalBinPath()}${path.delimiter}${process.env.PATH ?? ''}`,
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const previousSessionSecret = process.env.SESSION_SECRET;
|
|
108
|
+
const previousJwtSecret = process.env.AUTH_JWT_SECRET;
|
|
109
|
+
const previousNodeEnv = process.env.NODE_ENV;
|
|
110
|
+
const previousPort = process.env.PORT;
|
|
111
|
+
const previousApiBaseUrl = process.env.API_BASE_URL;
|
|
112
|
+
delete process.env.SESSION_SECRET;
|
|
113
|
+
delete process.env.AUTH_JWT_SECRET;
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
await backendProvider.build({ workspaceRoot: workspace, env, incremental: false });
|
|
117
|
+
|
|
118
|
+
const builtEnvModule = path.join(workspace, 'build', 'backend', 'env.js');
|
|
119
|
+
const mod = await import(pathToFileURL(builtEnvModule).href);
|
|
120
|
+
const first = mod.loadEnv();
|
|
121
|
+
const second = mod.loadEnv();
|
|
122
|
+
|
|
123
|
+
assert.notEqual(first.sessions.secret, 'webstir-dev-session-secret');
|
|
124
|
+
assert.equal(first.sessions.secret, second.sessions.secret);
|
|
125
|
+
assert.ok(first.sessions.secret.length >= 32);
|
|
126
|
+
} finally {
|
|
127
|
+
if (previousSessionSecret === undefined) {
|
|
128
|
+
delete process.env.SESSION_SECRET;
|
|
129
|
+
} else {
|
|
130
|
+
process.env.SESSION_SECRET = previousSessionSecret;
|
|
131
|
+
}
|
|
132
|
+
if (previousJwtSecret === undefined) {
|
|
133
|
+
delete process.env.AUTH_JWT_SECRET;
|
|
134
|
+
} else {
|
|
135
|
+
process.env.AUTH_JWT_SECRET = previousJwtSecret;
|
|
136
|
+
}
|
|
137
|
+
if (previousNodeEnv === undefined) {
|
|
138
|
+
delete process.env.NODE_ENV;
|
|
139
|
+
} else {
|
|
140
|
+
process.env.NODE_ENV = previousNodeEnv;
|
|
141
|
+
}
|
|
142
|
+
if (previousPort === undefined) {
|
|
143
|
+
delete process.env.PORT;
|
|
144
|
+
} else {
|
|
145
|
+
process.env.PORT = previousPort;
|
|
146
|
+
}
|
|
147
|
+
if (previousApiBaseUrl === undefined) {
|
|
148
|
+
delete process.env.API_BASE_URL;
|
|
149
|
+
} else {
|
|
150
|
+
process.env.API_BASE_URL = previousApiBaseUrl;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test('env loader requires SESSION_SECRET in production', async () => {
|
|
156
|
+
const workspace = await createTempWorkspace('webstir-backend-env-session-prod-');
|
|
157
|
+
await seedBackendWorkspace(workspace, '@demo/env-loader-session-prod');
|
|
158
|
+
|
|
159
|
+
const env = {
|
|
160
|
+
WEBSTIR_MODULE_MODE: 'build',
|
|
161
|
+
WEBSTIR_BACKEND_TYPECHECK: 'skip',
|
|
162
|
+
NODE_OPTIONS: '--experimental-transform-types',
|
|
163
|
+
PATH: `${getLocalBinPath()}${path.delimiter}${process.env.PATH ?? ''}`,
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
const previousEnv = snapshotEnv(['NODE_ENV', 'SESSION_SECRET', 'AUTH_JWT_SECRET']);
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
await backendProvider.build({ workspaceRoot: workspace, env, incremental: false });
|
|
170
|
+
|
|
171
|
+
const builtEnvModule = path.join(workspace, 'build', 'backend', 'env.js');
|
|
172
|
+
process.env.NODE_ENV = 'production';
|
|
173
|
+
delete process.env.SESSION_SECRET;
|
|
174
|
+
delete process.env.AUTH_JWT_SECRET;
|
|
175
|
+
|
|
176
|
+
const mod = await import(pathToFileURL(builtEnvModule).href);
|
|
177
|
+
assert.throws(() => mod.loadEnv(), /SESSION_SECRET is required when NODE_ENV=production/);
|
|
178
|
+
} finally {
|
|
179
|
+
restoreEnv(previousEnv);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test('env loader falls back from blank WORKSPACE_ROOT to WEBSTIR_WORKSPACE_ROOT outside the workspace cwd', async () => {
|
|
184
|
+
const workspace = await createTempWorkspace('webstir-backend-env-root-');
|
|
185
|
+
const alternateCwd = await createTempWorkspace('webstir-backend-env-root-cwd-');
|
|
186
|
+
await seedBackendWorkspace(workspace, '@demo/env-loader-root');
|
|
187
|
+
await fs.writeFile(
|
|
188
|
+
path.join(workspace, '.env'),
|
|
189
|
+
'PORT=6060\nAPI_BASE_URL=https://root.example.com\n',
|
|
190
|
+
'utf8',
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
const env = {
|
|
194
|
+
WEBSTIR_MODULE_MODE: 'build',
|
|
195
|
+
WEBSTIR_BACKEND_TYPECHECK: 'skip',
|
|
196
|
+
NODE_OPTIONS: '--experimental-transform-types',
|
|
197
|
+
PATH: `${getLocalBinPath()}${path.delimiter}${process.env.PATH ?? ''}`,
|
|
54
198
|
};
|
|
55
199
|
|
|
56
200
|
await backendProvider.build({ workspaceRoot: workspace, env, incremental: false });
|
|
57
201
|
|
|
58
202
|
const builtEnvModule = path.join(workspace, 'build', 'backend', 'env.js');
|
|
59
|
-
const
|
|
60
|
-
|
|
203
|
+
const previousEnv = snapshotEnv([
|
|
204
|
+
'WORKSPACE_ROOT',
|
|
205
|
+
'WEBSTIR_WORKSPACE_ROOT',
|
|
206
|
+
'PORT',
|
|
207
|
+
'API_BASE_URL',
|
|
208
|
+
]);
|
|
209
|
+
const previousCwd = process.cwd();
|
|
210
|
+
|
|
211
|
+
try {
|
|
212
|
+
process.env.WORKSPACE_ROOT = ' ';
|
|
213
|
+
process.env.WEBSTIR_WORKSPACE_ROOT = workspace;
|
|
214
|
+
delete process.env.PORT;
|
|
215
|
+
delete process.env.API_BASE_URL;
|
|
216
|
+
process.chdir(alternateCwd);
|
|
61
217
|
|
|
62
|
-
|
|
63
|
-
|
|
218
|
+
const mod = await import(pathToFileURL(builtEnvModule).href);
|
|
219
|
+
const loaded = mod.loadEnv();
|
|
220
|
+
|
|
221
|
+
assert.equal(loaded.PORT, 6060);
|
|
222
|
+
assert.equal(loaded.API_BASE_URL, 'https://root.example.com');
|
|
223
|
+
} finally {
|
|
224
|
+
process.chdir(previousCwd);
|
|
225
|
+
restoreEnv(previousEnv);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
test('env loader infers workspace root from the built module path outside the workspace cwd', async () => {
|
|
230
|
+
const workspace = await createTempWorkspace('webstir-backend-env-infer-');
|
|
231
|
+
const alternateCwd = await createTempWorkspace('webstir-backend-env-infer-cwd-');
|
|
232
|
+
await seedBackendWorkspace(workspace, '@demo/env-loader-infer');
|
|
233
|
+
await fs.writeFile(
|
|
234
|
+
path.join(workspace, '.env'),
|
|
235
|
+
'PORT=7070\nAPI_BASE_URL=https://infer.example.com\n',
|
|
236
|
+
'utf8',
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
const env = {
|
|
240
|
+
WEBSTIR_MODULE_MODE: 'build',
|
|
241
|
+
WEBSTIR_BACKEND_TYPECHECK: 'skip',
|
|
242
|
+
NODE_OPTIONS: '--experimental-transform-types',
|
|
243
|
+
PATH: `${getLocalBinPath()}${path.delimiter}${process.env.PATH ?? ''}`,
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
await backendProvider.build({ workspaceRoot: workspace, env, incremental: false });
|
|
247
|
+
|
|
248
|
+
const builtEnvModule = path.join(workspace, 'build', 'backend', 'env.js');
|
|
249
|
+
const previousEnv = snapshotEnv([
|
|
250
|
+
'WORKSPACE_ROOT',
|
|
251
|
+
'WEBSTIR_WORKSPACE_ROOT',
|
|
252
|
+
'PORT',
|
|
253
|
+
'API_BASE_URL',
|
|
254
|
+
]);
|
|
255
|
+
const previousCwd = process.cwd();
|
|
256
|
+
|
|
257
|
+
try {
|
|
258
|
+
delete process.env.WORKSPACE_ROOT;
|
|
259
|
+
delete process.env.WEBSTIR_WORKSPACE_ROOT;
|
|
260
|
+
delete process.env.PORT;
|
|
261
|
+
delete process.env.API_BASE_URL;
|
|
262
|
+
process.chdir(alternateCwd);
|
|
263
|
+
|
|
264
|
+
const mod = await import(pathToFileURL(builtEnvModule).href);
|
|
265
|
+
const loaded = mod.loadEnv();
|
|
266
|
+
|
|
267
|
+
assert.equal(loaded.PORT, 7070);
|
|
268
|
+
assert.equal(loaded.API_BASE_URL, 'https://infer.example.com');
|
|
269
|
+
} finally {
|
|
270
|
+
process.chdir(previousCwd);
|
|
271
|
+
restoreEnv(previousEnv);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test('env loader resolves AUTH_JWT_PUBLIC_KEY_FILE from the workspace root', async () => {
|
|
276
|
+
const workspace = await createTempWorkspace('webstir-backend-env-auth-key-');
|
|
277
|
+
const alternateCwd = await createTempWorkspace('webstir-backend-env-auth-key-cwd-');
|
|
278
|
+
await seedBackendWorkspace(workspace, '@demo/env-loader-auth-key');
|
|
279
|
+
|
|
280
|
+
const { publicKey } = crypto.generateKeyPairSync('rsa', { modulusLength: 2048 });
|
|
281
|
+
const publicKeyPem = publicKey.export({ type: 'spki', format: 'pem' }).toString();
|
|
282
|
+
await fs.mkdir(path.join(workspace, 'config'), { recursive: true });
|
|
283
|
+
await fs.writeFile(path.join(workspace, 'config', 'jwt-public.pem'), publicKeyPem, 'utf8');
|
|
284
|
+
|
|
285
|
+
const env = {
|
|
286
|
+
WEBSTIR_MODULE_MODE: 'build',
|
|
287
|
+
WEBSTIR_BACKEND_TYPECHECK: 'skip',
|
|
288
|
+
NODE_OPTIONS: '--experimental-transform-types',
|
|
289
|
+
PATH: `${getLocalBinPath()}${path.delimiter}${process.env.PATH ?? ''}`,
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
await backendProvider.build({ workspaceRoot: workspace, env, incremental: false });
|
|
293
|
+
|
|
294
|
+
const builtEnvModule = path.join(workspace, 'build', 'backend', 'env.js');
|
|
295
|
+
const previousEnv = snapshotEnv([
|
|
296
|
+
'WORKSPACE_ROOT',
|
|
297
|
+
'WEBSTIR_WORKSPACE_ROOT',
|
|
298
|
+
'AUTH_JWT_PUBLIC_KEY',
|
|
299
|
+
'AUTH_JWT_PUBLIC_KEY_FILE',
|
|
300
|
+
]);
|
|
301
|
+
const previousCwd = process.cwd();
|
|
302
|
+
|
|
303
|
+
try {
|
|
304
|
+
process.env.WORKSPACE_ROOT = ' ';
|
|
305
|
+
process.env.WEBSTIR_WORKSPACE_ROOT = workspace;
|
|
306
|
+
delete process.env.AUTH_JWT_PUBLIC_KEY;
|
|
307
|
+
process.env.AUTH_JWT_PUBLIC_KEY_FILE = 'config/jwt-public.pem';
|
|
308
|
+
process.chdir(alternateCwd);
|
|
309
|
+
|
|
310
|
+
const mod = await import(pathToFileURL(builtEnvModule).href);
|
|
311
|
+
const loaded = mod.loadEnv();
|
|
312
|
+
|
|
313
|
+
assert.match(loaded.auth.jwtPublicKey ?? '', /BEGIN PUBLIC KEY/);
|
|
314
|
+
} finally {
|
|
315
|
+
process.chdir(previousCwd);
|
|
316
|
+
restoreEnv(previousEnv);
|
|
317
|
+
}
|
|
64
318
|
});
|