@pcg/core 1.0.0-alpha.0 → 1.0.0-alpha.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/dist/index.d.ts +21 -1189
- package/dist/index.js +76 -1867
- package/dist/index.js.map +1 -1
- package/package.json +16 -3
- package/.turbo/turbo-build.log +0 -15
- package/CHANGELOG.md +0 -7
- package/src/abstracts/index.ts +0 -3
- package/src/abstracts/nestjs-resource-service.ts +0 -154
- package/src/abstracts/nestjs-service.ts +0 -25
- package/src/configs/app.config.ts +0 -185
- package/src/configs/db.config.ts +0 -122
- package/src/configs/index.ts +0 -4
- package/src/configs/logger.config.ts +0 -62
- package/src/context/action-context.ts +0 -34
- package/src/context/current-user.ts +0 -49
- package/src/context/index.ts +0 -5
- package/src/context/platform-method-context.ts +0 -5
- package/src/context/service-method-context.ts +0 -47
- package/src/db/snake-naming.strategy.ts +0 -277
- package/src/enums/app-env.enum.ts +0 -36
- package/src/enums/app-mode.enum.ts +0 -5
- package/src/enums/app-server.enum.ts +0 -39
- package/src/enums/index.ts +0 -4
- package/src/enums/worker-mode.enum.ts +0 -11
- package/src/errors/access-denied.error.ts +0 -18
- package/src/errors/bad-request.error.ts +0 -9
- package/src/errors/forbidden.error.ts +0 -9
- package/src/errors/index.ts +0 -8
- package/src/errors/input-validation.error.ts +0 -16
- package/src/errors/nest-error.filter.ts +0 -70
- package/src/errors/nest-error.ts +0 -63
- package/src/errors/not-found.error.ts +0 -9
- package/src/errors/unauthorized.error.ts +0 -9
- package/src/exceptions/http-exception-response.ts +0 -34
- package/src/exceptions/http-exceptions.filter.ts +0 -95
- package/src/index.ts +0 -32
- package/src/jwt/extractors.ts +0 -80
- package/src/jwt/types.ts +0 -209
- package/src/logger/classes/logger-factory.ts +0 -54
- package/src/logger/classes/logger.ts +0 -340
- package/src/logger/classes/nest-system-logger.ts +0 -63
- package/src/logger/classes/typeorm-logger.ts +0 -83
- package/src/logger/index.ts +0 -20
- package/src/logger/logger.constants.ts +0 -24
- package/src/logger/logger.interfaces.ts +0 -98
- package/src/logger/logger.module.ts +0 -45
- package/src/logger/logger.providers.ts +0 -140
- package/src/logger/winston.tools.ts +0 -241
- package/src/middlewares/app.middleware.ts +0 -26
- package/src/middlewares/index.ts +0 -1
- package/src/modules/hooks/base-hook.ts +0 -64
- package/src/modules/hooks/decorators/on-hook.decorator.ts +0 -19
- package/src/modules/hooks/hooks.module.ts +0 -10
- package/src/modules/hooks/hooks.service.ts +0 -28
- package/src/modules/hooks/index.ts +0 -11
- package/src/modules/id/id.module.ts +0 -26
- package/src/modules/id/id.service.ts +0 -57
- package/src/modules/id/index.ts +0 -2
- package/src/modules/postgres-pubsub/index.ts +0 -3
- package/src/modules/postgres-pubsub/postgres-pubsub.module.ts +0 -14
- package/src/modules/postgres-pubsub/postgres-pubsub.ts +0 -461
- package/src/pagination/constants.ts +0 -9
- package/src/pagination/cursor/cursor-pagination.exception.ts +0 -16
- package/src/pagination/cursor/cursor-pagination.helpers.ts +0 -145
- package/src/pagination/cursor/cursor-pagination.input.ts +0 -96
- package/src/pagination/cursor/cursor-pagination.types.ts +0 -127
- package/src/pagination/index.ts +0 -9
- package/src/pagination/offset/offset-pagination.exception.ts +0 -15
- package/src/pagination/offset/offset-pagination.helpers.ts +0 -122
- package/src/pagination/offset/offset-pagination.input.ts +0 -30
- package/src/pagination/offset/offset-pagination.types.ts +0 -82
- package/src/pagination/tools.ts +0 -53
- package/src/tools/compose.ts +0 -92
- package/src/tools/convert-to-bigint.ts +0 -27
- package/src/tools/create-list-meta.ts +0 -64
- package/src/tools/define-statuses.ts +0 -15
- package/src/tools/env.ts +0 -139
- package/src/tools/fetch-total-with-query.ts +0 -48
- package/src/tools/generate-entity-id.ts +0 -23
- package/src/tools/get-request-language.ts +0 -13
- package/src/tools/is-object.ts +0 -10
- package/src/tools/postgres/locale-to-pg-collate.ts +0 -21
- package/src/tools/remove-undefined-properties.ts +0 -20
- package/src/tools/request-id.ts +0 -25
- package/src/tools/stringify-opts.ts +0 -20
- package/src/tools/typeorm/add-filter.ts +0 -164
- package/src/tools/typeorm/ensure-inner-join.ts +0 -36
- package/src/tools/typeorm/ensure-left-join.ts +0 -36
- package/src/tools/typeorm/is-alias-already-busy.ts +0 -25
- package/src/tools/wait.ts +0 -26
- package/src/types/express-request.ts +0 -8
- package/src/types/list-mehod-options.ts +0 -32
- package/src/types/list-meta.ts +0 -16
- package/src/types/maybe.ts +0 -2
- package/src/validation/index.ts +0 -1
- package/src/validation/validation-pipe.ts +0 -14
- package/tsconfig.lib.json +0 -9
- package/tsdown.config.ts +0 -15
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Inject, Provider, Type,
|
|
3
|
-
} from '@nestjs/common';
|
|
4
|
-
import {
|
|
5
|
-
createLogger,
|
|
6
|
-
Logger,
|
|
7
|
-
LoggerOptions,
|
|
8
|
-
} from 'winston';
|
|
9
|
-
|
|
10
|
-
import { LoggerFactory } from './classes/logger-factory.js';
|
|
11
|
-
import { NestSystemLogger } from './classes/nest-system-logger.js';
|
|
12
|
-
import {
|
|
13
|
-
NESTKIT_LOGGER_FACTORY_PROVIDER,
|
|
14
|
-
NESTKIT_LOGGER_MODULE_OPTIONS,
|
|
15
|
-
NESTKIT_LOGGER_PROVIDER,
|
|
16
|
-
NESTKIT_SYSTEM_LOGGER_PROVIDER,
|
|
17
|
-
NESTKIT_WINSTON_LOGGER_PROVIDER,
|
|
18
|
-
} from './logger.constants.js';
|
|
19
|
-
import {
|
|
20
|
-
LoggerModuleAsyncOptions,
|
|
21
|
-
LoggerModuleOptions,
|
|
22
|
-
LoggerModuleOptionsFactory,
|
|
23
|
-
} from './logger.interfaces.js';
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Syntax sugar. Injects logger via NESTKIT_LOGGER_PROVIDER token
|
|
27
|
-
* @example
|
|
28
|
-
* ```ts
|
|
29
|
-
* class SomeService {
|
|
30
|
-
* constructor(
|
|
31
|
-
* @InjectLogger() private readonly logger: Logger
|
|
32
|
-
* ) {}
|
|
33
|
-
* ```
|
|
34
|
-
*/
|
|
35
|
-
export const InjectLogger = () => Inject(NESTKIT_LOGGER_PROVIDER);
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Syntax sugar. Injects winston logger factory by WINSTON_MODULE_FACTORY_PROVIDER token
|
|
39
|
-
* @example
|
|
40
|
-
* ```ts
|
|
41
|
-
* class SomeService {
|
|
42
|
-
* constructor(
|
|
43
|
-
* @InjectLoggerFactory() private readonly loggerFactory: LoggerFactory
|
|
44
|
-
* ) {}
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
export const InjectLoggerFactory = () => Inject(NESTKIT_LOGGER_FACTORY_PROVIDER);
|
|
48
|
-
|
|
49
|
-
export const createNestLogger = (
|
|
50
|
-
loggerOpts: LoggerModuleOptions,
|
|
51
|
-
): Logger => {
|
|
52
|
-
return new Logger(createLogger(loggerOpts));
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
export const createLoggerProviders = (
|
|
56
|
-
loggerOpts: LoggerModuleOptions,
|
|
57
|
-
): Provider[] => {
|
|
58
|
-
return [
|
|
59
|
-
{
|
|
60
|
-
provide: NESTKIT_WINSTON_LOGGER_PROVIDER,
|
|
61
|
-
useFactory: () => createLogger(loggerOpts),
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
provide: NESTKIT_LOGGER_PROVIDER,
|
|
65
|
-
useFactory: (logger: Logger) => {
|
|
66
|
-
return new Logger(logger);
|
|
67
|
-
},
|
|
68
|
-
inject: [NESTKIT_WINSTON_LOGGER_PROVIDER],
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
provide: NESTKIT_SYSTEM_LOGGER_PROVIDER,
|
|
72
|
-
useClass: NestSystemLogger,
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
provide: NESTKIT_LOGGER_FACTORY_PROVIDER,
|
|
76
|
-
useFactory: (logger: Logger) => {
|
|
77
|
-
return new LoggerFactory(logger);
|
|
78
|
-
},
|
|
79
|
-
inject: [NESTKIT_WINSTON_LOGGER_PROVIDER],
|
|
80
|
-
},
|
|
81
|
-
];
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
export const createLoggerAsyncProviders = (
|
|
85
|
-
options: LoggerModuleAsyncOptions,
|
|
86
|
-
): Provider[] => {
|
|
87
|
-
const providers: Provider[] = [
|
|
88
|
-
{
|
|
89
|
-
provide: NESTKIT_WINSTON_LOGGER_PROVIDER,
|
|
90
|
-
useFactory: (loggerOpts: LoggerOptions) => createLogger(loggerOpts),
|
|
91
|
-
inject: [NESTKIT_LOGGER_MODULE_OPTIONS],
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
provide: NESTKIT_LOGGER_PROVIDER,
|
|
95
|
-
useFactory: (logger: Logger) => {
|
|
96
|
-
return new Logger(logger);
|
|
97
|
-
},
|
|
98
|
-
inject: [NESTKIT_WINSTON_LOGGER_PROVIDER],
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
provide: NESTKIT_SYSTEM_LOGGER_PROVIDER,
|
|
102
|
-
useClass: NestSystemLogger,
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
provide: NESTKIT_LOGGER_FACTORY_PROVIDER,
|
|
106
|
-
useFactory: (logger: Logger) => {
|
|
107
|
-
return new LoggerFactory(logger);
|
|
108
|
-
},
|
|
109
|
-
inject: [NESTKIT_WINSTON_LOGGER_PROVIDER],
|
|
110
|
-
},
|
|
111
|
-
];
|
|
112
|
-
|
|
113
|
-
if (options.useClass) {
|
|
114
|
-
const useClass = options.useClass as Type<LoggerModuleOptionsFactory>;
|
|
115
|
-
providers.push(
|
|
116
|
-
...[
|
|
117
|
-
{
|
|
118
|
-
provide: NESTKIT_LOGGER_MODULE_OPTIONS,
|
|
119
|
-
useFactory: async (optionsFactory: LoggerModuleOptionsFactory) =>
|
|
120
|
-
await optionsFactory.createLoggerModuleOptions(),
|
|
121
|
-
inject: [useClass],
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
provide: useClass,
|
|
125
|
-
useClass,
|
|
126
|
-
},
|
|
127
|
-
],
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (options.useFactory) {
|
|
132
|
-
providers.push({
|
|
133
|
-
provide: NESTKIT_LOGGER_MODULE_OPTIONS,
|
|
134
|
-
useFactory: options.useFactory,
|
|
135
|
-
inject: options.inject || [],
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return providers;
|
|
140
|
-
};
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
import { LogLevel } from '@nestjs/common';
|
|
2
|
-
import clc from 'cli-color';
|
|
3
|
-
import bare from 'cli-color/bare';
|
|
4
|
-
import { Format } from 'logform';
|
|
5
|
-
import { format } from 'winston';
|
|
6
|
-
import { DestructuredError } from './logger.interfaces.js';
|
|
7
|
-
|
|
8
|
-
const nestLikeColorScheme: Record<string, bare.Format> = {
|
|
9
|
-
log: clc.greenBright,
|
|
10
|
-
info: clc.greenBright,
|
|
11
|
-
error: clc.red,
|
|
12
|
-
warn: clc.yellow,
|
|
13
|
-
debug: clc.magentaBright,
|
|
14
|
-
verbose: clc.cyanBright,
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Options for nest-like formatting
|
|
19
|
-
*/
|
|
20
|
-
export interface CreatePrettyMessageOptions {
|
|
21
|
-
/**
|
|
22
|
-
* Application name
|
|
23
|
-
* @example 'Jetstream'
|
|
24
|
-
*/
|
|
25
|
-
appName: string;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Log level (info, error, warn, debug, verbose, log)
|
|
29
|
-
* @example 'info'
|
|
30
|
-
*/
|
|
31
|
-
level: LogLevel;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Timestamp in ISO 8601 format
|
|
35
|
-
* @example '2021-06-10T16:33:42.000Z'
|
|
36
|
-
*/
|
|
37
|
-
timestamp: string;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Message text
|
|
41
|
-
* @example 'Failed to create cloudlfare output'
|
|
42
|
-
*/
|
|
43
|
-
message: string;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Scope where the message was logged
|
|
47
|
-
* @example 'VideoService'
|
|
48
|
-
*/
|
|
49
|
-
scope?: string;
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Action where the message was logged
|
|
53
|
-
* @example 'createOutput'
|
|
54
|
-
*/
|
|
55
|
-
action?: string;
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Error stack from Error object (`Error.stack`)
|
|
59
|
-
*/
|
|
60
|
-
stack?: string;
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Message context (additional data)
|
|
64
|
-
* @example { id: 'xxx' }
|
|
65
|
-
*/
|
|
66
|
-
context: Record<string, unknown>;
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Error key from 'enum'
|
|
70
|
-
* @example 'NST_SA_EMAIL_NOT_UNIQUE'
|
|
71
|
-
*/
|
|
72
|
-
errorKey?: string;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* HTTP status code
|
|
76
|
-
* @example '400'
|
|
77
|
-
*/
|
|
78
|
-
statusCode?: string;
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Parent path for child errors
|
|
82
|
-
* @example 'MainService.start --> VideoService.createOutput'
|
|
83
|
-
*/
|
|
84
|
-
parentPath?: string;
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Error cause
|
|
88
|
-
*/
|
|
89
|
-
cause?: DestructuredError;
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Recursion depth
|
|
93
|
-
* @example 0
|
|
94
|
-
*/
|
|
95
|
-
deep?: number;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Create a pretty message for the logger with nest-like formatting
|
|
100
|
-
* Use recursion to print child errors
|
|
101
|
-
* @param vars - message variables
|
|
102
|
-
* @returns - formatted message
|
|
103
|
-
* @example
|
|
104
|
-
* [Jetstream] - 6/10/2022, 4:33:42 PM ERROR [VideoService.createOutput] Failed to create cloudlfare output
|
|
105
|
-
*/
|
|
106
|
-
export const createPrettyMessage = ({
|
|
107
|
-
appName,
|
|
108
|
-
action,
|
|
109
|
-
level,
|
|
110
|
-
timestamp,
|
|
111
|
-
message,
|
|
112
|
-
scope,
|
|
113
|
-
stack,
|
|
114
|
-
errorKey,
|
|
115
|
-
// statusCode,
|
|
116
|
-
context,
|
|
117
|
-
parentPath,
|
|
118
|
-
cause,
|
|
119
|
-
deep = 0,
|
|
120
|
-
}: CreatePrettyMessageOptions): string => {
|
|
121
|
-
if ('undefined' !== typeof timestamp) {
|
|
122
|
-
// Only format the timestamp to a locale representation if it's ISO 8601 format. Any format
|
|
123
|
-
// that is not a valid date string will throw, just ignore it (it will be printed as-is).
|
|
124
|
-
try {
|
|
125
|
-
if (timestamp === new Date(timestamp).toISOString()) {
|
|
126
|
-
timestamp = new Date(timestamp).toLocaleString();
|
|
127
|
-
}
|
|
128
|
-
} catch {
|
|
129
|
-
// Ignore
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const color =
|
|
134
|
-
nestLikeColorScheme[level] || ((text: string): string => text);
|
|
135
|
-
|
|
136
|
-
if (errorKey) {
|
|
137
|
-
message += ` [${errorKey}]`;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// [Nest] 9539 - 05/26/2022, 9:00:29 AM LOG [InstanceLoader] OrganizationsModule dependencies initialized +1ms
|
|
141
|
-
|
|
142
|
-
const sAppName = color(`[${appName}]`);
|
|
143
|
-
const sTimestamp = timestamp ? `${timestamp} ` : '';
|
|
144
|
-
const sLevel = color(level.toUpperCase());
|
|
145
|
-
|
|
146
|
-
let path = '';
|
|
147
|
-
let sPath = '';
|
|
148
|
-
if ('undefined' !== typeof scope && 'undefined' !== typeof action) {
|
|
149
|
-
path = `${scope}.${action}`;
|
|
150
|
-
} else if ('undefined' !== typeof scope) {
|
|
151
|
-
path = scope;
|
|
152
|
-
} else if ('undefined' !== typeof action) {
|
|
153
|
-
path = action;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// SyncWorker.sync --> CloudflareApi.createOutput]
|
|
157
|
-
if (path && parentPath) {
|
|
158
|
-
path = `${parentPath} --> ${path}`;
|
|
159
|
-
} else if (parentPath) {
|
|
160
|
-
path = parentPath;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (path) {
|
|
164
|
-
sPath = clc.yellow(` [${path}]`);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// const sDeep = color(printDeep(deep));
|
|
168
|
-
const sMessage = color(` ${message}`);
|
|
169
|
-
const sStack = 'undefined' !== typeof stack ? color(`\n ${stack}`) : '';
|
|
170
|
-
|
|
171
|
-
let sRecursion = '';
|
|
172
|
-
if (cause) {
|
|
173
|
-
const {
|
|
174
|
-
action,
|
|
175
|
-
scope,
|
|
176
|
-
...context
|
|
177
|
-
} = cause?.context || {
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Print child errors recursively
|
|
182
|
-
*/
|
|
183
|
-
sRecursion = cause ? `\n${createPrettyMessage({
|
|
184
|
-
appName,
|
|
185
|
-
action,
|
|
186
|
-
level,
|
|
187
|
-
timestamp,
|
|
188
|
-
message: cause.message ?? message,
|
|
189
|
-
scope,
|
|
190
|
-
stack: cause.stack,
|
|
191
|
-
errorKey: cause.errorKey,
|
|
192
|
-
context,
|
|
193
|
-
parentPath: path,
|
|
194
|
-
cause: cause.cause,
|
|
195
|
-
deep: deep + 1,
|
|
196
|
-
})}` : '';
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const sContext = context && Object.keys(context).length > 0 ? color(` -- ${JSON.stringify(context, null, 2)}`) : '';
|
|
200
|
-
|
|
201
|
-
// sAppName sTimestamp sLevel sPath sMessage
|
|
202
|
-
// [Jetstream] - 6/10/2022, 4:33:42 PM ERROR [VideoService.createOutput] Failer to create cloudlfare output
|
|
203
|
-
return `${sAppName} - ${sTimestamp} ${sLevel}${sPath}${sMessage}${sStack}${sContext}${sRecursion}`;
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Create a nest-like console format
|
|
208
|
-
* @param appName - App name (Jetstream, WHATSBIBLE, etc.)
|
|
209
|
-
* @returns Winston format
|
|
210
|
-
*/
|
|
211
|
-
export const nestLikeConsoleFormat = (appName = 'Nest'): Format =>
|
|
212
|
-
format.printf(
|
|
213
|
-
({
|
|
214
|
-
level,
|
|
215
|
-
timestamp,
|
|
216
|
-
message,
|
|
217
|
-
scope,
|
|
218
|
-
action,
|
|
219
|
-
// ms,
|
|
220
|
-
stack,
|
|
221
|
-
errorKey,
|
|
222
|
-
statusCode,
|
|
223
|
-
error: cause,
|
|
224
|
-
...context
|
|
225
|
-
}) => {
|
|
226
|
-
return createPrettyMessage({
|
|
227
|
-
appName,
|
|
228
|
-
action,
|
|
229
|
-
level: level as LogLevel,
|
|
230
|
-
timestamp,
|
|
231
|
-
message,
|
|
232
|
-
stack,
|
|
233
|
-
context,
|
|
234
|
-
scope,
|
|
235
|
-
errorKey,
|
|
236
|
-
statusCode,
|
|
237
|
-
cause,
|
|
238
|
-
deep: 0,
|
|
239
|
-
} as CreatePrettyMessageOptions);
|
|
240
|
-
},
|
|
241
|
-
);
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
// app.middleware.ts
|
|
2
|
-
import { Injectable, NestMiddleware } from '@nestjs/common';
|
|
3
|
-
import { Response } from 'express';
|
|
4
|
-
|
|
5
|
-
import { AppConfigType, InjectAppConfig } from '#/configs/app.config';
|
|
6
|
-
import { getRequestLanguage } from '#/tools/get-request-language';
|
|
7
|
-
import { extractRequestId } from '#/tools/request-id';
|
|
8
|
-
import { NestExpressRequest } from '#/types/express-request';
|
|
9
|
-
|
|
10
|
-
@Injectable()
|
|
11
|
-
export class AppMiddleware implements NestMiddleware {
|
|
12
|
-
constructor(
|
|
13
|
-
@InjectAppConfig() private readonly appConfig: AppConfigType,
|
|
14
|
-
) {}
|
|
15
|
-
|
|
16
|
-
use(req: NestExpressRequest, res: Response, next: () => void) {
|
|
17
|
-
const fallbackLang = this.appConfig.fallbackLanguage;
|
|
18
|
-
|
|
19
|
-
req.appShortname = this.appConfig.shortname;
|
|
20
|
-
req.requestId = extractRequestId(req);
|
|
21
|
-
req.query.lang = getRequestLanguage(req, fallbackLang);
|
|
22
|
-
req.query.fallbackLang = fallbackLang;
|
|
23
|
-
|
|
24
|
-
next();
|
|
25
|
-
}
|
|
26
|
-
}
|
package/src/middlewares/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './app.middleware.js';
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { BaseServiceMethodContext } from '#/context';
|
|
2
|
-
import { paramCase } from '@pcg/text-kit';
|
|
3
|
-
|
|
4
|
-
export type BaseHookContext = BaseServiceMethodContext;
|
|
5
|
-
|
|
6
|
-
const createHookIdFromClassName = (className: string) => {
|
|
7
|
-
const paramName = paramCase(className.replace(/Hook$/, ''));
|
|
8
|
-
const [first, ...rest] = paramName.split('-');
|
|
9
|
-
|
|
10
|
-
if (rest.length === 0) {
|
|
11
|
-
return first;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// If the first part of the name is a number, prepend 'hook' to it
|
|
15
|
-
return `${first}.${rest.join('-')}`;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Interface for BaseHook class constructor with static id property
|
|
20
|
-
*/
|
|
21
|
-
export interface BaseHookConstructor {
|
|
22
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
23
|
-
new (...args: any[]): BaseHook;
|
|
24
|
-
readonly id: string;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Base class for all hooks. Extend this class to create a new hook type.
|
|
29
|
-
*/
|
|
30
|
-
export abstract class BaseHook<T = unknown, U extends BaseHookContext = BaseHookContext> {
|
|
31
|
-
/**
|
|
32
|
-
* Static id getter for accessing the hook type ID directly from the class
|
|
33
|
-
*/
|
|
34
|
-
static get id(): string {
|
|
35
|
-
return createHookIdFromClassName(this.name);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Unique identifier for the hook type.
|
|
40
|
-
* This ID will be used for event emitting and subscribing.
|
|
41
|
-
* Automatically generated from the class name.
|
|
42
|
-
*/
|
|
43
|
-
get id() {
|
|
44
|
-
return createHookIdFromClassName(this.constructor.name);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Optional payload that will be passed to all hook subscribers.
|
|
49
|
-
*/
|
|
50
|
-
payload?: T;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Context information for the hook
|
|
54
|
-
*/
|
|
55
|
-
ctx: U;
|
|
56
|
-
|
|
57
|
-
constructor(payload?: T, ctx?: U) {
|
|
58
|
-
if (payload) {
|
|
59
|
-
this.payload = payload;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
this.ctx = ctx as U;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { OnEvent } from '@nestjs/event-emitter';
|
|
2
|
-
|
|
3
|
-
import { BaseHookConstructor } from '../base-hook.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Decorator that registers a method as a handler for a specific hook.
|
|
7
|
-
*
|
|
8
|
-
* @param hook Class reference to the hook type (not an instance)
|
|
9
|
-
* @returns Method decorator
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```typescript
|
|
13
|
-
* @OnHook(ExampleHook)
|
|
14
|
-
* handleExampleHook(hook: ExampleHook) {
|
|
15
|
-
* // Handle the hook here
|
|
16
|
-
* }
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
19
|
-
export const OnHook = (hook: BaseHookConstructor): MethodDecorator => OnEvent(hook.id);
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@nestjs/common';
|
|
2
|
-
import { EventEmitter2 } from '@nestjs/event-emitter';
|
|
3
|
-
|
|
4
|
-
import { NestJsService } from '#/abstracts/nestjs-service';
|
|
5
|
-
import { BaseHook } from './base-hook.js';
|
|
6
|
-
|
|
7
|
-
@Injectable()
|
|
8
|
-
export class HooksService extends NestJsService {
|
|
9
|
-
constructor(private readonly eventEmitter: EventEmitter2) {
|
|
10
|
-
super();
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Run a hook and notify all subscribers.
|
|
15
|
-
* This method will wait for all subscribers to complete their execution.
|
|
16
|
-
*
|
|
17
|
-
* @param hook The hook to run
|
|
18
|
-
* @returns Promise that resolves when all subscribers have completed
|
|
19
|
-
*/
|
|
20
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
-
async runHook<T>(hook: BaseHook<T>): Promise<any> {
|
|
22
|
-
this.logger.debug(`Running hook with ID: "${hook.id}"`, {
|
|
23
|
-
payload: hook.payload,
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
return await this.eventEmitter.emitAsync(hook.id, hook);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
// Export the base hook class
|
|
2
|
-
export * from './base-hook.js';
|
|
3
|
-
|
|
4
|
-
// Export decorators
|
|
5
|
-
export * from './decorators/on-hook.decorator.js';
|
|
6
|
-
|
|
7
|
-
// Export the hooks module
|
|
8
|
-
export * from './hooks.module.js';
|
|
9
|
-
|
|
10
|
-
// Export the hooks service
|
|
11
|
-
export * from './hooks.service.js';
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { Global, Module } from '@nestjs/common';
|
|
2
|
-
|
|
3
|
-
import { IdService } from './id.service.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* An IdModule is a module within your application that provides services to generate unique IDs
|
|
7
|
-
* for entities and other data objects.
|
|
8
|
-
* @example
|
|
9
|
-
* ```ts
|
|
10
|
-
* // app.module.ts
|
|
11
|
-
* import { IdModule } from './id.module';
|
|
12
|
-
*
|
|
13
|
-
* @Module({
|
|
14
|
-
* imports: [IdModule],
|
|
15
|
-
* controllers: [AppController],
|
|
16
|
-
* providers: [AppService],
|
|
17
|
-
* })
|
|
18
|
-
* export class AppModule {}
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
@Global()
|
|
22
|
-
@Module({
|
|
23
|
-
providers: [IdService],
|
|
24
|
-
exports: [IdService],
|
|
25
|
-
})
|
|
26
|
-
export class IdModule {}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { Inject, Injectable } from '@nestjs/common';
|
|
2
|
-
import { getConfigToken } from '@nestjs/config';
|
|
3
|
-
import { createRandomString } from '@pcg/text-kit';
|
|
4
|
-
|
|
5
|
-
import { APP_CONFIG_TOKEN, type AppConfigType } from '#/configs/app.config';
|
|
6
|
-
import { AppEnv } from '#/enums';
|
|
7
|
-
import { generateEntityId } from '#/tools/generate-entity-id';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* An IdService is a service within your application that provides methods to generate unique IDs
|
|
11
|
-
* for entities and other data objects.
|
|
12
|
-
*/
|
|
13
|
-
@Injectable()
|
|
14
|
-
export class IdService {
|
|
15
|
-
constructor(
|
|
16
|
-
@Inject(getConfigToken(APP_CONFIG_TOKEN)) private readonly appConfig: AppConfigType,
|
|
17
|
-
) {}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Returns a delimiter string based on the current environment.
|
|
21
|
-
* This delimiter is used in constructing the entity IDs.
|
|
22
|
-
* The delimiter is ':dev:' for development environments,
|
|
23
|
-
* :stage:' for staging environments and ':' for other environments.
|
|
24
|
-
*
|
|
25
|
-
* This allows for better differentiation and traceability of entities across various environments.
|
|
26
|
-
*/
|
|
27
|
-
get delimiter() {
|
|
28
|
-
switch (this.appConfig.env) {
|
|
29
|
-
case AppEnv.TEST:
|
|
30
|
-
return ':test:';
|
|
31
|
-
case AppEnv.DEVELOPMENT:
|
|
32
|
-
return ':dev:';
|
|
33
|
-
case AppEnv.STAGE:
|
|
34
|
-
return ':stage:';
|
|
35
|
-
default:
|
|
36
|
-
return ':';
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Generates unique id for entity
|
|
42
|
-
* @param prefix - entity id prefix in database (e.g. 'u' for users)
|
|
43
|
-
* @param app - app shortname (e.g. 'js')
|
|
44
|
-
* @returns id in format 'jsu:xxxxxxxxxxx' or 'jsu:stage:xxxxxxxxxxx' for staging environment
|
|
45
|
-
*/
|
|
46
|
-
generateEntityId(prefix: string, app?: string): string {
|
|
47
|
-
return generateEntityId(app ?? this.appConfig.shortname, prefix, this.delimiter, 11);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Generates unique id with length 11
|
|
52
|
-
* @returns id in format 'xxxxxxxxxxx'
|
|
53
|
-
*/
|
|
54
|
-
generateId(size?: number) {
|
|
55
|
-
return createRandomString(size);
|
|
56
|
-
}
|
|
57
|
-
}
|
package/src/modules/id/index.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { Global, Module } from '@nestjs/common';
|
|
2
|
-
|
|
3
|
-
import { PostgresPubSub } from './postgres-pubsub.js';
|
|
4
|
-
|
|
5
|
-
@Global()
|
|
6
|
-
@Module({
|
|
7
|
-
providers: [
|
|
8
|
-
PostgresPubSub,
|
|
9
|
-
],
|
|
10
|
-
exports: [
|
|
11
|
-
PostgresPubSub,
|
|
12
|
-
],
|
|
13
|
-
})
|
|
14
|
-
export class PostgresPubSubModule {}
|