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 +1 -1
- package/src/modules/accounts.mjs +33 -18
- package/src/modules/db-prisma.mjs +5 -9
- package/src/modules/executor.test.mjs +17 -1
- package/templates/module-presets/db-prisma/apps/api/prisma/seed.ts +40 -19
- package/templates/module-presets/accounts/apps/api/src/accounts/forgeon-accounts-db-prisma.module.ts +0 -17
package/package.json
CHANGED
package/src/modules/accounts.mjs
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
.
|
|
19
|
-
await
|
|
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
|
});
|
package/templates/module-presets/accounts/apps/api/src/accounts/forgeon-accounts-db-prisma.module.ts
DELETED
|
@@ -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 {}
|