create-forgeon 0.3.17 → 0.3.19

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-forgeon",
3
- "version": "0.3.17",
3
+ "version": "0.3.19",
4
4
  "description": "Forgeon project generator CLI",
5
5
  "license": "MIT",
6
6
  "author": "Forgeon",
@@ -172,38 +172,51 @@ function patchAppModule(targetRoot) {
172
172
  let content = fs.readFileSync(filePath, 'utf8').replace(/\r\n/g, '\n');
173
173
  content = content.replace(
174
174
  "import { authConfig, authEnvSchema, ForgeonAccountsModule } from '@forgeon/accounts-api';",
175
+ "import { ACCOUNTS_PERSISTENCE_PORT, authConfig, authEnvSchema, ForgeonAccountsModule, UsersModule } from '@forgeon/accounts-api';",
176
+ );
177
+ content = content.replace(
175
178
  "import { authConfig, authEnvSchema, ForgeonAccountsModule, UsersModule } from '@forgeon/accounts-api';",
179
+ "import { ACCOUNTS_PERSISTENCE_PORT, authConfig, authEnvSchema, ForgeonAccountsModule, UsersModule } from '@forgeon/accounts-api';",
176
180
  );
177
181
  content = ensureImportLine(
178
182
  content,
179
- "import { authConfig, authEnvSchema, ForgeonAccountsModule, UsersModule } from '@forgeon/accounts-api';",
183
+ "import { ACCOUNTS_PERSISTENCE_PORT, authConfig, authEnvSchema, ForgeonAccountsModule, UsersModule } from '@forgeon/accounts-api';",
180
184
  );
181
185
  content = ensureImportLine(
182
186
  content,
183
- "import { ForgeonAccountsDbPrismaModule } from './accounts/forgeon-accounts-db-prisma.module';",
187
+ "import { PrismaAccountsPersistenceStore } from './accounts/prisma-accounts-persistence.store';",
188
+ );
189
+ content = content.replace(
190
+ /^import \{ ForgeonAccountsDbPrismaModule \} from '\.\/accounts\/forgeon-accounts-db-prisma\.module';\r?\n/m,
191
+ '',
184
192
  );
185
193
  content = ensureLoadItem(content, 'authConfig');
186
194
  content = ensureValidatorSchema(content, 'authEnvSchema');
187
-
188
- if (!content.includes(' ForgeonAccountsDbPrismaModule,')) {
189
- if (content.includes(' DbPrismaModule,')) {
190
- content = ensureLineAfter(content, ' DbPrismaModule,', ' ForgeonAccountsDbPrismaModule,');
191
- } else {
192
- content = ensureLineAfter(content, ' CoreErrorsModule,', ' ForgeonAccountsDbPrismaModule,');
193
- }
194
- }
195
+ content = content.replace(/^\s*ForgeonAccountsDbPrismaModule,\r?\n/gm, '');
195
196
 
196
197
  const accountsModuleLine = ` ForgeonAccountsModule.register({
198
+ imports: [DbPrismaModule],
199
+ providers: [
200
+ PrismaAccountsPersistenceStore,
201
+ {
202
+ provide: ACCOUNTS_PERSISTENCE_PORT,
203
+ useExisting: PrismaAccountsPersistenceStore,
204
+ },
205
+ ],
197
206
  users: UsersModule.register({}),
198
207
  }),`;
199
- if (!content.includes('ForgeonAccountsModule.register({')) {
200
- if (content.includes(' ForgeonI18nModule.register({')) {
201
- content = ensureLineBefore(content, ' ForgeonI18nModule.register({', accountsModuleLine);
202
- } else if (content.includes(' ForgeonAccountsDbPrismaModule,')) {
203
- content = ensureLineAfter(content, ' ForgeonAccountsDbPrismaModule,', accountsModuleLine);
204
- } else {
205
- content = ensureLineAfter(content, ' CoreErrorsModule,', accountsModuleLine);
206
- }
208
+
209
+ if (content.includes(' ForgeonAccountsModule.register({')) {
210
+ content = content.replace(
211
+ / {4}ForgeonAccountsModule\.register\(\{[\s\S]*? {4}\}\),/m,
212
+ accountsModuleLine,
213
+ );
214
+ } else if (content.includes(' ForgeonI18nModule.register({')) {
215
+ content = ensureLineBefore(content, ' ForgeonI18nModule.register({', accountsModuleLine);
216
+ } else if (content.includes(' DbPrismaModule,')) {
217
+ content = ensureLineAfter(content, ' DbPrismaModule,', accountsModuleLine);
218
+ } else {
219
+ content = ensureLineAfter(content, ' CoreErrorsModule,', accountsModuleLine);
207
220
  }
208
221
 
209
222
  fs.writeFileSync(filePath, `${content.trimEnd()}\n`, 'utf8');
@@ -414,3 +427,5 @@ export function applyAccountsModule({ packageRoot, targetRoot }) {
414
427
  }
415
428
 
416
429
 
430
+
431
+
@@ -1,4 +1,4 @@
1
- import fs from 'node:fs';
1
+ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { copyRecursive, writeJson } from '../utils/fs.mjs';
4
4
  import {
@@ -156,17 +156,12 @@ function patchHealthController(targetRoot, probeTargets) {
156
156
  const dbMethod = `
157
157
  @Post('db')
158
158
  async getDbProbe() {
159
- const token = \`\${Date.now()}-\${Math.floor(Math.random() * 1_000_000)}\`;
160
- const email = \`health-probe-\${token}@example.local\`;
161
- const user = await this.prisma.user.create({
162
- data: { email },
163
- select: { id: true, email: true, createdAt: true },
164
- });
159
+ const queryResult = await this.prisma.$queryRaw\`SELECT 1 AS ok\`;
165
160
 
166
161
  return {
167
162
  status: 'ok',
168
163
  feature: 'db-prisma',
169
- user,
164
+ queryResult,
170
165
  };
171
166
  }
172
167
  `;
@@ -183,7 +178,7 @@ function registerWebProbe(targetRoot, probeTargets) {
183
178
  definition: {
184
179
  id: 'db',
185
180
  title: 'Database',
186
- buttonLabel: 'Check database (create user)',
181
+ buttonLabel: 'Check database query',
187
182
  resultTitle: 'DB probe response',
188
183
  path: '/health/db',
189
184
  request: { method: 'POST' },
@@ -336,3 +331,4 @@ export function applyDbPrismaModule({ packageRoot, targetRoot }) {
336
331
  'DATABASE_URL=postgresql://postgres:postgres@db:5432/app?schema=public',
337
332
  ]);
338
333
  }
334
+
@@ -716,8 +716,11 @@ function assertAccountsWiring(projectRoot) {
716
716
  const appModule = fs.readFileSync(path.join(projectRoot, 'apps', 'api', 'src', 'app.module.ts'), 'utf8');
717
717
  assert.match(appModule, /authConfig/);
718
718
  assert.match(appModule, /authEnvSchema/);
719
- assert.match(appModule, /ForgeonAccountsDbPrismaModule/);
720
719
  assert.match(appModule, /ForgeonAccountsModule\.register\(\{/);
720
+ assert.match(appModule, /imports: \[DbPrismaModule\]/);
721
+ assert.match(appModule, /PrismaAccountsPersistenceStore/);
722
+ assert.match(appModule, /provide: ACCOUNTS_PERSISTENCE_PORT/);
723
+ assert.match(appModule, /useExisting: PrismaAccountsPersistenceStore/);
721
724
  assert.match(appModule, /UsersModule\.register\(\{\}\)/);
722
725
  assert.doesNotMatch(appModule, /AUTH_REFRESH_TOKEN_STORE/);
723
726
 
@@ -727,6 +730,8 @@ function assertAccountsWiring(projectRoot) {
727
730
  );
728
731
  assert.match(healthController, /@Get\('auth'\)/);
729
732
  assert.match(healthController, /authService\.getProbeStatus/);
733
+ assert.match(healthController, /\$queryRaw/);
734
+ assert.doesNotMatch(healthController, /data:\s*\{\s*email\s*\}/);
730
735
  assert.doesNotMatch(healthController, /,\s*,/);
731
736
 
732
737
  assertWebProbeShell(projectRoot);
@@ -2211,6 +2216,10 @@ describe('addModule', () => {
2211
2216
  );
2212
2217
  assert.equal(fs.existsSync(migrationPath), true);
2213
2218
 
2219
+ const seedSource = fs.readFileSync(path.join(projectRoot, 'apps', 'api', 'prisma', 'seed.ts'), 'utf8');
2220
+ assert.match(seedSource, /Prisma\.dmmf/);
2221
+ assert.match(seedSource, /userFields\.has\('email'\)/);
2222
+
2214
2223
  const readme = fs.readFileSync(path.join(projectRoot, 'README.md'), 'utf8');
2215
2224
  assert.match(readme, /POST \/api\/auth\/register/);
2216
2225
  assert.match(readme, /POST \/api\/auth\/password-reset\/request/);
@@ -2634,3 +2643,10 @@ describe('addModule', () => {
2634
2643
 
2635
2644
 
2636
2645
 
2646
+
2647
+
2648
+
2649
+
2650
+
2651
+
2652
+
@@ -1,20 +1,41 @@
1
- import { PrismaClient } from '@prisma/client';
2
-
3
- const prisma = new PrismaClient();
4
-
5
- async function main() {
6
- await prisma.user.upsert({
7
- where: { email: 'seed@example.com' },
8
- update: {},
9
- create: { email: 'seed@example.com' },
10
- });
11
- }
12
-
13
- main()
14
- .catch((error) => {
15
- console.error(error);
16
- process.exit(1);
17
- })
18
- .finally(async () => {
19
- await prisma.$disconnect();
1
+ import { Prisma, PrismaClient } from '@prisma/client';
2
+
3
+ const prisma = new PrismaClient();
4
+
5
+ function getUserFieldSet() {
6
+ const userModel = Prisma.dmmf.datamodel.models.find((model) => model.name === 'User');
7
+ return new Set((userModel?.fields ?? []).map((field) => field.name));
8
+ }
9
+
10
+ async function main() {
11
+ const userFields = getUserFieldSet();
12
+ const userDelegate = prisma.user as unknown as {
13
+ findFirst(args?: Record<string, unknown>): Promise<{ id: string } | null>;
14
+ upsert(args: Record<string, unknown>): Promise<unknown>;
15
+ create(args: Record<string, unknown>): Promise<unknown>;
16
+ };
17
+
18
+ if (userFields.has('email')) {
19
+ await userDelegate.upsert({
20
+ where: { email: 'seed@example.com' },
21
+ update: {},
22
+ create: { email: 'seed@example.com' },
23
+ });
24
+ return;
25
+ }
26
+
27
+ const existingUser = await userDelegate.findFirst({ select: { id: true } });
28
+ if (!existingUser) {
29
+ const data = userFields.has('status') ? { status: 'active' } : {};
30
+ await userDelegate.create({ data });
31
+ }
32
+ }
33
+
34
+ main()
35
+ .catch((error) => {
36
+ console.error(error);
37
+ process.exit(1);
38
+ })
39
+ .finally(async () => {
40
+ await prisma.$disconnect();
20
41
  });
@@ -1,17 +0,0 @@
1
- import { Module } from '@nestjs/common';
2
- import { ACCOUNTS_PERSISTENCE_PORT } from '@forgeon/accounts-api';
3
- import { DbPrismaModule } from '@forgeon/db-prisma';
4
- import { PrismaAccountsPersistenceStore } from './prisma-accounts-persistence.store';
5
-
6
- @Module({
7
- imports: [DbPrismaModule],
8
- providers: [
9
- PrismaAccountsPersistenceStore,
10
- {
11
- provide: ACCOUNTS_PERSISTENCE_PORT,
12
- useExisting: PrismaAccountsPersistenceStore,
13
- },
14
- ],
15
- exports: [ACCOUNTS_PERSISTENCE_PORT],
16
- })
17
- export class ForgeonAccountsDbPrismaModule {}