@auto-engineer/server-generator-apollo-emmett 1.107.0 → 1.109.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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +6 -6
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +69 -0
- package/dist/src/commands/initialize-server.d.ts +1 -0
- package/dist/src/commands/initialize-server.d.ts.map +1 -1
- package/dist/src/commands/initialize-server.js +109 -29
- package/dist/src/commands/initialize-server.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/commands/initialize-server-fallback.specs.ts +76 -0
- package/src/commands/initialize-server.ts +123 -38
package/package.json
CHANGED
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"uuid": "^13.0.0",
|
|
33
33
|
"web-streams-polyfill": "^4.1.0",
|
|
34
34
|
"zod": "^3.22.4",
|
|
35
|
-
"@auto-engineer/narrative": "1.
|
|
36
|
-
"@auto-engineer/message-bus": "1.
|
|
35
|
+
"@auto-engineer/narrative": "1.109.0",
|
|
36
|
+
"@auto-engineer/message-bus": "1.109.0"
|
|
37
37
|
},
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"access": "public"
|
|
@@ -44,9 +44,9 @@
|
|
|
44
44
|
"typescript": "^5.8.3",
|
|
45
45
|
"vitest": "^3.2.4",
|
|
46
46
|
"tsx": "^4.19.2",
|
|
47
|
-
"@auto-engineer/cli": "1.
|
|
47
|
+
"@auto-engineer/cli": "1.109.0"
|
|
48
48
|
},
|
|
49
|
-
"version": "1.
|
|
49
|
+
"version": "1.109.0",
|
|
50
50
|
"scripts": {
|
|
51
51
|
"generate:server": "tsx src/cli/index.ts",
|
|
52
52
|
"build": "tsc && tsx ../../scripts/fix-esm-imports.ts && rm -rf dist/src/codegen/templates && mkdir -p dist/src/codegen && cp -r src/codegen/templates dist/src/codegen/templates && cp src/server.ts dist/src && cp -r src/utils dist/src && cp -r src/domain dist/src",
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { mkdtemp, rm } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import fs from 'fs-extra';
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
6
|
+
import { applyTemplateFallback } from './initialize-server';
|
|
7
|
+
|
|
8
|
+
describe('applyTemplateFallback', () => {
|
|
9
|
+
let tempDir: string;
|
|
10
|
+
|
|
11
|
+
beforeEach(async () => {
|
|
12
|
+
tempDir = await mkdtemp(join(tmpdir(), 'init-server-fallback-'));
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
afterEach(async () => {
|
|
16
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('copies template to pkgPath when no existing package.json', async () => {
|
|
20
|
+
const templatePkg = {
|
|
21
|
+
name: 'generated-server',
|
|
22
|
+
version: '0.0.0',
|
|
23
|
+
scripts: { start: 'tsx src/server.ts' },
|
|
24
|
+
dependencies: { graphql: '^16.0.0' },
|
|
25
|
+
devDependencies: { typescript: '^5.0.0' },
|
|
26
|
+
};
|
|
27
|
+
const templatePath = join(tempDir, 'server-package.json');
|
|
28
|
+
await fs.writeJson(templatePath, templatePkg, { spaces: 2 });
|
|
29
|
+
|
|
30
|
+
const pkgPath = join(tempDir, 'output', 'package.json');
|
|
31
|
+
await fs.ensureDir(join(tempDir, 'output'));
|
|
32
|
+
|
|
33
|
+
await applyTemplateFallback(pkgPath, templatePath);
|
|
34
|
+
|
|
35
|
+
const result = await fs.readJson(pkgPath);
|
|
36
|
+
expect(result).toEqual(templatePkg);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('merges template deps into existing package.json', async () => {
|
|
40
|
+
const templatePath = join(tempDir, 'server-package.json');
|
|
41
|
+
await fs.writeJson(
|
|
42
|
+
templatePath,
|
|
43
|
+
{
|
|
44
|
+
name: 'generated-server',
|
|
45
|
+
dependencies: { graphql: '^16.0.0', zod: '^3.0.0' },
|
|
46
|
+
devDependencies: { typescript: '^5.0.0' },
|
|
47
|
+
},
|
|
48
|
+
{ spaces: 2 },
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const pkgPath = join(tempDir, 'package.json');
|
|
52
|
+
await fs.writeJson(pkgPath, { name: 'my-server', dependencies: { 'custom-dep': '1.0.0' } }, { spaces: 2 });
|
|
53
|
+
|
|
54
|
+
await applyTemplateFallback(pkgPath, templatePath);
|
|
55
|
+
|
|
56
|
+
const result = await fs.readJson(pkgPath);
|
|
57
|
+
expect(result).toEqual({
|
|
58
|
+
name: 'my-server',
|
|
59
|
+
dependencies: {
|
|
60
|
+
'custom-dep': '1.0.0',
|
|
61
|
+
graphql: '^16.0.0',
|
|
62
|
+
zod: '^3.0.0',
|
|
63
|
+
},
|
|
64
|
+
devDependencies: { typescript: '^5.0.0' },
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('throws when template path does not exist', async () => {
|
|
69
|
+
const pkgPath = join(tempDir, 'package.json');
|
|
70
|
+
const missingTemplate = join(tempDir, 'nonexistent.json');
|
|
71
|
+
|
|
72
|
+
await expect(applyTemplateFallback(pkgPath, missingTemplate)).rejects.toThrow(
|
|
73
|
+
'Cannot resolve package root and no template fallback available',
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -87,50 +87,78 @@ function resolvePackageRoot(): string {
|
|
|
87
87
|
return resolve(__dirname, '../../..');
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
const pkgPath = join(serverDir, 'package.json');
|
|
90
|
+
const TEMPLATE_SERVER_PKG = '/app/.templates/server-package.json';
|
|
92
91
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
92
|
+
export async function applyTemplateFallback(pkgPath: string, templatePath: string): Promise<void> {
|
|
93
|
+
if (!(await fs.pathExists(templatePath))) {
|
|
94
|
+
throw new Error('Cannot resolve package root and no template fallback available');
|
|
95
|
+
}
|
|
96
|
+
const template = (await fs.readJson(templatePath)) as {
|
|
98
97
|
dependencies?: Record<string, string>;
|
|
99
98
|
devDependencies?: Record<string, string>;
|
|
100
99
|
};
|
|
100
|
+
if (await fs.pathExists(pkgPath)) {
|
|
101
|
+
const existing = await fs.readJson(pkgPath);
|
|
102
|
+
existing.dependencies = { ...existing.dependencies, ...template.dependencies };
|
|
103
|
+
existing.devDependencies = { ...existing.devDependencies, ...template.devDependencies };
|
|
104
|
+
await fs.writeJson(pkgPath, existing, { spaces: 2 });
|
|
105
|
+
} else {
|
|
106
|
+
await fs.copy(templatePath, pkgPath);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
101
109
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
110
|
+
async function writeOrUpdatePackageJson(serverDir: string): Promise<void> {
|
|
111
|
+
const pkgPath = join(serverDir, 'package.json');
|
|
112
|
+
|
|
113
|
+
let resolvedDeps: Record<string, string>;
|
|
114
|
+
let resolvedDevDeps: Record<string, string>;
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
const packageRoot = resolvePackageRoot();
|
|
118
|
+
const localPkgPath = resolve(packageRoot, 'package.json');
|
|
119
|
+
const rootPkgPath = resolve(packageRoot, '../../package.json');
|
|
120
|
+
|
|
121
|
+
const localPkg = (await fs.readJson(localPkgPath)) as {
|
|
122
|
+
dependencies?: Record<string, string>;
|
|
123
|
+
devDependencies?: Record<string, string>;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const rootPkg = (await fs.readJson(rootPkgPath).catch(() => ({}))) as {
|
|
127
|
+
dependencies?: Record<string, string>;
|
|
128
|
+
devDependencies?: Record<string, string>;
|
|
129
|
+
};
|
|
106
130
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
131
|
+
const getDepVersion = (dep: string): string | undefined =>
|
|
132
|
+
localPkg.dependencies?.[dep] ??
|
|
133
|
+
localPkg.devDependencies?.[dep] ??
|
|
134
|
+
rootPkg.dependencies?.[dep] ??
|
|
135
|
+
rootPkg.devDependencies?.[dep];
|
|
136
|
+
|
|
137
|
+
const resolveDeps = (deps: string[]): Record<string, string> =>
|
|
138
|
+
deps.reduce<Record<string, string>>((acc, dep) => {
|
|
139
|
+
const version = getDepVersion(dep);
|
|
140
|
+
if (typeof version === 'string') acc[dep] = version;
|
|
141
|
+
return acc;
|
|
142
|
+
}, {});
|
|
143
|
+
|
|
144
|
+
resolvedDeps = resolveDeps([
|
|
145
|
+
'@event-driven-io/emmett',
|
|
146
|
+
'@event-driven-io/emmett-sqlite',
|
|
147
|
+
'type-graphql',
|
|
148
|
+
'graphql-type-json',
|
|
149
|
+
'graphql',
|
|
150
|
+
'fast-glob',
|
|
151
|
+
'reflect-metadata',
|
|
152
|
+
'zod',
|
|
153
|
+
'apollo-server',
|
|
154
|
+
'uuid',
|
|
155
|
+
'sqlite3',
|
|
156
|
+
]);
|
|
157
|
+
resolvedDevDeps = resolveDeps(['typescript', 'vitest', 'tsx']);
|
|
158
|
+
} catch {
|
|
159
|
+
await applyTemplateFallback(pkgPath, TEMPLATE_SERVER_PKG);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
134
162
|
|
|
135
163
|
if (await fs.pathExists(pkgPath)) {
|
|
136
164
|
const existing = await fs.readJson(pkgPath);
|
|
@@ -305,6 +333,62 @@ export class HealthResolver {
|
|
|
305
333
|
}
|
|
306
334
|
`;
|
|
307
335
|
|
|
336
|
+
const BIOME_JSON = `{
|
|
337
|
+
"$schema": "https://biomejs.dev/schemas/2.3.10/schema.json",
|
|
338
|
+
"vcs": {
|
|
339
|
+
"enabled": true,
|
|
340
|
+
"clientKind": "git",
|
|
341
|
+
"useIgnoreFile": false
|
|
342
|
+
},
|
|
343
|
+
"files": {
|
|
344
|
+
"ignoreUnknown": true
|
|
345
|
+
},
|
|
346
|
+
"formatter": {
|
|
347
|
+
"indentStyle": "tab",
|
|
348
|
+
"indentWidth": 2,
|
|
349
|
+
"lineWidth": 120,
|
|
350
|
+
"lineEnding": "lf"
|
|
351
|
+
},
|
|
352
|
+
"javascript": {
|
|
353
|
+
"formatter": {
|
|
354
|
+
"quoteStyle": "single",
|
|
355
|
+
"trailingCommas": "all",
|
|
356
|
+
"semicolons": "always",
|
|
357
|
+
"arrowParentheses": "always"
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
"linter": {
|
|
361
|
+
"rules": {
|
|
362
|
+
"recommended": true,
|
|
363
|
+
"correctness": {
|
|
364
|
+
"noUnusedImports": "error",
|
|
365
|
+
"noUnusedVariables": "error"
|
|
366
|
+
},
|
|
367
|
+
"suspicious": {
|
|
368
|
+
"noExplicitAny": "error",
|
|
369
|
+
"noConsole": "warn",
|
|
370
|
+
"noEmptyBlockStatements": "error"
|
|
371
|
+
},
|
|
372
|
+
"style": {
|
|
373
|
+
"useConst": "error",
|
|
374
|
+
"noNonNullAssertion": "error",
|
|
375
|
+
"useImportType": "error",
|
|
376
|
+
"useExportType": "error",
|
|
377
|
+
"useNodejsImportProtocol": "error",
|
|
378
|
+
"noParameterAssign": "error"
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
"assist": {
|
|
383
|
+
"actions": {
|
|
384
|
+
"source": {
|
|
385
|
+
"organizeImports": "on"
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
`;
|
|
391
|
+
|
|
308
392
|
const UTILS_INDEX_TS = `export * from './loadResolvers.js';
|
|
309
393
|
`;
|
|
310
394
|
|
|
@@ -323,6 +407,7 @@ export async function handleInitializeServerInternal(
|
|
|
323
407
|
await writeOrUpdatePackageJson(serverDir);
|
|
324
408
|
await writeTsconfig(serverDir);
|
|
325
409
|
await writeVitestConfigIfMissing(serverDir);
|
|
410
|
+
await writeIfMissing(join(serverDir, 'biome.json'), BIOME_JSON);
|
|
326
411
|
await writeSchemaScriptIfMissing(serverDir, absDest);
|
|
327
412
|
|
|
328
413
|
await writeIfMissing(join(serverDir, 'src', 'server.ts'), SERVER_TS);
|