@nestledjs/api 0.1.13 → 0.2.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/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/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/generator.js +5 -0
- 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,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'),
|
|
@@ -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
|
|
package/src/prisma/generator.js
CHANGED
|
@@ -49,6 +49,11 @@ function generateLibraries(tree_1) {
|
|
|
49
49
|
if (!json.scripts['prisma:reset']) {
|
|
50
50
|
json.scripts['prisma:reset'] = 'pnpm prisma migrate reset && pnpm prisma:seed';
|
|
51
51
|
}
|
|
52
|
+
// Add db-update convenience script to regenerate CRUD, models, custom, and SDK
|
|
53
|
+
if (!json.scripts['db-update']) {
|
|
54
|
+
json.scripts['db-update'] =
|
|
55
|
+
'nx g @nestledjs/api:generate-crud && pnpm generate:models && nx g @nestledjs/api:custom && nx g @nestledjs/shared:sdk';
|
|
56
|
+
}
|
|
52
57
|
return json;
|
|
53
58
|
});
|
|
54
59
|
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":";;AAIA,oCA6DC;;AAjED,uCAAkG;AAClG,4CAAsD;AAGtD,SAA8B,iBAAiB;iEAAC,IAAU,EAAE,UAAoC,EAAE;QAChG,MAAM,gBAAgB,GAAG,IAAA,0BAAiB,EAAC,SAAS,EAAE,SAAS,CAAC,CAAA;QAChE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,KAAK,IAAI,CAAA;QAE5C,sBAAsB;QACtB,IAAA,mBAAU,EAAC,IAAI,EAAE,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE;YACxC,yBAAyB;YACzB,IAAI,CAAC,MAAM,GAAG;gBACZ,MAAM,EAAE,iCAAiC;gBACzC,IAAI,EAAE,+FAA+F;aACtG,CAAA;YACD,6DAA6D;YAC7D,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClB,IAAI,CAAC,OAAO,GAAG,EAAE,CAAA;YACnB,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACrC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC;oBAC7B,0GAA0G,CAAA;YAC9G,CAAC;YAED,0DAA0D;YAC1D,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;gBAClC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,2CAA2C,CAAA;YAC5E,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACpC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,qBAAqB,CAAA;YACxD,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;gBACnC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,oBAAoB,CAAA;YACtD,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACrC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,GAAG,sBAAsB,CAAA;YAC1D,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACpC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,oDAAoD,CAAA;YACvF,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;gBACjC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;oBACzB,0FAA0F,CAAA;YAC9F,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;gBACnC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,GAAG,2BAA2B,CAAA;YAC7D,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;gBAClC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,+CAA+C,CAAA;YAChF,CAAC;YACD,+EAA+E;YAC/E,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;oBACvB,uHAAuH,CAAA;YAC3H,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC,CAAC,CAAA;QAEF,MAAM,IAAA,2BAAmB,EAAC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,gBAAgB,CAAC,CAAA;QAEhF,MAAM,IAAA,oBAAW,EAAC,IAAI,CAAC,CAAA;QAEvB,OAAO,GAAG,EAAE;YACV,IAAA,4BAAmB,EAAC,IAAI,CAAC,CAAA;QAC3B,CAAC,CAAA;IACH,CAAC;CAAA"}
|
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
|
|