@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/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.107.0",
36
- "@auto-engineer/message-bus": "1.107.0"
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.107.0"
47
+ "@auto-engineer/cli": "1.109.0"
48
48
  },
49
- "version": "1.107.0",
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
- async function writeOrUpdatePackageJson(serverDir: string): Promise<void> {
91
- const pkgPath = join(serverDir, 'package.json');
90
+ const TEMPLATE_SERVER_PKG = '/app/.templates/server-package.json';
92
91
 
93
- const packageRoot = resolvePackageRoot();
94
- const localPkgPath = resolve(packageRoot, 'package.json');
95
- const rootPkgPath = resolve(packageRoot, '../../package.json');
96
-
97
- const localPkg = (await fs.readJson(localPkgPath)) as {
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
- const rootPkg = (await fs.readJson(rootPkgPath).catch(() => ({}))) as {
103
- dependencies?: Record<string, string>;
104
- devDependencies?: Record<string, string>;
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
- const getDepVersion = (dep: string): string | undefined =>
108
- localPkg.dependencies?.[dep] ??
109
- localPkg.devDependencies?.[dep] ??
110
- rootPkg.dependencies?.[dep] ??
111
- rootPkg.devDependencies?.[dep];
112
-
113
- const resolveDeps = (deps: string[]): Record<string, string> =>
114
- deps.reduce<Record<string, string>>((acc, dep) => {
115
- const version = getDepVersion(dep);
116
- if (typeof version === 'string') acc[dep] = version;
117
- return acc;
118
- }, {});
119
-
120
- const resolvedDeps = resolveDeps([
121
- '@event-driven-io/emmett',
122
- '@event-driven-io/emmett-sqlite',
123
- 'type-graphql',
124
- 'graphql-type-json',
125
- 'graphql',
126
- 'fast-glob',
127
- 'reflect-metadata',
128
- 'zod',
129
- 'apollo-server',
130
- 'uuid',
131
- 'sqlite3',
132
- ]);
133
- const resolvedDevDeps = resolveDeps(['typescript', 'vitest', 'tsx']);
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);