@pipeline-builder/pipeline-data 4.1.15 → 4.1.17
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/lib/api/access-control-builder.d.ts +18 -1
- package/lib/api/access-control-builder.js +19 -6
- package/lib/api/crud-service.d.ts +94 -36
- package/lib/api/crud-service.js +188 -166
- package/lib/api/plugin-resolution.d.ts +253 -0
- package/lib/api/plugin-resolution.js +649 -0
- package/lib/api/public-directory.d.ts +281 -0
- package/lib/api/public-directory.js +457 -0
- package/lib/api/query-builders.d.ts +13 -0
- package/lib/api/query-builders.js +74 -9
- package/lib/api/reporting/caches.js +4 -4
- package/lib/api/reporting/dora-scoring.d.ts +3 -3
- package/lib/api/reporting/dora-scoring.js +4 -4
- package/lib/api/reporting/dora.d.ts +6 -6
- package/lib/api/reporting/dora.js +97 -73
- package/lib/api/reporting/plugin-runtime.d.ts +25 -0
- package/lib/api/reporting/plugin-runtime.js +106 -0
- package/lib/api/reporting/query-scope.d.ts +8 -2
- package/lib/api/reporting/query-scope.js +16 -7
- package/lib/api/reporting/retention.d.ts +4 -10
- package/lib/api/reporting/retention.js +8 -11
- package/lib/api/reporting/sql-helpers.d.ts +4 -7
- package/lib/api/reporting/sql-helpers.js +8 -9
- package/lib/api/reporting/types.d.ts +55 -17
- package/lib/api/reporting/types.js +1 -1
- package/lib/api/reporting-service.d.ts +35 -26
- package/lib/api/reporting-service.js +245 -161
- package/lib/api/semver-range.d.ts +73 -0
- package/lib/api/semver-range.js +227 -0
- package/lib/api/soft-delete-sweep.js +8 -20
- package/lib/core/query-filters.d.ts +18 -3
- package/lib/core/query-filters.js +1 -1
- package/lib/database/drizzle-schema.d.ts +7790 -2461
- package/lib/database/drizzle-schema.js +29 -1
- package/lib/database/index.d.ts +4 -2
- package/lib/database/index.js +5 -3
- package/lib/database/pg-result.d.ts +19 -0
- package/lib/database/pg-result.js +32 -0
- package/lib/database/postgres-connection.js +14 -24
- package/lib/database/public-reader.d.ts +14 -0
- package/lib/database/public-reader.js +68 -0
- package/lib/database/retry-strategy.d.ts +3 -5
- package/lib/database/retry-strategy.js +4 -6
- package/lib/database/schema/compliance.d.ts +16 -34
- package/lib/database/schema/compliance.js +4 -4
- package/lib/database/schema/dashboard.js +4 -2
- package/lib/database/schema/ecosystem.d.ts +6586 -0
- package/lib/database/schema/ecosystem.js +709 -0
- package/lib/database/schema/message.d.ts +6 -12
- package/lib/database/schema/message.js +3 -1
- package/lib/database/schema/pipeline.d.ts +79 -5
- package/lib/database/schema/pipeline.js +46 -25
- package/lib/database/schema/plugin.d.ts +587 -3
- package/lib/database/schema/plugin.js +86 -14
- package/lib/database/tenancy.d.ts +6 -7
- package/lib/database/tenancy.js +13 -14
- package/lib/index.d.ts +7 -4
- package/lib/index.js +7 -4
- package/lib/testing/exports.json +146 -0
- package/package.json +44 -7
|
@@ -72,6 +72,18 @@ export interface BaseAccessFilter {
|
|
|
72
72
|
viewerUserId?: string;
|
|
73
73
|
viewerIsSuperAdmin?: boolean;
|
|
74
74
|
}
|
|
75
|
+
/** Per-entity tuning of {@link AccessControlQueryBuilder}. */
|
|
76
|
+
export interface AccessControlOptions {
|
|
77
|
+
/**
|
|
78
|
+
* Whether the SYSTEM org's `public` rung reaches callers in other orgs (and
|
|
79
|
+
* anonymous callers). Default true: the system org's sample pipelines,
|
|
80
|
+
* templates and dashboards are visible from every org. Plugins set it false:
|
|
81
|
+
* since the plugin ecosystem the Official catalog reaches
|
|
82
|
+
* other orgs only as LISTINGS resolved through installs, never through
|
|
83
|
+
* `visibility = 'public'` on a `plugins` row.
|
|
84
|
+
*/
|
|
85
|
+
systemCatalog?: boolean;
|
|
86
|
+
}
|
|
75
87
|
/**
|
|
76
88
|
* Generic access control query builder for multi-tenant entities.
|
|
77
89
|
*
|
|
@@ -86,7 +98,8 @@ export interface BaseAccessFilter {
|
|
|
86
98
|
*/
|
|
87
99
|
export declare class AccessControlQueryBuilder<TSchema extends AccessControlSchema, TFilter extends BaseAccessFilter> {
|
|
88
100
|
private schema;
|
|
89
|
-
|
|
101
|
+
private options;
|
|
102
|
+
constructor(schema: TSchema, options?: AccessControlOptions);
|
|
90
103
|
/**
|
|
91
104
|
* Build the caller's visible slice of a catalog, from the three-rung
|
|
92
105
|
* `visibility` ladder shared by every catalog entity.
|
|
@@ -103,6 +116,10 @@ export declare class AccessControlQueryBuilder<TSchema extends AccessControlSche
|
|
|
103
116
|
* always see everything you are entitled to, or a freshly-created private row
|
|
104
117
|
* would vanish from its own author's listing.
|
|
105
118
|
*
|
|
119
|
+
* An entity can drop the system-org branch with `systemCatalog: false`
|
|
120
|
+
* ({@link AccessControlOptions}): plugins do, so a system-org plugin reaches
|
|
121
|
+
* other orgs only as an Official listing.
|
|
122
|
+
*
|
|
106
123
|
* An explicit `visibility` filter NARROWS within that set, never widens it —
|
|
107
124
|
* so `?visibility=public` still surfaces the system-org catalog.
|
|
108
125
|
*
|
|
@@ -103,8 +103,10 @@ const NO_ROWS = sql `false`;
|
|
|
103
103
|
*/
|
|
104
104
|
export class AccessControlQueryBuilder {
|
|
105
105
|
schema;
|
|
106
|
-
|
|
106
|
+
options;
|
|
107
|
+
constructor(schema, options = {}) {
|
|
107
108
|
this.schema = schema;
|
|
109
|
+
this.options = options;
|
|
108
110
|
}
|
|
109
111
|
/**
|
|
110
112
|
* Build the caller's visible slice of a catalog, from the three-rung
|
|
@@ -122,6 +124,10 @@ export class AccessControlQueryBuilder {
|
|
|
122
124
|
* always see everything you are entitled to, or a freshly-created private row
|
|
123
125
|
* would vanish from its own author's listing.
|
|
124
126
|
*
|
|
127
|
+
* An entity can drop the system-org branch with `systemCatalog: false`
|
|
128
|
+
* ({@link AccessControlOptions}): plugins do, so a system-org plugin reaches
|
|
129
|
+
* other orgs only as an Official listing.
|
|
130
|
+
*
|
|
125
131
|
* An explicit `visibility` filter NARROWS within that set, never widens it —
|
|
126
132
|
* so `?visibility=public` still surfaces the system-org catalog.
|
|
127
133
|
*
|
|
@@ -138,8 +144,12 @@ export class AccessControlQueryBuilder {
|
|
|
138
144
|
buildAccessControl(filter, orgId, parentOrgId) {
|
|
139
145
|
const conditions = [];
|
|
140
146
|
const requested = filter.visibility;
|
|
147
|
+
const systemCatalog = this.options.systemCatalog !== false;
|
|
141
148
|
if (!orgId) {
|
|
142
|
-
// No org context — only the system org's public catalog
|
|
149
|
+
// No org context — only the system org's public catalog (nothing at all
|
|
150
|
+
// for an entity without one).
|
|
151
|
+
if (!systemCatalog)
|
|
152
|
+
return [NO_ROWS];
|
|
143
153
|
conditions.push(eq(this.schema.orgId, SYSTEM_ORG_ID));
|
|
144
154
|
conditions.push(eq(this.schema.visibility, 'public'));
|
|
145
155
|
// An anonymous caller asking for a narrower rung gets nothing, rather than
|
|
@@ -155,11 +165,14 @@ export class AccessControlQueryBuilder {
|
|
|
155
165
|
? eq(this.schema.orgId, normalizedOrgId)
|
|
156
166
|
: and(eq(this.schema.orgId, normalizedOrgId), or(ne(this.schema.visibility, 'private'), ownDraftsOnly));
|
|
157
167
|
// Rows from OTHER orgs are only ever visible at the `public` rung.
|
|
158
|
-
const otherOrgScopes = [
|
|
168
|
+
const otherOrgScopes = [];
|
|
169
|
+
if (systemCatalog)
|
|
170
|
+
otherOrgScopes.push(eq(this.schema.orgId, SYSTEM_ORG_ID));
|
|
159
171
|
if (parentOrgId)
|
|
160
172
|
otherOrgScopes.push(eq(this.schema.orgId, parentOrgId.toLowerCase()));
|
|
161
|
-
|
|
162
|
-
|
|
173
|
+
conditions.push(otherOrgScopes.length > 0
|
|
174
|
+
? or(ownOrg, and(eq(this.schema.visibility, 'public'), or(...otherOrgScopes)))
|
|
175
|
+
: ownOrg);
|
|
163
176
|
if (requested !== undefined)
|
|
164
177
|
conditions.push(eq(this.schema.visibility, requested));
|
|
165
178
|
return conditions;
|
|
@@ -208,4 +221,4 @@ export class AccessControlQueryBuilder {
|
|
|
208
221
|
return conditions;
|
|
209
222
|
}
|
|
210
223
|
}
|
|
211
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLWNvbnRyb2wtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvYWNjZXNzLWNvbnRyb2wtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFHeEQsTUFBTSxTQUFTLEdBQUcsaUVBQWlFLENBQUM7QUFFcEY7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUFDLEdBQVc7SUFDN0MsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDOUUsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSwwQkFBMEIsQ0FBQyxNQUFpQixFQUFFLE9BQWU7SUFDM0UsTUFBTSxPQUFPLEdBQUcsbUJBQW1CLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDM0QsT0FBTyxHQUFHLENBQUEsbURBQW1ELE1BQU0sZ0NBQWdDLEdBQUcsR0FBRyxPQUFPLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDNUgsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUFDLEtBQWM7SUFDL0MsSUFBSSxPQUFPLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDN0MsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxLQUFLLEtBQUssTUFBTSxDQUFDO0lBQ3ZELE9BQU8sT0FBTyxDQUFDLEtBQUss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LEVBQUUsQ0FBQztRQUU3QixnRUFBZ0U7UUFDaEUsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFFeEUsaUNBQWlDO1FBQ2pDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2xELElBQUksV0FBVztZQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFOUMsa0JBQWtCO1FBQ2xCLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUVyRCxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgU1lTVEVNX09SR19JRCB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IGFuZCwgZXEsIG5lLCBvciwgc3FsLCBTUUwgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgdHlwZSB7IEFueUNvbHVtbiB9IGZyb20gJ2RyaXp6bGUtb3JtL2NvbHVtbic7XG5cbmNvbnN0IEZVTExfVVVJRCA9IC9eWzAtOWEtZl17OH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17MTJ9JC9pO1xuXG4vKipcbiAqIEVzY2FwZSBTUUwgTElLRSB3aWxkY2FyZCBjaGFyYWN0ZXJzIHRvIHByZXZlbnQgd2lsZGNhcmQgaW5qZWN0aW9uLlxuICogUmVwbGFjZXMgYCVgIOKGkiBgXFxcXCVgLCBgX2Ag4oaSIGBcXFxcX2AsIGFuZCBgXFxcXGAg4oaSIGBcXFxcXFxcXGAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVMaWtlV2lsZGNhcmRzKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9cXFxcL2csICdcXFxcXFxcXCcpLnJlcGxhY2UoLyUvZywgJ1xcXFwlJykucmVwbGFjZSgvXy9nLCAnXFxcXF8nKTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIGNvbmRpdGlvbiB0aGF0IGNoZWNrcyBpZiBhIEpTT05CIHRleHQgYXJyYXkgY29sdW1uIGNvbnRhaW5zIGEga2V5d29yZCAoY2FzZS1pbnNlbnNpdGl2ZSkuXG4gKiBVc2VkIGZvciBrZXl3b3Jkcy90YWdzIGZpbHRlcmluZyBvbiBwaXBlbGluZXMsIHBsdWdpbnMsIGFuZCBjb21wbGlhbmNlIHJ1bGVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRKc29uYktleXdvcmRDb25kaXRpb24oY29sdW1uOiBBbnlDb2x1bW4sIGtleXdvcmQ6IHN0cmluZyk6IFNRTCB7XG4gIGNvbnN0IGVzY2FwZWQgPSBlc2NhcGVMaWtlV2lsZGNhcmRzKGtleXdvcmQudG9Mb3dlckNhc2UoKSk7XG4gIHJldHVybiBzcWxgRVhJU1RTIChTRUxFQ1QgMSBGUk9NIGpzb25iX2FycmF5X2VsZW1lbnRzX3RleHQoJHtjb2x1bW59KSBBUyBlbCBXSEVSRSBsb3dlcihlbCkgTElLRSAkeyclJyArIGVzY2FwZWQgKyAnJSd9KWA7XG59XG5cbi8qKlxuICogUGFyc2UgYm9vbGVhbiBmaWx0ZXIgdmFsdWUgZnJvbSBzdHJpbmcgb3IgYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VCb29sZWFuRmlsdGVyKHZhbHVlOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykgcmV0dXJuIHZhbHVlO1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgcmV0dXJuIHZhbHVlID09PSAndHJ1ZSc7XG4gIHJldHVybiBCb29sZWFuKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgc3RyaW5nIGZpbHRlciB2YWx1ZSB0byBsb3dlcmNhc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVN0cmluZ0ZpbHRlcih2YWx1ZTogdW5rbm93bik6IHN0cmluZyB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gdmFsdWUudG9Mb3dlckNhc2UoKSA6IFN0cmluZyh2YWx1ZSkudG9Mb3dlckNhc2UoKTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhbiBJRCBwcmVkaWNhdGUgd2l0aCBVVUlEIHByZWZpeCBtYXRjaGluZy5cbiAqXG4gKiAtIEZ1bGwgVVVJRCDihpIgZXhhY3QgbWF0Y2hcbiAqIC0gUGFydGlhbCBVVUlEIOKGkiBwcmVmaXggbWF0Y2ggdmlhIGBMSUtFYCAoYSBsaXN0LXNlYXJjaCBhZmZvcmRhbmNlKVxuICogLSBBYnNlbnQg4oaSIGBudWxsYCAobm8gcHJlZGljYXRlKVxuICpcbiAqIFN0YW5kYWxvbmUgc28gZW50aXRpZXMgdGhhdCBET04nVCB1c2Uge0BsaW5rIEFjY2Vzc0NvbnRyb2xRdWVyeUJ1aWxkZXJ9J3NcbiAqIGFjY2VzcyBjb250cm9sIChlLmcuIHBpcGVsaW5lIHRlbXBsYXRlcywgd2hpY2ggY2FycnkgdGhlaXIgb3duIHRocmVlLXJ1bmdcbiAqIHZpc2liaWxpdHkgbGFkZGVyKSBzdGlsbCBzaGFyZSBvbmUgaWQtbWF0Y2hpbmcgaW1wbGVtZW50YXRpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZElkQ29uZGl0aW9uKGlkQ29sdW1uOiBBbnlDb2x1bW4sIGlkOiB1bmtub3duKTogU1FMIHwgbnVsbCB7XG4gIGlmIChpZCA9PT0gdW5kZWZpbmVkIHx8IGlkID09PSBudWxsKSByZXR1cm4gbnVsbDtcblxuICAvLyBgQmFzZUFjY2Vzc0ZpbHRlci5pZGAgaXMgZGVjbGFyZWQgYHN0cmluZyB8IHN0cmluZ1tdYCwgc28gaG9ub3VyIHRoZSBhcnJheVxuICAvLyBmb3JtOiBtYXRjaCBBTlkgb2YgdGhlIGlkcywgZWFjaCB3aXRoIHRoZSBzYW1lIGV4YWN0LXZzLXByZWZpeCBzZW1hbnRpY3MgYXNcbiAgLy8gYSBzaW5nbGUgdmFsdWUuIGBTdHJpbmcoWydhJywnYiddKWAgd291bGQgb3RoZXJ3aXNlIHByb2R1Y2UgYExJS0UgJ2EsYiUnYFxuICAvLyBhbmQgc2lsZW50bHkgcmV0dXJuIHplcm8gcm93cyDigJQgYSB0cmFwIGZvciB0aGUgZmlyc3QgY2FsbGVyIHRvIHBhc3Mgb25lLlxuICBpZiAoQXJyYXkuaXNBcnJheShpZCkpIHtcbiAgICBjb25zdCBwYXJ0cyA9IGlkXG4gICAgICAubWFwKChvbmUpID0+IGJ1aWxkSWRDb25kaXRpb24oaWRDb2x1bW4sIG9uZSkpXG4gICAgICAuZmlsdGVyKChjKTogYyBpcyBTUUwgPT4gYyAhPT0gbnVsbCk7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHBhcnRzLmxlbmd0aCA9PT0gMSA/IHBhcnRzWzBdIDogKG9yKC4uLnBhcnRzKSBhcyBTUUwpO1xuICB9XG5cbiAgY29uc3QgaWRTdHJpbmcgPSBTdHJpbmcoaWQpLnRvTG93ZXJDYXNlKCk7XG4gIGlmIChGVUxMX1VVSUQudGVzdChpZFN0cmluZykpIHtcbiAgICByZXR1cm4gZXEoaWRDb2x1bW4sIGlkU3RyaW5nKTtcbiAgfVxuICAvLyBFc2NhcGUgU1FMIExJS0Ugd2lsZGNhcmRzIHRvIHByZXZlbnQgd2lsZGNhcmQgaW5qZWN0aW9uXG4gIGNvbnN0IGVzY2FwZWQgPSBlc2NhcGVMaWtlV2lsZGNhcmRzKGlkU3RyaW5nKTtcbiAgcmV0dXJuIHNxbGAke2lkQ29sdW1ufTo6dGV4dCBMSUtFICR7ZXNjYXBlZCArICclJ30gRVNDQVBFICdcXFxcJ2A7XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIGBpc0RlZmF1bHRgIC8gYGlzQWN0aXZlYCBwcmVkaWNhdGVzIHNoYXJlZCBieSBldmVyeSBjYXRhbG9nIGVudGl0eS5cbiAqIGBpc0FjdGl2ZWAgZGVmYXVsdHMgdG8gdHJ1ZSBzbyBzb2Z0LWRlbGV0ZWQgcm93cyBzdGF5IG91dCBvZiBub3JtYWwgcmVhZHMuXG4gKiBTdGFuZGFsb25lIGZvciB0aGUgc2FtZSByZWFzb24gYXMge0BsaW5rIGJ1aWxkSWRDb25kaXRpb259LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRCb29sZWFuQ29uZGl0aW9ucyhcbiAgY29sdW1uczogeyBpc0RlZmF1bHQ6IEFueUNvbHVtbjsgaXNBY3RpdmU6IEFueUNvbHVtbiB9LFxuICBmaWx0ZXI6IHsgaXNEZWZhdWx0PzogdW5rbm93bjsgaXNBY3RpdmU/OiB1bmtub3duIH0sXG4pOiBTUUxbXSB7XG4gIGNvbnN0IGNvbmRpdGlvbnM6IFNRTFtdID0gW107XG5cbiAgaWYgKGZpbHRlci5pc0RlZmF1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgIGNvbmRpdGlvbnMucHVzaChlcShjb2x1bW5zLmlzRGVmYXVsdCwgcGFyc2VCb29sZWFuRmlsdGVyKGZpbHRlci5pc0RlZmF1bHQpKSk7XG4gIH1cblxuICBpZiAoZmlsdGVyLmlzQWN0aXZlICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25kaXRpb25zLnB1c2goZXEoY29sdW1ucy5pc0FjdGl2ZSwgcGFyc2VCb29sZWFuRmlsdGVyKGZpbHRlci5pc0FjdGl2ZSkpKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBEZWZhdWx0IHRvIGFjdGl2ZSByZWNvcmRzIG9ubHkgdG8gZXhjbHVkZSBzb2Z0LWRlbGV0ZWQgZW50aXRpZXNcbiAgICBjb25kaXRpb25zLnB1c2goZXEoY29sdW1ucy5pc0FjdGl2ZSwgdHJ1ZSkpO1xuICB9XG5cbiAgcmV0dXJuIGNvbmRpdGlvbnM7XG59XG5cbi8qKlxuICogU2NoZW1hIHRhYmxlIGludGVyZmFjZSBmb3IgYWNjZXNzIGNvbnRyb2wgcXVlcmllcy4gRXZlcnkgY2F0YWxvZyBlbnRpdHlcbiAqIGNhcnJpZXMgdGhlIHNhbWUgZml2ZSBjb2x1bW5zLCB3aGljaCBpcyB3aGF0IGxldHMgT05FIHByZWRpY2F0ZSBzZXJ2ZVxuICogcGlwZWxpbmVzLCBwbHVnaW5zIGFuZCB0ZW1wbGF0ZXMgYWxpa2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWNjZXNzQ29udHJvbFNjaGVtYSB7XG4gIGlkOiBBbnlDb2x1bW47XG4gIG9yZ0lkOiBBbnlDb2x1bW47XG4gIC8qKiBUaHJlZS1ydW5nIHNoYXJpbmcgbGFkZGVyIOKAlCBzZWUgYXBpLWNvcmUncyBgVmlzaWJpbGl0eWAuICovXG4gIHZpc2liaWxpdHk6IEFueUNvbHVtbjtcbiAgLyoqIEF1dGhvci4gT3ducyB0aGUgYHByaXZhdGVgIHJ1bmcuICovXG4gIGNyZWF0ZWRCeTogQW55Q29sdW1uO1xuICBpc0RlZmF1bHQ6IEFueUNvbHVtbjtcbiAgaXNBY3RpdmU6IEFueUNvbHVtbjtcbn1cblxuLyoqXG4gKiBCYXNlIGZpbHRlciBpbnRlcmZhY2Ugd2l0aCBjb21tb24gYWNjZXNzIGNvbnRyb2wgZmllbGRzLlxuICpcbiAqIGB2aWV3ZXJVc2VySWRgIC8gYHZpZXdlcklzU3VwZXJBZG1pbmAgYXJlIFNFUlZFUi1TRVQgKHN0YW1wZWQgZnJvbSB0aGUgcmVxdWVzdCdzXG4gKiB0ZW5hbnQgY29udGV4dCBieSBgd2l0aFZpZXdlckNvbnRleHRgKSwgbmV2ZXIgY2xpZW50LXN1cHBsaWVkIOKAlCBzZWVcbiAqIGB2aWV3ZXItY29udGV4dC50c2AgZm9yIHdoeSB0aGUgdGVuYW50IGNvbnRleHQgaXMgdGhlIGNoYW5uZWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmFzZUFjY2Vzc0ZpbHRlciB7XG4gIGlkPzogc3RyaW5nIHwgc3RyaW5nW107XG4gIHZpc2liaWxpdHk/OiBzdHJpbmc7XG4gIGlzRGVmYXVsdD86IGJvb2xlYW4gfCBzdHJpbmc7XG4gIGlzQWN0aXZlPzogYm9vbGVhbiB8IHN0cmluZztcbiAgdmlld2VyVXNlcklkPzogc3RyaW5nO1xuICB2aWV3ZXJJc1N1cGVyQWRtaW4/OiBib29sZWFuO1xufVxuXG4vKiogRmFpbC1jbG9zZWQgcHJlZGljYXRlOiBtYXRjaGVzIG5vIHJvd3MuICovXG5jb25zdCBOT19ST1dTOiBTUUwgPSBzcWxgZmFsc2VgO1xuXG4vKipcbiAqIEdlbmVyaWMgYWNjZXNzIGNvbnRyb2wgcXVlcnkgYnVpbGRlciBmb3IgbXVsdGktdGVuYW50IGVudGl0aWVzLlxuICpcbiAqIENvbnNvbGlkYXRlcyBkdXBsaWNhdGUgYWNjZXNzIGNvbnRyb2wgbG9naWMgc2hhcmVkIGFjcm9zcyBwaXBlbGluZSBhbmQgcGx1Z2luIHF1ZXJpZXMuXG4gKiBIYW5kbGVzOlxuICogLSBNdWx0aS10ZW5hbnQgYWNjZXNzIGNvbnRyb2wgKHB1YmxpYy9wcml2YXRlL29yZy1hbmQtcHVibGljKVxuICogLSBVVUlEIHByZWZpeCBtYXRjaGluZyBmb3IgSUQgZmlsdGVyc1xuICogLSBCb29sZWFuIGZpZWxkIG5vcm1hbGl6YXRpb25cbiAqXG4gKiBAdHlwZVBhcmFtIFRTY2hlbWEgLSBTY2hlbWEgdGFibGUgdHlwZSB3aXRoIGFjY2VzcyBjb250cm9sIGZpZWxkc1xuICogQHR5cGVQYXJhbSBURmlsdGVyIC0gRmlsdGVyIHR5cGUgZXh0ZW5kaW5nIEJhc2VBY2Nlc3NGaWx0ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIEFjY2Vzc0NvbnRyb2xRdWVyeUJ1aWxkZXI8XG4gIFRTY2hlbWEgZXh0ZW5kcyBBY2Nlc3NDb250cm9sU2NoZW1hLFxuICBURmlsdGVyIGV4dGVuZHMgQmFzZUFjY2Vzc0ZpbHRlcixcbj4ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHNjaGVtYTogVFNjaGVtYSxcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBCdWlsZCB0aGUgY2FsbGVyJ3MgdmlzaWJsZSBzbGljZSBvZiBhIGNhdGFsb2csIGZyb20gdGhlIHRocmVlLXJ1bmdcbiAgICogYHZpc2liaWxpdHlgIGxhZGRlciBzaGFyZWQgYnkgZXZlcnkgY2F0YWxvZyBlbnRpdHkuXG4gICAqXG4gICAqIEVmZmVjdGl2ZSByZWFkIHNldCBmb3IgYSBjYWxsZXIgaW4gb3JnIGBPYCBhcyB1c2VyIGBWYCB3aG9zZSBwYXJlbnQgb3JnIGlzIGBQYDpcbiAgICpcbiAgICogICAob3JnX2lkID0gTyBBTkQgKHZpc2liaWxpdHkgPD4gJ3ByaXZhdGUnIE9SIGNyZWF0ZWRfYnkgPSBWKSlcbiAgICogICBPUiAodmlzaWJpbGl0eSA9ICdwdWJsaWMnIEFORCAob3JnX2lkID0gJ3N5c3RlbScgT1Igb3JnX2lkID0gUCkpXG4gICAqXG4gICAqIGkuZS4geW91ciBvd24gb3JnJ3Mgc2hhcmVkIHJ1bmdzIHBsdXMgeW91ciBvd24gZHJhZnRzLCB3aWRlbmVkIGJ5IHRoZSBzeXN0ZW1cbiAgICogb3JnJ3MgcHVibGljIGNhdGFsb2cgKHRoZSBzdGFuZGluZyBcInN5c3RlbS1vcmcgY29udGVudCBpcyB2aXNpYmxlIGZyb20gZXZlcnlcbiAgICogb3JnXCIgcnVsZSkgYW5kIOKAlCBmb3IgYSB0ZWFtIOKAlCBpdHMgcGFyZW50J3MgcHVibGljIHJvd3MuIFRoZSBgcHVibGljYC1vbmx5XG4gICAqIHJlc3RyaWN0aW9uIGFwcGxpZXMgc29sZWx5IHRvIHRob3NlIE9USEVSIG9yZ3MnIHJvd3M7IHdpdGhpbiB5b3VyIG93biBvcmcgeW91XG4gICAqIGFsd2F5cyBzZWUgZXZlcnl0aGluZyB5b3UgYXJlIGVudGl0bGVkIHRvLCBvciBhIGZyZXNobHktY3JlYXRlZCBwcml2YXRlIHJvd1xuICAgKiB3b3VsZCB2YW5pc2ggZnJvbSBpdHMgb3duIGF1dGhvcidzIGxpc3RpbmcuXG4gICAqXG4gICAqIEFuIGV4cGxpY2l0IGB2aXNpYmlsaXR5YCBmaWx0ZXIgTkFSUk9XUyB3aXRoaW4gdGhhdCBzZXQsIG5ldmVyIHdpZGVucyBpdCDigJRcbiAgICogc28gYD92aXNpYmlsaXR5PXB1YmxpY2Agc3RpbGwgc3VyZmFjZXMgdGhlIHN5c3RlbS1vcmcgY2F0YWxvZy5cbiAgICpcbiAgICogRmFpbHMgQ0xPU0VEIG9uIGJvdGggYXhlczogbm8gYG9yZ0lkYCAoYW5vbnltb3VzKSDih5Igc3lzdGVtLW9yZyBwdWJsaWMgb25seTtcbiAgICogbm8gYHZpZXdlclVzZXJJZGAg4oeSIHRoZSBwcml2YXRlIHJ1bmcgbWF0Y2hlcyBub3RoaW5nIHJhdGhlciB0aGFuIGV2ZXJ5dGhpbmcuXG4gICAqIGB2aWV3ZXJJc1N1cGVyQWRtaW5gIGxpZnRzIHRoZSBwcml2YXRlIHJ1bmcgb25seSDigJQgYSBwbGF0Zm9ybSBvcGVyYXRvclxuICAgKiBhZG1pbmlzdGVycyB0aGUgd2hvbGUgY2F0YWxvZy5cbiAgICpcbiAgICogQHBhcmFtIGZpbHRlciAtIEZpbHRlciBjcml0ZXJpYVxuICAgKiBAcGFyYW0gb3JnSWQgLSBVc2VyJ3Mgb3JnYW5pemF0aW9uIElEIChvcHRpb25hbClcbiAgICogQHBhcmFtIHBhcmVudE9yZ0lkIC0gUGFyZW50IG9yZyBJRCB3aGVuIHRoZSBjYWxsZXIgaXMgYSB0ZWFtIChvcHRpb25hbClcbiAgICogQHJldHVybnMgQXJyYXkgb2YgU1FMIGNvbmRpdGlvbnMgZm9yIGFjY2VzcyBjb250cm9sXG4gICAqL1xuICBwcm90ZWN0ZWQgYnVpbGRBY2Nlc3NDb250cm9sKGZpbHRlcjogUGFydGlhbDxURmlsdGVyPiwgb3JnSWQ/OiBzdHJpbmcsIHBhcmVudE9yZ0lkPzogc3RyaW5nKTogU1FMW10ge1xuICAgIGNvbnN0IGNvbmRpdGlvbnM6IFNRTFtdID0gW107XG4gICAgY29uc3QgcmVxdWVzdGVkID0gZmlsdGVyLnZpc2liaWxpdHk7XG5cbiAgICBpZiAoIW9yZ0lkKSB7XG4gICAgICAvLyBObyBvcmcgY29udGV4dCDigJQgb25seSB0aGUgc3lzdGVtIG9yZydzIHB1YmxpYyBjYXRhbG9nLlxuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLm9yZ0lkLCBTWVNURU1fT1JHX0lEKSk7XG4gICAgICBjb25kaXRpb25zLnB1c2goZXEodGhpcy5zY2hlbWEudmlzaWJpbGl0eSwgJ3B1YmxpYycpKTtcbiAgICAgIC8vIEFuIGFub255bW91cyBjYWxsZXIgYXNraW5nIGZvciBhIG5hcnJvd2VyIHJ1bmcgZ2V0cyBub3RoaW5nLCByYXRoZXIgdGhhblxuICAgICAgLy8gaGF2aW5nIHRoZSBuYXJyb3dpbmcgc2lsZW50bHkgaWdub3JlZC5cbiAgICAgIGlmIChyZXF1ZXN0ZWQgIT09IHVuZGVmaW5lZCAmJiByZXF1ZXN0ZWQgIT09ICdwdWJsaWMnKSBjb25kaXRpb25zLnB1c2goTk9fUk9XUyk7XG4gICAgICByZXR1cm4gY29uZGl0aW9ucztcbiAgICB9XG5cbiAgICBjb25zdCBub3JtYWxpemVkT3JnSWQgPSBvcmdJZC50b0xvd2VyQ2FzZSgpO1xuXG4gICAgLy8gT3duLW9yZyByb3dzOiBldmVyeXRoaW5nIEVYQ0VQVCBvdGhlciBwZW9wbGUncyBwcml2YXRlIGRyYWZ0cy5cbiAgICBjb25zdCBvd25EcmFmdHNPbmx5ID0gZmlsdGVyLnZpZXdlclVzZXJJZCA/IGVxKHRoaXMuc2NoZW1hLmNyZWF0ZWRCeSwgZmlsdGVyLnZpZXdlclVzZXJJZCkgOiBOT19ST1dTO1xuICAgIGNvbnN0IG93bk9yZyA9IGZpbHRlci52aWV3ZXJJc1N1cGVyQWRtaW5cbiAgICAgID8gZXEodGhpcy5zY2hlbWEub3JnSWQsIG5vcm1hbGl6ZWRPcmdJZClcbiAgICAgIDogYW5kKGVxKHRoaXMuc2NoZW1hLm9yZ0lkLCBub3JtYWxpemVkT3JnSWQpLCBvcihuZSh0aGlzLnNjaGVtYS52aXNpYmlsaXR5LCAncHJpdmF0ZScpLCBvd25EcmFmdHNPbmx5KSEpITtcblxuICAgIC8vIFJvd3MgZnJvbSBPVEhFUiBvcmdzIGFyZSBvbmx5IGV2ZXIgdmlzaWJsZSBhdCB0aGUgYHB1YmxpY2AgcnVuZy5cbiAgICBjb25zdCBvdGhlck9yZ1Njb3BlcyA9IFtlcSh0aGlzLnNjaGVtYS5vcmdJZCwgU1lTVEVNX09SR19JRCldO1xuICAgIGlmIChwYXJlbnRPcmdJZCkgb3RoZXJPcmdTY29wZXMucHVzaChlcSh0aGlzLnNjaGVtYS5vcmdJZCwgcGFyZW50T3JnSWQudG9Mb3dlckNhc2UoKSkpO1xuICAgIGNvbnN0IG90aGVyT3Jnc1B1YmxpYyA9IGFuZChlcSh0aGlzLnNjaGVtYS52aXNpYmlsaXR5LCAncHVibGljJyksIG9yKC4uLm90aGVyT3JnU2NvcGVzKSEpITtcblxuICAgIGNvbmRpdGlvbnMucHVzaChvcihvd25PcmcsIG90aGVyT3Jnc1B1YmxpYykhKTtcblxuICAgIGlmIChyZXF1ZXN0ZWQgIT09IHVuZGVmaW5lZCkgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLnZpc2liaWxpdHksIHJlcXVlc3RlZCkpO1xuXG4gICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgSUQgZmlsdGVyIHdpdGggVVVJRCBwcmVmaXggbWF0Y2hpbmcgc3VwcG9ydFxuICAgKlxuICAgKiAtIEZ1bGwgVVVJRDogRXhhY3QgbWF0Y2hcbiAgICogLSBQYXJ0aWFsIFVVSUQ6IFByZWZpeCBtYXRjaCB1c2luZyBTUUwgTElLRVxuICAgKlxuICAgKiBAcGFyYW0gaWQgLSBJRCBmaWx0ZXIgdmFsdWUgKGZ1bGwgb3IgcGFydGlhbCBVVUlEKVxuICAgKiBAcmV0dXJucyBTUUwgY29uZGl0aW9uIG9yIG51bGwgaWYgbm8gSUQgZmlsdGVyXG4gICAqL1xuICBwcm90ZWN0ZWQgYnVpbGRJZEZpbHRlcihpZDogdW5rbm93bik6IFNRTCB8IG51bGwge1xuICAgIHJldHVybiBidWlsZElkQ29uZGl0aW9uKHRoaXMuc2NoZW1hLmlkLCBpZCk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYm9vbGVhbiBmaWVsZCBjb25kaXRpb25zIChpc0RlZmF1bHQsIGlzQWN0aXZlKVxuICAgKlxuICAgKiBAcGFyYW0gZmlsdGVyIC0gRmlsdGVyIGNyaXRlcmlhXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIFNRTCBjb25kaXRpb25zIGZvciBib29sZWFuIGZpZWxkc1xuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkQm9vbGVhbkZpbHRlcnMoZmlsdGVyOiBQYXJ0aWFsPFRGaWx0ZXI+KTogU1FMW10ge1xuICAgIHJldHVybiBidWlsZEJvb2xlYW5Db25kaXRpb25zKHRoaXMuc2NoZW1hLCBmaWx0ZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGFsbCBjb21tb24gY29uZGl0aW9ucyAoYWNjZXNzIGNvbnRyb2wgKyBJRCArIGJvb2xlYW5zKVxuICAgKlxuICAgKiBUaGlzIGNvbWJpbmVzIGFsbCB0aGUgZ2VuZXJpYyBmaWx0ZXJzIHRoYXQgYXBwbHkgdG8gYW55IGFjY2Vzcy1jb250cm9sbGVkIGVudGl0eS5cbiAgICogU3ViY2xhc3NlcyBzaG91bGQgY2FsbCB0aGlzIGFuZCBhZGQgZW50aXR5LXNwZWNpZmljIGNvbmRpdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwg4oCUIGZhbGxzIGJhY2sgdG8gc3lzdGVtLXB1YmxpYy1vbmx5KVxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBTUUwgY29uZGl0aW9uc1xuICAgKi9cbiAgcHVibGljIGJ1aWxkQ29tbW9uQ29uZGl0aW9ucyhmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtdO1xuXG4gICAgLy8gQWNjZXNzIGNvbnRyb2wgKG11bHRpLXRlbmFudCkg4oCUIGhhbmRsZXMgdmlzaWJpbGl0eSBpbnRlcm5hbGx5XG4gICAgY29uZGl0aW9ucy5wdXNoKC4uLnRoaXMuYnVpbGRBY2Nlc3NDb250cm9sKGZpbHRlciwgb3JnSWQsIHBhcmVudE9yZ0lkKSk7XG5cbiAgICAvLyBJRCBmaWx0ZXIgd2l0aCBwcmVmaXggbWF0Y2hpbmdcbiAgICBjb25zdCBpZENvbmRpdGlvbiA9IHRoaXMuYnVpbGRJZEZpbHRlcihmaWx0ZXIuaWQpO1xuICAgIGlmIChpZENvbmRpdGlvbikgY29uZGl0aW9ucy5wdXNoKGlkQ29uZGl0aW9uKTtcblxuICAgIC8vIEJvb2xlYW4gZmlsdGVyc1xuICAgIGNvbmRpdGlvbnMucHVzaCguLi50aGlzLmJ1aWxkQm9vbGVhbkZpbHRlcnMoZmlsdGVyKSk7XG5cbiAgICByZXR1cm4gY29uZGl0aW9ucztcbiAgfVxufVxuIl19
|
|
224
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLWNvbnRyb2wtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcGkvYWNjZXNzLWNvbnRyb2wtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFHeEQsTUFBTSxTQUFTLEdBQUcsaUVBQWlFLENBQUM7QUFFcEY7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUFDLEdBQVc7SUFDN0MsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFDOUUsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSwwQkFBMEIsQ0FBQyxNQUFpQixFQUFFLE9BQWU7SUFDM0UsTUFBTSxPQUFPLEdBQUcsbUJBQW1CLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDM0QsT0FBTyxHQUFHLENBQUEsbURBQW1ELE1BQU0sZ0NBQWdDLEdBQUcsR0FBRyxPQUFPLEdBQUcsR0FBRyxHQUFHLENBQUM7QUFDNUgsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUFDLEtBQWM7SUFDL0MsSUFBSSxPQUFPLEtBQUssS0FBSyxTQUFTO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDN0MsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQUUsT0FBTyxLQUFLLEtBQUssTUFBTSxDQUFDO0lBQ3ZELE9BQU8sT0FBTyxDQUFDLEtBQUss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Q0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDTyxtQkFBbUIsQ0FBQyxNQUF3QjtRQUNwRCxPQUFPLHNCQUFzQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDckQsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLHFCQUFxQixDQUFDLE1BQXdCLEVBQUUsS0FBYyxFQUFFLFdBQW9CO1FBQ3pGLE1BQU0sVUFBVSxHQUFVLEVBQUUsQ0FBQztRQUU3QixnRUFBZ0U7UUFDaEUsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFFeEUsaUNBQWlDO1FBQ2pDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2xELElBQUksV0FBVztZQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFOUMsa0JBQWtCO1FBQ2xCLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUVyRCxPQUFPLFVBQVUsQ0FBQztJQUNwQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgU1lTVEVNX09SR19JRCB9IGZyb20gJ0BwaXBlbGluZS1idWlsZGVyL2FwaS1jb3JlJztcbmltcG9ydCB7IGFuZCwgZXEsIG5lLCBvciwgc3FsLCBTUUwgfSBmcm9tICdkcml6emxlLW9ybSc7XG5pbXBvcnQgdHlwZSB7IEFueUNvbHVtbiB9IGZyb20gJ2RyaXp6bGUtb3JtL2NvbHVtbic7XG5cbmNvbnN0IEZVTExfVVVJRCA9IC9eWzAtOWEtZl17OH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17NH0tWzAtOWEtZl17MTJ9JC9pO1xuXG4vKipcbiAqIEVzY2FwZSBTUUwgTElLRSB3aWxkY2FyZCBjaGFyYWN0ZXJzIHRvIHByZXZlbnQgd2lsZGNhcmQgaW5qZWN0aW9uLlxuICogUmVwbGFjZXMgYCVgIOKGkiBgXFxcXCVgLCBgX2Ag4oaSIGBcXFxcX2AsIGFuZCBgXFxcXGAg4oaSIGBcXFxcXFxcXGAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVMaWtlV2lsZGNhcmRzKHN0cjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9cXFxcL2csICdcXFxcXFxcXCcpLnJlcGxhY2UoLyUvZywgJ1xcXFwlJykucmVwbGFjZSgvXy9nLCAnXFxcXF8nKTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhIGNvbmRpdGlvbiB0aGF0IGNoZWNrcyBpZiBhIEpTT05CIHRleHQgYXJyYXkgY29sdW1uIGNvbnRhaW5zIGEga2V5d29yZCAoY2FzZS1pbnNlbnNpdGl2ZSkuXG4gKiBVc2VkIGZvciBrZXl3b3Jkcy90YWdzIGZpbHRlcmluZyBvbiBwaXBlbGluZXMsIHBsdWdpbnMsIGFuZCBjb21wbGlhbmNlIHJ1bGVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRKc29uYktleXdvcmRDb25kaXRpb24oY29sdW1uOiBBbnlDb2x1bW4sIGtleXdvcmQ6IHN0cmluZyk6IFNRTCB7XG4gIGNvbnN0IGVzY2FwZWQgPSBlc2NhcGVMaWtlV2lsZGNhcmRzKGtleXdvcmQudG9Mb3dlckNhc2UoKSk7XG4gIHJldHVybiBzcWxgRVhJU1RTIChTRUxFQ1QgMSBGUk9NIGpzb25iX2FycmF5X2VsZW1lbnRzX3RleHQoJHtjb2x1bW59KSBBUyBlbCBXSEVSRSBsb3dlcihlbCkgTElLRSAkeyclJyArIGVzY2FwZWQgKyAnJSd9KWA7XG59XG5cbi8qKlxuICogUGFyc2UgYm9vbGVhbiBmaWx0ZXIgdmFsdWUgZnJvbSBzdHJpbmcgb3IgYm9vbGVhblxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VCb29sZWFuRmlsdGVyKHZhbHVlOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykgcmV0dXJuIHZhbHVlO1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgcmV0dXJuIHZhbHVlID09PSAndHJ1ZSc7XG4gIHJldHVybiBCb29sZWFuKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgc3RyaW5nIGZpbHRlciB2YWx1ZSB0byBsb3dlcmNhc2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVN0cmluZ0ZpbHRlcih2YWx1ZTogdW5rbm93bik6IHN0cmluZyB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gdmFsdWUudG9Mb3dlckNhc2UoKSA6IFN0cmluZyh2YWx1ZSkudG9Mb3dlckNhc2UoKTtcbn1cblxuLyoqXG4gKiBCdWlsZCBhbiBJRCBwcmVkaWNhdGUgd2l0aCBVVUlEIHByZWZpeCBtYXRjaGluZy5cbiAqXG4gKiAtIEZ1bGwgVVVJRCDihpIgZXhhY3QgbWF0Y2hcbiAqIC0gUGFydGlhbCBVVUlEIOKGkiBwcmVmaXggbWF0Y2ggdmlhIGBMSUtFYCAoYSBsaXN0LXNlYXJjaCBhZmZvcmRhbmNlKVxuICogLSBBYnNlbnQg4oaSIGBudWxsYCAobm8gcHJlZGljYXRlKVxuICpcbiAqIFN0YW5kYWxvbmUgc28gZW50aXRpZXMgdGhhdCBET04nVCB1c2Uge0BsaW5rIEFjY2Vzc0NvbnRyb2xRdWVyeUJ1aWxkZXJ9J3NcbiAqIGFjY2VzcyBjb250cm9sIChlLmcuIHBpcGVsaW5lIHRlbXBsYXRlcywgd2hpY2ggY2FycnkgdGhlaXIgb3duIHRocmVlLXJ1bmdcbiAqIHZpc2liaWxpdHkgbGFkZGVyKSBzdGlsbCBzaGFyZSBvbmUgaWQtbWF0Y2hpbmcgaW1wbGVtZW50YXRpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZElkQ29uZGl0aW9uKGlkQ29sdW1uOiBBbnlDb2x1bW4sIGlkOiB1bmtub3duKTogU1FMIHwgbnVsbCB7XG4gIGlmIChpZCA9PT0gdW5kZWZpbmVkIHx8IGlkID09PSBudWxsKSByZXR1cm4gbnVsbDtcblxuICAvLyBgQmFzZUFjY2Vzc0ZpbHRlci5pZGAgaXMgZGVjbGFyZWQgYHN0cmluZyB8IHN0cmluZ1tdYCwgc28gaG9ub3VyIHRoZSBhcnJheVxuICAvLyBmb3JtOiBtYXRjaCBBTlkgb2YgdGhlIGlkcywgZWFjaCB3aXRoIHRoZSBzYW1lIGV4YWN0LXZzLXByZWZpeCBzZW1hbnRpY3MgYXNcbiAgLy8gYSBzaW5nbGUgdmFsdWUuIGBTdHJpbmcoWydhJywnYiddKWAgd291bGQgb3RoZXJ3aXNlIHByb2R1Y2UgYExJS0UgJ2EsYiUnYFxuICAvLyBhbmQgc2lsZW50bHkgcmV0dXJuIHplcm8gcm93cyDigJQgYSB0cmFwIGZvciB0aGUgZmlyc3QgY2FsbGVyIHRvIHBhc3Mgb25lLlxuICBpZiAoQXJyYXkuaXNBcnJheShpZCkpIHtcbiAgICBjb25zdCBwYXJ0cyA9IGlkXG4gICAgICAubWFwKChvbmUpID0+IGJ1aWxkSWRDb25kaXRpb24oaWRDb2x1bW4sIG9uZSkpXG4gICAgICAuZmlsdGVyKChjKTogYyBpcyBTUUwgPT4gYyAhPT0gbnVsbCk7XG4gICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHBhcnRzLmxlbmd0aCA9PT0gMSA/IHBhcnRzWzBdIDogKG9yKC4uLnBhcnRzKSBhcyBTUUwpO1xuICB9XG5cbiAgY29uc3QgaWRTdHJpbmcgPSBTdHJpbmcoaWQpLnRvTG93ZXJDYXNlKCk7XG4gIGlmIChGVUxMX1VVSUQudGVzdChpZFN0cmluZykpIHtcbiAgICByZXR1cm4gZXEoaWRDb2x1bW4sIGlkU3RyaW5nKTtcbiAgfVxuICAvLyBFc2NhcGUgU1FMIExJS0Ugd2lsZGNhcmRzIHRvIHByZXZlbnQgd2lsZGNhcmQgaW5qZWN0aW9uXG4gIGNvbnN0IGVzY2FwZWQgPSBlc2NhcGVMaWtlV2lsZGNhcmRzKGlkU3RyaW5nKTtcbiAgcmV0dXJuIHNxbGAke2lkQ29sdW1ufTo6dGV4dCBMSUtFICR7ZXNjYXBlZCArICclJ30gRVNDQVBFICdcXFxcJ2A7XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIGBpc0RlZmF1bHRgIC8gYGlzQWN0aXZlYCBwcmVkaWNhdGVzIHNoYXJlZCBieSBldmVyeSBjYXRhbG9nIGVudGl0eS5cbiAqIGBpc0FjdGl2ZWAgZGVmYXVsdHMgdG8gdHJ1ZSBzbyBzb2Z0LWRlbGV0ZWQgcm93cyBzdGF5IG91dCBvZiBub3JtYWwgcmVhZHMuXG4gKiBTdGFuZGFsb25lIGZvciB0aGUgc2FtZSByZWFzb24gYXMge0BsaW5rIGJ1aWxkSWRDb25kaXRpb259LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRCb29sZWFuQ29uZGl0aW9ucyhcbiAgY29sdW1uczogeyBpc0RlZmF1bHQ6IEFueUNvbHVtbjsgaXNBY3RpdmU6IEFueUNvbHVtbiB9LFxuICBmaWx0ZXI6IHsgaXNEZWZhdWx0PzogdW5rbm93bjsgaXNBY3RpdmU/OiB1bmtub3duIH0sXG4pOiBTUUxbXSB7XG4gIGNvbnN0IGNvbmRpdGlvbnM6IFNRTFtdID0gW107XG5cbiAgaWYgKGZpbHRlci5pc0RlZmF1bHQgIT09IHVuZGVmaW5lZCkge1xuICAgIGNvbmRpdGlvbnMucHVzaChlcShjb2x1bW5zLmlzRGVmYXVsdCwgcGFyc2VCb29sZWFuRmlsdGVyKGZpbHRlci5pc0RlZmF1bHQpKSk7XG4gIH1cblxuICBpZiAoZmlsdGVyLmlzQWN0aXZlICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25kaXRpb25zLnB1c2goZXEoY29sdW1ucy5pc0FjdGl2ZSwgcGFyc2VCb29sZWFuRmlsdGVyKGZpbHRlci5pc0FjdGl2ZSkpKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBEZWZhdWx0IHRvIGFjdGl2ZSByZWNvcmRzIG9ubHkgdG8gZXhjbHVkZSBzb2Z0LWRlbGV0ZWQgZW50aXRpZXNcbiAgICBjb25kaXRpb25zLnB1c2goZXEoY29sdW1ucy5pc0FjdGl2ZSwgdHJ1ZSkpO1xuICB9XG5cbiAgcmV0dXJuIGNvbmRpdGlvbnM7XG59XG5cbi8qKlxuICogU2NoZW1hIHRhYmxlIGludGVyZmFjZSBmb3IgYWNjZXNzIGNvbnRyb2wgcXVlcmllcy4gRXZlcnkgY2F0YWxvZyBlbnRpdHlcbiAqIGNhcnJpZXMgdGhlIHNhbWUgZml2ZSBjb2x1bW5zLCB3aGljaCBpcyB3aGF0IGxldHMgT05FIHByZWRpY2F0ZSBzZXJ2ZVxuICogcGlwZWxpbmVzLCBwbHVnaW5zIGFuZCB0ZW1wbGF0ZXMgYWxpa2UuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQWNjZXNzQ29udHJvbFNjaGVtYSB7XG4gIGlkOiBBbnlDb2x1bW47XG4gIG9yZ0lkOiBBbnlDb2x1bW47XG4gIC8qKiBUaHJlZS1ydW5nIHNoYXJpbmcgbGFkZGVyIOKAlCBzZWUgYXBpLWNvcmUncyBgVmlzaWJpbGl0eWAuICovXG4gIHZpc2liaWxpdHk6IEFueUNvbHVtbjtcbiAgLyoqIEF1dGhvci4gT3ducyB0aGUgYHByaXZhdGVgIHJ1bmcuICovXG4gIGNyZWF0ZWRCeTogQW55Q29sdW1uO1xuICBpc0RlZmF1bHQ6IEFueUNvbHVtbjtcbiAgaXNBY3RpdmU6IEFueUNvbHVtbjtcbn1cblxuLyoqXG4gKiBCYXNlIGZpbHRlciBpbnRlcmZhY2Ugd2l0aCBjb21tb24gYWNjZXNzIGNvbnRyb2wgZmllbGRzLlxuICpcbiAqIGB2aWV3ZXJVc2VySWRgIC8gYHZpZXdlcklzU3VwZXJBZG1pbmAgYXJlIFNFUlZFUi1TRVQgKHN0YW1wZWQgZnJvbSB0aGUgcmVxdWVzdCdzXG4gKiB0ZW5hbnQgY29udGV4dCBieSBgd2l0aFZpZXdlckNvbnRleHRgKSwgbmV2ZXIgY2xpZW50LXN1cHBsaWVkIOKAlCBzZWVcbiAqIGB2aWV3ZXItY29udGV4dC50c2AgZm9yIHdoeSB0aGUgdGVuYW50IGNvbnRleHQgaXMgdGhlIGNoYW5uZWwuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmFzZUFjY2Vzc0ZpbHRlciB7XG4gIGlkPzogc3RyaW5nIHwgc3RyaW5nW107XG4gIHZpc2liaWxpdHk/OiBzdHJpbmc7XG4gIGlzRGVmYXVsdD86IGJvb2xlYW4gfCBzdHJpbmc7XG4gIGlzQWN0aXZlPzogYm9vbGVhbiB8IHN0cmluZztcbiAgdmlld2VyVXNlcklkPzogc3RyaW5nO1xuICB2aWV3ZXJJc1N1cGVyQWRtaW4/OiBib29sZWFuO1xufVxuXG4vKiogRmFpbC1jbG9zZWQgcHJlZGljYXRlOiBtYXRjaGVzIG5vIHJvd3MuICovXG5jb25zdCBOT19ST1dTOiBTUUwgPSBzcWxgZmFsc2VgO1xuXG4vKiogUGVyLWVudGl0eSB0dW5pbmcgb2Yge0BsaW5rIEFjY2Vzc0NvbnRyb2xRdWVyeUJ1aWxkZXJ9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBBY2Nlc3NDb250cm9sT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBTWVNURU0gb3JnJ3MgYHB1YmxpY2AgcnVuZyByZWFjaGVzIGNhbGxlcnMgaW4gb3RoZXIgb3JncyAoYW5kXG4gICAqIGFub255bW91cyBjYWxsZXJzKS4gRGVmYXVsdCB0cnVlOiB0aGUgc3lzdGVtIG9yZydzIHNhbXBsZSBwaXBlbGluZXMsXG4gICAqIHRlbXBsYXRlcyBhbmQgZGFzaGJvYXJkcyBhcmUgdmlzaWJsZSBmcm9tIGV2ZXJ5IG9yZy4gUGx1Z2lucyBzZXQgaXQgZmFsc2U6XG4gICAqIHNpbmNlIHRoZSBwbHVnaW4gZWNvc3lzdGVtIHRoZSBPZmZpY2lhbCBjYXRhbG9nIHJlYWNoZXNcbiAgICogb3RoZXIgb3JncyBvbmx5IGFzIExJU1RJTkdTIHJlc29sdmVkIHRocm91Z2ggaW5zdGFsbHMsIG5ldmVyIHRocm91Z2hcbiAgICogYHZpc2liaWxpdHkgPSAncHVibGljJ2Agb24gYSBgcGx1Z2luc2Agcm93LlxuICAgKi9cbiAgc3lzdGVtQ2F0YWxvZz86IGJvb2xlYW47XG59XG5cbi8qKlxuICogR2VuZXJpYyBhY2Nlc3MgY29udHJvbCBxdWVyeSBidWlsZGVyIGZvciBtdWx0aS10ZW5hbnQgZW50aXRpZXMuXG4gKlxuICogQ29uc29saWRhdGVzIGR1cGxpY2F0ZSBhY2Nlc3MgY29udHJvbCBsb2dpYyBzaGFyZWQgYWNyb3NzIHBpcGVsaW5lIGFuZCBwbHVnaW4gcXVlcmllcy5cbiAqIEhhbmRsZXM6XG4gKiAtIE11bHRpLXRlbmFudCBhY2Nlc3MgY29udHJvbCAocHVibGljL3ByaXZhdGUvb3JnLWFuZC1wdWJsaWMpXG4gKiAtIFVVSUQgcHJlZml4IG1hdGNoaW5nIGZvciBJRCBmaWx0ZXJzXG4gKiAtIEJvb2xlYW4gZmllbGQgbm9ybWFsaXphdGlvblxuICpcbiAqIEB0eXBlUGFyYW0gVFNjaGVtYSAtIFNjaGVtYSB0YWJsZSB0eXBlIHdpdGggYWNjZXNzIGNvbnRyb2wgZmllbGRzXG4gKiBAdHlwZVBhcmFtIFRGaWx0ZXIgLSBGaWx0ZXIgdHlwZSBleHRlbmRpbmcgQmFzZUFjY2Vzc0ZpbHRlclxuICovXG5leHBvcnQgY2xhc3MgQWNjZXNzQ29udHJvbFF1ZXJ5QnVpbGRlcjxcbiAgVFNjaGVtYSBleHRlbmRzIEFjY2Vzc0NvbnRyb2xTY2hlbWEsXG4gIFRGaWx0ZXIgZXh0ZW5kcyBCYXNlQWNjZXNzRmlsdGVyLFxuPiB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgc2NoZW1hOiBUU2NoZW1hLFxuICAgIHByaXZhdGUgb3B0aW9uczogQWNjZXNzQ29udHJvbE9wdGlvbnMgPSB7fSxcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBCdWlsZCB0aGUgY2FsbGVyJ3MgdmlzaWJsZSBzbGljZSBvZiBhIGNhdGFsb2csIGZyb20gdGhlIHRocmVlLXJ1bmdcbiAgICogYHZpc2liaWxpdHlgIGxhZGRlciBzaGFyZWQgYnkgZXZlcnkgY2F0YWxvZyBlbnRpdHkuXG4gICAqXG4gICAqIEVmZmVjdGl2ZSByZWFkIHNldCBmb3IgYSBjYWxsZXIgaW4gb3JnIGBPYCBhcyB1c2VyIGBWYCB3aG9zZSBwYXJlbnQgb3JnIGlzIGBQYDpcbiAgICpcbiAgICogICAob3JnX2lkID0gTyBBTkQgKHZpc2liaWxpdHkgPD4gJ3ByaXZhdGUnIE9SIGNyZWF0ZWRfYnkgPSBWKSlcbiAgICogICBPUiAodmlzaWJpbGl0eSA9ICdwdWJsaWMnIEFORCAob3JnX2lkID0gJ3N5c3RlbScgT1Igb3JnX2lkID0gUCkpXG4gICAqXG4gICAqIGkuZS4geW91ciBvd24gb3JnJ3Mgc2hhcmVkIHJ1bmdzIHBsdXMgeW91ciBvd24gZHJhZnRzLCB3aWRlbmVkIGJ5IHRoZSBzeXN0ZW1cbiAgICogb3JnJ3MgcHVibGljIGNhdGFsb2cgKHRoZSBzdGFuZGluZyBcInN5c3RlbS1vcmcgY29udGVudCBpcyB2aXNpYmxlIGZyb20gZXZlcnlcbiAgICogb3JnXCIgcnVsZSkgYW5kIOKAlCBmb3IgYSB0ZWFtIOKAlCBpdHMgcGFyZW50J3MgcHVibGljIHJvd3MuIFRoZSBgcHVibGljYC1vbmx5XG4gICAqIHJlc3RyaWN0aW9uIGFwcGxpZXMgc29sZWx5IHRvIHRob3NlIE9USEVSIG9yZ3MnIHJvd3M7IHdpdGhpbiB5b3VyIG93biBvcmcgeW91XG4gICAqIGFsd2F5cyBzZWUgZXZlcnl0aGluZyB5b3UgYXJlIGVudGl0bGVkIHRvLCBvciBhIGZyZXNobHktY3JlYXRlZCBwcml2YXRlIHJvd1xuICAgKiB3b3VsZCB2YW5pc2ggZnJvbSBpdHMgb3duIGF1dGhvcidzIGxpc3RpbmcuXG4gICAqXG4gICAqIEFuIGVudGl0eSBjYW4gZHJvcCB0aGUgc3lzdGVtLW9yZyBicmFuY2ggd2l0aCBgc3lzdGVtQ2F0YWxvZzogZmFsc2VgXG4gICAqICh7QGxpbmsgQWNjZXNzQ29udHJvbE9wdGlvbnN9KTogcGx1Z2lucyBkbywgc28gYSBzeXN0ZW0tb3JnIHBsdWdpbiByZWFjaGVzXG4gICAqIG90aGVyIG9yZ3Mgb25seSBhcyBhbiBPZmZpY2lhbCBsaXN0aW5nLlxuICAgKlxuICAgKiBBbiBleHBsaWNpdCBgdmlzaWJpbGl0eWAgZmlsdGVyIE5BUlJPV1Mgd2l0aGluIHRoYXQgc2V0LCBuZXZlciB3aWRlbnMgaXQg4oCUXG4gICAqIHNvIGA/dmlzaWJpbGl0eT1wdWJsaWNgIHN0aWxsIHN1cmZhY2VzIHRoZSBzeXN0ZW0tb3JnIGNhdGFsb2cuXG4gICAqXG4gICAqIEZhaWxzIENMT1NFRCBvbiBib3RoIGF4ZXM6IG5vIGBvcmdJZGAgKGFub255bW91cykg4oeSIHN5c3RlbS1vcmcgcHVibGljIG9ubHk7XG4gICAqIG5vIGB2aWV3ZXJVc2VySWRgIOKHkiB0aGUgcHJpdmF0ZSBydW5nIG1hdGNoZXMgbm90aGluZyByYXRoZXIgdGhhbiBldmVyeXRoaW5nLlxuICAgKiBgdmlld2VySXNTdXBlckFkbWluYCBsaWZ0cyB0aGUgcHJpdmF0ZSBydW5nIG9ubHkg4oCUIGEgcGxhdGZvcm0gb3BlcmF0b3JcbiAgICogYWRtaW5pc3RlcnMgdGhlIHdob2xlIGNhdGFsb2cuXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXIgLSBGaWx0ZXIgY3JpdGVyaWFcbiAgICogQHBhcmFtIG9yZ0lkIC0gVXNlcidzIG9yZ2FuaXphdGlvbiBJRCAob3B0aW9uYWwpXG4gICAqIEBwYXJhbSBwYXJlbnRPcmdJZCAtIFBhcmVudCBvcmcgSUQgd2hlbiB0aGUgY2FsbGVyIGlzIGEgdGVhbSAob3B0aW9uYWwpXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIFNRTCBjb25kaXRpb25zIGZvciBhY2Nlc3MgY29udHJvbFxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkQWNjZXNzQ29udHJvbChmaWx0ZXI6IFBhcnRpYWw8VEZpbHRlcj4sIG9yZ0lkPzogc3RyaW5nLCBwYXJlbnRPcmdJZD86IHN0cmluZyk6IFNRTFtdIHtcbiAgICBjb25zdCBjb25kaXRpb25zOiBTUUxbXSA9IFtdO1xuICAgIGNvbnN0IHJlcXVlc3RlZCA9IGZpbHRlci52aXNpYmlsaXR5O1xuXG4gICAgY29uc3Qgc3lzdGVtQ2F0YWxvZyA9IHRoaXMub3B0aW9ucy5zeXN0ZW1DYXRhbG9nICE9PSBmYWxzZTtcblxuICAgIGlmICghb3JnSWQpIHtcbiAgICAgIC8vIE5vIG9yZyBjb250ZXh0IOKAlCBvbmx5IHRoZSBzeXN0ZW0gb3JnJ3MgcHVibGljIGNhdGFsb2cgKG5vdGhpbmcgYXQgYWxsXG4gICAgICAvLyBmb3IgYW4gZW50aXR5IHdpdGhvdXQgb25lKS5cbiAgICAgIGlmICghc3lzdGVtQ2F0YWxvZykgcmV0dXJuIFtOT19ST1dTXTtcbiAgICAgIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLnNjaGVtYS5vcmdJZCwgU1lTVEVNX09SR19JRCkpO1xuICAgICAgY29uZGl0aW9ucy5wdXNoKGVxKHRoaXMuc2NoZW1hLnZpc2liaWxpdHksICdwdWJsaWMnKSk7XG4gICAgICAvLyBBbiBhbm9ueW1vdXMgY2FsbGVyIGFza2luZyBmb3IgYSBuYXJyb3dlciBydW5nIGdldHMgbm90aGluZywgcmF0aGVyIHRoYW5cbiAgICAgIC8vIGhhdmluZyB0aGUgbmFycm93aW5nIHNpbGVudGx5IGlnbm9yZWQuXG4gICAgICBpZiAocmVxdWVzdGVkICE9PSB1bmRlZmluZWQgJiYgcmVxdWVzdGVkICE9PSAncHVibGljJykgY29uZGl0aW9ucy5wdXNoKE5PX1JPV1MpO1xuICAgICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gICAgfVxuXG4gICAgY29uc3Qgbm9ybWFsaXplZE9yZ0lkID0gb3JnSWQudG9Mb3dlckNhc2UoKTtcblxuICAgIC8vIE93bi1vcmcgcm93czogZXZlcnl0aGluZyBFWENFUFQgb3RoZXIgcGVvcGxlJ3MgcHJpdmF0ZSBkcmFmdHMuXG4gICAgY29uc3Qgb3duRHJhZnRzT25seSA9IGZpbHRlci52aWV3ZXJVc2VySWQgPyBlcSh0aGlzLnNjaGVtYS5jcmVhdGVkQnksIGZpbHRlci52aWV3ZXJVc2VySWQpIDogTk9fUk9XUztcbiAgICBjb25zdCBvd25PcmcgPSBmaWx0ZXIudmlld2VySXNTdXBlckFkbWluXG4gICAgICA/IGVxKHRoaXMuc2NoZW1hLm9yZ0lkLCBub3JtYWxpemVkT3JnSWQpXG4gICAgICA6IGFuZChlcSh0aGlzLnNjaGVtYS5vcmdJZCwgbm9ybWFsaXplZE9yZ0lkKSwgb3IobmUodGhpcy5zY2hlbWEudmlzaWJpbGl0eSwgJ3ByaXZhdGUnKSwgb3duRHJhZnRzT25seSkhKSE7XG5cbiAgICAvLyBSb3dzIGZyb20gT1RIRVIgb3JncyBhcmUgb25seSBldmVyIHZpc2libGUgYXQgdGhlIGBwdWJsaWNgIHJ1bmcuXG4gICAgY29uc3Qgb3RoZXJPcmdTY29wZXM6IFNRTFtdID0gW107XG4gICAgaWYgKHN5c3RlbUNhdGFsb2cpIG90aGVyT3JnU2NvcGVzLnB1c2goZXEodGhpcy5zY2hlbWEub3JnSWQsIFNZU1RFTV9PUkdfSUQpKTtcbiAgICBpZiAocGFyZW50T3JnSWQpIG90aGVyT3JnU2NvcGVzLnB1c2goZXEodGhpcy5zY2hlbWEub3JnSWQsIHBhcmVudE9yZ0lkLnRvTG93ZXJDYXNlKCkpKTtcbiAgICBjb25kaXRpb25zLnB1c2gob3RoZXJPcmdTY29wZXMubGVuZ3RoID4gMFxuICAgICAgPyBvcihvd25PcmcsIGFuZChlcSh0aGlzLnNjaGVtYS52aXNpYmlsaXR5LCAncHVibGljJyksIG9yKC4uLm90aGVyT3JnU2NvcGVzKSEpISkhXG4gICAgICA6IG93bk9yZyk7XG5cbiAgICBpZiAocmVxdWVzdGVkICE9PSB1bmRlZmluZWQpIGNvbmRpdGlvbnMucHVzaChlcSh0aGlzLnNjaGVtYS52aXNpYmlsaXR5LCByZXF1ZXN0ZWQpKTtcblxuICAgIHJldHVybiBjb25kaXRpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIElEIGZpbHRlciB3aXRoIFVVSUQgcHJlZml4IG1hdGNoaW5nIHN1cHBvcnRcbiAgICpcbiAgICogLSBGdWxsIFVVSUQ6IEV4YWN0IG1hdGNoXG4gICAqIC0gUGFydGlhbCBVVUlEOiBQcmVmaXggbWF0Y2ggdXNpbmcgU1FMIExJS0VcbiAgICpcbiAgICogQHBhcmFtIGlkIC0gSUQgZmlsdGVyIHZhbHVlIChmdWxsIG9yIHBhcnRpYWwgVVVJRClcbiAgICogQHJldHVybnMgU1FMIGNvbmRpdGlvbiBvciBudWxsIGlmIG5vIElEIGZpbHRlclxuICAgKi9cbiAgcHJvdGVjdGVkIGJ1aWxkSWRGaWx0ZXIoaWQ6IHVua25vd24pOiBTUUwgfCBudWxsIHtcbiAgICByZXR1cm4gYnVpbGRJZENvbmRpdGlvbih0aGlzLnNjaGVtYS5pZCwgaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGJvb2xlYW4gZmllbGQgY29uZGl0aW9ucyAoaXNEZWZhdWx0LCBpc0FjdGl2ZSlcbiAgICpcbiAgICogQHBhcmFtIGZpbHRlciAtIEZpbHRlciBjcml0ZXJpYVxuICAgKiBAcmV0dXJucyBBcnJheSBvZiBTUUwgY29uZGl0aW9ucyBmb3IgYm9vbGVhbiBmaWVsZHNcbiAgICovXG4gIHByb3RlY3RlZCBidWlsZEJvb2xlYW5GaWx0ZXJzKGZpbHRlcjogUGFydGlhbDxURmlsdGVyPik6IFNRTFtdIHtcbiAgICByZXR1cm4gYnVpbGRCb29sZWFuQ29uZGl0aW9ucyh0aGlzLnNjaGVtYSwgZmlsdGVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBhbGwgY29tbW9uIGNvbmRpdGlvbnMgKGFjY2VzcyBjb250cm9sICsgSUQgKyBib29sZWFucylcbiAgICpcbiAgICogVGhpcyBjb21iaW5lcyBhbGwgdGhlIGdlbmVyaWMgZmlsdGVycyB0aGF0IGFwcGx5IHRvIGFueSBhY2Nlc3MtY29udHJvbGxlZCBlbnRpdHkuXG4gICAqIFN1YmNsYXNzZXMgc2hvdWxkIGNhbGwgdGhpcyBhbmQgYWRkIGVudGl0eS1zcGVjaWZpYyBjb25kaXRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0gZmlsdGVyIC0gRmlsdGVyIGNyaXRlcmlhXG4gICAqIEBwYXJhbSBvcmdJZCAtIFVzZXIncyBvcmdhbml6YXRpb24gSUQgKG9wdGlvbmFsIOKAlCBmYWxscyBiYWNrIHRvIHN5c3RlbS1wdWJsaWMtb25seSlcbiAgICogQHJldHVybnMgQXJyYXkgb2YgU1FMIGNvbmRpdGlvbnNcbiAgICovXG4gIHB1YmxpYyBidWlsZENvbW1vbkNvbmRpdGlvbnMoZmlsdGVyOiBQYXJ0aWFsPFRGaWx0ZXI+LCBvcmdJZD86IHN0cmluZywgcGFyZW50T3JnSWQ/OiBzdHJpbmcpOiBTUUxbXSB7XG4gICAgY29uc3QgY29uZGl0aW9uczogU1FMW10gPSBbXTtcblxuICAgIC8vIEFjY2VzcyBjb250cm9sIChtdWx0aS10ZW5hbnQpIOKAlCBoYW5kbGVzIHZpc2liaWxpdHkgaW50ZXJuYWxseVxuICAgIGNvbmRpdGlvbnMucHVzaCguLi50aGlzLmJ1aWxkQWNjZXNzQ29udHJvbChmaWx0ZXIsIG9yZ0lkLCBwYXJlbnRPcmdJZCkpO1xuXG4gICAgLy8gSUQgZmlsdGVyIHdpdGggcHJlZml4IG1hdGNoaW5nXG4gICAgY29uc3QgaWRDb25kaXRpb24gPSB0aGlzLmJ1aWxkSWRGaWx0ZXIoZmlsdGVyLmlkKTtcbiAgICBpZiAoaWRDb25kaXRpb24pIGNvbmRpdGlvbnMucHVzaChpZENvbmRpdGlvbik7XG5cbiAgICAvLyBCb29sZWFuIGZpbHRlcnNcbiAgICBjb25kaXRpb25zLnB1c2goLi4udGhpcy5idWlsZEJvb2xlYW5GaWx0ZXJzKGZpbHRlcikpO1xuXG4gICAgcmV0dXJuIGNvbmRpdGlvbnM7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -66,15 +66,47 @@ export interface PaginatedResult<T> {
|
|
|
66
66
|
* soft-delete paths (e.g. platform's hand-rolled dashboard/alert services)
|
|
67
67
|
* stamp `purge_after` with the SAME window the CrudService entities use. */
|
|
68
68
|
export declare function softDeleteRetentionMs(): number;
|
|
69
|
+
/**
|
|
70
|
+
* Abstract CRUD service with multi-tenant access control and pagination.
|
|
71
|
+
*
|
|
72
|
+
* Subclasses bind to a specific Drizzle table by implementing `schema`,
|
|
73
|
+
* `buildConditions`, `getSortColumn`, and the org/project-column accessors.
|
|
74
|
+
*
|
|
75
|
+
* @typeParam TEntity - Entity type extending BaseEntity
|
|
76
|
+
* @typeParam TFilter - Filter type for query parameters
|
|
77
|
+
* @typeParam TInsert - Insert DTO type
|
|
78
|
+
* @typeParam TUpdate - Update DTO type
|
|
79
|
+
*
|
|
80
|
+
* **A note on the type casts.** Drizzle's row types are inferred from
|
|
81
|
+
* `pgTable(...)` and don't generically narrow through the abstract `schema`
|
|
82
|
+
* getter, so the base class casts query results to `TEntity` and back. The
|
|
83
|
+
* cast is *not* a runtime safety guarantee — it relies on each subclass
|
|
84
|
+
* passing the matching entity type. Org-scoping is enforced by every
|
|
85
|
+
* subclass's `buildConditions` injecting `WHERE org_id = $1`; this class
|
|
86
|
+
* does not add that filter itself.
|
|
87
|
+
*
|
|
88
|
+
* **Error policy.** Errors propagate up to the route-level handler
|
|
89
|
+
* (`withRoute`); no catch-and-swallow here.
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* class PipelineService extends CrudService<Pipeline, PipelineFilter, PipelineInsert, PipelineUpdate> {
|
|
94
|
+
* protected get schema() { return schema.pipeline; }
|
|
95
|
+
* protected buildConditions(filter, orgId) { return buildPipelineConditions(filter, orgId); }
|
|
96
|
+
* protected getSortColumn(sortBy) { return Object.hasOwn(sortColumnMap, sortBy) ? sortColumnMap[sortBy] : null; }
|
|
97
|
+
* protected getProjectColumn() { return schema.pipeline.project; }
|
|
98
|
+
* protected getOrgColumn() { return schema.pipeline.orgId; }
|
|
99
|
+
* }
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
69
102
|
export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, TInsert, TUpdate> {
|
|
70
103
|
/** Drizzle schema table for this entity */
|
|
71
104
|
protected abstract get schema(): PgTable;
|
|
72
105
|
/**
|
|
73
106
|
* Typed column view of {@link schema}. `PgTable` exposes no static columns, so
|
|
74
|
-
* the
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* and the index signature covers dynamic sparse-fieldset column lookup.
|
|
107
|
+
* this is the single unavoidable cast for column access. `visibility` is
|
|
108
|
+
* optional (not every entity has it) and the index signature covers dynamic
|
|
109
|
+
* sparse-fieldset column lookup.
|
|
78
110
|
*/
|
|
79
111
|
private get cols();
|
|
80
112
|
/**
|
|
@@ -102,6 +134,16 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
|
|
|
102
134
|
* hierarchy) — same opt-in semantics as `find`/`findPaginated`. Omitted by the
|
|
103
135
|
* write path (`writeConditions`), which must stay own-org scoped. */
|
|
104
136
|
private idConditions;
|
|
137
|
+
/**
|
|
138
|
+
* Excludes soft-deleted tombstones on entities with a `deletedAt` column. The
|
|
139
|
+
* by-id filter deliberately skips the `isActive` default (a deactivated row is
|
|
140
|
+
* still readable by id), so without this a tombstone would be readable and —
|
|
141
|
+
* through `update` — half-revivable (`isActive` flipped back while
|
|
142
|
+
* `deletedAt`/`purgeAfter` stay set, so the sweep later purges a row the UI
|
|
143
|
+
* shows as live). Tombstones are reached only via the dedicated
|
|
144
|
+
* restore/purge/findDeleted paths.
|
|
145
|
+
*/
|
|
146
|
+
private notTombstoned;
|
|
105
147
|
/**
|
|
106
148
|
* Conditions for a MUTATION (update/delete) of a single entity.
|
|
107
149
|
*
|
|
@@ -117,6 +159,25 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
|
|
|
117
159
|
* `schema` is typed `PgTable` (no static `.id`), so cast — same pattern the
|
|
118
160
|
* sort/default helpers use for column access. */
|
|
119
161
|
private exactIdCondition;
|
|
162
|
+
/** The actor stamped on a write: the caller, or the system actor for background work. */
|
|
163
|
+
private actor;
|
|
164
|
+
/**
|
|
165
|
+
* The one cast point for `.set()` / `.values()` / `.select()` shapes. The base class writes
|
|
166
|
+
* the shared columns (`updatedBy`, `deletedAt`, …) through the abstract
|
|
167
|
+
* `PgTable`, whose insert/update types can't prove those columns exist.
|
|
168
|
+
*/
|
|
169
|
+
private row;
|
|
170
|
+
/** Run a lifecycle hook best-effort: a failure is logged, never thrown. */
|
|
171
|
+
private runHook;
|
|
172
|
+
/** The columns a soft-delete stamps, including the purge deadline. */
|
|
173
|
+
private tombstoneSet;
|
|
174
|
+
/**
|
|
175
|
+
* Hard-delete up to `limit` rows matching `conditions` in one transaction:
|
|
176
|
+
* dependents are torn down first by `onBeforePurge` in the SAME tx (a
|
|
177
|
+
* FK-blocking child can't strand the parent; a throw aborts the batch), then
|
|
178
|
+
* `onAfterPurge` handles external side-effects best-effort. Returns the ids.
|
|
179
|
+
*/
|
|
180
|
+
private purgeWhere;
|
|
120
181
|
/** Called after a new entity is created */
|
|
121
182
|
protected onAfterCreate(_entity: TEntity, _userId: string): Promise<void>;
|
|
122
183
|
/** Called after an entity is updated */
|
|
@@ -171,10 +232,18 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
|
|
|
171
232
|
* @param orgId - User's organization ID (optional — omit for anonymous/system-public-only access)
|
|
172
233
|
*/
|
|
173
234
|
find(filter: Partial<TFilter>, orgId?: string, parentOrgId?: string): Promise<TEntity[]>;
|
|
235
|
+
/**
|
|
236
|
+
* ORDER BY for {@link findFirst}, so "take one" is deterministic rather than
|
|
237
|
+
* whatever row the planner meets first: the default row, then the newest,
|
|
238
|
+
* then id as the final tiebreak. Services override it to rank by their own
|
|
239
|
+
* notion of "best match" (plugins: own org first, then semver).
|
|
240
|
+
*/
|
|
241
|
+
protected findFirstOrderBy(_filter: Partial<TFilter>, _orgId?: string, _parentOrgId?: string): SQL[];
|
|
174
242
|
/**
|
|
175
243
|
* Find the FIRST entity matching `filter` — a bounded (`LIMIT 1`) variant of
|
|
176
244
|
* `find` for the "match by filter, take one" read paths (e.g. `GET /find`), so
|
|
177
|
-
* they don't `SELECT` every matching org row just to return `[0]`.
|
|
245
|
+
* they don't `SELECT` every matching org row just to return `[0]`. Ranked by
|
|
246
|
+
* {@link findFirstOrderBy}.
|
|
178
247
|
*/
|
|
179
248
|
findFirst(filter: Partial<TFilter>, orgId?: string, parentOrgId?: string): Promise<TEntity | null>;
|
|
180
249
|
/**
|
|
@@ -218,9 +287,8 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
|
|
|
218
287
|
*/
|
|
219
288
|
findById(id: string, orgId?: string, parentOrgId?: string): Promise<TEntity | null>;
|
|
220
289
|
/**
|
|
221
|
-
* Defense-in-depth tenant stamp
|
|
222
|
-
*
|
|
223
|
-
* its OWN org, so pin the row to the trusted tenant-context org.
|
|
290
|
+
* Defense-in-depth tenant stamp alongside RLS: a NON-sysadmin caller may only
|
|
291
|
+
* write into its OWN org, so pin the row to the trusted tenant-context org.
|
|
224
292
|
*
|
|
225
293
|
* The stamp fires whenever the payload's `orgId` differs from the context org —
|
|
226
294
|
* which covers BOTH a forged/mismatched `data.orgId` AND an ABSENT one. The
|
|
@@ -271,15 +339,8 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
|
|
|
271
339
|
bulkDelete(ids: string[], orgId: string, userId: string,
|
|
272
340
|
/**
|
|
273
341
|
* The caller's authority on the three-rung `visibility` ladder. Omit (or
|
|
274
|
-
* pass `isSystemAdmin: true`) for an unrestricted delete.
|
|
275
|
-
*
|
|
276
|
-
* This used to be a `restrictToPrivate` boolean that narrowed to
|
|
277
|
-
* `visibility = 'private'`. That encoded the OLD two-state model: since
|
|
278
|
-
* `resolveVisibility` defaults pipelines and plugins to `org`, and
|
|
279
|
-
* single-row delete allows an `org` row with plain `:write`, bulk delete
|
|
280
|
-
* 403'd the normal case — an org admin could delete a pipeline one at a
|
|
281
|
-
* time but not in bulk. The rungs enforced here mirror
|
|
282
|
-
* `requireVisibilityWriteAccess` exactly:
|
|
342
|
+
* pass `isSystemAdmin: true`) for an unrestricted delete. The rungs mirror
|
|
343
|
+
* `requireVisibilityWriteAccess` exactly, so bulk and single-row delete agree:
|
|
283
344
|
* - `private` → author only (`createdBy === userId`)
|
|
284
345
|
* - `org` → any member of the org (plain `:write`)
|
|
285
346
|
* - `public` → requires the entity's publish permission
|
|
@@ -288,19 +349,6 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
|
|
|
288
349
|
isSystemAdmin: boolean;
|
|
289
350
|
canPublish: boolean;
|
|
290
351
|
}): Promise<TEntity[]>;
|
|
291
|
-
/**
|
|
292
|
-
* Restore a soft-deleted (tombstoned) entity: clear `isActive`/`deletedAt`/
|
|
293
|
-
* `deletedBy`/`purgeAfter` so it reappears in normal reads.
|
|
294
|
-
*
|
|
295
|
-
* Matches ONLY a genuine tombstone — `isActive = false` AND `deletedAt IS NOT
|
|
296
|
-
* NULL` — so a merely *deactivated* row (isActive=false, no deletedAt) is never
|
|
297
|
-
* silently "restored". Pinned to the caller's own org (orgId-less sysadmin
|
|
298
|
-
* context spans orgs, matching delete/update). Returns null when there is no
|
|
299
|
-
* such tombstone (already active, purged, or unknown) so the route can 404.
|
|
300
|
-
* A unique-key collision (a live row already holds the key) surfaces as the
|
|
301
|
-
* driver's unique-violation for the route to map to 409 — in practice the
|
|
302
|
-
* tombstone IS the key holder, so this is defensive.
|
|
303
|
-
*/
|
|
304
352
|
/** Conditions matching a GENUINE tombstone (`isActive=false` AND `deletedAt IS
|
|
305
353
|
* NOT NULL`), optionally pinned to `id` and/or `orgId`. Single source of truth
|
|
306
354
|
* for restore/findDeletedById/findDeleted so the "what is a tombstone" rule
|
|
@@ -309,12 +357,9 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
|
|
|
309
357
|
/**
|
|
310
358
|
* The `private` rung, for TOMBSTONE reads and restore.
|
|
311
359
|
*
|
|
312
|
-
* Deleting a row does not declassify it
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
* else's PRIVATE pipelines, plugins and templates — rows the very same member
|
|
316
|
-
* could not read one second before they were deleted. `restore` shared the
|
|
317
|
-
* clause, so they could also bring one back.
|
|
360
|
+
* Deleting a row does not declassify it: without this, the "recently
|
|
361
|
+
* deleted" list (and restore) would expose other members' PRIVATE rows that
|
|
362
|
+
* the same viewer could not read before they were deleted.
|
|
318
363
|
*
|
|
319
364
|
* Mirrors the live read ladder (`visibility <> 'private' OR created_by = V`)
|
|
320
365
|
* rather than the delete ladder: this gates who may SEE a tombstone, and a
|
|
@@ -327,6 +372,19 @@ export declare abstract class CrudService<TEntity extends BaseEntity, TFilter, T
|
|
|
327
372
|
* it runs org-wide under a sysadmin scope and must reach every tombstone.
|
|
328
373
|
*/
|
|
329
374
|
private tombstoneVisibilityConditions;
|
|
375
|
+
/**
|
|
376
|
+
* Restore a soft-deleted (tombstoned) entity: clear `isActive`/`deletedAt`/
|
|
377
|
+
* `deletedBy`/`purgeAfter` so it reappears in normal reads.
|
|
378
|
+
*
|
|
379
|
+
* Matches ONLY a genuine tombstone — `isActive = false` AND `deletedAt IS NOT
|
|
380
|
+
* NULL` — so a merely *deactivated* row (isActive=false, no deletedAt) is never
|
|
381
|
+
* silently "restored". Pinned to the caller's own org (orgId-less sysadmin
|
|
382
|
+
* context spans orgs, matching delete/update). Returns null when there is no
|
|
383
|
+
* such tombstone (already active, purged, or unknown) so the route can 404.
|
|
384
|
+
* A unique-key collision (a live row already holds the key) surfaces as the
|
|
385
|
+
* driver's unique-violation for the route to map to 409 — in practice the
|
|
386
|
+
* tombstone IS the key holder, so this is defensive.
|
|
387
|
+
*/
|
|
330
388
|
restore(id: string, orgId: string, userId: string): Promise<TEntity | null>;
|
|
331
389
|
/**
|
|
332
390
|
* Read a soft-deleted entity by id (the inverse of the default `isActive=true`
|