@geekmidas/cli 0.10.0 → 0.13.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/README.md +525 -0
- package/dist/bundler-B1qy9b-j.cjs +112 -0
- package/dist/bundler-B1qy9b-j.cjs.map +1 -0
- package/dist/bundler-DskIqW2t.mjs +111 -0
- package/dist/bundler-DskIqW2t.mjs.map +1 -0
- package/dist/{config-C9aXOHBe.cjs → config-AmInkU7k.cjs} +8 -8
- package/dist/config-AmInkU7k.cjs.map +1 -0
- package/dist/{config-BrkUalUh.mjs → config-DYULeEv8.mjs} +3 -3
- package/dist/config-DYULeEv8.mjs.map +1 -0
- package/dist/config.cjs +1 -1
- package/dist/config.d.cts +1 -1
- package/dist/config.d.mts +1 -1
- package/dist/config.mjs +1 -1
- package/dist/encryption-C8H-38Yy.mjs +42 -0
- package/dist/encryption-C8H-38Yy.mjs.map +1 -0
- package/dist/encryption-Dyf_r1h-.cjs +44 -0
- package/dist/encryption-Dyf_r1h-.cjs.map +1 -0
- package/dist/index.cjs +2123 -179
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +2141 -192
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-CZLI4QTr.mjs → openapi-BfFlOBCG.mjs} +801 -38
- package/dist/openapi-BfFlOBCG.mjs.map +1 -0
- package/dist/{openapi-BeHLKcwP.cjs → openapi-Bt_1FDpT.cjs} +794 -31
- package/dist/openapi-Bt_1FDpT.cjs.map +1 -0
- package/dist/{openapi-react-query-o5iMi8tz.cjs → openapi-react-query-B-sNWHFU.cjs} +5 -5
- package/dist/openapi-react-query-B-sNWHFU.cjs.map +1 -0
- package/dist/{openapi-react-query-CcciaVu5.mjs → openapi-react-query-B6XTeGqS.mjs} +5 -5
- package/dist/openapi-react-query-B6XTeGqS.mjs.map +1 -0
- package/dist/openapi-react-query.cjs +1 -1
- package/dist/openapi-react-query.d.cts.map +1 -1
- package/dist/openapi-react-query.d.mts.map +1 -1
- package/dist/openapi-react-query.mjs +1 -1
- package/dist/openapi.cjs +2 -2
- package/dist/openapi.d.cts +1 -1
- package/dist/openapi.d.cts.map +1 -1
- package/dist/openapi.d.mts +1 -1
- package/dist/openapi.d.mts.map +1 -1
- package/dist/openapi.mjs +2 -2
- package/dist/storage-BOOpAF8N.cjs +5 -0
- package/dist/storage-Bj1E26lU.cjs +187 -0
- package/dist/storage-Bj1E26lU.cjs.map +1 -0
- package/dist/storage-kSxTjkNb.mjs +133 -0
- package/dist/storage-kSxTjkNb.mjs.map +1 -0
- package/dist/storage-tgZSUnKl.mjs +3 -0
- package/dist/{types-b-vwGpqc.d.cts → types-BR0M2v_c.d.mts} +100 -1
- package/dist/types-BR0M2v_c.d.mts.map +1 -0
- package/dist/{types-DXgiA1sF.d.mts → types-BhkZc-vm.d.cts} +100 -1
- package/dist/types-BhkZc-vm.d.cts.map +1 -0
- package/examples/cron-example.ts +27 -27
- package/examples/env.ts +27 -27
- package/examples/function-example.ts +31 -31
- package/examples/gkm.config.json +20 -20
- package/examples/gkm.config.ts +8 -8
- package/examples/gkm.minimal.config.json +5 -5
- package/examples/gkm.production.config.json +25 -25
- package/examples/logger.ts +2 -2
- package/package.json +6 -6
- package/src/__tests__/EndpointGenerator.hooks.spec.ts +191 -191
- package/src/__tests__/config.spec.ts +55 -55
- package/src/__tests__/loadEnvFiles.spec.ts +93 -93
- package/src/__tests__/normalizeHooksConfig.spec.ts +58 -58
- package/src/__tests__/openapi-react-query.spec.ts +497 -497
- package/src/__tests__/openapi.spec.ts +428 -428
- package/src/__tests__/test-helpers.ts +76 -76
- package/src/auth/__tests__/credentials.spec.ts +204 -0
- package/src/auth/__tests__/index.spec.ts +168 -0
- package/src/auth/credentials.ts +187 -0
- package/src/auth/index.ts +226 -0
- package/src/build/__tests__/bundler.spec.ts +444 -0
- package/src/build/__tests__/index-new.spec.ts +474 -474
- package/src/build/__tests__/manifests.spec.ts +333 -333
- package/src/build/bundler.ts +210 -0
- package/src/build/endpoint-analyzer.ts +236 -0
- package/src/build/handler-templates.ts +1253 -0
- package/src/build/index.ts +260 -179
- package/src/build/manifests.ts +52 -52
- package/src/build/providerResolver.ts +145 -145
- package/src/build/types.ts +64 -43
- package/src/config.ts +39 -39
- package/src/deploy/__tests__/docker.spec.ts +111 -0
- package/src/deploy/__tests__/dokploy.spec.ts +245 -0
- package/src/deploy/__tests__/init.spec.ts +662 -0
- package/src/deploy/docker.ts +128 -0
- package/src/deploy/dokploy.ts +204 -0
- package/src/deploy/index.ts +136 -0
- package/src/deploy/init.ts +484 -0
- package/src/deploy/types.ts +48 -0
- package/src/dev/__tests__/index.spec.ts +266 -266
- package/src/dev/index.ts +647 -601
- package/src/docker/__tests__/compose.spec.ts +531 -0
- package/src/docker/__tests__/templates.spec.ts +280 -0
- package/src/docker/compose.ts +273 -0
- package/src/docker/index.ts +230 -0
- package/src/docker/templates.ts +446 -0
- package/src/generators/CronGenerator.ts +72 -72
- package/src/generators/EndpointGenerator.ts +699 -398
- package/src/generators/FunctionGenerator.ts +84 -84
- package/src/generators/Generator.ts +72 -72
- package/src/generators/OpenApiTsGenerator.ts +577 -577
- package/src/generators/SubscriberGenerator.ts +124 -124
- package/src/generators/__tests__/CronGenerator.spec.ts +433 -433
- package/src/generators/__tests__/EndpointGenerator.spec.ts +532 -382
- package/src/generators/__tests__/FunctionGenerator.spec.ts +244 -244
- package/src/generators/__tests__/SubscriberGenerator.spec.ts +397 -382
- package/src/generators/index.ts +4 -4
- package/src/index.ts +623 -201
- package/src/init/__tests__/generators.spec.ts +334 -334
- package/src/init/__tests__/init.spec.ts +332 -332
- package/src/init/__tests__/utils.spec.ts +89 -89
- package/src/init/generators/config.ts +175 -175
- package/src/init/generators/docker.ts +41 -41
- package/src/init/generators/env.ts +72 -72
- package/src/init/generators/index.ts +1 -1
- package/src/init/generators/models.ts +64 -64
- package/src/init/generators/monorepo.ts +161 -161
- package/src/init/generators/package.ts +71 -71
- package/src/init/generators/source.ts +6 -6
- package/src/init/index.ts +203 -208
- package/src/init/templates/api.ts +115 -115
- package/src/init/templates/index.ts +75 -75
- package/src/init/templates/minimal.ts +98 -98
- package/src/init/templates/serverless.ts +89 -89
- package/src/init/templates/worker.ts +98 -98
- package/src/init/utils.ts +54 -56
- package/src/openapi-react-query.ts +194 -194
- package/src/openapi.ts +63 -63
- package/src/secrets/__tests__/encryption.spec.ts +226 -0
- package/src/secrets/__tests__/generator.spec.ts +319 -0
- package/src/secrets/__tests__/index.spec.ts +91 -0
- package/src/secrets/__tests__/storage.spec.ts +611 -0
- package/src/secrets/encryption.ts +91 -0
- package/src/secrets/generator.ts +164 -0
- package/src/secrets/index.ts +383 -0
- package/src/secrets/storage.ts +192 -0
- package/src/secrets/types.ts +53 -0
- package/src/types.ts +295 -176
- package/tsdown.config.ts +11 -8
- package/dist/config-BrkUalUh.mjs.map +0 -1
- package/dist/config-C9aXOHBe.cjs.map +0 -1
- package/dist/openapi-BeHLKcwP.cjs.map +0 -1
- package/dist/openapi-CZLI4QTr.mjs.map +0 -1
- package/dist/openapi-react-query-CcciaVu5.mjs.map +0 -1
- package/dist/openapi-react-query-o5iMi8tz.cjs.map +0 -1
- package/dist/types-DXgiA1sF.d.mts.map +0 -1
- package/dist/types-b-vwGpqc.d.cts.map +0 -1
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import type { Construct } from '@geekmidas/constructs';
|
|
4
|
+
import { itWithDir } from '@geekmidas/testkit/os';
|
|
5
|
+
import { beforeEach, describe, expect, vi } from 'vitest';
|
|
6
|
+
import type { StageSecrets } from '../../secrets/types';
|
|
7
|
+
import { bundleServer } from '../bundler';
|
|
8
|
+
|
|
9
|
+
// Mock child_process to avoid actually running tsdown
|
|
10
|
+
vi.mock('node:child_process', () => ({
|
|
11
|
+
execSync: vi.fn(),
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
// Mock construct that returns specific environment variables
|
|
15
|
+
function createMockConstruct(envVars: string[]): Construct {
|
|
16
|
+
return {
|
|
17
|
+
getEnvironment: vi.fn().mockResolvedValue(envVars),
|
|
18
|
+
} as unknown as Construct;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Helper to create a minimal secrets file
|
|
22
|
+
async function createSecretsFile(
|
|
23
|
+
dir: string,
|
|
24
|
+
stage: string,
|
|
25
|
+
secrets: Partial<StageSecrets>,
|
|
26
|
+
): Promise<void> {
|
|
27
|
+
const secretsDir = join(dir, '.gkm', 'secrets');
|
|
28
|
+
await mkdir(secretsDir, { recursive: true });
|
|
29
|
+
|
|
30
|
+
const fullSecrets: StageSecrets = {
|
|
31
|
+
stage,
|
|
32
|
+
createdAt: new Date().toISOString(),
|
|
33
|
+
updatedAt: new Date().toISOString(),
|
|
34
|
+
services: {},
|
|
35
|
+
urls: {},
|
|
36
|
+
custom: {},
|
|
37
|
+
...secrets,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
await writeFile(
|
|
41
|
+
join(secretsDir, `${stage}.json`),
|
|
42
|
+
JSON.stringify(fullSecrets, null, 2),
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Helper to create a minimal entry point file and mock the bundle output
|
|
47
|
+
async function createEntryPoint(dir: string): Promise<string> {
|
|
48
|
+
const outputDir = join(dir, '.gkm', 'server');
|
|
49
|
+
const distDir = join(outputDir, 'dist');
|
|
50
|
+
await mkdir(outputDir, { recursive: true });
|
|
51
|
+
await mkdir(distDir, { recursive: true });
|
|
52
|
+
|
|
53
|
+
const entryPoint = join(outputDir, 'server.ts');
|
|
54
|
+
await writeFile(entryPoint, 'console.log("hello");');
|
|
55
|
+
|
|
56
|
+
// Create the output file that tsdown would normally create
|
|
57
|
+
// (since we're mocking execSync, the file won't be created automatically)
|
|
58
|
+
await writeFile(join(distDir, 'server.js'), 'console.log("bundled");');
|
|
59
|
+
|
|
60
|
+
return entryPoint;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
describe('bundleServer environment validation', () => {
|
|
64
|
+
beforeEach(() => {
|
|
65
|
+
vi.clearAllMocks();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
itWithDir(
|
|
69
|
+
'should pass validation when all required env vars are present',
|
|
70
|
+
async ({ dir }) => {
|
|
71
|
+
const entryPoint = await createEntryPoint(dir);
|
|
72
|
+
await createSecretsFile(dir, 'production', {
|
|
73
|
+
urls: { DATABASE_URL: 'postgresql://localhost/db' },
|
|
74
|
+
custom: { API_KEY: 'sk_test_123' },
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const constructs = [
|
|
78
|
+
createMockConstruct(['DATABASE_URL']),
|
|
79
|
+
createMockConstruct(['API_KEY']),
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
const originalCwd = process.cwd();
|
|
83
|
+
process.chdir(dir);
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
// Should not throw
|
|
87
|
+
const result = await bundleServer({
|
|
88
|
+
entryPoint,
|
|
89
|
+
outputDir: join(dir, '.gkm', 'server', 'dist'),
|
|
90
|
+
minify: false,
|
|
91
|
+
sourcemap: false,
|
|
92
|
+
external: [],
|
|
93
|
+
stage: 'production',
|
|
94
|
+
constructs,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
expect(result.masterKey).toBeDefined();
|
|
98
|
+
expect(constructs[0].getEnvironment).toHaveBeenCalled();
|
|
99
|
+
expect(constructs[1].getEnvironment).toHaveBeenCalled();
|
|
100
|
+
} finally {
|
|
101
|
+
process.chdir(originalCwd);
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
itWithDir(
|
|
107
|
+
'should throw error when required env vars are missing',
|
|
108
|
+
async ({ dir }) => {
|
|
109
|
+
const entryPoint = await createEntryPoint(dir);
|
|
110
|
+
await createSecretsFile(dir, 'production', {
|
|
111
|
+
urls: { DATABASE_URL: 'postgresql://localhost/db' },
|
|
112
|
+
custom: {},
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const constructs = [
|
|
116
|
+
createMockConstruct(['DATABASE_URL', 'API_KEY', 'JWT_SECRET']),
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
const originalCwd = process.cwd();
|
|
120
|
+
process.chdir(dir);
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
await expect(
|
|
124
|
+
bundleServer({
|
|
125
|
+
entryPoint,
|
|
126
|
+
outputDir: join(dir, '.gkm', 'server', 'dist'),
|
|
127
|
+
minify: false,
|
|
128
|
+
sourcemap: false,
|
|
129
|
+
external: [],
|
|
130
|
+
stage: 'production',
|
|
131
|
+
constructs,
|
|
132
|
+
}),
|
|
133
|
+
).rejects.toThrow('Missing environment variables');
|
|
134
|
+
} finally {
|
|
135
|
+
process.chdir(originalCwd);
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
itWithDir(
|
|
141
|
+
'should include missing variables in error message',
|
|
142
|
+
async ({ dir }) => {
|
|
143
|
+
const entryPoint = await createEntryPoint(dir);
|
|
144
|
+
await createSecretsFile(dir, 'staging', {
|
|
145
|
+
custom: { EXISTING_VAR: 'value' },
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const constructs = [
|
|
149
|
+
createMockConstruct(['EXISTING_VAR', 'MISSING_VAR_1', 'MISSING_VAR_2']),
|
|
150
|
+
];
|
|
151
|
+
|
|
152
|
+
const originalCwd = process.cwd();
|
|
153
|
+
process.chdir(dir);
|
|
154
|
+
|
|
155
|
+
try {
|
|
156
|
+
await expect(
|
|
157
|
+
bundleServer({
|
|
158
|
+
entryPoint,
|
|
159
|
+
outputDir: join(dir, '.gkm', 'server', 'dist'),
|
|
160
|
+
minify: false,
|
|
161
|
+
sourcemap: false,
|
|
162
|
+
external: [],
|
|
163
|
+
stage: 'staging',
|
|
164
|
+
constructs,
|
|
165
|
+
}),
|
|
166
|
+
).rejects.toThrow(/MISSING_VAR_1/);
|
|
167
|
+
|
|
168
|
+
await expect(
|
|
169
|
+
bundleServer({
|
|
170
|
+
entryPoint,
|
|
171
|
+
outputDir: join(dir, '.gkm', 'server', 'dist'),
|
|
172
|
+
minify: false,
|
|
173
|
+
sourcemap: false,
|
|
174
|
+
external: [],
|
|
175
|
+
stage: 'staging',
|
|
176
|
+
constructs,
|
|
177
|
+
}),
|
|
178
|
+
).rejects.toThrow(/MISSING_VAR_2/);
|
|
179
|
+
} finally {
|
|
180
|
+
process.chdir(originalCwd);
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
itWithDir(
|
|
186
|
+
'should collect env vars from multiple constructs',
|
|
187
|
+
async ({ dir }) => {
|
|
188
|
+
const entryPoint = await createEntryPoint(dir);
|
|
189
|
+
await createSecretsFile(dir, 'production', {
|
|
190
|
+
urls: { DATABASE_URL: 'postgresql://localhost/db' },
|
|
191
|
+
custom: {
|
|
192
|
+
API_KEY: 'key',
|
|
193
|
+
REDIS_URL: 'redis://localhost',
|
|
194
|
+
JWT_SECRET: 'secret',
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
const constructs = [
|
|
199
|
+
createMockConstruct(['DATABASE_URL']),
|
|
200
|
+
createMockConstruct(['API_KEY', 'REDIS_URL']),
|
|
201
|
+
createMockConstruct(['JWT_SECRET']),
|
|
202
|
+
];
|
|
203
|
+
|
|
204
|
+
const originalCwd = process.cwd();
|
|
205
|
+
process.chdir(dir);
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
const result = await bundleServer({
|
|
209
|
+
entryPoint,
|
|
210
|
+
outputDir: join(dir, '.gkm', 'server', 'dist'),
|
|
211
|
+
minify: false,
|
|
212
|
+
sourcemap: false,
|
|
213
|
+
external: [],
|
|
214
|
+
stage: 'production',
|
|
215
|
+
constructs,
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
expect(result.masterKey).toBeDefined();
|
|
219
|
+
|
|
220
|
+
// All constructs should have been checked
|
|
221
|
+
for (const construct of constructs) {
|
|
222
|
+
expect(construct.getEnvironment).toHaveBeenCalled();
|
|
223
|
+
}
|
|
224
|
+
} finally {
|
|
225
|
+
process.chdir(originalCwd);
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
itWithDir(
|
|
231
|
+
'should deduplicate env vars from multiple constructs',
|
|
232
|
+
async ({ dir }) => {
|
|
233
|
+
const entryPoint = await createEntryPoint(dir);
|
|
234
|
+
await createSecretsFile(dir, 'production', {
|
|
235
|
+
custom: { SHARED_VAR: 'value' },
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// Multiple constructs requiring the same variable
|
|
239
|
+
const constructs = [
|
|
240
|
+
createMockConstruct(['SHARED_VAR']),
|
|
241
|
+
createMockConstruct(['SHARED_VAR']),
|
|
242
|
+
createMockConstruct(['SHARED_VAR']),
|
|
243
|
+
];
|
|
244
|
+
|
|
245
|
+
const originalCwd = process.cwd();
|
|
246
|
+
process.chdir(dir);
|
|
247
|
+
|
|
248
|
+
try {
|
|
249
|
+
// Should pass since SHARED_VAR is provided once
|
|
250
|
+
const result = await bundleServer({
|
|
251
|
+
entryPoint,
|
|
252
|
+
outputDir: join(dir, '.gkm', 'server', 'dist'),
|
|
253
|
+
minify: false,
|
|
254
|
+
sourcemap: false,
|
|
255
|
+
external: [],
|
|
256
|
+
stage: 'production',
|
|
257
|
+
constructs,
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
expect(result.masterKey).toBeDefined();
|
|
261
|
+
} finally {
|
|
262
|
+
process.chdir(originalCwd);
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
itWithDir(
|
|
268
|
+
'should skip validation when no constructs provided',
|
|
269
|
+
async ({ dir }) => {
|
|
270
|
+
const entryPoint = await createEntryPoint(dir);
|
|
271
|
+
await createSecretsFile(dir, 'production', {
|
|
272
|
+
custom: {},
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
const originalCwd = process.cwd();
|
|
276
|
+
process.chdir(dir);
|
|
277
|
+
|
|
278
|
+
try {
|
|
279
|
+
// Should not throw even with empty secrets
|
|
280
|
+
const result = await bundleServer({
|
|
281
|
+
entryPoint,
|
|
282
|
+
outputDir: join(dir, '.gkm', 'server', 'dist'),
|
|
283
|
+
minify: false,
|
|
284
|
+
sourcemap: false,
|
|
285
|
+
external: [],
|
|
286
|
+
stage: 'production',
|
|
287
|
+
constructs: [],
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
expect(result.masterKey).toBeDefined();
|
|
291
|
+
} finally {
|
|
292
|
+
process.chdir(originalCwd);
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
itWithDir(
|
|
298
|
+
'should skip validation when constructs is undefined',
|
|
299
|
+
async ({ dir }) => {
|
|
300
|
+
const entryPoint = await createEntryPoint(dir);
|
|
301
|
+
await createSecretsFile(dir, 'production', {
|
|
302
|
+
custom: {},
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
const originalCwd = process.cwd();
|
|
306
|
+
process.chdir(dir);
|
|
307
|
+
|
|
308
|
+
try {
|
|
309
|
+
const result = await bundleServer({
|
|
310
|
+
entryPoint,
|
|
311
|
+
outputDir: join(dir, '.gkm', 'server', 'dist'),
|
|
312
|
+
minify: false,
|
|
313
|
+
sourcemap: false,
|
|
314
|
+
external: [],
|
|
315
|
+
stage: 'production',
|
|
316
|
+
// No constructs provided
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
expect(result.masterKey).toBeDefined();
|
|
320
|
+
} finally {
|
|
321
|
+
process.chdir(originalCwd);
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
itWithDir(
|
|
327
|
+
'should recognize service credentials as provided',
|
|
328
|
+
async ({ dir }) => {
|
|
329
|
+
const entryPoint = await createEntryPoint(dir);
|
|
330
|
+
await createSecretsFile(dir, 'production', {
|
|
331
|
+
services: {
|
|
332
|
+
postgres: {
|
|
333
|
+
host: 'localhost',
|
|
334
|
+
port: 5432,
|
|
335
|
+
username: 'app',
|
|
336
|
+
password: 'secret',
|
|
337
|
+
database: 'mydb',
|
|
338
|
+
},
|
|
339
|
+
},
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
const constructs = [
|
|
343
|
+
createMockConstruct([
|
|
344
|
+
'POSTGRES_HOST',
|
|
345
|
+
'POSTGRES_PORT',
|
|
346
|
+
'POSTGRES_USER',
|
|
347
|
+
'POSTGRES_PASSWORD',
|
|
348
|
+
'POSTGRES_DB',
|
|
349
|
+
]),
|
|
350
|
+
];
|
|
351
|
+
|
|
352
|
+
const originalCwd = process.cwd();
|
|
353
|
+
process.chdir(dir);
|
|
354
|
+
|
|
355
|
+
try {
|
|
356
|
+
const result = await bundleServer({
|
|
357
|
+
entryPoint,
|
|
358
|
+
outputDir: join(dir, '.gkm', 'server', 'dist'),
|
|
359
|
+
minify: false,
|
|
360
|
+
sourcemap: false,
|
|
361
|
+
external: [],
|
|
362
|
+
stage: 'production',
|
|
363
|
+
constructs,
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
expect(result.masterKey).toBeDefined();
|
|
367
|
+
} finally {
|
|
368
|
+
process.chdir(originalCwd);
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
itWithDir(
|
|
374
|
+
'should throw when secrets file does not exist',
|
|
375
|
+
async ({ dir }) => {
|
|
376
|
+
const entryPoint = await createEntryPoint(dir);
|
|
377
|
+
// Don't create secrets file
|
|
378
|
+
|
|
379
|
+
const constructs = [createMockConstruct(['DATABASE_URL'])];
|
|
380
|
+
|
|
381
|
+
const originalCwd = process.cwd();
|
|
382
|
+
process.chdir(dir);
|
|
383
|
+
|
|
384
|
+
try {
|
|
385
|
+
await expect(
|
|
386
|
+
bundleServer({
|
|
387
|
+
entryPoint,
|
|
388
|
+
outputDir: join(dir, '.gkm', 'server', 'dist'),
|
|
389
|
+
minify: false,
|
|
390
|
+
sourcemap: false,
|
|
391
|
+
external: [],
|
|
392
|
+
stage: 'production',
|
|
393
|
+
constructs,
|
|
394
|
+
}),
|
|
395
|
+
).rejects.toThrow('No secrets found for stage "production"');
|
|
396
|
+
} finally {
|
|
397
|
+
process.chdir(originalCwd);
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
);
|
|
401
|
+
|
|
402
|
+
itWithDir(
|
|
403
|
+
'should include helpful instructions in error message',
|
|
404
|
+
async ({ dir }) => {
|
|
405
|
+
const entryPoint = await createEntryPoint(dir);
|
|
406
|
+
await createSecretsFile(dir, 'myapp', {
|
|
407
|
+
custom: {},
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
const constructs = [createMockConstruct(['MISSING_VAR'])];
|
|
411
|
+
|
|
412
|
+
const originalCwd = process.cwd();
|
|
413
|
+
process.chdir(dir);
|
|
414
|
+
|
|
415
|
+
try {
|
|
416
|
+
await expect(
|
|
417
|
+
bundleServer({
|
|
418
|
+
entryPoint,
|
|
419
|
+
outputDir: join(dir, '.gkm', 'server', 'dist'),
|
|
420
|
+
minify: false,
|
|
421
|
+
sourcemap: false,
|
|
422
|
+
external: [],
|
|
423
|
+
stage: 'myapp',
|
|
424
|
+
constructs,
|
|
425
|
+
}),
|
|
426
|
+
).rejects.toThrow(/gkm secrets:set/);
|
|
427
|
+
|
|
428
|
+
await expect(
|
|
429
|
+
bundleServer({
|
|
430
|
+
entryPoint,
|
|
431
|
+
outputDir: join(dir, '.gkm', 'server', 'dist'),
|
|
432
|
+
minify: false,
|
|
433
|
+
sourcemap: false,
|
|
434
|
+
external: [],
|
|
435
|
+
stage: 'myapp',
|
|
436
|
+
constructs,
|
|
437
|
+
}),
|
|
438
|
+
).rejects.toThrow(/gkm secrets:import/);
|
|
439
|
+
} finally {
|
|
440
|
+
process.chdir(originalCwd);
|
|
441
|
+
}
|
|
442
|
+
},
|
|
443
|
+
);
|
|
444
|
+
});
|