@pipeline-builder/api-core 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +51 -0
- package/lib/constants/ai-providers.d.ts +41 -0
- package/lib/constants/ai-providers.js +88 -0
- package/lib/constants/http-status.d.ts +24 -0
- package/lib/constants/http-status.js +29 -0
- package/lib/constants/index.d.ts +3 -0
- package/lib/constants/index.js +22 -0
- package/lib/constants/time.d.ts +10 -0
- package/lib/constants/time.js +16 -0
- package/lib/errors/app-errors.d.ts +30 -0
- package/lib/errors/app-errors.js +62 -0
- package/lib/errors/index.d.ts +1 -0
- package/lib/errors/index.js +20 -0
- package/lib/helpers/access-helpers.d.ts +40 -0
- package/lib/helpers/access-helpers.js +56 -0
- package/lib/helpers/crud-helpers.d.ts +16 -0
- package/lib/helpers/crud-helpers.js +34 -0
- package/lib/helpers/index.d.ts +4 -0
- package/lib/helpers/index.js +23 -0
- package/lib/helpers/mask-helpers.d.ts +33 -0
- package/lib/helpers/mask-helpers.js +54 -0
- package/lib/helpers/sse-helpers.d.ts +13 -0
- package/lib/helpers/sse-helpers.js +40 -0
- package/lib/index.d.ts +57 -0
- package/lib/index.js +86 -0
- package/lib/middleware/auth.d.ts +50 -0
- package/lib/middleware/auth.js +171 -0
- package/lib/middleware/index.d.ts +1 -0
- package/lib/middleware/index.js +20 -0
- package/lib/openapi/extend-zod.d.ts +1 -0
- package/lib/openapi/extend-zod.js +8 -0
- package/lib/openapi/index.d.ts +2 -0
- package/lib/openapi/index.js +10 -0
- package/lib/openapi/registry.d.ts +17 -0
- package/lib/openapi/registry.js +42 -0
- package/lib/openapi/routes/billing-routes.d.ts +1 -0
- package/lib/openapi/routes/billing-routes.js +69 -0
- package/lib/openapi/routes/index.d.ts +5 -0
- package/lib/openapi/routes/index.js +22 -0
- package/lib/openapi/routes/message-routes.d.ts +1 -0
- package/lib/openapi/routes/message-routes.js +108 -0
- package/lib/openapi/routes/pipeline-routes.d.ts +1 -0
- package/lib/openapi/routes/pipeline-routes.js +90 -0
- package/lib/openapi/routes/plugin-routes.d.ts +1 -0
- package/lib/openapi/routes/plugin-routes.js +99 -0
- package/lib/openapi/routes/quota-routes.d.ts +1 -0
- package/lib/openapi/routes/quota-routes.js +65 -0
- package/lib/openapi/schema-registry.d.ts +25 -0
- package/lib/openapi/schema-registry.js +95 -0
- package/lib/routes/health.d.ts +47 -0
- package/lib/routes/health.js +81 -0
- package/lib/routes/index.d.ts +1 -0
- package/lib/routes/index.js +20 -0
- package/lib/services/admin-audit.d.ts +13 -0
- package/lib/services/admin-audit.js +31 -0
- package/lib/services/cache-service.d.ts +108 -0
- package/lib/services/cache-service.js +212 -0
- package/lib/services/compliance-client.d.ts +46 -0
- package/lib/services/compliance-client.js +102 -0
- package/lib/services/compliance-event-subscriber.d.ts +11 -0
- package/lib/services/compliance-event-subscriber.js +60 -0
- package/lib/services/compliance-queue.d.ts +11 -0
- package/lib/services/compliance-queue.js +38 -0
- package/lib/services/entity-events.d.ts +44 -0
- package/lib/services/entity-events.js +63 -0
- package/lib/services/http-client.d.ts +108 -0
- package/lib/services/http-client.js +285 -0
- package/lib/services/index.d.ts +10 -0
- package/lib/services/index.js +40 -0
- package/lib/services/quota.d.ts +59 -0
- package/lib/services/quota.js +137 -0
- package/lib/services/retry-strategy.d.ts +74 -0
- package/lib/services/retry-strategy.js +127 -0
- package/lib/types/billing.d.ts +47 -0
- package/lib/types/billing.js +5 -0
- package/lib/types/common.d.ts +161 -0
- package/lib/types/common.js +53 -0
- package/lib/types/error-codes.d.ts +38 -0
- package/lib/types/error-codes.js +77 -0
- package/lib/types/feature-flags.d.ts +38 -0
- package/lib/types/feature-flags.js +107 -0
- package/lib/types/http.d.ts +37 -0
- package/lib/types/http.js +5 -0
- package/lib/types/index.d.ts +7 -0
- package/lib/types/index.js +26 -0
- package/lib/types/pipeline.d.ts +70 -0
- package/lib/types/pipeline.js +44 -0
- package/lib/types/quota-tiers.d.ts +23 -0
- package/lib/types/quota-tiers.js +26 -0
- package/lib/utils/alias-resolver.d.ts +16 -0
- package/lib/utils/alias-resolver.js +49 -0
- package/lib/utils/headers.d.ts +18 -0
- package/lib/utils/headers.js +24 -0
- package/lib/utils/identity.d.ts +61 -0
- package/lib/utils/identity.js +75 -0
- package/lib/utils/index.d.ts +7 -0
- package/lib/utils/index.js +26 -0
- package/lib/utils/logger.d.ts +28 -0
- package/lib/utils/logger.js +77 -0
- package/lib/utils/object.d.ts +13 -0
- package/lib/utils/object.js +21 -0
- package/lib/utils/params.d.ts +89 -0
- package/lib/utils/params.js +148 -0
- package/lib/utils/response.d.ts +142 -0
- package/lib/utils/response.js +237 -0
- package/lib/validation/ai-schemas.d.ts +61 -0
- package/lib/validation/ai-schemas.js +81 -0
- package/lib/validation/common-schemas.d.ts +72 -0
- package/lib/validation/common-schemas.js +58 -0
- package/lib/validation/index.d.ts +6 -0
- package/lib/validation/index.js +25 -0
- package/lib/validation/message-schemas.d.ts +79 -0
- package/lib/validation/message-schemas.js +42 -0
- package/lib/validation/middleware.d.ts +60 -0
- package/lib/validation/middleware.js +77 -0
- package/lib/validation/pipeline-schemas.d.ts +135 -0
- package/lib/validation/pipeline-schemas.js +85 -0
- package/lib/validation/plugin-schemas.d.ts +127 -0
- package/lib/validation/plugin-schemas.js +84 -0
- package/openapi.yaml +292 -0
- package/package.json +127 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Request, Response } from 'express';
|
|
2
|
+
/**
|
|
3
|
+
* Apply access control to a filter object.
|
|
4
|
+
*
|
|
5
|
+
* Non-system-admins are restricted to 'private' (org-scoped) resources.
|
|
6
|
+
* System admins see all access modifiers.
|
|
7
|
+
*
|
|
8
|
+
* @param filter - Query filter to modify
|
|
9
|
+
* @param req - Express request (used to check admin status)
|
|
10
|
+
* @returns Filter with accessModifier applied for non-admins
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const effectiveFilter = applyAccessControl(filter, req);
|
|
15
|
+
* const results = await service.find(effectiveFilter, orgId);
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function applyAccessControl<T extends {
|
|
19
|
+
accessModifier?: string;
|
|
20
|
+
}>(filter: T, req: Request): T;
|
|
21
|
+
/**
|
|
22
|
+
* Check whether a non-admin user may modify a public resource.
|
|
23
|
+
*
|
|
24
|
+
* Returns `true` if the request may proceed. Returns `false` and sends
|
|
25
|
+
* a 403 response if the user lacks permission.
|
|
26
|
+
*
|
|
27
|
+
* @param req - Express request
|
|
28
|
+
* @param res - Express response
|
|
29
|
+
* @param resource - Resource with an accessModifier field
|
|
30
|
+
* @returns `true` if access is allowed, `false` if blocked (response already sent)
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* if (!requirePublicAccess(req, res, pipeline)) return;
|
|
35
|
+
* await pipelineService.delete(id, orgId, userId);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function requirePublicAccess(req: Request, res: Response, resource: {
|
|
39
|
+
accessModifier?: string;
|
|
40
|
+
}): boolean;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.applyAccessControl = applyAccessControl;
|
|
6
|
+
exports.requirePublicAccess = requirePublicAccess;
|
|
7
|
+
const auth_1 = require("../middleware/auth");
|
|
8
|
+
const error_codes_1 = require("../types/error-codes");
|
|
9
|
+
const pipeline_1 = require("../types/pipeline");
|
|
10
|
+
const response_1 = require("../utils/response");
|
|
11
|
+
/**
|
|
12
|
+
* Apply access control to a filter object.
|
|
13
|
+
*
|
|
14
|
+
* Non-system-admins are restricted to 'private' (org-scoped) resources.
|
|
15
|
+
* System admins see all access modifiers.
|
|
16
|
+
*
|
|
17
|
+
* @param filter - Query filter to modify
|
|
18
|
+
* @param req - Express request (used to check admin status)
|
|
19
|
+
* @returns Filter with accessModifier applied for non-admins
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const effectiveFilter = applyAccessControl(filter, req);
|
|
24
|
+
* const results = await service.find(effectiveFilter, orgId);
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
function applyAccessControl(filter, req) {
|
|
28
|
+
return !(0, auth_1.isSystemAdmin)(req)
|
|
29
|
+
? { ...filter, accessModifier: pipeline_1.AccessModifier.PRIVATE }
|
|
30
|
+
: filter;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Check whether a non-admin user may modify a public resource.
|
|
34
|
+
*
|
|
35
|
+
* Returns `true` if the request may proceed. Returns `false` and sends
|
|
36
|
+
* a 403 response if the user lacks permission.
|
|
37
|
+
*
|
|
38
|
+
* @param req - Express request
|
|
39
|
+
* @param res - Express response
|
|
40
|
+
* @param resource - Resource with an accessModifier field
|
|
41
|
+
* @returns `true` if access is allowed, `false` if blocked (response already sent)
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* if (!requirePublicAccess(req, res, pipeline)) return;
|
|
46
|
+
* await pipelineService.delete(id, orgId, userId);
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
function requirePublicAccess(req, res, resource) {
|
|
50
|
+
if (!(0, auth_1.isSystemAdmin)(req) && resource.accessModifier !== pipeline_1.AccessModifier.PRIVATE) {
|
|
51
|
+
(0, response_1.sendError)(res, 403, 'Only system admins can modify public resources.', error_codes_1.ErrorCode.INSUFFICIENT_PERMISSIONS);
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLWhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaGVscGVycy9hY2Nlc3MtaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsK0NBQStDO0FBQy9DLHNDQUFzQzs7QUF3QnRDLGdEQU9DO0FBbUJELGtEQWVDO0FBOURELDZDQUFtRDtBQUNuRCxzREFBaUQ7QUFDakQsZ0RBQW1EO0FBQ25ELGdEQUE4QztBQUU5Qzs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxTQUFnQixrQkFBa0IsQ0FDaEMsTUFBUyxFQUNULEdBQVk7SUFFWixPQUFPLENBQUMsSUFBQSxvQkFBYSxFQUFDLEdBQUcsQ0FBQztRQUN4QixDQUFDLENBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxjQUFjLEVBQUUseUJBQWMsQ0FBQyxPQUFPLEVBQUU7UUFDdkQsQ0FBQyxDQUFDLE1BQU0sQ0FBQztBQUNiLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILFNBQWdCLG1CQUFtQixDQUNqQyxHQUFZLEVBQ1osR0FBYSxFQUNiLFFBQXFDO0lBRXJDLElBQUksQ0FBQyxJQUFBLG9CQUFhLEVBQUMsR0FBRyxDQUFDLElBQUksUUFBUSxDQUFDLGNBQWMsS0FBSyx5QkFBYyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzlFLElBQUEsb0JBQVMsRUFDUCxHQUFHLEVBQ0gsR0FBRyxFQUNILGlEQUFpRCxFQUNqRCx1QkFBUyxDQUFDLHdCQUF3QixDQUNuQyxDQUFDO1FBQ0YsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IGlzU3lzdGVtQWRtaW4gfSBmcm9tICcuLi9taWRkbGV3YXJlL2F1dGgnO1xuaW1wb3J0IHsgRXJyb3JDb2RlIH0gZnJvbSAnLi4vdHlwZXMvZXJyb3ItY29kZXMnO1xuaW1wb3J0IHsgQWNjZXNzTW9kaWZpZXIgfSBmcm9tICcuLi90eXBlcy9waXBlbGluZSc7XG5pbXBvcnQgeyBzZW5kRXJyb3IgfSBmcm9tICcuLi91dGlscy9yZXNwb25zZSc7XG5cbi8qKlxuICogQXBwbHkgYWNjZXNzIGNvbnRyb2wgdG8gYSBmaWx0ZXIgb2JqZWN0LlxuICpcbiAqIE5vbi1zeXN0ZW0tYWRtaW5zIGFyZSByZXN0cmljdGVkIHRvICdwcml2YXRlJyAob3JnLXNjb3BlZCkgcmVzb3VyY2VzLlxuICogU3lzdGVtIGFkbWlucyBzZWUgYWxsIGFjY2VzcyBtb2RpZmllcnMuXG4gKlxuICogQHBhcmFtIGZpbHRlciAtIFF1ZXJ5IGZpbHRlciB0byBtb2RpZnlcbiAqIEBwYXJhbSByZXEgLSBFeHByZXNzIHJlcXVlc3QgKHVzZWQgdG8gY2hlY2sgYWRtaW4gc3RhdHVzKVxuICogQHJldHVybnMgRmlsdGVyIHdpdGggYWNjZXNzTW9kaWZpZXIgYXBwbGllZCBmb3Igbm9uLWFkbWluc1xuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBjb25zdCBlZmZlY3RpdmVGaWx0ZXIgPSBhcHBseUFjY2Vzc0NvbnRyb2woZmlsdGVyLCByZXEpO1xuICogY29uc3QgcmVzdWx0cyA9IGF3YWl0IHNlcnZpY2UuZmluZChlZmZlY3RpdmVGaWx0ZXIsIG9yZ0lkKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlBY2Nlc3NDb250cm9sPFQgZXh0ZW5kcyB7IGFjY2Vzc01vZGlmaWVyPzogc3RyaW5nIH0+KFxuICBmaWx0ZXI6IFQsXG4gIHJlcTogUmVxdWVzdCxcbik6IFQge1xuICByZXR1cm4gIWlzU3lzdGVtQWRtaW4ocmVxKVxuICAgID8geyAuLi5maWx0ZXIsIGFjY2Vzc01vZGlmaWVyOiBBY2Nlc3NNb2RpZmllci5QUklWQVRFIH1cbiAgICA6IGZpbHRlcjtcbn1cblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIGEgbm9uLWFkbWluIHVzZXIgbWF5IG1vZGlmeSBhIHB1YmxpYyByZXNvdXJjZS5cbiAqXG4gKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcmVxdWVzdCBtYXkgcHJvY2VlZC4gUmV0dXJucyBgZmFsc2VgIGFuZCBzZW5kc1xuICogYSA0MDMgcmVzcG9uc2UgaWYgdGhlIHVzZXIgbGFja3MgcGVybWlzc2lvbi5cbiAqXG4gKiBAcGFyYW0gcmVxIC0gRXhwcmVzcyByZXF1ZXN0XG4gKiBAcGFyYW0gcmVzIC0gRXhwcmVzcyByZXNwb25zZVxuICogQHBhcmFtIHJlc291cmNlIC0gUmVzb3VyY2Ugd2l0aCBhbiBhY2Nlc3NNb2RpZmllciBmaWVsZFxuICogQHJldHVybnMgYHRydWVgIGlmIGFjY2VzcyBpcyBhbGxvd2VkLCBgZmFsc2VgIGlmIGJsb2NrZWQgKHJlc3BvbnNlIGFscmVhZHkgc2VudClcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogaWYgKCFyZXF1aXJlUHVibGljQWNjZXNzKHJlcSwgcmVzLCBwaXBlbGluZSkpIHJldHVybjtcbiAqIGF3YWl0IHBpcGVsaW5lU2VydmljZS5kZWxldGUoaWQsIG9yZ0lkLCB1c2VySWQpO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlUHVibGljQWNjZXNzKFxuICByZXE6IFJlcXVlc3QsXG4gIHJlczogUmVzcG9uc2UsXG4gIHJlc291cmNlOiB7IGFjY2Vzc01vZGlmaWVyPzogc3RyaW5nIH0sXG4pOiBib29sZWFuIHtcbiAgaWYgKCFpc1N5c3RlbUFkbWluKHJlcSkgJiYgcmVzb3VyY2UuYWNjZXNzTW9kaWZpZXIgIT09IEFjY2Vzc01vZGlmaWVyLlBSSVZBVEUpIHtcbiAgICBzZW5kRXJyb3IoXG4gICAgICByZXMsXG4gICAgICA0MDMsXG4gICAgICAnT25seSBzeXN0ZW0gYWRtaW5zIGNhbiBtb2RpZnkgcHVibGljIHJlc291cmNlcy4nLFxuICAgICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgICApO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Response } from 'express';
|
|
2
|
+
/**
|
|
3
|
+
* Generic record normalizer - ensures array fields are always arrays
|
|
4
|
+
* @param record - The record to normalize
|
|
5
|
+
* @param arrayFields - Fields that should be arrays
|
|
6
|
+
* @returns Normalized record with array fields guaranteed to be arrays
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeArrayFields<T extends Record<string, unknown>>(record: T, arrayFields: (keyof T)[]): T;
|
|
9
|
+
/**
|
|
10
|
+
* Generic entity not-found response
|
|
11
|
+
* Sends standardized 404 response for missing entities
|
|
12
|
+
* @param res - Express response object
|
|
13
|
+
* @param entityName - Name of the entity type (e.g., "Pipeline", "Plugin")
|
|
14
|
+
* @returns Express response
|
|
15
|
+
*/
|
|
16
|
+
export declare function sendEntityNotFound(res: Response, entityName: string): void;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.normalizeArrayFields = normalizeArrayFields;
|
|
6
|
+
exports.sendEntityNotFound = sendEntityNotFound;
|
|
7
|
+
const error_codes_1 = require("../types/error-codes");
|
|
8
|
+
const response_1 = require("../utils/response");
|
|
9
|
+
/**
|
|
10
|
+
* Generic record normalizer - ensures array fields are always arrays
|
|
11
|
+
* @param record - The record to normalize
|
|
12
|
+
* @param arrayFields - Fields that should be arrays
|
|
13
|
+
* @returns Normalized record with array fields guaranteed to be arrays
|
|
14
|
+
*/
|
|
15
|
+
function normalizeArrayFields(record, arrayFields) {
|
|
16
|
+
const normalized = { ...record };
|
|
17
|
+
for (const field of arrayFields) {
|
|
18
|
+
if (field in normalized && !Array.isArray(normalized[field])) {
|
|
19
|
+
normalized[field] = [];
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return normalized;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Generic entity not-found response
|
|
26
|
+
* Sends standardized 404 response for missing entities
|
|
27
|
+
* @param res - Express response object
|
|
28
|
+
* @param entityName - Name of the entity type (e.g., "Pipeline", "Plugin")
|
|
29
|
+
* @returns Express response
|
|
30
|
+
*/
|
|
31
|
+
function sendEntityNotFound(res, entityName) {
|
|
32
|
+
(0, response_1.sendError)(res, 404, `${entityName} not found.`, error_codes_1.ErrorCode.NOT_FOUND);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3J1ZC1oZWxwZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hlbHBlcnMvY3J1ZC1oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDOztBQVl0QyxvREFXQztBQVNELGdEQUVDO0FBL0JELHNEQUFpRDtBQUNqRCxnREFBOEM7QUFFOUM7Ozs7O0dBS0c7QUFDSCxTQUFnQixvQkFBb0IsQ0FDbEMsTUFBUyxFQUNULFdBQXdCO0lBRXhCLE1BQU0sVUFBVSxHQUFHLEVBQUUsR0FBRyxNQUFNLEVBQUUsQ0FBQztJQUNqQyxLQUFLLE1BQU0sS0FBSyxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBQ2hDLElBQUksS0FBSyxJQUFJLFVBQVUsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUM1RCxVQUFzQyxDQUFDLEtBQWUsQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNoRSxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sVUFBVSxDQUFDO0FBQ3BCLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixrQkFBa0IsQ0FBQyxHQUFhLEVBQUUsVUFBa0I7SUFDbEUsSUFBQSxvQkFBUyxFQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxVQUFVLGFBQWEsRUFBRSx1QkFBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQ3ZFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHR5cGUgeyBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgRXJyb3JDb2RlIH0gZnJvbSAnLi4vdHlwZXMvZXJyb3ItY29kZXMnO1xuaW1wb3J0IHsgc2VuZEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UnO1xuXG4vKipcbiAqIEdlbmVyaWMgcmVjb3JkIG5vcm1hbGl6ZXIgLSBlbnN1cmVzIGFycmF5IGZpZWxkcyBhcmUgYWx3YXlzIGFycmF5c1xuICogQHBhcmFtIHJlY29yZCAtIFRoZSByZWNvcmQgdG8gbm9ybWFsaXplXG4gKiBAcGFyYW0gYXJyYXlGaWVsZHMgLSBGaWVsZHMgdGhhdCBzaG91bGQgYmUgYXJyYXlzXG4gKiBAcmV0dXJucyBOb3JtYWxpemVkIHJlY29yZCB3aXRoIGFycmF5IGZpZWxkcyBndWFyYW50ZWVkIHRvIGJlIGFycmF5c1xuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplQXJyYXlGaWVsZHM8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIHVua25vd24+PihcbiAgcmVjb3JkOiBULFxuICBhcnJheUZpZWxkczogKGtleW9mIFQpW10sXG4pOiBUIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IHsgLi4ucmVjb3JkIH07XG4gIGZvciAoY29uc3QgZmllbGQgb2YgYXJyYXlGaWVsZHMpIHtcbiAgICBpZiAoZmllbGQgaW4gbm9ybWFsaXplZCAmJiAhQXJyYXkuaXNBcnJheShub3JtYWxpemVkW2ZpZWxkXSkpIHtcbiAgICAgIChub3JtYWxpemVkIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtmaWVsZCBhcyBzdHJpbmddID0gW107XG4gICAgfVxuICB9XG4gIHJldHVybiBub3JtYWxpemVkO1xufVxuXG4vKipcbiAqIEdlbmVyaWMgZW50aXR5IG5vdC1mb3VuZCByZXNwb25zZVxuICogU2VuZHMgc3RhbmRhcmRpemVkIDQwNCByZXNwb25zZSBmb3IgbWlzc2luZyBlbnRpdGllc1xuICogQHBhcmFtIHJlcyAtIEV4cHJlc3MgcmVzcG9uc2Ugb2JqZWN0XG4gKiBAcGFyYW0gZW50aXR5TmFtZSAtIE5hbWUgb2YgdGhlIGVudGl0eSB0eXBlIChlLmcuLCBcIlBpcGVsaW5lXCIsIFwiUGx1Z2luXCIpXG4gKiBAcmV0dXJucyBFeHByZXNzIHJlc3BvbnNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZW5kRW50aXR5Tm90Rm91bmQocmVzOiBSZXNwb25zZSwgZW50aXR5TmFtZTogc3RyaW5nKTogdm9pZCB7XG4gIHNlbmRFcnJvcihyZXMsIDQwNCwgYCR7ZW50aXR5TmFtZX0gbm90IGZvdW5kLmAsIEVycm9yQ29kZS5OT1RfRk9VTkQpO1xufVxuIl19
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
+
if (k2 === undefined) k2 = k;
|
|
6
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
+
}
|
|
10
|
+
Object.defineProperty(o, k2, desc);
|
|
11
|
+
}) : (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
o[k2] = m[k];
|
|
14
|
+
}));
|
|
15
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
16
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
__exportStar(require("./crud-helpers"), exports);
|
|
20
|
+
__exportStar(require("./access-helpers"), exports);
|
|
21
|
+
__exportStar(require("./mask-helpers"), exports);
|
|
22
|
+
__exportStar(require("./sse-helpers"), exports);
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaGVscGVycy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsK0NBQStDO0FBQy9DLHNDQUFzQzs7Ozs7Ozs7Ozs7Ozs7OztBQUV0QyxpREFBK0I7QUFDL0IsbURBQWlDO0FBQ2pDLGlEQUErQjtBQUMvQixnREFBOEIiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuZXhwb3J0ICogZnJvbSAnLi9jcnVkLWhlbHBlcnMnO1xuZXhwb3J0ICogZnJvbSAnLi9hY2Nlc3MtaGVscGVycyc7XG5leHBvcnQgKiBmcm9tICcuL21hc2staGVscGVycyc7XG5leHBvcnQgKiBmcm9tICcuL3NzZS1oZWxwZXJzJztcbiJdfQ==
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mask the middle digits of a sensitive identifier.
|
|
3
|
+
* Preserves the first and last `visible` characters, replacing the rest with asterisks.
|
|
4
|
+
*
|
|
5
|
+
* @param value - The string to mask
|
|
6
|
+
* @param visible - Number of characters to keep visible on each side (default: 4)
|
|
7
|
+
* @returns Masked string, or '****' if the input is too short
|
|
8
|
+
*
|
|
9
|
+
* @example maskId('123456789012') → '1234****9012'
|
|
10
|
+
*/
|
|
11
|
+
export declare function maskId(value: string, visible?: number): string;
|
|
12
|
+
/**
|
|
13
|
+
* One-way hash of a sensitive identifier using SHA-256.
|
|
14
|
+
* Returns a deterministic, fixed-length hex string that cannot be reversed.
|
|
15
|
+
*
|
|
16
|
+
* @param value - The sensitive value to hash (e.g. AWS account number)
|
|
17
|
+
* @param length - Number of hex characters to return (default: 12, matching AWS account length)
|
|
18
|
+
* @returns Truncated SHA-256 hex digest
|
|
19
|
+
*
|
|
20
|
+
* @example hashId('123456789012') → 'a1b2c3d4e5f6'
|
|
21
|
+
*/
|
|
22
|
+
export declare function hashId(value: string, length?: number): string;
|
|
23
|
+
/**
|
|
24
|
+
* Replace the AWS account number in an ARN with its SHA-256 hash.
|
|
25
|
+
* Both the deploy registration and event ingestion sides call this function,
|
|
26
|
+
* so registry lookups still match — the real account never reaches the database.
|
|
27
|
+
*
|
|
28
|
+
* ARN format: `arn:partition:service:region:account:resource`
|
|
29
|
+
*
|
|
30
|
+
* @example hashAccountInArn('arn:aws:codepipeline:us-east-1:123456789012:my-pipeline')
|
|
31
|
+
* → 'arn:aws:codepipeline:us-east-1:a1b2c3d4e5f6:my-pipeline'
|
|
32
|
+
*/
|
|
33
|
+
export declare function hashAccountInArn(arn: string): string;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.maskId = maskId;
|
|
6
|
+
exports.hashId = hashId;
|
|
7
|
+
exports.hashAccountInArn = hashAccountInArn;
|
|
8
|
+
const crypto_1 = require("crypto");
|
|
9
|
+
/**
|
|
10
|
+
* Mask the middle digits of a sensitive identifier.
|
|
11
|
+
* Preserves the first and last `visible` characters, replacing the rest with asterisks.
|
|
12
|
+
*
|
|
13
|
+
* @param value - The string to mask
|
|
14
|
+
* @param visible - Number of characters to keep visible on each side (default: 4)
|
|
15
|
+
* @returns Masked string, or '****' if the input is too short
|
|
16
|
+
*
|
|
17
|
+
* @example maskId('123456789012') → '1234****9012'
|
|
18
|
+
*/
|
|
19
|
+
function maskId(value, visible = 4) {
|
|
20
|
+
if (!value || value.length <= visible * 2)
|
|
21
|
+
return '****';
|
|
22
|
+
return value.slice(0, visible) + '*'.repeat(value.length - visible * 2) + value.slice(-visible);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* One-way hash of a sensitive identifier using SHA-256.
|
|
26
|
+
* Returns a deterministic, fixed-length hex string that cannot be reversed.
|
|
27
|
+
*
|
|
28
|
+
* @param value - The sensitive value to hash (e.g. AWS account number)
|
|
29
|
+
* @param length - Number of hex characters to return (default: 12, matching AWS account length)
|
|
30
|
+
* @returns Truncated SHA-256 hex digest
|
|
31
|
+
*
|
|
32
|
+
* @example hashId('123456789012') → 'a1b2c3d4e5f6'
|
|
33
|
+
*/
|
|
34
|
+
function hashId(value, length = 12) {
|
|
35
|
+
return (0, crypto_1.createHash)('sha256').update(value).digest('hex').slice(0, length);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Replace the AWS account number in an ARN with its SHA-256 hash.
|
|
39
|
+
* Both the deploy registration and event ingestion sides call this function,
|
|
40
|
+
* so registry lookups still match — the real account never reaches the database.
|
|
41
|
+
*
|
|
42
|
+
* ARN format: `arn:partition:service:region:account:resource`
|
|
43
|
+
*
|
|
44
|
+
* @example hashAccountInArn('arn:aws:codepipeline:us-east-1:123456789012:my-pipeline')
|
|
45
|
+
* → 'arn:aws:codepipeline:us-east-1:a1b2c3d4e5f6:my-pipeline'
|
|
46
|
+
*/
|
|
47
|
+
function hashAccountInArn(arn) {
|
|
48
|
+
const parts = arn.split(':');
|
|
49
|
+
if (parts.length < 5 || !parts[4])
|
|
50
|
+
return arn;
|
|
51
|
+
parts[4] = hashId(parts[4]);
|
|
52
|
+
return parts.join(':');
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFzay1oZWxwZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hlbHBlcnMvbWFzay1oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDOztBQWN0Qyx3QkFHQztBQVlELHdCQUVDO0FBWUQsNENBS0M7QUE5Q0QsbUNBQW9DO0FBRXBDOzs7Ozs7Ozs7R0FTRztBQUNILFNBQWdCLE1BQU0sQ0FBQyxLQUFhLEVBQUUsT0FBTyxHQUFHLENBQUM7SUFDL0MsSUFBSSxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLE9BQU8sR0FBRyxDQUFDO1FBQUUsT0FBTyxNQUFNLENBQUM7SUFDekQsT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsT0FBTyxHQUFHLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUNsRyxDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsU0FBZ0IsTUFBTSxDQUFDLEtBQWEsRUFBRSxNQUFNLEdBQUcsRUFBRTtJQUMvQyxPQUFPLElBQUEsbUJBQVUsRUFBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDM0UsQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILFNBQWdCLGdCQUFnQixDQUFDLEdBQVc7SUFDMUMsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM3QixJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUFFLE9BQU8sR0FBRyxDQUFDO0lBQzlDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUIsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gJ2NyeXB0byc7XG5cbi8qKlxuICogTWFzayB0aGUgbWlkZGxlIGRpZ2l0cyBvZiBhIHNlbnNpdGl2ZSBpZGVudGlmaWVyLlxuICogUHJlc2VydmVzIHRoZSBmaXJzdCBhbmQgbGFzdCBgdmlzaWJsZWAgY2hhcmFjdGVycywgcmVwbGFjaW5nIHRoZSByZXN0IHdpdGggYXN0ZXJpc2tzLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSAtIFRoZSBzdHJpbmcgdG8gbWFza1xuICogQHBhcmFtIHZpc2libGUgLSBOdW1iZXIgb2YgY2hhcmFjdGVycyB0byBrZWVwIHZpc2libGUgb24gZWFjaCBzaWRlIChkZWZhdWx0OiA0KVxuICogQHJldHVybnMgTWFza2VkIHN0cmluZywgb3IgJyoqKionIGlmIHRoZSBpbnB1dCBpcyB0b28gc2hvcnRcbiAqXG4gKiBAZXhhbXBsZSBtYXNrSWQoJzEyMzQ1Njc4OTAxMicpIOKGkiAnMTIzNCoqKio5MDEyJ1xuICovXG5leHBvcnQgZnVuY3Rpb24gbWFza0lkKHZhbHVlOiBzdHJpbmcsIHZpc2libGUgPSA0KTogc3RyaW5nIHtcbiAgaWYgKCF2YWx1ZSB8fCB2YWx1ZS5sZW5ndGggPD0gdmlzaWJsZSAqIDIpIHJldHVybiAnKioqKic7XG4gIHJldHVybiB2YWx1ZS5zbGljZSgwLCB2aXNpYmxlKSArICcqJy5yZXBlYXQodmFsdWUubGVuZ3RoIC0gdmlzaWJsZSAqIDIpICsgdmFsdWUuc2xpY2UoLXZpc2libGUpO1xufVxuXG4vKipcbiAqIE9uZS13YXkgaGFzaCBvZiBhIHNlbnNpdGl2ZSBpZGVudGlmaWVyIHVzaW5nIFNIQS0yNTYuXG4gKiBSZXR1cm5zIGEgZGV0ZXJtaW5pc3RpYywgZml4ZWQtbGVuZ3RoIGhleCBzdHJpbmcgdGhhdCBjYW5ub3QgYmUgcmV2ZXJzZWQuXG4gKlxuICogQHBhcmFtIHZhbHVlIC0gVGhlIHNlbnNpdGl2ZSB2YWx1ZSB0byBoYXNoIChlLmcuIEFXUyBhY2NvdW50IG51bWJlcilcbiAqIEBwYXJhbSBsZW5ndGggLSBOdW1iZXIgb2YgaGV4IGNoYXJhY3RlcnMgdG8gcmV0dXJuIChkZWZhdWx0OiAxMiwgbWF0Y2hpbmcgQVdTIGFjY291bnQgbGVuZ3RoKVxuICogQHJldHVybnMgVHJ1bmNhdGVkIFNIQS0yNTYgaGV4IGRpZ2VzdFxuICpcbiAqIEBleGFtcGxlIGhhc2hJZCgnMTIzNDU2Nzg5MDEyJykg4oaSICdhMWIyYzNkNGU1ZjYnXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNoSWQodmFsdWU6IHN0cmluZywgbGVuZ3RoID0gMTIpOiBzdHJpbmcge1xuICByZXR1cm4gY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKHZhbHVlKS5kaWdlc3QoJ2hleCcpLnNsaWNlKDAsIGxlbmd0aCk7XG59XG5cbi8qKlxuICogUmVwbGFjZSB0aGUgQVdTIGFjY291bnQgbnVtYmVyIGluIGFuIEFSTiB3aXRoIGl0cyBTSEEtMjU2IGhhc2guXG4gKiBCb3RoIHRoZSBkZXBsb3kgcmVnaXN0cmF0aW9uIGFuZCBldmVudCBpbmdlc3Rpb24gc2lkZXMgY2FsbCB0aGlzIGZ1bmN0aW9uLFxuICogc28gcmVnaXN0cnkgbG9va3VwcyBzdGlsbCBtYXRjaCDigJQgdGhlIHJlYWwgYWNjb3VudCBuZXZlciByZWFjaGVzIHRoZSBkYXRhYmFzZS5cbiAqXG4gKiBBUk4gZm9ybWF0OiBgYXJuOnBhcnRpdGlvbjpzZXJ2aWNlOnJlZ2lvbjphY2NvdW50OnJlc291cmNlYFxuICpcbiAqIEBleGFtcGxlIGhhc2hBY2NvdW50SW5Bcm4oJ2Fybjphd3M6Y29kZXBpcGVsaW5lOnVzLWVhc3QtMToxMjM0NTY3ODkwMTI6bXktcGlwZWxpbmUnKVxuICogICDihpIgJ2Fybjphd3M6Y29kZXBpcGVsaW5lOnVzLWVhc3QtMTphMWIyYzNkNGU1ZjY6bXktcGlwZWxpbmUnXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNoQWNjb3VudEluQXJuKGFybjogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgcGFydHMgPSBhcm4uc3BsaXQoJzonKTtcbiAgaWYgKHBhcnRzLmxlbmd0aCA8IDUgfHwgIXBhcnRzWzRdKSByZXR1cm4gYXJuO1xuICBwYXJ0c1s0XSA9IGhhc2hJZChwYXJ0c1s0XSk7XG4gIHJldHVybiBwYXJ0cy5qb2luKCc6Jyk7XG59XG4iXX0=
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Request, Response } from 'express';
|
|
2
|
+
/**
|
|
3
|
+
* Set SSE response headers and flush.
|
|
4
|
+
* Returns an `aborted()` function to check if the client disconnected.
|
|
5
|
+
*/
|
|
6
|
+
export declare function initSSEStream(req: Request, res: Response, timeoutMs: number): {
|
|
7
|
+
aborted: () => boolean;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Classify AI generation errors and send the appropriate HTTP response or SSE event.
|
|
11
|
+
* If headers are already sent (streaming), writes an SSE error event and ends the response.
|
|
12
|
+
*/
|
|
13
|
+
export declare function handleAIError(res: Response, message: string, fallbackMessage: string): void;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.initSSEStream = initSSEStream;
|
|
6
|
+
exports.handleAIError = handleAIError;
|
|
7
|
+
const response_1 = require("../utils/response");
|
|
8
|
+
/**
|
|
9
|
+
* Set SSE response headers and flush.
|
|
10
|
+
* Returns an `aborted()` function to check if the client disconnected.
|
|
11
|
+
*/
|
|
12
|
+
function initSSEStream(req, res, timeoutMs) {
|
|
13
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
14
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
15
|
+
res.setHeader('Connection', 'keep-alive');
|
|
16
|
+
res.setHeader('X-Accel-Buffering', 'no');
|
|
17
|
+
res.setTimeout(timeoutMs);
|
|
18
|
+
res.flushHeaders();
|
|
19
|
+
let _aborted = false;
|
|
20
|
+
req.on('close', () => { _aborted = true; });
|
|
21
|
+
return { aborted: () => _aborted };
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Classify AI generation errors and send the appropriate HTTP response or SSE event.
|
|
25
|
+
* If headers are already sent (streaming), writes an SSE error event and ends the response.
|
|
26
|
+
*/
|
|
27
|
+
function handleAIError(res, message, fallbackMessage) {
|
|
28
|
+
if (!res.headersSent) {
|
|
29
|
+
if (message.includes('not configured') || message.includes('API key')) {
|
|
30
|
+
return (0, response_1.sendInternalError)(res, 'AI generation is not configured for the requested provider');
|
|
31
|
+
}
|
|
32
|
+
if (message.includes('not available for provider')) {
|
|
33
|
+
return (0, response_1.sendBadRequest)(res, message);
|
|
34
|
+
}
|
|
35
|
+
return (0, response_1.sendInternalError)(res, fallbackMessage, { details: message });
|
|
36
|
+
}
|
|
37
|
+
res.write(`data: ${JSON.stringify({ type: 'error', message })}\n\n`);
|
|
38
|
+
res.end();
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NlLWhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaGVscGVycy9zc2UtaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsK0NBQStDO0FBQy9DLHNDQUFzQzs7QUFTdEMsc0NBVUM7QUFNRCxzQ0FZQztBQWxDRCxnREFBc0U7QUFFdEU7OztHQUdHO0FBQ0gsU0FBZ0IsYUFBYSxDQUFDLEdBQVksRUFBRSxHQUFhLEVBQUUsU0FBaUI7SUFDMUUsR0FBRyxDQUFDLFNBQVMsQ0FBQyxjQUFjLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztJQUNuRCxHQUFHLENBQUMsU0FBUyxDQUFDLGVBQWUsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUMzQyxHQUFHLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQztJQUMxQyxHQUFHLENBQUMsU0FBUyxDQUFDLG1CQUFtQixFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3pDLEdBQUcsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDMUIsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ25CLElBQUksUUFBUSxHQUFHLEtBQUssQ0FBQztJQUNyQixHQUFHLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRyxRQUFRLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDNUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxRQUFRLEVBQUUsQ0FBQztBQUNyQyxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBZ0IsYUFBYSxDQUFDLEdBQWEsRUFBRSxPQUFlLEVBQUUsZUFBdUI7SUFDbkYsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNyQixJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDdEUsT0FBTyxJQUFBLDRCQUFpQixFQUFDLEdBQUcsRUFBRSw0REFBNEQsQ0FBQyxDQUFDO1FBQzlGLENBQUM7UUFDRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsNEJBQTRCLENBQUMsRUFBRSxDQUFDO1lBQ25ELE9BQU8sSUFBQSx5QkFBYyxFQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBQ0QsT0FBTyxJQUFBLDRCQUFpQixFQUFDLEdBQUcsRUFBRSxlQUFlLEVBQUUsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBQ0QsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3JFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNaLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHR5cGUgeyBSZXF1ZXN0LCBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgc2VuZEJhZFJlcXVlc3QsIHNlbmRJbnRlcm5hbEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UnO1xuXG4vKipcbiAqIFNldCBTU0UgcmVzcG9uc2UgaGVhZGVycyBhbmQgZmx1c2guXG4gKiBSZXR1cm5zIGFuIGBhYm9ydGVkKClgIGZ1bmN0aW9uIHRvIGNoZWNrIGlmIHRoZSBjbGllbnQgZGlzY29ubmVjdGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5pdFNTRVN0cmVhbShyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIHRpbWVvdXRNczogbnVtYmVyKTogeyBhYm9ydGVkOiAoKSA9PiBib29sZWFuIH0ge1xuICByZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAndGV4dC9ldmVudC1zdHJlYW0nKTtcbiAgcmVzLnNldEhlYWRlcignQ2FjaGUtQ29udHJvbCcsICduby1jYWNoZScpO1xuICByZXMuc2V0SGVhZGVyKCdDb25uZWN0aW9uJywgJ2tlZXAtYWxpdmUnKTtcbiAgcmVzLnNldEhlYWRlcignWC1BY2NlbC1CdWZmZXJpbmcnLCAnbm8nKTtcbiAgcmVzLnNldFRpbWVvdXQodGltZW91dE1zKTtcbiAgcmVzLmZsdXNoSGVhZGVycygpO1xuICBsZXQgX2Fib3J0ZWQgPSBmYWxzZTtcbiAgcmVxLm9uKCdjbG9zZScsICgpID0+IHsgX2Fib3J0ZWQgPSB0cnVlOyB9KTtcbiAgcmV0dXJuIHsgYWJvcnRlZDogKCkgPT4gX2Fib3J0ZWQgfTtcbn1cblxuLyoqXG4gKiBDbGFzc2lmeSBBSSBnZW5lcmF0aW9uIGVycm9ycyBhbmQgc2VuZCB0aGUgYXBwcm9wcmlhdGUgSFRUUCByZXNwb25zZSBvciBTU0UgZXZlbnQuXG4gKiBJZiBoZWFkZXJzIGFyZSBhbHJlYWR5IHNlbnQgKHN0cmVhbWluZyksIHdyaXRlcyBhbiBTU0UgZXJyb3IgZXZlbnQgYW5kIGVuZHMgdGhlIHJlc3BvbnNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFuZGxlQUlFcnJvcihyZXM6IFJlc3BvbnNlLCBtZXNzYWdlOiBzdHJpbmcsIGZhbGxiYWNrTWVzc2FnZTogc3RyaW5nKTogdm9pZCB7XG4gIGlmICghcmVzLmhlYWRlcnNTZW50KSB7XG4gICAgaWYgKG1lc3NhZ2UuaW5jbHVkZXMoJ25vdCBjb25maWd1cmVkJykgfHwgbWVzc2FnZS5pbmNsdWRlcygnQVBJIGtleScpKSB7XG4gICAgICByZXR1cm4gc2VuZEludGVybmFsRXJyb3IocmVzLCAnQUkgZ2VuZXJhdGlvbiBpcyBub3QgY29uZmlndXJlZCBmb3IgdGhlIHJlcXVlc3RlZCBwcm92aWRlcicpO1xuICAgIH1cbiAgICBpZiAobWVzc2FnZS5pbmNsdWRlcygnbm90IGF2YWlsYWJsZSBmb3IgcHJvdmlkZXInKSkge1xuICAgICAgcmV0dXJuIHNlbmRCYWRSZXF1ZXN0KHJlcywgbWVzc2FnZSk7XG4gICAgfVxuICAgIHJldHVybiBzZW5kSW50ZXJuYWxFcnJvcihyZXMsIGZhbGxiYWNrTWVzc2FnZSwgeyBkZXRhaWxzOiBtZXNzYWdlIH0pO1xuICB9XG4gIHJlcy53cml0ZShgZGF0YTogJHtKU09OLnN0cmluZ2lmeSh7IHR5cGU6ICdlcnJvcicsIG1lc3NhZ2UgfSl9XFxuXFxuYCk7XG4gIHJlcy5lbmQoKTtcbn1cbiJdfQ==
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @pipeline-builder/api-core
|
|
3
|
+
*
|
|
4
|
+
* Core API utilities shared across all services.
|
|
5
|
+
*
|
|
6
|
+
* **Middleware**
|
|
7
|
+
* - requireAuth, optionalAuth, requireOrganization, requireAdmin — JWT authentication
|
|
8
|
+
* - isSystemOrg, isSystemAdmin — authorization helpers
|
|
9
|
+
*
|
|
10
|
+
* **Types**
|
|
11
|
+
* - ErrorCode, ErrorCodeStatus — standardized error code enum and status mapping
|
|
12
|
+
* - RequestIdentity — parsed JWT identity
|
|
13
|
+
* - ServiceConfig, RequestOptions, HttpResponse — HTTP client types
|
|
14
|
+
* - QuotaType, QuotaCheckResult — quota service types
|
|
15
|
+
* - PipelineType, ComputeType, AccessModifier — pipeline domain types
|
|
16
|
+
* - FeatureFlags, BillingPlan — feature and billing types
|
|
17
|
+
*
|
|
18
|
+
* **Utilities**
|
|
19
|
+
* - createLogger — Winston-based structured logger factory
|
|
20
|
+
* - sendSuccess, sendError, sendPaginated, sendBadRequest, sendInternalError — HTTP response helpers
|
|
21
|
+
* - getParam, getRequiredParam, getParams, getOrgId, getAuthHeader — request parameter extraction
|
|
22
|
+
* - parseQueryBoolean, parseQueryInt, parseQueryString — query string parsing
|
|
23
|
+
* - getIdentity, validateIdentity — identity extraction from requests
|
|
24
|
+
* - errorMessage — safe error-to-string conversion
|
|
25
|
+
*
|
|
26
|
+
* **Constants**
|
|
27
|
+
* - HTTP status codes, AI provider identifiers, time constants
|
|
28
|
+
*
|
|
29
|
+
* **Services**
|
|
30
|
+
* - InternalHttpClient, createSafeClient — internal service-to-service HTTP client
|
|
31
|
+
* - createQuotaService — quota enforcement client factory
|
|
32
|
+
* - CacheService — in-memory TTL cache
|
|
33
|
+
* - ComplianceClient — compliance service client
|
|
34
|
+
* - EntityEventEmitter — domain event pub/sub
|
|
35
|
+
*
|
|
36
|
+
* **Errors**
|
|
37
|
+
* - AppError, NotFoundError, ForbiddenError — typed HTTP error classes
|
|
38
|
+
*
|
|
39
|
+
* **Validation**
|
|
40
|
+
* - Zod-based request validation schemas and middleware
|
|
41
|
+
*
|
|
42
|
+
* **Routes**
|
|
43
|
+
* - Health check route factory
|
|
44
|
+
*
|
|
45
|
+
* **OpenAPI**
|
|
46
|
+
* - Schema registry and spec generation
|
|
47
|
+
*/
|
|
48
|
+
export * from './types';
|
|
49
|
+
export * from './constants';
|
|
50
|
+
export * from './utils';
|
|
51
|
+
export * from './helpers';
|
|
52
|
+
export * from './services';
|
|
53
|
+
export * from './middleware';
|
|
54
|
+
export * from './routes';
|
|
55
|
+
export * from './errors';
|
|
56
|
+
export * from './validation';
|
|
57
|
+
export * from './openapi';
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
+
if (k2 === undefined) k2 = k;
|
|
6
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
+
}
|
|
10
|
+
Object.defineProperty(o, k2, desc);
|
|
11
|
+
}) : (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
o[k2] = m[k];
|
|
14
|
+
}));
|
|
15
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
16
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
/**
|
|
20
|
+
* @module @pipeline-builder/api-core
|
|
21
|
+
*
|
|
22
|
+
* Core API utilities shared across all services.
|
|
23
|
+
*
|
|
24
|
+
* **Middleware**
|
|
25
|
+
* - requireAuth, optionalAuth, requireOrganization, requireAdmin — JWT authentication
|
|
26
|
+
* - isSystemOrg, isSystemAdmin — authorization helpers
|
|
27
|
+
*
|
|
28
|
+
* **Types**
|
|
29
|
+
* - ErrorCode, ErrorCodeStatus — standardized error code enum and status mapping
|
|
30
|
+
* - RequestIdentity — parsed JWT identity
|
|
31
|
+
* - ServiceConfig, RequestOptions, HttpResponse — HTTP client types
|
|
32
|
+
* - QuotaType, QuotaCheckResult — quota service types
|
|
33
|
+
* - PipelineType, ComputeType, AccessModifier — pipeline domain types
|
|
34
|
+
* - FeatureFlags, BillingPlan — feature and billing types
|
|
35
|
+
*
|
|
36
|
+
* **Utilities**
|
|
37
|
+
* - createLogger — Winston-based structured logger factory
|
|
38
|
+
* - sendSuccess, sendError, sendPaginated, sendBadRequest, sendInternalError — HTTP response helpers
|
|
39
|
+
* - getParam, getRequiredParam, getParams, getOrgId, getAuthHeader — request parameter extraction
|
|
40
|
+
* - parseQueryBoolean, parseQueryInt, parseQueryString — query string parsing
|
|
41
|
+
* - getIdentity, validateIdentity — identity extraction from requests
|
|
42
|
+
* - errorMessage — safe error-to-string conversion
|
|
43
|
+
*
|
|
44
|
+
* **Constants**
|
|
45
|
+
* - HTTP status codes, AI provider identifiers, time constants
|
|
46
|
+
*
|
|
47
|
+
* **Services**
|
|
48
|
+
* - InternalHttpClient, createSafeClient — internal service-to-service HTTP client
|
|
49
|
+
* - createQuotaService — quota enforcement client factory
|
|
50
|
+
* - CacheService — in-memory TTL cache
|
|
51
|
+
* - ComplianceClient — compliance service client
|
|
52
|
+
* - EntityEventEmitter — domain event pub/sub
|
|
53
|
+
*
|
|
54
|
+
* **Errors**
|
|
55
|
+
* - AppError, NotFoundError, ForbiddenError — typed HTTP error classes
|
|
56
|
+
*
|
|
57
|
+
* **Validation**
|
|
58
|
+
* - Zod-based request validation schemas and middleware
|
|
59
|
+
*
|
|
60
|
+
* **Routes**
|
|
61
|
+
* - Health check route factory
|
|
62
|
+
*
|
|
63
|
+
* **OpenAPI**
|
|
64
|
+
* - Schema registry and spec generation
|
|
65
|
+
*/
|
|
66
|
+
// Types
|
|
67
|
+
__exportStar(require("./types"), exports);
|
|
68
|
+
// Constants
|
|
69
|
+
__exportStar(require("./constants"), exports);
|
|
70
|
+
// Utils
|
|
71
|
+
__exportStar(require("./utils"), exports);
|
|
72
|
+
// Helpers
|
|
73
|
+
__exportStar(require("./helpers"), exports);
|
|
74
|
+
// Services
|
|
75
|
+
__exportStar(require("./services"), exports);
|
|
76
|
+
// Middleware
|
|
77
|
+
__exportStar(require("./middleware"), exports);
|
|
78
|
+
// Routes
|
|
79
|
+
__exportStar(require("./routes"), exports);
|
|
80
|
+
// Errors
|
|
81
|
+
__exportStar(require("./errors"), exports);
|
|
82
|
+
// Validation
|
|
83
|
+
__exportStar(require("./validation"), exports);
|
|
84
|
+
// OpenAPI
|
|
85
|
+
__exportStar(require("./openapi"), exports);
|
|
86
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4Q0c7QUFFSCxRQUFRO0FBQ1IsMENBQXdCO0FBRXhCLFlBQVk7QUFDWiw4Q0FBNEI7QUFFNUIsUUFBUTtBQUNSLDBDQUF3QjtBQUV4QixVQUFVO0FBQ1YsNENBQTBCO0FBRTFCLFdBQVc7QUFDWCw2Q0FBMkI7QUFFM0IsYUFBYTtBQUNiLCtDQUE2QjtBQUU3QixTQUFTO0FBQ1QsMkNBQXlCO0FBRXpCLFNBQVM7QUFDVCwyQ0FBeUI7QUFFekIsYUFBYTtBQUNiLCtDQUE2QjtBQUU3QixVQUFVO0FBQ1YsNENBQTBCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogQG1vZHVsZSBAcGlwZWxpbmUtYnVpbGRlci9hcGktY29yZVxuICpcbiAqIENvcmUgQVBJIHV0aWxpdGllcyBzaGFyZWQgYWNyb3NzIGFsbCBzZXJ2aWNlcy5cbiAqXG4gKiAqKk1pZGRsZXdhcmUqKlxuICogLSByZXF1aXJlQXV0aCwgb3B0aW9uYWxBdXRoLCByZXF1aXJlT3JnYW5pemF0aW9uLCByZXF1aXJlQWRtaW4g4oCUIEpXVCBhdXRoZW50aWNhdGlvblxuICogLSBpc1N5c3RlbU9yZywgaXNTeXN0ZW1BZG1pbiDigJQgYXV0aG9yaXphdGlvbiBoZWxwZXJzXG4gKlxuICogKipUeXBlcyoqXG4gKiAtIEVycm9yQ29kZSwgRXJyb3JDb2RlU3RhdHVzIOKAlCBzdGFuZGFyZGl6ZWQgZXJyb3IgY29kZSBlbnVtIGFuZCBzdGF0dXMgbWFwcGluZ1xuICogLSBSZXF1ZXN0SWRlbnRpdHkg4oCUIHBhcnNlZCBKV1QgaWRlbnRpdHlcbiAqIC0gU2VydmljZUNvbmZpZywgUmVxdWVzdE9wdGlvbnMsIEh0dHBSZXNwb25zZSDigJQgSFRUUCBjbGllbnQgdHlwZXNcbiAqIC0gUXVvdGFUeXBlLCBRdW90YUNoZWNrUmVzdWx0IOKAlCBxdW90YSBzZXJ2aWNlIHR5cGVzXG4gKiAtIFBpcGVsaW5lVHlwZSwgQ29tcHV0ZVR5cGUsIEFjY2Vzc01vZGlmaWVyIOKAlCBwaXBlbGluZSBkb21haW4gdHlwZXNcbiAqIC0gRmVhdHVyZUZsYWdzLCBCaWxsaW5nUGxhbiDigJQgZmVhdHVyZSBhbmQgYmlsbGluZyB0eXBlc1xuICpcbiAqICoqVXRpbGl0aWVzKipcbiAqIC0gY3JlYXRlTG9nZ2VyIOKAlCBXaW5zdG9uLWJhc2VkIHN0cnVjdHVyZWQgbG9nZ2VyIGZhY3RvcnlcbiAqIC0gc2VuZFN1Y2Nlc3MsIHNlbmRFcnJvciwgc2VuZFBhZ2luYXRlZCwgc2VuZEJhZFJlcXVlc3QsIHNlbmRJbnRlcm5hbEVycm9yIOKAlCBIVFRQIHJlc3BvbnNlIGhlbHBlcnNcbiAqIC0gZ2V0UGFyYW0sIGdldFJlcXVpcmVkUGFyYW0sIGdldFBhcmFtcywgZ2V0T3JnSWQsIGdldEF1dGhIZWFkZXIg4oCUIHJlcXVlc3QgcGFyYW1ldGVyIGV4dHJhY3Rpb25cbiAqIC0gcGFyc2VRdWVyeUJvb2xlYW4sIHBhcnNlUXVlcnlJbnQsIHBhcnNlUXVlcnlTdHJpbmcg4oCUIHF1ZXJ5IHN0cmluZyBwYXJzaW5nXG4gKiAtIGdldElkZW50aXR5LCB2YWxpZGF0ZUlkZW50aXR5IOKAlCBpZGVudGl0eSBleHRyYWN0aW9uIGZyb20gcmVxdWVzdHNcbiAqIC0gZXJyb3JNZXNzYWdlIOKAlCBzYWZlIGVycm9yLXRvLXN0cmluZyBjb252ZXJzaW9uXG4gKlxuICogKipDb25zdGFudHMqKlxuICogLSBIVFRQIHN0YXR1cyBjb2RlcywgQUkgcHJvdmlkZXIgaWRlbnRpZmllcnMsIHRpbWUgY29uc3RhbnRzXG4gKlxuICogKipTZXJ2aWNlcyoqXG4gKiAtIEludGVybmFsSHR0cENsaWVudCwgY3JlYXRlU2FmZUNsaWVudCDigJQgaW50ZXJuYWwgc2VydmljZS10by1zZXJ2aWNlIEhUVFAgY2xpZW50XG4gKiAtIGNyZWF0ZVF1b3RhU2VydmljZSDigJQgcXVvdGEgZW5mb3JjZW1lbnQgY2xpZW50IGZhY3RvcnlcbiAqIC0gQ2FjaGVTZXJ2aWNlIOKAlCBpbi1tZW1vcnkgVFRMIGNhY2hlXG4gKiAtIENvbXBsaWFuY2VDbGllbnQg4oCUIGNvbXBsaWFuY2Ugc2VydmljZSBjbGllbnRcbiAqIC0gRW50aXR5RXZlbnRFbWl0dGVyIOKAlCBkb21haW4gZXZlbnQgcHViL3N1YlxuICpcbiAqICoqRXJyb3JzKipcbiAqIC0gQXBwRXJyb3IsIE5vdEZvdW5kRXJyb3IsIEZvcmJpZGRlbkVycm9yIOKAlCB0eXBlZCBIVFRQIGVycm9yIGNsYXNzZXNcbiAqXG4gKiAqKlZhbGlkYXRpb24qKlxuICogLSBab2QtYmFzZWQgcmVxdWVzdCB2YWxpZGF0aW9uIHNjaGVtYXMgYW5kIG1pZGRsZXdhcmVcbiAqXG4gKiAqKlJvdXRlcyoqXG4gKiAtIEhlYWx0aCBjaGVjayByb3V0ZSBmYWN0b3J5XG4gKlxuICogKipPcGVuQVBJKipcbiAqIC0gU2NoZW1hIHJlZ2lzdHJ5IGFuZCBzcGVjIGdlbmVyYXRpb25cbiAqL1xuXG4vLyBUeXBlc1xuZXhwb3J0ICogZnJvbSAnLi90eXBlcyc7XG5cbi8vIENvbnN0YW50c1xuZXhwb3J0ICogZnJvbSAnLi9jb25zdGFudHMnO1xuXG4vLyBVdGlsc1xuZXhwb3J0ICogZnJvbSAnLi91dGlscyc7XG5cbi8vIEhlbHBlcnNcbmV4cG9ydCAqIGZyb20gJy4vaGVscGVycyc7XG5cbi8vIFNlcnZpY2VzXG5leHBvcnQgKiBmcm9tICcuL3NlcnZpY2VzJztcblxuLy8gTWlkZGxld2FyZVxuZXhwb3J0ICogZnJvbSAnLi9taWRkbGV3YXJlJztcblxuLy8gUm91dGVzXG5leHBvcnQgKiBmcm9tICcuL3JvdXRlcyc7XG5cbi8vIEVycm9yc1xuZXhwb3J0ICogZnJvbSAnLi9lcnJvcnMnO1xuXG4vLyBWYWxpZGF0aW9uXG5leHBvcnQgKiBmcm9tICcuL3ZhbGlkYXRpb24nO1xuXG4vLyBPcGVuQVBJXG5leHBvcnQgKiBmcm9tICcuL29wZW5hcGknO1xuIl19
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
export interface RequireAuthOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Allow x-org-id/x-org-name headers to override the JWT's organization fields.
|
|
5
|
+
*
|
|
6
|
+
* **SECURITY WARNING:** When enabled, a caller can set `x-org-id` to ANY
|
|
7
|
+
* organization ID, effectively impersonating that org. This MUST only be
|
|
8
|
+
* used on routes that are:
|
|
9
|
+
* 1. Internal service-to-service routes (not exposed to end users)
|
|
10
|
+
* 2. Behind network isolation (container network, VPC, etc.)
|
|
11
|
+
*
|
|
12
|
+
* NEVER enable this on user-facing API routes. If unsure, leave it disabled.
|
|
13
|
+
*/
|
|
14
|
+
allowOrgHeaderOverride?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** JWT auth middleware. Use directly or call with options. */
|
|
17
|
+
export declare function requireAuth(req: Request, res: Response, next: NextFunction): void;
|
|
18
|
+
export declare function requireAuth(options?: RequireAuthOptions): (req: Request, res: Response, next: NextFunction) => void;
|
|
19
|
+
/** Requires organization membership. Use after requireAuth. */
|
|
20
|
+
export declare function requireOrganization(req: Request, res: Response, next: NextFunction): void;
|
|
21
|
+
/**
|
|
22
|
+
* Requires admin role. Use after requireAuth.
|
|
23
|
+
* Permits users whose per-org role is 'admin' or 'owner'.
|
|
24
|
+
*/
|
|
25
|
+
export declare function requireAdmin(req: Request, res: Response, next: NextFunction): void;
|
|
26
|
+
/** Organization ID/name that identifies the system (super-admin) tenant. */
|
|
27
|
+
export declare const SYSTEM_ORG_ID: string;
|
|
28
|
+
/**
|
|
29
|
+
* Check if an orgId or orgName matches the system org.
|
|
30
|
+
* Use this instead of comparing directly against SYSTEM_ORG_ID,
|
|
31
|
+
* because the JWT orgId is a database ID (e.g. MongoDB ObjectId)
|
|
32
|
+
* while SYSTEM_ORG_ID is the well-known name "system".
|
|
33
|
+
*/
|
|
34
|
+
export declare function isSystemOrgId(orgId?: string, orgName?: string): boolean;
|
|
35
|
+
export declare function isSystemOrg(req: Request): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Check if the request is from a system admin.
|
|
38
|
+
* A system admin has per-org role 'admin' or 'owner' in the system organization.
|
|
39
|
+
*/
|
|
40
|
+
export declare function isSystemAdmin(req: Request): boolean;
|
|
41
|
+
/** Requires system admin (admin role + system organization). */
|
|
42
|
+
export declare function requireSystemAdmin(req: Request, res: Response, next: NextFunction): void;
|
|
43
|
+
/**
|
|
44
|
+
* Require a specific feature flag. Use after requireAuth.
|
|
45
|
+
* Checks the `features` array in the JWT payload (set at token issuance).
|
|
46
|
+
* System org users always pass (all features enabled).
|
|
47
|
+
*/
|
|
48
|
+
export declare function requireFeature(feature: string): (req: Request, res: Response, next: NextFunction) => void;
|
|
49
|
+
/** Only system admins can set access to 'public'; everyone else gets 'private'. */
|
|
50
|
+
export declare function resolveAccessModifier(req: Request, requested: string | undefined): 'public' | 'private';
|