@impactor/nest 3.0.0 → 3.0.2
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/README.md +89 -6
- package/index.d.ts +1 -0
- package/package.json +7 -5
- package/src/configs/app.d.ts +2 -0
- package/src/configs/app.js +1 -0
- package/src/configs/app.js.map +1 -1
- package/src/create-app.js +10 -1
- package/src/create-app.js.map +1 -1
- package/src/decorators/entity.decorator.d.ts +6 -0
- package/src/decorators/entity.decorator.js +66 -0
- package/src/decorators/entity.decorator.js.map +1 -0
- package/src/nest-swagger-metadata.js +57 -17
- package/src/nest-swagger-metadata.js.map +1 -1
- package/src/register-entities.d.ts +1 -0
- package/src/register-entities.js +118 -0
- package/src/register-entities.js.map +1 -0
- package/src/utils/typeorm-to-swagger.d.ts +3 -0
- package/src/utils/typeorm-to-swagger.js +315 -0
- package/src/utils/typeorm-to-swagger.js.map +1 -0
package/README.md
CHANGED
|
@@ -2,6 +2,13 @@ utils for NestJs
|
|
|
2
2
|
|
|
3
3
|
## Decorators
|
|
4
4
|
|
|
5
|
+
## @Controller()
|
|
6
|
+
|
|
7
|
+
Quickly generate all API endpoints and Crud operations of a controller without a single line of code.
|
|
8
|
+
It also generate Swagger decorators for all routes.
|
|
9
|
+
|
|
10
|
+
[Read more...](./README.controller.md)
|
|
11
|
+
|
|
5
12
|
## @Prop()
|
|
6
13
|
|
|
7
14
|
a param decorator that extracts a field from the request
|
|
@@ -30,20 +37,96 @@ and add the suitable Swagger's docs.
|
|
|
30
37
|
|
|
31
38
|
```
|
|
32
39
|
|
|
33
|
-
##
|
|
40
|
+
## Exceptions
|
|
34
41
|
|
|
35
|
-
|
|
36
|
-
It also generate Swagger decorators for all routes.
|
|
42
|
+
RPC exceptions equivalent to the corresponding HTTP exceptions, such as:
|
|
37
43
|
|
|
38
|
-
|
|
44
|
+
- `RpcBadRequestException` -> `HttpBadRequestException`
|
|
45
|
+
- `RpcConflictException` -> `HttpConflictException`
|
|
46
|
+
- `RpcInternalServerErrorException` -> `HttpInternalServerErrorException`
|
|
47
|
+
- `RpcMethodNotAllowedException` -> `HttpMethodNotAllowedException`
|
|
48
|
+
- `RpcNotFoundException` -> `HttpNotFoundException`
|
|
49
|
+
- `RpcNotImplementedException` -> `HttpNotImplementedException`
|
|
50
|
+
- `RpcUnauthorizedException` -> `HttpUnauthorizedException`
|
|
51
|
+
|
|
52
|
+
Use these exceptions in microservices instead of the HTTP exceptions Nest provides, so you can handle RPC exception correctly.
|
|
53
|
+
|
|
54
|
+
usage:
|
|
55
|
+
|
|
56
|
+
inside microservices:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
export function doAction() {
|
|
60
|
+
// if a bad request is received
|
|
61
|
+
throw new RpcBadRequestException(); // correct
|
|
62
|
+
throw new HttpBadRequestException(); // wrong
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
if you returned an instance of HttpException, Nest will handle it just like any other http, causes the exception not propagated to the microservice that requested the action and your response will be lost.
|
|
67
|
+
|
|
68
|
+
Using RPC exceptions instead, with the RPC exception filter we provide, you can handle this type of exceptions correctly.
|
|
39
69
|
|
|
40
70
|
## Exception Filters
|
|
41
71
|
|
|
42
|
-
-
|
|
72
|
+
- RPC: convert Error to RpcException
|
|
43
73
|
- WS: convert Error to WsException
|
|
44
|
-
- TypeORM
|
|
74
|
+
- TypeORM: detect TypeORM exceptions and handle them.
|
|
75
|
+
|
|
76
|
+
## Guards
|
|
77
|
+
|
|
78
|
+
### Auth guard
|
|
79
|
+
|
|
80
|
+
- `JwtAuthGuard`: inspects the JWT token and guard your routes based on this token.
|
|
81
|
+
|
|
82
|
+
it also checks the specified roles to determine weather to pass the guard or not.
|
|
83
|
+
|
|
84
|
+
Thi guard also provides the following decorators:
|
|
85
|
+
|
|
86
|
+
- `@Public()` and `@Private()`: to allow or disallow un-authenticated users to use the route. You can use it in the class-level or route-level.
|
|
87
|
+
- `@Roles()`: if provided, the guard checks the user roles before allowing him to use the route. you need to provide the user role when creating `req.user` object.
|
|
88
|
+
|
|
89
|
+
### example
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
// app.module.ts
|
|
93
|
+
import { JwtAuthGuard } from "@impactor/nest"
|
|
94
|
+
|
|
95
|
+
@Module({
|
|
96
|
+
imports: [...],
|
|
97
|
+
providers: [
|
|
98
|
+
AppService,
|
|
99
|
+
{
|
|
100
|
+
provide: APP_GUARD,
|
|
101
|
+
useClass: JwtAuthGuard, //<---
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
// users.controller.ts
|
|
109
|
+
import { Public, Private } from "@impactor/nest";
|
|
110
|
+
|
|
111
|
+
@Controller()
|
|
112
|
+
@Private() //<--- lock all routes
|
|
113
|
+
export class UsersController {
|
|
114
|
+
@Pot()
|
|
115
|
+
addUser() {}
|
|
116
|
+
|
|
117
|
+
@Get()
|
|
118
|
+
@Public() //<--- allow this route
|
|
119
|
+
getUserById() {}
|
|
120
|
+
|
|
121
|
+
@Get()
|
|
122
|
+
@Roles("admin", "moderators") //<--- limit access to admins and moderators only
|
|
123
|
+
getAllUsers() {}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
45
126
|
|
|
46
127
|
## Features
|
|
47
128
|
|
|
48
129
|
- `BasicModule`
|
|
130
|
+
- `createApp()`: create a Nest app [learn more](./README.createApp.md)
|
|
49
131
|
- `createMicroservice()`: create a microservice
|
|
132
|
+
- `generate-metadata`: generate Swagger metadata
|
package/index.d.ts
CHANGED
|
@@ -38,3 +38,4 @@ export * from './src/decorators/controller/route-handler';
|
|
|
38
38
|
export * from './src/decorators/controller/services/crud-typeorm.service';
|
|
39
39
|
export * from './src/decorators/controller/types';
|
|
40
40
|
export * from './src/decorators/controller/utils/merge-options';
|
|
41
|
+
export * from './src/decorators/entity.decorator';
|
package/package.json
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@impactor/nest",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "utils for NestJs. Automatically generate APIs and crud operators for NestJs apps",
|
|
6
6
|
"private": false,
|
|
7
7
|
"publishConfig": {
|
|
8
|
-
"access": "public"
|
|
8
|
+
"access": "public",
|
|
9
|
+
"directory": "dist",
|
|
10
|
+
"linkDirectory": false
|
|
9
11
|
},
|
|
10
12
|
"nx": {
|
|
11
13
|
"projectType": "library",
|
|
@@ -55,11 +57,11 @@
|
|
|
55
57
|
"typeorm": "^0.3.28",
|
|
56
58
|
"winston": "^3.19.0",
|
|
57
59
|
"@fastify/multipart": "^9.3.0",
|
|
58
|
-
"@impactor/javascript": "3.0.2",
|
|
59
|
-
"@impactor/nodejs": "3.0.2",
|
|
60
60
|
"@nestjs/passport": "^11.0.5",
|
|
61
61
|
"merge-anything": "^6.0.6",
|
|
62
|
-
"reflect-metadata": "^0.2.2"
|
|
62
|
+
"reflect-metadata": "^0.2.2",
|
|
63
|
+
"@impactor/javascript": "^3.0.2",
|
|
64
|
+
"@impactor/nodejs": "^3.0.2"
|
|
63
65
|
},
|
|
64
66
|
"devDependencies": {
|
|
65
67
|
"@types/amqplib": "^0.10.8",
|
package/src/configs/app.d.ts
CHANGED
|
@@ -12,9 +12,11 @@ export interface IAppConfig extends NestApplicationOptions {
|
|
|
12
12
|
prefix?: string | IPrefix;
|
|
13
13
|
versioning?: VersioningOptions;
|
|
14
14
|
swagger?: Partial<Omit<OpenAPIObject, 'paths'>>;
|
|
15
|
+
swaggerPath?: string;
|
|
15
16
|
multipart?: boolean;
|
|
16
17
|
validationPipe?: ValidationPipeOptions;
|
|
17
18
|
package?: string | Record<string, unknown>;
|
|
19
|
+
registerEntities?: boolean | Function[];
|
|
18
20
|
onServerRun?: (app: IApp) => void | Promise<void>;
|
|
19
21
|
onServerError?: (error: Error, app: IApp) => void | Promise<void>;
|
|
20
22
|
}
|
package/src/configs/app.js
CHANGED
package/src/configs/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/configs/app.ts"],"sourcesContent":["import { logger } from '../utils/logger';\nimport {\n ValidationPipeOptions,\n type VersioningOptions,\n VersioningType,\n} from '@nestjs/common';\nimport type {\n GlobalPrefixOptions,\n NestApplicationOptions,\n} from '@nestjs/common/interfaces';\nimport { NestExpressApplication } from '@nestjs/platform-express';\nimport { NestFastifyApplication } from '@nestjs/platform-fastify/interfaces';\nimport { OpenAPIObject } from '@nestjs/swagger';\n\nexport type IApp = NestFastifyApplication | NestExpressApplication;\nexport interface IPrefix extends GlobalPrefixOptions {\n prefix: string;\n}\n\n// todo: adaptor: fastify | express = fastify\nexport interface IAppConfig extends NestApplicationOptions {\n /**\n * The port that the app will listen to\n * if not provided, `app.listen()` is not called\n */\n port?: string | number;\n /** the global prefix for every HTTP route path. see Nest.setGlobalPrefix() */\n prefix?: string | IPrefix;\n versioning?: VersioningOptions;\n /**\n * Swagger API spec.\n * https://spec.openapis.org/oas\n */\n swagger?: Partial<Omit<OpenAPIObject, 'paths'>>;\n /** whether to enable parsing multiPart */\n multipart?: boolean;\n /**\n * validation pipe options\n */\n validationPipe?: ValidationPipeOptions;\n /**\n * package.json absolute path or object, or the path of the project root dir\n * used to extract info for Swagger docs, such as title, description, and version.\n */\n // todo: import IPackage interface from @impactor/javascript (move from @impactor/nx-manager)\n package?: string | Record<string, unknown>;\n /**\n * a hook that executed when the server runs and listens to the specified port\n * get the server by app.getHttpServer()\n */\n onServerRun?: (app: IApp) => void | Promise<void>;\n onServerError?: (error: Error, app: IApp) => void | Promise<void>;\n}\n\n/**\n * the default app configs\n */\nexport const appConfig: IAppConfig = {\n port: process.env.PORT,\n prefix: { prefix: 'api', exclude: ['sitemap.xml', 'robots.txt'] },\n // or use `DocumentBuilder` from \"@nestjs/swagger\"\n swagger: {\n openapi: '3.1.0',\n info: { title: 'API', version: '1.0' },\n components: {\n securitySchemes: {\n // add `@ApiBearerAuth()` to controllers which you need to check their bearer auth header\n bearer: {\n scheme: 'bearer',\n bearerFormat: 'JWT',\n type: 'http',\n },\n },\n },\n },\n versioning: {\n defaultVersion: ['1.0'],\n type: VersioningType.URI,\n },\n // cors: {\n // // todo: add APP_URL or localhost by default\n // origin: '*',\n // methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',\n // allowedHeaders: '*',\n // },\n onServerRun: async (app) => {\n logger.log(`running at ${await app.getUrl()}`);\n logger.log(`Env: ${process.env.NODE_ENV}`);\n if (process.env.DB_NAME) {\n logger.log(\n `database: ${process.env.DB_NAME}@${process.env.DB_HOST || 'localhost'}`,\n );\n }\n },\n onServerError: (error, _app) => {\n logger.error(`Server failed to run`);\n throw error;\n },\n};\n"],"names":["appConfig","port","process","env","PORT","prefix","exclude","swagger","openapi","info","title","version","components","securitySchemes","bearer","scheme","bearerFormat","type","versioning","defaultVersion","VersioningType","URI","onServerRun","app","logger","log","getUrl","NODE_ENV","DB_NAME","DB_HOST","onServerError","error","_app"],"mappings":";;;;+
|
|
1
|
+
{"version":3,"sources":["../../../src/configs/app.ts"],"sourcesContent":["import { logger } from '../utils/logger';\nimport {\n ValidationPipeOptions,\n type VersioningOptions,\n VersioningType,\n} from '@nestjs/common';\nimport type {\n GlobalPrefixOptions,\n NestApplicationOptions,\n} from '@nestjs/common/interfaces';\nimport { NestExpressApplication } from '@nestjs/platform-express';\nimport { NestFastifyApplication } from '@nestjs/platform-fastify/interfaces';\nimport { OpenAPIObject } from '@nestjs/swagger';\n\nexport type IApp = NestFastifyApplication | NestExpressApplication;\nexport interface IPrefix extends GlobalPrefixOptions {\n prefix: string;\n}\n\n// todo: adaptor: fastify | express = fastify\nexport interface IAppConfig extends NestApplicationOptions {\n /**\n * The port that the app will listen to\n * if not provided, `app.listen()` is not called\n */\n port?: string | number;\n /** the global prefix for every HTTP route path. see Nest.setGlobalPrefix() */\n prefix?: string | IPrefix;\n versioning?: VersioningOptions;\n /**\n * Swagger API spec.\n * https://spec.openapis.org/oas\n */\n swagger?: Partial<Omit<OpenAPIObject, 'paths'>>;\n /**\n * The path to the Swagger UI page\n * @default ''\n */\n swaggerPath?: string;\n /** whether to enable parsing multiPart */\n multipart?: boolean;\n /**\n * validation pipe options\n */\n validationPipe?: ValidationPipeOptions;\n /**\n * package.json absolute path or object, or the path of the project root dir\n * used to extract info for Swagger docs, such as title, description, and version.\n */\n // todo: import IPackage interface from @impactor/javascript (move from @impactor/nx-manager)\n package?: string | Record<string, unknown>;\n /**\n * weather to register entities to automatically generate Swagger and class-validator decorators\n * You can specify list of models to be registered\n */\n registerEntities?: boolean | Function[];\n /**\n * a hook that executed when the server runs and listens to the specified port\n * get the server by app.getHttpServer()\n */\n onServerRun?: (app: IApp) => void | Promise<void>;\n onServerError?: (error: Error, app: IApp) => void | Promise<void>;\n}\n\n/**\n * the default app configs\n */\nexport const appConfig: IAppConfig = {\n port: process.env.PORT,\n prefix: { prefix: 'api', exclude: ['sitemap.xml', 'robots.txt'] },\n // or use `DocumentBuilder` from \"@nestjs/swagger\"\n swagger: {\n openapi: '3.1.0',\n info: { title: 'API', version: '1.0' },\n components: {\n securitySchemes: {\n // add `@ApiBearerAuth()` to controllers which you need to check their bearer auth header\n bearer: {\n scheme: 'bearer',\n bearerFormat: 'JWT',\n type: 'http',\n },\n },\n },\n },\n swaggerPath: '',\n versioning: {\n defaultVersion: ['1.0'],\n type: VersioningType.URI,\n },\n // cors: {\n // // todo: add APP_URL or localhost by default\n // origin: '*',\n // methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',\n // allowedHeaders: '*',\n // },\n onServerRun: async (app) => {\n logger.log(`running at ${await app.getUrl()}`);\n logger.log(`Env: ${process.env.NODE_ENV}`);\n if (process.env.DB_NAME) {\n logger.log(\n `database: ${process.env.DB_NAME}@${process.env.DB_HOST || 'localhost'}`,\n );\n }\n },\n onServerError: (error, _app) => {\n logger.error(`Server failed to run`);\n throw error;\n },\n};\n"],"names":["appConfig","port","process","env","PORT","prefix","exclude","swagger","openapi","info","title","version","components","securitySchemes","bearer","scheme","bearerFormat","type","swaggerPath","versioning","defaultVersion","VersioningType","URI","onServerRun","app","logger","log","getUrl","NODE_ENV","DB_NAME","DB_HOST","onServerError","error","_app"],"mappings":";;;;+BAmEaA;;;eAAAA;;;wBAnEU;wBAKhB;AA8DA,MAAMA,YAAwB;IACnCC,MAAMC,QAAQC,GAAG,CAACC,IAAI;IACtBC,QAAQ;QAAEA,QAAQ;QAAOC,SAAS;YAAC;YAAe;SAAa;IAAC;IAChE,kDAAkD;IAClDC,SAAS;QACPC,SAAS;QACTC,MAAM;YAAEC,OAAO;YAAOC,SAAS;QAAM;QACrCC,YAAY;YACVC,iBAAiB;gBACf,yFAAyF;gBACzFC,QAAQ;oBACNC,QAAQ;oBACRC,cAAc;oBACdC,MAAM;gBACR;YACF;QACF;IACF;IACAC,aAAa;IACbC,YAAY;QACVC,gBAAgB;YAAC;SAAM;QACvBH,MAAMI,sBAAc,CAACC,GAAG;IAC1B;IACA,UAAU;IACV,iDAAiD;IACjD,iBAAiB;IACjB,+CAA+C;IAC/C,yBAAyB;IACzB,KAAK;IACLC,aAAa,OAAOC;QAClBC,cAAM,CAACC,GAAG,CAAC,CAAC,WAAW,EAAE,MAAMF,IAAIG,MAAM,IAAI;QAC7CF,cAAM,CAACC,GAAG,CAAC,CAAC,KAAK,EAAExB,QAAQC,GAAG,CAACyB,QAAQ,EAAE;QACzC,IAAI1B,QAAQC,GAAG,CAAC0B,OAAO,EAAE;YACvBJ,cAAM,CAACC,GAAG,CACR,CAAC,UAAU,EAAExB,QAAQC,GAAG,CAAC0B,OAAO,CAAC,CAAC,EAAE3B,QAAQC,GAAG,CAAC2B,OAAO,IAAI,aAAa;QAE5E;IACF;IACAC,eAAe,CAACC,OAAOC;QACrBR,cAAM,CAACO,KAAK,CAAC,CAAC,oBAAoB,CAAC;QACnC,MAAMA;IACR;AACF"}
|
package/src/create-app.js
CHANGED
|
@@ -18,6 +18,7 @@ const _javascript = require("@impactor/javascript");
|
|
|
18
18
|
const _nodejs = require("@impactor/nodejs");
|
|
19
19
|
const _generatemetadata = require("./generate-metadata");
|
|
20
20
|
const _logger = require("./utils/logger");
|
|
21
|
+
const _registerentities = require("./register-entities");
|
|
21
22
|
function _interop_require_default(obj) {
|
|
22
23
|
return obj && obj.__esModule ? obj : {
|
|
23
24
|
default: obj
|
|
@@ -62,6 +63,14 @@ function createApp(module, options) {
|
|
|
62
63
|
forbidNonWhitelisted: true,
|
|
63
64
|
...opts.validationPipe
|
|
64
65
|
}));
|
|
66
|
+
// this must be before registering Swagger
|
|
67
|
+
if (opts.registerEntities !== false) {
|
|
68
|
+
if (Array.isArray(opts.registerEntities)) {
|
|
69
|
+
(0, _registerentities.registerEntities)(opts.registerEntities);
|
|
70
|
+
} else {
|
|
71
|
+
(0, _registerentities.registerEntities)();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
65
74
|
// swagger docs
|
|
66
75
|
// navigate to localhost:PORT to see API docs
|
|
67
76
|
// navigate to localhost:PORT/-json to download the API json file
|
|
@@ -87,7 +96,7 @@ function createApp(module, options) {
|
|
|
87
96
|
});
|
|
88
97
|
if (opts.swagger) {
|
|
89
98
|
let document = _swagger.SwaggerModule.createDocument(app, opts.swagger);
|
|
90
|
-
_swagger.SwaggerModule.setup('', app, document);
|
|
99
|
+
_swagger.SwaggerModule.setup(opts.swaggerPath || '', app, document);
|
|
91
100
|
}
|
|
92
101
|
}
|
|
93
102
|
// todo: import `FastifyMulterModule` from '@nest-lab/fastify-multer' in the module
|
package/src/create-app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/create-app.ts"],"sourcesContent":["import { NestFactory } from '@nestjs/core';\nimport { OpenAPIObject, SwaggerModule } from '@nestjs/swagger';\nimport {\n FastifyAdapter,\n type NestFastifyApplication,\n} from '@nestjs/platform-fastify';\nimport multiPart from '@fastify/multipart';\nimport { type IAppConfig, appConfig } from './configs/app';\nimport { ValidationPipe } from '@nestjs/common';\nimport { merge } from '@impactor/javascript';\nimport { isDirSync, readSync } from '@impactor/nodejs';\nimport {\n generateSwaggerMetadata,\n loadSwaggerMetadata,\n} from './generate-metadata';\nimport { logger } from './utils/logger';\n\n// todo: add type to `module`\nexport function createApp(module: any, options?: IAppConfig) {\n // todo: options.adapter = fastify | express\n return NestFactory.create<NestFastifyApplication>(\n module,\n new FastifyAdapter(),\n options,\n ).then(async (app) => {\n let pkg = (\n typeof options?.package === 'string'\n ? isDirSync(options.package)\n ? // todo: use IPackage interface\n readSync(`${options.package}/package.json`)\n : readSync(options.package)\n : options?.package || {}\n ) as Record<string, string>;\n\n let opts = merge(\n [\n appConfig,\n {\n swagger: {\n info: {\n title: pkg.name,\n description:\n pkg.description || `${pkg.name ? `${pkg.name} ` : ''}API`,\n version: `v${pkg.version || '1.0'}`,\n },\n },\n },\n options,\n ],\n {\n deep: true,\n },\n ) as IAppConfig;\n\n if (opts?.prefix) {\n if (typeof opts.prefix === 'string') {\n app.setGlobalPrefix(opts.prefix);\n } else {\n let { prefix, ...prefixOptions } = opts.prefix;\n app.setGlobalPrefix(prefix, prefixOptions);\n }\n }\n\n if (opts.versioning) {\n app.enableVersioning(opts.versioning);\n }\n\n app.useGlobalPipes(\n new ValidationPipe({\n // apply class-transformer decorators, such as @Transform()\n transform: true,\n // Strip out any properties that are not defined in your DTO.\n whitelist: true,\n // Instead of silently removing unknown fields, it throws a 400 error.\n forbidNonWhitelisted: true,\n ...opts.validationPipe,\n }),\n );\n\n // swagger docs\n // navigate to localhost:PORT to see API docs\n // navigate to localhost:PORT/-json to download the API json file\n if (opts.swagger) {\n // emit swagger metadata\n // this file will be generated in runtime\n // todo: when emitting swagger metadata using generateSwaggerMetadata(),\n // the TSDocs comments are no longer read by nest,\n // and we must manually add @ApiProperty() to all properties\n let metadataPath = generateSwaggerMetadata({\n // @ts-ignore `import.meta` requires `module: nodeNext`\n outputDir: import.meta.dirname,\n // fixes: src/nest-swagger-metadata.ts:2:1 - error TS2742:\n // The inferred type of 'default' cannot be named without a reference to '../node_modules/@impactor/utils/src/dto/order.dto'.\n // This is likely not portable. A type annotation is necessary.\n transform: (content) =>\n content.replaceAll('../node_modules/@impactor/', '@impactor/'),\n });\n\n // todo: the file by default is related to CWD(),\n // change cwd of the target \"serve\" in nx.json to \"{projectRoot}/dist\"\n await loadSwaggerMetadata(metadataPath)\n .then(() => logger.debug('Swagger metadata loaded'))\n // ignore if the metadata file hasn't generated\n .catch((error) => {\n logger.warn(`Failed to load Swagger metadata`, error);\n });\n\n if (opts.swagger) {\n let document = SwaggerModule.createDocument(\n app,\n opts.swagger as OpenAPIObject,\n );\n SwaggerModule.setup('', app, document);\n }\n }\n\n // todo: import `FastifyMulterModule` from '@nest-lab/fastify-multer' in the module\n // that wants to receive files, instead of registering 'multipart' globally\n if (opts.multipart !== false) {\n await app.register(multiPart);\n }\n\n return opts.port\n ? app\n // if the server runs inside a container, it should bound to '0.0.0.0' instead of 'localhost' (the default)\n // so it can listen to the external requests i.e. from the browser\n .listen(opts.port, '0.0.0.0')\n .then((_server) => opts.onServerRun?.(app))\n .catch((error) => opts.onServerError?.(error, app))\n .then(() => app)\n : app;\n });\n}\n"],"names":["createApp","module","options","NestFactory","create","FastifyAdapter","then","app","pkg","package","isDirSync","readSync","opts","merge","appConfig","swagger","info","title","name","description","version","deep","prefix","setGlobalPrefix","prefixOptions","versioning","enableVersioning","useGlobalPipes","ValidationPipe","transform","whitelist","forbidNonWhitelisted","validationPipe","metadataPath","generateSwaggerMetadata","outputDir","content","replaceAll","loadSwaggerMetadata","logger","debug","catch","error","warn","document","SwaggerModule","createDocument","setup","multipart","register","multiPart","port","listen","_server","onServerRun","onServerError"],"mappings":";;;;+
|
|
1
|
+
{"version":3,"sources":["../../src/create-app.ts"],"sourcesContent":["import { NestFactory } from '@nestjs/core';\nimport { OpenAPIObject, SwaggerModule } from '@nestjs/swagger';\nimport {\n FastifyAdapter,\n type NestFastifyApplication,\n} from '@nestjs/platform-fastify';\nimport multiPart from '@fastify/multipart';\nimport { type IAppConfig, appConfig } from './configs/app';\nimport { ValidationPipe } from '@nestjs/common';\nimport { merge } from '@impactor/javascript';\nimport { isDirSync, readSync } from '@impactor/nodejs';\nimport {\n generateSwaggerMetadata,\n loadSwaggerMetadata,\n} from './generate-metadata';\nimport { logger } from './utils/logger';\nimport { registerEntities } from './register-entities';\n\n// todo: add type to `module`\nexport function createApp(module: any, options?: IAppConfig) {\n // todo: options.adapter = fastify | express\n return NestFactory.create<NestFastifyApplication>(\n module,\n new FastifyAdapter(),\n options,\n ).then(async (app) => {\n let pkg = (\n typeof options?.package === 'string'\n ? isDirSync(options.package)\n ? // todo: use IPackage interface\n readSync(`${options.package}/package.json`)\n : readSync(options.package)\n : options?.package || {}\n ) as Record<string, string>;\n\n let opts = merge(\n [\n appConfig,\n {\n swagger: {\n info: {\n title: pkg.name,\n description:\n pkg.description || `${pkg.name ? `${pkg.name} ` : ''}API`,\n version: `v${pkg.version || '1.0'}`,\n },\n },\n },\n options,\n ],\n {\n deep: true,\n },\n ) as IAppConfig;\n\n if (opts?.prefix) {\n if (typeof opts.prefix === 'string') {\n app.setGlobalPrefix(opts.prefix);\n } else {\n let { prefix, ...prefixOptions } = opts.prefix;\n app.setGlobalPrefix(prefix, prefixOptions);\n }\n }\n\n if (opts.versioning) {\n app.enableVersioning(opts.versioning);\n }\n\n app.useGlobalPipes(\n new ValidationPipe({\n // apply class-transformer decorators, such as @Transform()\n transform: true,\n // Strip out any properties that are not defined in your DTO.\n whitelist: true,\n // Instead of silently removing unknown fields, it throws a 400 error.\n forbidNonWhitelisted: true,\n ...opts.validationPipe,\n }),\n );\n\n // this must be before registering Swagger\n if (opts.registerEntities !== false) {\n if (Array.isArray(opts.registerEntities)) {\n registerEntities(opts.registerEntities);\n } else {\n registerEntities();\n }\n }\n\n // swagger docs\n // navigate to localhost:PORT to see API docs\n // navigate to localhost:PORT/-json to download the API json file\n if (opts.swagger) {\n // emit swagger metadata\n // this file will be generated in runtime\n // todo: when emitting swagger metadata using generateSwaggerMetadata(),\n // the TSDocs comments are no longer read by nest,\n // and we must manually add @ApiProperty() to all properties\n let metadataPath = generateSwaggerMetadata({\n // @ts-ignore `import.meta` requires `module: nodeNext`\n outputDir: import.meta.dirname,\n // fixes: src/nest-swagger-metadata.ts:2:1 - error TS2742:\n // The inferred type of 'default' cannot be named without a reference to '../node_modules/@impactor/utils/src/dto/order.dto'.\n // This is likely not portable. A type annotation is necessary.\n transform: (content) =>\n content.replaceAll('../node_modules/@impactor/', '@impactor/'),\n });\n\n // todo: the file by default is related to CWD(),\n // change cwd of the target \"serve\" in nx.json to \"{projectRoot}/dist\"\n await loadSwaggerMetadata(metadataPath)\n .then(() => logger.debug('Swagger metadata loaded'))\n // ignore if the metadata file hasn't generated\n .catch((error) => {\n logger.warn(`Failed to load Swagger metadata`, error);\n });\n\n if (opts.swagger) {\n let document = SwaggerModule.createDocument(\n app,\n opts.swagger as OpenAPIObject,\n );\n SwaggerModule.setup(opts.swaggerPath || '', app, document);\n }\n }\n\n // todo: import `FastifyMulterModule` from '@nest-lab/fastify-multer' in the module\n // that wants to receive files, instead of registering 'multipart' globally\n if (opts.multipart !== false) {\n await app.register(multiPart);\n }\n\n return opts.port\n ? app\n // if the server runs inside a container, it should bound to '0.0.0.0' instead of 'localhost' (the default)\n // so it can listen to the external requests i.e. from the browser\n .listen(opts.port, '0.0.0.0')\n .then((_server) => opts.onServerRun?.(app))\n .catch((error) => opts.onServerError?.(error, app))\n .then(() => app)\n : app;\n });\n}\n"],"names":["createApp","module","options","NestFactory","create","FastifyAdapter","then","app","pkg","package","isDirSync","readSync","opts","merge","appConfig","swagger","info","title","name","description","version","deep","prefix","setGlobalPrefix","prefixOptions","versioning","enableVersioning","useGlobalPipes","ValidationPipe","transform","whitelist","forbidNonWhitelisted","validationPipe","registerEntities","Array","isArray","metadataPath","generateSwaggerMetadata","outputDir","content","replaceAll","loadSwaggerMetadata","logger","debug","catch","error","warn","document","SwaggerModule","createDocument","setup","swaggerPath","multipart","register","multiPart","port","listen","_server","onServerRun","onServerError"],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get Entity () {
|
|
13
|
+
return Entity;
|
|
14
|
+
},
|
|
15
|
+
get Hide () {
|
|
16
|
+
return Hide;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const _registerentities = require("../register-entities");
|
|
20
|
+
const _typeorm = require("typeorm");
|
|
21
|
+
const _StringUtils = require("typeorm/util/StringUtils");
|
|
22
|
+
function Entity(name, options) {
|
|
23
|
+
return (target)=>{
|
|
24
|
+
new EntityFactory(target, {
|
|
25
|
+
name,
|
|
26
|
+
...options
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
let EntityFactory = class EntityFactory {
|
|
31
|
+
/**
|
|
32
|
+
* decorate the class with TypeORM `@Entity()`
|
|
33
|
+
*/ addEntity() {
|
|
34
|
+
// TypeORM's `@Entity()` adds the class to storage.tables
|
|
35
|
+
if (!this.storage.tables.some((el)=>el.target === this.model)) {
|
|
36
|
+
Reflect.decorate([
|
|
37
|
+
(0, _typeorm.Entity)(this.options?.name || // todo: generate plural names
|
|
38
|
+
(0, _StringUtils.snakeCase)(this.model.name.replace(/(Entity|DTO|Model)$/i, '') + 's'), this.options)
|
|
39
|
+
], this.model);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* add Swagger decorators to all the model fields
|
|
44
|
+
*/ addSwaggerDecorators() {
|
|
45
|
+
// todo: also get the class that this.model extends, if any.
|
|
46
|
+
(0, _registerentities.registerEntities)([
|
|
47
|
+
this.model
|
|
48
|
+
]);
|
|
49
|
+
}
|
|
50
|
+
constructor(model, options){
|
|
51
|
+
this.model = model;
|
|
52
|
+
this.options = options;
|
|
53
|
+
/**
|
|
54
|
+
* contains all TypeORM metadata for all entities
|
|
55
|
+
*/ this.storage = (0, _typeorm.getMetadataArgsStorage)();
|
|
56
|
+
this.addEntity();
|
|
57
|
+
this.addSwaggerDecorators();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
function Hide() {
|
|
61
|
+
return (target, key)=>{
|
|
62
|
+
Reflect.defineMetadata('swagger/apiModelProperties', false, target, key);
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=entity.decorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/decorators/entity.decorator.ts"],"sourcesContent":["import { registerEntities } from '../register-entities';\nimport {\n Entity as TypeORMEntity,\n EntityOptions,\n getMetadataArgsStorage,\n} from 'typeorm';\nimport { MetadataArgsStorage } from 'typeorm/metadata-args/MetadataArgsStorage';\nimport { snakeCase } from 'typeorm/util/StringUtils';\n\nexport interface IEntityOptions extends EntityOptions {\n name?: string;\n}\n\n/**\n * Define a class as a TypeORM entity\n * - add Swagger decorators to all columns\n *\n * note: currently, this decorator ignores `@ApiHideProperty()`\n * use `@Hide()` instead\n * https://github.com/nestjs/swagger/issues/3711\n */\n// todo: add basic columns such as id, created_at, updated_at\n// this has a downside, that TS cannot detect props that are defined dynamically\n// i.e. `Model.id` will cause a TS error\n// todo: add class validator decorators from column definition\n// for instance `@Column(type: 'varchar', length: 200)` -> `@IsString() @MaxLength(200)`\n// note that we cannot access uninitialized classes properties,\n// so `this.model[col.propertyName]` is always undefined,\n// also Reflect methods cannot be used to decorate those properties as they are not existing\n// otherwise use a property decorator to work with each property separately\n// todo: create `@Column()` decorator to apply these steps on property-level\n// this has a downside: it'll use the property name rather than the final column name,\n// because TypeORM may rename the column using a naming strategy\n// so, we need to access the naming strategy to apply it on each prop\nexport function Entity(name?: string, options?: EntityOptions): ClassDecorator {\n return (target: Function) => {\n new EntityFactory(target, { name, ...options });\n };\n}\n\nclass EntityFactory {\n /**\n * contains all TypeORM metadata for all entities\n */\n private storage: MetadataArgsStorage = getMetadataArgsStorage();\n\n constructor(\n private model: Function,\n private options?: IEntityOptions,\n ) {\n this.addEntity();\n this.addSwaggerDecorators();\n }\n\n /**\n * decorate the class with TypeORM `@Entity()`\n */\n addEntity() {\n // TypeORM's `@Entity()` adds the class to storage.tables\n if (!this.storage.tables.some((el) => el.target === this.model)) {\n Reflect.decorate(\n [\n TypeORMEntity(\n this.options?.name ||\n // todo: generate plural names\n snakeCase(\n this.model.name.replace(/(Entity|DTO|Model)$/i, '') + 's',\n ),\n this.options,\n ),\n ],\n this.model,\n );\n }\n }\n\n /**\n * add Swagger decorators to all the model fields\n */\n addSwaggerDecorators() {\n // todo: also get the class that this.model extends, if any.\n registerEntities([this.model]);\n }\n}\n\n/**\n * add `@Hide()` to properties that you don't want to hide in Swagger\n * Using `@ApiHideProperty()` from `@nestjs/swagger` is not supported\n * `@ApiHideProperty()` doesn't add a metadata -> use `@Hide()`\n * https://github.com/nestjs/swagger/blob/master/lib/decorators/api-hide-property.decorator.ts\n */\nexport function Hide(): PropertyDecorator {\n return (target: Object, key: string | symbol) => {\n Reflect.defineMetadata('swagger/apiModelProperties', false, target, key);\n };\n}\n"],"names":["Entity","Hide","name","options","target","EntityFactory","addEntity","storage","tables","some","el","model","Reflect","decorate","TypeORMEntity","snakeCase","replace","addSwaggerDecorators","registerEntities","getMetadataArgsStorage","key","defineMetadata"],"mappings":";;;;;;;;;;;QAkCgBA;eAAAA;;QAyDAC;eAAAA;;;kCA3FiB;yBAK1B;6BAEmB;AA2BnB,SAASD,OAAOE,IAAa,EAAEC,OAAuB;IAC3D,OAAO,CAACC;QACN,IAAIC,cAAcD,QAAQ;YAAEF;YAAM,GAAGC,OAAO;QAAC;IAC/C;AACF;AAEA,IAAA,AAAME,gBAAN,MAAMA;IAcJ;;GAEC,GACDC,YAAY;QACV,yDAAyD;QACzD,IAAI,CAAC,IAAI,CAACC,OAAO,CAACC,MAAM,CAACC,IAAI,CAAC,CAACC,KAAOA,GAAGN,MAAM,KAAK,IAAI,CAACO,KAAK,GAAG;YAC/DC,QAAQC,QAAQ,CACd;gBACEC,IAAAA,eAAa,EACX,IAAI,CAACX,OAAO,EAAED,QACZ,8BAA8B;gBAC9Ba,IAAAA,sBAAS,EACP,IAAI,CAACJ,KAAK,CAACT,IAAI,CAACc,OAAO,CAAC,wBAAwB,MAAM,MAE1D,IAAI,CAACb,OAAO;aAEf,EACD,IAAI,CAACQ,KAAK;QAEd;IACF;IAEA;;GAEC,GACDM,uBAAuB;QACrB,4DAA4D;QAC5DC,IAAAA,kCAAgB,EAAC;YAAC,IAAI,CAACP,KAAK;SAAC;IAC/B;IApCA,YACE,AAAQA,KAAe,EACvB,AAAQR,OAAwB,CAChC;aAFQQ,QAAAA;aACAR,UAAAA;QAPV;;GAEC,QACOI,UAA+BY,IAAAA,+BAAsB;QAM3D,IAAI,CAACb,SAAS;QACd,IAAI,CAACW,oBAAoB;IAC3B;AA+BF;AAQO,SAAShB;IACd,OAAO,CAACG,QAAgBgB;QACtBR,QAAQS,cAAc,CAAC,8BAA8B,OAAOjB,QAAQgB;IACtE;AACF"}
|
|
@@ -51,14 +51,18 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
51
51
|
}
|
|
52
52
|
const _default = async ()=>{
|
|
53
53
|
const t = {
|
|
54
|
+
["../../../apps/edu-backend/src/types/approve-status.enum"]: await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/types/approve-status.enum"))),
|
|
54
55
|
["../../../apps/edu-backend/src/api/users/entities/user.entity"]: await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/api/users/entities/user.entity"))),
|
|
55
56
|
["../../../apps/edu-backend/src/types/schedule"]: await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/types/schedule"))),
|
|
56
57
|
["../../../apps/edu-backend/src/api/cards/entities/card.entity"]: await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/api/cards/entities/card.entity"))),
|
|
57
58
|
["../../../apps/edu-backend/src/api/card-templates/entities/card-template.entity"]: await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/api/card-templates/entities/card-template.entity"))),
|
|
58
59
|
["../../../apps/edu-backend/src/api/notes/entities/note.entity"]: await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/api/notes/entities/note.entity"))),
|
|
60
|
+
["../../../apps/edu-backend/src/api/schedule/entities/schedule.entity"]: await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/api/schedule/entities/schedule.entity"))),
|
|
61
|
+
["../../../apps/edu-backend/src/api/review-history/entities/review-history.entity"]: await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/api/review-history/entities/review-history.entity"))),
|
|
59
62
|
["../../../apps/edu-backend/src/api/note-types/entities/note-type.entity"]: await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/api/note-types/entities/note-type.entity"))),
|
|
60
63
|
["../../../apps/edu-backend/src/api/note-fields/entities/note-field.entity"]: await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/api/note-fields/entities/note-field.entity"))),
|
|
61
|
-
["../../../apps/edu-backend/src/types/countries.enum"]: await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/types/countries.enum")))
|
|
64
|
+
["../../../apps/edu-backend/src/types/countries.enum"]: await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/types/countries.enum"))),
|
|
65
|
+
["../../../apps/edu-backend/src/api/collections/entities/collection.entity"]: await Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/api/collections/entities/collection.entity")))
|
|
62
66
|
};
|
|
63
67
|
return {
|
|
64
68
|
"@nestjs/swagger": {
|
|
@@ -67,6 +71,20 @@ const _default = async ()=>{
|
|
|
67
71
|
Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/utils/basic.entity"))),
|
|
68
72
|
{
|
|
69
73
|
"BasicEntity": {
|
|
74
|
+
id: {
|
|
75
|
+
required: true,
|
|
76
|
+
type: ()=>String
|
|
77
|
+
},
|
|
78
|
+
_version: {
|
|
79
|
+
required: true,
|
|
80
|
+
type: ()=>Number,
|
|
81
|
+
description: "the version number of the updated row",
|
|
82
|
+
example: 1
|
|
83
|
+
},
|
|
84
|
+
approve_status: {
|
|
85
|
+
required: true,
|
|
86
|
+
enum: t["../../../apps/edu-backend/src/types/approve-status.enum"].ApproveStatus
|
|
87
|
+
},
|
|
70
88
|
tags: {
|
|
71
89
|
required: true,
|
|
72
90
|
type: ()=>[
|
|
@@ -164,7 +182,7 @@ const _default = async ()=>{
|
|
|
164
182
|
difficulty: {
|
|
165
183
|
required: false,
|
|
166
184
|
type: ()=>Number,
|
|
167
|
-
description: "FSRS difficulty value.\nControls how quickly stability grows or decays.
|
|
185
|
+
description: "FSRS difficulty value.\nControls how quickly stability grows or decays.",
|
|
168
186
|
minimum: 0
|
|
169
187
|
},
|
|
170
188
|
elapsed_days: {
|
|
@@ -222,6 +240,16 @@ const _default = async ()=>{
|
|
|
222
240
|
note: {
|
|
223
241
|
required: true,
|
|
224
242
|
type: ()=>t["../../../apps/edu-backend/src/api/notes/entities/note.entity"].Note
|
|
243
|
+
},
|
|
244
|
+
schedule: {
|
|
245
|
+
required: true,
|
|
246
|
+
type: ()=>t["../../../apps/edu-backend/src/api/schedule/entities/schedule.entity"].Schedule
|
|
247
|
+
},
|
|
248
|
+
reviewHistory: {
|
|
249
|
+
required: true,
|
|
250
|
+
type: ()=>[
|
|
251
|
+
t["../../../apps/edu-backend/src/api/review-history/entities/review-history.entity"].ReviewHistory
|
|
252
|
+
]
|
|
225
253
|
}
|
|
226
254
|
}
|
|
227
255
|
}
|
|
@@ -256,6 +284,12 @@ const _default = async ()=>{
|
|
|
256
284
|
type: {
|
|
257
285
|
required: true,
|
|
258
286
|
type: ()=>t["../../../apps/edu-backend/src/api/note-types/entities/note-type.entity"].NoteType
|
|
287
|
+
},
|
|
288
|
+
cards: {
|
|
289
|
+
required: true,
|
|
290
|
+
type: ()=>[
|
|
291
|
+
t["../../../apps/edu-backend/src/api/cards/entities/card.entity"].Card
|
|
292
|
+
]
|
|
259
293
|
}
|
|
260
294
|
}
|
|
261
295
|
}
|
|
@@ -348,13 +382,13 @@ const _default = async ()=>{
|
|
|
348
382
|
firstName: {
|
|
349
383
|
required: true,
|
|
350
384
|
type: ()=>String,
|
|
351
|
-
|
|
385
|
+
minLength: 2,
|
|
352
386
|
maxLength: 100
|
|
353
387
|
},
|
|
354
388
|
lastName: {
|
|
355
389
|
required: true,
|
|
356
390
|
type: ()=>String,
|
|
357
|
-
|
|
391
|
+
minLength: 2,
|
|
358
392
|
maxLength: 100
|
|
359
393
|
},
|
|
360
394
|
gender: {
|
|
@@ -368,40 +402,46 @@ const _default = async ()=>{
|
|
|
368
402
|
city: {
|
|
369
403
|
required: true,
|
|
370
404
|
type: ()=>String,
|
|
371
|
-
example: "Cairo",
|
|
372
405
|
maxLength: 100
|
|
373
406
|
},
|
|
374
407
|
email: {
|
|
375
408
|
required: true,
|
|
376
409
|
type: ()=>String,
|
|
377
|
-
example: "ali.mostafa@gmail.com",
|
|
378
410
|
format: "email"
|
|
379
411
|
},
|
|
380
412
|
mobile: {
|
|
381
413
|
required: true,
|
|
382
414
|
type: ()=>String,
|
|
383
|
-
description: "the mobile number including the country code",
|
|
384
|
-
example: "+14844731795",
|
|
385
415
|
format: "mobile-phone",
|
|
386
416
|
pattern: "/^\\+/"
|
|
387
417
|
},
|
|
388
418
|
password: {
|
|
389
419
|
required: true,
|
|
390
420
|
type: ()=>String,
|
|
391
|
-
example: "P@sSwrd",
|
|
392
421
|
minLength: 8
|
|
422
|
+
},
|
|
423
|
+
role: {
|
|
424
|
+
required: true,
|
|
425
|
+
type: ()=>String,
|
|
426
|
+
enum: t["../../../apps/edu-backend/src/api/users/entities/user.entity"].UserRole
|
|
427
|
+
},
|
|
428
|
+
collections: {
|
|
429
|
+
required: true,
|
|
430
|
+
type: ()=>[
|
|
431
|
+
t["../../../apps/edu-backend/src/api/collections/entities/collection.entity"].Collection
|
|
432
|
+
]
|
|
393
433
|
}
|
|
394
434
|
}
|
|
395
435
|
}
|
|
396
436
|
],
|
|
397
437
|
[
|
|
398
|
-
Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/node_modules/@impactor/nest
|
|
438
|
+
Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/node_modules/@impactor/nest/src/decorators/controller/dto/empty.dto"))),
|
|
399
439
|
{
|
|
400
440
|
"EmptyDto": {}
|
|
401
441
|
}
|
|
402
442
|
],
|
|
403
443
|
[
|
|
404
|
-
Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/node_modules/@impactor/nest
|
|
444
|
+
Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/node_modules/@impactor/nest/src/decorators/controller/dto/update-response.dto"))),
|
|
405
445
|
{
|
|
406
446
|
"UpdateResponseDto": {
|
|
407
447
|
affected: {
|
|
@@ -468,6 +508,12 @@ const _default = async ()=>{
|
|
|
468
508
|
]
|
|
469
509
|
],
|
|
470
510
|
"controllers": [
|
|
511
|
+
[
|
|
512
|
+
Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/node_modules/@impactor/nest/src/modules/basic/basic.controller"))),
|
|
513
|
+
{
|
|
514
|
+
"BasicController": {}
|
|
515
|
+
}
|
|
516
|
+
],
|
|
471
517
|
[
|
|
472
518
|
Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/src/api/auth/auth.controller"))),
|
|
473
519
|
{
|
|
@@ -538,12 +584,6 @@ const _default = async ()=>{
|
|
|
538
584
|
"subscribe": {}
|
|
539
585
|
}
|
|
540
586
|
}
|
|
541
|
-
],
|
|
542
|
-
[
|
|
543
|
-
Promise.resolve().then(()=>/*#__PURE__*/ _interop_require_wildcard(require("../../../apps/edu-backend/node_modules/@impactor/nest/src/modules/basic/basic.controller"))),
|
|
544
|
-
{
|
|
545
|
-
"BasicController": {}
|
|
546
|
-
}
|
|
547
587
|
]
|
|
548
588
|
]
|
|
549
589
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/nest-swagger-metadata.js"],"sourcesContent":["/* eslint-disable */\nexport default async () => {\n const t = {\n [\"../../../apps/edu-backend/src/api/users/entities/user.entity\"]: await import(\"../../../apps/edu-backend/src/api/users/entities/user.entity\"),\n [\"../../../apps/edu-backend/src/types/schedule\"]: await import(\"../../../apps/edu-backend/src/types/schedule\"),\n [\"../../../apps/edu-backend/src/api/cards/entities/card.entity\"]: await import(\"../../../apps/edu-backend/src/api/cards/entities/card.entity\"),\n [\"../../../apps/edu-backend/src/api/card-templates/entities/card-template.entity\"]: await import(\"../../../apps/edu-backend/src/api/card-templates/entities/card-template.entity\"),\n [\"../../../apps/edu-backend/src/api/notes/entities/note.entity\"]: await import(\"../../../apps/edu-backend/src/api/notes/entities/note.entity\"),\n [\"../../../apps/edu-backend/src/api/note-types/entities/note-type.entity\"]: await import(\"../../../apps/edu-backend/src/api/note-types/entities/note-type.entity\"),\n [\"../../../apps/edu-backend/src/api/note-fields/entities/note-field.entity\"]: await import(\"../../../apps/edu-backend/src/api/note-fields/entities/note-field.entity\"),\n [\"../../../apps/edu-backend/src/types/countries.enum\"]: await import(\"../../../apps/edu-backend/src/types/countries.enum\")\n };\n return { \"@nestjs/swagger\": { \"models\": [[import(\"../../../apps/edu-backend/src/utils/basic.entity\"), { \"BasicEntity\": { tags: { required: true, type: () => [String], maxLength: 50, maxItems: 20 }, created_by: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/users/entities/user.entity\"].UserEntity } }, \"EntityWithCount\": { data: { required: true }, count: { required: true, type: () => Number } } }], [import(\"../../../apps/edu-backend/src/api/review-history/entities/review-history.entity\"), { \"ReviewHistory\": { rating: { required: true, type: () => Number, description: \"FSRS rating for this review (0 = Again, 1 = Hard, 2 = Good, 3 = Easy)\", minimum: 0 }, state: { required: true, description: \"Current FSRS state of the card\", enum: t[\"../../../apps/edu-backend/src/types/schedule\"].State }, stability: { required: false, type: () => Number, description: \"Stability value controlling retention (can use scaled bigint for performance)\", minimum: 0 }, difficulty: { required: false, type: () => Number, description: \"Difficulty value controlling growth/decay of stability\", minimum: 0 }, elapsed_days: { required: false, type: () => Number, description: \"Days elapsed since last review\", deprecated: true, minimum: 0 }, last_elapsed_days: { required: false, type: () => Number, description: \"Last elapsed days (from previous review)\", deprecated: true, minimum: 0 }, scheduled_days: { required: false, type: () => Number, description: \"Number of scheduled days for this review (can be -1 before scheduling)\" }, learning_steps: { required: false, type: () => Number, description: \"Learning step index (for cards in learning phase)\", minimum: 0 }, card: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/cards/entities/card.entity\"].Card, description: \"Card associated with this review\" } } }], [import(\"../../../apps/edu-backend/src/api/schedule/entities/schedule.entity\"), { \"Schedule\": { stability: { required: false, type: () => Number, description: \"FSRS stability value.\\nRepresents memory retention strength.\", minimum: 0 }, difficulty: { required: false, type: () => Number, description: \"FSRS difficulty value.\\nControls how quickly stability grows or decays. *\", minimum: 0 }, elapsed_days: { required: false, type: () => Number, description: \"Number of days elapsed since the previous review.\\nProvided by FSRS during scheduling.\", deprecated: true, minimum: 0 }, scheduled_days: { required: false, type: () => Number, description: \"Number of days the card was scheduled for at the time of the last review.\", minimum: 0 }, reps: { required: false, type: () => Number, description: \"Total number of successful reviews for the card.\", minimum: 0 }, lapses: { required: false, type: () => Number, description: \"Number of times the card was forgotten, i.e. \\\"Again\\\"\", minimum: 0 }, learning_steps: { required: false, type: () => Number, description: \"Current learning step index.\\nUsed mainly during the learning / relearning phases.\", minimum: 0 }, state: { required: false, description: \"Current FSRS state of the card\\n(New, Learning, Review, Relearning).\", enum: t[\"../../../apps/edu-backend/src/types/schedule\"].State }, card: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/cards/entities/card.entity\"].Card, description: \"The card this schedule belongs to.\" } } }], [import(\"../../../apps/edu-backend/src/api/cards/entities/card.entity\"), { \"Card\": { template: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/card-templates/entities/card-template.entity\"].CardTemplate }, note: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/notes/entities/note.entity\"].Note } } }], [import(\"../../../apps/edu-backend/src/api/card-templates/entities/card-template.entity\"), { \"CardTemplate\": { title: { required: true, type: () => String, maxLength: 200 }, front: { required: true, type: () => String }, back: { required: true, type: () => String }, css: { required: true, type: () => String, description: \"the CSS style, without `<style>`\" }, js: { required: true, type: () => String, description: \"A javascript code to be executed when the card is rendered, including `<script>`\" }, type: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/note-types/entities/note-type.entity\"].NoteType } } }], [import(\"../../../apps/edu-backend/src/api/note-entry/entities/note-entry.entity\"), { \"NoteEntry\": { value: { required: true, type: () => String }, field: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/note-fields/entities/note-field.entity\"].NoteField }, note: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/notes/entities/note.entity\"].Note } } }], [import(\"../../../apps/edu-backend/src/api/note-fields/entities/note-field.entity\"), { \"NoteField\": { title: { required: true, type: () => String, maxLength: 200 }, type: { required: true, description: \"The field type mainly used in UI to create a form field.\\nit also can be used to perform proper queries,\\nfor instance, filtering a number field where its value > a specific number\", enum: t[\"../../../apps/edu-backend/src/api/note-fields/entities/note-field.entity\"].FieldType }, noteType: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/note-types/entities/note-type.entity\"].NoteType } } }], [import(\"../../../apps/edu-backend/src/api/note-types/entities/note-type.entity\"), { \"NoteType\": { title: { required: true, type: () => String }, description: { required: true, type: () => String } } }], [import(\"../../../apps/edu-backend/src/api/notes/entities/note.entity\"), { \"Note\": { type: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/note-types/entities/note-type.entity\"].NoteType } } }], [import(\"../../../apps/edu-backend/src/api/collections/entities/collection.entity\"), { \"Collection\": { title: { required: true, type: () => String }, description: { required: true, type: () => String } } }], [import(\"../../../apps/edu-backend/src/api/users/entities/user.entity\"), { \"UserEntity\": { firstName: { required: true, type: () => String, example: \"Ali\", maxLength: 100 }, lastName: { required: true, type: () => String, example: \"Mostafa\", maxLength: 100 }, gender: { required: true, enum: t[\"../../../apps/edu-backend/src/api/users/entities/user.entity\"].Gender }, country: { required: true, enum: t[\"../../../apps/edu-backend/src/types/countries.enum\"].Country }, city: { required: true, type: () => String, example: \"Cairo\", maxLength: 100 }, email: { required: true, type: () => String, example: \"ali.mostafa@gmail.com\", format: \"email\" }, mobile: { required: true, type: () => String, description: \"the mobile number including the country code\", example: \"+14844731795\", format: \"mobile-phone\", pattern: \"/^\\\\+/\" }, password: { required: true, type: () => String, example: \"P@sSwrd\", minLength: 8 } } }], [import(\"../../../apps/edu-backend/node_modules/@impactor/nest-crud/src/dto/empty.dto\"), { \"EmptyDto\": {} }], [import(\"../../../apps/edu-backend/node_modules/@impactor/nest-crud/src/dto/update-response.dto\"), { \"UpdateResponseDto\": { affected: { required: true, type: () => Number, description: \"the total number of the affecter rows\" } } }], [import(\"../../../apps/edu-backend/src/api/auth/entities/token.entity\"), { \"Token\": { tokenId: { required: true, type: () => String, description: \"a random UUID hash that stored in payload.tokenId,\\nwhen the JWT token is validated, the tokenId is extracted from it,\\nand then checked if it existing here, to revoke a token just remove its corresponding tokenId from here.\\nAvoid storing the token itself here, so no one can use it without permission\" } } }], [import(\"../../../apps/edu-backend/src/api/auth/dto/auth-response.dto\"), { \"AuthResponseDto\": { access_token: { required: true, type: () => String } } }], [import(\"../../../apps/edu-backend/src/api/auth/dto/login.dto\"), { \"LoginDto\": {} }], [import(\"../../../apps/edu-backend/src/types/errors-response.dto\"), { \"ErrorResponse\": { message: { required: true, type: () => String, description: \"the error message\", example: \"duplicate key value violates unique constraint\" }, request: { required: false, type: () => String, description: \"the endpoint that caused the error\", example: \"GET /example\" }, code: { required: false, type: () => String, description: \"the error code\", example: \"DB_ERR\" } } }]], \"controllers\": [[import(\"../../../apps/edu-backend/src/api/auth/auth.controller\"), { \"AuthController\": { \"login\": { type: Object }, \"register\": { type: Object }, \"getTokens\": {}, \"getToken\": { type: Object } } }], [import(\"../../../apps/edu-backend/src/api/users/users.controller\"), { \"UsersController\": { \"me\": { summary: \"get the current loggedIn user\", type: Object }, \"updateOwnData\": { summary: \"update the user's own data\", type: Object } } }], [import(\"../../../apps/edu-backend/src/api/schedule/schedule.controller\"), { \"ScheduleController\": { \"getCardSchedule\": { type: Object }, \"review\": { type: Object }, \"next\": { type: Object }, \"getRetrievability\": { type: Number }, \"undo\": { type: Object }, \"forget\": { type: Object }, \"reschedule\": { type: Object } } }], [import(\"../../../apps/edu-backend/src/api/collections/collections.controller\"), { \"CollectionsController\": { \"addNote\": {}, \"getCollectionNotes\": {}, \"getCollectionSubscribers\": {}, \"subscribe\": {} } }], [import(\"../../../apps/edu-backend/node_modules/@impactor/nest/src/modules/basic/basic.controller\"), { \"BasicController\": {} }]] } };\n};"],"names":["t","tags","required","type","String","maxLength","maxItems","created_by","UserEntity","data","count","Number","rating","description","minimum","state","enum","State","stability","difficulty","elapsed_days","deprecated","last_elapsed_days","scheduled_days","learning_steps","card","Card","reps","lapses","template","CardTemplate","note","Note","title","front","back","css","js","NoteType","value","field","NoteField","FieldType","noteType","firstName","example","lastName","gender","Gender","country","Country","city","email","format","mobile","pattern","password","minLength","affected","tokenId","access_token","message","request","code","Object","summary"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/nest-swagger-metadata.js"],"sourcesContent":["/* eslint-disable */\nexport default async () => {\n const t = {\n [\"../../../apps/edu-backend/src/types/approve-status.enum\"]: await import(\"../../../apps/edu-backend/src/types/approve-status.enum\"),\n [\"../../../apps/edu-backend/src/api/users/entities/user.entity\"]: await import(\"../../../apps/edu-backend/src/api/users/entities/user.entity\"),\n [\"../../../apps/edu-backend/src/types/schedule\"]: await import(\"../../../apps/edu-backend/src/types/schedule\"),\n [\"../../../apps/edu-backend/src/api/cards/entities/card.entity\"]: await import(\"../../../apps/edu-backend/src/api/cards/entities/card.entity\"),\n [\"../../../apps/edu-backend/src/api/card-templates/entities/card-template.entity\"]: await import(\"../../../apps/edu-backend/src/api/card-templates/entities/card-template.entity\"),\n [\"../../../apps/edu-backend/src/api/notes/entities/note.entity\"]: await import(\"../../../apps/edu-backend/src/api/notes/entities/note.entity\"),\n [\"../../../apps/edu-backend/src/api/schedule/entities/schedule.entity\"]: await import(\"../../../apps/edu-backend/src/api/schedule/entities/schedule.entity\"),\n [\"../../../apps/edu-backend/src/api/review-history/entities/review-history.entity\"]: await import(\"../../../apps/edu-backend/src/api/review-history/entities/review-history.entity\"),\n [\"../../../apps/edu-backend/src/api/note-types/entities/note-type.entity\"]: await import(\"../../../apps/edu-backend/src/api/note-types/entities/note-type.entity\"),\n [\"../../../apps/edu-backend/src/api/note-fields/entities/note-field.entity\"]: await import(\"../../../apps/edu-backend/src/api/note-fields/entities/note-field.entity\"),\n [\"../../../apps/edu-backend/src/types/countries.enum\"]: await import(\"../../../apps/edu-backend/src/types/countries.enum\"),\n [\"../../../apps/edu-backend/src/api/collections/entities/collection.entity\"]: await import(\"../../../apps/edu-backend/src/api/collections/entities/collection.entity\")\n };\n return { \"@nestjs/swagger\": { \"models\": [[import(\"../../../apps/edu-backend/src/utils/basic.entity\"), { \"BasicEntity\": { id: { required: true, type: () => String }, _version: { required: true, type: () => Number, description: \"the version number of the updated row\", example: 1 }, approve_status: { required: true, enum: t[\"../../../apps/edu-backend/src/types/approve-status.enum\"].ApproveStatus }, tags: { required: true, type: () => [String], maxLength: 50, maxItems: 20 }, created_by: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/users/entities/user.entity\"].UserEntity } }, \"EntityWithCount\": { data: { required: true }, count: { required: true, type: () => Number } } }], [import(\"../../../apps/edu-backend/src/api/review-history/entities/review-history.entity\"), { \"ReviewHistory\": { rating: { required: true, type: () => Number, description: \"FSRS rating for this review (0 = Again, 1 = Hard, 2 = Good, 3 = Easy)\", minimum: 0 }, state: { required: true, description: \"Current FSRS state of the card\", enum: t[\"../../../apps/edu-backend/src/types/schedule\"].State }, stability: { required: false, type: () => Number, description: \"Stability value controlling retention (can use scaled bigint for performance)\", minimum: 0 }, difficulty: { required: false, type: () => Number, description: \"Difficulty value controlling growth/decay of stability\", minimum: 0 }, elapsed_days: { required: false, type: () => Number, description: \"Days elapsed since last review\", deprecated: true, minimum: 0 }, last_elapsed_days: { required: false, type: () => Number, description: \"Last elapsed days (from previous review)\", deprecated: true, minimum: 0 }, scheduled_days: { required: false, type: () => Number, description: \"Number of scheduled days for this review (can be -1 before scheduling)\" }, learning_steps: { required: false, type: () => Number, description: \"Learning step index (for cards in learning phase)\", minimum: 0 }, card: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/cards/entities/card.entity\"].Card, description: \"Card associated with this review\" } } }], [import(\"../../../apps/edu-backend/src/api/schedule/entities/schedule.entity\"), { \"Schedule\": { stability: { required: false, type: () => Number, description: \"FSRS stability value.\\nRepresents memory retention strength.\", minimum: 0 }, difficulty: { required: false, type: () => Number, description: \"FSRS difficulty value.\\nControls how quickly stability grows or decays.\", minimum: 0 }, elapsed_days: { required: false, type: () => Number, description: \"Number of days elapsed since the previous review.\\nProvided by FSRS during scheduling.\", deprecated: true, minimum: 0 }, scheduled_days: { required: false, type: () => Number, description: \"Number of days the card was scheduled for at the time of the last review.\", minimum: 0 }, reps: { required: false, type: () => Number, description: \"Total number of successful reviews for the card.\", minimum: 0 }, lapses: { required: false, type: () => Number, description: \"Number of times the card was forgotten, i.e. \\\"Again\\\"\", minimum: 0 }, learning_steps: { required: false, type: () => Number, description: \"Current learning step index.\\nUsed mainly during the learning / relearning phases.\", minimum: 0 }, state: { required: false, description: \"Current FSRS state of the card\\n(New, Learning, Review, Relearning).\", enum: t[\"../../../apps/edu-backend/src/types/schedule\"].State }, card: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/cards/entities/card.entity\"].Card, description: \"The card this schedule belongs to.\" } } }], [import(\"../../../apps/edu-backend/src/api/cards/entities/card.entity\"), { \"Card\": { template: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/card-templates/entities/card-template.entity\"].CardTemplate }, note: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/notes/entities/note.entity\"].Note }, schedule: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/schedule/entities/schedule.entity\"].Schedule }, reviewHistory: { required: true, type: () => [t[\"../../../apps/edu-backend/src/api/review-history/entities/review-history.entity\"].ReviewHistory] } } }], [import(\"../../../apps/edu-backend/src/api/card-templates/entities/card-template.entity\"), { \"CardTemplate\": { title: { required: true, type: () => String, maxLength: 200 }, front: { required: true, type: () => String }, back: { required: true, type: () => String }, css: { required: true, type: () => String, description: \"the CSS style, without `<style>`\" }, js: { required: true, type: () => String, description: \"A javascript code to be executed when the card is rendered, including `<script>`\" }, type: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/note-types/entities/note-type.entity\"].NoteType }, cards: { required: true, type: () => [t[\"../../../apps/edu-backend/src/api/cards/entities/card.entity\"].Card] } } }], [import(\"../../../apps/edu-backend/src/api/note-entry/entities/note-entry.entity\"), { \"NoteEntry\": { value: { required: true, type: () => String }, field: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/note-fields/entities/note-field.entity\"].NoteField }, note: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/notes/entities/note.entity\"].Note } } }], [import(\"../../../apps/edu-backend/src/api/note-fields/entities/note-field.entity\"), { \"NoteField\": { title: { required: true, type: () => String, maxLength: 200 }, type: { required: true, description: \"The field type mainly used in UI to create a form field.\\nit also can be used to perform proper queries,\\nfor instance, filtering a number field where its value > a specific number\", enum: t[\"../../../apps/edu-backend/src/api/note-fields/entities/note-field.entity\"].FieldType }, noteType: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/note-types/entities/note-type.entity\"].NoteType } } }], [import(\"../../../apps/edu-backend/src/api/note-types/entities/note-type.entity\"), { \"NoteType\": { title: { required: true, type: () => String }, description: { required: true, type: () => String } } }], [import(\"../../../apps/edu-backend/src/api/notes/entities/note.entity\"), { \"Note\": { type: { required: true, type: () => t[\"../../../apps/edu-backend/src/api/note-types/entities/note-type.entity\"].NoteType } } }], [import(\"../../../apps/edu-backend/src/api/collections/entities/collection.entity\"), { \"Collection\": { title: { required: true, type: () => String }, description: { required: true, type: () => String } } }], [import(\"../../../apps/edu-backend/src/api/users/entities/user.entity\"), { \"UserEntity\": { firstName: { required: true, type: () => String, minLength: 2, maxLength: 100 }, lastName: { required: true, type: () => String, minLength: 2, maxLength: 100 }, gender: { required: true, enum: t[\"../../../apps/edu-backend/src/api/users/entities/user.entity\"].Gender }, country: { required: true, enum: t[\"../../../apps/edu-backend/src/types/countries.enum\"].Country }, city: { required: true, type: () => String, maxLength: 100 }, email: { required: true, type: () => String, format: \"email\" }, mobile: { required: true, type: () => String, format: \"mobile-phone\", pattern: \"/^\\\\+/\" }, password: { required: true, type: () => String, minLength: 8 }, role: { required: true, type: () => String, enum: t[\"../../../apps/edu-backend/src/api/users/entities/user.entity\"].UserRole }, collections: { required: true, type: () => [t[\"../../../apps/edu-backend/src/api/collections/entities/collection.entity\"].Collection] } } }], [import(\"../../../apps/edu-backend/node_modules/@impactor/nest/src/decorators/controller/dto/empty.dto\"), { \"EmptyDto\": {} }], [import(\"../../../apps/edu-backend/node_modules/@impactor/nest/src/decorators/controller/dto/update-response.dto\"), { \"UpdateResponseDto\": { affected: { required: true, type: () => Number, description: \"the total number of the affecter rows\" } } }], [import(\"../../../apps/edu-backend/src/api/auth/entities/token.entity\"), { \"Token\": { tokenId: { required: true, type: () => String, description: \"a random UUID hash that stored in payload.tokenId,\\nwhen the JWT token is validated, the tokenId is extracted from it,\\nand then checked if it existing here, to revoke a token just remove its corresponding tokenId from here.\\nAvoid storing the token itself here, so no one can use it without permission\" } } }], [import(\"../../../apps/edu-backend/src/api/auth/dto/auth-response.dto\"), { \"AuthResponseDto\": { access_token: { required: true, type: () => String } } }], [import(\"../../../apps/edu-backend/src/api/auth/dto/login.dto\"), { \"LoginDto\": {} }], [import(\"../../../apps/edu-backend/src/types/errors-response.dto\"), { \"ErrorResponse\": { message: { required: true, type: () => String, description: \"the error message\", example: \"duplicate key value violates unique constraint\" }, request: { required: false, type: () => String, description: \"the endpoint that caused the error\", example: \"GET /example\" }, code: { required: false, type: () => String, description: \"the error code\", example: \"DB_ERR\" } } }]], \"controllers\": [[import(\"../../../apps/edu-backend/node_modules/@impactor/nest/src/modules/basic/basic.controller\"), { \"BasicController\": {} }], [import(\"../../../apps/edu-backend/src/api/auth/auth.controller\"), { \"AuthController\": { \"login\": { type: Object }, \"register\": { type: Object }, \"getTokens\": {}, \"getToken\": { type: Object } } }], [import(\"../../../apps/edu-backend/src/api/users/users.controller\"), { \"UsersController\": { \"me\": { summary: \"get the current loggedIn user\", type: Object }, \"updateOwnData\": { summary: \"update the user's own data\", type: Object } } }], [import(\"../../../apps/edu-backend/src/api/schedule/schedule.controller\"), { \"ScheduleController\": { \"getCardSchedule\": { type: Object }, \"review\": { type: Object }, \"next\": { type: Object }, \"getRetrievability\": { type: Number }, \"undo\": { type: Object }, \"forget\": { type: Object }, \"reschedule\": { type: Object } } }], [import(\"../../../apps/edu-backend/src/api/collections/collections.controller\"), { \"CollectionsController\": { \"addNote\": {}, \"getCollectionNotes\": {}, \"getCollectionSubscribers\": {}, \"subscribe\": {} } }]] } };\n};"],"names":["t","id","required","type","String","_version","Number","description","example","approve_status","enum","ApproveStatus","tags","maxLength","maxItems","created_by","UserEntity","data","count","rating","minimum","state","State","stability","difficulty","elapsed_days","deprecated","last_elapsed_days","scheduled_days","learning_steps","card","Card","reps","lapses","template","CardTemplate","note","Note","schedule","Schedule","reviewHistory","ReviewHistory","title","front","back","css","js","NoteType","cards","value","field","NoteField","FieldType","noteType","firstName","minLength","lastName","gender","Gender","country","Country","city","email","format","mobile","pattern","password","role","UserRole","collections","Collection","affected","tokenId","access_token","message","request","code","Object","summary"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function registerEntities(models?: Function[]): void;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "registerEntities", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return registerEntities;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _typeormtoswagger = require("./utils/typeorm-to-swagger");
|
|
12
|
+
const _swagger = require("@nestjs/swagger");
|
|
13
|
+
const _typeorm = require("typeorm");
|
|
14
|
+
function registerEntities(models) {
|
|
15
|
+
let storage = (0, _typeorm.getMetadataArgsStorage)(), // todo: handle when col.target is string
|
|
16
|
+
cols = storage.columns.filter((el)=>typeof el.target === 'function'), relations = storage.relations.filter((el)=>typeof el.target === 'function' && el.relationType.endsWith('to-one')), joinColumns = storage.joinColumns;
|
|
17
|
+
if (Array.isArray(models)) {
|
|
18
|
+
cols = cols.filter((el)=>models.includes(el.target));
|
|
19
|
+
relations = relations.filter((el)=>models.includes(el.target));
|
|
20
|
+
}
|
|
21
|
+
for (let col of cols){
|
|
22
|
+
// existing props, i.e. options that the consumer already specified in `@ApiProperty()`
|
|
23
|
+
let props = Reflect.getMetadata('swagger/apiModelProperties', col.target.prototype, col.propertyName), // if the column is auto generated
|
|
24
|
+
// this is similar to `storage.generations.filter()`
|
|
25
|
+
// this also contains the generation strategy, such as "uuid"
|
|
26
|
+
isGenerated = [
|
|
27
|
+
'createDate',
|
|
28
|
+
'updateDate',
|
|
29
|
+
'deleteDate',
|
|
30
|
+
'version',
|
|
31
|
+
'treeChildrenCount',
|
|
32
|
+
'treeLevel',
|
|
33
|
+
'objectId'
|
|
34
|
+
].includes(col.mode) || !!storage.findGenerated(col.target, col.propertyName);
|
|
35
|
+
Reflect.decorate([
|
|
36
|
+
(0, _swagger.ApiProperty)({
|
|
37
|
+
readOnly: isGenerated,
|
|
38
|
+
// try using the column type as "format",
|
|
39
|
+
// unless `typeORMToSwagger()` returned the correct one
|
|
40
|
+
// todo: if `format` cannot detected, try to infer it from the column name
|
|
41
|
+
// for instance:
|
|
42
|
+
// - email -> format: email
|
|
43
|
+
// - password -> format: password
|
|
44
|
+
// - image -> format: binary
|
|
45
|
+
format: col.options.type,
|
|
46
|
+
...col.options.type ? (0, _typeormtoswagger.typeORMToSwagger)(col.options.type) : {},
|
|
47
|
+
enumName: col.options.enumName,
|
|
48
|
+
default: col.options.default,
|
|
49
|
+
required: !!col.options.nullable,
|
|
50
|
+
nullable: col.options.nullable,
|
|
51
|
+
...col.options.enum ? {
|
|
52
|
+
enum: col.options.enum
|
|
53
|
+
} : {},
|
|
54
|
+
...col.options.length ? {
|
|
55
|
+
maxLength: +col.options.length
|
|
56
|
+
} : {},
|
|
57
|
+
...props
|
|
58
|
+
})
|
|
59
|
+
], col.target.prototype, col.propertyName, Reflect.getOwnPropertyDescriptor(col.target.prototype, col.propertyName));
|
|
60
|
+
}
|
|
61
|
+
for (let rel of relations){
|
|
62
|
+
let props = Reflect.getMetadata('swagger/apiModelProperties', rel.target.prototype, rel.propertyName);
|
|
63
|
+
// todo: get the reference column name, mostly the primary key of the other table
|
|
64
|
+
// for instance if `posts.user` -> `user.id`, then FK name is "id"
|
|
65
|
+
let foreignKey = joinColumns.find((el)=>el.propertyName === rel.propertyName)?.foreignKeyConstraintName || // todo: this should be the PK of the other table,
|
|
66
|
+
// but currently we are unable to get the other table
|
|
67
|
+
'id';
|
|
68
|
+
if (rel.relationType.endsWith('to-one')) {
|
|
69
|
+
// todo: in one-to-one, we may want to display this field in the join column only
|
|
70
|
+
// for instance, for this relation `user.info <-> info.user`,
|
|
71
|
+
// we may need to inset `user.info.id`, not `info.user.id`
|
|
72
|
+
Reflect.decorate([
|
|
73
|
+
(0, _swagger.ApiProperty)({
|
|
74
|
+
// todo: `type: rel.type` -> gives `string`
|
|
75
|
+
// or get `design:type` metadata -> gives `{}`
|
|
76
|
+
// i.e. `Reflect.getMetadata('design:type',(<Function>rel.target).prototype, rel.propertyName)`
|
|
77
|
+
type: 'object',
|
|
78
|
+
// todo: properties{} should refer to the other table definition
|
|
79
|
+
// for `post.user`, it should be `user{}` props
|
|
80
|
+
properties: {
|
|
81
|
+
// todo: get foreign column name (by default the PK of the other table), type (string/number), and format (uuid)
|
|
82
|
+
[foreignKey]: {
|
|
83
|
+
type: 'string'
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
required: !!rel.options.nullable,
|
|
87
|
+
nullable: rel.options.nullable,
|
|
88
|
+
...props
|
|
89
|
+
})
|
|
90
|
+
], rel.target.prototype, rel.propertyName, Reflect.getOwnPropertyDescriptor(rel.target.prototype, rel.propertyName));
|
|
91
|
+
} else {
|
|
92
|
+
// `*-to-many` relations should appear in GET operations only
|
|
93
|
+
// we don't need to insert them when creating or updating the record
|
|
94
|
+
// we insert them from the other side
|
|
95
|
+
// for instance, for this relation `posts.user <-> user.posts`,
|
|
96
|
+
// we often refer to the user when inserting a new post, not the other way around
|
|
97
|
+
// todo: we need to specify the relation definition, i.e. the shape of the other table
|
|
98
|
+
// todo: in `many-to-many`, we can allow inserting relations from the joining side
|
|
99
|
+
// todo: these fields don't display in Swagger UI even after applying `@ApiProperty()` on them
|
|
100
|
+
(0, _swagger.ApiProperty)({
|
|
101
|
+
readOnly: true,
|
|
102
|
+
isArray: true,
|
|
103
|
+
type: 'array',
|
|
104
|
+
items: {
|
|
105
|
+
type: 'object',
|
|
106
|
+
properties: {
|
|
107
|
+
[foreignKey]: {
|
|
108
|
+
type: 'string'
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
...props
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
//# sourceMappingURL=register-entities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/register-entities.ts"],"sourcesContent":["import { typeORMToSwagger } from './utils/typeorm-to-swagger';\nimport { ApiProperty } from '@nestjs/swagger';\nimport { getMetadataArgsStorage } from 'typeorm';\n\n/**\n * Register models and add Swagger and class-validator decorators\n * call this function before `SwaggerModule.createDocument()`\n *\n * This function extracts info from each column to generate best Swagger model and best validations as much as possible.\n *\n * add `@Hide()` to properties that you want to hide from Swagger\n * `@ApiHideProperty()` doesn't work.\n *\n * to skip processing a property by this function add `@Skip()`\n *\n * to apply this function on a specific model, decorate it with `@Entity()`\n * or use `registerEntities([model])`\n *\n * existing options in `@ApiProperty()` will be merged into options generated by this function\n *\n * `ManyToMany` and `OneToMany` relations are ignored by default, you need to add `@ApiProperty()` to include them\n * `OneToOne` and `ManyToOne` relation is included but with a different name, after suffixing the primary key name\n *\n * @param models list of models to apply this function to\n */\nexport function registerEntities(models?: Function[]) {\n let storage = getMetadataArgsStorage(),\n // todo: handle when col.target is string\n cols = storage.columns.filter((el) => typeof el.target === 'function'),\n relations = storage.relations.filter(\n (el) =>\n typeof el.target === 'function' && el.relationType.endsWith('to-one'),\n ),\n joinColumns = storage.joinColumns;\n\n if (Array.isArray(models)) {\n cols = cols.filter((el) => models.includes(el.target as Function));\n relations = relations.filter((el) =>\n models.includes(el.target as Function),\n );\n }\n\n for (let col of cols) {\n // existing props, i.e. options that the consumer already specified in `@ApiProperty()`\n let props = Reflect.getMetadata(\n 'swagger/apiModelProperties',\n (col.target as Function).prototype,\n col.propertyName,\n ),\n // if the column is auto generated\n // this is similar to `storage.generations.filter()`\n // this also contains the generation strategy, such as \"uuid\"\n isGenerated =\n [\n 'createDate',\n 'updateDate',\n 'deleteDate',\n 'version',\n 'treeChildrenCount',\n 'treeLevel',\n 'objectId',\n ].includes(col.mode) ||\n !!storage.findGenerated(col.target, col.propertyName);\n\n Reflect.decorate(\n [\n ApiProperty({\n readOnly: isGenerated,\n // try using the column type as \"format\",\n // unless `typeORMToSwagger()` returned the correct one\n // todo: if `format` cannot detected, try to infer it from the column name\n // for instance:\n // - email -> format: email\n // - password -> format: password\n // - image -> format: binary\n format: col.options.type,\n ...(col.options.type ? typeORMToSwagger(col.options.type) : {}),\n enumName: col.options.enumName,\n default: col.options.default,\n required: !!col.options.nullable,\n nullable: col.options.nullable,\n ...(col.options.enum ? { enum: col.options.enum } : {}),\n ...(col.options.length ? { maxLength: +col.options.length } : {}),\n ...props,\n }),\n ],\n (col.target as Function).prototype,\n col.propertyName,\n Reflect.getOwnPropertyDescriptor(\n (col.target as Function).prototype,\n col.propertyName,\n ),\n );\n }\n\n for (let rel of relations) {\n let props = Reflect.getMetadata(\n 'swagger/apiModelProperties',\n (rel.target as Function).prototype,\n rel.propertyName,\n );\n // todo: get the reference column name, mostly the primary key of the other table\n // for instance if `posts.user` -> `user.id`, then FK name is \"id\"\n let foreignKey =\n joinColumns.find((el) => el.propertyName === rel.propertyName)\n ?.foreignKeyConstraintName ||\n // todo: this should be the PK of the other table,\n // but currently we are unable to get the other table\n 'id';\n\n if (rel.relationType.endsWith('to-one')) {\n // todo: in one-to-one, we may want to display this field in the join column only\n // for instance, for this relation `user.info <-> info.user`,\n // we may need to inset `user.info.id`, not `info.user.id`\n Reflect.decorate(\n [\n ApiProperty({\n // todo: `type: rel.type` -> gives `string`\n // or get `design:type` metadata -> gives `{}`\n // i.e. `Reflect.getMetadata('design:type',(<Function>rel.target).prototype, rel.propertyName)`\n type: 'object',\n // todo: properties{} should refer to the other table definition\n // for `post.user`, it should be `user{}` props\n properties: {\n // todo: get foreign column name (by default the PK of the other table), type (string/number), and format (uuid)\n [foreignKey]: { type: 'string' },\n },\n required: !!rel.options.nullable,\n nullable: rel.options.nullable,\n ...props,\n }),\n ],\n (rel.target as Function).prototype,\n rel.propertyName,\n Reflect.getOwnPropertyDescriptor(\n (rel.target as Function).prototype,\n rel.propertyName,\n ),\n );\n } else {\n // `*-to-many` relations should appear in GET operations only\n // we don't need to insert them when creating or updating the record\n // we insert them from the other side\n // for instance, for this relation `posts.user <-> user.posts`,\n // we often refer to the user when inserting a new post, not the other way around\n // todo: we need to specify the relation definition, i.e. the shape of the other table\n // todo: in `many-to-many`, we can allow inserting relations from the joining side\n // todo: these fields don't display in Swagger UI even after applying `@ApiProperty()` on them\n ApiProperty({\n readOnly: true,\n isArray: true,\n type: 'array',\n items: {\n type: 'object',\n properties: {\n [foreignKey]: { type: 'string' },\n },\n // required: [foreignKey],\n },\n ...props,\n });\n }\n }\n}\n"],"names":["registerEntities","models","storage","getMetadataArgsStorage","cols","columns","filter","el","target","relations","relationType","endsWith","joinColumns","Array","isArray","includes","col","props","Reflect","getMetadata","prototype","propertyName","isGenerated","mode","findGenerated","decorate","ApiProperty","readOnly","format","options","type","typeORMToSwagger","enumName","default","required","nullable","enum","length","maxLength","getOwnPropertyDescriptor","rel","foreignKey","find","foreignKeyConstraintName","properties","items"],"mappings":"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"}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "typeORMToSwagger", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return typeORMToSwagger;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
function typeORMToSwagger(type) {
|
|
12
|
+
// the column type as string
|
|
13
|
+
// it may be a BooleanConstructor | DateConstructor | ....
|
|
14
|
+
let value = (typeof type === 'string' ? type : type.name).toLowerCase();
|
|
15
|
+
// numbers
|
|
16
|
+
if ([
|
|
17
|
+
'numeric',
|
|
18
|
+
'number',
|
|
19
|
+
'int',
|
|
20
|
+
'int2',
|
|
21
|
+
'int4',
|
|
22
|
+
'int8',
|
|
23
|
+
'int64',
|
|
24
|
+
'integer',
|
|
25
|
+
'tinyint',
|
|
26
|
+
'smallint',
|
|
27
|
+
'mediumint',
|
|
28
|
+
'bigint',
|
|
29
|
+
'unsigned big int',
|
|
30
|
+
'rowid',
|
|
31
|
+
'urowid',
|
|
32
|
+
'float',
|
|
33
|
+
'float4',
|
|
34
|
+
'float8',
|
|
35
|
+
'float64',
|
|
36
|
+
'money',
|
|
37
|
+
'smallmoney',
|
|
38
|
+
'decimal',
|
|
39
|
+
'smalldecimal',
|
|
40
|
+
'dec',
|
|
41
|
+
'double',
|
|
42
|
+
'double precision',
|
|
43
|
+
'fixed',
|
|
44
|
+
'real'
|
|
45
|
+
].includes(value)) {
|
|
46
|
+
// todo: set the best 'format' for each type
|
|
47
|
+
return {
|
|
48
|
+
type: 'number'
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// booleans
|
|
52
|
+
if ([
|
|
53
|
+
'boolean',
|
|
54
|
+
'bool',
|
|
55
|
+
'bit',
|
|
56
|
+
'bit varying',
|
|
57
|
+
'varbit'
|
|
58
|
+
].includes(value)) {
|
|
59
|
+
return {
|
|
60
|
+
type: 'boolean'
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// arrays / collections
|
|
64
|
+
if ([
|
|
65
|
+
'array',
|
|
66
|
+
'simple-array',
|
|
67
|
+
'set',
|
|
68
|
+
'cube',
|
|
69
|
+
'ltree'
|
|
70
|
+
].includes(value)) {
|
|
71
|
+
return {
|
|
72
|
+
type: 'array'
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// files
|
|
76
|
+
if ([
|
|
77
|
+
'blob',
|
|
78
|
+
'longblob',
|
|
79
|
+
'mediumblob',
|
|
80
|
+
'tinyblob',
|
|
81
|
+
'bytea',
|
|
82
|
+
'bytes',
|
|
83
|
+
'image',
|
|
84
|
+
'rowversion',
|
|
85
|
+
'raw',
|
|
86
|
+
'long raw',
|
|
87
|
+
'bfile',
|
|
88
|
+
'binary',
|
|
89
|
+
'varbinary'
|
|
90
|
+
].includes(value)) {
|
|
91
|
+
// todo: openAPI v3 changed 'file' to 'string' with format 'binary' | 'byte'
|
|
92
|
+
// https://swagger.io/docs/specification/v3_0/data-models/data-types/#files
|
|
93
|
+
return {
|
|
94
|
+
type: 'string',
|
|
95
|
+
format: 'binary'
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
// date
|
|
99
|
+
if ([
|
|
100
|
+
'date'
|
|
101
|
+
].includes(value)) {
|
|
102
|
+
return {
|
|
103
|
+
type: 'string',
|
|
104
|
+
format: 'date'
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
if ([
|
|
108
|
+
'year'
|
|
109
|
+
].includes(value)) {
|
|
110
|
+
return {
|
|
111
|
+
type: 'integer',
|
|
112
|
+
format: 'int32',
|
|
113
|
+
example: new Date().getFullYear()
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// time
|
|
117
|
+
if ([
|
|
118
|
+
'time',
|
|
119
|
+
'timetz'
|
|
120
|
+
].includes(value)) {
|
|
121
|
+
return {
|
|
122
|
+
type: 'string',
|
|
123
|
+
format: 'time'
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
// date-time
|
|
127
|
+
if ([
|
|
128
|
+
'timestamp',
|
|
129
|
+
'timestamptz',
|
|
130
|
+
'timestamp without time zone',
|
|
131
|
+
'timestamp with time zone',
|
|
132
|
+
'timestamp with local time zone',
|
|
133
|
+
'datetime',
|
|
134
|
+
'datetime2',
|
|
135
|
+
'datetimeoffset',
|
|
136
|
+
'smalldatetime',
|
|
137
|
+
'seconddate'
|
|
138
|
+
].includes(value)) {
|
|
139
|
+
return {
|
|
140
|
+
type: 'string',
|
|
141
|
+
format: 'date-time'
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
// intervals and durations
|
|
145
|
+
if ([
|
|
146
|
+
'interval',
|
|
147
|
+
'interval year to month',
|
|
148
|
+
'interval day to second'
|
|
149
|
+
].includes(value)) {
|
|
150
|
+
return {
|
|
151
|
+
type: 'string',
|
|
152
|
+
format: 'duration',
|
|
153
|
+
example: 'P1Y2M3DT4H5M6S'
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
// strings
|
|
157
|
+
if ([
|
|
158
|
+
'text',
|
|
159
|
+
'tinytext',
|
|
160
|
+
'shorttext',
|
|
161
|
+
'mediumtext',
|
|
162
|
+
'longtext',
|
|
163
|
+
'ntext',
|
|
164
|
+
'citext',
|
|
165
|
+
'string',
|
|
166
|
+
'character varying',
|
|
167
|
+
'varying character',
|
|
168
|
+
'char varying',
|
|
169
|
+
'varchar2',
|
|
170
|
+
'nvarchar',
|
|
171
|
+
'nvarchar2',
|
|
172
|
+
'national varchar',
|
|
173
|
+
'character',
|
|
174
|
+
'native character',
|
|
175
|
+
'varchar',
|
|
176
|
+
'char',
|
|
177
|
+
'nchar',
|
|
178
|
+
'national char',
|
|
179
|
+
'alphanum',
|
|
180
|
+
'jsonpath',
|
|
181
|
+
'xml',
|
|
182
|
+
'long',
|
|
183
|
+
'clob',
|
|
184
|
+
'nclob',
|
|
185
|
+
// ranges
|
|
186
|
+
// this can also represented as object `{start, end}`
|
|
187
|
+
'int4range',
|
|
188
|
+
'int8range',
|
|
189
|
+
'numrange',
|
|
190
|
+
'tsrange',
|
|
191
|
+
'tstzrange',
|
|
192
|
+
'daterange',
|
|
193
|
+
'int4multirange',
|
|
194
|
+
'int8multirange',
|
|
195
|
+
'nummultirange',
|
|
196
|
+
'tsmultirange',
|
|
197
|
+
'tstzmultirange',
|
|
198
|
+
'datemultirange',
|
|
199
|
+
// enums
|
|
200
|
+
'enum',
|
|
201
|
+
'simple-enum',
|
|
202
|
+
// network
|
|
203
|
+
'cidr',
|
|
204
|
+
'inet',
|
|
205
|
+
'inet4',
|
|
206
|
+
'inet6',
|
|
207
|
+
'macaddr',
|
|
208
|
+
'macaddr8',
|
|
209
|
+
// full-text search types
|
|
210
|
+
'tsvector',
|
|
211
|
+
'tsquery',
|
|
212
|
+
// identifiers
|
|
213
|
+
'rowid',
|
|
214
|
+
'urowid',
|
|
215
|
+
'hierarchyid',
|
|
216
|
+
'sql_variant'
|
|
217
|
+
].includes(value)) {
|
|
218
|
+
return {
|
|
219
|
+
type: 'string'
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
if ([
|
|
223
|
+
'uuid',
|
|
224
|
+
// most databases generates a 128-bit GUID, the same as a UUID
|
|
225
|
+
// so, it is safe to represent it in Swagger UI as a UUID string
|
|
226
|
+
'uniqueidentifier'
|
|
227
|
+
].includes(value)) {
|
|
228
|
+
return {
|
|
229
|
+
type: 'string',
|
|
230
|
+
format: 'uuid'
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
// vectors
|
|
234
|
+
if ([
|
|
235
|
+
'vector',
|
|
236
|
+
'halfvec',
|
|
237
|
+
'half_vector',
|
|
238
|
+
'real_vector'
|
|
239
|
+
].includes(value)) {
|
|
240
|
+
return {
|
|
241
|
+
type: 'array',
|
|
242
|
+
items: {
|
|
243
|
+
type: 'number'
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
// JSON
|
|
248
|
+
if ([
|
|
249
|
+
'json',
|
|
250
|
+
'jsonb',
|
|
251
|
+
'simple-json',
|
|
252
|
+
'hstore'
|
|
253
|
+
].includes(value)) {
|
|
254
|
+
return {
|
|
255
|
+
type: 'object',
|
|
256
|
+
items: {
|
|
257
|
+
type: 'number'
|
|
258
|
+
},
|
|
259
|
+
// in hstore, keys must ve string
|
|
260
|
+
additionalProperties: value === 'hstore' ? {
|
|
261
|
+
type: 'string'
|
|
262
|
+
} : true
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
// geometry types
|
|
266
|
+
if ([
|
|
267
|
+
'geometry',
|
|
268
|
+
'geography',
|
|
269
|
+
'st_geometry',
|
|
270
|
+
'st_point',
|
|
271
|
+
'point',
|
|
272
|
+
'line',
|
|
273
|
+
'polygon',
|
|
274
|
+
'circle',
|
|
275
|
+
'multipolygon',
|
|
276
|
+
'linestring',
|
|
277
|
+
'multilinestring',
|
|
278
|
+
'multipoint',
|
|
279
|
+
'geometrycollection',
|
|
280
|
+
'lseg',
|
|
281
|
+
'box',
|
|
282
|
+
'path'
|
|
283
|
+
].includes(value)) {
|
|
284
|
+
return {
|
|
285
|
+
// they're saved as JSON objects
|
|
286
|
+
type: 'object',
|
|
287
|
+
properties: {
|
|
288
|
+
type: {
|
|
289
|
+
type: 'string',
|
|
290
|
+
example: 'Point'
|
|
291
|
+
},
|
|
292
|
+
coordinates: {
|
|
293
|
+
type: 'array',
|
|
294
|
+
items: {
|
|
295
|
+
type: 'number'
|
|
296
|
+
},
|
|
297
|
+
example: [
|
|
298
|
+
125.6,
|
|
299
|
+
10.1
|
|
300
|
+
]
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
required: [
|
|
304
|
+
'type',
|
|
305
|
+
'coordinates'
|
|
306
|
+
],
|
|
307
|
+
description: 'GeoJSON object representing geometry or geography'
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
type: 'null'
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
//# sourceMappingURL=typeorm-to-swagger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/utils/typeorm-to-swagger.ts"],"sourcesContent":["import { ApiPropertyOptions } from '@nestjs/swagger';\nimport { ColumnType } from 'typeorm/driver/types/ColumnTypes';\n\n/**\n * extract openAPI type and format from TypeORM column type\n * @example `typeORMToSwaggerType(\"file\")` // { type: 'string', format: 'binary' }\n */\nexport function typeORMToSwagger(type: ColumnType): ApiPropertyOptions {\n // the column type as string\n // it may be a BooleanConstructor | DateConstructor | ....\n let value = (typeof type === 'string' ? type : type.name).toLowerCase();\n\n // numbers\n if (\n [\n 'numeric',\n 'number',\n 'int',\n 'int2',\n 'int4',\n 'int8',\n 'int64',\n 'integer',\n 'tinyint',\n 'smallint',\n 'mediumint',\n 'bigint',\n 'unsigned big int',\n 'rowid',\n 'urowid',\n 'float',\n 'float4',\n 'float8',\n 'float64',\n 'money',\n 'smallmoney',\n 'decimal',\n 'smalldecimal',\n 'dec',\n 'double',\n 'double precision',\n 'fixed',\n 'real',\n ].includes(value)\n ) {\n // todo: set the best 'format' for each type\n return { type: 'number' };\n }\n\n // booleans\n if (['boolean', 'bool', 'bit', 'bit varying', 'varbit'].includes(value)) {\n return { type: 'boolean' };\n }\n\n // arrays / collections\n if (['array', 'simple-array', 'set', 'cube', 'ltree'].includes(value)) {\n return { type: 'array' };\n }\n\n // files\n if (\n [\n 'blob',\n 'longblob',\n 'mediumblob',\n 'tinyblob',\n 'bytea',\n 'bytes',\n 'image',\n 'rowversion',\n 'raw',\n 'long raw',\n 'bfile',\n 'binary',\n 'varbinary',\n ].includes(value)\n ) {\n // todo: openAPI v3 changed 'file' to 'string' with format 'binary' | 'byte'\n // https://swagger.io/docs/specification/v3_0/data-models/data-types/#files\n return { type: 'string', format: 'binary' };\n }\n\n // date\n if (['date'].includes(value)) {\n return { type: 'string', format: 'date' };\n }\n\n if (['year'].includes(value)) {\n return {\n type: 'integer',\n format: 'int32',\n example: new Date().getFullYear(),\n };\n }\n\n // time\n if (['time', 'timetz'].includes(value)) {\n return { type: 'string', format: 'time' };\n }\n\n // date-time\n if (\n [\n 'timestamp',\n 'timestamptz',\n 'timestamp without time zone',\n 'timestamp with time zone',\n 'timestamp with local time zone',\n 'datetime',\n 'datetime2',\n 'datetimeoffset',\n 'smalldatetime',\n 'seconddate',\n ].includes(value)\n ) {\n return { type: 'string', format: 'date-time' };\n }\n\n // intervals and durations\n if (\n ['interval', 'interval year to month', 'interval day to second'].includes(\n value,\n )\n ) {\n return { type: 'string', format: 'duration', example: 'P1Y2M3DT4H5M6S' };\n }\n\n // strings\n if (\n [\n 'text',\n 'tinytext',\n 'shorttext',\n 'mediumtext',\n 'longtext',\n 'ntext',\n 'citext',\n 'string',\n 'character varying',\n 'varying character',\n 'char varying',\n 'varchar2',\n 'nvarchar',\n 'nvarchar2',\n 'national varchar',\n 'character',\n 'native character',\n 'varchar',\n 'char',\n 'nchar',\n 'national char',\n 'alphanum',\n 'jsonpath',\n 'xml',\n 'long',\n 'clob',\n 'nclob',\n // ranges\n // this can also represented as object `{start, end}`\n 'int4range',\n 'int8range',\n 'numrange',\n 'tsrange',\n 'tstzrange',\n 'daterange',\n 'int4multirange',\n 'int8multirange',\n 'nummultirange',\n 'tsmultirange',\n 'tstzmultirange',\n 'datemultirange',\n\n // enums\n 'enum',\n 'simple-enum',\n // network\n 'cidr',\n 'inet',\n 'inet4',\n 'inet6',\n 'macaddr',\n 'macaddr8',\n // full-text search types\n 'tsvector',\n 'tsquery',\n // identifiers\n 'rowid',\n 'urowid',\n 'hierarchyid',\n 'sql_variant',\n ].includes(value)\n ) {\n return { type: 'string' };\n }\n\n if (\n [\n 'uuid',\n // most databases generates a 128-bit GUID, the same as a UUID\n // so, it is safe to represent it in Swagger UI as a UUID string\n 'uniqueidentifier',\n ].includes(value)\n ) {\n return { type: 'string', format: 'uuid' };\n }\n\n // vectors\n if (['vector', 'halfvec', 'half_vector', 'real_vector'].includes(value)) {\n return {\n type: 'array',\n items: { type: 'number' },\n };\n }\n\n // JSON\n if (['json', 'jsonb', 'simple-json', 'hstore'].includes(value)) {\n return {\n type: 'object',\n items: { type: 'number' },\n // in hstore, keys must ve string\n additionalProperties: value === 'hstore' ? { type: 'string' } : true,\n };\n }\n\n // geometry types\n if (\n [\n 'geometry',\n 'geography',\n 'st_geometry',\n 'st_point',\n 'point',\n 'line',\n 'polygon',\n 'circle',\n 'multipolygon',\n 'linestring',\n 'multilinestring',\n 'multipoint',\n 'geometrycollection',\n 'lseg',\n 'box',\n 'path',\n ].includes(value)\n ) {\n return {\n // they're saved as JSON objects\n type: 'object',\n properties: {\n type: { type: 'string', example: 'Point' },\n coordinates: {\n type: 'array',\n items: { type: 'number' },\n example: [125.6, 10.1],\n },\n },\n required: ['type', 'coordinates'],\n description: 'GeoJSON object representing geometry or geography',\n };\n }\n\n return { type: 'null' };\n}\n"],"names":["typeORMToSwagger","type","value","name","toLowerCase","includes","format","example","Date","getFullYear","items","additionalProperties","properties","coordinates","required","description"],"mappings":"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"}
|