@nage-api/core 1.0.0-beta.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/LICENSE +202 -0
- package/README.md +141 -0
- package/dist/bootstrap/bootstrap.d.ts +48 -0
- package/dist/bootstrap/bootstrap.js +255 -0
- package/dist/bootstrap/drain.d.ts +48 -0
- package/dist/bootstrap/drain.js +113 -0
- package/dist/bootstrap/lifecycle.d.ts +30 -0
- package/dist/bootstrap/lifecycle.js +64 -0
- package/dist/bootstrap/process-guards.d.ts +42 -0
- package/dist/bootstrap/process-guards.js +103 -0
- package/dist/bootstrap/query-parser.d.ts +34 -0
- package/dist/bootstrap/query-parser.js +37 -0
- package/dist/bootstrap/shutdown.d.ts +55 -0
- package/dist/bootstrap/shutdown.js +182 -0
- package/dist/constants.d.ts +32 -0
- package/dist/constants.js +48 -0
- package/dist/context/active-context.d.ts +23 -0
- package/dist/context/active-context.js +34 -0
- package/dist/context/request-context.middleware.d.ts +31 -0
- package/dist/context/request-context.middleware.js +95 -0
- package/dist/context/request-context.service.d.ts +29 -0
- package/dist/context/request-context.service.js +67 -0
- package/dist/decorators/owner.decorator.d.ts +18 -0
- package/dist/decorators/owner.decorator.js +31 -0
- package/dist/decorators/public.decorator.d.ts +13 -0
- package/dist/decorators/public.decorator.js +23 -0
- package/dist/decorators/version.decorators.d.ts +34 -0
- package/dist/decorators/version.decorators.js +40 -0
- package/dist/errors/catalog.d.ts +149 -0
- package/dist/errors/catalog.js +289 -0
- package/dist/errors/index.d.ts +3 -0
- package/dist/errors/index.js +22 -0
- package/dist/errors/nage.error.d.ts +43 -0
- package/dist/errors/nage.error.js +45 -0
- package/dist/guards/api-version.guard.d.ts +20 -0
- package/dist/guards/api-version.guard.js +73 -0
- package/dist/http/all-exceptions.filter.d.ts +25 -0
- package/dist/http/all-exceptions.filter.js +256 -0
- package/dist/http/envelope.d.ts +25 -0
- package/dist/http/envelope.js +44 -0
- package/dist/http/no-envelope.decorator.d.ts +11 -0
- package/dist/http/no-envelope.decorator.js +16 -0
- package/dist/http/request-timeout.decorators.d.ts +23 -0
- package/dist/http/request-timeout.decorators.js +29 -0
- package/dist/http/request-timeout.interceptor.d.ts +28 -0
- package/dist/http/request-timeout.interceptor.js +75 -0
- package/dist/http/response.interceptor.d.ts +19 -0
- package/dist/http/response.interceptor.js +73 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +135 -0
- package/dist/job/job.factory.d.ts +29 -0
- package/dist/job/job.factory.js +50 -0
- package/dist/logging/json.logger.d.ts +23 -0
- package/dist/logging/json.logger.js +136 -0
- package/dist/logging/nest-logger.adapter.d.ts +20 -0
- package/dist/logging/nest-logger.adapter.js +46 -0
- package/dist/module/core.module.d.ts +40 -0
- package/dist/module/core.module.js +112 -0
- package/dist/security/audit.d.ts +42 -0
- package/dist/security/audit.js +399 -0
- package/dist/security/index.d.ts +15 -0
- package/dist/security/index.js +50 -0
- package/dist/security/legacy-scan.d.ts +24 -0
- package/dist/security/legacy-scan.js +98 -0
- package/dist/security/random.d.ts +40 -0
- package/dist/security/random.js +87 -0
- package/dist/security/rate-limit.decorators.d.ts +24 -0
- package/dist/security/rate-limit.decorators.js +25 -0
- package/dist/security/rate-limit.guard.d.ts +44 -0
- package/dist/security/rate-limit.guard.js +130 -0
- package/dist/security/rate-limit.store.d.ts +30 -0
- package/dist/security/rate-limit.store.js +63 -0
- package/dist/security/redaction.d.ts +54 -0
- package/dist/security/redaction.js +146 -0
- package/dist/security/tls.d.ts +29 -0
- package/dist/security/tls.js +48 -0
- package/dist/tokens.d.ts +60 -0
- package/dist/tokens.js +89 -0
- package/dist/version.d.ts +5 -0
- package/dist/version.js +8 -0
- package/package.json +77 -0
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The single global response interceptor (PLAN.md §16.1).
|
|
4
|
+
*
|
|
5
|
+
* Controllers `return data`. This wraps it. Nothing in application code touches
|
|
6
|
+
* `res` — the `@Res()` escape hatch used by 18 legacy controllers bypassed the
|
|
7
|
+
* interceptor pipeline entirely and is what made the envelope inconsistent.
|
|
8
|
+
*/
|
|
9
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
10
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
11
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
12
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
13
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
14
|
+
};
|
|
15
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
16
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
17
|
+
};
|
|
18
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
19
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.ResponseInterceptor = void 0;
|
|
23
|
+
const common_1 = require("@nestjs/common");
|
|
24
|
+
const core_1 = require("@nestjs/core");
|
|
25
|
+
const operators_1 = require("rxjs/operators");
|
|
26
|
+
const constants_js_1 = require("../constants.js");
|
|
27
|
+
const request_context_service_js_1 = require("../context/request-context.service.js");
|
|
28
|
+
const envelope_js_1 = require("./envelope.js");
|
|
29
|
+
let ResponseInterceptor = class ResponseInterceptor {
|
|
30
|
+
reflector;
|
|
31
|
+
context;
|
|
32
|
+
constructor(reflector, context) {
|
|
33
|
+
this.reflector = reflector;
|
|
34
|
+
this.context = context;
|
|
35
|
+
}
|
|
36
|
+
intercept(context, next) {
|
|
37
|
+
// Only HTTP responses carry the envelope; websocket and microservice
|
|
38
|
+
// payloads have their own contracts.
|
|
39
|
+
if (context.getType() !== 'http')
|
|
40
|
+
return next.handle();
|
|
41
|
+
const noEnvelope = this.reflector.getAllAndOverride(constants_js_1.METADATA_KEYS.noEnvelope, [context.getHandler(), context.getClass()]);
|
|
42
|
+
if (noEnvelope === true)
|
|
43
|
+
return next.handle();
|
|
44
|
+
return next.handle().pipe((0, operators_1.map)((data) => this.#wrap(data)));
|
|
45
|
+
}
|
|
46
|
+
#wrap(data) {
|
|
47
|
+
const requestContext = this.context.get();
|
|
48
|
+
const requestId = requestContext?.requestId ?? 'unknown';
|
|
49
|
+
const version = requestContext?.apiVersion;
|
|
50
|
+
if ((0, envelope_js_1.isPaginated)(data)) {
|
|
51
|
+
return (0, envelope_js_1.successEnvelope)(data.records, {
|
|
52
|
+
requestId,
|
|
53
|
+
pagination: data.pagination,
|
|
54
|
+
...(version === undefined ? {} : { version }),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// A handler that returns nothing (204, or a delete) still gets a body-shaped
|
|
58
|
+
// envelope with `data: null`, so clients can parse one shape unconditionally.
|
|
59
|
+
return (0, envelope_js_1.successEnvelope)(data === undefined ? null : data, {
|
|
60
|
+
requestId,
|
|
61
|
+
...(version === undefined ? {} : { version }),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
exports.ResponseInterceptor = ResponseInterceptor;
|
|
66
|
+
exports.ResponseInterceptor = ResponseInterceptor = __decorate([
|
|
67
|
+
(0, common_1.Injectable)(),
|
|
68
|
+
__param(0, (0, common_1.Inject)(core_1.Reflector)),
|
|
69
|
+
__param(1, (0, common_1.Inject)(request_context_service_js_1.RequestContextService)),
|
|
70
|
+
__metadata("design:paramtypes", [core_1.Reflector,
|
|
71
|
+
request_context_service_js_1.RequestContextService])
|
|
72
|
+
], ResponseInterceptor);
|
|
73
|
+
//# sourceMappingURL=response.interceptor.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@nage-api/core` — the small mandatory layer every application depends on
|
|
3
|
+
* (PLAN.md §7.2).
|
|
4
|
+
*
|
|
5
|
+
* Core depends on `@nage-api/contracts` and on nothing else: never on a feature
|
|
6
|
+
* package, never on a project entity. That direction is what the legacy
|
|
7
|
+
* `src/core` inverted, and it is enforced in CI.
|
|
8
|
+
*/
|
|
9
|
+
export type * from '@nage-api/contracts';
|
|
10
|
+
export { NAGE_CORE_VERSION, NAGE_MIN_NODE_VERSION } from './version.js';
|
|
11
|
+
export { DEFAULT_REDACTED_FIELDS, DEFAULT_REQUEST_TIMEOUT_MS, API_VERSION_HEADER, CORRELATION_ID_HEADER, DEFAULT_API_VERSION, METADATA_KEYS, REQUEST_ID_HEADER, REQUEST_ID_PATTERN, } from './constants.js';
|
|
12
|
+
export { createToken, keyValueStoreToken, repositoryToken, NAGE_CONFIG, NAGE_LIFECYCLE, NAGE_LOGGER, NAGE_RATE_LIMIT_STORE, NAGE_REQUEST_CONTEXT, NAGE_UNIT_OF_WORK, type Token, } from './tokens.js';
|
|
13
|
+
export { getActiveContext, runWithContext, setContextValue, type MutableRequestContext, } from './context/active-context.js';
|
|
14
|
+
export { RequestContextService } from './context/request-context.service.js';
|
|
15
|
+
export { RequestContextMiddleware, parseApiVersion, resolveRequestId, } from './context/request-context.middleware.js';
|
|
16
|
+
export * from './errors/index.js';
|
|
17
|
+
export { buildMeta, errorEnvelope, isPaginated, successEnvelope, type EnvelopeMetaInput, } from './http/envelope.js';
|
|
18
|
+
export { NoEnvelope } from './http/no-envelope.decorator.js';
|
|
19
|
+
export { ResponseInterceptor } from './http/response.interceptor.js';
|
|
20
|
+
export { AllExceptionsFilter } from './http/all-exceptions.filter.js';
|
|
21
|
+
export { RequestTimeoutInterceptor } from './http/request-timeout.interceptor.js';
|
|
22
|
+
export { RequestTimeout, SkipRequestTimeout } from './http/request-timeout.decorators.js';
|
|
23
|
+
export { Public, isPublicRoute } from './decorators/public.decorator.js';
|
|
24
|
+
export { Owner, OptionalOwner } from './decorators/owner.decorator.js';
|
|
25
|
+
export { BetweenVersions, ForVersion, FromVersion, TillVersion, versionSatisfies, type VersionRule, } from './decorators/version.decorators.js';
|
|
26
|
+
export { ApiVersionGuard } from './guards/api-version.guard.js';
|
|
27
|
+
export { createJob, emptyPage, paginate, type CreateJobInput } from './job/job.factory.js';
|
|
28
|
+
export { JsonLogger } from './logging/json.logger.js';
|
|
29
|
+
export { NestLoggerAdapter } from './logging/nest-logger.adapter.js';
|
|
30
|
+
export * from './security/index.js';
|
|
31
|
+
export { NageCoreModule, buildValidationPipe, type NageCoreModuleOptions, } from './module/core.module.js';
|
|
32
|
+
export { bootstrap, createApplication, resolveCorsOptions, type ApplicationModule, type BootstrapOptions, } from './bootstrap/bootstrap.js';
|
|
33
|
+
export { enableQueryDsl } from './bootstrap/query-parser.js';
|
|
34
|
+
export { LifecycleState, processLifecycle, type LifecyclePhase } from './bootstrap/lifecycle.js';
|
|
35
|
+
export { RequestDrain, requestDrainFor, registerRequestDrain, type DrainMiddleware, type DrainResponseLike, type RequestDrainOptions, } from './bootstrap/drain.js';
|
|
36
|
+
export { installShutdown, shutdownHandleFor, registerShutdownHandle, type ClosableApplication, type ShutdownHandle, type ShutdownOptions, } from './bootstrap/shutdown.js';
|
|
37
|
+
export { installProcessGuards, type DisposeProcessGuards, type FatalKind, type ProcessGuardOptions, } from './bootstrap/process-guards.js';
|
|
38
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `@nage-api/core` — the small mandatory layer every application depends on
|
|
4
|
+
* (PLAN.md §7.2).
|
|
5
|
+
*
|
|
6
|
+
* Core depends on `@nage-api/contracts` and on nothing else: never on a feature
|
|
7
|
+
* package, never on a project entity. That direction is what the legacy
|
|
8
|
+
* `src/core` inverted, and it is enforced in CI.
|
|
9
|
+
*/
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
22
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.JsonLogger = exports.paginate = exports.emptyPage = exports.createJob = exports.ApiVersionGuard = exports.versionSatisfies = exports.TillVersion = exports.FromVersion = exports.ForVersion = exports.BetweenVersions = exports.OptionalOwner = exports.Owner = exports.isPublicRoute = exports.Public = exports.SkipRequestTimeout = exports.RequestTimeout = exports.RequestTimeoutInterceptor = exports.AllExceptionsFilter = exports.ResponseInterceptor = exports.NoEnvelope = exports.successEnvelope = exports.isPaginated = exports.errorEnvelope = exports.buildMeta = exports.resolveRequestId = exports.parseApiVersion = exports.RequestContextMiddleware = exports.RequestContextService = exports.setContextValue = exports.runWithContext = exports.getActiveContext = exports.NAGE_UNIT_OF_WORK = exports.NAGE_REQUEST_CONTEXT = exports.NAGE_RATE_LIMIT_STORE = exports.NAGE_LOGGER = exports.NAGE_LIFECYCLE = exports.NAGE_CONFIG = exports.repositoryToken = exports.keyValueStoreToken = exports.createToken = exports.REQUEST_ID_PATTERN = exports.REQUEST_ID_HEADER = exports.METADATA_KEYS = exports.DEFAULT_API_VERSION = exports.CORRELATION_ID_HEADER = exports.API_VERSION_HEADER = exports.DEFAULT_REQUEST_TIMEOUT_MS = exports.DEFAULT_REDACTED_FIELDS = exports.NAGE_MIN_NODE_VERSION = exports.NAGE_CORE_VERSION = void 0;
|
|
26
|
+
exports.installProcessGuards = exports.registerShutdownHandle = exports.shutdownHandleFor = exports.installShutdown = exports.registerRequestDrain = exports.requestDrainFor = exports.RequestDrain = exports.processLifecycle = exports.LifecycleState = exports.enableQueryDsl = exports.resolveCorsOptions = exports.createApplication = exports.bootstrap = exports.buildValidationPipe = exports.NageCoreModule = exports.NestLoggerAdapter = void 0;
|
|
27
|
+
var version_js_1 = require("./version.js");
|
|
28
|
+
Object.defineProperty(exports, "NAGE_CORE_VERSION", { enumerable: true, get: function () { return version_js_1.NAGE_CORE_VERSION; } });
|
|
29
|
+
Object.defineProperty(exports, "NAGE_MIN_NODE_VERSION", { enumerable: true, get: function () { return version_js_1.NAGE_MIN_NODE_VERSION; } });
|
|
30
|
+
// Configuration surface consumed by bootstrap; the types themselves live in
|
|
31
|
+
// @nage-api/contracts and are re-exported above. @nage-api/config produces a value.
|
|
32
|
+
var constants_js_1 = require("./constants.js");
|
|
33
|
+
Object.defineProperty(exports, "DEFAULT_REDACTED_FIELDS", { enumerable: true, get: function () { return constants_js_1.DEFAULT_REDACTED_FIELDS; } });
|
|
34
|
+
Object.defineProperty(exports, "DEFAULT_REQUEST_TIMEOUT_MS", { enumerable: true, get: function () { return constants_js_1.DEFAULT_REQUEST_TIMEOUT_MS; } });
|
|
35
|
+
Object.defineProperty(exports, "API_VERSION_HEADER", { enumerable: true, get: function () { return constants_js_1.API_VERSION_HEADER; } });
|
|
36
|
+
Object.defineProperty(exports, "CORRELATION_ID_HEADER", { enumerable: true, get: function () { return constants_js_1.CORRELATION_ID_HEADER; } });
|
|
37
|
+
Object.defineProperty(exports, "DEFAULT_API_VERSION", { enumerable: true, get: function () { return constants_js_1.DEFAULT_API_VERSION; } });
|
|
38
|
+
Object.defineProperty(exports, "METADATA_KEYS", { enumerable: true, get: function () { return constants_js_1.METADATA_KEYS; } });
|
|
39
|
+
Object.defineProperty(exports, "REQUEST_ID_HEADER", { enumerable: true, get: function () { return constants_js_1.REQUEST_ID_HEADER; } });
|
|
40
|
+
Object.defineProperty(exports, "REQUEST_ID_PATTERN", { enumerable: true, get: function () { return constants_js_1.REQUEST_ID_PATTERN; } });
|
|
41
|
+
// DI tokens — how feature packages collaborate without importing each other.
|
|
42
|
+
var tokens_js_1 = require("./tokens.js");
|
|
43
|
+
Object.defineProperty(exports, "createToken", { enumerable: true, get: function () { return tokens_js_1.createToken; } });
|
|
44
|
+
Object.defineProperty(exports, "keyValueStoreToken", { enumerable: true, get: function () { return tokens_js_1.keyValueStoreToken; } });
|
|
45
|
+
Object.defineProperty(exports, "repositoryToken", { enumerable: true, get: function () { return tokens_js_1.repositoryToken; } });
|
|
46
|
+
Object.defineProperty(exports, "NAGE_CONFIG", { enumerable: true, get: function () { return tokens_js_1.NAGE_CONFIG; } });
|
|
47
|
+
Object.defineProperty(exports, "NAGE_LIFECYCLE", { enumerable: true, get: function () { return tokens_js_1.NAGE_LIFECYCLE; } });
|
|
48
|
+
Object.defineProperty(exports, "NAGE_LOGGER", { enumerable: true, get: function () { return tokens_js_1.NAGE_LOGGER; } });
|
|
49
|
+
Object.defineProperty(exports, "NAGE_RATE_LIMIT_STORE", { enumerable: true, get: function () { return tokens_js_1.NAGE_RATE_LIMIT_STORE; } });
|
|
50
|
+
Object.defineProperty(exports, "NAGE_REQUEST_CONTEXT", { enumerable: true, get: function () { return tokens_js_1.NAGE_REQUEST_CONTEXT; } });
|
|
51
|
+
Object.defineProperty(exports, "NAGE_UNIT_OF_WORK", { enumerable: true, get: function () { return tokens_js_1.NAGE_UNIT_OF_WORK; } });
|
|
52
|
+
// Request context (CLS).
|
|
53
|
+
var active_context_js_1 = require("./context/active-context.js");
|
|
54
|
+
Object.defineProperty(exports, "getActiveContext", { enumerable: true, get: function () { return active_context_js_1.getActiveContext; } });
|
|
55
|
+
Object.defineProperty(exports, "runWithContext", { enumerable: true, get: function () { return active_context_js_1.runWithContext; } });
|
|
56
|
+
Object.defineProperty(exports, "setContextValue", { enumerable: true, get: function () { return active_context_js_1.setContextValue; } });
|
|
57
|
+
var request_context_service_js_1 = require("./context/request-context.service.js");
|
|
58
|
+
Object.defineProperty(exports, "RequestContextService", { enumerable: true, get: function () { return request_context_service_js_1.RequestContextService; } });
|
|
59
|
+
var request_context_middleware_js_1 = require("./context/request-context.middleware.js");
|
|
60
|
+
Object.defineProperty(exports, "RequestContextMiddleware", { enumerable: true, get: function () { return request_context_middleware_js_1.RequestContextMiddleware; } });
|
|
61
|
+
Object.defineProperty(exports, "parseApiVersion", { enumerable: true, get: function () { return request_context_middleware_js_1.parseApiVersion; } });
|
|
62
|
+
Object.defineProperty(exports, "resolveRequestId", { enumerable: true, get: function () { return request_context_middleware_js_1.resolveRequestId; } });
|
|
63
|
+
// Typed error catalog.
|
|
64
|
+
__exportStar(require("./errors/index.js"), exports);
|
|
65
|
+
// Response envelope, interceptor and exception filter.
|
|
66
|
+
var envelope_js_1 = require("./http/envelope.js");
|
|
67
|
+
Object.defineProperty(exports, "buildMeta", { enumerable: true, get: function () { return envelope_js_1.buildMeta; } });
|
|
68
|
+
Object.defineProperty(exports, "errorEnvelope", { enumerable: true, get: function () { return envelope_js_1.errorEnvelope; } });
|
|
69
|
+
Object.defineProperty(exports, "isPaginated", { enumerable: true, get: function () { return envelope_js_1.isPaginated; } });
|
|
70
|
+
Object.defineProperty(exports, "successEnvelope", { enumerable: true, get: function () { return envelope_js_1.successEnvelope; } });
|
|
71
|
+
var no_envelope_decorator_js_1 = require("./http/no-envelope.decorator.js");
|
|
72
|
+
Object.defineProperty(exports, "NoEnvelope", { enumerable: true, get: function () { return no_envelope_decorator_js_1.NoEnvelope; } });
|
|
73
|
+
var response_interceptor_js_1 = require("./http/response.interceptor.js");
|
|
74
|
+
Object.defineProperty(exports, "ResponseInterceptor", { enumerable: true, get: function () { return response_interceptor_js_1.ResponseInterceptor; } });
|
|
75
|
+
var all_exceptions_filter_js_1 = require("./http/all-exceptions.filter.js");
|
|
76
|
+
Object.defineProperty(exports, "AllExceptionsFilter", { enumerable: true, get: function () { return all_exceptions_filter_js_1.AllExceptionsFilter; } });
|
|
77
|
+
// Request timeout (§21): on by default, per-route overrides for the routes whose
|
|
78
|
+
// duration is the caller's business.
|
|
79
|
+
var request_timeout_interceptor_js_1 = require("./http/request-timeout.interceptor.js");
|
|
80
|
+
Object.defineProperty(exports, "RequestTimeoutInterceptor", { enumerable: true, get: function () { return request_timeout_interceptor_js_1.RequestTimeoutInterceptor; } });
|
|
81
|
+
var request_timeout_decorators_js_1 = require("./http/request-timeout.decorators.js");
|
|
82
|
+
Object.defineProperty(exports, "RequestTimeout", { enumerable: true, get: function () { return request_timeout_decorators_js_1.RequestTimeout; } });
|
|
83
|
+
Object.defineProperty(exports, "SkipRequestTimeout", { enumerable: true, get: function () { return request_timeout_decorators_js_1.SkipRequestTimeout; } });
|
|
84
|
+
// Base decorators and guards.
|
|
85
|
+
var public_decorator_js_1 = require("./decorators/public.decorator.js");
|
|
86
|
+
Object.defineProperty(exports, "Public", { enumerable: true, get: function () { return public_decorator_js_1.Public; } });
|
|
87
|
+
Object.defineProperty(exports, "isPublicRoute", { enumerable: true, get: function () { return public_decorator_js_1.isPublicRoute; } });
|
|
88
|
+
var owner_decorator_js_1 = require("./decorators/owner.decorator.js");
|
|
89
|
+
Object.defineProperty(exports, "Owner", { enumerable: true, get: function () { return owner_decorator_js_1.Owner; } });
|
|
90
|
+
Object.defineProperty(exports, "OptionalOwner", { enumerable: true, get: function () { return owner_decorator_js_1.OptionalOwner; } });
|
|
91
|
+
var version_decorators_js_1 = require("./decorators/version.decorators.js");
|
|
92
|
+
Object.defineProperty(exports, "BetweenVersions", { enumerable: true, get: function () { return version_decorators_js_1.BetweenVersions; } });
|
|
93
|
+
Object.defineProperty(exports, "ForVersion", { enumerable: true, get: function () { return version_decorators_js_1.ForVersion; } });
|
|
94
|
+
Object.defineProperty(exports, "FromVersion", { enumerable: true, get: function () { return version_decorators_js_1.FromVersion; } });
|
|
95
|
+
Object.defineProperty(exports, "TillVersion", { enumerable: true, get: function () { return version_decorators_js_1.TillVersion; } });
|
|
96
|
+
Object.defineProperty(exports, "versionSatisfies", { enumerable: true, get: function () { return version_decorators_js_1.versionSatisfies; } });
|
|
97
|
+
var api_version_guard_js_1 = require("./guards/api-version.guard.js");
|
|
98
|
+
Object.defineProperty(exports, "ApiVersionGuard", { enumerable: true, get: function () { return api_version_guard_js_1.ApiVersionGuard; } });
|
|
99
|
+
// Job / pagination helpers.
|
|
100
|
+
var job_factory_js_1 = require("./job/job.factory.js");
|
|
101
|
+
Object.defineProperty(exports, "createJob", { enumerable: true, get: function () { return job_factory_js_1.createJob; } });
|
|
102
|
+
Object.defineProperty(exports, "emptyPage", { enumerable: true, get: function () { return job_factory_js_1.emptyPage; } });
|
|
103
|
+
Object.defineProperty(exports, "paginate", { enumerable: true, get: function () { return job_factory_js_1.paginate; } });
|
|
104
|
+
// Logging.
|
|
105
|
+
var json_logger_js_1 = require("./logging/json.logger.js");
|
|
106
|
+
Object.defineProperty(exports, "JsonLogger", { enumerable: true, get: function () { return json_logger_js_1.JsonLogger; } });
|
|
107
|
+
var nest_logger_adapter_js_1 = require("./logging/nest-logger.adapter.js");
|
|
108
|
+
Object.defineProperty(exports, "NestLoggerAdapter", { enumerable: true, get: function () { return nest_logger_adapter_js_1.NestLoggerAdapter; } });
|
|
109
|
+
// Security baseline (§12): CSPRNG, redaction, TLS policy, throttling, audit.
|
|
110
|
+
__exportStar(require("./security/index.js"), exports);
|
|
111
|
+
// Module and bootstrap.
|
|
112
|
+
var core_module_js_1 = require("./module/core.module.js");
|
|
113
|
+
Object.defineProperty(exports, "NageCoreModule", { enumerable: true, get: function () { return core_module_js_1.NageCoreModule; } });
|
|
114
|
+
Object.defineProperty(exports, "buildValidationPipe", { enumerable: true, get: function () { return core_module_js_1.buildValidationPipe; } });
|
|
115
|
+
var bootstrap_js_1 = require("./bootstrap/bootstrap.js");
|
|
116
|
+
Object.defineProperty(exports, "bootstrap", { enumerable: true, get: function () { return bootstrap_js_1.bootstrap; } });
|
|
117
|
+
Object.defineProperty(exports, "createApplication", { enumerable: true, get: function () { return bootstrap_js_1.createApplication; } });
|
|
118
|
+
Object.defineProperty(exports, "resolveCorsOptions", { enumerable: true, get: function () { return bootstrap_js_1.resolveCorsOptions; } });
|
|
119
|
+
var query_parser_js_1 = require("./bootstrap/query-parser.js");
|
|
120
|
+
Object.defineProperty(exports, "enableQueryDsl", { enumerable: true, get: function () { return query_parser_js_1.enableQueryDsl; } });
|
|
121
|
+
// Production lifecycle (§21): ordered drain, readiness phase, fatal-error policy.
|
|
122
|
+
var lifecycle_js_1 = require("./bootstrap/lifecycle.js");
|
|
123
|
+
Object.defineProperty(exports, "LifecycleState", { enumerable: true, get: function () { return lifecycle_js_1.LifecycleState; } });
|
|
124
|
+
Object.defineProperty(exports, "processLifecycle", { enumerable: true, get: function () { return lifecycle_js_1.processLifecycle; } });
|
|
125
|
+
var drain_js_1 = require("./bootstrap/drain.js");
|
|
126
|
+
Object.defineProperty(exports, "RequestDrain", { enumerable: true, get: function () { return drain_js_1.RequestDrain; } });
|
|
127
|
+
Object.defineProperty(exports, "requestDrainFor", { enumerable: true, get: function () { return drain_js_1.requestDrainFor; } });
|
|
128
|
+
Object.defineProperty(exports, "registerRequestDrain", { enumerable: true, get: function () { return drain_js_1.registerRequestDrain; } });
|
|
129
|
+
var shutdown_js_1 = require("./bootstrap/shutdown.js");
|
|
130
|
+
Object.defineProperty(exports, "installShutdown", { enumerable: true, get: function () { return shutdown_js_1.installShutdown; } });
|
|
131
|
+
Object.defineProperty(exports, "shutdownHandleFor", { enumerable: true, get: function () { return shutdown_js_1.shutdownHandleFor; } });
|
|
132
|
+
Object.defineProperty(exports, "registerShutdownHandle", { enumerable: true, get: function () { return shutdown_js_1.registerShutdownHandle; } });
|
|
133
|
+
var process_guards_js_1 = require("./bootstrap/process-guards.js");
|
|
134
|
+
Object.defineProperty(exports, "installProcessGuards", { enumerable: true, get: function () { return process_guards_js_1.installProcessGuards; } });
|
|
135
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime helpers for the `Job` / `Paginated` contracts (PLAN.md §13, §14.1).
|
|
3
|
+
*
|
|
4
|
+
* The `Job` work unit and its lifecycle hooks are the legacy framework's best
|
|
5
|
+
* idea; what undercut them was `body: any` / `records: any[]`. `@nage-api/data`
|
|
6
|
+
* (Phase 5) builds every job through these helpers so a job is typed against its
|
|
7
|
+
* entity from the moment it is created.
|
|
8
|
+
*/
|
|
9
|
+
import type { DeepPartial, Job, JobAction, Paginated, PaginationMeta, RequestContext, UnknownRecord } from '@nage-api/contracts';
|
|
10
|
+
export interface CreateJobInput<TEntity, TBody, TParams extends UnknownRecord> {
|
|
11
|
+
readonly action: JobAction;
|
|
12
|
+
readonly params?: TParams;
|
|
13
|
+
readonly query?: Job<TEntity, TBody, TParams>['query'];
|
|
14
|
+
readonly body?: TBody;
|
|
15
|
+
readonly id?: Job<TEntity, TBody, TParams>['id'];
|
|
16
|
+
readonly deleteMode?: Job<TEntity, TBody, TParams>['deleteMode'];
|
|
17
|
+
/** Defaults to the ambient request context. */
|
|
18
|
+
readonly context?: RequestContext;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build a job, defaulting the owner and context from the active request — the
|
|
22
|
+
* reason audit columns and ownership scoping need no plumbing at call sites.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createJob<TEntity, TBody = DeepPartial<TEntity>, TParams extends UnknownRecord = UnknownRecord>(input: CreateJobInput<TEntity, TBody, TParams>): Job<TEntity, TBody, TParams>;
|
|
25
|
+
/** Assemble the standard page shape returned by every repository. */
|
|
26
|
+
export declare function paginate<TEntity>(records: readonly TEntity[], pagination: PaginationMeta): Paginated<TEntity>;
|
|
27
|
+
/** An empty page — the correct answer for a filtered query with no matches. */
|
|
28
|
+
export declare function emptyPage<TEntity>(offset?: number, limit?: number): Paginated<TEntity>;
|
|
29
|
+
//# sourceMappingURL=job.factory.d.ts.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Runtime helpers for the `Job` / `Paginated` contracts (PLAN.md §13, §14.1).
|
|
4
|
+
*
|
|
5
|
+
* The `Job` work unit and its lifecycle hooks are the legacy framework's best
|
|
6
|
+
* idea; what undercut them was `body: any` / `records: any[]`. `@nage-api/data`
|
|
7
|
+
* (Phase 5) builds every job through these helpers so a job is typed against its
|
|
8
|
+
* entity from the moment it is created.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.createJob = createJob;
|
|
12
|
+
exports.paginate = paginate;
|
|
13
|
+
exports.emptyPage = emptyPage;
|
|
14
|
+
const active_context_js_1 = require("../context/active-context.js");
|
|
15
|
+
const catalog_js_1 = require("../errors/catalog.js");
|
|
16
|
+
/**
|
|
17
|
+
* Build a job, defaulting the owner and context from the active request — the
|
|
18
|
+
* reason audit columns and ownership scoping need no plumbing at call sites.
|
|
19
|
+
*/
|
|
20
|
+
function createJob(input) {
|
|
21
|
+
const context = input.context ?? (0, active_context_js_1.getActiveContext)();
|
|
22
|
+
if (context === undefined) {
|
|
23
|
+
throw new catalog_js_1.InternalError({
|
|
24
|
+
detail: 'A job needs a request context',
|
|
25
|
+
meta: {
|
|
26
|
+
action: input.action,
|
|
27
|
+
hint: 'Create the job inside a request, or pass `context` explicitly for background work.',
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
action: input.action,
|
|
33
|
+
params: input.params ?? {},
|
|
34
|
+
query: input.query ?? {},
|
|
35
|
+
body: input.body ?? {},
|
|
36
|
+
context,
|
|
37
|
+
...(input.id === undefined ? {} : { id: input.id }),
|
|
38
|
+
...(context.user === undefined ? {} : { owner: context.user }),
|
|
39
|
+
...(input.deleteMode === undefined ? {} : { deleteMode: input.deleteMode }),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Assemble the standard page shape returned by every repository. */
|
|
43
|
+
function paginate(records, pagination) {
|
|
44
|
+
return { records, pagination };
|
|
45
|
+
}
|
|
46
|
+
/** An empty page — the correct answer for a filtered query with no matches. */
|
|
47
|
+
function emptyPage(offset = 0, limit = 0) {
|
|
48
|
+
return { records: [], pagination: { offset, limit, count: 0 } };
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=job.factory.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal structured logger (PLAN.md §18).
|
|
3
|
+
*
|
|
4
|
+
* Newline-delimited JSON to stdout, with the correlation id pulled from the
|
|
5
|
+
* ambient context so no caller has to remember to pass it, and configured
|
|
6
|
+
* fields redacted before anything is written. `@nage-api/observability` (Phase 8)
|
|
7
|
+
* replaces this with pino behind the same `LoggerPort` — nothing else changes.
|
|
8
|
+
*/
|
|
9
|
+
import type { LogFields, LoggerPort, NageCoreConfig } from '@nage-api/contracts';
|
|
10
|
+
import { RequestContextService } from '../context/request-context.service.js';
|
|
11
|
+
export declare class JsonLogger implements LoggerPort {
|
|
12
|
+
#private;
|
|
13
|
+
private readonly context?;
|
|
14
|
+
constructor(context?: RequestContextService | undefined, config?: NageCoreConfig);
|
|
15
|
+
trace(message: string, fields?: LogFields): void;
|
|
16
|
+
debug(message: string, fields?: LogFields): void;
|
|
17
|
+
info(message: string, fields?: LogFields): void;
|
|
18
|
+
warn(message: string, fields?: LogFields): void;
|
|
19
|
+
error(message: string, fields?: LogFields): void;
|
|
20
|
+
fatal(message: string, fields?: LogFields): void;
|
|
21
|
+
child(bindings: LogFields): LoggerPort;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=json.logger.d.ts.map
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Minimal structured logger (PLAN.md §18).
|
|
4
|
+
*
|
|
5
|
+
* Newline-delimited JSON to stdout, with the correlation id pulled from the
|
|
6
|
+
* ambient context so no caller has to remember to pass it, and configured
|
|
7
|
+
* fields redacted before anything is written. `@nage-api/observability` (Phase 8)
|
|
8
|
+
* replaces this with pino behind the same `LoggerPort` — nothing else changes.
|
|
9
|
+
*/
|
|
10
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
11
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
12
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
13
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
14
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
15
|
+
};
|
|
16
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
17
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
18
|
+
};
|
|
19
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
20
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
21
|
+
};
|
|
22
|
+
var JsonLogger_1;
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.JsonLogger = void 0;
|
|
25
|
+
const common_1 = require("@nestjs/common");
|
|
26
|
+
const request_context_service_js_1 = require("../context/request-context.service.js");
|
|
27
|
+
const redaction_js_1 = require("../security/redaction.js");
|
|
28
|
+
const tokens_js_1 = require("../tokens.js");
|
|
29
|
+
const LEVEL_ORDER = {
|
|
30
|
+
trace: 10,
|
|
31
|
+
debug: 20,
|
|
32
|
+
info: 30,
|
|
33
|
+
warn: 40,
|
|
34
|
+
error: 50,
|
|
35
|
+
fatal: 60,
|
|
36
|
+
};
|
|
37
|
+
let JsonLogger = JsonLogger_1 = class JsonLogger {
|
|
38
|
+
context;
|
|
39
|
+
#minimum;
|
|
40
|
+
#redacted;
|
|
41
|
+
#json;
|
|
42
|
+
#config;
|
|
43
|
+
/** Set only via `child()`; not a constructor parameter, which Nest would try to inject. */
|
|
44
|
+
#bindings = {};
|
|
45
|
+
constructor(context, config) {
|
|
46
|
+
this.context = context;
|
|
47
|
+
this.#minimum = LEVEL_ORDER[config?.logging?.level ?? 'info'];
|
|
48
|
+
this.#redacted = (0, redaction_js_1.redactionSet)(config?.logging?.redact ?? []);
|
|
49
|
+
this.#json = config?.logging?.json ?? config?.app.environment !== 'development';
|
|
50
|
+
this.#config = config;
|
|
51
|
+
}
|
|
52
|
+
trace(message, fields) {
|
|
53
|
+
this.#write('trace', message, fields);
|
|
54
|
+
}
|
|
55
|
+
debug(message, fields) {
|
|
56
|
+
this.#write('debug', message, fields);
|
|
57
|
+
}
|
|
58
|
+
info(message, fields) {
|
|
59
|
+
this.#write('info', message, fields);
|
|
60
|
+
}
|
|
61
|
+
warn(message, fields) {
|
|
62
|
+
this.#write('warn', message, fields);
|
|
63
|
+
}
|
|
64
|
+
error(message, fields) {
|
|
65
|
+
this.#write('error', message, fields);
|
|
66
|
+
}
|
|
67
|
+
fatal(message, fields) {
|
|
68
|
+
this.#write('fatal', message, fields);
|
|
69
|
+
}
|
|
70
|
+
child(bindings) {
|
|
71
|
+
const logger = new JsonLogger_1(this.context, this.#config);
|
|
72
|
+
logger.#bindings = { ...this.#bindings, ...bindings };
|
|
73
|
+
return logger;
|
|
74
|
+
}
|
|
75
|
+
#write(level, message, fields = {}) {
|
|
76
|
+
if (LEVEL_ORDER[level] < this.#minimum)
|
|
77
|
+
return;
|
|
78
|
+
const context = this.context?.get();
|
|
79
|
+
const scrubbed = (0, redaction_js_1.redact)(fields, this.#redacted);
|
|
80
|
+
const entry = {
|
|
81
|
+
level,
|
|
82
|
+
time: new Date().toISOString(),
|
|
83
|
+
message,
|
|
84
|
+
...this.#bindings,
|
|
85
|
+
...(context === undefined
|
|
86
|
+
? {}
|
|
87
|
+
: {
|
|
88
|
+
requestId: context.requestId,
|
|
89
|
+
...(context.user === undefined ? {} : { userId: context.user.id }),
|
|
90
|
+
...(context.tenantId === undefined ? {} : { tenantId: context.tenantId }),
|
|
91
|
+
}),
|
|
92
|
+
...scrubbed,
|
|
93
|
+
};
|
|
94
|
+
// The pretty line gets the *scrubbed* fields, not the originals. It used to
|
|
95
|
+
// print `fields`, so `logging.json: false` — the documented setting for
|
|
96
|
+
// human-readable output, and the default outside production — wrote
|
|
97
|
+
// passwords and bearer tokens in clear.
|
|
98
|
+
const fallback = { level, time: entry.time, message };
|
|
99
|
+
const line = this.#json
|
|
100
|
+
? safeStringify(entry, fallback)
|
|
101
|
+
: `${entry.time} ${level.toUpperCase().padEnd(5)} ${message} ${safeStringify(scrubbed, {})}`;
|
|
102
|
+
// Written directly rather than through console so the stream stays a single
|
|
103
|
+
// newline-delimited JSON document, exactly as a log shipper expects.
|
|
104
|
+
const stream = LEVEL_ORDER[level] >= LEVEL_ORDER.error ? process.stderr : process.stdout;
|
|
105
|
+
stream.write(`${line}\n`);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
exports.JsonLogger = JsonLogger;
|
|
109
|
+
exports.JsonLogger = JsonLogger = JsonLogger_1 = __decorate([
|
|
110
|
+
(0, common_1.Injectable)(),
|
|
111
|
+
__param(0, (0, common_1.Optional)()),
|
|
112
|
+
__param(0, (0, common_1.Inject)(request_context_service_js_1.RequestContextService)),
|
|
113
|
+
__param(1, (0, common_1.Optional)()),
|
|
114
|
+
__param(1, (0, common_1.Inject)(tokens_js_1.NAGE_CONFIG)),
|
|
115
|
+
__metadata("design:paramtypes", [request_context_service_js_1.RequestContextService, Object])
|
|
116
|
+
], JsonLogger);
|
|
117
|
+
/**
|
|
118
|
+
* A log call must never be the thing that fails a request.
|
|
119
|
+
*
|
|
120
|
+
* `redact` already replaces cycles, but a field can still carry a getter that
|
|
121
|
+
* throws or a `toJSON` that does, and `JSON.stringify` propagates both. The
|
|
122
|
+
* fallback keeps the level, time and message — what an operator needs in order
|
|
123
|
+
* to find the request — and records why the fields are missing.
|
|
124
|
+
*/
|
|
125
|
+
function safeStringify(entry, fallback) {
|
|
126
|
+
try {
|
|
127
|
+
return JSON.stringify(entry);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
return JSON.stringify({
|
|
131
|
+
...fallback,
|
|
132
|
+
fieldsError: error instanceof Error ? error.message : String(error),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=json.logger.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridges Nest's internal `LoggerService` onto our `LoggerPort` (PLAN.md §18).
|
|
3
|
+
*
|
|
4
|
+
* Without this, a process emits two log formats: Nest's coloured boot lines and
|
|
5
|
+
* the framework's JSON. One structured stream is the whole point — a log shipper
|
|
6
|
+
* should never have to parse two grammars from one stdout.
|
|
7
|
+
*/
|
|
8
|
+
import type { LoggerService } from '@nestjs/common';
|
|
9
|
+
import type { LoggerPort } from '@nage-api/contracts';
|
|
10
|
+
export declare class NestLoggerAdapter implements LoggerService {
|
|
11
|
+
private readonly logger;
|
|
12
|
+
constructor(logger: LoggerPort);
|
|
13
|
+
log(message: unknown, ...optional: unknown[]): void;
|
|
14
|
+
error(message: unknown, ...optional: unknown[]): void;
|
|
15
|
+
warn(message: unknown, ...optional: unknown[]): void;
|
|
16
|
+
debug(message: unknown, ...optional: unknown[]): void;
|
|
17
|
+
verbose(message: unknown, ...optional: unknown[]): void;
|
|
18
|
+
fatal(message: unknown, ...optional: unknown[]): void;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=nest-logger.adapter.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Bridges Nest's internal `LoggerService` onto our `LoggerPort` (PLAN.md §18).
|
|
4
|
+
*
|
|
5
|
+
* Without this, a process emits two log formats: Nest's coloured boot lines and
|
|
6
|
+
* the framework's JSON. One structured stream is the whole point — a log shipper
|
|
7
|
+
* should never have to parse two grammars from one stdout.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.NestLoggerAdapter = void 0;
|
|
11
|
+
function fields(context, extra = {}) {
|
|
12
|
+
return typeof context === 'string' ? { context, ...extra } : extra;
|
|
13
|
+
}
|
|
14
|
+
function messageOf(message) {
|
|
15
|
+
return typeof message === 'string' ? message : JSON.stringify(message);
|
|
16
|
+
}
|
|
17
|
+
class NestLoggerAdapter {
|
|
18
|
+
logger;
|
|
19
|
+
constructor(logger) {
|
|
20
|
+
this.logger = logger;
|
|
21
|
+
}
|
|
22
|
+
log(message, ...optional) {
|
|
23
|
+
this.logger.info(messageOf(message), fields(optional[0]));
|
|
24
|
+
}
|
|
25
|
+
error(message, ...optional) {
|
|
26
|
+
const [trace, context] = optional;
|
|
27
|
+
this.logger.error(messageOf(message), {
|
|
28
|
+
...fields(context ?? trace),
|
|
29
|
+
...(typeof trace === 'string' ? { stack: trace } : {}),
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
warn(message, ...optional) {
|
|
33
|
+
this.logger.warn(messageOf(message), fields(optional[0]));
|
|
34
|
+
}
|
|
35
|
+
debug(message, ...optional) {
|
|
36
|
+
this.logger.debug(messageOf(message), fields(optional[0]));
|
|
37
|
+
}
|
|
38
|
+
verbose(message, ...optional) {
|
|
39
|
+
this.logger.trace(messageOf(message), fields(optional[0]));
|
|
40
|
+
}
|
|
41
|
+
fatal(message, ...optional) {
|
|
42
|
+
this.logger.fatal(messageOf(message), fields(optional[0]));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
exports.NestLoggerAdapter = NestLoggerAdapter;
|
|
46
|
+
//# sourceMappingURL=nest-logger.adapter.js.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `NageCoreModule.forRoot(config)` — the one module every application imports
|
|
3
|
+
* (PLAN.md §7.3).
|
|
4
|
+
*
|
|
5
|
+
* Registering the interceptor, filter and guard as providers (rather than
|
|
6
|
+
* `app.useGlobal*`) keeps them inside the DI container, so they can inject the
|
|
7
|
+
* context and the logger, and so tests get the same wiring as production.
|
|
8
|
+
*/
|
|
9
|
+
import { ValidationPipe, type DynamicModule, type MiddlewareConsumer, type NestModule } from '@nestjs/common';
|
|
10
|
+
import type { NageCoreConfig, RateLimitStore } from '@nage-api/contracts';
|
|
11
|
+
/**
|
|
12
|
+
* Validation defaults (§16.2). `forbidNonWhitelisted` means an unexpected
|
|
13
|
+
* property is an error rather than something silently dropped — a mass-assignment
|
|
14
|
+
* guard, not a style preference.
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildValidationPipe(config: NageCoreConfig): ValidationPipe;
|
|
17
|
+
/**
|
|
18
|
+
* Wiring that is a decision rather than configuration, so it does not belong in
|
|
19
|
+
* `NageCoreConfig` — a `NageCoreConfig` is data, loadable from a file or an
|
|
20
|
+
* environment, and a store is an object with a connection.
|
|
21
|
+
*/
|
|
22
|
+
export interface NageCoreModuleOptions {
|
|
23
|
+
/**
|
|
24
|
+
* Counter store behind the global throttle (§12). Defaults to
|
|
25
|
+
* `MemoryRateLimitStore`, which counts **per process** — so with the default,
|
|
26
|
+
* a limit of N across M instances is really N×M. A multi-instance deployment
|
|
27
|
+
* passes a shared implementation here.
|
|
28
|
+
*
|
|
29
|
+
* Supplying it from the application module instead does not work and is worth
|
|
30
|
+
* saying explicitly: `forRoot` binds `NAGE_RATE_LIMIT_STORE` inside this
|
|
31
|
+
* module, and `RateLimitGuard` resolves it from this module's injector, so an
|
|
32
|
+
* app-level provider for the same token is simply not the one the guard sees.
|
|
33
|
+
*/
|
|
34
|
+
readonly rateLimitStore?: RateLimitStore;
|
|
35
|
+
}
|
|
36
|
+
export declare class NageCoreModule implements NestModule {
|
|
37
|
+
static forRoot(config: NageCoreConfig, options?: NageCoreModuleOptions): DynamicModule;
|
|
38
|
+
configure(consumer: MiddlewareConsumer): void;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=core.module.d.ts.map
|