@nestledjs/api 0.0.1 → 0.0.4
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 +11 -2
- package/src/core/files/models/src/lib/generate-models.ts__tmpl__ +21 -5
- package/src/setup/generator.ts +1 -0
- package/src/workspace-setup/generator.spec.ts +6 -3
- package/src/workspace-setup/generator.ts +20 -12
- package/src/workspace-setup/lib/helpers.ts +17 -10
- package/vite.config.mts +2 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestledjs/api",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"generators": "./generators.json",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -16,6 +16,15 @@
|
|
|
16
16
|
"access": "public"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"tslib": "^2.3.0"
|
|
19
|
+
"tslib": "^2.3.0",
|
|
20
|
+
"@nx/devkit": "21.2.0",
|
|
21
|
+
"@nx/js": "21.2.0",
|
|
22
|
+
"@prisma/internals": "^6.9.0",
|
|
23
|
+
"pluralize": "^8.0.0",
|
|
24
|
+
"dotenv": "16.4.5",
|
|
25
|
+
"pg": "^8.13.0"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"@nestledjs/utils": "0.0.2"
|
|
20
29
|
}
|
|
21
30
|
}
|
|
@@ -170,8 +170,15 @@ function generateModels(models: readonly any[], enums: readonly any[]): string {
|
|
|
170
170
|
const originalType = field.type
|
|
171
171
|
// const isRequired = field.isRequired // Natively supported by DMMF
|
|
172
172
|
|
|
173
|
-
//
|
|
174
|
-
|
|
173
|
+
// ALWAYS LOG: Print every field processed for debugging
|
|
174
|
+
console.log('*** FIELD DEBUG ***', {
|
|
175
|
+
model: model.name,
|
|
176
|
+
field: field.name,
|
|
177
|
+
kind: field.kind,
|
|
178
|
+
type: field.type,
|
|
179
|
+
isList: field.isList,
|
|
180
|
+
isRequired: field.isRequired,
|
|
181
|
+
});
|
|
175
182
|
|
|
176
183
|
let tsType = originalType
|
|
177
184
|
|
|
@@ -248,9 +255,18 @@ function generateModels(models: readonly any[], enums: readonly any[]): string {
|
|
|
248
255
|
// For simplicity, let's assume if it's a relation object, it's the Type itself.
|
|
249
256
|
// Partial is useful for inputs or update DTOs, less so for GQL ObjectTypes unless specifically designed.
|
|
250
257
|
let finalTsType = tsType
|
|
251
|
-
if (isRelation
|
|
252
|
-
//
|
|
253
|
-
finalTsType =
|
|
258
|
+
if (isRelation) {
|
|
259
|
+
// For relations, always use Partial<Type> (for both single and list)
|
|
260
|
+
finalTsType = `Partial<${tsType}>`;
|
|
261
|
+
// DEBUG: Log relation fields
|
|
262
|
+
console.log('DEBUG: Relation field detected:', {
|
|
263
|
+
model: model.name,
|
|
264
|
+
field: field.name,
|
|
265
|
+
kind: field.kind,
|
|
266
|
+
type: field.type,
|
|
267
|
+
isList: field.isList,
|
|
268
|
+
isRequired: field.isRequired,
|
|
269
|
+
});
|
|
254
270
|
}
|
|
255
271
|
|
|
256
272
|
// Never add '| null' to any field
|
package/src/setup/generator.ts
CHANGED
|
@@ -9,6 +9,7 @@ const {
|
|
|
9
9
|
runPrismaSeed,
|
|
10
10
|
runPrismaSetup,
|
|
11
11
|
runGraphQLTypeGeneration,
|
|
12
|
+
sleep,
|
|
12
13
|
} = vi.hoisted(() => {
|
|
13
14
|
return {
|
|
14
15
|
canConnect: vi.fn(),
|
|
@@ -19,6 +20,7 @@ const {
|
|
|
19
20
|
runPrismaSeed: vi.fn(),
|
|
20
21
|
runPrismaSetup: vi.fn(),
|
|
21
22
|
runGraphQLTypeGeneration: vi.fn(),
|
|
23
|
+
sleep: vi.fn(),
|
|
22
24
|
}
|
|
23
25
|
})
|
|
24
26
|
|
|
@@ -31,6 +33,7 @@ vi.mock('./lib/helpers', () => ({
|
|
|
31
33
|
runPrismaSeed,
|
|
32
34
|
runPrismaSetup,
|
|
33
35
|
runGraphQLTypeGeneration,
|
|
36
|
+
sleep,
|
|
34
37
|
}))
|
|
35
38
|
|
|
36
39
|
import generator from './generator'
|
|
@@ -47,7 +50,7 @@ describe('workspace-setup generator', () => {
|
|
|
47
50
|
|
|
48
51
|
it('should throw an error if DATABASE_URL is not on localhost', async () => {
|
|
49
52
|
process.env.DATABASE_URL = 'some-remote-db'
|
|
50
|
-
await expect(generator()).rejects.toThrow("
|
|
53
|
+
await expect(generator()).rejects.toThrow("Refusing to connect to non-local database: some-remote-db")
|
|
51
54
|
})
|
|
52
55
|
|
|
53
56
|
it('should run setup without docker if already connected', async () => {
|
|
@@ -58,7 +61,7 @@ describe('workspace-setup generator', () => {
|
|
|
58
61
|
|
|
59
62
|
expect(ensureDotEnv).toHaveBeenCalled()
|
|
60
63
|
expect(canConnect).toHaveBeenCalledWith('localhost:5432')
|
|
61
|
-
expect(ensureDockerIsRunning).
|
|
64
|
+
expect(ensureDockerIsRunning).toHaveBeenCalled()
|
|
62
65
|
expect(ensureDockerComposeIsRunning).not.toHaveBeenCalled()
|
|
63
66
|
expect(runPrismaSetup).toHaveBeenCalled()
|
|
64
67
|
expect(runGraphQLTypeGeneration).toHaveBeenCalled()
|
|
@@ -79,4 +82,4 @@ describe('workspace-setup generator', () => {
|
|
|
79
82
|
expect(runGraphQLTypeGeneration).toHaveBeenCalled()
|
|
80
83
|
expect(runPrismaSeed).toHaveBeenCalled()
|
|
81
84
|
})
|
|
82
|
-
})
|
|
85
|
+
})
|
|
@@ -5,45 +5,53 @@ import {
|
|
|
5
5
|
ensureDockerIsRunning,
|
|
6
6
|
ensureDotEnv,
|
|
7
7
|
log,
|
|
8
|
+
runGraphQLTypeGeneration,
|
|
8
9
|
runPrismaSeed,
|
|
9
10
|
runPrismaSetup,
|
|
10
|
-
|
|
11
|
+
sleep,
|
|
11
12
|
} from './lib/helpers'
|
|
12
13
|
|
|
13
14
|
export default async function () {
|
|
14
|
-
log('Setting up workspace
|
|
15
|
+
log('Setting up workspace')
|
|
15
16
|
|
|
16
17
|
ensureDotEnv()
|
|
17
18
|
require('dotenv').config()
|
|
18
|
-
|
|
19
|
+
|
|
19
20
|
const DATABASE_URL = process.env.DATABASE_URL
|
|
20
21
|
|
|
21
22
|
if (!DATABASE_URL) {
|
|
22
|
-
throw new Error(
|
|
23
|
+
throw new Error('Please provide DATABASE_URL env var')
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
if (!DATABASE_URL.includes('localhost')) {
|
|
26
|
-
throw new Error(`
|
|
27
|
+
throw new Error(`Refusing to connect to non-local database: ${DATABASE_URL}`)
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
ensureDockerIsRunning()
|
|
31
|
+
|
|
29
32
|
const connected = await canConnect(DATABASE_URL)
|
|
30
33
|
|
|
31
34
|
if (!connected) {
|
|
32
|
-
ensureDockerIsRunning()
|
|
33
35
|
await ensureDockerComposeIsRunning()
|
|
36
|
+
// Extra safety delay — DB might show "healthy" before accepting connections
|
|
37
|
+
await sleep(2000)
|
|
34
38
|
}
|
|
35
39
|
|
|
36
40
|
try {
|
|
41
|
+
log('Applying Prisma migrations...')
|
|
37
42
|
runPrismaSetup()
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
|
|
44
|
+
await sleep(2000)
|
|
45
|
+
|
|
41
46
|
log('Generating GraphQL types from Prisma schema...')
|
|
42
47
|
runGraphQLTypeGeneration()
|
|
43
|
-
|
|
48
|
+
|
|
49
|
+
log('Seeding database...')
|
|
44
50
|
runPrismaSeed()
|
|
45
|
-
|
|
51
|
+
|
|
52
|
+
log('✅ Workspace setup complete')
|
|
46
53
|
} catch (error) {
|
|
47
|
-
console.error('Error during workspace setup:', error.message)
|
|
54
|
+
console.error('❌ Error during workspace setup:', error.message)
|
|
55
|
+
process.exit(1)
|
|
48
56
|
}
|
|
49
57
|
}
|
|
@@ -2,6 +2,7 @@ import { execSync } from 'child_process'
|
|
|
2
2
|
import { existsSync, readFileSync, writeFileSync } from 'fs'
|
|
3
3
|
import { basename } from 'path'
|
|
4
4
|
import { Client } from 'pg'
|
|
5
|
+
import { workspaceRoot } from '@nx/devkit'
|
|
5
6
|
|
|
6
7
|
export const MAX_RETRIES = 30
|
|
7
8
|
export const WORKSPACE_NAME = basename(process.cwd())
|
|
@@ -40,10 +41,7 @@ export function ensureDockerIsRunning() {
|
|
|
40
41
|
|
|
41
42
|
export function isDockerComposeRunning(): boolean {
|
|
42
43
|
try {
|
|
43
|
-
const res = execSync(
|
|
44
|
-
stdio: ['inherit', 'inherit'],
|
|
45
|
-
})
|
|
46
|
-
|
|
44
|
+
const res = execSync('pnpm run docker:ps', { stdio: ['inherit', 'inherit'], cwd: workspaceRoot })
|
|
47
45
|
if (res) {
|
|
48
46
|
log('Docker Compose is Running')
|
|
49
47
|
return true
|
|
@@ -57,15 +55,23 @@ export function isDockerComposeRunning(): boolean {
|
|
|
57
55
|
export async function ensureDockerComposeIsRunning() {
|
|
58
56
|
const isRunning = isDockerComposeRunning()
|
|
59
57
|
if (isRunning) {
|
|
58
|
+
log('Docker Compose already running')
|
|
60
59
|
return true
|
|
61
60
|
}
|
|
62
61
|
|
|
62
|
+
log('Starting Docker Compose...')
|
|
63
|
+
try {
|
|
64
|
+
execSync('pnpm run docker:up', { stdio: 'inherit', cwd: workspaceRoot })
|
|
65
|
+
} catch (e) {
|
|
66
|
+
throw new Error(`Failed to start Docker Compose: ${e.message}`)
|
|
67
|
+
}
|
|
68
|
+
|
|
63
69
|
try {
|
|
64
|
-
execSync(`docker compose -f ${DOCKER_COMPOSE_FILE} up -d`, { stdio: 'ignore' })
|
|
65
70
|
await waitForConnection()
|
|
66
|
-
log('Docker Compose Started')
|
|
71
|
+
log('Docker Compose Started and DB connection confirmed')
|
|
67
72
|
} catch {
|
|
68
|
-
|
|
73
|
+
execSync('pnpm run docker:logs', { stdio: 'inherit', cwd: workspaceRoot })
|
|
74
|
+
throw new Error(`Database failed to start or respond in time`)
|
|
69
75
|
}
|
|
70
76
|
}
|
|
71
77
|
|
|
@@ -84,11 +90,12 @@ export function ensureDotEnv() {
|
|
|
84
90
|
|
|
85
91
|
export function runPrismaSetup() {
|
|
86
92
|
try {
|
|
87
|
-
execSync('pnpm prisma:apply', { stdio: '
|
|
93
|
+
execSync('pnpm prisma:apply', { stdio: 'inherit', cwd: workspaceRoot })
|
|
88
94
|
log('Prisma Setup is Done')
|
|
89
95
|
return true
|
|
90
|
-
} catch {
|
|
91
|
-
|
|
96
|
+
} catch (e) {
|
|
97
|
+
execSync('pnpm run docker:logs', { stdio: 'inherit', cwd: workspaceRoot })
|
|
98
|
+
throw new Error(`There was an issue running 'pnpm prisma:apply': ${e.message}`)
|
|
92
99
|
}
|
|
93
100
|
}
|
|
94
101
|
|
package/vite.config.mts
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
/// <reference types="vitest" />
|
|
2
2
|
import { defineConfig } from 'vite'
|
|
3
|
-
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin'
|
|
4
3
|
import { nxCopyAssetsPlugin } from '@nx/vite/plugins/nx-copy-assets.plugin'
|
|
5
|
-
import
|
|
4
|
+
import tsconfigPaths from 'vite-tsconfig-paths'
|
|
6
5
|
|
|
7
6
|
export default defineConfig(() => ({
|
|
8
7
|
root: __dirname,
|
|
9
8
|
cacheDir: '../../node_modules/.vite/generators/api',
|
|
10
|
-
plugins: [nxCopyAssetsPlugin(['*.md'])],
|
|
11
|
-
resolve: {
|
|
12
|
-
alias: {
|
|
13
|
-
'@nestledjs/utils': path.resolve(__dirname, '../../dist/generators/utils/src/index.js'),
|
|
14
|
-
},
|
|
15
|
-
},
|
|
9
|
+
plugins: [nxCopyAssetsPlugin(['*.md']), tsconfigPaths()],
|
|
16
10
|
// Uncomment this if you are using workers.
|
|
17
11
|
// worker: {
|
|
18
12
|
// plugins: [ nxViteTsPaths() ],
|