@atlasauth/backend 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +84 -0
- package/README.md +227 -0
- package/dist/client/activity.d.ts +104 -0
- package/dist/client/activity.js +29 -0
- package/dist/client/activity.js.map +1 -0
- package/dist/client/api-keys.d.ts +100 -0
- package/dist/client/api-keys.js +15 -0
- package/dist/client/api-keys.js.map +1 -1
- package/dist/client/audit-events.d.ts +103 -0
- package/dist/client/audit-events.js +43 -0
- package/dist/client/audit-events.js.map +1 -0
- package/dist/client/billing-plans.d.ts +43 -0
- package/dist/client/billing-plans.js +26 -0
- package/dist/client/billing-plans.js.map +1 -1
- package/dist/client/connectors.d.ts +174 -0
- package/dist/client/connectors.js +54 -0
- package/dist/client/connectors.js.map +1 -0
- package/dist/client/data-subject-requests.d.ts +21 -0
- package/dist/client/data-subject-requests.js +15 -0
- package/dist/client/data-subject-requests.js.map +1 -1
- package/dist/client/design.d.ts +295 -0
- package/dist/client/design.js +76 -0
- package/dist/client/design.js.map +1 -0
- package/dist/client/diagnostics.d.ts +53 -0
- package/dist/client/diagnostics.js +24 -0
- package/dist/client/diagnostics.js.map +1 -0
- package/dist/client/email-addresses.d.ts +22 -0
- package/dist/client/email-addresses.js +17 -0
- package/dist/client/email-addresses.js.map +1 -0
- package/dist/client/entitlement-overrides.d.ts +50 -0
- package/dist/client/entitlement-overrides.js +20 -0
- package/dist/client/entitlement-overrides.js.map +1 -0
- package/dist/client/error.d.ts +34 -0
- package/dist/client/error.js +33 -1
- package/dist/client/error.js.map +1 -1
- package/dist/client/import-export.d.ts +2 -0
- package/dist/client/import-export.js.map +1 -1
- package/dist/client/index.d.ts +461 -16
- package/dist/client/index.js +76 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client/instance.d.ts +54 -0
- package/dist/client/instance.js +18 -0
- package/dist/client/instance.js.map +1 -1
- package/dist/client/invitations.d.ts +14 -0
- package/dist/client/invitations.js +9 -0
- package/dist/client/invitations.js.map +1 -1
- package/dist/client/legacy-auth.d.ts +45 -0
- package/dist/client/legacy-auth.js +18 -0
- package/dist/client/legacy-auth.js.map +1 -0
- package/dist/client/mcp.d.ts +86 -0
- package/dist/client/mcp.js +47 -0
- package/dist/client/mcp.js.map +1 -0
- package/dist/client/notifications.d.ts +92 -0
- package/dist/client/notifications.js +55 -0
- package/dist/client/notifications.js.map +1 -0
- package/dist/client/oauth-clients.d.ts +46 -2
- package/dist/client/oauth-clients.js +4 -0
- package/dist/client/oauth-clients.js.map +1 -1
- package/dist/client/oauth-providers.d.ts +67 -7
- package/dist/client/oauth-providers.js +7 -2
- package/dist/client/oauth-providers.js.map +1 -1
- package/dist/client/openfga.d.ts +137 -0
- package/dist/client/openfga.js +72 -0
- package/dist/client/openfga.js.map +1 -0
- package/dist/client/org-ldap-connections.d.ts +75 -0
- package/dist/client/org-ldap-connections.js +36 -0
- package/dist/client/org-ldap-connections.js.map +1 -0
- package/dist/client/organization-settings-schema.d.ts +24 -0
- package/dist/client/organization-settings-schema.js +30 -0
- package/dist/client/organization-settings-schema.js.map +1 -0
- package/dist/client/organizations.d.ts +205 -4
- package/dist/client/organizations.js +109 -0
- package/dist/client/organizations.js.map +1 -1
- package/dist/client/pca.d.ts +59 -0
- package/dist/client/pca.js +40 -0
- package/dist/client/pca.js.map +1 -0
- package/dist/client/platform.d.ts +328 -0
- package/dist/client/platform.js +187 -0
- package/dist/client/platform.js.map +1 -0
- package/dist/client/redirect-urls.d.ts +23 -0
- package/dist/client/redirect-urls.js +22 -0
- package/dist/client/redirect-urls.js.map +1 -0
- package/dist/client/request.d.ts +45 -0
- package/dist/client/request.js +35 -2
- package/dist/client/request.js.map +1 -1
- package/dist/client/session-exchange-apps.d.ts +43 -0
- package/dist/client/session-exchange-apps.js +25 -0
- package/dist/client/session-exchange-apps.js.map +1 -0
- package/dist/client/sessions.d.ts +28 -0
- package/dist/client/sessions.js +20 -0
- package/dist/client/sessions.js.map +1 -1
- package/dist/client/sign-in-tokens.d.ts +13 -1
- package/dist/client/sign-in-tokens.js +11 -0
- package/dist/client/sign-in-tokens.js.map +1 -1
- package/dist/client/test-mode.d.ts +44 -0
- package/dist/client/test-mode.js +26 -0
- package/dist/client/test-mode.js.map +1 -0
- package/dist/client/tickets.d.ts +49 -0
- package/dist/client/tickets.js +19 -0
- package/dist/client/tickets.js.map +1 -0
- package/dist/client/users.d.ts +351 -0
- package/dist/client/users.js +228 -0
- package/dist/client/users.js.map +1 -1
- package/dist/client/waitlist.d.ts +21 -0
- package/dist/client/waitlist.js +16 -0
- package/dist/client/waitlist.js.map +1 -1
- package/dist/client/webhooks.d.ts +60 -6
- package/dist/client/webhooks.js +36 -2
- package/dist/client/webhooks.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/logout-token.d.ts +97 -0
- package/dist/logout-token.js +182 -0
- package/dist/logout-token.js.map +1 -0
- package/dist/verify.d.ts +7 -0
- package/dist/verify.js +13 -0
- package/dist/verify.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { type RequestFn } from './request';
|
|
2
|
+
import type { CursorPage, CursorParams } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Your OWN audit events — actions in your product you want on an audit trail
|
|
5
|
+
* (e.g. `invoice.sent`). Org-scoped events are streamed to that organization's
|
|
6
|
+
* audit streams. Separate from `auditLogs`, which records what happened in Atlas.
|
|
7
|
+
*/
|
|
8
|
+
export interface CustomAuditEvent {
|
|
9
|
+
object: 'audit_event';
|
|
10
|
+
id: string;
|
|
11
|
+
/** The org this event is scoped to, if any. */
|
|
12
|
+
organization_id?: string | null;
|
|
13
|
+
/** Your own actor vocabulary, e.g. `user`, `service`. */
|
|
14
|
+
actor: {
|
|
15
|
+
type?: string;
|
|
16
|
+
id?: string | null;
|
|
17
|
+
};
|
|
18
|
+
/** Your own action string, e.g. `invoice.sent`. */
|
|
19
|
+
action: string;
|
|
20
|
+
target: {
|
|
21
|
+
type?: string | null;
|
|
22
|
+
id?: string | null;
|
|
23
|
+
name?: string | null;
|
|
24
|
+
};
|
|
25
|
+
/** When it happened in your system (epoch ms). */
|
|
26
|
+
occurred_at: number;
|
|
27
|
+
metadata: unknown;
|
|
28
|
+
/** When Atlas received it (epoch ms). */
|
|
29
|
+
created_at: number;
|
|
30
|
+
}
|
|
31
|
+
export interface CreateCustomAuditEventBody {
|
|
32
|
+
actor: {
|
|
33
|
+
type: string;
|
|
34
|
+
id?: string;
|
|
35
|
+
};
|
|
36
|
+
action: string;
|
|
37
|
+
target?: {
|
|
38
|
+
type?: string;
|
|
39
|
+
id?: string;
|
|
40
|
+
name?: string;
|
|
41
|
+
};
|
|
42
|
+
/** Scope to an org (and stream to its SIEM). An unknown org id is a 404. */
|
|
43
|
+
organization_id?: string;
|
|
44
|
+
/** Epoch ms NUMBER; defaults to now. */
|
|
45
|
+
occurred_at?: number;
|
|
46
|
+
/** Non-secret structured context. */
|
|
47
|
+
metadata?: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
/** Shared filters of the list and export endpoints. */
|
|
50
|
+
export interface CustomAuditEventFilters {
|
|
51
|
+
/** Omit to query across all organizations (a blank value is a 400). */
|
|
52
|
+
organization_id?: string;
|
|
53
|
+
/** One id, or a comma-separated list (matches any). */
|
|
54
|
+
actor_id?: string;
|
|
55
|
+
/** One action, or a comma-separated list. */
|
|
56
|
+
action?: string;
|
|
57
|
+
/** One type, or a comma-separated list. */
|
|
58
|
+
target_type?: string;
|
|
59
|
+
/** One id, or a comma-separated list. */
|
|
60
|
+
target_id?: string;
|
|
61
|
+
/** Inclusive lower bound of occurred_at (epoch ms). */
|
|
62
|
+
from?: number;
|
|
63
|
+
/** Upper bound of occurred_at (epoch ms). */
|
|
64
|
+
to?: number;
|
|
65
|
+
/** OR the actor_id / target_type / target_id filters instead of AND. */
|
|
66
|
+
any_of?: boolean;
|
|
67
|
+
/** Give together with `metadata_value`: match events whose metadata[key] equals the value. */
|
|
68
|
+
metadata_key?: string;
|
|
69
|
+
metadata_value?: string;
|
|
70
|
+
}
|
|
71
|
+
export interface ListCustomAuditEventsParams extends CustomAuditEventFilters, CursorParams {
|
|
72
|
+
}
|
|
73
|
+
export interface ExportCustomAuditEventsParams extends CustomAuditEventFilters {
|
|
74
|
+
/** `jsonl` (default) or `csv`. */
|
|
75
|
+
format?: 'jsonl' | 'csv';
|
|
76
|
+
starting_after?: string;
|
|
77
|
+
}
|
|
78
|
+
export declare function auditEventsResource(request: RequestFn): {
|
|
79
|
+
create(body: CreateCustomAuditEventBody, idempotencyKey?: string): Promise<CustomAuditEvent>;
|
|
80
|
+
/** Up to 100 events, stored atomically (one bad org id fails the whole batch). */
|
|
81
|
+
createBatch(events: CreateCustomAuditEventBody[], idempotencyKey?: string): Promise<{
|
|
82
|
+
object: "list";
|
|
83
|
+
data: CustomAuditEvent[];
|
|
84
|
+
}>;
|
|
85
|
+
/** Newest first, cursor-paginated. */
|
|
86
|
+
list(params?: ListCustomAuditEventsParams): Promise<CursorPage<CustomAuditEvent>>;
|
|
87
|
+
/**
|
|
88
|
+
* Every matching event in one response, as text: JSONL (one event per line;
|
|
89
|
+
* a capped export ends with a `{"truncated":true,…}` line) or CSV.
|
|
90
|
+
*/
|
|
91
|
+
export(params?: ExportCustomAuditEventsParams): Promise<string>;
|
|
92
|
+
/**
|
|
93
|
+
* Test-mode reset: delete the custom audit events of a DEVELOPMENT instance,
|
|
94
|
+
* optionally only one org's and/or one action's. A production instance is a 403.
|
|
95
|
+
*/
|
|
96
|
+
deleteAll(params?: {
|
|
97
|
+
organization_id?: string;
|
|
98
|
+
action?: string;
|
|
99
|
+
}): Promise<{
|
|
100
|
+
object: "audit_events.bulk_delete";
|
|
101
|
+
deleted: number;
|
|
102
|
+
}>;
|
|
103
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.auditEventsResource = auditEventsResource;
|
|
4
|
+
function auditEventsResource(request) {
|
|
5
|
+
return {
|
|
6
|
+
create(body, idempotencyKey) {
|
|
7
|
+
return request({ method: 'POST', path: '/v1/audit_events', body, idempotencyKey });
|
|
8
|
+
},
|
|
9
|
+
/** Up to 100 events, stored atomically (one bad org id fails the whole batch). */
|
|
10
|
+
createBatch(events, idempotencyKey) {
|
|
11
|
+
return request({
|
|
12
|
+
method: 'POST',
|
|
13
|
+
path: '/v1/audit_events/batch',
|
|
14
|
+
body: { events },
|
|
15
|
+
idempotencyKey,
|
|
16
|
+
});
|
|
17
|
+
},
|
|
18
|
+
/** Newest first, cursor-paginated. */
|
|
19
|
+
list(params = {}) {
|
|
20
|
+
return request({ method: 'GET', path: '/v1/audit_events', query: { ...params } });
|
|
21
|
+
},
|
|
22
|
+
/**
|
|
23
|
+
* Every matching event in one response, as text: JSONL (one event per line;
|
|
24
|
+
* a capped export ends with a `{"truncated":true,…}` line) or CSV.
|
|
25
|
+
*/
|
|
26
|
+
export(params = {}) {
|
|
27
|
+
return request({
|
|
28
|
+
method: 'GET',
|
|
29
|
+
path: '/v1/audit_events/export',
|
|
30
|
+
query: { ...params },
|
|
31
|
+
raw: true,
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
/**
|
|
35
|
+
* Test-mode reset: delete the custom audit events of a DEVELOPMENT instance,
|
|
36
|
+
* optionally only one org's and/or one action's. A production instance is a 403.
|
|
37
|
+
*/
|
|
38
|
+
deleteAll(params = {}) {
|
|
39
|
+
return request({ method: 'DELETE', path: '/v1/audit_events', query: { ...params } });
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=audit-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-events.js","sourceRoot":"","sources":["../../src/client/audit-events.ts"],"names":[],"mappings":";;AAoEA,kDA2CC;AA3CD,SAAgB,mBAAmB,CAAC,OAAkB;IACpD,OAAO;QACL,MAAM,CAAC,IAAgC,EAAE,cAAuB;YAC9D,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QACrF,CAAC;QACD,kFAAkF;QAClF,WAAW,CACT,MAAoC,EACpC,cAAuB;YAEvB,OAAO,OAAO,CAAC;gBACb,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,wBAAwB;gBAC9B,IAAI,EAAE,EAAE,MAAM,EAAE;gBAChB,cAAc;aACf,CAAC,CAAC;QACL,CAAC;QACD,sCAAsC;QACtC,IAAI,CAAC,SAAsC,EAAE;YAC3C,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QACpF,CAAC;QACD;;;WAGG;QACH,MAAM,CAAC,SAAwC,EAAE;YAC/C,OAAO,OAAO,CAAC;gBACb,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,yBAAyB;gBAC/B,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE;gBACpB,GAAG,EAAE,IAAI;aACV,CAAC,CAAC;QACL,CAAC;QACD;;;WAGG;QACH,SAAS,CACP,SAAwD,EAAE;YAE1D,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QACvF,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -67,6 +67,37 @@ export interface ListSubscriptionsParams {
|
|
|
67
67
|
subject_type?: string;
|
|
68
68
|
subject_id?: string;
|
|
69
69
|
}
|
|
70
|
+
/** Adopt an existing Stripe subscription (same Stripe account) onto an Atlas subject. */
|
|
71
|
+
export interface ImportBillingSubscriptionBody {
|
|
72
|
+
subject_type: 'user' | 'org';
|
|
73
|
+
subject_id: string;
|
|
74
|
+
stripe_subscription_id: string;
|
|
75
|
+
stripe_customer_id?: string;
|
|
76
|
+
/** Resolved from the subscription's price when omitted. */
|
|
77
|
+
plan_id?: string;
|
|
78
|
+
}
|
|
79
|
+
/** Report metered usage for a subject. Idempotent on `idempotency_key`. */
|
|
80
|
+
export interface ReportBillingUsageBody {
|
|
81
|
+
subject_type: 'user' | 'org';
|
|
82
|
+
subject_id: string;
|
|
83
|
+
/** Non-negative. */
|
|
84
|
+
quantity: number;
|
|
85
|
+
idempotency_key: string;
|
|
86
|
+
}
|
|
87
|
+
export interface BillingUsageReport {
|
|
88
|
+
object: 'billing_usage';
|
|
89
|
+
/** False when this `idempotency_key` was already recorded. */
|
|
90
|
+
recorded: boolean;
|
|
91
|
+
/** Whether it was mirrored to a Stripe meter (the plan is metered and configured). */
|
|
92
|
+
metered: boolean;
|
|
93
|
+
total: number;
|
|
94
|
+
}
|
|
95
|
+
export interface BillingSeatSync {
|
|
96
|
+
object: 'billing_seats';
|
|
97
|
+
subject_type: string;
|
|
98
|
+
subject_id: string;
|
|
99
|
+
quantity: number;
|
|
100
|
+
}
|
|
70
101
|
export declare function billingResource(request: RequestFn): {
|
|
71
102
|
listPlans(): Promise<ListPage<BillingPlan>>;
|
|
72
103
|
createPlan(body: CreateBillingPlanBody, idempotencyKey?: string): Promise<BillingPlan>;
|
|
@@ -78,4 +109,16 @@ export declare function billingResource(request: RequestFn): {
|
|
|
78
109
|
deleted: true;
|
|
79
110
|
}>;
|
|
80
111
|
listSubscriptions(params?: ListSubscriptionsParams): Promise<ListPage<BillingSubscription>>;
|
|
112
|
+
/**
|
|
113
|
+
* Adopt an EXISTING Stripe subscription onto a user/org + plan, for
|
|
114
|
+
* migrating billing into Atlas without re-charging. Read-only on Stripe.
|
|
115
|
+
*/
|
|
116
|
+
importSubscription(body: ImportBillingSubscriptionBody, idempotencyKey?: string): Promise<BillingSubscription>;
|
|
117
|
+
/** Report metered usage (mirrored to a Stripe meter event when the plan is metered). */
|
|
118
|
+
reportUsage(body: ReportBillingUsageBody): Promise<BillingUsageReport>;
|
|
119
|
+
/**
|
|
120
|
+
* Sync a per-seat subscription's Stripe quantity to the org's current member
|
|
121
|
+
* count (prorated). Never changes the paid status.
|
|
122
|
+
*/
|
|
123
|
+
syncSeats(subjectType: "user" | "org", subjectId: string): Promise<BillingSeatSync>;
|
|
81
124
|
};
|
|
@@ -22,6 +22,32 @@ function billingResource(request) {
|
|
|
22
22
|
listSubscriptions(params) {
|
|
23
23
|
return request({ method: 'GET', path: '/v1/billing/subscriptions', query: { ...params } });
|
|
24
24
|
},
|
|
25
|
+
/**
|
|
26
|
+
* Adopt an EXISTING Stripe subscription onto a user/org + plan, for
|
|
27
|
+
* migrating billing into Atlas without re-charging. Read-only on Stripe.
|
|
28
|
+
*/
|
|
29
|
+
importSubscription(body, idempotencyKey) {
|
|
30
|
+
return request({
|
|
31
|
+
method: 'POST',
|
|
32
|
+
path: '/v1/billing/subscriptions/import',
|
|
33
|
+
body,
|
|
34
|
+
idempotencyKey,
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
/** Report metered usage (mirrored to a Stripe meter event when the plan is metered). */
|
|
38
|
+
reportUsage(body) {
|
|
39
|
+
return request({ method: 'POST', path: '/v1/billing/usage', body });
|
|
40
|
+
},
|
|
41
|
+
/**
|
|
42
|
+
* Sync a per-seat subscription's Stripe quantity to the org's current member
|
|
43
|
+
* count (prorated). Never changes the paid status.
|
|
44
|
+
*/
|
|
45
|
+
syncSeats(subjectType, subjectId) {
|
|
46
|
+
return request({
|
|
47
|
+
method: 'POST',
|
|
48
|
+
path: `/v1/billing/subjects/${(0, request_1.enc)(subjectType)}/${(0, request_1.enc)(subjectId)}/sync_seats`,
|
|
49
|
+
});
|
|
50
|
+
},
|
|
25
51
|
};
|
|
26
52
|
}
|
|
27
53
|
//# sourceMappingURL=billing-plans.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"billing-plans.js","sourceRoot":"","sources":["../../src/client/billing-plans.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"billing-plans.js","sourceRoot":"","sources":["../../src/client/billing-plans.ts"],"names":[],"mappings":";;AA8GA,0CAkDC;AAhKD,uCAAgD;AA8GhD,SAAgB,eAAe,CAAC,OAAkB;IAChD,OAAO;QACL,SAAS;YACP,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,UAAU,CAAC,IAA2B,EAAE,cAAuB;YAC7D,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QACtF,CAAC;QACD,OAAO,CAAC,EAAU;YAChB,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,qBAAqB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1E,CAAC;QACD,UAAU,CAAC,EAAU,EAAE,IAA2B;YAChD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,qBAAqB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAClF,CAAC;QACD,UAAU,CAAC,EAAU;YACnB,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,qBAAqB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,iBAAiB,CAAC,MAAgC;YAChD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7F,CAAC;QACD;;;WAGG;QACH,kBAAkB,CAChB,IAAmC,EACnC,cAAuB;YAEvB,OAAO,OAAO,CAAC;gBACb,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,kCAAkC;gBACxC,IAAI;gBACJ,cAAc;aACf,CAAC,CAAC;QACL,CAAC;QACD,wFAAwF;QACxF,WAAW,CAAC,IAA4B;YACtC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,CAAC;QACtE,CAAC;QACD;;;WAGG;QACH,SAAS,CAAC,WAA2B,EAAE,SAAiB;YACtD,OAAO,OAAO,CAAC;gBACb,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,wBAAwB,IAAA,aAAG,EAAC,WAAW,CAAC,IAAI,IAAA,aAAG,EAAC,SAAS,CAAC,aAAa;aAC9E,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { type RequestFn } from './request';
|
|
2
|
+
/** How an installing instance gets OAuth credentials for a connector. */
|
|
3
|
+
export type ConnectorShareMode = 'prefill' | 'full_shared' | 'full_idp';
|
|
4
|
+
/**
|
|
5
|
+
* A community connector profile you publish to the connector directory: its
|
|
6
|
+
* public listing, OAuth config and share modes. The shared client secret is
|
|
7
|
+
* never returned.
|
|
8
|
+
*/
|
|
9
|
+
export interface CommunityConnector {
|
|
10
|
+
object: 'connector';
|
|
11
|
+
id: string;
|
|
12
|
+
slug: string;
|
|
13
|
+
display_name: string;
|
|
14
|
+
logo_url?: string | null;
|
|
15
|
+
tagline?: string | null;
|
|
16
|
+
description?: string | null;
|
|
17
|
+
category: string;
|
|
18
|
+
tags: unknown[];
|
|
19
|
+
website_url?: string | null;
|
|
20
|
+
docs_url?: string | null;
|
|
21
|
+
support_url?: string | null;
|
|
22
|
+
setup_guide?: string | null;
|
|
23
|
+
protocol: string;
|
|
24
|
+
authorization_endpoint?: string | null;
|
|
25
|
+
token_endpoint?: string | null;
|
|
26
|
+
userinfo_endpoint?: string | null;
|
|
27
|
+
issuer?: string | null;
|
|
28
|
+
default_scopes: string[];
|
|
29
|
+
api_scopes?: unknown[];
|
|
30
|
+
credential_fields?: unknown[];
|
|
31
|
+
share_modes: ConnectorShareMode[];
|
|
32
|
+
shared_client_id?: string | null;
|
|
33
|
+
shared_revoked: boolean;
|
|
34
|
+
idp_issuer?: string | null;
|
|
35
|
+
idp_auto_register: boolean;
|
|
36
|
+
status: 'draft' | 'published' | 'unlisted' | 'banned';
|
|
37
|
+
verified: boolean;
|
|
38
|
+
featured: boolean;
|
|
39
|
+
install_count: number;
|
|
40
|
+
view_count: number;
|
|
41
|
+
rating_avg: number;
|
|
42
|
+
rating_count: number;
|
|
43
|
+
/** Epoch ms. */
|
|
44
|
+
created_at: number;
|
|
45
|
+
/** Epoch ms. */
|
|
46
|
+
updated_at: number;
|
|
47
|
+
}
|
|
48
|
+
/** Fields of a connector profile you can set on create or update. */
|
|
49
|
+
export interface UpdateCommunityConnectorBody {
|
|
50
|
+
slug?: string;
|
|
51
|
+
display_name?: string;
|
|
52
|
+
logo_url?: string;
|
|
53
|
+
tagline?: string;
|
|
54
|
+
description?: string;
|
|
55
|
+
category?: string;
|
|
56
|
+
tags?: string[];
|
|
57
|
+
website_url?: string;
|
|
58
|
+
docs_url?: string;
|
|
59
|
+
support_url?: string;
|
|
60
|
+
screenshots?: unknown[];
|
|
61
|
+
setup_guide?: string;
|
|
62
|
+
protocol?: string;
|
|
63
|
+
authorization_endpoint?: string;
|
|
64
|
+
token_endpoint?: string;
|
|
65
|
+
userinfo_endpoint?: string;
|
|
66
|
+
issuer?: string;
|
|
67
|
+
default_scopes?: string[];
|
|
68
|
+
api_scopes?: unknown[];
|
|
69
|
+
credential_fields?: unknown[];
|
|
70
|
+
authorization_params?: Record<string, unknown>;
|
|
71
|
+
quirks?: Record<string, unknown>;
|
|
72
|
+
share_modes?: ConnectorShareMode[];
|
|
73
|
+
idp_instance_id?: string;
|
|
74
|
+
idp_issuer?: string;
|
|
75
|
+
idp_auto_register?: boolean;
|
|
76
|
+
}
|
|
77
|
+
/** `slug` is globally unique and may not shadow a built-in provider. */
|
|
78
|
+
export interface CreateCommunityConnectorBody extends UpdateCommunityConnectorBody {
|
|
79
|
+
slug: string;
|
|
80
|
+
display_name: string;
|
|
81
|
+
}
|
|
82
|
+
/** Set or rotate (`client_id` + `client_secret`) or revoke (`revoke: true`) the full_shared credentials. */
|
|
83
|
+
export interface ConnectorSharedCredentialsBody {
|
|
84
|
+
client_id?: string;
|
|
85
|
+
client_secret?: string;
|
|
86
|
+
revoke?: boolean;
|
|
87
|
+
}
|
|
88
|
+
export interface InstallConnectorBody {
|
|
89
|
+
share_mode: ConnectorShareMode;
|
|
90
|
+
/** Your own credentials (prefill mode). */
|
|
91
|
+
client_id?: string;
|
|
92
|
+
client_secret?: string;
|
|
93
|
+
scopes?: string[];
|
|
94
|
+
}
|
|
95
|
+
export interface ConnectorInstall {
|
|
96
|
+
object: 'connector_install';
|
|
97
|
+
connector: string;
|
|
98
|
+
share_mode: string;
|
|
99
|
+
provider_key?: string;
|
|
100
|
+
/** True when the install still needs your own client credentials. */
|
|
101
|
+
needs_credentials?: boolean;
|
|
102
|
+
}
|
|
103
|
+
export interface ConnectorReview {
|
|
104
|
+
object: 'connector_review';
|
|
105
|
+
connector: string;
|
|
106
|
+
rating: number;
|
|
107
|
+
}
|
|
108
|
+
/** A directory entry (built-in provider or community connector). Keys are camelCase. */
|
|
109
|
+
export interface ConnectorDirectoryEntry {
|
|
110
|
+
source: 'builtin' | 'community';
|
|
111
|
+
key: string;
|
|
112
|
+
slug: string;
|
|
113
|
+
displayName: string;
|
|
114
|
+
category: string;
|
|
115
|
+
tagline?: string | null;
|
|
116
|
+
description?: string | null;
|
|
117
|
+
logoUrl?: string | null;
|
|
118
|
+
websiteUrl?: string | null;
|
|
119
|
+
docsUrl?: string | null;
|
|
120
|
+
verified?: boolean;
|
|
121
|
+
featured?: boolean;
|
|
122
|
+
installCount?: number;
|
|
123
|
+
ratingAvg?: number;
|
|
124
|
+
ratingCount?: number;
|
|
125
|
+
rankScore?: number;
|
|
126
|
+
defaultScopes?: string[];
|
|
127
|
+
apiScopes?: unknown[];
|
|
128
|
+
credentialFields?: unknown[];
|
|
129
|
+
shareModes?: string[];
|
|
130
|
+
}
|
|
131
|
+
export interface ConnectorDirectoryParams {
|
|
132
|
+
category?: string;
|
|
133
|
+
/** Only verified community connectors. */
|
|
134
|
+
verified?: boolean;
|
|
135
|
+
/** Free-text search. */
|
|
136
|
+
q?: string;
|
|
137
|
+
limit?: number;
|
|
138
|
+
offset?: number;
|
|
139
|
+
}
|
|
140
|
+
export declare function connectorsResource(request: RequestFn): {
|
|
141
|
+
/** Your own connector profiles (draft and published). */
|
|
142
|
+
list(): Promise<{
|
|
143
|
+
object: "list";
|
|
144
|
+
data: CommunityConnector[];
|
|
145
|
+
has_more: false;
|
|
146
|
+
}>;
|
|
147
|
+
create(body: CreateCommunityConnectorBody, idempotencyKey?: string): Promise<CommunityConnector>;
|
|
148
|
+
get(id: string): Promise<CommunityConnector>;
|
|
149
|
+
update(id: string, body: UpdateCommunityConnectorBody): Promise<CommunityConnector>;
|
|
150
|
+
/** Deletes the profile and its installs, reviews and reports. */
|
|
151
|
+
delete(id: string): Promise<{
|
|
152
|
+
object: "connector";
|
|
153
|
+
id: string;
|
|
154
|
+
deleted: true;
|
|
155
|
+
}>;
|
|
156
|
+
/** List it in the public directory (unverified until reviewed). */
|
|
157
|
+
publish(id: string): Promise<CommunityConnector>;
|
|
158
|
+
/** Take it out of the directory without deleting it. */
|
|
159
|
+
unlist(id: string): Promise<CommunityConnector>;
|
|
160
|
+
/** Set, rotate or revoke the full_shared credentials. Revoking stops every install. */
|
|
161
|
+
setSharedCredentials(id: string, body: ConnectorSharedCredentialsBody): Promise<CommunityConnector>;
|
|
162
|
+
/** Enable a published connector (by slug) on this instance. */
|
|
163
|
+
install(slug: string, body: InstallConnectorBody): Promise<ConnectorInstall>;
|
|
164
|
+
/** Rate a connector you installed, 1–5, with optional text. */
|
|
165
|
+
review(slug: string, body: {
|
|
166
|
+
rating: number;
|
|
167
|
+
body?: string;
|
|
168
|
+
}): Promise<ConnectorReview>;
|
|
169
|
+
/** Browse built-in providers plus published community connectors, popular first. */
|
|
170
|
+
directory(params?: ConnectorDirectoryParams): Promise<{
|
|
171
|
+
object: "list";
|
|
172
|
+
data: ConnectorDirectoryEntry[];
|
|
173
|
+
}>;
|
|
174
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.connectorsResource = connectorsResource;
|
|
4
|
+
const request_1 = require("./request");
|
|
5
|
+
function connectorsResource(request) {
|
|
6
|
+
return {
|
|
7
|
+
/** Your own connector profiles (draft and published). */
|
|
8
|
+
list() {
|
|
9
|
+
return request({ method: 'GET', path: '/v1/connectors' });
|
|
10
|
+
},
|
|
11
|
+
create(body, idempotencyKey) {
|
|
12
|
+
return request({ method: 'POST', path: '/v1/connectors', body, idempotencyKey });
|
|
13
|
+
},
|
|
14
|
+
get(id) {
|
|
15
|
+
return request({ method: 'GET', path: `/v1/connectors/${(0, request_1.enc)(id)}` });
|
|
16
|
+
},
|
|
17
|
+
update(id, body) {
|
|
18
|
+
return request({ method: 'PATCH', path: `/v1/connectors/${(0, request_1.enc)(id)}`, body });
|
|
19
|
+
},
|
|
20
|
+
/** Deletes the profile and its installs, reviews and reports. */
|
|
21
|
+
delete(id) {
|
|
22
|
+
return request({ method: 'DELETE', path: `/v1/connectors/${(0, request_1.enc)(id)}` });
|
|
23
|
+
},
|
|
24
|
+
/** List it in the public directory (unverified until reviewed). */
|
|
25
|
+
publish(id) {
|
|
26
|
+
return request({ method: 'POST', path: `/v1/connectors/${(0, request_1.enc)(id)}/publish` });
|
|
27
|
+
},
|
|
28
|
+
/** Take it out of the directory without deleting it. */
|
|
29
|
+
unlist(id) {
|
|
30
|
+
return request({ method: 'POST', path: `/v1/connectors/${(0, request_1.enc)(id)}/unlist` });
|
|
31
|
+
},
|
|
32
|
+
/** Set, rotate or revoke the full_shared credentials. Revoking stops every install. */
|
|
33
|
+
setSharedCredentials(id, body) {
|
|
34
|
+
return request({
|
|
35
|
+
method: 'POST',
|
|
36
|
+
path: `/v1/connectors/${(0, request_1.enc)(id)}/shared_credentials`,
|
|
37
|
+
body,
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
/** Enable a published connector (by slug) on this instance. */
|
|
41
|
+
install(slug, body) {
|
|
42
|
+
return request({ method: 'POST', path: `/v1/connectors/${(0, request_1.enc)(slug)}/install`, body });
|
|
43
|
+
},
|
|
44
|
+
/** Rate a connector you installed, 1–5, with optional text. */
|
|
45
|
+
review(slug, body) {
|
|
46
|
+
return request({ method: 'POST', path: `/v1/connectors/${(0, request_1.enc)(slug)}/reviews`, body });
|
|
47
|
+
},
|
|
48
|
+
/** Browse built-in providers plus published community connectors, popular first. */
|
|
49
|
+
directory(params = {}) {
|
|
50
|
+
return request({ method: 'GET', path: '/v1/directory', query: { ...params } });
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=connectors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connectors.js","sourceRoot":"","sources":["../../src/client/connectors.ts"],"names":[],"mappings":";;AAsJA,gDAwDC;AA9MD,uCAAgD;AAsJhD,SAAgB,kBAAkB,CAAC,OAAkB;IACnD,OAAO;QACL,yDAAyD;QACzD,IAAI;YACF,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,CACJ,IAAkC,EAClC,cAAuB;YAEvB,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QACnF,CAAC;QACD,GAAG,CAAC,EAAU;YACZ,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,kBAAkB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,CAAC,EAAU,EAAE,IAAkC;YACnD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,kBAAkB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,iEAAiE;QACjE,MAAM,CAAC,EAAU;YACf,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,kBAAkB,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1E,CAAC;QACD,mEAAmE;QACnE,OAAO,CAAC,EAAU;YAChB,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,IAAA,aAAG,EAAC,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC;QAChF,CAAC;QACD,wDAAwD;QACxD,MAAM,CAAC,EAAU;YACf,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,IAAA,aAAG,EAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,uFAAuF;QACvF,oBAAoB,CAClB,EAAU,EACV,IAAoC;YAEpC,OAAO,OAAO,CAAC;gBACb,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,kBAAkB,IAAA,aAAG,EAAC,EAAE,CAAC,qBAAqB;gBACpD,IAAI;aACL,CAAC,CAAC;QACL,CAAC;QACD,+DAA+D;QAC/D,OAAO,CAAC,IAAY,EAAE,IAA0B;YAC9C,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,IAAA,aAAG,EAAC,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,+DAA+D;QAC/D,MAAM,CAAC,IAAY,EAAE,IAAuC;YAC1D,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,IAAA,aAAG,EAAC,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,oFAAoF;QACpF,SAAS,CACP,SAAmC,EAAE;YAErC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QACjF,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -17,6 +17,8 @@ export interface DataSubjectRequest {
|
|
|
17
17
|
requested_by_id: string | null;
|
|
18
18
|
reason: string | null;
|
|
19
19
|
scheduled_for: number | null;
|
|
20
|
+
/** Estimated completion (epoch ms): an erasure's grace deadline; null for an export. */
|
|
21
|
+
eta?: number | null;
|
|
20
22
|
requested_at: number;
|
|
21
23
|
updated_at: number;
|
|
22
24
|
completed_at: number | null;
|
|
@@ -28,7 +30,26 @@ export interface ListDataSubjectRequestsParams extends CursorParams {
|
|
|
28
30
|
status?: string;
|
|
29
31
|
user_id?: string;
|
|
30
32
|
}
|
|
33
|
+
/** Identify the subject by `user_id` OR `subject_email` (`user_id` wins if both are given). */
|
|
34
|
+
export interface CreateDataSubjectRequestBody {
|
|
35
|
+
type: 'export' | 'erasure';
|
|
36
|
+
user_id?: string;
|
|
37
|
+
/** The subject's email (verified, else unverified), resolved to the user. */
|
|
38
|
+
subject_email?: string;
|
|
39
|
+
reason?: string;
|
|
40
|
+
}
|
|
31
41
|
export declare function dataSubjectRequestsResource(request: RequestFn): {
|
|
42
|
+
/**
|
|
43
|
+
* Open an export or erasure request for a user from the backend. Same worker,
|
|
44
|
+
* grace window and webhooks as the self-service flow; idempotent on an
|
|
45
|
+
* in-flight request.
|
|
46
|
+
*/
|
|
47
|
+
create(body: CreateDataSubjectRequestBody, idempotencyKey?: string): Promise<DataSubjectRequest>;
|
|
48
|
+
/**
|
|
49
|
+
* Cancel a scheduled erasure inside its grace window. Once processing or
|
|
50
|
+
* terminal it is a 409; exports are not cancellable.
|
|
51
|
+
*/
|
|
52
|
+
cancel(id: string): Promise<DataSubjectRequest>;
|
|
32
53
|
list(params?: ListDataSubjectRequestsParams): Promise<CursorPage<DataSubjectRequest>>;
|
|
33
54
|
get(id: string): Promise<DataSubjectRequest>;
|
|
34
55
|
/** Fulfil a request now — build the export package, or run the erasure — ahead of schedule. */
|
|
@@ -4,6 +4,21 @@ exports.dataSubjectRequestsResource = dataSubjectRequestsResource;
|
|
|
4
4
|
const request_1 = require("./request");
|
|
5
5
|
function dataSubjectRequestsResource(request) {
|
|
6
6
|
return {
|
|
7
|
+
/**
|
|
8
|
+
* Open an export or erasure request for a user from the backend. Same worker,
|
|
9
|
+
* grace window and webhooks as the self-service flow; idempotent on an
|
|
10
|
+
* in-flight request.
|
|
11
|
+
*/
|
|
12
|
+
create(body, idempotencyKey) {
|
|
13
|
+
return request({ method: 'POST', path: '/v1/data_subject_requests', body, idempotencyKey });
|
|
14
|
+
},
|
|
15
|
+
/**
|
|
16
|
+
* Cancel a scheduled erasure inside its grace window. Once processing or
|
|
17
|
+
* terminal it is a 409; exports are not cancellable.
|
|
18
|
+
*/
|
|
19
|
+
cancel(id) {
|
|
20
|
+
return request({ method: 'POST', path: `/v1/data_subject_requests/${(0, request_1.enc)(id)}/cancel` });
|
|
21
|
+
},
|
|
7
22
|
list(params = {}) {
|
|
8
23
|
return request({ method: 'GET', path: '/v1/data_subject_requests', query: { ...params } });
|
|
9
24
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-subject-requests.js","sourceRoot":"","sources":["../../src/client/data-subject-requests.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"data-subject-requests.js","sourceRoot":"","sources":["../../src/client/data-subject-requests.ts"],"names":[],"mappings":";;AA4CA,kEAkDC;AA9FD,uCAAgD;AA4ChD,SAAgB,2BAA2B,CAAC,OAAkB;IAC5D,OAAO;QACL;;;;WAIG;QACH,MAAM,CACJ,IAAkC,EAClC,cAAuB;YAEvB,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,2BAA2B,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QAC9F,CAAC;QACD;;;WAGG;QACH,MAAM,CAAC,EAAU;YACf,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,6BAA6B,IAAA,aAAG,EAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,IAAI,CACF,SAAwC,EAAE;YAE1C,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,EAAE,CAAC,CAAC;QAC7F,CAAC;QACD,GAAG,CAAC,EAAU;YACZ,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,6BAA6B,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAClF,CAAC;QACD,+FAA+F;QAC/F,OAAO,CAAC,EAAU,EAAE,cAAuB;YACzC,OAAO,OAAO,CAAC;gBACb,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,6BAA6B,IAAA,aAAG,EAAC,EAAE,CAAC,UAAU;gBACpD,cAAc;aACf,CAAC,CAAC;QACL,CAAC;QACD,oFAAoF;QACpF,MAAM,CACJ,EAAU,EACV,OAA4B,EAAE,EAC9B,cAAuB;YAEvB,OAAO,OAAO,CAAC;gBACb,MAAM,EAAE,MAAM;gBACd,IAAI,EAAE,6BAA6B,IAAA,aAAG,EAAC,EAAE,CAAC,SAAS;gBACnD,IAAI;gBACJ,cAAc;aACf,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|