@pipeline-builder/api-core 4.1.13 → 4.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/lib/constants/index.d.ts +0 -1
- package/lib/constants/index.js +1 -2
- package/lib/errors/app-errors.d.ts +8 -3
- package/lib/errors/app-errors.js +10 -5
- package/lib/helpers/access-helpers.d.ts +4 -6
- package/lib/helpers/access-helpers.js +6 -8
- package/lib/helpers/index.d.ts +3 -3
- package/lib/helpers/index.js +4 -4
- package/lib/helpers/org-hierarchy-http.d.ts +11 -10
- package/lib/helpers/org-hierarchy-http.js +24 -35
- package/lib/helpers/org-hierarchy.d.ts +37 -3
- package/lib/helpers/org-hierarchy.js +45 -4
- package/lib/helpers/restore-helpers.d.ts +44 -24
- package/lib/helpers/restore-helpers.js +41 -52
- package/lib/helpers/sse-helpers.d.ts +29 -7
- package/lib/helpers/sse-helpers.js +36 -9
- package/lib/index.d.ts +16 -14
- package/lib/index.js +17 -15
- package/lib/middleware/assurance.d.ts +116 -0
- package/lib/middleware/assurance.js +176 -0
- package/lib/middleware/auth.d.ts +5 -427
- package/lib/middleware/auth.js +36 -789
- package/lib/middleware/ecosystem-guard.d.ts +47 -0
- package/lib/middleware/ecosystem-guard.js +60 -0
- package/lib/middleware/index.d.ts +11 -4
- package/lib/middleware/index.js +12 -5
- package/lib/middleware/jwt-verify.d.ts +52 -0
- package/lib/middleware/jwt-verify.js +105 -0
- package/lib/middleware/permission-gates.d.ts +133 -0
- package/lib/middleware/permission-gates.js +260 -0
- package/lib/middleware/revocation.d.ts +96 -0
- package/lib/middleware/revocation.js +162 -0
- package/lib/middleware/route-table.d.ts +11 -0
- package/lib/middleware/route-table.js +4 -1
- package/lib/middleware/service-tokens.d.ts +83 -0
- package/lib/middleware/service-tokens.js +158 -0
- package/lib/middleware/step-up.d.ts +2 -2
- package/lib/middleware/step-up.js +8 -7
- package/lib/middleware/system-org.d.ts +20 -0
- package/lib/middleware/system-org.js +25 -0
- package/lib/openapi/routes/plugin-routes.js +133 -10
- package/lib/openapi/schema-registry.js +2 -5
- package/lib/routes/index.d.ts +1 -1
- package/lib/routes/index.js +2 -2
- package/lib/services/api-key-exchange.js +7 -5
- package/lib/services/audit-spool.d.ts +34 -10
- package/lib/services/audit-spool.js +75 -34
- package/lib/services/cache-service.d.ts +7 -0
- package/lib/services/cache-service.js +1 -1
- package/lib/services/circuit-breaker.d.ts +14 -1
- package/lib/services/circuit-breaker.js +36 -10
- package/lib/services/compliance-client.d.ts +10 -2
- package/lib/services/compliance-client.js +17 -10
- package/lib/services/compliance-event-subscriber.js +6 -6
- package/lib/services/durable-event-bus.js +8 -11
- package/lib/services/ecosystem-notify-client.d.ts +32 -0
- package/lib/services/ecosystem-notify-client.js +71 -0
- package/lib/services/env-redis.d.ts +4 -1
- package/lib/services/env-redis.js +32 -3
- package/lib/services/http-client.d.ts +19 -0
- package/lib/services/http-client.js +98 -19
- package/lib/services/index.d.ts +25 -24
- package/lib/services/index.js +25 -22
- package/lib/services/jwks-cache.js +5 -4
- package/lib/services/leader-lock.d.ts +22 -5
- package/lib/services/leader-lock.js +61 -6
- package/lib/services/quota.d.ts +9 -4
- package/lib/services/quota.js +34 -40
- package/lib/services/remote-audit-client.d.ts +28 -32
- package/lib/services/remote-audit-client.js +166 -49
- package/lib/services/retry-forever.js +5 -11
- package/lib/services/retry-strategy.d.ts +1 -1
- package/lib/services/retry-strategy.js +5 -4
- package/lib/services/scheduler.d.ts +8 -3
- package/lib/services/scheduler.js +17 -5
- package/lib/services/service-boot.d.ts +14 -13
- package/lib/services/service-boot.js +18 -15
- package/lib/services/service-keys.d.ts +1 -1
- package/lib/services/service-keys.js +12 -18
- package/lib/services/sse-ticket-store.d.ts +9 -1
- package/lib/services/sse-ticket-store.js +24 -9
- package/lib/services/system-notification.d.ts +27 -0
- package/lib/services/system-notification.js +50 -0
- package/lib/services/token-revocation.d.ts +50 -1
- package/lib/services/token-revocation.js +103 -3
- package/lib/types/audit-events.d.ts +6 -6
- package/lib/types/audit-events.js +1 -1
- package/lib/types/common.d.ts +32 -13
- package/lib/types/common.js +2 -1
- package/lib/types/ecosystem-notifications.d.ts +142 -0
- package/lib/types/ecosystem-notifications.js +210 -0
- package/lib/types/ecosystem.d.ts +77 -0
- package/lib/types/ecosystem.js +119 -0
- package/lib/types/error-codes.d.ts +81 -0
- package/lib/types/error-codes.js +108 -1
- package/lib/types/feature-flags.d.ts +21 -1
- package/lib/types/feature-flags.js +36 -2
- package/lib/types/index.d.ts +14 -9
- package/lib/types/index.js +15 -10
- package/lib/types/permissions.d.ts +46 -8
- package/lib/types/permissions.js +75 -12
- package/lib/types/plugin-catalog.d.ts +35 -0
- package/lib/types/plugin-catalog.js +39 -0
- package/lib/types/plugin-health.d.ts +102 -0
- package/lib/types/plugin-health.js +184 -0
- package/lib/types/quota-tiers.d.ts +15 -0
- package/lib/types/quota-tiers.js +23 -3
- package/lib/types/wire-vocabulary.d.ts +102 -0
- package/lib/types/wire-vocabulary.js +94 -0
- package/lib/utils/alias-resolver.js +2 -2
- package/lib/utils/audit.d.ts +5 -2
- package/lib/utils/audit.js +6 -3
- package/lib/utils/compliance-attributes.js +3 -4
- package/lib/utils/concurrency.d.ts +7 -0
- package/lib/utils/concurrency.js +13 -1
- package/lib/utils/env.d.ts +3 -4
- package/lib/utils/env.js +4 -5
- package/lib/utils/identity.d.ts +13 -4
- package/lib/utils/identity.js +18 -10
- package/lib/utils/index.d.ts +13 -10
- package/lib/utils/index.js +13 -10
- package/lib/utils/jwk.d.ts +4 -0
- package/lib/utils/jwk.js +13 -1
- package/lib/utils/logger.d.ts +1 -1
- package/lib/utils/logger.js +1 -1
- package/lib/utils/object.d.ts +11 -0
- package/lib/utils/object.js +24 -1
- package/lib/utils/params.d.ts +8 -22
- package/lib/utils/params.js +15 -43
- package/lib/utils/plugin-compliance.d.ts +98 -0
- package/lib/utils/plugin-compliance.js +78 -0
- package/lib/utils/proof-of-work.d.ts +69 -0
- package/lib/utils/proof-of-work.js +139 -0
- package/lib/utils/response.d.ts +16 -6
- package/lib/utils/response.js +18 -15
- package/lib/utils/retention.d.ts +17 -0
- package/lib/utils/retention.js +30 -0
- package/lib/utils/secret-encryption.d.ts +7 -7
- package/lib/utils/secret-encryption.js +9 -10
- package/lib/utils/secret-rotation.js +2 -2
- package/lib/utils/sensitive-patterns.js +4 -5
- package/lib/utils/service-registry.d.ts +15 -0
- package/lib/utils/service-registry.js +24 -0
- package/lib/utils/ssrf.d.ts +11 -2
- package/lib/utils/ssrf.js +112 -33
- package/lib/validation/ai-schemas.js +3 -2
- package/lib/validation/common-schemas.d.ts +0 -9
- package/lib/validation/common-schemas.js +1 -7
- package/lib/validation/dockerfile-static.d.ts +26 -0
- package/lib/validation/dockerfile-static.js +210 -0
- package/lib/validation/index.d.ts +13 -4
- package/lib/validation/index.js +14 -5
- package/lib/validation/message-schemas.js +6 -4
- package/lib/validation/pipeline-schemas.d.ts +8 -2
- package/lib/validation/pipeline-schemas.js +30 -4
- package/lib/validation/plugin-base-images.d.ts +20 -0
- package/lib/validation/plugin-base-images.js +17 -0
- package/lib/validation/plugin-catalog-detect.d.ts +86 -0
- package/lib/validation/plugin-catalog-detect.js +237 -0
- package/lib/validation/plugin-catalog-metadata.d.ts +141 -0
- package/lib/validation/plugin-catalog-metadata.js +162 -0
- package/lib/validation/plugin-heuristics.d.ts +41 -0
- package/lib/validation/plugin-heuristics.js +211 -0
- package/lib/validation/plugin-lint.d.ts +18 -0
- package/lib/validation/plugin-lint.js +136 -0
- package/lib/validation/plugin-name-confusable.d.ts +15 -0
- package/lib/validation/plugin-name-confusable.js +81 -0
- package/lib/validation/plugin-schemas.d.ts +40 -26
- package/lib/validation/plugin-schemas.js +26 -23
- package/lib/validation/plugin-spec-schema.d.ts +112 -0
- package/lib/validation/plugin-spec-schema.js +163 -0
- package/lib/validation/plugin-template-contract.d.ts +64 -0
- package/lib/validation/plugin-template-contract.js +113 -0
- package/package.json +69 -4
- package/lib/testing/mock-api-core.d.ts +0 -150
- package/lib/testing/mock-api-core.js +0 -246
- package/lib/testing/mock-drizzle.d.ts +0 -6
- package/lib/testing/mock-drizzle.js +0 -57
- package/lib/testing/route-coverage.d.ts +0 -64
- package/lib/testing/route-coverage.js +0 -183
- package/lib/testing/service-tokens.d.ts +0 -66
- package/lib/testing/service-tokens.js +0 -137
- package/lib/testing/tier-mock.d.ts +0 -44
- package/lib/testing/tier-mock.js +0 -65
- package/lib/testing/user-tokens.d.ts +0 -75
- package/lib/testing/user-tokens.js +0 -115
|
@@ -15,9 +15,8 @@
|
|
|
15
15
|
* - {@link isAncestorOrgWith} — UP: is A an ancestor of B?
|
|
16
16
|
* - {@link expandOrgScopeWith} — DOWN: self + all descendant org ids.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* orgs get parents.
|
|
18
|
+
* A root org (`parentOrgId` null) resolves to `{ rootOrgId: self }` and scope
|
|
19
|
+
* `[self]`.
|
|
21
20
|
*/
|
|
22
21
|
/** Hard ceiling on ancestry/descendant traversal — cycle + abuse guard. */
|
|
23
22
|
export const MAX_ORG_DEPTH = 16;
|
|
@@ -56,6 +55,27 @@ export function createOrgIdCaster(ObjectIdCtor) {
|
|
|
56
55
|
return isObjectIdHex(idStr) ? new ObjectIdCtor(idStr) : idStr;
|
|
57
56
|
};
|
|
58
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* The parent/children lookups over a service's own `organizations` model, for
|
|
60
|
+
* the `*With` traversals below. `getChildOrgIds` returns LIVE children only (a
|
|
61
|
+
* soft-deleted team leaves every downward scope); `getParentOrgId` does not
|
|
62
|
+
* filter, so a deleted team still resolves through its parent.
|
|
63
|
+
*/
|
|
64
|
+
export function createMongoOrgHierarchy(Model, toOrgId) {
|
|
65
|
+
return {
|
|
66
|
+
async getParentOrgId(orgId) {
|
|
67
|
+
const org = await Model.findById(toOrgId(orgId)).select('parentOrgId').lean();
|
|
68
|
+
return toOrgIdString(org?.parentOrgId);
|
|
69
|
+
},
|
|
70
|
+
async getChildOrgIds(frontier) {
|
|
71
|
+
// `deletedAt: null` matches both an explicit null and an absent field.
|
|
72
|
+
const children = await Model.find({ parentOrgId: { $in: frontier }, deletedAt: null }).select('_id').lean();
|
|
73
|
+
return children
|
|
74
|
+
.map((c) => toOrgIdString(c._id))
|
|
75
|
+
.filter((id) => !!id);
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
59
79
|
/**
|
|
60
80
|
* Walk `parentOrgId` from `orgId` up to the root. Returns the direct parent (if
|
|
61
81
|
* any) and the root org id (the input itself when the org has no parent). On a
|
|
@@ -85,6 +105,27 @@ export async function resolveOrgLineageWith(orgId, getParent) {
|
|
|
85
105
|
export async function resolveRootOrgIdWith(orgId, getParent) {
|
|
86
106
|
return (await resolveOrgLineageWith(orgId, getParent)).rootOrgId;
|
|
87
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Fail-CLOSED variant of {@link resolveRootOrgIdWith}: returns `null` when the
|
|
110
|
+
* root can't be proven — a cycle or a chain deeper than {@link MAX_ORG_DEPTH} —
|
|
111
|
+
* instead of treating the last reached id as the root. Lookup errors propagate.
|
|
112
|
+
* For callers where a wrong root is worse than no answer (e.g. a retention purge
|
|
113
|
+
* that would otherwise apply a team's shorter default window).
|
|
114
|
+
*/
|
|
115
|
+
export async function resolveRootOrgIdStrict(orgId, getParent) {
|
|
116
|
+
const seen = new Set([orgId]);
|
|
117
|
+
let currentId = orgId;
|
|
118
|
+
for (let depth = 0; depth < MAX_ORG_DEPTH; depth++) {
|
|
119
|
+
const parent = toOrgIdString(await getParent(currentId));
|
|
120
|
+
if (!parent || parent === currentId)
|
|
121
|
+
return currentId;
|
|
122
|
+
if (seen.has(parent))
|
|
123
|
+
return null;
|
|
124
|
+
seen.add(parent);
|
|
125
|
+
currentId = parent;
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
88
129
|
/**
|
|
89
130
|
* True when `ancestorOrgId` is an ancestor of `candidateOrgId` — i.e.
|
|
90
131
|
* `candidateOrgId` lives somewhere in the subtree rooted at `ancestorOrgId`.
|
|
@@ -135,4 +176,4 @@ export async function expandOrgScopeWith(orgId, getChildren) {
|
|
|
135
176
|
}
|
|
136
177
|
return result;
|
|
137
178
|
}
|
|
138
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JnLWhpZXJhcmNoeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9oZWxwZXJzL29yZy1oaWVyYXJjaHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBRUgsMkVBQTJFO0FBQzNFLE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxFQUFFLENBQUM7QUFRaEMsb0ZBQW9GO0FBQ3BGLE1BQU0sVUFBVSxhQUFhLENBQUMsQ0FBVTtJQUN0QyxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLFNBQVM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUNwRCxNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDcEIsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLE1BQU0sSUFBSSxDQUFDLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUNoRSxDQUFDO0FBRUQsa0ZBQWtGO0FBQ2xGLFNBQVMsYUFBYSxDQUFDLEVBQVU7SUFDL0IsT0FBTyxFQUFFLENBQUMsTUFBTSxLQUFLLEVBQUUsSUFBSSxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDMUQsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FDL0IsWUFBb0M7SUFFcEMsT0FBTyxDQUFDLEVBQUUsRUFBRSxFQUFFO1FBQ1osTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDN0MsT0FBTyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksWUFBWSxDQUFDLEtBQUssQ0FB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YUFBYSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUM7UUFDMUUsTUFBTSxRQUFRLEdBQUcsTUFBTSxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDN0MsTUFBTSxJQUFJLEdBQWEsRUFBRSxDQUFDO1FBQzFCLEtBQUssTUFBTSxHQUFHLElBQUksUUFBUSxFQUFFLENBQUM7WUFDM0IsTUFBTSxFQUFFLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzlCLElBQUksQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQUUsU0FBUztZQUNsQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2IsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2hCLENBQUM7UUFDRCxRQUFRLEdBQUcsSUFBSSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogT3JnIOKGkiB0ZWFtIGhpZXJhcmNoeSB0cmF2ZXJzYWwgKG9yZy10ZWFtLWhpZXJhcmNoeSBwcm9wb3NhbCkuXG4gKlxuICogQSBcInRlYW1cIiBpcyBhbiBvcmdhbml6YXRpb24gd2hvc2UgYHBhcmVudE9yZ0lkYCBwb2ludHMgYXQgYW5vdGhlciBvcmc7IGEgcm9vdFxuICogb3JnIGhhcyBgcGFyZW50T3JnSWQgPSBudWxsYC4gVGhlc2UgaGVscGVycyB3YWxrIHRoYXQgc2luZ2xlIHNlbGYtcmVmZXJlbnRpYWxcbiAqIGNvbHVtbiwgYnV0IGhvbGQgKipubyBkYXRhYmFzZSBkZXBlbmRlbmN5Kiogb2YgdGhlaXIgb3duOiBlYWNoIHRha2VzIGEgcXVlcnlcbiAqIGNhbGxiYWNrIHNvIGV2ZXJ5IHNlcnZpY2UgKHBsYXRmb3JtLCBxdW90YSwg4oCmKSBjYW4gc2hhcmUgdGhlIGN5Y2xlLXNhZmUsXG4gKiBkZXB0aC1jYXBwZWQgdHJhdmVyc2FsIGxvZ2ljIHdoaWxlIHJlYWRpbmcgaXRzIG93biBNb25nb29zZSBtb2RlbCB3aXRoIGl0cyBvd25cbiAqIGBfaWRgIGNhc3RpbmcgcnVsZXMuXG4gKlxuICogICAtIHtAbGluayByZXNvbHZlT3JnTGluZWFnZVdpdGh9IOKAlCBVUDogZGlyZWN0IHBhcmVudCArIHJvb3Qgb2YgdGhlIGNoYWluLlxuICogICAtIHtAbGluayByZXNvbHZlUm9vdE9yZ0lkV2l0aH0gICDigJQgVVA6IGp1c3QgdGhlIHJvb3QgaWQuXG4gKiAgIC0ge0BsaW5rIGlzQW5jZXN0b3JPcmdXaXRofSAgICAgIOKAlCBVUDogaXMgQSBhbiBhbmNlc3RvciBvZiBCP1xuICogICAtIHtAbGluayBleHBhbmRPcmdTY29wZVdpdGh9ICAgICDigJQgRE9XTjogc2VsZiArIGFsbCBkZXNjZW5kYW50IG9yZyBpZHMuXG4gKlxuICogRXZlcnkgb3JnIGlzIGZsYXQgdG9kYXkgKGBwYXJlbnRPcmdJZGAgbnVsbCBvbiBhbGwgcm93cyksIHNvIGxpbmVhZ2UgcmVzb2x2ZXNcbiAqIHRvIGB7IHJvb3RPcmdJZDogc2VsZiB9YCBhbmQgc2NvcGUgdG8gYFtzZWxmXWAg4oCUIGkuZS4gdGhlc2UgYXJlIG5vLW9wcyB1bnRpbFxuICogb3JncyBnZXQgcGFyZW50cy5cbiAqL1xuXG4vKiogSGFyZCBjZWlsaW5nIG9uIGFuY2VzdHJ5L2Rlc2NlbmRhbnQgdHJhdmVyc2FsIOKAlCBjeWNsZSArIGFidXNlIGd1YXJkLiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9PUkdfREVQVEggPSAxNjtcblxuLyoqIEZldGNoIGFuIG9yZydzIGRpcmVjdCBgcGFyZW50T3JnSWRgLCBvciB1bmRlZmluZWQgZm9yIGEgcm9vdC9taXNzaW5nIG9yZy4gKi9cbmV4cG9ydCB0eXBlIEdldFBhcmVudE9yZ0lkID0gKG9yZ0lkOiBzdHJpbmcpID0+IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPjtcblxuLyoqIEZldGNoIHRoZSBkaXJlY3QgY2hpbGQgb3JnIGlkcyBvZiBldmVyeSBvcmcgaW4gYGZyb250aWVyYCAob25lIHJvdW5kIG9mIEJGUykuICovXG5leHBvcnQgdHlwZSBHZXRDaGlsZE9yZ0lkcyA9IChmcm9udGllcjogc3RyaW5nW10pID0+IFByb21pc2U8c3RyaW5nW10+O1xuXG4vKiogTm9ybWFsaXplIGEgTWl4ZWQvT2JqZWN0SWQvc3RyaW5nIG9yZyBpZCB0byBhIG5vbi1lbXB0eSBzdHJpbmcsIG9yIHVuZGVmaW5lZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b09yZ0lkU3RyaW5nKHY6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAodiA9PT0gbnVsbCB8fCB2ID09PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IHMgPSBTdHJpbmcodik7XG4gIHJldHVybiBzICYmIHMgIT09ICdudWxsJyAmJiBzICE9PSAndW5kZWZpbmVkJyA/IHMgOiB1bmRlZmluZWQ7XG59XG5cbi8qKiBUcnVlIHdoZW4gYGlkYCBpcyBhIDI0LWNoYXJhY3RlciBoZXggc3RyaW5nIOKAlCBpLmUuIGNhc3RhYmxlIHRvIGFuIE9iamVjdElkLiAqL1xuZnVuY3Rpb24gaXNPYmplY3RJZEhleChpZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBpZC5sZW5ndGggPT09IDI0ICYmIC9eWzAtOWEtZkEtRl17MjR9JC8udGVzdChpZCk7XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIG9yZy1pZCBjYXN0IHRoZSBNb25nby1iYWNrZWQgc2VydmljZXMgdXNlIG9uIGV2ZXJ5IGBfaWRgIGxvb2t1cC5cbiAqXG4gKiBQbGF0Zm9ybSB3cml0ZXMgT2JqZWN0SWQgYF9pZGBzIGludG8gdGhlIHNoYXJlZCBgb3JnYW5pemF0aW9uc2AgY29sbGVjdGlvbixcbiAqIHdoaWxlIHRoZSB3ZWxsLWtub3duIGAnc3lzdGVtJ2Agb3JnIChhbmQgYHBhcmVudE9yZ0lkYCwgc3RpbGwgYSBTdHJpbmcgY29sdW1uKVxuICogYXJlIHBsYWluIHN0cmluZ3Mg4oCUIHNvIGEgMjQtaGV4IGlkIGFycml2aW5nIGZyb20gYSByb3V0ZSBwYXJhbSAvIEpXVCBjbGFpbSAvXG4gKiBjcm9zcy1zZXJ2aWNlIHBheWxvYWQgbXVzdCBiZSBjYXN0IG9yIGBmaW5kQnlJZCgnPDI0aGV4PicpYCBuZXZlciBtYXRjaGVzLlxuICpcbiAqIFBsYXRmb3JtIGFuZCBxdW90YSBlYWNoIGhhZCB0aGVpciBPV04gYHRvT3JnSWRgIHdpdGggYSBkaWZmZXJlbnQgc2lnbmF0dXJlXG4gKiAoYHN0cmluZyB8IHN0cmluZ1tdYCB2cyBgc3RyaW5nYCksIHdoaWNoIGlzIGV4YWN0bHkgdGhlIGRyaWZ0IHRoaXMgcmVtb3ZlczpcbiAqIHRoZSBsb2dpYyBhbmQgdGhlIHNpZ25hdHVyZSBsaXZlIGhlcmUgb25jZSwgYW5kIGVhY2ggc2VydmljZSBzdXBwbGllcyBvbmx5XG4gKiBpdHMgbW9uZ29vc2UgYFR5cGVzLk9iamVjdElkYCBjb25zdHJ1Y3Rvci4gYXBpLWNvcmUgY2Fubm90IGltcG9ydCBtb25nb29zZVxuICogaXRzZWxmIChpdCBpcyBub3Qg4oCUIGFuZCBzaG91bGQgbm90IGJlY29tZSDigJQgYW4gYXBpLWNvcmUgZGVwZW5kZW5jeSksIHNvIHRoZVxuICogY29uc3RydWN0b3IgaXMgaW5qZWN0ZWQgcmF0aGVyIHRoYW4gaW1wb3J0ZWQuXG4gKlxuICogQGV4YW1wbGVcbiAqIGV4cG9ydCBjb25zdCB0b09yZ0lkID0gY3JlYXRlT3JnSWRDYXN0ZXIobW9uZ29vc2UuVHlwZXMuT2JqZWN0SWQpO1xuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlT3JnSWRDYXN0ZXI8VD4oXG4gIE9iamVjdElkQ3RvcjogbmV3IChoZXg6IHN0cmluZykgPT4gVCxcbik6IChpZDogc3RyaW5nIHwgc3RyaW5nW10pID0+IHN0cmluZyB8IFQge1xuICByZXR1cm4gKGlkKSA9PiB7XG4gICAgY29uc3QgaWRTdHIgPSBBcnJheS5pc0FycmF5KGlkKSA/IGlkWzBdIDogaWQ7XG4gICAgcmV0dXJuIGlzT2JqZWN0SWRIZXgoaWRTdHIpID8gbmV3IE9iamVjdElkQ3RvcihpZFN0cikgOiBpZFN0cjtcbiAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcmdMaW5lYWdlIHtcbiAgLyoqIFRoZSBvcmcncyBkaXJlY3QgcGFyZW50IGlkLCBvciBgdW5kZWZpbmVkYCB3aGVuIGl0J3MgYSByb290IG9yZy4gKi9cbiAgcGFyZW50T3JnSWQ/OiBzdHJpbmc7XG4gIC8qKiBUb3Agb2YgdGhlIGFuY2VzdHJ5IGNoYWluLiBFcXVhbHMgdGhlIGlucHV0IGBvcmdJZGAgZm9yIGEgcm9vdCBvcmcuICovXG4gIHJvb3RPcmdJZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIFdhbGsgYHBhcmVudE9yZ0lkYCBmcm9tIGBvcmdJZGAgdXAgdG8gdGhlIHJvb3QuIFJldHVybnMgdGhlIGRpcmVjdCBwYXJlbnQgKGlmXG4gKiBhbnkpIGFuZCB0aGUgcm9vdCBvcmcgaWQgKHRoZSBpbnB1dCBpdHNlbGYgd2hlbiB0aGUgb3JnIGhhcyBubyBwYXJlbnQpLiBPbiBhXG4gKiBkZXRlY3RlZCBjeWNsZSwgYSBtaXNzaW5nIG9yZywgb3IgdGhlIGRlcHRoIGNhcCwgdHJhdmVyc2FsIHN0b3BzIGFuZCB0aGUgbGFzdFxuICogcmVhY2hlZCBpZCBpcyB0cmVhdGVkIGFzIHRoZSByb290LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZU9yZ0xpbmVhZ2VXaXRoKG9yZ0lkOiBzdHJpbmcsIGdldFBhcmVudDogR2V0UGFyZW50T3JnSWQpOiBQcm9taXNlPE9yZ0xpbmVhZ2U+IHtcbiAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPihbb3JnSWRdKTtcbiAgbGV0IGN1cnJlbnRJZCA9IG9yZ0lkO1xuICBsZXQgcGFyZW50T3JnSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICBmb3IgKGxldCBkZXB0aCA9IDA7IGRlcHRoIDwgTUFYX09SR19ERVBUSDsgZGVwdGgrKykge1xuICAgIGNvbnN0IHBhcmVudCA9IHRvT3JnSWRTdHJpbmcoYXdhaXQgZ2V0UGFyZW50KGN1cnJlbnRJZCkpO1xuICAgIGlmICghcGFyZW50KSBicmVhazsgLy8gY3VycmVudElkIGlzIHRoZSByb290XG4gICAgLy8gUmVjb3JkIHRoZSBkaXJlY3QgcGFyZW50IG9ubHkgd2hlbiBpdCBpc24ndCBhIHNlbGYtbG9vcCwgc28gYSBtYWxmb3JtZWRcbiAgICAvLyBB4oaSQSBvcmcgaXNuJ3QgcmVwb3J0ZWQgYXMgaXRzIG93biBwYXJlbnQuXG4gICAgaWYgKGRlcHRoID09PSAwICYmIHBhcmVudCAhPT0gb3JnSWQpIHBhcmVudE9yZ0lkID0gcGFyZW50O1xuICAgIGlmIChzZWVuLmhhcyhwYXJlbnQpKSBicmVhazsgLy8gY3ljbGUg4oCUIHRyZWF0IGN1cnJlbnRJZCBhcyB0aGUgcm9vdFxuICAgIHNlZW4uYWRkKHBhcmVudCk7XG4gICAgY3VycmVudElkID0gcGFyZW50O1xuICB9XG5cbiAgcmV0dXJuIHsgcm9vdE9yZ0lkOiBjdXJyZW50SWQsIC4uLihwYXJlbnRPcmdJZCAmJiB7IHBhcmVudE9yZ0lkIH0pIH07XG59XG5cbi8qKiBXYWxrIGBwYXJlbnRPcmdJZGAgdXAgdG8gdGhlIHJvb3QgYW5kIHJldHVybiBqdXN0IHRoZSByb290IGlkLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlc29sdmVSb290T3JnSWRXaXRoKG9yZ0lkOiBzdHJpbmcsIGdldFBhcmVudDogR2V0UGFyZW50T3JnSWQpOiBQcm9taXNlPHN0cmluZz4ge1xuICByZXR1cm4gKGF3YWl0IHJlc29sdmVPcmdMaW5lYWdlV2l0aChvcmdJZCwgZ2V0UGFyZW50KSkucm9vdE9yZ0lkO1xufVxuXG4vKipcbiAqIFRydWUgd2hlbiBgYW5jZXN0b3JPcmdJZGAgaXMgYW4gYW5jZXN0b3Igb2YgYGNhbmRpZGF0ZU9yZ0lkYCDigJQgaS5lLlxuICogYGNhbmRpZGF0ZU9yZ0lkYCBsaXZlcyBzb21ld2hlcmUgaW4gdGhlIHN1YnRyZWUgcm9vdGVkIGF0IGBhbmNlc3Rvck9yZ0lkYC5cbiAqIFdhbGtzIGBjYW5kaWRhdGVPcmdJZGAncyBwYXJlbnQgY2hhaW4gdXB3YXJkLCBkZXB0aC1jYXBwZWQgYW5kIGN5Y2xlLXNhZmUuXG4gKiBSZXR1cm5zIGBmYWxzZWAgd2hlbiB0aGUgdHdvIGFyZSBlcXVhbCAoYW4gb3JnIGlzIG5vdCBpdHMgb3duIGFuY2VzdG9yKSBvclxuICogdW5yZWxhdGVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaXNBbmNlc3Rvck9yZ1dpdGgoXG4gIGFuY2VzdG9yT3JnSWQ6IHN0cmluZyxcbiAgY2FuZGlkYXRlT3JnSWQ6IHN0cmluZyxcbiAgZ2V0UGFyZW50OiBHZXRQYXJlbnRPcmdJZCxcbik6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBpZiAoYW5jZXN0b3JPcmdJZCA9PT0gY2FuZGlkYXRlT3JnSWQpIHJldHVybiBmYWxzZTtcblxuICBjb25zdCBzZWVuID0gbmV3IFNldDxzdHJpbmc+KFtjYW5kaWRhdGVPcmdJZF0pO1xuICBsZXQgY3VycmVudElkID0gY2FuZGlkYXRlT3JnSWQ7XG5cbiAgZm9yIChsZXQgZGVwdGggPSAwOyBkZXB0aCA8IE1BWF9PUkdfREVQVEg7IGRlcHRoKyspIHtcbiAgICBjb25zdCBwYXJlbnQgPSB0b09yZ0lkU3RyaW5nKGF3YWl0IGdldFBhcmVudChjdXJyZW50SWQpKTtcbiAgICBpZiAoIXBhcmVudCkgcmV0dXJuIGZhbHNlOyAvLyByZWFjaGVkIGEgcm9vdCB3aXRob3V0IG1hdGNoaW5nXG4gICAgaWYgKHBhcmVudCA9PT0gYW5jZXN0b3JPcmdJZCkgcmV0dXJuIHRydWU7XG4gICAgaWYgKHNlZW4uaGFzKHBhcmVudCkpIHJldHVybiBmYWxzZTsgLy8gY3ljbGVcbiAgICBzZWVuLmFkZChwYXJlbnQpO1xuICAgIGN1cnJlbnRJZCA9IHBhcmVudDtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBFeHBhbmQgYG9yZ0lkYCB0byBpdHNlbGYgcGx1cyBldmVyeSBkZXNjZW5kYW50IG9yZyBpZCAoYnJlYWR0aC1maXJzdCBvdmVyXG4gKiBgcGFyZW50T3JnSWRgKS4gVGhpcyBpcyB0aGUgc2NvcGUgYSBwYXJlbnQgb3JnIFwic2Vlc1wiIGZvciB2aXNpYmlsaXR5IGFuZFxuICogYW5hbHl0aWNzIHJvbGx1cHM6IGBbc2VsZiwgLi4uZGVzY2VuZGFudHNdYC4gUmV0dXJucyBgW29yZ0lkXWAgd2hlbiB0aGUgb3JnXG4gKiBoYXMgbm8gY2hpbGRyZW4uIEN5Y2xlLXNhZmUgYW5kIGRlcHRoLWNhcHBlZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGV4cGFuZE9yZ1Njb3BlV2l0aChvcmdJZDogc3RyaW5nLCBnZXRDaGlsZHJlbjogR2V0Q2hpbGRPcmdJZHMpOiBQcm9taXNlPHN0cmluZ1tdPiB7XG4gIGNvbnN0IHJlc3VsdDogc3RyaW5nW10gPSBbb3JnSWRdO1xuICBjb25zdCBzZWVuID0gbmV3IFNldDxzdHJpbmc+KFtvcmdJZF0pO1xuICBsZXQgZnJvbnRpZXI6IHN0cmluZ1tdID0gW29yZ0lkXTtcblxuICBmb3IgKGxldCBkZXB0aCA9IDA7IGRlcHRoIDwgTUFYX09SR19ERVBUSCAmJiBmcm9udGllci5sZW5ndGggPiAwOyBkZXB0aCsrKSB7XG4gICAgY29uc3QgY2hpbGRyZW4gPSBhd2FpdCBnZXRDaGlsZHJlbihmcm9udGllcik7XG4gICAgY29uc3QgbmV4dDogc3RyaW5nW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHJhdyBvZiBjaGlsZHJlbikge1xuICAgICAgY29uc3QgaWQgPSB0b09yZ0lkU3RyaW5nKHJhdyk7XG4gICAgICBpZiAoIWlkIHx8IHNlZW4uaGFzKGlkKSkgY29udGludWU7XG4gICAgICBzZWVuLmFkZChpZCk7XG4gICAgICByZXN1bHQucHVzaChpZCk7XG4gICAgICBuZXh0LnB1c2goaWQpO1xuICAgIH1cbiAgICBmcm9udGllciA9IG5leHQ7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuIl19
|
|
179
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3JnLWhpZXJhcmNoeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9oZWxwZXJzL29yZy1oaWVyYXJjaHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFFSCwyRUFBMkU7QUFDM0UsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLEVBQUUsQ0FBQztBQVFoQyxvRkFBb0Y7QUFDcEYsTUFBTSxVQUFVLGFBQWEsQ0FBQyxDQUFVO0lBQ3RDLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssU0FBUztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQ3BELE1BQU0sQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwQixPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssTUFBTSxJQUFJLENBQUMsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ2hFLENBQUM7QUFFRCxrRkFBa0Y7QUFDbEYsU0FBUyxhQUFhLENBQUMsRUFBVTtJQUMvQixPQUFPLEVBQUUsQ0FBQyxNQUFNLEtBQUssRUFBRSxJQUFJLG1CQUFtQixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMxRCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUMvQixZQUFvQztJQUVwQyxPQUFPLENBQUMsRUFBRSxFQUFFLEVBQUU7UUFDWixNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUM3QyxPQUFPLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFD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Q0FBQztJQUNyQixDQUFDO0lBRUQsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLGtCQUFrQixDQUFDLEtBQWEsRUFBRSxXQUEyQjtJQUNqRixNQUFNLE1BQU0sR0FBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pDLE1BQU0sSUFBSSxHQUFHLElBQUksR0FBRyxDQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUN0QyxJQUFJLFFBQVEsR0FBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRWpDLEtBQUssSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxhQUFhLElBQUksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQztRQUMxRSxNQUFNLFFBQVEsR0FBRyxNQUFNLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM3QyxNQUFNLElBQUksR0FBYSxFQUFFLENBQUM7UUFDMUIsS0FBSyxNQUFNLEdBQUcsSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUMzQixNQUFNLEVBQUUsR0FBRyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDOUIsSUFBSSxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFBRSxTQUFTO1lBQ2xDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDYixNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hCLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDaEIsQ0FBQztRQUNELFFBQVEsR0FBRyxJQUFJLENBQUM7SUFDbEIsQ0FBQztJQUVELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuLyoqXG4gKiBPcmcg4oaSIHRlYW0gaGllcmFyY2h5IHRyYXZlcnNhbCAob3JnLXRlYW0taGllcmFyY2h5IHByb3Bvc2FsKS5cbiAqXG4gKiBBIFwidGVhbVwiIGlzIGFuIG9yZ2FuaXphdGlvbiB3aG9zZSBgcGFyZW50T3JnSWRgIHBvaW50cyBhdCBhbm90aGVyIG9yZzsgYSByb290XG4gKiBvcmcgaGFzIGBwYXJlbnRPcmdJZCA9IG51bGxgLiBUaGVzZSBoZWxwZXJzIHdhbGsgdGhhdCBzaW5nbGUgc2VsZi1yZWZlcmVudGlhbFxuICogY29sdW1uLCBidXQgaG9sZCAqKm5vIGRhdGFiYXNlIGRlcGVuZGVuY3kqKiBvZiB0aGVpciBvd246IGVhY2ggdGFrZXMgYSBxdWVyeVxuICogY2FsbGJhY2sgc28gZXZlcnkgc2VydmljZSAocGxhdGZvcm0sIHF1b3RhLCDigKYpIGNhbiBzaGFyZSB0aGUgY3ljbGUtc2FmZSxcbiAqIGRlcHRoLWNhcHBlZCB0cmF2ZXJzYWwgbG9naWMgd2hpbGUgcmVhZGluZyBpdHMgb3duIE1vbmdvb3NlIG1vZGVsIHdpdGggaXRzIG93blxuICogYF9pZGAgY2FzdGluZyBydWxlcy5cbiAqXG4gKiAgIC0ge0BsaW5rIHJlc29sdmVPcmdMaW5lYWdlV2l0aH0g4oCUIFVQOiBkaXJlY3QgcGFyZW50ICsgcm9vdCBvZiB0aGUgY2hhaW4uXG4gKiAgIC0ge0BsaW5rIHJlc29sdmVSb290T3JnSWRXaXRofSAgIOKAlCBVUDoganVzdCB0aGUgcm9vdCBpZC5cbiAqICAgLSB7QGxpbmsgaXNBbmNlc3Rvck9yZ1dpdGh9ICAgICAg4oCUIFVQOiBpcyBBIGFuIGFuY2VzdG9yIG9mIEI/XG4gKiAgIC0ge0BsaW5rIGV4cGFuZE9yZ1Njb3BlV2l0aH0gICAgIOKAlCBET1dOOiBzZWxmICsgYWxsIGRlc2NlbmRhbnQgb3JnIGlkcy5cbiAqXG4gKiBBIHJvb3Qgb3JnIChgcGFyZW50T3JnSWRgIG51bGwpIHJlc29sdmVzIHRvIGB7IHJvb3RPcmdJZDogc2VsZiB9YCBhbmQgc2NvcGVcbiAqIGBbc2VsZl1gLlxuICovXG5cbi8qKiBIYXJkIGNlaWxpbmcgb24gYW5jZXN0cnkvZGVzY2VuZGFudCB0cmF2ZXJzYWwg4oCUIGN5Y2xlICsgYWJ1c2UgZ3VhcmQuICovXG5leHBvcnQgY29uc3QgTUFYX09SR19ERVBUSCA9IDE2O1xuXG4vKiogRmV0Y2ggYW4gb3JnJ3MgZGlyZWN0IGBwYXJlbnRPcmdJZGAsIG9yIHVuZGVmaW5lZCBmb3IgYSByb290L21pc3Npbmcgb3JnLiAqL1xuZXhwb3J0IHR5cGUgR2V0UGFyZW50T3JnSWQgPSAob3JnSWQ6IHN0cmluZykgPT4gUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+O1xuXG4vKiogRmV0Y2ggdGhlIGRpcmVjdCBjaGlsZCBvcmcgaWRzIG9mIGV2ZXJ5IG9yZyBpbiBgZnJvbnRpZXJgIChvbmUgcm91bmQgb2YgQkZTKS4gKi9cbmV4cG9ydCB0eXBlIEdldENoaWxkT3JnSWRzID0gKGZyb250aWVyOiBzdHJpbmdbXSkgPT4gUHJvbWlzZTxzdHJpbmdbXT47XG5cbi8qKiBOb3JtYWxpemUgYSBNaXhlZC9PYmplY3RJZC9zdHJpbmcgb3JnIGlkIHRvIGEgbm9uLWVtcHR5IHN0cmluZywgb3IgdW5kZWZpbmVkLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvT3JnSWRTdHJpbmcodjogdW5rbm93bik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICh2ID09PSBudWxsIHx8IHYgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgcyA9IFN0cmluZyh2KTtcbiAgcmV0dXJuIHMgJiYgcyAhPT0gJ251bGwnICYmIHMgIT09ICd1bmRlZmluZWQnID8gcyA6IHVuZGVmaW5lZDtcbn1cblxuLyoqIFRydWUgd2hlbiBgaWRgIGlzIGEgMjQtY2hhcmFjdGVyIGhleCBzdHJpbmcg4oCUIGkuZS4gY2FzdGFibGUgdG8gYW4gT2JqZWN0SWQuICovXG5mdW5jdGlvbiBpc09iamVjdElkSGV4KGlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIGlkLmxlbmd0aCA9PT0gMjQgJiYgL15bMC05YS1mQS1GXXsyNH0kLy50ZXN0KGlkKTtcbn1cblxuLyoqXG4gKiBCdWlsZCB0aGUgb3JnLWlkIGNhc3QgdGhlIE1vbmdvLWJhY2tlZCBzZXJ2aWNlcyB1c2Ugb24gZXZlcnkgYF9pZGAgbG9va3VwLlxuICpcbiAqIFBsYXRmb3JtIHdyaXRlcyBPYmplY3RJZCBgX2lkYHMgaW50byB0aGUgc2hhcmVkIGBvcmdhbml6YXRpb25zYCBjb2xsZWN0aW9uLFxuICogd2hpbGUgdGhlIHdlbGwta25vd24gYCdzeXN0ZW0nYCBvcmcgKGFuZCBgcGFyZW50T3JnSWRgLCBzdGlsbCBhIFN0cmluZyBjb2x1bW4pXG4gKiBhcmUgcGxhaW4gc3RyaW5ncyDigJQgc28gYSAyNC1oZXggaWQgYXJyaXZpbmcgZnJvbSBhIHJvdXRlIHBhcmFtIC8gSldUIGNsYWltIC9cbiAqIGNyb3NzLXNlcnZpY2UgcGF5bG9hZCBtdXN0IGJlIGNhc3Qgb3IgYGZpbmRCeUlkKCc8MjRoZXg+JylgIG5ldmVyIG1hdGNoZXMuXG4gKlxuICogUGxhdGZvcm0gYW5kIHF1b3RhIGVhY2ggaGFkIHRoZWlyIE9XTiBgdG9PcmdJZGAgd2l0aCBhIGRpZmZlcmVudCBzaWduYXR1cmVcbiAqIChgc3RyaW5nIHwgc3RyaW5nW11gIHZzIGBzdHJpbmdgKSwgd2hpY2ggaXMgZXhhY3RseSB0aGUgZHJpZnQgdGhpcyByZW1vdmVzOlxuICogdGhlIGxvZ2ljIGFuZCB0aGUgc2lnbmF0dXJlIGxpdmUgaGVyZSBvbmNlLCBhbmQgZWFjaCBzZXJ2aWNlIHN1cHBsaWVzIG9ubHlcbiAqIGl0cyBtb25nb29zZSBgVHlwZXMuT2JqZWN0SWRgIGNvbnN0cnVjdG9yLiBhcGktY29yZSBjYW5ub3QgaW1wb3J0IG1vbmdvb3NlXG4gKiBpdHNlbGYgKGl0IGlzIG5vdCDigJQgYW5kIHNob3VsZCBub3QgYmVjb21lIOKAlCBhbiBhcGktY29yZSBkZXBlbmRlbmN5KSwgc28gdGhlXG4gKiBjb25zdHJ1Y3RvciBpcyBpbmplY3RlZCByYXRoZXIgdGhhbiBpbXBvcnRlZC5cbiAqXG4gKiBAZXhhbXBsZVxuICogZXhwb3J0IGNvbnN0IHRvT3JnSWQgPSBjcmVhdGVPcmdJZENhc3Rlcihtb25nb29zZS5UeXBlcy5PYmplY3RJZCk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVPcmdJZENhc3RlcjxUPihcbiAgT2JqZWN0SWRDdG9yOiBuZXcgKGhleDogc3RyaW5nKSA9PiBULFxuKTogKGlkOiBzdHJpbmcgfCBzdHJpbmdbXSkgPT4gc3RyaW5nIHwgVCB7XG4gIHJldHVybiAoaWQpID0+IHtcbiAgICBjb25zdCBpZFN0ciA9IEFycmF5LmlzQXJyYXkoaWQpID8gaWRbMF0gOiBpZDtcbiAgICByZXR1cm4gaXNPYmplY3RJZEhleChpZFN0cikgPyBuZXcgT2JqZWN0SWRDdG9yKGlkU3RyKSA6IGlkU3RyO1xuICB9O1xufVxuXG4vKipcbiAqIFRoZSBzbGljZSBvZiBhIE1vbmdvb3NlIGBPcmdhbml6YXRpb25gIG1vZGVsIHRoZSBoaWVyYXJjaHkgY2FsbGJhY2tzIHJlYWQuXG4gKiBTdHJ1Y3R1cmFsIChhcGktY29yZSBoYXMgbm8gbW9uZ29vc2UgZGVwZW5kZW5jeSk7IGBzZWxlY3QoKS5sZWFuKClgIGNoYWlucyBhc1xuICogbW9uZ29vc2UgcXVlcmllcyBkby5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPcmdIaWVyYXJjaHlNb2RlbCB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIGZpbmRCeUlkKGlkOiBhbnkpOiB7IHNlbGVjdChmaWVsZHM6IHN0cmluZyk6IHsgbGVhbigpOiBQcm9taXNlTGlrZTx1bmtub3duPiB9IH07XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gIGZpbmQoZmlsdGVyOiBhbnkpOiB7IHNlbGVjdChmaWVsZHM6IHN0cmluZyk6IHsgbGVhbigpOiBQcm9taXNlTGlrZTx1bmtub3duW10+IH0gfTtcbn1cblxuLyoqXG4gKiBUaGUgcGFyZW50L2NoaWxkcmVuIGxvb2t1cHMgb3ZlciBhIHNlcnZpY2UncyBvd24gYG9yZ2FuaXphdGlvbnNgIG1vZGVsLCBmb3JcbiAqIHRoZSBgKldpdGhgIHRyYXZlcnNhbHMgYmVsb3cuIGBnZXRDaGlsZE9yZ0lkc2AgcmV0dXJucyBMSVZFIGNoaWxkcmVuIG9ubHkgKGFcbiAqIHNvZnQtZGVsZXRlZCB0ZWFtIGxlYXZlcyBldmVyeSBkb3dud2FyZCBzY29wZSk7IGBnZXRQYXJlbnRPcmdJZGAgZG9lcyBub3RcbiAqIGZpbHRlciwgc28gYSBkZWxldGVkIHRlYW0gc3RpbGwgcmVzb2x2ZXMgdGhyb3VnaCBpdHMgcGFyZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTW9uZ29PcmdIaWVyYXJjaHkoXG4gIE1vZGVsOiBPcmdIaWVyYXJjaHlNb2RlbCxcbiAgdG9PcmdJZDogKGlkOiBzdHJpbmcpID0+IHVua25vd24sXG4pOiB7IGdldFBhcmVudE9yZ0lkOiBHZXRQYXJlbnRPcmdJZDsgZ2V0Q2hpbGRPcmdJZHM6IEdldENoaWxkT3JnSWRzIH0ge1xuICByZXR1cm4ge1xuICAgIGFzeW5jIGdldFBhcmVudE9yZ0lkKG9yZ0lkKSB7XG4gICAgICBjb25zdCBvcmcgPSBhd2FpdCBNb2RlbC5maW5kQnlJZCh0b09yZ0lkKG9yZ0lkKSkuc2VsZWN0KCdwYXJlbnRPcmdJZCcpLmxlYW4oKTtcbiAgICAgIHJldHVybiB0b09yZ0lkU3RyaW5nKChvcmcgYXMgeyBwYXJlbnRPcmdJZD86IHVua25vd24gfSB8IG51bGwpPy5wYXJlbnRPcmdJZCk7XG4gICAgfSxcbiAgICBhc3luYyBnZXRDaGlsZE9yZ0lkcyhmcm9udGllcikge1xuICAgICAgLy8gYGRlbGV0ZWRBdDogbnVsbGAgbWF0Y2hlcyBib3RoIGFuIGV4cGxpY2l0IG51bGwgYW5kIGFuIGFic2VudCBmaWVsZC5cbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gYXdhaXQgTW9kZWwuZmluZCh7IHBhcmVudE9yZ0lkOiB7ICRpbjogZnJvbnRpZXIgfSwgZGVsZXRlZEF0OiBudWxsIH0pLnNlbGVjdCgnX2lkJykubGVhbigpO1xuICAgICAgcmV0dXJuIGNoaWxkcmVuXG4gICAgICAgIC5tYXAoKGMpID0+IHRvT3JnSWRTdHJpbmcoKGMgYXMgeyBfaWQ/OiB1bmtub3duIH0pLl9pZCkpXG4gICAgICAgIC5maWx0ZXIoKGlkKTogaWQgaXMgc3RyaW5nID0+ICEhaWQpO1xuICAgIH0sXG4gIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3JnTGluZWFnZSB7XG4gIC8qKiBUaGUgb3JnJ3MgZGlyZWN0IHBhcmVudCBpZCwgb3IgYHVuZGVmaW5lZGAgd2hlbiBpdCdzIGEgcm9vdCBvcmcuICovXG4gIHBhcmVudE9yZ0lkPzogc3RyaW5nO1xuICAvKiogVG9wIG9mIHRoZSBhbmNlc3RyeSBjaGFpbi4gRXF1YWxzIHRoZSBpbnB1dCBgb3JnSWRgIGZvciBhIHJvb3Qgb3JnLiAqL1xuICByb290T3JnSWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBXYWxrIGBwYXJlbnRPcmdJZGAgZnJvbSBgb3JnSWRgIHVwIHRvIHRoZSByb290LiBSZXR1cm5zIHRoZSBkaXJlY3QgcGFyZW50IChpZlxuICogYW55KSBhbmQgdGhlIHJvb3Qgb3JnIGlkICh0aGUgaW5wdXQgaXRzZWxmIHdoZW4gdGhlIG9yZyBoYXMgbm8gcGFyZW50KS4gT24gYVxuICogZGV0ZWN0ZWQgY3ljbGUsIGEgbWlzc2luZyBvcmcsIG9yIHRoZSBkZXB0aCBjYXAsIHRyYXZlcnNhbCBzdG9wcyBhbmQgdGhlIGxhc3RcbiAqIHJlYWNoZWQgaWQgaXMgdHJlYXRlZCBhcyB0aGUgcm9vdC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlc29sdmVPcmdMaW5lYWdlV2l0aChvcmdJZDogc3RyaW5nLCBnZXRQYXJlbnQ6IEdldFBhcmVudE9yZ0lkKTogUHJvbWlzZTxPcmdMaW5lYWdlPiB7XG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0PHN0cmluZz4oW29yZ0lkXSk7XG4gIGxldCBjdXJyZW50SWQgPSBvcmdJZDtcbiAgbGV0IHBhcmVudE9yZ0lkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgZm9yIChsZXQgZGVwdGggPSAwOyBkZXB0aCA8IE1BWF9PUkdfREVQVEg7IGRlcHRoKyspIHtcbiAgICBjb25zdCBwYXJlbnQgPSB0b09yZ0lkU3RyaW5nKGF3YWl0IGdldFBhcmVudChjdXJyZW50SWQpKTtcbiAgICBpZiAoIXBhcmVudCkgYnJlYWs7IC8vIGN1cnJlbnRJZCBpcyB0aGUgcm9vdFxuICAgIC8vIFJlY29yZCB0aGUgZGlyZWN0IHBhcmVudCBvbmx5IHdoZW4gaXQgaXNuJ3QgYSBzZWxmLWxvb3AsIHNvIGEgbWFsZm9ybWVkXG4gICAgLy8gQeKGkkEgb3JnIGlzbid0IHJlcG9ydGVkIGFzIGl0cyBvd24gcGFyZW50LlxuICAgIGlmIChkZXB0aCA9PT0gMCAmJiBwYXJlbnQgIT09IG9yZ0lkKSBwYXJlbnRPcmdJZCA9IHBhcmVudDtcbiAgICBpZiAoc2Vlbi5oYXMocGFyZW50KSkgYnJlYWs7IC8vIGN5Y2xlIOKAlCB0cmVhdCBjdXJyZW50SWQgYXMgdGhlIHJvb3RcbiAgICBzZWVuLmFkZChwYXJlbnQpO1xuICAgIGN1cnJlbnRJZCA9IHBhcmVudDtcbiAgfVxuXG4gIHJldHVybiB7IHJvb3RPcmdJZDogY3VycmVudElkLCAuLi4ocGFyZW50T3JnSWQgJiYgeyBwYXJlbnRPcmdJZCB9KSB9O1xufVxuXG4vKiogV2FsayBgcGFyZW50T3JnSWRgIHVwIHRvIHRoZSByb290IGFuZCByZXR1cm4ganVzdCB0aGUgcm9vdCBpZC4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXNvbHZlUm9vdE9yZ0lkV2l0aChvcmdJZDogc3RyaW5nLCBnZXRQYXJlbnQ6IEdldFBhcmVudE9yZ0lkKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgcmV0dXJuIChhd2FpdCByZXNvbHZlT3JnTGluZWFnZVdpdGgob3JnSWQsIGdldFBhcmVudCkpLnJvb3RPcmdJZDtcbn1cblxuLyoqXG4gKiBGYWlsLUNMT1NFRCB2YXJpYW50IG9mIHtAbGluayByZXNvbHZlUm9vdE9yZ0lkV2l0aH06IHJldHVybnMgYG51bGxgIHdoZW4gdGhlXG4gKiByb290IGNhbid0IGJlIHByb3ZlbiDigJQgYSBjeWNsZSBvciBhIGNoYWluIGRlZXBlciB0aGFuIHtAbGluayBNQVhfT1JHX0RFUFRIfSDigJRcbiAqIGluc3RlYWQgb2YgdHJlYXRpbmcgdGhlIGxhc3QgcmVhY2hlZCBpZCBhcyB0aGUgcm9vdC4gTG9va3VwIGVycm9ycyBwcm9wYWdhdGUuXG4gKiBGb3IgY2FsbGVycyB3aGVyZSBhIHdyb25nIHJvb3QgaXMgd29yc2UgdGhhbiBubyBhbnN3ZXIgKGUuZy4gYSByZXRlbnRpb24gcHVyZ2VcbiAqIHRoYXQgd291bGQgb3RoZXJ3aXNlIGFwcGx5IGEgdGVhbSdzIHNob3J0ZXIgZGVmYXVsdCB3aW5kb3cpLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVJvb3RPcmdJZFN0cmljdChvcmdJZDogc3RyaW5nLCBnZXRQYXJlbnQ6IEdldFBhcmVudE9yZ0lkKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPiB7XG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0PHN0cmluZz4oW29yZ0lkXSk7XG4gIGxldCBjdXJyZW50SWQgPSBvcmdJZDtcbiAgZm9yIChsZXQgZGVwdGggPSAwOyBkZXB0aCA8IE1BWF9PUkdfREVQVEg7IGRlcHRoKyspIHtcbiAgICBjb25zdCBwYXJlbnQgPSB0b09yZ0lkU3RyaW5nKGF3YWl0IGdldFBhcmVudChjdXJyZW50SWQpKTtcbiAgICBpZiAoIXBhcmVudCB8fCBwYXJlbnQgPT09IGN1cnJlbnRJZCkgcmV0dXJuIGN1cnJlbnRJZDtcbiAgICBpZiAoc2Vlbi5oYXMocGFyZW50KSkgcmV0dXJuIG51bGw7XG4gICAgc2Vlbi5hZGQocGFyZW50KTtcbiAgICBjdXJyZW50SWQgPSBwYXJlbnQ7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogVHJ1ZSB3aGVuIGBhbmNlc3Rvck9yZ0lkYCBpcyBhbiBhbmNlc3RvciBvZiBgY2FuZGlkYXRlT3JnSWRgIOKAlCBpLmUuXG4gKiBgY2FuZGlkYXRlT3JnSWRgIGxpdmVzIHNvbWV3aGVyZSBpbiB0aGUgc3VidHJlZSByb290ZWQgYXQgYGFuY2VzdG9yT3JnSWRgLlxuICogV2Fsa3MgYGNhbmRpZGF0ZU9yZ0lkYCdzIHBhcmVudCBjaGFpbiB1cHdhcmQsIGRlcHRoLWNhcHBlZCBhbmQgY3ljbGUtc2FmZS5cbiAqIFJldHVybnMgYGZhbHNlYCB3aGVuIHRoZSB0d28gYXJlIGVxdWFsIChhbiBvcmcgaXMgbm90IGl0cyBvd24gYW5jZXN0b3IpIG9yXG4gKiB1bnJlbGF0ZWQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpc0FuY2VzdG9yT3JnV2l0aChcbiAgYW5jZXN0b3JPcmdJZDogc3RyaW5nLFxuICBjYW5kaWRhdGVPcmdJZDogc3RyaW5nLFxuICBnZXRQYXJlbnQ6IEdldFBhcmVudE9yZ0lkLFxuKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGlmIChhbmNlc3Rvck9yZ0lkID09PSBjYW5kaWRhdGVPcmdJZCkgcmV0dXJuIGZhbHNlO1xuXG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0PHN0cmluZz4oW2NhbmRpZGF0ZU9yZ0lkXSk7XG4gIGxldCBjdXJyZW50SWQgPSBjYW5kaWRhdGVPcmdJZDtcblxuICBmb3IgKGxldCBkZXB0aCA9IDA7IGRlcHRoIDwgTUFYX09SR19ERVBUSDsgZGVwdGgrKykge1xuICAgIGNvbnN0IHBhcmVudCA9IHRvT3JnSWRTdHJpbmcoYXdhaXQgZ2V0UGFyZW50KGN1cnJlbnRJZCkpO1xuICAgIGlmICghcGFyZW50KSByZXR1cm4gZmFsc2U7IC8vIHJlYWNoZWQgYSByb290IHdpdGhvdXQgbWF0Y2hpbmdcbiAgICBpZiAocGFyZW50ID09PSBhbmNlc3Rvck9yZ0lkKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoc2Vlbi5oYXMocGFyZW50KSkgcmV0dXJuIGZhbHNlOyAvLyBjeWNsZVxuICAgIHNlZW4uYWRkKHBhcmVudCk7XG4gICAgY3VycmVudElkID0gcGFyZW50O1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIEV4cGFuZCBgb3JnSWRgIHRvIGl0c2VsZiBwbHVzIGV2ZXJ5IGRlc2NlbmRhbnQgb3JnIGlkIChicmVhZHRoLWZpcnN0IG92ZXJcbiAqIGBwYXJlbnRPcmdJZGApLiBUaGlzIGlzIHRoZSBzY29wZSBhIHBhcmVudCBvcmcgXCJzZWVzXCIgZm9yIHZpc2liaWxpdHkgYW5kXG4gKiBhbmFseXRpY3Mgcm9sbHVwczogYFtzZWxmLCAuLi5kZXNjZW5kYW50c11gLiBSZXR1cm5zIGBbb3JnSWRdYCB3aGVuIHRoZSBvcmdcbiAqIGhhcyBubyBjaGlsZHJlbi4gQ3ljbGUtc2FmZSBhbmQgZGVwdGgtY2FwcGVkLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZXhwYW5kT3JnU2NvcGVXaXRoKG9yZ0lkOiBzdHJpbmcsIGdldENoaWxkcmVuOiBHZXRDaGlsZE9yZ0lkcyk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgY29uc3QgcmVzdWx0OiBzdHJpbmdbXSA9IFtvcmdJZF07XG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0PHN0cmluZz4oW29yZ0lkXSk7XG4gIGxldCBmcm9udGllcjogc3RyaW5nW10gPSBbb3JnSWRdO1xuXG4gIGZvciAobGV0IGRlcHRoID0gMDsgZGVwdGggPCBNQVhfT1JHX0RFUFRIICYmIGZyb250aWVyLmxlbmd0aCA+IDA7IGRlcHRoKyspIHtcbiAgICBjb25zdCBjaGlsZHJlbiA9IGF3YWl0IGdldENoaWxkcmVuKGZyb250aWVyKTtcbiAgICBjb25zdCBuZXh0OiBzdHJpbmdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgcmF3IG9mIGNoaWxkcmVuKSB7XG4gICAgICBjb25zdCBpZCA9IHRvT3JnSWRTdHJpbmcocmF3KTtcbiAgICAgIGlmICghaWQgfHwgc2Vlbi5oYXMoaWQpKSBjb250aW51ZTtcbiAgICAgIHNlZW4uYWRkKGlkKTtcbiAgICAgIHJlc3VsdC5wdXNoKGlkKTtcbiAgICAgIG5leHQucHVzaChpZCk7XG4gICAgfVxuICAgIGZyb250aWVyID0gbmV4dDtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG4iXX0=
|
|
@@ -13,37 +13,57 @@ export interface RestorableService<T extends RestorableEntity> {
|
|
|
13
13
|
findDeletedById(id: string, orgId?: string): Promise<T | null>;
|
|
14
14
|
restore(id: string, orgId: string, userId: string): Promise<T | null>;
|
|
15
15
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Shared skeleton for a step-up-gated entity restore route: extract `:id`, load
|
|
18
|
-
* the own-org tombstone, gate it on the visibility ladder (parity with delete),
|
|
19
|
-
* restore, and 404 on miss. Returns `{ existing, restored }` on success,
|
|
20
|
-
* or `null` when it has ALREADY sent a response (400/404/403) — the caller then
|
|
21
|
-
* does the entity-specific audit + response. DRYs the near-identical
|
|
22
|
-
* pipeline / plugin / pipeline_template restore routes (which differ only in
|
|
23
|
-
* service, audit action, and response shaping).
|
|
24
|
-
*/
|
|
25
|
-
export declare function loadAndRestore<T extends RestorableEntity>(req: Request, res: Response, orgId: string, userId: string, service: RestorableService<T>, label: string, publishPermission: Permission): Promise<{
|
|
26
|
-
existing: T;
|
|
27
|
-
restored: T;
|
|
28
|
-
} | null>;
|
|
29
16
|
/** The slice of a service a purge route uses (satisfied by any CrudService). */
|
|
30
17
|
export interface PurgeableService<T extends RestorableEntity> {
|
|
31
18
|
findDeletedById(id: string, orgId?: string): Promise<T | null>;
|
|
32
19
|
purgeById(id: string, orgId?: string): Promise<string | null>;
|
|
33
20
|
}
|
|
34
21
|
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
22
|
+
* Decides whether the caller may restore/purge the loaded tombstone. Returns
|
|
23
|
+
* false after it has ANSWERED the request (403). Load-bearing: the tombstone
|
|
24
|
+
* load is org-scoped, not visibility-scoped, so this is what stops a colleague
|
|
25
|
+
* resurrecting (or destroying) someone else's draft.
|
|
26
|
+
*/
|
|
27
|
+
export type TombstoneAuthorizer<T> = (existing: T, req: Request, res: Response) => boolean;
|
|
28
|
+
export type TombstoneRouteOptions<T extends RestorableEntity> = {
|
|
29
|
+
orgId: string;
|
|
30
|
+
userId: string;
|
|
31
|
+
/** User-facing entity noun for the 400/404 messages ('Pipeline', 'Rule', …). */
|
|
32
|
+
label: string;
|
|
33
|
+
/**
|
|
34
|
+
* The org the tombstone load and the mutation are pinned to. Defaults to
|
|
35
|
+
* `orgId`; `undefined` spans orgs (system-admin moderation).
|
|
36
|
+
*/
|
|
37
|
+
scopeOrgId?: string | undefined;
|
|
38
|
+
} & (
|
|
39
|
+
/** Same authority as delete on the visibility ladder: `publishPermission`
|
|
40
|
+
* for a public row, authorship for a private one. */
|
|
41
|
+
{
|
|
42
|
+
publishPermission: Permission;
|
|
43
|
+
authorize?: undefined;
|
|
44
|
+
} | {
|
|
45
|
+
authorize: TombstoneAuthorizer<T>;
|
|
46
|
+
publishPermission?: undefined;
|
|
47
|
+
});
|
|
48
|
+
/**
|
|
49
|
+
* Shared skeleton for a step-up-gated entity RESTORE route: extract `:id`, load
|
|
50
|
+
* the tombstone, authorize it, restore, and 404 on miss. Returns
|
|
51
|
+
* `{ existing, restored }` on success, or `null` when it has ALREADY sent a
|
|
52
|
+
* response (400/404/403) — the caller then does the entity-specific audit +
|
|
53
|
+
* response. Step-up is the route's job.
|
|
54
|
+
*/
|
|
55
|
+
export declare function loadAndRestore<T extends RestorableEntity>(req: Request, res: Response, service: RestorableService<T>, opts: TombstoneRouteOptions<T>): Promise<{
|
|
56
|
+
existing: T;
|
|
57
|
+
restored: T;
|
|
58
|
+
} | null>;
|
|
59
|
+
/**
|
|
60
|
+
* Shared skeleton for an entity PURGE route: the same load + authorization as
|
|
61
|
+
* restore, then a permanent hard-delete via the retention sweep's single-id
|
|
62
|
+
* purge (same tombstone match + dependent-teardown hooks). Returns
|
|
63
|
+
* `{ existing, purgedId }` (the caller audits off `existing`), or `null` when it
|
|
64
|
+
* has ALREADY sent a response. Step-up is the route's job.
|
|
45
65
|
*/
|
|
46
|
-
export declare function loadAndPurge<T extends RestorableEntity>(req: Request, res: Response,
|
|
66
|
+
export declare function loadAndPurge<T extends RestorableEntity>(req: Request, res: Response, service: PurgeableService<T>, opts: TombstoneRouteOptions<T>): Promise<{
|
|
47
67
|
existing: T;
|
|
48
68
|
purgedId: string;
|
|
49
69
|
} | null>;
|
|
@@ -5,74 +5,63 @@ import { sendEntityNotFound } from './crud-helpers.js';
|
|
|
5
5
|
import { ErrorCode } from '../types/error-codes.js';
|
|
6
6
|
import { getParam } from '../utils/params.js';
|
|
7
7
|
import { sendBadRequest } from '../utils/response.js';
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
-
* the own-org tombstone, gate it on the visibility ladder (parity with delete),
|
|
11
|
-
* restore, and 404 on miss. Returns `{ existing, restored }` on success,
|
|
12
|
-
* or `null` when it has ALREADY sent a response (400/404/403) — the caller then
|
|
13
|
-
* does the entity-specific audit + response. DRYs the near-identical
|
|
14
|
-
* pipeline / plugin / pipeline_template restore routes (which differ only in
|
|
15
|
-
* service, audit action, and response shaping).
|
|
16
|
-
*/
|
|
17
|
-
export async function loadAndRestore(req, res, orgId, userId, service, label, publishPermission) {
|
|
8
|
+
/** Shared prelude: `:id` → own-scope tombstone → authorization. `null` = answered. */
|
|
9
|
+
async function loadTombstone(req, res, service, opts) {
|
|
18
10
|
const id = getParam(req.params, 'id');
|
|
19
11
|
if (!id) {
|
|
20
|
-
sendBadRequest(res, `${label} ID is required.`, ErrorCode.MISSING_REQUIRED_FIELD);
|
|
12
|
+
sendBadRequest(res, `${opts.label} ID is required.`, ErrorCode.MISSING_REQUIRED_FIELD);
|
|
21
13
|
return null;
|
|
22
14
|
}
|
|
23
|
-
|
|
24
|
-
|
|
15
|
+
const scope = 'scopeOrgId' in opts ? opts.scopeOrgId : opts.orgId;
|
|
16
|
+
// A live row / unknown id / already-purged → 404, so a currently-active entity
|
|
17
|
+
// is never restored or hard-deleted through these paths.
|
|
18
|
+
const existing = await service.findDeletedById(id, scope);
|
|
25
19
|
if (!existing) {
|
|
26
|
-
sendEntityNotFound(res, label);
|
|
20
|
+
sendEntityNotFound(res, opts.label);
|
|
27
21
|
return null;
|
|
28
22
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (!
|
|
33
|
-
return null;
|
|
34
|
-
const restored = await service.restore(id, orgId, userId || 'system');
|
|
35
|
-
if (!restored) {
|
|
36
|
-
sendEntityNotFound(res, label);
|
|
23
|
+
const allowed = opts.authorize
|
|
24
|
+
? opts.authorize(existing, req, res)
|
|
25
|
+
: requireVisibilityWriteAccess(req, res, existing, opts.userId, opts.publishPermission);
|
|
26
|
+
if (!allowed)
|
|
37
27
|
return null;
|
|
38
|
-
}
|
|
39
|
-
return { existing, restored };
|
|
28
|
+
return { id, existing, scope };
|
|
40
29
|
}
|
|
41
30
|
/**
|
|
42
|
-
* Shared skeleton for
|
|
43
|
-
* tombstone,
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* (the caller emits the entity-specific audit off `existing`), or `null` when it
|
|
48
|
-
* has ALREADY sent a response (400/404/403). Step-up is the ROUTE's job: the
|
|
49
|
-
* pipeline, template and plugin services mount purge behind `requireStepUp`
|
|
50
|
-
* (sharing restore's chain so one token isn't consumed twice). DRYs the near-identical
|
|
51
|
-
* pipeline / pipeline_template purge routes.
|
|
31
|
+
* Shared skeleton for a step-up-gated entity RESTORE route: extract `:id`, load
|
|
32
|
+
* the tombstone, authorize it, restore, and 404 on miss. Returns
|
|
33
|
+
* `{ existing, restored }` on success, or `null` when it has ALREADY sent a
|
|
34
|
+
* response (400/404/403) — the caller then does the entity-specific audit +
|
|
35
|
+
* response. Step-up is the route's job.
|
|
52
36
|
*/
|
|
53
|
-
export async function
|
|
54
|
-
const
|
|
55
|
-
if (!
|
|
56
|
-
sendBadRequest(res, `${label} ID is required.`, ErrorCode.MISSING_REQUIRED_FIELD);
|
|
37
|
+
export async function loadAndRestore(req, res, service, opts) {
|
|
38
|
+
const loaded = await loadTombstone(req, res, service, opts);
|
|
39
|
+
if (!loaded)
|
|
57
40
|
return null;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const existing = await service.findDeletedById(id, orgId);
|
|
62
|
-
if (!existing) {
|
|
63
|
-
sendEntityNotFound(res, label);
|
|
41
|
+
const restored = await service.restore(loaded.id, loaded.scope ?? '', opts.userId);
|
|
42
|
+
if (!restored) {
|
|
43
|
+
sendEntityNotFound(res, opts.label);
|
|
64
44
|
return null;
|
|
65
45
|
}
|
|
66
|
-
|
|
67
|
-
|
|
46
|
+
return { existing: loaded.existing, restored };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Shared skeleton for an entity PURGE route: the same load + authorization as
|
|
50
|
+
* restore, then a permanent hard-delete via the retention sweep's single-id
|
|
51
|
+
* purge (same tombstone match + dependent-teardown hooks). Returns
|
|
52
|
+
* `{ existing, purgedId }` (the caller audits off `existing`), or `null` when it
|
|
53
|
+
* has ALREADY sent a response. Step-up is the route's job.
|
|
54
|
+
*/
|
|
55
|
+
export async function loadAndPurge(req, res, service, opts) {
|
|
56
|
+
const loaded = await loadTombstone(req, res, service, opts);
|
|
57
|
+
if (!loaded)
|
|
68
58
|
return null;
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
const purgedId = await service.purgeById(id, orgId);
|
|
59
|
+
// Null on a race (already purged) → 404.
|
|
60
|
+
const purgedId = await service.purgeById(loaded.id, loaded.scope ?? '');
|
|
72
61
|
if (!purgedId) {
|
|
73
|
-
sendEntityNotFound(res, label);
|
|
62
|
+
sendEntityNotFound(res, opts.label);
|
|
74
63
|
return null;
|
|
75
64
|
}
|
|
76
|
-
return { existing, purgedId };
|
|
65
|
+
return { existing: loaded.existing, purgedId };
|
|
77
66
|
}
|
|
78
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdG9yZS1oZWxwZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hlbHBlcnMvcmVzdG9yZS1oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFHdEMsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDbkUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXBELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFpQnREOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxjQUFjLENBQ2xDLEdBQVksRUFDWixHQUFhLEVBQ2IsS0FBYSxFQUNiLE1BQWMsRUFDZCxPQUE2QixFQUM3QixLQUFhLEVBQ2IsaUJBQTZCO0lBRTdCLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3RDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUNSLGNBQWMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxLQUFLLGtCQUFrQixFQUFFLFNBQVMsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ2xGLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELGdGQUFnRjtJQUNoRixNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxlQUFlLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzFELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNkLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCwrRUFBK0U7SUFDL0UsMkVBQTJFO0lBQzNFLDZFQUE2RTtJQUM3RSxJQUFJLENBQUMsNEJBQTRCLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsTUFBTSxJQUFJLEVBQUUsRUFBRSxpQkFBaUIsQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBRXBHLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sSUFBSSxRQUFRLENBQUMsQ0FBQztJQUN0RSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDZCxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDL0IsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsQ0FBQztBQUNoQyxDQUFDO0FBUUQ7Ozs7Ozs7Ozs7O0dBV0c7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFlBQVksQ0FDaEMsR0FBWSxFQUNaLEdBQWEsRUFDYixLQUFhLEVBQ2IsT0FBNEIsRUFDNUIsS0FBYSxFQUNiLGlCQUE2QixFQUM3QixNQUFjO0lBRWQsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDdEMsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ1IsY0FBYyxDQUFDLEdBQUcsRUFBRSxHQUFHLEtBQUssa0JBQWtCLEVBQUUsU0FBUyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFDbEYsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsZ0ZBQWdGO0lBQ2hGLHdFQUF3RTtJQUN4RSxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxlQUFlLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzFELElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNkLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxnRUFBZ0U7SUFDaEUsSUFBSSxDQUFDLDRCQUE0QixDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLE1BQU0sSUFBSSxFQUFFLEVBQUUsaUJBQWlCLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUVwRyw0RUFBNEU7SUFDNUUsNEVBQTRFO0lBQzVFLE1BQU0sUUFBUSxHQUFHLE1BQU0sT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDcEQsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2Qsa0JBQWtCLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQy9CLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLENBQUM7QUFDaEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgdHlwZSB7IFJlcXVlc3QsIFJlc3BvbnNlIH0gZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyByZXF1aXJlVmlzaWJpbGl0eVdyaXRlQWNjZXNzIH0gZnJvbSAnLi9hY2Nlc3MtaGVscGVycy5qcyc7XG5pbXBvcnQgeyBzZW5kRW50aXR5Tm90Rm91bmQgfSBmcm9tICcuL2NydWQtaGVscGVycy5qcyc7XG5pbXBvcnQgeyBFcnJvckNvZGUgfSBmcm9tICcuLi90eXBlcy9lcnJvci1jb2Rlcy5qcyc7XG5pbXBvcnQgdHlwZSB7IFBlcm1pc3Npb24gfSBmcm9tICcuLi90eXBlcy9wZXJtaXNzaW9ucy5qcyc7XG5pbXBvcnQgeyBnZXRQYXJhbSB9IGZyb20gJy4uL3V0aWxzL3BhcmFtcy5qcyc7XG5pbXBvcnQgeyBzZW5kQmFkUmVxdWVzdCB9IGZyb20gJy4uL3V0aWxzL3Jlc3BvbnNlLmpzJztcblxuLyoqIE1pbmltYWwgc2hhcGUgYSByZXN0b3JlIHJvdXRlIG5lZWRzIGZyb20gdGhlIGVudGl0eSBpdCByZXN0b3Jlcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzdG9yYWJsZUVudGl0eSB7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIC8qKiBSdW5nIHRoZSB0b21ic3RvbmUgc2F0IGF0IOKAlCBkcml2ZXMgdGhlIHJlc3RvcmUvcHVyZ2UgYXV0aG9yaXR5IGNoZWNrLiAqL1xuICB2aXNpYmlsaXR5Pzogc3RyaW5nO1xuICAvKiogQXV0aG9yIOKAlCB0aGUgb25seSBub24tYWRtaW4gd2hvIG1heSByZXN0b3JlL3B1cmdlIGEgYHByaXZhdGVgIHJvdy4gKi9cbiAgY3JlYXRlZEJ5Pzogc3RyaW5nO1xufVxuXG4vKiogVGhlIHNsaWNlIG9mIGEgc2VydmljZSBhIHJlc3RvcmUgcm91dGUgdXNlcyAoc2F0aXNmaWVkIGJ5IGFueSBDcnVkU2VydmljZSkuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc3RvcmFibGVTZXJ2aWNlPFQgZXh0ZW5kcyBSZXN0b3JhYmxlRW50aXR5PiB7XG4gIGZpbmREZWxldGVkQnlJZChpZDogc3RyaW5nLCBvcmdJZD86IHN0cmluZyk6IFByb21pc2U8VCB8IG51bGw+O1xuICByZXN0b3JlKGlkOiBzdHJpbmcsIG9yZ0lkOiBzdHJpbmcsIHVzZXJJZDogc3RyaW5nKTogUHJvbWlzZTxUIHwgbnVsbD47XG59XG5cbi8qKlxuICogU2hhcmVkIHNrZWxldG9uIGZvciBhIHN0ZXAtdXAtZ2F0ZWQgZW50aXR5IHJlc3RvcmUgcm91dGU6IGV4dHJhY3QgYDppZGAsIGxvYWRcbiAqIHRoZSBvd24tb3JnIHRvbWJzdG9uZSwgZ2F0ZSBpdCBvbiB0aGUgdmlzaWJpbGl0eSBsYWRkZXIgKHBhcml0eSB3aXRoIGRlbGV0ZSksXG4gKiByZXN0b3JlLCBhbmQgNDA0IG9uIG1pc3MuIFJldHVybnMgYHsgZXhpc3RpbmcsIHJlc3RvcmVkIH1gIG9uIHN1Y2Nlc3MsXG4gKiBvciBgbnVsbGAgd2hlbiBpdCBoYXMgQUxSRUFEWSBzZW50IGEgcmVzcG9uc2UgKDQwMC80MDQvNDAzKSDigJQgdGhlIGNhbGxlciB0aGVuXG4gKiBkb2VzIHRoZSBlbnRpdHktc3BlY2lmaWMgYXVkaXQgKyByZXNwb25zZS4gRFJZcyB0aGUgbmVhci1pZGVudGljYWxcbiAqIHBpcGVsaW5lIC8gcGx1Z2luIC8gcGlwZWxpbmVfdGVtcGxhdGUgcmVzdG9yZSByb3V0ZXMgKHdoaWNoIGRpZmZlciBvbmx5IGluXG4gKiBzZXJ2aWNlLCBhdWRpdCBhY3Rpb24sIGFuZCByZXNwb25zZSBzaGFwaW5nKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWRBbmRSZXN0b3JlPFQgZXh0ZW5kcyBSZXN0b3JhYmxlRW50aXR5PihcbiAgcmVxOiBSZXF1ZXN0LFxuICByZXM6IFJlc3BvbnNlLFxuICBvcmdJZDogc3RyaW5nLFxuICB1c2VySWQ6IHN0cmluZyxcbiAgc2VydmljZTogUmVzdG9yYWJsZVNlcnZpY2U8VD4sXG4gIGxhYmVsOiBzdHJpbmcsXG4gIHB1Ymxpc2hQZXJtaXNzaW9uOiBQZXJtaXNzaW9uLFxuKTogUHJvbWlzZTx7IGV4aXN0aW5nOiBUOyByZXN0b3JlZDogVCB9IHwgbnVsbD4ge1xuICBjb25zdCBpZCA9IGdldFBhcmFtKHJlcS5wYXJhbXMsICdpZCcpO1xuICBpZiAoIWlkKSB7XG4gICAgc2VuZEJhZFJlcXVlc3QocmVzLCBgJHtsYWJlbH0gSUQgaXMgcmVxdWlyZWQuYCwgRXJyb3JDb2RlLk1JU1NJTkdfUkVRVUlSRURfRklFTEQpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gTG9hZCB0aGUgVE9NQlNUT05FIChvd24tb3JnKS4gQSBsaXZlIHJvdyAvIHVua25vd24gaWQgLyBhbHJlYWR5LXB1cmdlZCDihpIgNDA0LlxuICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHNlcnZpY2UuZmluZERlbGV0ZWRCeUlkKGlkLCBvcmdJZCk7XG4gIGlmICghZXhpc3RpbmcpIHtcbiAgICBzZW5kRW50aXR5Tm90Rm91bmQocmVzLCBsYWJlbCk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBTYW1lIGxhZGRlciBhdXRob3JpdHkgYXMgZGVsZXRlOiBgOnB1Ymxpc2hgIGZvciBhIHB1YmxpYyByb3csIGF1dGhvcnNoaXAgZm9yXG4gIC8vIGEgcHJpdmF0ZSBvbmUuIExvYWQtYmVhcmluZyBoZXJlIOKAlCB0aGUgdG9tYnN0b25lIGxvYWQgaXMgb3JnLXNjb3BlZCwgbm90XG4gIC8vIHZpc2liaWxpdHktc2NvcGVkLCBzbyB0aGlzIGlzIHdoYXQgc3RvcHMgYSBjb2xsZWFndWUgcmVzdXJyZWN0aW5nIGEgZHJhZnQuXG4gIGlmICghcmVxdWlyZVZpc2liaWxpdHlXcml0ZUFjY2VzcyhyZXEsIHJlcywgZXhpc3RpbmcsIHVzZXJJZCB8fCAnJywgcHVibGlzaFBlcm1pc3Npb24pKSByZXR1cm4gbnVsbDtcblxuICBjb25zdCByZXN0b3JlZCA9IGF3YWl0IHNlcnZpY2UucmVzdG9yZShpZCwgb3JnSWQsIHVzZXJJZCB8fCAnc3lzdGVtJyk7XG4gIGlmICghcmVzdG9yZWQpIHtcbiAgICBzZW5kRW50aXR5Tm90Rm91bmQocmVzLCBsYWJlbCk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4geyBleGlzdGluZywgcmVzdG9yZWQgfTtcbn1cblxuLyoqIFRoZSBzbGljZSBvZiBhIHNlcnZpY2UgYSBwdXJnZSByb3V0ZSB1c2VzIChzYXRpc2ZpZWQgYnkgYW55IENydWRTZXJ2aWNlKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHVyZ2VhYmxlU2VydmljZTxUIGV4dGVuZHMgUmVzdG9yYWJsZUVudGl0eT4ge1xuICBmaW5kRGVsZXRlZEJ5SWQoaWQ6IHN0cmluZywgb3JnSWQ/OiBzdHJpbmcpOiBQcm9taXNlPFQgfCBudWxsPjtcbiAgcHVyZ2VCeUlkKGlkOiBzdHJpbmcsIG9yZ0lkPzogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCBudWxsPjtcbn1cblxuLyoqXG4gKiBTaGFyZWQgc2tlbGV0b24gZm9yIGFuIGVudGl0eSBQVVJHRSByb3V0ZTogZXh0cmFjdCBgOmlkYCwgbG9hZCB0aGUgb3duLW9yZ1xuICogdG9tYnN0b25lLCBnYXRlIGl0IG9uIHRoZSB2aXNpYmlsaXR5IGxhZGRlciAocGFyaXR5IHdpdGhcbiAqIGRlbGV0ZS9yZXN0b3JlKSwgdGhlbiBwZXJtYW5lbnRseSBoYXJkLWRlbGV0ZSBpdCDigJQgYnV0IE9OTFkgd2hlbiBpdCBpcyBhXG4gKiBnZW51aW5lIHRvbWJzdG9uZSAoYSBsaXZlL2FjdGl2ZSByb3cgbG9hZHMgYXMgYG51bGxgIGhlcmUgYW5kIDQwNHMsIHNvIHB1cmdlXG4gKiBjYW4gbmV2ZXIgaGFyZC1kZWxldGUgYSBsaXZlIHJvdykuIFJldHVybnMgYHsgZXhpc3RpbmcsIHB1cmdlZElkIH1gIG9uIHN1Y2Nlc3NcbiAqICh0aGUgY2FsbGVyIGVtaXRzIHRoZSBlbnRpdHktc3BlY2lmaWMgYXVkaXQgb2ZmIGBleGlzdGluZ2ApLCBvciBgbnVsbGAgd2hlbiBpdFxuICogaGFzIEFMUkVBRFkgc2VudCBhIHJlc3BvbnNlICg0MDAvNDA0LzQwMykuIFN0ZXAtdXAgaXMgdGhlIFJPVVRFJ3Mgam9iOiB0aGVcbiAqIHBpcGVsaW5lLCB0ZW1wbGF0ZSBhbmQgcGx1Z2luIHNlcnZpY2VzIG1vdW50IHB1cmdlIGJlaGluZCBgcmVxdWlyZVN0ZXBVcGBcbiAqIChzaGFyaW5nIHJlc3RvcmUncyBjaGFpbiBzbyBvbmUgdG9rZW4gaXNuJ3QgY29uc3VtZWQgdHdpY2UpLiBEUllzIHRoZSBuZWFyLWlkZW50aWNhbFxuICogcGlwZWxpbmUgLyBwaXBlbGluZV90ZW1wbGF0ZSBwdXJnZSByb3V0ZXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2FkQW5kUHVyZ2U8VCBleHRlbmRzIFJlc3RvcmFibGVFbnRpdHk+KFxuICByZXE6IFJlcXVlc3QsXG4gIHJlczogUmVzcG9uc2UsXG4gIG9yZ0lkOiBzdHJpbmcsXG4gIHNlcnZpY2U6IFB1cmdlYWJsZVNlcnZpY2U8VD4sXG4gIGxhYmVsOiBzdHJpbmcsXG4gIHB1Ymxpc2hQZXJtaXNzaW9uOiBQZXJtaXNzaW9uLFxuICB1c2VySWQ6IHN0cmluZyxcbik6IFByb21pc2U8eyBleGlzdGluZzogVDsgcHVyZ2VkSWQ6IHN0cmluZyB9IHwgbnVsbD4ge1xuICBjb25zdCBpZCA9IGdldFBhcmFtKHJlcS5wYXJhbXMsICdpZCcpO1xuICBpZiAoIWlkKSB7XG4gICAgc2VuZEJhZFJlcXVlc3QocmVzLCBgJHtsYWJlbH0gSUQgaXMgcmVxdWlyZWQuYCwgRXJyb3JDb2RlLk1JU1NJTkdfUkVRVUlSRURfRklFTEQpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gTG9hZCB0aGUgVE9NQlNUT05FIChvd24tb3JnKS4gQSBsaXZlIHJvdyAvIHVua25vd24gaWQgLyBhbHJlYWR5LXB1cmdlZCDihpIgNDA0LFxuICAvLyBzbyBhIGN1cnJlbnRseS1hY3RpdmUgZW50aXR5IGlzIG5ldmVyIGhhcmQtZGVsZXRlZCB0aHJvdWdoIHRoaXMgcGF0aC5cbiAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBzZXJ2aWNlLmZpbmREZWxldGVkQnlJZChpZCwgb3JnSWQpO1xuICBpZiAoIWV4aXN0aW5nKSB7XG4gICAgc2VuZEVudGl0eU5vdEZvdW5kKHJlcywgbGFiZWwpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gU2FtZSBsYWRkZXIgYXV0aG9yaXR5IGFzIGRlbGV0ZS9yZXN0b3JlIChzZWUgbG9hZEFuZFJlc3RvcmUpLlxuICBpZiAoIXJlcXVpcmVWaXNpYmlsaXR5V3JpdGVBY2Nlc3MocmVxLCByZXMsIGV4aXN0aW5nLCB1c2VySWQgfHwgJycsIHB1Ymxpc2hQZXJtaXNzaW9uKSkgcmV0dXJuIG51bGw7XG5cbiAgLy8gUmV1c2UgdGhlIHJldGVudGlvbiBzd2VlcCdzIHNpbmdsZS1pZCBoYXJkLWRlbGV0ZSAoc2FtZSB0b21ic3RvbmUgbWF0Y2ggK1xuICAvLyBkZXBlbmRlbnQtdGVhcmRvd24gaG9va3MpLiBSZXR1cm5zIG51bGwgb24gYSByYWNlIChhbHJlYWR5IHB1cmdlZCkg4oaSIDQwNC5cbiAgY29uc3QgcHVyZ2VkSWQgPSBhd2FpdCBzZXJ2aWNlLnB1cmdlQnlJZChpZCwgb3JnSWQpO1xuICBpZiAoIXB1cmdlZElkKSB7XG4gICAgc2VuZEVudGl0eU5vdEZvdW5kKHJlcywgbGFiZWwpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHsgZXhpc3RpbmcsIHB1cmdlZElkIH07XG59XG4iXX0=
|
|
67
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdG9yZS1oZWxwZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hlbHBlcnMvcmVzdG9yZS1oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFHdEMsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDbkUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXBELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFnRHRELHNGQUFzRjtBQUN0RixLQUFLLFVBQVUsYUFBYSxDQUMxQixHQUFZLEVBQ1osR0FBYSxFQUNiLE9BQTJFLEVBQzNFLElBQThCO0lBRTlCLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3RDLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUNSLGNBQWMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxrQkFBa0IsRUFBRSxTQUFTLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUN2RixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFDRCxNQUFNLEtBQUssR0FBRyxZQUFZLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBRWxFLCtFQUErRTtJQUMvRSx5REFBeUQ7SUFDekQsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsZUFBZSxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUMxRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDZCxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxTQUFTO1FBQzVCLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDO1FBQ3BDLENBQUMsQ0FBQyw0QkFBNEIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQzFGLElBQUksQ0FBQyxPQUFPO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDMUIsT0FBTyxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUM7QUFDakMsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsY0FBYyxDQUNsQyxHQUFZLEVBQ1osR0FBYSxFQUNiLE9BQTZCLEVBQzdCLElBQThCO0lBRTlCLE1BQU0sTUFBTSxHQUFHLE1BQU0sYUFBYSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzVELElBQUksQ0FBQyxNQUFNO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFFekIsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLEtBQUssSUFBSSxFQUFFLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ25GLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNkLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDcEMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQ0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxDQUFDO0FBQ2pELENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFlBQVksQ0FDaEMsR0FBWSxFQUNaLEdBQWEsRUFDYixPQUE0QixFQUM1QixJQUE4QjtJQUU5QixNQUFNLE1BQU0sR0FBRyxNQUFNLGFBQWEsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM1RCxJQUFJLENBQUMsTUFBTTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBRXpCLHlDQUF5QztJQUN6QyxNQUFNLFFBQVEsR0FBRyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ3hFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUNkLGtCQUFrQixDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDcEMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQ0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxDQUFDO0FBQ2pELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHR5cGUgeyBSZXF1ZXN0LCBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgcmVxdWlyZVZpc2liaWxpdHlXcml0ZUFjY2VzcyB9IGZyb20gJy4vYWNjZXNzLWhlbHBlcnMuanMnO1xuaW1wb3J0IHsgc2VuZEVudGl0eU5vdEZvdW5kIH0gZnJvbSAnLi9jcnVkLWhlbHBlcnMuanMnO1xuaW1wb3J0IHsgRXJyb3JDb2RlIH0gZnJvbSAnLi4vdHlwZXMvZXJyb3ItY29kZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBQZXJtaXNzaW9uIH0gZnJvbSAnLi4vdHlwZXMvcGVybWlzc2lvbnMuanMnO1xuaW1wb3J0IHsgZ2V0UGFyYW0gfSBmcm9tICcuLi91dGlscy9wYXJhbXMuanMnO1xuaW1wb3J0IHsgc2VuZEJhZFJlcXVlc3QgfSBmcm9tICcuLi91dGlscy9yZXNwb25zZS5qcyc7XG5cbi8qKiBNaW5pbWFsIHNoYXBlIGEgcmVzdG9yZSByb3V0ZSBuZWVkcyBmcm9tIHRoZSBlbnRpdHkgaXQgcmVzdG9yZXMuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc3RvcmFibGVFbnRpdHkge1xuICBvcmdJZDogc3RyaW5nO1xuICAvKiogUnVuZyB0aGUgdG9tYnN0b25lIHNhdCBhdCDigJQgZHJpdmVzIHRoZSByZXN0b3JlL3B1cmdlIGF1dGhvcml0eSBjaGVjay4gKi9cbiAgdmlzaWJpbGl0eT86IHN0cmluZztcbiAgLyoqIEF1dGhvciDigJQgdGhlIG9ubHkgbm9uLWFkbWluIHdobyBtYXkgcmVzdG9yZS9wdXJnZSBhIGBwcml2YXRlYCByb3cuICovXG4gIGNyZWF0ZWRCeT86IHN0cmluZztcbn1cblxuLyoqIFRoZSBzbGljZSBvZiBhIHNlcnZpY2UgYSByZXN0b3JlIHJvdXRlIHVzZXMgKHNhdGlzZmllZCBieSBhbnkgQ3J1ZFNlcnZpY2UpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXN0b3JhYmxlU2VydmljZTxUIGV4dGVuZHMgUmVzdG9yYWJsZUVudGl0eT4ge1xuICBmaW5kRGVsZXRlZEJ5SWQoaWQ6IHN0cmluZywgb3JnSWQ/OiBzdHJpbmcpOiBQcm9taXNlPFQgfCBudWxsPjtcbiAgcmVzdG9yZShpZDogc3RyaW5nLCBvcmdJZDogc3RyaW5nLCB1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8VCB8IG51bGw+O1xufVxuXG4vKiogVGhlIHNsaWNlIG9mIGEgc2VydmljZSBhIHB1cmdlIHJvdXRlIHVzZXMgKHNhdGlzZmllZCBieSBhbnkgQ3J1ZFNlcnZpY2UpLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQdXJnZWFibGVTZXJ2aWNlPFQgZXh0ZW5kcyBSZXN0b3JhYmxlRW50aXR5PiB7XG4gIGZpbmREZWxldGVkQnlJZChpZDogc3RyaW5nLCBvcmdJZD86IHN0cmluZyk6IFByb21pc2U8VCB8IG51bGw+O1xuICBwdXJnZUJ5SWQoaWQ6IHN0cmluZywgb3JnSWQ/OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IG51bGw+O1xufVxuXG4vKipcbiAqIERlY2lkZXMgd2hldGhlciB0aGUgY2FsbGVyIG1heSByZXN0b3JlL3B1cmdlIHRoZSBsb2FkZWQgdG9tYnN0b25lLiBSZXR1cm5zXG4gKiBmYWxzZSBhZnRlciBpdCBoYXMgQU5TV0VSRUQgdGhlIHJlcXVlc3QgKDQwMykuIExvYWQtYmVhcmluZzogdGhlIHRvbWJzdG9uZVxuICogbG9hZCBpcyBvcmctc2NvcGVkLCBub3QgdmlzaWJpbGl0eS1zY29wZWQsIHNvIHRoaXMgaXMgd2hhdCBzdG9wcyBhIGNvbGxlYWd1ZVxuICogcmVzdXJyZWN0aW5nIChvciBkZXN0cm95aW5nKSBzb21lb25lIGVsc2UncyBkcmFmdC5cbiAqL1xuZXhwb3J0IHR5cGUgVG9tYnN0b25lQXV0aG9yaXplcjxUPiA9IChleGlzdGluZzogVCwgcmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSA9PiBib29sZWFuO1xuXG5leHBvcnQgdHlwZSBUb21ic3RvbmVSb3V0ZU9wdGlvbnM8VCBleHRlbmRzIFJlc3RvcmFibGVFbnRpdHk+ID0ge1xuICBvcmdJZDogc3RyaW5nO1xuICB1c2VySWQ6IHN0cmluZztcbiAgLyoqIFVzZXItZmFjaW5nIGVudGl0eSBub3VuIGZvciB0aGUgNDAwLzQwNCBtZXNzYWdlcyAoJ1BpcGVsaW5lJywgJ1J1bGUnLCDigKYpLiAqL1xuICBsYWJlbDogc3RyaW5nO1xuICAvKipcbiAgICogVGhlIG9yZyB0aGUgdG9tYnN0b25lIGxvYWQgYW5kIHRoZSBtdXRhdGlvbiBhcmUgcGlubmVkIHRvLiBEZWZhdWx0cyB0b1xuICAgKiBgb3JnSWRgOyBgdW5kZWZpbmVkYCBzcGFucyBvcmdzIChzeXN0ZW0tYWRtaW4gbW9kZXJhdGlvbikuXG4gICAqL1xuICBzY29wZU9yZ0lkPzogc3RyaW5nIHwgdW5kZWZpbmVkO1xufSAmIChcbiAgLyoqIFNhbWUgYXV0aG9yaXR5IGFzIGRlbGV0ZSBvbiB0aGUgdmlzaWJpbGl0eSBsYWRkZXI6IGBwdWJsaXNoUGVybWlzc2lvbmBcbiAgICogIGZvciBhIHB1YmxpYyByb3csIGF1dGhvcnNoaXAgZm9yIGEgcHJpdmF0ZSBvbmUuICovXG4gIHwgeyBwdWJsaXNoUGVybWlzc2lvbjogUGVybWlzc2lvbjsgYXV0aG9yaXplPzogdW5kZWZpbmVkIH1cbiAgfCB7IGF1dGhvcml6ZTogVG9tYnN0b25lQXV0aG9yaXplcjxUPjsgcHVibGlzaFBlcm1pc3Npb24/OiB1bmRlZmluZWQgfVxuKTtcblxuLyoqIFNoYXJlZCBwcmVsdWRlOiBgOmlkYCDihpIgb3duLXNjb3BlIHRvbWJzdG9uZSDihpIgYXV0aG9yaXphdGlvbi4gYG51bGxgID0gYW5zd2VyZWQuICovXG5hc3luYyBmdW5jdGlvbiBsb2FkVG9tYnN0b25lPFQgZXh0ZW5kcyBSZXN0b3JhYmxlRW50aXR5PihcbiAgcmVxOiBSZXF1ZXN0LFxuICByZXM6IFJlc3BvbnNlLFxuICBzZXJ2aWNlOiB7IGZpbmREZWxldGVkQnlJZChpZDogc3RyaW5nLCBvcmdJZD86IHN0cmluZyk6IFByb21pc2U8VCB8IG51bGw+IH0sXG4gIG9wdHM6IFRvbWJzdG9uZVJvdXRlT3B0aW9uczxUPixcbik6IFByb21pc2U8eyBpZDogc3RyaW5nOyBleGlzdGluZzogVDsgc2NvcGU6IHN0cmluZyB8IHVuZGVmaW5lZCB9IHwgbnVsbD4ge1xuICBjb25zdCBpZCA9IGdldFBhcmFtKHJlcS5wYXJhbXMsICdpZCcpO1xuICBpZiAoIWlkKSB7XG4gICAgc2VuZEJhZFJlcXVlc3QocmVzLCBgJHtvcHRzLmxhYmVsfSBJRCBpcyByZXF1aXJlZC5gLCBFcnJvckNvZGUuTUlTU0lOR19SRVFVSVJFRF9GSUVMRCk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgY29uc3Qgc2NvcGUgPSAnc2NvcGVPcmdJZCcgaW4gb3B0cyA/IG9wdHMuc2NvcGVPcmdJZCA6IG9wdHMub3JnSWQ7XG5cbiAgLy8gQSBsaXZlIHJvdyAvIHVua25vd24gaWQgLyBhbHJlYWR5LXB1cmdlZCDihpIgNDA0LCBzbyBhIGN1cnJlbnRseS1hY3RpdmUgZW50aXR5XG4gIC8vIGlzIG5ldmVyIHJlc3RvcmVkIG9yIGhhcmQtZGVsZXRlZCB0aHJvdWdoIHRoZXNlIHBhdGhzLlxuICBjb25zdCBleGlzdGluZyA9IGF3YWl0IHNlcnZpY2UuZmluZERlbGV0ZWRCeUlkKGlkLCBzY29wZSk7XG4gIGlmICghZXhpc3RpbmcpIHtcbiAgICBzZW5kRW50aXR5Tm90Rm91bmQocmVzLCBvcHRzLmxhYmVsKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGFsbG93ZWQgPSBvcHRzLmF1dGhvcml6ZVxuICAgID8gb3B0cy5hdXRob3JpemUoZXhpc3RpbmcsIHJlcSwgcmVzKVxuICAgIDogcmVxdWlyZVZpc2liaWxpdHlXcml0ZUFjY2VzcyhyZXEsIHJlcywgZXhpc3RpbmcsIG9wdHMudXNlcklkLCBvcHRzLnB1Ymxpc2hQZXJtaXNzaW9uKTtcbiAgaWYgKCFhbGxvd2VkKSByZXR1cm4gbnVsbDtcbiAgcmV0dXJuIHsgaWQsIGV4aXN0aW5nLCBzY29wZSB9O1xufVxuXG4vKipcbiAqIFNoYXJlZCBza2VsZXRvbiBmb3IgYSBzdGVwLXVwLWdhdGVkIGVudGl0eSBSRVNUT1JFIHJvdXRlOiBleHRyYWN0IGA6aWRgLCBsb2FkXG4gKiB0aGUgdG9tYnN0b25lLCBhdXRob3JpemUgaXQsIHJlc3RvcmUsIGFuZCA0MDQgb24gbWlzcy4gUmV0dXJuc1xuICogYHsgZXhpc3RpbmcsIHJlc3RvcmVkIH1gIG9uIHN1Y2Nlc3MsIG9yIGBudWxsYCB3aGVuIGl0IGhhcyBBTFJFQURZIHNlbnQgYVxuICogcmVzcG9uc2UgKDQwMC80MDQvNDAzKSDigJQgdGhlIGNhbGxlciB0aGVuIGRvZXMgdGhlIGVudGl0eS1zcGVjaWZpYyBhdWRpdCArXG4gKiByZXNwb25zZS4gU3RlcC11cCBpcyB0aGUgcm91dGUncyBqb2IuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2FkQW5kUmVzdG9yZTxUIGV4dGVuZHMgUmVzdG9yYWJsZUVudGl0eT4oXG4gIHJlcTogUmVxdWVzdCxcbiAgcmVzOiBSZXNwb25zZSxcbiAgc2VydmljZTogUmVzdG9yYWJsZVNlcnZpY2U8VD4sXG4gIG9wdHM6IFRvbWJzdG9uZVJvdXRlT3B0aW9uczxUPixcbik6IFByb21pc2U8eyBleGlzdGluZzogVDsgcmVzdG9yZWQ6IFQgfSB8IG51bGw+IHtcbiAgY29uc3QgbG9hZGVkID0gYXdhaXQgbG9hZFRvbWJzdG9uZShyZXEsIHJlcywgc2VydmljZSwgb3B0cyk7XG4gIGlmICghbG9hZGVkKSByZXR1cm4gbnVsbDtcblxuICBjb25zdCByZXN0b3JlZCA9IGF3YWl0IHNlcnZpY2UucmVzdG9yZShsb2FkZWQuaWQsIGxvYWRlZC5zY29wZSA/PyAnJywgb3B0cy51c2VySWQpO1xuICBpZiAoIXJlc3RvcmVkKSB7XG4gICAgc2VuZEVudGl0eU5vdEZvdW5kKHJlcywgb3B0cy5sYWJlbCk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIHsgZXhpc3Rpbmc6IGxvYWRlZC5leGlzdGluZywgcmVzdG9yZWQgfTtcbn1cblxuLyoqXG4gKiBTaGFyZWQgc2tlbGV0b24gZm9yIGFuIGVudGl0eSBQVVJHRSByb3V0ZTogdGhlIHNhbWUgbG9hZCArIGF1dGhvcml6YXRpb24gYXNcbiAqIHJlc3RvcmUsIHRoZW4gYSBwZXJtYW5lbnQgaGFyZC1kZWxldGUgdmlhIHRoZSByZXRlbnRpb24gc3dlZXAncyBzaW5nbGUtaWRcbiAqIHB1cmdlIChzYW1lIHRvbWJzdG9uZSBtYXRjaCArIGRlcGVuZGVudC10ZWFyZG93biBob29rcykuIFJldHVybnNcbiAqIGB7IGV4aXN0aW5nLCBwdXJnZWRJZCB9YCAodGhlIGNhbGxlciBhdWRpdHMgb2ZmIGBleGlzdGluZ2ApLCBvciBgbnVsbGAgd2hlbiBpdFxuICogaGFzIEFMUkVBRFkgc2VudCBhIHJlc3BvbnNlLiBTdGVwLXVwIGlzIHRoZSByb3V0ZSdzIGpvYi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvYWRBbmRQdXJnZTxUIGV4dGVuZHMgUmVzdG9yYWJsZUVudGl0eT4oXG4gIHJlcTogUmVxdWVzdCxcbiAgcmVzOiBSZXNwb25zZSxcbiAgc2VydmljZTogUHVyZ2VhYmxlU2VydmljZTxUPixcbiAgb3B0czogVG9tYnN0b25lUm91dGVPcHRpb25zPFQ+LFxuKTogUHJvbWlzZTx7IGV4aXN0aW5nOiBUOyBwdXJnZWRJZDogc3RyaW5nIH0gfCBudWxsPiB7XG4gIGNvbnN0IGxvYWRlZCA9IGF3YWl0IGxvYWRUb21ic3RvbmUocmVxLCByZXMsIHNlcnZpY2UsIG9wdHMpO1xuICBpZiAoIWxvYWRlZCkgcmV0dXJuIG51bGw7XG5cbiAgLy8gTnVsbCBvbiBhIHJhY2UgKGFscmVhZHkgcHVyZ2VkKSDihpIgNDA0LlxuICBjb25zdCBwdXJnZWRJZCA9IGF3YWl0IHNlcnZpY2UucHVyZ2VCeUlkKGxvYWRlZC5pZCwgbG9hZGVkLnNjb3BlID8/ICcnKTtcbiAgaWYgKCFwdXJnZWRJZCkge1xuICAgIHNlbmRFbnRpdHlOb3RGb3VuZChyZXMsIG9wdHMubGFiZWwpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHJldHVybiB7IGV4aXN0aW5nOiBsb2FkZWQuZXhpc3RpbmcsIHB1cmdlZElkIH07XG59XG4iXX0=
|
|
@@ -6,22 +6,44 @@ import type { Request, Response } from 'express';
|
|
|
6
6
|
* `X-Accel-Buffering: no` (disable nginx buffering) block.
|
|
7
7
|
*/
|
|
8
8
|
export declare function writeSseHeaders(res: Response): void;
|
|
9
|
+
/** The slice of an Express/Node response needed to observe a client disconnect. */
|
|
10
|
+
interface ClosableResponse {
|
|
11
|
+
on(event: 'close', listener: () => void): unknown;
|
|
12
|
+
readonly writableFinished: boolean;
|
|
13
|
+
}
|
|
9
14
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
15
|
+
* An AbortSignal that fires when the client disconnects before the response
|
|
16
|
+
* finished — cancels a provider call (avoids wasted spend) and tells the route
|
|
17
|
+
* to stop writing.
|
|
12
18
|
*
|
|
13
19
|
* Disconnect is detected on the RESPONSE: `res` emits 'close' when the
|
|
14
20
|
* underlying connection goes away, and `writableFinished` tells an early close
|
|
15
21
|
* (client gone) from the normal close after `res.end()`. The request's own
|
|
16
22
|
* 'close' is not a disconnect signal — on current Node it fires once the request
|
|
17
|
-
* BODY has been consumed
|
|
18
|
-
*
|
|
23
|
+
* BODY has been consumed (express.json() does that before the handler runs), so
|
|
24
|
+
* a disconnect would never be observed.
|
|
19
25
|
*/
|
|
20
|
-
export declare function
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
export declare function clientAbortSignal(res: ClosableResponse): AbortSignal;
|
|
27
|
+
/** An open SSE response. */
|
|
28
|
+
export interface SseStream {
|
|
29
|
+
/** Aborted when the client disconnects before the stream finished. */
|
|
30
|
+
readonly signal: AbortSignal;
|
|
31
|
+
/** True once the client has disconnected. */
|
|
32
|
+
aborted(): boolean;
|
|
33
|
+
/** Write one `data:` frame carrying `event` as JSON. A no-op after a disconnect. */
|
|
34
|
+
send(event: unknown): void;
|
|
35
|
+
/** Write the terminal `data: [DONE]` frame (preceded by `event`, when given).
|
|
36
|
+
* A no-op after a disconnect. The caller still ends the response. */
|
|
37
|
+
done(event?: unknown): void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Set SSE response headers, flush, and return the stream's writer plus its
|
|
41
|
+
* client-disconnect signal (see {@link clientAbortSignal}).
|
|
42
|
+
*/
|
|
43
|
+
export declare function initSSEStream(_req: Request, res: Response, timeoutMs: number): SseStream;
|
|
23
44
|
/**
|
|
24
45
|
* Classify AI generation errors and send the appropriate HTTP response or SSE event.
|
|
25
46
|
* If headers are already sent (streaming), writes an SSE error event and ends the response.
|
|
26
47
|
*/
|
|
27
48
|
export declare function handleAIError(res: Response, message: string, fallbackMessage: string): void;
|
|
49
|
+
export {};
|
|
@@ -14,24 +14,51 @@ export function writeSseHeaders(res) {
|
|
|
14
14
|
res.setHeader('X-Accel-Buffering', 'no');
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* An AbortSignal that fires when the client disconnects before the response
|
|
18
|
+
* finished — cancels a provider call (avoids wasted spend) and tells the route
|
|
19
|
+
* to stop writing.
|
|
19
20
|
*
|
|
20
21
|
* Disconnect is detected on the RESPONSE: `res` emits 'close' when the
|
|
21
22
|
* underlying connection goes away, and `writableFinished` tells an early close
|
|
22
23
|
* (client gone) from the normal close after `res.end()`. The request's own
|
|
23
24
|
* 'close' is not a disconnect signal — on current Node it fires once the request
|
|
24
|
-
* BODY has been consumed
|
|
25
|
-
*
|
|
25
|
+
* BODY has been consumed (express.json() does that before the handler runs), so
|
|
26
|
+
* a disconnect would never be observed.
|
|
27
|
+
*/
|
|
28
|
+
export function clientAbortSignal(res) {
|
|
29
|
+
const controller = new AbortController();
|
|
30
|
+
res.on('close', () => {
|
|
31
|
+
if (!res.writableFinished)
|
|
32
|
+
controller.abort();
|
|
33
|
+
});
|
|
34
|
+
return controller.signal;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Set SSE response headers, flush, and return the stream's writer plus its
|
|
38
|
+
* client-disconnect signal (see {@link clientAbortSignal}).
|
|
26
39
|
*/
|
|
27
40
|
export function initSSEStream(_req, res, timeoutMs) {
|
|
28
41
|
writeSseHeaders(res);
|
|
29
42
|
res.setTimeout(timeoutMs);
|
|
30
43
|
res.flushHeaders();
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
44
|
+
const signal = clientAbortSignal(res);
|
|
45
|
+
const send = (event) => {
|
|
46
|
+
if (signal.aborted)
|
|
47
|
+
return;
|
|
48
|
+
res.write(`data: ${JSON.stringify(event)}\n\n`);
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
signal,
|
|
52
|
+
aborted: () => signal.aborted,
|
|
53
|
+
send,
|
|
54
|
+
done: (event) => {
|
|
55
|
+
if (signal.aborted)
|
|
56
|
+
return;
|
|
57
|
+
if (event !== undefined)
|
|
58
|
+
send(event);
|
|
59
|
+
res.write('data: [DONE]\n\n');
|
|
60
|
+
},
|
|
61
|
+
};
|
|
35
62
|
}
|
|
36
63
|
/**
|
|
37
64
|
* Classify AI generation errors and send the appropriate HTTP response or SSE event.
|
|
@@ -57,4 +84,4 @@ export function handleAIError(res, message, fallbackMessage) {
|
|
|
57
84
|
res.write(`data: ${JSON.stringify({ type: 'error', message })}\n\n`);
|
|
58
85
|
res.end();
|
|
59
86
|
}
|
|
60
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
87
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3NlLWhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaGVscGVycy9zc2UtaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBR3RDLE9BQU8sRUFBRSxjQUFjLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV6RTs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsR0FBYTtJQUMzQyxHQUFHLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO0lBQ25ELEdBQUcsQ0FBQyxTQUFTLENBQUMsZUFBZSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQzNDLEdBQUcsQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQzFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDM0MsQ0FBQztBQVFEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLEdBQXFCO0lBQ3JELE1BQU0sVUFBVSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7SUFDekMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO1FBQ25CLElBQUksQ0FBQyxHQUFHLENBQUMsZ0JBQWdCO1lBQUUsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2hELENBQUMsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxVQUFVLENBQUMsTUFBTSxDQUFDO0FBQzNCLENBQUM7QUFlRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsYUFBYSxDQUFDLElBQWEsRUFBRSxHQUFhLEVBQUUsU0FBaUI7SUFDM0UsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3JCLEdBQUcsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDMUIsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQ25CLE1BQU0sTUFBTSxHQUFHLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3RDLE1BQU0sSUFBSSxHQUFHLENBQUMsS0FBYyxFQUFRLEVBQUU7UUFDcEMsSUFBSSxNQUFNLENBQUMsT0FBTztZQUFFLE9BQU87UUFDM0IsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ2xELENBQUMsQ0FBQztJQUNGLE9BQU87UUFDTCxNQUFNO1FBQ04sT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPO1FBQzdCLElBQUk7UUFDSixJQUFJLEVBQUUsQ0FBQyxLQUFlLEVBQVEsRUFBRTtZQUM5QixJQUFJLE1BQU0sQ0FBQyxPQUFPO2dCQUFFLE9BQU87WUFDM0IsSUFBSSxLQUFLLEtBQUssU0FBUztnQkFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDckMsR0FBRyxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2hDLENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxhQUFhLENBQUMsR0FBYSxFQUFFLE9BQWUsRUFBRSxlQUF1QjtJQUNuRixJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3JCLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUN0RSxxRUFBcUU7WUFDckUsd0VBQXdFO1lBQ3hFLHdFQUF3RTtZQUN4RSxpRUFBaUU7WUFDakUsMEVBQTBFO1lBQzFFLHlFQUF5RTtZQUN6RSx5RUFBeUU7WUFDekUsT0FBTyxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDekMsQ0FBQztRQUNELElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyw0QkFBNEIsQ0FBQyxFQUFFLENBQUM7WUFDbkQsT0FBTyxjQUFjLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3RDLENBQUM7UUFDRCxPQUFPLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxlQUFlLEVBQUUsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBQ0QsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3JFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNaLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHR5cGUgeyBSZXF1ZXN0LCBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgc2VuZEJhZFJlcXVlc3QsIHNlbmRJbnRlcm5hbEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG4vKipcbiAqIFNldCB0aGUgZm91ciBzdGFuZGFyZCBTU0UgcmVzcG9uc2UgaGVhZGVycyAoZG9lcyBOT1QgZmx1c2gg4oCUIHRoZSBjYWxsZXIgZmx1c2hlc1xuICogYWZ0ZXIgYW55IGFkZGl0aW9uYWwgcGVyLWVuZHBvaW50IHNldHVwIGxpa2UgYHJlcy5zZXRUaW1lb3V0YCkuIFRoZSBzaW5nbGVcbiAqIHNvdXJjZSBvZiB0cnV0aCBmb3IgdGhlIGB0ZXh0L2V2ZW50LXN0cmVhbWAgKyBuby1jYWNoZSArIGtlZXAtYWxpdmUgK1xuICogYFgtQWNjZWwtQnVmZmVyaW5nOiBub2AgKGRpc2FibGUgbmdpbnggYnVmZmVyaW5nKSBibG9jay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyaXRlU3NlSGVhZGVycyhyZXM6IFJlc3BvbnNlKTogdm9pZCB7XG4gIHJlcy5zZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICd0ZXh0L2V2ZW50LXN0cmVhbScpO1xuICByZXMuc2V0SGVhZGVyKCdDYWNoZS1Db250cm9sJywgJ25vLWNhY2hlJyk7XG4gIHJlcy5zZXRIZWFkZXIoJ0Nvbm5lY3Rpb24nLCAna2VlcC1hbGl2ZScpO1xuICByZXMuc2V0SGVhZGVyKCdYLUFjY2VsLUJ1ZmZlcmluZycsICdubycpO1xufVxuXG4vKiogVGhlIHNsaWNlIG9mIGFuIEV4cHJlc3MvTm9kZSByZXNwb25zZSBuZWVkZWQgdG8gb2JzZXJ2ZSBhIGNsaWVudCBkaXNjb25uZWN0LiAqL1xuaW50ZXJmYWNlIENsb3NhYmxlUmVzcG9uc2Uge1xuICBvbihldmVudDogJ2Nsb3NlJywgbGlzdGVuZXI6ICgpID0+IHZvaWQpOiB1bmtub3duO1xuICByZWFkb25seSB3cml0YWJsZUZpbmlzaGVkOiBib29sZWFuO1xufVxuXG4vKipcbiAqIEFuIEFib3J0U2lnbmFsIHRoYXQgZmlyZXMgd2hlbiB0aGUgY2xpZW50IGRpc2Nvbm5lY3RzIGJlZm9yZSB0aGUgcmVzcG9uc2VcbiAqIGZpbmlzaGVkIOKAlCBjYW5jZWxzIGEgcHJvdmlkZXIgY2FsbCAoYXZvaWRzIHdhc3RlZCBzcGVuZCkgYW5kIHRlbGxzIHRoZSByb3V0ZVxuICogdG8gc3RvcCB3cml0aW5nLlxuICpcbiAqIERpc2Nvbm5lY3QgaXMgZGV0ZWN0ZWQgb24gdGhlIFJFU1BPTlNFOiBgcmVzYCBlbWl0cyAnY2xvc2UnIHdoZW4gdGhlXG4gKiB1bmRlcmx5aW5nIGNvbm5lY3Rpb24gZ29lcyBhd2F5LCBhbmQgYHdyaXRhYmxlRmluaXNoZWRgIHRlbGxzIGFuIGVhcmx5IGNsb3NlXG4gKiAoY2xpZW50IGdvbmUpIGZyb20gdGhlIG5vcm1hbCBjbG9zZSBhZnRlciBgcmVzLmVuZCgpYC4gVGhlIHJlcXVlc3QncyBvd25cbiAqICdjbG9zZScgaXMgbm90IGEgZGlzY29ubmVjdCBzaWduYWwg4oCUIG9uIGN1cnJlbnQgTm9kZSBpdCBmaXJlcyBvbmNlIHRoZSByZXF1ZXN0XG4gKiBCT0RZIGhhcyBiZWVuIGNvbnN1bWVkIChleHByZXNzLmpzb24oKSBkb2VzIHRoYXQgYmVmb3JlIHRoZSBoYW5kbGVyIHJ1bnMpLCBzb1xuICogYSBkaXNjb25uZWN0IHdvdWxkIG5ldmVyIGJlIG9ic2VydmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2xpZW50QWJvcnRTaWduYWwocmVzOiBDbG9zYWJsZVJlc3BvbnNlKTogQWJvcnRTaWduYWwge1xuICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICByZXMub24oJ2Nsb3NlJywgKCkgPT4ge1xuICAgIGlmICghcmVzLndyaXRhYmxlRmluaXNoZWQpIGNvbnRyb2xsZXIuYWJvcnQoKTtcbiAgfSk7XG4gIHJldHVybiBjb250cm9sbGVyLnNpZ25hbDtcbn1cblxuLyoqIEFuIG9wZW4gU1NFIHJlc3BvbnNlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTc2VTdHJlYW0ge1xuICAvKiogQWJvcnRlZCB3aGVuIHRoZSBjbGllbnQgZGlzY29ubmVjdHMgYmVmb3JlIHRoZSBzdHJlYW0gZmluaXNoZWQuICovXG4gIHJlYWRvbmx5IHNpZ25hbDogQWJvcnRTaWduYWw7XG4gIC8qKiBUcnVlIG9uY2UgdGhlIGNsaWVudCBoYXMgZGlzY29ubmVjdGVkLiAqL1xuICBhYm9ydGVkKCk6IGJvb2xlYW47XG4gIC8qKiBXcml0ZSBvbmUgYGRhdGE6YCBmcmFtZSBjYXJyeWluZyBgZXZlbnRgIGFzIEpTT04uIEEgbm8tb3AgYWZ0ZXIgYSBkaXNjb25uZWN0LiAqL1xuICBzZW5kKGV2ZW50OiB1bmtub3duKTogdm9pZDtcbiAgLyoqIFdyaXRlIHRoZSB0ZXJtaW5hbCBgZGF0YTogW0RPTkVdYCBmcmFtZSAocHJlY2VkZWQgYnkgYGV2ZW50YCwgd2hlbiBnaXZlbikuXG4gICAqICBBIG5vLW9wIGFmdGVyIGEgZGlzY29ubmVjdC4gVGhlIGNhbGxlciBzdGlsbCBlbmRzIHRoZSByZXNwb25zZS4gKi9cbiAgZG9uZShldmVudD86IHVua25vd24pOiB2b2lkO1xufVxuXG4vKipcbiAqIFNldCBTU0UgcmVzcG9uc2UgaGVhZGVycywgZmx1c2gsIGFuZCByZXR1cm4gdGhlIHN0cmVhbSdzIHdyaXRlciBwbHVzIGl0c1xuICogY2xpZW50LWRpc2Nvbm5lY3Qgc2lnbmFsIChzZWUge0BsaW5rIGNsaWVudEFib3J0U2lnbmFsfSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbml0U1NFU3RyZWFtKF9yZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIHRpbWVvdXRNczogbnVtYmVyKTogU3NlU3RyZWFtIHtcbiAgd3JpdGVTc2VIZWFkZXJzKHJlcyk7XG4gIHJlcy5zZXRUaW1lb3V0KHRpbWVvdXRNcyk7XG4gIHJlcy5mbHVzaEhlYWRlcnMoKTtcbiAgY29uc3Qgc2lnbmFsID0gY2xpZW50QWJvcnRTaWduYWwocmVzKTtcbiAgY29uc3Qgc2VuZCA9IChldmVudDogdW5rbm93bik6IHZvaWQgPT4ge1xuICAgIGlmIChzaWduYWwuYWJvcnRlZCkgcmV0dXJuO1xuICAgIHJlcy53cml0ZShgZGF0YTogJHtKU09OLnN0cmluZ2lmeShldmVudCl9XFxuXFxuYCk7XG4gIH07XG4gIHJldHVybiB7XG4gICAgc2lnbmFsLFxuICAgIGFib3J0ZWQ6ICgpID0+IHNpZ25hbC5hYm9ydGVkLFxuICAgIHNlbmQsXG4gICAgZG9uZTogKGV2ZW50PzogdW5rbm93bik6IHZvaWQgPT4ge1xuICAgICAgaWYgKHNpZ25hbC5hYm9ydGVkKSByZXR1cm47XG4gICAgICBpZiAoZXZlbnQgIT09IHVuZGVmaW5lZCkgc2VuZChldmVudCk7XG4gICAgICByZXMud3JpdGUoJ2RhdGE6IFtET05FXVxcblxcbicpO1xuICAgIH0sXG4gIH07XG59XG5cbi8qKlxuICogQ2xhc3NpZnkgQUkgZ2VuZXJhdGlvbiBlcnJvcnMgYW5kIHNlbmQgdGhlIGFwcHJvcHJpYXRlIEhUVFAgcmVzcG9uc2Ugb3IgU1NFIGV2ZW50LlxuICogSWYgaGVhZGVycyBhcmUgYWxyZWFkeSBzZW50IChzdHJlYW1pbmcpLCB3cml0ZXMgYW4gU1NFIGVycm9yIGV2ZW50IGFuZCBlbmRzIHRoZSByZXNwb25zZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZUFJRXJyb3IocmVzOiBSZXNwb25zZSwgbWVzc2FnZTogc3RyaW5nLCBmYWxsYmFja01lc3NhZ2U6IHN0cmluZyk6IHZvaWQge1xuICBpZiAoIXJlcy5oZWFkZXJzU2VudCkge1xuICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKCdub3QgY29uZmlndXJlZCcpIHx8IG1lc3NhZ2UuaW5jbHVkZXMoJ0FQSSBrZXknKSkge1xuICAgICAgLy8gU3VyZmFjZSB0aGUgT1JJR0lOQUwgbWVzc2FnZS4gSXQgbmFtZXMgdGhlIE1JU1NJTkcgQ09ORklHVVJBVElPTiDigJRcbiAgICAgIC8vIFwibm8gcHJvdmlkZXIgQVBJIGtleSBpcyBzZXQgYW5kIE9QRU5BSV9DT01QQVRJQkxFX0JBU0VfVVJMIGlzIHVuc2V0XCIsXG4gICAgICAvLyBvciB3aGljaCBlbnYgdmFyIGEgbmFtZWQgcHJvdmlkZXIgd2FudHMg4oCUIG5ldmVyIGEgc2VjcmV0IFZBTFVFLCBzbyBpdFxuICAgICAgLy8gaXMgc2FmZSB0byBzaG93IGFuZCBpdCBpcyB0aGUgb25seSB0aGluZyB0aGF0IG1ha2VzIHRoaXMgZXJyb3JcbiAgICAgIC8vIGFjdGlvbmFibGUuIFRoZSBnZW5lcmljIHJlcGxhY2VtZW50IGFsc28gbWlzLWRlc2NyaWJlZCB0aGUgY29tbW9uIGNhc2U6XG4gICAgICAvLyBpdCBzYWlkIFwiZm9yIHRoZSByZXF1ZXN0ZWQgcHJvdmlkZXJcIiB3aGVuIG5vIHByb3ZpZGVyIHdhcyByZXF1ZXN0ZWQgYXRcbiAgICAgIC8vIGFsbCwgcG9pbnRpbmcgb3BlcmF0b3JzIGF0IGEgcHJvdmlkZXIgYnVnIGluc3RlYWQgb2YgYXQgY29uZmlndXJhdGlvbi5cbiAgICAgIHJldHVybiBzZW5kSW50ZXJuYWxFcnJvcihyZXMsIG1lc3NhZ2UpO1xuICAgIH1cbiAgICBpZiAobWVzc2FnZS5pbmNsdWRlcygnbm90IGF2YWlsYWJsZSBmb3IgcHJvdmlkZXInKSkge1xuICAgICAgcmV0dXJuIHNlbmRCYWRSZXF1ZXN0KHJlcywgbWVzc2FnZSk7XG4gICAgfVxuICAgIHJldHVybiBzZW5kSW50ZXJuYWxFcnJvcihyZXMsIGZhbGxiYWNrTWVzc2FnZSwgeyBkZXRhaWxzOiBtZXNzYWdlIH0pO1xuICB9XG4gIHJlcy53cml0ZShgZGF0YTogJHtKU09OLnN0cmluZ2lmeSh7IHR5cGU6ICdlcnJvcicsIG1lc3NhZ2UgfSl9XFxuXFxuYCk7XG4gIHJlcy5lbmQoKTtcbn1cbiJdfQ==
|
package/lib/index.d.ts
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* **Utilities**
|
|
20
20
|
* - createLogger — Winston-based structured logger factory
|
|
21
21
|
* - sendSuccess, sendError, sendPaginatedNested, sendBadRequest, sendInternalError — HTTP response helpers
|
|
22
|
-
* - getParam
|
|
22
|
+
* - getParam — request parameter extraction
|
|
23
23
|
* - parseQueryInt, parseQueryString — query string parsing
|
|
24
24
|
* - getIdentity — identity extraction from requests
|
|
25
25
|
* - actorId — the audit actor for a route context (one `system` sentinel)
|
|
@@ -52,25 +52,27 @@
|
|
|
52
52
|
* PUBLIC SURFACE POLICY
|
|
53
53
|
*
|
|
54
54
|
* The root re-exports the ten sub-barrels, and each SUB-BARREL is the allow-list
|
|
55
|
-
* for its own area
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
55
|
+
* for its own area: every re-export NAMES what it exports (no `export *`), and
|
|
56
|
+
* a name is on the list only because some other package — a service, the
|
|
57
|
+
* frontend, a test, a deploy script — actually imports it. Internals are
|
|
58
|
+
* excluded there rather than here, so the exclusion sits next to the code that
|
|
59
|
+
* defines them. Adding an export to a module does NOT publish it; add it to
|
|
60
|
+
* the sub-barrel when a consumer needs it.
|
|
59
61
|
*
|
|
60
|
-
*
|
|
61
|
-
* - `services/retry-strategy` — decision functions only; `parseRetryAfter
|
|
62
|
-
* `addJitter` are backoff internals.
|
|
63
|
-
* - `services/circuit-breaker` — `
|
|
64
|
-
*
|
|
65
|
-
* services.
|
|
62
|
+
* Deliberately internal, for example:
|
|
63
|
+
* - `services/retry-strategy` — decision functions only; `parseRetryAfter`,
|
|
64
|
+
* `addJitter` and the DEFAULT_* constants are backoff internals.
|
|
65
|
+
* - `services/circuit-breaker` — `resetCircuitBreakers` only; the
|
|
66
|
+
* `CircuitBreaker` class is wired by the shared HTTP client, not by services.
|
|
66
67
|
* - `services/service-keys` — verify/inspect only; signing, the key bundle and
|
|
67
68
|
* `_resetServiceKeysForTests` stay inside.
|
|
68
69
|
* - `utils/jwk` — constants, shapes, decoders and the two signer-facing helpers
|
|
69
70
|
* platform needs; `jwkThumbprint` / `publicKeyFromJwk` stay inside.
|
|
70
71
|
*
|
|
71
|
-
* api-core's own modules
|
|
72
|
-
* by DEEP import
|
|
73
|
-
*
|
|
72
|
+
* api-core's own modules reach the excluded symbols by relative import; unit
|
|
73
|
+
* tests reach them by DEEP import
|
|
74
|
+
* (`@pipeline-builder/api-core/lib/services/service-keys.js`). Test helpers are
|
|
75
|
+
* the separate `@pipeline-builder/api-core/testing` entry, never this barrel.
|
|
74
76
|
*/
|
|
75
77
|
export * from './types/index.js';
|
|
76
78
|
export * from './constants/index.js';
|