@abgov/nx-adsp 12.23.1 → 12.25.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 +1 -1
- package/src/generators/express-service/express-service.js +24 -25
- package/src/generators/express-service/express-service.js.map +1 -1
- package/src/generators/express-service/express-service.spec.ts +21 -8
- package/src/generators/express-service/files/AGENTS.md__tmpl__ +28 -18
- package/src/generators/express-service/files/src/main.ts__tmpl__ +2 -2
- package/src/generators/express-service/files-postgres/drizzle.config.ts__tmpl__ +17 -0
- package/src/generators/express-service/files-postgres/scripts/dev-db.sh__tmpl__ +1 -1
- package/src/generators/express-service/files-postgres/src/database.ts__tmpl__ +13 -2
- package/src/generators/express-service/files-postgres/src/db/schema.ts__tmpl__ +17 -0
- package/src/generators/express-service/files-postgres/src/migrate.ts__tmpl__ +41 -0
- package/src/generators/express-service/files-postgres/webpack.config.js__tmpl__ +36 -0
- package/src/generators/express-service/schema.json +1 -1
- package/src/generators/mevn/mevn.spec.ts +1 -1
- package/src/generators/pean/pean.spec.ts +1 -1
- package/src/generators/pern/pern.spec.ts +1 -1
- package/src/generators/pevn/pevn.spec.ts +1 -1
- package/src/generators/express-service/files-postgres/prisma/schema.prisma__tmpl__ +0 -14
- /package/src/generators/express-service/files-postgres/{prisma/migrations → drizzle}/.gitkeep +0 -0
package/package.json
CHANGED
|
@@ -56,11 +56,11 @@ function addFiles(host, options) {
|
|
|
56
56
|
}
|
|
57
57
|
function default_1(host, options) {
|
|
58
58
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
59
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
59
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
60
60
|
const normalizedOptions = yield normalizeOptions(host, options);
|
|
61
61
|
const { applicationGenerator: initExpress } = yield Promise.resolve().then(() => require('@nx/express'));
|
|
62
62
|
yield initExpress(host, Object.assign(Object.assign({}, options), { skipFormat: true, skipPackageJson: false, linter: eslint_1.Linter.EsLint, unitTestRunner: 'jest', js: false, directory: normalizedOptions.projectRoot }));
|
|
63
|
-
(0, devkit_1.addDependenciesToPackageJson)(host, Object.assign(Object.assign({ '@abgov/adsp-service-sdk': '^2.23.0', compression: '^1.8.1', cors: '^2.8.5', dotenv: '^16.4.7', envalid: '^8.0.0', helmet: '^8.0.0', passport: '^0.7.0', 'passport-anonymous': '^1.0.1', zod: '^3.0.0' }, (normalizedOptions.database === 'postgres' ? { '
|
|
63
|
+
(0, devkit_1.addDependenciesToPackageJson)(host, Object.assign(Object.assign({ '@abgov/adsp-service-sdk': '^2.23.0', compression: '^1.8.1', cors: '^2.8.5', dotenv: '^16.4.7', envalid: '^8.0.0', helmet: '^8.0.0', passport: '^0.7.0', 'passport-anonymous': '^1.0.1', zod: '^3.0.0' }, (normalizedOptions.database === 'postgres' ? { 'drizzle-orm': '^0.44.0', pg: '^8.11.0' } : {})), (normalizedOptions.database === 'mongo' ? { mongoose: '^8.0.0' } : {})), Object.assign(Object.assign({ '@types/compression': '^1.7.5', '@types/cors': '^2.8.17', '@types/passport': '^1.0.16', '@types/passport-anonymous': '^1.0.3' }, (normalizedOptions.database === 'postgres' ? { 'drizzle-kit': '^0.31.0', '@types/pg': '^8.11.0' } : {})), { 'eslint-plugin-security': '^3.0.0', 'eslint-plugin-no-secrets': '^2.0.0', 'eslint-plugin-jest': '^28.0.0' }));
|
|
64
64
|
addFiles(host, normalizedOptions);
|
|
65
65
|
(0, quality_1.addEslintQualityRules)(host, normalizedOptions.projectRoot, ['**/*.spec.ts', '**/*.test.ts']);
|
|
66
66
|
(0, quality_1.addJestCoverageConfig)(host, normalizedOptions.projectRoot);
|
|
@@ -81,33 +81,32 @@ function default_1(host, options) {
|
|
|
81
81
|
if (normalizedOptions.database === 'postgres') {
|
|
82
82
|
targets['db:generate'] = {
|
|
83
83
|
executor: 'nx:run-commands',
|
|
84
|
-
options: { command: 'npx
|
|
84
|
+
options: { command: 'npx drizzle-kit generate', cwd: '{projectRoot}' },
|
|
85
85
|
};
|
|
86
86
|
targets['db:migrate'] = {
|
|
87
87
|
executor: 'nx:run-commands',
|
|
88
|
-
options: { command: 'npx
|
|
88
|
+
options: { command: 'npx drizzle-kit migrate', cwd: '{projectRoot}' },
|
|
89
89
|
};
|
|
90
90
|
targets['db:migrate:deploy'] = {
|
|
91
91
|
executor: 'nx:run-commands',
|
|
92
|
-
options: { command: 'npx
|
|
92
|
+
options: { command: 'npx drizzle-kit migrate', cwd: '{projectRoot}' },
|
|
93
93
|
};
|
|
94
94
|
targets['db:studio'] = {
|
|
95
95
|
executor: 'nx:run-commands',
|
|
96
|
-
options: { command: 'npx
|
|
96
|
+
options: { command: 'npx drizzle-kit studio', cwd: '{projectRoot}' },
|
|
97
97
|
};
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
98
|
+
// Ship the SQL migrations (drizzle/) into the build output so the migrate.js
|
|
99
|
+
// init container can apply them at deploy time. Drizzle is pure TypeScript
|
|
100
|
+
// with no client codegen, so the build has no db:generate prerequisite.
|
|
101
|
+
if ((_b = targets['build']) === null || _b === void 0 ? void 0 : _b.options) {
|
|
102
|
+
targets['build'] = Object.assign(Object.assign({}, targets['build']), { options: Object.assign(Object.assign({}, targets['build'].options), { assets: [
|
|
103
|
+
...((_c = targets['build'].options.assets) !== null && _c !== void 0 ? _c : []),
|
|
104
|
+
{
|
|
105
|
+
input: `${normalizedOptions.projectRoot}/drizzle`,
|
|
106
|
+
glob: '**/*',
|
|
107
|
+
output: 'drizzle',
|
|
108
|
+
},
|
|
109
|
+
] }) });
|
|
111
110
|
}
|
|
112
111
|
}
|
|
113
112
|
}
|
|
@@ -116,7 +115,7 @@ function default_1(host, options) {
|
|
|
116
115
|
yield (0, devkit_1.formatFiles)(host);
|
|
117
116
|
if (normalizedOptions.adsp) {
|
|
118
117
|
const clientId = `urn:ads:${normalizedOptions.adsp.tenant}:${normalizedOptions.projectName}`;
|
|
119
|
-
const accessToken = (
|
|
118
|
+
const accessToken = (_d = normalizedOptions.accessToken) !== null && _d !== void 0 ? _d : normalizedOptions.adsp.accessToken;
|
|
120
119
|
const clientSecret = yield (0, keycloak_admin_1.ensureServiceClient)(normalizedOptions.adsp.accessServiceUrl, normalizedOptions.adsp.tenantRealm, clientId, accessToken);
|
|
121
120
|
if (clientSecret) {
|
|
122
121
|
const envPath = `${normalizedOptions.projectRoot}/.env`;
|
|
@@ -143,16 +142,16 @@ function default_1(host, options) {
|
|
|
143
142
|
// from the single realm login already performed during normalizeOptions.
|
|
144
143
|
// token from the single realm login. Fall back to a new login only when the
|
|
145
144
|
// full interactive flow was used and no token is available.
|
|
146
|
-
const accessToken = (
|
|
145
|
+
const accessToken = (_e = normalizedOptions.accessToken) !== null && _e !== void 0 ? _e : (yield (0, nx_oc_1.realmLogin)(normalizedOptions.adsp.accessServiceUrl, normalizedOptions.adsp.tenantRealm).catch((err) => {
|
|
147
146
|
var _a;
|
|
148
147
|
process.stdout.write(`Agent sign-in failed (${(_a = err === null || err === void 0 ? void 0 : err.message) !== null && _a !== void 0 ? _a : err}) — skipping agent interaction.\n`);
|
|
149
148
|
return undefined;
|
|
150
149
|
}));
|
|
151
|
-
const mainTs = (
|
|
152
|
-
const environmentTs = (
|
|
153
|
-
const eventsTs = (
|
|
150
|
+
const mainTs = (_g = (_f = host.read(`${normalizedOptions.projectRoot}/src/main.ts`)) === null || _f === void 0 ? void 0 : _f.toString()) !== null && _g !== void 0 ? _g : '';
|
|
151
|
+
const environmentTs = (_j = (_h = host.read(`${normalizedOptions.projectRoot}/src/environment.ts`)) === null || _h === void 0 ? void 0 : _h.toString()) !== null && _j !== void 0 ? _j : '';
|
|
152
|
+
const eventsTs = (_l = (_k = host.read(`${normalizedOptions.projectRoot}/src/events.ts`)) === null || _k === void 0 ? void 0 : _k.toString()) !== null && _l !== void 0 ? _l : '';
|
|
154
153
|
const databaseTs = normalizedOptions.database !== 'none'
|
|
155
|
-
? (
|
|
154
|
+
? (_o = (_m = host.read(`${normalizedOptions.projectRoot}/src/database.ts`)) === null || _m === void 0 ? void 0 : _m.toString()) !== null && _o !== void 0 ? _o : ''
|
|
156
155
|
: undefined;
|
|
157
156
|
const agentResult = yield (0, agent_1.consultAgent)(normalizedOptions.adsp.directoryServiceUrl, accessToken, {
|
|
158
157
|
projectName: normalizedOptions.projectName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express-service.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/express-service/express-service.ts"],"names":[],"mappings":";;AAiGA,
|
|
1
|
+
{"version":3,"file":"express-service.js","sourceRoot":"","sources":["../../../../../../packages/nx-adsp/src/generators/express-service/express-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -51,17 +51,20 @@ describe('Express Service Generator', () => {
|
|
|
51
51
|
const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
52
52
|
await generator(host, { ...options, database: 'postgres' });
|
|
53
53
|
|
|
54
|
-
expect(host.exists('apps/test/
|
|
54
|
+
expect(host.exists('apps/test/src/db/schema.ts')).toBeTruthy();
|
|
55
55
|
expect(host.exists('apps/test/src/database.ts')).toBeTruthy();
|
|
56
|
+
expect(host.exists('apps/test/src/migrate.ts')).toBeTruthy();
|
|
57
|
+
expect(host.exists('apps/test/drizzle.config.ts')).toBeTruthy();
|
|
56
58
|
expect(host.exists('apps/test/scripts/dev-db.sh')).toBeTruthy();
|
|
57
59
|
expect(host.exists('apps/test/.env.example')).toBeTruthy();
|
|
58
60
|
|
|
59
|
-
const schema = host.read('apps/test/prisma/schema.prisma').toString();
|
|
60
|
-
expect(schema).toContain('postgresql');
|
|
61
|
-
expect(schema).toContain('src/generated/prisma');
|
|
62
|
-
|
|
63
61
|
const database = host.read('apps/test/src/database.ts').toString();
|
|
64
|
-
expect(database).toContain('
|
|
62
|
+
expect(database).toContain('drizzle-orm/node-postgres');
|
|
63
|
+
expect(database).toContain('closeDatabase');
|
|
64
|
+
|
|
65
|
+
// webpack emits a second bundle (migrate.js) for the deploy init container.
|
|
66
|
+
const webpackConfig = host.read('apps/test/webpack.config.js').toString();
|
|
67
|
+
expect(webpackConfig).toContain('migrate');
|
|
65
68
|
|
|
66
69
|
const config = readProjectConfiguration(host, 'test');
|
|
67
70
|
expect(config.targets['dev-db']).toBeTruthy();
|
|
@@ -70,7 +73,17 @@ describe('Express Service Generator', () => {
|
|
|
70
73
|
expect(config.targets['db:migrate:deploy']).toBeTruthy();
|
|
71
74
|
expect(config.targets['db:studio']).toBeTruthy();
|
|
72
75
|
expect(config.targets['serve'].dependsOn).toContain('dev-db');
|
|
73
|
-
|
|
76
|
+
|
|
77
|
+
// Drizzle has no client codegen, so build must NOT depend on db:generate.
|
|
78
|
+
expect(config.targets['build'].dependsOn ?? []).not.toContain('db:generate');
|
|
79
|
+
// The SQL migrations are shipped as a build asset.
|
|
80
|
+
const assets = config.targets['build'].options.assets ?? [];
|
|
81
|
+
expect(
|
|
82
|
+
assets.some(
|
|
83
|
+
(a: unknown) =>
|
|
84
|
+
typeof a === 'object' && (a as { output?: string }).output === 'drizzle'
|
|
85
|
+
)
|
|
86
|
+
).toBe(true);
|
|
74
87
|
}, 60000);
|
|
75
88
|
|
|
76
89
|
it('scaffolds mongo database files and targets', async () => {
|
|
@@ -94,7 +107,7 @@ describe('Express Service Generator', () => {
|
|
|
94
107
|
const host = createTreeWithEmptyWorkspace({ layout: 'apps-libs' });
|
|
95
108
|
await generator(host, { ...options, database: 'none' });
|
|
96
109
|
|
|
97
|
-
expect(host.exists('apps/test/
|
|
110
|
+
expect(host.exists('apps/test/src/db/schema.ts')).toBeFalsy();
|
|
98
111
|
expect(host.exists('apps/test/src/database.ts')).toBeFalsy();
|
|
99
112
|
expect(host.exists('apps/test/scripts/dev-db.sh')).toBeFalsy();
|
|
100
113
|
|
|
@@ -18,7 +18,7 @@ When working on a feature that spans both projects, read `apps/<%= pairedProject
|
|
|
18
18
|
event publishing, configuration management, and service discovery
|
|
19
19
|
- **Tests**: Jest
|
|
20
20
|
<% if (database === 'postgres') { %>
|
|
21
|
-
- **Database**: PostgreSQL via
|
|
21
|
+
- **Database**: PostgreSQL via Drizzle ORM (pure TypeScript, node-postgres driver)
|
|
22
22
|
<% } else if (database === 'mongo') { %>
|
|
23
23
|
- **Database**: MongoDB via Mongoose
|
|
24
24
|
<% } %>
|
|
@@ -31,8 +31,10 @@ When working on a feature that spans both projects, read `apps/<%= pairedProject
|
|
|
31
31
|
| `src/environment.ts` | Validated env config with defaults pre-set from ADSP tenant |
|
|
32
32
|
| `src/events.ts` | Domain event definitions — register in `initializeService({ events })` |
|
|
33
33
|
<% if (database === 'postgres') { %>
|
|
34
|
-
| `src/database.ts` |
|
|
35
|
-
| `
|
|
34
|
+
| `src/database.ts` | Drizzle `db` instance — import `{ db }` in route handlers |
|
|
35
|
+
| `src/db/schema.ts` | Drizzle table definitions — edit to add tables, then run `nx db:generate <%= projectName %>` |
|
|
36
|
+
| `src/migrate.ts` | Standalone migration runner — bundled to `migrate.js`, run as the deploy init container |
|
|
37
|
+
| `drizzle.config.ts` | drizzle-kit config (schema path, migrations output, connection) |
|
|
36
38
|
<% } else if (database === 'mongo') { %>
|
|
37
39
|
| `src/database.ts` | Mongoose connection helpers — `connectDatabase()` and `disconnectDatabase()` |
|
|
38
40
|
<% } %>
|
|
@@ -144,35 +146,43 @@ podman machine init
|
|
|
144
146
|
podman machine start
|
|
145
147
|
```
|
|
146
148
|
|
|
147
|
-
## Adding a
|
|
149
|
+
## Adding a table
|
|
148
150
|
|
|
149
|
-
1. Edit `
|
|
150
|
-
2. Run `nx db:
|
|
151
|
-
3. Run `nx db:
|
|
152
|
-
4. Import `{
|
|
151
|
+
1. Edit `src/db/schema.ts` to add your table (Drizzle `pgTable`)
|
|
152
|
+
2. Run `nx db:generate <%= projectName %>` — writes a SQL migration to `drizzle/`
|
|
153
|
+
3. Run `nx db:migrate <%= projectName %>` — applies pending migrations to your dev DB
|
|
154
|
+
4. Import `{ db }` from `./database` and your table from `./db/schema` in a handler
|
|
153
155
|
|
|
154
156
|
```typescript
|
|
155
|
-
// Example route using
|
|
157
|
+
// Example route using Drizzle
|
|
158
|
+
import { db } from './database';
|
|
159
|
+
import { items } from './db/schema';
|
|
160
|
+
|
|
156
161
|
app.get('/<%= projectName %>/v1/items', async (_req, res) => {
|
|
157
|
-
const
|
|
158
|
-
res.json(
|
|
162
|
+
const rows = await db.select().from(items);
|
|
163
|
+
res.json(rows);
|
|
159
164
|
});
|
|
160
165
|
```
|
|
161
166
|
|
|
162
|
-
##
|
|
167
|
+
## Drizzle targets
|
|
163
168
|
|
|
164
169
|
| Target | Command | Use |
|
|
165
170
|
|--------|---------|-----|
|
|
166
|
-
| `nx db:
|
|
167
|
-
| `nx db:migrate
|
|
168
|
-
| `nx db:
|
|
169
|
-
| `nx db:studio <%= projectName %>` | `
|
|
171
|
+
| `nx db:generate <%= projectName %>` | `drizzle-kit generate` | Generate a SQL migration from schema changes |
|
|
172
|
+
| `nx db:migrate <%= projectName %>` | `drizzle-kit migrate` | Apply pending migrations to the dev DB |
|
|
173
|
+
| `nx db:migrate:deploy <%= projectName %>` | `drizzle-kit migrate` | Apply pending migrations in a dev/CI shell |
|
|
174
|
+
| `nx db:studio <%= projectName %>` | `drizzle-kit studio` | Open Drizzle Studio to browse data |
|
|
175
|
+
|
|
176
|
+
`drizzle-kit` is a dev-only dependency. In the container, migrations are applied
|
|
177
|
+
by `migrate.js` (bundled from `src/migrate.ts`), which uses only `drizzle-orm` +
|
|
178
|
+
`pg` — no CLI and no native engine — so it runs under OpenShift's arbitrary UID.
|
|
170
179
|
|
|
171
180
|
## OpenShift deployment — database
|
|
172
181
|
|
|
173
182
|
The deployment manifest references a Secret named `{appName}-database` for the
|
|
174
|
-
`DATABASE_URL` value, and runs `
|
|
175
|
-
|
|
183
|
+
`DATABASE_URL` value, and runs `node migrate.js` as an init container before the
|
|
184
|
+
application starts. The generated SQL migrations in `drizzle/` are shipped into
|
|
185
|
+
the build output as assets so the init container can apply them.
|
|
176
186
|
|
|
177
187
|
Create the Secret in each OpenShift namespace before first deploy:
|
|
178
188
|
|
|
@@ -7,7 +7,7 @@ import passport from 'passport';
|
|
|
7
7
|
import { Strategy as AnonymousStrategy } from 'passport-anonymous';
|
|
8
8
|
import { z } from 'zod';
|
|
9
9
|
<% if (database === 'postgres') { %>
|
|
10
|
-
import {
|
|
10
|
+
import { closeDatabase } from './database';
|
|
11
11
|
<% } else if (database === 'mongo') { %>
|
|
12
12
|
import { connectDatabase, disconnectDatabase } from './database';
|
|
13
13
|
<% } %>
|
|
@@ -136,7 +136,7 @@ initializeApp().then(({ app, logger }) => {
|
|
|
136
136
|
|
|
137
137
|
const shutdown = async () => {
|
|
138
138
|
server.close();
|
|
139
|
-
await
|
|
139
|
+
await closeDatabase();
|
|
140
140
|
};
|
|
141
141
|
process.on('SIGTERM', shutdown);
|
|
142
142
|
process.on('SIGINT', shutdown);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { config } from 'dotenv';
|
|
2
|
+
import { defineConfig } from 'drizzle-kit';
|
|
3
|
+
|
|
4
|
+
// drizzle-kit (generate/migrate/studio) is a dev-only CLI. Load the local
|
|
5
|
+
// DATABASE_URL the same way the app does: .env first, then .env.local (written
|
|
6
|
+
// by `nx dev-db`) taking precedence.
|
|
7
|
+
config({ path: '.env' });
|
|
8
|
+
config({ path: '.env.local', override: true });
|
|
9
|
+
|
|
10
|
+
export default defineConfig({
|
|
11
|
+
schema: './src/db/schema.ts',
|
|
12
|
+
out: './drizzle',
|
|
13
|
+
dialect: 'postgresql',
|
|
14
|
+
dbCredentials: {
|
|
15
|
+
url: process.env.DATABASE_URL as string,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
@@ -37,7 +37,7 @@ until podman exec "${CONTAINER}" pg_isready -U "${DB_USER}" -d "${DB_NAME}" &>/d
|
|
|
37
37
|
done
|
|
38
38
|
echo "Postgres is ready."
|
|
39
39
|
|
|
40
|
-
# Write DATABASE_URL to .env.local so
|
|
40
|
+
# Write DATABASE_URL to .env.local so Drizzle and the app pick it up without
|
|
41
41
|
# manual .env editing. Overridden by the SECRET in OpenShift at runtime.
|
|
42
42
|
echo "DATABASE_URL=postgresql://${DB_USER}:${DB_PASS}@localhost:${PORT}/${DB_NAME}" > .env.local
|
|
43
43
|
echo "DATABASE_URL written to .env.local"
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { drizzle } from 'drizzle-orm/node-postgres';
|
|
2
|
+
import { Pool } from 'pg';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
import { environment } from './environment';
|
|
5
|
+
import * as schema from './db/schema';
|
|
6
|
+
|
|
7
|
+
// Drizzle is pure TypeScript: the node-postgres (pg) driver owns the connection,
|
|
8
|
+
// so there is no native database engine to download, ship, or run — the
|
|
9
|
+
// container image needs nothing beyond the app's JS and node_modules.
|
|
10
|
+
const pool = new Pool({ connectionString: environment.DATABASE_URL });
|
|
11
|
+
|
|
12
|
+
export const db = drizzle(pool, { schema });
|
|
13
|
+
|
|
14
|
+
export const closeDatabase = (): Promise<void> => pool.end();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Drizzle schema — define your tables here.
|
|
2
|
+
//
|
|
3
|
+
// After editing this file:
|
|
4
|
+
// 1. nx db:generate <%= projectName %> — writes a SQL migration to ./drizzle
|
|
5
|
+
// 2. nx db:migrate <%= projectName %> — applies pending migrations to your dev DB
|
|
6
|
+
//
|
|
7
|
+
// Example (uncomment and adapt, then run the two commands above):
|
|
8
|
+
//
|
|
9
|
+
// import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';
|
|
10
|
+
//
|
|
11
|
+
// export const items = pgTable('items', {
|
|
12
|
+
// id: serial('id').primaryKey(),
|
|
13
|
+
// name: text('name').notNull(),
|
|
14
|
+
// createdAt: timestamp('created_at').defaultNow().notNull(),
|
|
15
|
+
// });
|
|
16
|
+
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
import { drizzle } from 'drizzle-orm/node-postgres';
|
|
3
|
+
import { migrate } from 'drizzle-orm/node-postgres/migrator';
|
|
4
|
+
import { Pool } from 'pg';
|
|
5
|
+
|
|
6
|
+
const MIGRATIONS_FOLDER = 'drizzle';
|
|
7
|
+
|
|
8
|
+
// Standalone migration runner — the deployment runs this as an init container
|
|
9
|
+
// (`node migrate.js`) before the app starts. It uses only drizzle-orm + pg,
|
|
10
|
+
// both runtime dependencies, so it survives `npm prune --omit=dev` and needs no
|
|
11
|
+
// CLI or native engine in the image. The SQL files in ./drizzle are shipped as
|
|
12
|
+
// build assets alongside this bundle.
|
|
13
|
+
async function main() {
|
|
14
|
+
// A freshly generated service has no models yet, so there are no migrations
|
|
15
|
+
// to apply. Skip cleanly instead of failing the init container.
|
|
16
|
+
if (!existsSync(`${MIGRATIONS_FOLDER}/meta/_journal.json`)) {
|
|
17
|
+
// eslint-disable-next-line no-console
|
|
18
|
+
console.log('No migrations to apply.');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const connectionString = process.env.DATABASE_URL;
|
|
23
|
+
if (!connectionString) {
|
|
24
|
+
throw new Error('DATABASE_URL is not set.');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const pool = new Pool({ connectionString });
|
|
28
|
+
try {
|
|
29
|
+
await migrate(drizzle(pool), { migrationsFolder: MIGRATIONS_FOLDER });
|
|
30
|
+
// eslint-disable-next-line no-console
|
|
31
|
+
console.log('Migrations applied.');
|
|
32
|
+
} finally {
|
|
33
|
+
await pool.end();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
main().catch((err) => {
|
|
38
|
+
// eslint-disable-next-line no-console
|
|
39
|
+
console.error('Migration failed:', err);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
const { composePlugins, withNx } = require('@nx/webpack');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
// Nx plugins for webpack.
|
|
5
|
+
module.exports = composePlugins(
|
|
6
|
+
withNx({
|
|
7
|
+
target: 'node',
|
|
8
|
+
}),
|
|
9
|
+
(config) => {
|
|
10
|
+
// Emit a second bundle, migrate.js, from src/migrate.ts. The deployment runs
|
|
11
|
+
// it as an init container (`node migrate.js`) to apply Drizzle migrations
|
|
12
|
+
// before the app starts — using only runtime deps, no CLI, no native engine.
|
|
13
|
+
const mainEntry = config.entry.main;
|
|
14
|
+
const migrateEntry = path.resolve(__dirname, 'src/migrate.ts');
|
|
15
|
+
config.entry = {
|
|
16
|
+
...config.entry,
|
|
17
|
+
migrate:
|
|
18
|
+
mainEntry && typeof mainEntry === 'object' && !Array.isArray(mainEntry)
|
|
19
|
+
? { ...mainEntry, import: [migrateEntry] }
|
|
20
|
+
: [migrateEntry],
|
|
21
|
+
};
|
|
22
|
+
config.output = {
|
|
23
|
+
...config.output,
|
|
24
|
+
// Per-entry filenames so main.js and migrate.js don't collide.
|
|
25
|
+
filename: '[name].js',
|
|
26
|
+
...(process.env.NODE_ENV !== 'production' && {
|
|
27
|
+
clean: true,
|
|
28
|
+
devtoolModuleFilenameTemplate: '[absolute-resource-path]',
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
31
|
+
config.devtool = 'source-map';
|
|
32
|
+
// Update the webpack config as needed here.
|
|
33
|
+
// e.g. `config.plugins.push(new MyPlugin())`
|
|
34
|
+
return config;
|
|
35
|
+
},
|
|
36
|
+
);
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"type": "list",
|
|
57
57
|
"items": [
|
|
58
58
|
{ "value": "none", "label": "None — add a database later" },
|
|
59
|
-
{ "value": "postgres", "label": "PostgreSQL (
|
|
59
|
+
{ "value": "postgres", "label": "PostgreSQL (Drizzle)" },
|
|
60
60
|
{ "value": "mongo", "label": "MongoDB (Mongoose)" }
|
|
61
61
|
]
|
|
62
62
|
}
|
|
@@ -42,6 +42,6 @@ describe('MEVN Generator', () => {
|
|
|
42
42
|
expect(nginxConf).toContain('http://test-service:3333/');
|
|
43
43
|
|
|
44
44
|
expect(host.exists('apps/test-app/src/App.vue')).toBeTruthy();
|
|
45
|
-
expect(host.exists('apps/test-service/
|
|
45
|
+
expect(host.exists('apps/test-service/src/db/schema.ts')).toBeFalsy();
|
|
46
46
|
}, 30000);
|
|
47
47
|
});
|
|
@@ -41,6 +41,6 @@ describe('PEAN Generator', () => {
|
|
|
41
41
|
const nginxConf = host.read('apps/test-app/nginx.conf').toString();
|
|
42
42
|
expect(nginxConf).toContain('http://test-service:3333/');
|
|
43
43
|
|
|
44
|
-
expect(host.exists('apps/test-service/
|
|
44
|
+
expect(host.exists('apps/test-service/src/db/schema.ts')).toBeTruthy();
|
|
45
45
|
}, 30000);
|
|
46
46
|
});
|
|
@@ -41,6 +41,6 @@ describe('PERN Generator', () => {
|
|
|
41
41
|
const nginxConf = host.read('apps/test-app/nginx.conf').toString();
|
|
42
42
|
expect(nginxConf).toContain('http://test-service:3333/');
|
|
43
43
|
|
|
44
|
-
expect(host.exists('apps/test-service/
|
|
44
|
+
expect(host.exists('apps/test-service/src/db/schema.ts')).toBeTruthy();
|
|
45
45
|
}, 30000);
|
|
46
46
|
});
|
|
@@ -44,6 +44,6 @@ describe('PEVN Generator', () => {
|
|
|
44
44
|
expect(nginxConf).toContain('http://test-service:3333/');
|
|
45
45
|
|
|
46
46
|
expect(host.exists('apps/test-app/src/App.vue')).toBeTruthy();
|
|
47
|
-
expect(host.exists('apps/test-service/
|
|
47
|
+
expect(host.exists('apps/test-service/src/db/schema.ts')).toBeTruthy();
|
|
48
48
|
}, 30000);
|
|
49
49
|
});
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
generator client {
|
|
2
|
-
provider = "prisma-client-js"
|
|
3
|
-
// Scoped output prevents multiple postgres services in the same workspace from
|
|
4
|
-
// overwriting each other's generated client in the shared node_modules.
|
|
5
|
-
output = "../src/generated/prisma"
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
datasource db {
|
|
9
|
-
provider = "postgresql"
|
|
10
|
-
url = env("DATABASE_URL")
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// Add your models here.
|
|
14
|
-
// After editing, run: nx db:migrate <%= projectName %>
|
/package/src/generators/express-service/files-postgres/{prisma/migrations → drizzle}/.gitkeep
RENAMED
|
File without changes
|