@nestledjs/api 0.1.13 → 1.0.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 +2 -2
- package/src/app/files/src/app.module.ts__tmpl__ +5 -4
- package/src/app/files/src/main.ts__tmpl__ +121 -23
- package/src/core/files/data-access/src/lib/models/core-paging.ts__tmpl__ +12 -0
- package/src/core/files/feature/src/lib/api-core-feature.module.ts__tmpl__ +0 -7
- package/src/core/files/models/src/lib/generate-models.ts__tmpl__ +56 -19
- package/src/core/files/models/src/lib/models/core-paging.model.ts__tmpl__ +12 -0
- package/src/custom/generator.js +8 -1
- package/src/custom/generator.js.map +1 -1
- package/src/generate-crud/files/data-access/src/lib/api-crud-data-access.service.ts__tmpl__ +11 -6
- package/src/prisma/files/config/prisma.config.ts__tmpl__ +12 -0
- package/src/prisma/generator.js +24 -6
- package/src/prisma/generator.js.map +1 -1
- package/src/setup/generator.js +2 -1
- package/src/setup/generator.js.map +1 -1
- package/src/user/files/data-access/src/lib/api-user-data-access.service.ts__tmpl__ +15 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nestledjs/api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"generators": "./generators.json",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -25,6 +25,6 @@
|
|
|
25
25
|
"pg": "^8.13.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"@nestledjs/utils": "0.
|
|
28
|
+
"@nestledjs/utils": "0.2.0"
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'
|
|
2
2
|
import { LoggerMiddleware } from './applogger.middleware'
|
|
3
|
-
import { ConfigModule } from '@nestjs/config'
|
|
4
|
-
import { configuration, validationSchema } from '@<%= npmScope %>/api/config'
|
|
3
|
+
import { ConfigModule as NestConfigModule } from '@nestjs/config'
|
|
4
|
+
import { ConfigModule as AppConfigModule, configuration, validationSchema } from '@<%= npmScope %>/api/config'
|
|
5
5
|
|
|
6
6
|
// Auto-generated modules with special functions
|
|
7
7
|
export const coreModules = [
|
|
@@ -24,7 +24,7 @@ export const appModules = [
|
|
|
24
24
|
|
|
25
25
|
@Module({
|
|
26
26
|
imports: [
|
|
27
|
-
|
|
27
|
+
NestConfigModule.forRoot({
|
|
28
28
|
load: [configuration],
|
|
29
29
|
validationSchema: validationSchema,
|
|
30
30
|
validationOptions: {
|
|
@@ -33,11 +33,12 @@ export const appModules = [
|
|
|
33
33
|
},
|
|
34
34
|
isGlobal: true,
|
|
35
35
|
}),
|
|
36
|
+
AppConfigModule,
|
|
36
37
|
...appModules,
|
|
37
38
|
],
|
|
38
39
|
})
|
|
39
40
|
export class AppModule implements NestModule {
|
|
40
41
|
configure(consumer: MiddlewareConsumer): void {
|
|
41
|
-
consumer.apply(LoggerMiddleware)
|
|
42
|
+
consumer.apply(LoggerMiddleware).forRoutes({ path: '*path', method: RequestMethod.ALL })
|
|
42
43
|
}
|
|
43
44
|
}
|
|
@@ -1,45 +1,143 @@
|
|
|
1
|
+
|
|
1
2
|
import { Logger } from '@nestjs/common'
|
|
2
3
|
import { NestFactory } from '@nestjs/core'
|
|
3
4
|
import { ConfigService } from '@<%= npmScope %>/api/config'
|
|
4
5
|
import cookieParser from 'cookie-parser'
|
|
6
|
+
import * as express from 'express'
|
|
7
|
+
import { NextFunction, Request, Response } from 'express'
|
|
8
|
+
import helmet from 'helmet'
|
|
5
9
|
|
|
6
10
|
import { AppModule } from './app.module'
|
|
7
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Middleware to redirect HTTP requests to HTTPS in production environments.
|
|
14
|
+
*/
|
|
15
|
+
function httpsRedirectMiddleware(
|
|
16
|
+
req: Request,
|
|
17
|
+
res: Response,
|
|
18
|
+
next: NextFunction,
|
|
19
|
+
) {
|
|
20
|
+
const isHttp = req.headers['x-forwarded-proto'] === 'http'
|
|
21
|
+
if (isHttp && process.env.NODE_ENV === 'production') {
|
|
22
|
+
const host = req.headers.host || req.hostname
|
|
23
|
+
Logger.debug(`[HttpsRedirect] Redirecting http://${host}${req.originalUrl} to https`)
|
|
24
|
+
return res.redirect(301, `https://${host}${req.originalUrl}`)
|
|
25
|
+
}
|
|
26
|
+
return next()
|
|
27
|
+
}
|
|
28
|
+
|
|
8
29
|
async function bootstrap() {
|
|
9
|
-
const app = await NestFactory.create(AppModule
|
|
30
|
+
const app = await NestFactory.create(AppModule, {
|
|
31
|
+
bodyParser: false, // Disable default parser for custom conditional parsing
|
|
32
|
+
})
|
|
33
|
+
|
|
10
34
|
const configService = app.get(ConfigService)
|
|
35
|
+
const globalPrefix = configService.prefix || 'api'
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Defines a list of known, valid API prefixes. This acts as an allow-list for the
|
|
39
|
+
* earlyRequestFilter, providing a "deny-by-default" security posture.
|
|
40
|
+
*
|
|
41
|
+
* !! IMPORTANT !!
|
|
42
|
+
* To expose a new REST controller, you MUST add its root path to this list.
|
|
43
|
+
* For example, for a `UsersController` at `/api/users`, add `/${globalPrefix}/users`.
|
|
44
|
+
*/
|
|
45
|
+
const VALID_API_PREFIXES = [
|
|
46
|
+
'/graphql', // Standard GraphQL endpoint
|
|
47
|
+
`/${globalPrefix}/uptime`, // Generic health-check endpoint
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Middleware to reject requests to non-existent or un-exposed API endpoints early.
|
|
52
|
+
* This prevents requests from even reaching the NestJS router if they are not on the allow-list.
|
|
53
|
+
*/
|
|
54
|
+
const earlyRequestFilter = (req: Request, res: Response, next: NextFunction) => {
|
|
55
|
+
const path = req.path
|
|
56
|
+
const isValidPath = VALID_API_PREFIXES.some(prefix => path.startsWith(prefix))
|
|
57
|
+
|
|
58
|
+
if (!isValidPath) {
|
|
59
|
+
Logger.debug(`[EarlyFilter] Rejecting request for un-exposed path: ${path}`)
|
|
60
|
+
return res.status(404).json({
|
|
61
|
+
statusCode: 404,
|
|
62
|
+
message: `Cannot ${req.method} ${path}`,
|
|
63
|
+
error: 'Not Found',
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return next()
|
|
68
|
+
}
|
|
11
69
|
|
|
12
|
-
//
|
|
13
|
-
const prefix = configService.prefix || 'api';
|
|
14
|
-
const port = configService.port || 3000;
|
|
15
|
-
const host = configService.host || 'localhost';
|
|
70
|
+
// --- Middleware & Security Setup ---
|
|
16
71
|
|
|
17
|
-
|
|
72
|
+
// 1. HTTPS Redirect: Enforce HTTPS in production.
|
|
73
|
+
app.use(httpsRedirectMiddleware)
|
|
18
74
|
|
|
19
|
-
//
|
|
20
|
-
|
|
75
|
+
// 2. Helmet: Apply security-related HTTP headers.
|
|
76
|
+
app.use(
|
|
77
|
+
helmet({
|
|
78
|
+
contentSecurityPolicy: process.env.NODE_ENV === 'production' ? undefined : false,
|
|
79
|
+
crossOriginEmbedderPolicy: false,
|
|
80
|
+
}),
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
// 3. Global Prefix: Set for all API routes.
|
|
84
|
+
app.setGlobalPrefix(globalPrefix)
|
|
85
|
+
|
|
86
|
+
// 4. CORS: Enable Cross-Origin Resource Sharing.
|
|
87
|
+
const origins = configService.apiCorsOrigins?.length
|
|
21
88
|
? configService.apiCorsOrigins
|
|
22
|
-
: ['http://localhost:4200']
|
|
89
|
+
: ['http://localhost:4200']
|
|
23
90
|
|
|
24
91
|
app.enableCors({
|
|
25
92
|
credentials: true,
|
|
26
|
-
origin: (origin, callback) => {
|
|
27
|
-
if (!origin) return callback(null, true)
|
|
28
|
-
if (origins.includes(origin))
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
return callback(new Error('Not allowed by CORS'));
|
|
93
|
+
origin: (origin: string, callback: (err: Error | null, allow?: boolean) => void) => {
|
|
94
|
+
if (!origin) return callback(null, true)
|
|
95
|
+
if (origins.includes(origin)) return callback(null, true)
|
|
96
|
+
return callback(new Error('Not allowed by CORS'))
|
|
32
97
|
},
|
|
33
|
-
})
|
|
34
|
-
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
// 5. Early Request Filter: Apply the "deny-by-default" filter.
|
|
101
|
+
app.use(earlyRequestFilter)
|
|
102
|
+
|
|
103
|
+
// 6. Conditional Body Parser: Handle raw bodies for webhooks, JSON for others.
|
|
104
|
+
app.use((req: Request, res: Response, next: NextFunction) => {
|
|
105
|
+
if (req.originalUrl.startsWith(`/${globalPrefix}/webhooks/`)) {
|
|
106
|
+
return express.raw({
|
|
107
|
+
type: '*/*',
|
|
108
|
+
verify: (req: Request, res, buf) => { (req as any).rawBody = buf },
|
|
109
|
+
})(req, res, next)
|
|
110
|
+
}
|
|
111
|
+
return express.json()(req, res, next)
|
|
112
|
+
})
|
|
113
|
+
app.use(express.urlencoded({ extended: true }))
|
|
114
|
+
|
|
115
|
+
// 7. Cookie Parser: Parse and optionally sign cookies.
|
|
116
|
+
const cookieSecret = configService.cookie.secret
|
|
117
|
+
if (!cookieSecret) {
|
|
118
|
+
if (process.env['NODE_ENV'] === 'production') {
|
|
119
|
+
Logger.error('Cookie secret is not configured in production. Set configService.cookie.secret.')
|
|
120
|
+
process.exit(1)
|
|
121
|
+
} else {
|
|
122
|
+
Logger.warn('Using default cookie secret in development. Set configService.cookie.secret for better security.')
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
app.use(cookieParser(cookieSecret || 'default-secret-in-dev'))
|
|
126
|
+
|
|
127
|
+
// --- Application Start ---
|
|
128
|
+
const port = process.env.PORT
|
|
129
|
+
? parseInt(process.env.PORT, 10)
|
|
130
|
+
: configService.port || 3000
|
|
35
131
|
|
|
36
|
-
await app.listen(port,
|
|
37
|
-
|
|
38
|
-
Logger.log(
|
|
132
|
+
await app.listen(port, () => {
|
|
133
|
+
const host = 'localhost'
|
|
134
|
+
Logger.log(`🚀 Application is running on: http://${host}:${port}/${globalPrefix}`)
|
|
135
|
+
Logger.log(`🚀 GraphQL endpoint is at: http://${host}:${port}/graphql`)
|
|
136
|
+
Logger.log(`🌿 Environment: ${process.env.NODE_ENV || 'development'}`)
|
|
39
137
|
})
|
|
40
138
|
}
|
|
41
139
|
|
|
42
140
|
bootstrap().catch((error) => {
|
|
43
|
-
Logger.error('Failed to start the application', error)
|
|
44
|
-
process.exit(1)
|
|
45
|
-
})
|
|
141
|
+
Logger.error('❌ Failed to start the application', error)
|
|
142
|
+
process.exit(1)
|
|
143
|
+
})
|
|
@@ -5,6 +5,9 @@ export class CorePaging {
|
|
|
5
5
|
@Field({ nullable: true })
|
|
6
6
|
total?: number
|
|
7
7
|
|
|
8
|
+
@Field({ nullable: true })
|
|
9
|
+
filteredTotal?: number
|
|
10
|
+
|
|
8
11
|
@Field({ nullable: true })
|
|
9
12
|
count?: number
|
|
10
13
|
|
|
@@ -16,4 +19,13 @@ export class CorePaging {
|
|
|
16
19
|
|
|
17
20
|
@Field({ nullable: true })
|
|
18
21
|
skip?: number
|
|
22
|
+
|
|
23
|
+
@Field({ nullable: true })
|
|
24
|
+
pages?: number
|
|
25
|
+
|
|
26
|
+
@Field({ nullable: true })
|
|
27
|
+
hasNext?: boolean
|
|
28
|
+
|
|
29
|
+
@Field({ nullable: true })
|
|
30
|
+
hasPrev?: boolean
|
|
19
31
|
}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo'
|
|
2
2
|
import { Module } from '@nestjs/common'
|
|
3
|
-
import { ConfigModule } from '@nestjs/config'
|
|
4
3
|
import { GraphQLModule } from '@nestjs/graphql'
|
|
5
4
|
import { join } from 'path'
|
|
6
5
|
import { Request, Response } from 'express'
|
|
7
6
|
import { apiCorePubSub } from '@<%= npmScope %>/api/core/data-access'
|
|
8
|
-
import { configuration, validationSchema } from '@<%= npmScope %>/api/config'
|
|
9
7
|
import { Context } from 'graphql-ws'
|
|
10
8
|
import { ApiCoreFeatureController } from './api-core-feature.controller'
|
|
11
9
|
import { ApiCoreFeatureResolver } from './api-core-feature.resolver'
|
|
@@ -23,11 +21,6 @@ const redisPubSubProvider = {
|
|
|
23
21
|
|
|
24
22
|
@Module({
|
|
25
23
|
imports: [
|
|
26
|
-
ConfigModule.forRoot({
|
|
27
|
-
isGlobal: true,
|
|
28
|
-
load: [configuration],
|
|
29
|
-
validationSchema,
|
|
30
|
-
}),
|
|
31
24
|
GraphQLModule.forRoot<ApolloDriverConfig>({
|
|
32
25
|
driver: ApolloDriver,
|
|
33
26
|
autoSchemaFile: join(process.cwd(), 'api-schema.graphql'),
|
|
@@ -3,6 +3,16 @@ import { join } from 'path'
|
|
|
3
3
|
import { execSync } from 'child_process'
|
|
4
4
|
import { getDMMF } from '@prisma/internals'
|
|
5
5
|
|
|
6
|
+
function extractQuotedStrings(input: string): string[] {
|
|
7
|
+
const values: string[] = []
|
|
8
|
+
const regex = /['"`]([^'"`]+)['"`]/g
|
|
9
|
+
let match: RegExpExecArray | null
|
|
10
|
+
while ((match = regex.exec(input)) !== null) {
|
|
11
|
+
values.push(match[1])
|
|
12
|
+
}
|
|
13
|
+
return values
|
|
14
|
+
}
|
|
15
|
+
|
|
6
16
|
// Find project root and get schema path from package.json
|
|
7
17
|
function findProjectRoot(startDir: string): string {
|
|
8
18
|
try {
|
|
@@ -20,24 +30,37 @@ function findProjectRoot(startDir: string): string {
|
|
|
20
30
|
}
|
|
21
31
|
}
|
|
22
32
|
|
|
23
|
-
// Determine the correct prisma import path based on
|
|
33
|
+
// Determine the correct prisma import path based on configuration
|
|
24
34
|
function getPrismaImportPath(): string {
|
|
25
35
|
try {
|
|
26
36
|
const projectRoot = findProjectRoot(__dirname)
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
37
|
+
const cfgCandidates = ['prisma.config.ts']
|
|
38
|
+
let schemaPathSetting = ''
|
|
39
|
+
for (const cfg of cfgCandidates) {
|
|
40
|
+
const configPath = join(projectRoot, cfg)
|
|
41
|
+
if (existsSync(configPath)) {
|
|
42
|
+
const content = readFileSync(configPath, 'utf-8')
|
|
43
|
+
const joinMatch = content.match(/schema\s*:\s*path\.join\(([^)]+)\)/)
|
|
44
|
+
if (joinMatch && joinMatch[1]) {
|
|
45
|
+
const parts = extractQuotedStrings(joinMatch[1])
|
|
46
|
+
if (parts.length) schemaPathSetting = parts.join('/')
|
|
47
|
+
}
|
|
48
|
+
if (!schemaPathSetting) {
|
|
49
|
+
const strMatch = content.match(/schema\s*:\s*['"`]([^'"`]+)['"`]/)
|
|
50
|
+
if (strMatch && strMatch[1]) schemaPathSetting = strMatch[1]
|
|
51
|
+
}
|
|
52
|
+
if (schemaPathSetting) break
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (!schemaPathSetting) {
|
|
56
|
+
const packageJsonPath = join(projectRoot, 'package.json')
|
|
57
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'))
|
|
58
|
+
schemaPathSetting = packageJson.prisma?.schema || ''
|
|
59
|
+
}
|
|
31
60
|
|
|
32
|
-
|
|
33
|
-
if (
|
|
34
|
-
schemaPathSetting.includes('libs/api/prisma') ||
|
|
35
|
-
schemaPathSetting.includes('prisma/src/lib')
|
|
36
|
-
) {
|
|
61
|
+
if (schemaPathSetting.includes('libs/api/prisma') || schemaPathSetting.includes('prisma/src/lib')) {
|
|
37
62
|
return '@<%= npmScope %>/api/prisma'
|
|
38
63
|
}
|
|
39
|
-
|
|
40
|
-
// Fallback to the original path if not explicitly the new structure
|
|
41
64
|
return '@<%= npmScope %>/api/core/data-access'
|
|
42
65
|
} catch (error) {
|
|
43
66
|
console.error('Error determining Prisma import path:', error)
|
|
@@ -46,20 +69,34 @@ function getPrismaImportPath(): string {
|
|
|
46
69
|
}
|
|
47
70
|
}
|
|
48
71
|
|
|
49
|
-
// Get schema directory path from
|
|
72
|
+
// Get schema directory path from configuration
|
|
50
73
|
function getPrismaSchemaDir(): string {
|
|
51
74
|
// Renamed
|
|
52
75
|
try {
|
|
53
76
|
const projectRoot = findProjectRoot(__dirname)
|
|
77
|
+
const cfgCandidates = ['prisma.config.ts']
|
|
78
|
+
for (const cfg of cfgCandidates) {
|
|
79
|
+
const configPath = join(projectRoot, cfg)
|
|
80
|
+
if (existsSync(configPath)) {
|
|
81
|
+
const content = readFileSync(configPath, 'utf-8')
|
|
82
|
+
const joinMatch = content.match(/schema\s*:\s*path\.join\(([^)]+)\)/)
|
|
83
|
+
if (joinMatch && joinMatch[1]) {
|
|
84
|
+
const parts = extractQuotedStrings(joinMatch[1])
|
|
85
|
+
if (parts.length) return join(projectRoot, parts.join('/'))
|
|
86
|
+
}
|
|
87
|
+
const strMatch = content.match(/schema\s*:\s*['"`]([^'"`]+)['"`]/)
|
|
88
|
+
if (strMatch && strMatch[1]) {
|
|
89
|
+
return join(projectRoot, strMatch[1])
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Fallback to old package.json field if config not found
|
|
54
94
|
const packageJsonPath = join(projectRoot, 'package.json')
|
|
55
95
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'))
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
throw new Error('prisma.schema path not found in package.json')
|
|
96
|
+
if (packageJson.prisma?.schema) {
|
|
97
|
+
return join(projectRoot, packageJson.prisma.schema)
|
|
59
98
|
}
|
|
60
|
-
|
|
61
|
-
// Join the project root with the schema path (which should be a directory)
|
|
62
|
-
return join(projectRoot, packageJson.prisma.schema)
|
|
99
|
+
throw new Error('Prisma schema path not found in config')
|
|
63
100
|
} catch (error) {
|
|
64
101
|
console.error('Error getting Prisma schema directory path:', error)
|
|
65
102
|
// Fallback to the old directory path for backward compatibility
|
|
@@ -5,6 +5,9 @@ export class CorePaging {
|
|
|
5
5
|
@Field({ nullable: true })
|
|
6
6
|
total?: number
|
|
7
7
|
|
|
8
|
+
@Field({ nullable: true })
|
|
9
|
+
filteredTotal?: number
|
|
10
|
+
|
|
8
11
|
@Field({ nullable: true })
|
|
9
12
|
count?: number
|
|
10
13
|
|
|
@@ -22,4 +25,13 @@ export class CorePaging {
|
|
|
22
25
|
|
|
23
26
|
@Field({ nullable: true })
|
|
24
27
|
totalSum?: number
|
|
28
|
+
|
|
29
|
+
@Field({ nullable: true })
|
|
30
|
+
pages?: number
|
|
31
|
+
|
|
32
|
+
@Field({ nullable: true })
|
|
33
|
+
hasNext?: boolean
|
|
34
|
+
|
|
35
|
+
@Field({ nullable: true })
|
|
36
|
+
hasPrev?: boolean
|
|
25
37
|
}
|
package/src/custom/generator.js
CHANGED
|
@@ -92,6 +92,7 @@ function updateIndexFileAdditively(tree, indexPath, newExports) {
|
|
|
92
92
|
}
|
|
93
93
|
function generateCustomFiles(tree, customLibraryRoot, models, npmScope, dependencies) {
|
|
94
94
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
95
|
+
var _a, _b;
|
|
95
96
|
const defaultDir = dependencies.join(customLibraryRoot, 'src/lib/default');
|
|
96
97
|
const pluginsDir = dependencies.join(customLibraryRoot, 'src/lib/plugins');
|
|
97
98
|
yield ensureDirExists(tree, defaultDir);
|
|
@@ -99,7 +100,13 @@ function generateCustomFiles(tree, customLibraryRoot, models, npmScope, dependen
|
|
|
99
100
|
// Create empty index.ts in pluginsDir for custom plugins (only if it doesn't exist)
|
|
100
101
|
const pluginsIndexPath = dependencies.join(pluginsDir, 'index.ts');
|
|
101
102
|
if (!tree.exists(pluginsIndexPath)) {
|
|
102
|
-
tree.write(pluginsIndexPath,
|
|
103
|
+
tree.write(pluginsIndexPath, "export const customPlugins = []\n");
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
const existingPluginsIndex = (_b = (_a = tree.read(pluginsIndexPath)) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : '';
|
|
107
|
+
if (existingPluginsIndex.trim() === '') {
|
|
108
|
+
tree.write(pluginsIndexPath, "export const customPlugins = []\n");
|
|
109
|
+
}
|
|
103
110
|
}
|
|
104
111
|
for (const model of models) {
|
|
105
112
|
const kebabModel = toKebabCase(model.modelName);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../generators/api/src/custom/generator.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../generators/api/src/custom/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -172,18 +172,23 @@ export class ApiCrudDataAccessService {
|
|
|
172
172
|
|
|
173
173
|
async <%= (model.pluralModelName === model.modelName ? model.pluralModelName + 'List' : model.pluralModelName).charAt(0).toLowerCase() + (model.pluralModelName === model.modelName ? model.pluralModelName + 'List' : model.pluralModelName).slice(1) %>Count(input?: dto.List<%= model.modelName %>Input) {
|
|
174
174
|
const total = await this.data['<%= model.modelPropertyName %>'].count()
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
});
|
|
178
|
-
const take = input?.take ?? 10
|
|
179
|
-
const skip = input?.skip ?? 0
|
|
175
|
+
const { where, take = 10, skip = 0 } = this.data.filter(input)
|
|
176
|
+
const filteredTotal = await this.data['<%= model.modelPropertyName %>'].count({ where })
|
|
180
177
|
const page = Math.floor(skip / take)
|
|
181
|
-
|
|
178
|
+
const pages = take > 0 ? Math.ceil(filteredTotal / take) : 0
|
|
179
|
+
const hasNext = skip + take < filteredTotal
|
|
180
|
+
const hasPrev = skip > 0
|
|
181
|
+
const count = Math.max(0, Math.min(take, filteredTotal - skip))
|
|
182
|
+
return {
|
|
182
183
|
take,
|
|
183
184
|
skip,
|
|
184
185
|
page,
|
|
186
|
+
pages,
|
|
187
|
+
hasNext,
|
|
188
|
+
hasPrev,
|
|
185
189
|
count,
|
|
186
190
|
total,
|
|
191
|
+
filteredTotal,
|
|
187
192
|
}
|
|
188
193
|
}
|
|
189
194
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import 'dotenv/config'
|
|
2
|
+
import * as path from 'node:path'
|
|
3
|
+
import { defineConfig } from 'prisma/config'
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
schema: path.join('libs', 'api', 'prisma', 'src', 'lib', 'schemas'),
|
|
7
|
+
migrations: {
|
|
8
|
+
seed: 'ts-node --project libs/api/prisma/tsconfig.lib.json libs/api/prisma/src/lib/seed/seed.ts',
|
|
9
|
+
},
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
|
package/src/prisma/generator.js
CHANGED
|
@@ -8,13 +8,26 @@ function generateLibraries(tree_1) {
|
|
|
8
8
|
return tslib_1.__awaiter(this, arguments, void 0, function* (tree, options = {}) {
|
|
9
9
|
const templateRootPath = (0, devkit_1.joinPathFragments)(__dirname, './files');
|
|
10
10
|
const overwrite = options.overwrite === true;
|
|
11
|
-
//
|
|
11
|
+
// Create prisma.config.ts at workspace root via template (idempotent)
|
|
12
|
+
if (!tree.exists('prisma.config.ts')) {
|
|
13
|
+
(0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(templateRootPath, 'config'), '.', { tmpl: '' });
|
|
14
|
+
// Ensure rename from template path to root file name if needed
|
|
15
|
+
if (!tree.exists('prisma.config.ts') && tree.exists('./prisma.config.ts__tmpl__')) {
|
|
16
|
+
tree.rename('./prisma.config.ts__tmpl__', 'prisma.config.ts');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
// Update package.json scripts (remove deprecated prisma.schema field if present)
|
|
12
20
|
(0, devkit_1.updateJson)(tree, 'package.json', (json) => {
|
|
13
|
-
|
|
14
|
-
json.prisma
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
21
|
+
var _a;
|
|
22
|
+
if ((_a = json.prisma) === null || _a === void 0 ? void 0 : _a.schema) {
|
|
23
|
+
delete json.prisma.schema;
|
|
24
|
+
}
|
|
25
|
+
if (!json.prisma) {
|
|
26
|
+
json.prisma = {};
|
|
27
|
+
}
|
|
28
|
+
if (!json.prisma.seed) {
|
|
29
|
+
json.prisma.seed = 'ts-node --project libs/api/prisma/tsconfig.lib.json libs/api/prisma/src/lib/seed/seed.ts';
|
|
30
|
+
}
|
|
18
31
|
// Add GraphQL model generation script for the 'core' library
|
|
19
32
|
if (!json.scripts) {
|
|
20
33
|
json.scripts = {};
|
|
@@ -49,6 +62,11 @@ function generateLibraries(tree_1) {
|
|
|
49
62
|
if (!json.scripts['prisma:reset']) {
|
|
50
63
|
json.scripts['prisma:reset'] = 'pnpm prisma migrate reset && pnpm prisma:seed';
|
|
51
64
|
}
|
|
65
|
+
// Add db-update convenience script to regenerate CRUD, models, custom, and SDK
|
|
66
|
+
if (!json.scripts['db-update']) {
|
|
67
|
+
json.scripts['db-update'] =
|
|
68
|
+
'nx g @nestledjs/api:generate-crud && pnpm generate:models && nx g @nestledjs/api:custom && nx g @nestledjs/shared:sdk';
|
|
69
|
+
}
|
|
52
70
|
return json;
|
|
53
71
|
});
|
|
54
72
|
yield (0, utils_1.apiLibraryGenerator)(tree, { name: 'prisma', overwrite }, templateRootPath);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../generators/api/src/prisma/generator.ts"],"names":[],"mappings":";;AAIA,
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../generators/api/src/prisma/generator.ts"],"names":[],"mappings":"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"}
|
package/src/setup/generator.js
CHANGED
|
@@ -41,6 +41,7 @@ function apiSetupGenerator(tree) {
|
|
|
41
41
|
'graphql-redis-subscriptions': '^2.7.0',
|
|
42
42
|
ioredis: '^5.6.1',
|
|
43
43
|
'cookie-parser': '^1.4.7',
|
|
44
|
+
helmet: '^8.1.0',
|
|
44
45
|
'passport-jwt': '^4.0.1',
|
|
45
46
|
}, {
|
|
46
47
|
nx: '21.2.3',
|
|
@@ -54,7 +55,7 @@ function apiSetupGenerator(tree) {
|
|
|
54
55
|
'@swc-node/register': '~1.10.10',
|
|
55
56
|
'@swc/cli': '~0.7.7',
|
|
56
57
|
'@swc/core': '~1.12.1',
|
|
57
|
-
'@types/cookie-parser': '^1.4.
|
|
58
|
+
'@types/cookie-parser': '^1.4.9',
|
|
58
59
|
'@types/express': '^5.0.3',
|
|
59
60
|
'@types/nodemailer': '^6.4.7',
|
|
60
61
|
'@types/passport-jwt': '^4.0.1',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../generators/api/src/setup/generator.ts"],"names":[],"mappings":";;AASA,
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../generators/api/src/setup/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,10 +25,23 @@ export class ApiUserDataAccessService {
|
|
|
25
25
|
): Promise<CorePaging> {
|
|
26
26
|
await this.data.ensureAdminUser(adminId);
|
|
27
27
|
const total = await this.data.user.count();
|
|
28
|
+
const { where, take = 20, skip = 0 } = this.data.filter(paging);
|
|
29
|
+
const filteredTotal = await this.data.user.count({ where });
|
|
30
|
+
const page = Math.floor(skip / take);
|
|
31
|
+
const pages = take > 0 ? Math.ceil(filteredTotal / take) : 0;
|
|
32
|
+
const hasNext = skip + take < filteredTotal;
|
|
33
|
+
const hasPrev = skip > 0;
|
|
34
|
+
const count = Math.max(0, Math.min(take, filteredTotal - skip));
|
|
28
35
|
return {
|
|
29
|
-
take
|
|
30
|
-
skip
|
|
36
|
+
take,
|
|
37
|
+
skip,
|
|
38
|
+
page,
|
|
39
|
+
pages,
|
|
40
|
+
hasNext,
|
|
41
|
+
hasPrev,
|
|
42
|
+
count,
|
|
31
43
|
total,
|
|
44
|
+
filteredTotal,
|
|
32
45
|
};
|
|
33
46
|
}
|
|
34
47
|
|