@atlasauth/backend 0.15.0 → 0.16.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 +19 -0
- package/dist/botid.d.ts +70 -0
- package/dist/botid.js +88 -0
- package/dist/botid.js.map +1 -0
- package/dist/client/action-gallery.d.ts +215 -0
- package/dist/client/action-gallery.js +66 -0
- package/dist/client/action-gallery.js.map +1 -0
- package/dist/client/actions.d.ts +21 -0
- package/dist/client/actions.js.map +1 -1
- package/dist/client/attack-protection.d.ts +33 -1
- package/dist/client/attack-protection.js.map +1 -1
- package/dist/client/billing-plans.d.ts +93 -0
- package/dist/client/billing-plans.js +31 -0
- package/dist/client/billing-plans.js.map +1 -1
- package/dist/client/custom-oauth-providers.d.ts +243 -0
- package/dist/client/custom-oauth-providers.js +60 -0
- package/dist/client/custom-oauth-providers.js.map +1 -0
- package/dist/client/email-templates.d.ts +1 -1
- package/dist/client/email-templates.js.map +1 -1
- package/dist/client/index.d.ts +108 -0
- package/dist/client/index.js +7 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/instance-security.d.ts +70 -0
- package/dist/client/instance-security.js +20 -0
- package/dist/client/instance-security.js.map +1 -1
- package/dist/client/oauth-clients.d.ts +29 -2
- package/dist/client/oauth-clients.js.map +1 -1
- package/dist/client/resource-servers.d.ts +22 -2
- package/dist/client/resource-servers.js.map +1 -1
- package/dist/client/risk-based-mfa.d.ts +3 -0
- package/dist/client/risk-based-mfa.js.map +1 -1
- package/dist/client/sessions.d.ts +16 -0
- package/dist/client/sessions.js +15 -0
- package/dist/client/sessions.js.map +1 -1
- package/dist/client/sso-connections.d.ts +83 -0
- package/dist/client/sso-connections.js +29 -0
- package/dist/client/sso-connections.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/oauth-resource.d.ts +81 -1
- package/dist/oauth-resource.js +204 -29
- package/dist/oauth-resource.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @atlasauth/backend changelog
|
|
2
2
|
|
|
3
|
+
## 0.16.0 — 2026-10-24
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- `actionGallery` (`list`, `get`, `install`, `installs`, `update`) and `actionTemplates` (`list`, `create`, `get`, `update`, `delete`, `addVersion`, `submitVersion`, `deleteVersion`, `publish`, `unlist`) for the Actions gallery.
|
|
8
|
+
- `ActionTestResult.http_requests` (what `api.http` queued in a dry run) and `organizations` / `country` on the sample event.
|
|
9
|
+
- DPoP server nonces (RFC 9449 §8) in `createAccessTokenVerifier`: `dpopNonces` requires every DPoP proof to carry a nonce the API issued, answering `use_dpop_nonce` with a fresh nonce otherwise; every result carries `dpopNonce` for the `DPoP-Nonce` response header. `memoryDpopNonceSource()` (one process) and `hmacDpopNonceSource(secret)` (stateless, shared by every process — and every Atlas server SDK — holding the same secret).
|
|
10
|
+
- Opaque access tokens: `createAccessTokenVerifier({ introspection: { clientId, clientSecret } })` validates a token that is not a JWT at the instance's introspection endpoint (RFC 7662), caching each answer (60 seconds by default, never past `exp`; inactive answers 10 seconds). `introspectJwts: true` checks JWTs live too, so a revoked grant is refused before the token expires. DPoP-bound opaque tokens keep their sender constraint (`cnf.jkt` from introspection). `createIntrospector` is the cache on its own.
|
|
11
|
+
- OAuth clients: `access_token_format` (`jwt` | `opaque`) and `token_lifetimes` (`OAuthTokenLifetimes`) on create, update and reads. Resource servers: `access_token_format`, `refresh_token_absolute_ttl_seconds`, `refresh_token_idle_ttl_seconds`, `introspection_client_ids`.
|
|
12
|
+
- `RotateSigningKeyBody.key` (`main` | `secondary`) and `SigningKeyRotation.secondary_kid` for KMS setups with one key per algorithm (`config.secondary`).
|
|
13
|
+
- KMS-backed signing keys: `instanceSecurity.getSigningKeyProvider()` / `setSigningKeyProvider({ provider, config, credentials })` / `removeSigningKeyProvider()` for AWS KMS, Google Cloud KMS and Azure Key Vault; `SigningKey.provider`.
|
|
14
|
+
- SSO connections: SAML Single Logout fields (`saml_single_logout`, `saml_idp_slo_url`, `saml_idp_slo_response_url`, `saml_idp_slo_binding`, `saml_idp_slo_soap_url` for back-channel logout) and `saml_require_encrypted_assertions`. Reads add `has_saml_encryption_key`, `has_previous_saml_encryption_key`, `saml_encryption_rotated_at`; `SamlMetadata.slo_url`. New `getSamlEncryptionKey()`, `createSamlEncryptionKey()` (generate or rotate), `retirePreviousSamlEncryptionKey()` and `deleteSamlEncryptionKey()` (`SamlEncryptionKey`).
|
|
15
|
+
- Custom OAuth 2.0 / OpenID Connect login providers: `customOAuthProviders` (`list`, `get`, `create`, `update`, `delete`, `discover`, `previewProfileMapping`, and `signingKeys(id)` with `list` / `rotate` / `retire` for `private_key_jwt`), with `ProfileMapping`, `TokenEndpointAuthMethod`, upstream (RP-initiated and front-channel) logout and third-party initiated login settings. Enterprise OIDC connections take the same `profile_mapping`, `token_endpoint_auth_method`, `client_assertion_audience`, `logout` and `idp_initiated_login`, and report `upstream_urls`.
|
|
16
|
+
- Attack protection: `dormant_accounts` (`DormantAccountsSettings`), readable and writable; `country_restrictions` / `device_accounts` typed. Risk-based MFA weights and signals gain `dormantAccount`. Email template key `account_reactivated`.
|
|
17
|
+
- Sessions: `custom_data` on reads and on create; `sessions.setCustomData(id, data)` (replace, `null` clears) and `sessions.updateCustomData(id, patch)` (merge).
|
|
18
|
+
- Billing: add-on plans (`kind: 'base' | 'addon'`) and several subscriptions per subject (`billing.getSubscription(id)`, and `changeSubscription` / `cancelSubscription` / `restoreSubscription` by subscription id); providers `chargebee`, `autumn` and `commet` (`BillingProviderName`); plan `limits` and Autumn `seat_feature_id`; `syncPlanEntitlements(id)`; `getSettings()` / `updateSettings()` for how limits merge across subscriptions (`max` | `sum`); `checkFeature({ subject_type, subject_id, feature, required })`; metered usage takes `feature` and `subscription_id`.
|
|
19
|
+
- Vercel BotID: `botIdAttestationHandler({ secret, checkBotId })` (a fetch-style route handler for your Vercel deployment) and `createBotIdAttestation()`, which sign a BotID verdict for Atlas's `vercel_botid` captcha provider.
|
|
20
|
+
- `instanceSecurity.setWalletRpcSecret({ chain_id, url })`: the wallet RPC endpoint for an EIP-155 chain (token gating and the Sign in with Ethereum ENS lookup); captcha secrets take `provider`.
|
|
21
|
+
|
|
3
22
|
## 0.15.0 — 2026-10-23
|
|
4
23
|
|
|
5
24
|
### Added
|
package/dist/botid.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vercel BotID for Atlas — the server half that runs on YOUR Vercel deployment.
|
|
3
|
+
*
|
|
4
|
+
* BotID's verdict only exists inside a Vercel-hosted request (`checkBotId()`
|
|
5
|
+
* from `botid/server` reads signals Vercel's edge attaches). Atlas is not that
|
|
6
|
+
* request, so your route runs `checkBotId()` and turns the verdict into a short
|
|
7
|
+
* signed attestation; the browser sends it to Atlas as `captcha_token`, and
|
|
8
|
+
* Atlas checks the signature, freshness and `isBot === false`, and spends it
|
|
9
|
+
* (each attestation passes once).
|
|
10
|
+
*
|
|
11
|
+
* // app/api/atlas/botid/route.ts (Next.js on Vercel)
|
|
12
|
+
* import { checkBotId } from 'botid/server';
|
|
13
|
+
* import { botIdAttestationHandler } from '@atlasauth/backend';
|
|
14
|
+
* export const POST = botIdAttestationHandler({
|
|
15
|
+
* secret: process.env.ATLAS_BOTID_SECRET!,
|
|
16
|
+
* checkBotId,
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* The same secret is stored in Atlas for the `vercel_botid` captcha provider.
|
|
20
|
+
* Protect the route with BotID on the client (`initBotId({ protect: [{ path:
|
|
21
|
+
* '/api/atlas/botid', method: 'POST' }] })`) and set the captcha's
|
|
22
|
+
* `attestationUrl` to it, so the prebuilt components fetch a verdict on submit.
|
|
23
|
+
*
|
|
24
|
+
* Format (version 1): `atlas_botid.v1.<payload>.<sig>` — `payload` is base64url
|
|
25
|
+
* JSON `{ v: 1, is_bot, verified_bot, iat, exp, jti }`, `sig` is base64url
|
|
26
|
+
* HMAC-SHA256 over `atlas_botid.v1.<payload>` keyed by the shared secret.
|
|
27
|
+
*/
|
|
28
|
+
/** The prefix every attestation carries. */
|
|
29
|
+
export declare const BOTID_ATTESTATION_PREFIX = "atlas_botid.v1.";
|
|
30
|
+
/** Atlas refuses attestations that live longer than this, in seconds. */
|
|
31
|
+
export declare const BOTID_ATTESTATION_MAX_TTL_SECONDS = 300;
|
|
32
|
+
/** Atlas refuses secrets shorter than this. */
|
|
33
|
+
export declare const BOTID_SECRET_MIN_LENGTH = 32;
|
|
34
|
+
/** The fields of BotID's `checkBotId()` result this helper reads. */
|
|
35
|
+
export interface BotIdVerdict {
|
|
36
|
+
isBot: boolean;
|
|
37
|
+
/** True for a known good bot (a search engine crawler). Recorded, still refused. */
|
|
38
|
+
isVerifiedBot?: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface CreateBotIdAttestationOptions {
|
|
41
|
+
/** The attestation secret shared with Atlas (at least 32 characters). */
|
|
42
|
+
secret: string;
|
|
43
|
+
/** The verdict `checkBotId()` returned for this request. */
|
|
44
|
+
verdict: BotIdVerdict;
|
|
45
|
+
/** Lifetime in seconds. Default 60, at most 300. */
|
|
46
|
+
ttlSeconds?: number;
|
|
47
|
+
/** Clock override, epoch ms (tests). */
|
|
48
|
+
now?: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Sign a BotID verdict for Atlas. Throws when the secret is too short (Atlas
|
|
52
|
+
* would refuse every attestation it signs). A bot verdict is still signed — it
|
|
53
|
+
* is Atlas that refuses it — so your route needs no branching.
|
|
54
|
+
*/
|
|
55
|
+
export declare function createBotIdAttestation(options: CreateBotIdAttestationOptions): string;
|
|
56
|
+
export interface BotIdAttestationHandlerOptions {
|
|
57
|
+
/** The attestation secret shared with Atlas. */
|
|
58
|
+
secret: string;
|
|
59
|
+
/** `checkBotId` from `botid/server`. */
|
|
60
|
+
checkBotId: () => Promise<BotIdVerdict>;
|
|
61
|
+
/** Lifetime of each attestation in seconds. Default 60. */
|
|
62
|
+
ttlSeconds?: number;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* A Web-standard `(request) => Response` route handler (Next.js App Router,
|
|
66
|
+
* Hono, any fetch-style runtime): runs `checkBotId()` and answers
|
|
67
|
+
* `{ token }` with the signed attestation, `no-store`. A BotID failure answers
|
|
68
|
+
* 503 so the client never sends a token that was never checked.
|
|
69
|
+
*/
|
|
70
|
+
export declare function botIdAttestationHandler(options: BotIdAttestationHandlerOptions): (request?: Request) => Promise<Response>;
|
package/dist/botid.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BOTID_SECRET_MIN_LENGTH = exports.BOTID_ATTESTATION_MAX_TTL_SECONDS = exports.BOTID_ATTESTATION_PREFIX = void 0;
|
|
4
|
+
exports.createBotIdAttestation = createBotIdAttestation;
|
|
5
|
+
exports.botIdAttestationHandler = botIdAttestationHandler;
|
|
6
|
+
const node_crypto_1 = require("node:crypto");
|
|
7
|
+
/**
|
|
8
|
+
* Vercel BotID for Atlas — the server half that runs on YOUR Vercel deployment.
|
|
9
|
+
*
|
|
10
|
+
* BotID's verdict only exists inside a Vercel-hosted request (`checkBotId()`
|
|
11
|
+
* from `botid/server` reads signals Vercel's edge attaches). Atlas is not that
|
|
12
|
+
* request, so your route runs `checkBotId()` and turns the verdict into a short
|
|
13
|
+
* signed attestation; the browser sends it to Atlas as `captcha_token`, and
|
|
14
|
+
* Atlas checks the signature, freshness and `isBot === false`, and spends it
|
|
15
|
+
* (each attestation passes once).
|
|
16
|
+
*
|
|
17
|
+
* // app/api/atlas/botid/route.ts (Next.js on Vercel)
|
|
18
|
+
* import { checkBotId } from 'botid/server';
|
|
19
|
+
* import { botIdAttestationHandler } from '@atlasauth/backend';
|
|
20
|
+
* export const POST = botIdAttestationHandler({
|
|
21
|
+
* secret: process.env.ATLAS_BOTID_SECRET!,
|
|
22
|
+
* checkBotId,
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* The same secret is stored in Atlas for the `vercel_botid` captcha provider.
|
|
26
|
+
* Protect the route with BotID on the client (`initBotId({ protect: [{ path:
|
|
27
|
+
* '/api/atlas/botid', method: 'POST' }] })`) and set the captcha's
|
|
28
|
+
* `attestationUrl` to it, so the prebuilt components fetch a verdict on submit.
|
|
29
|
+
*
|
|
30
|
+
* Format (version 1): `atlas_botid.v1.<payload>.<sig>` — `payload` is base64url
|
|
31
|
+
* JSON `{ v: 1, is_bot, verified_bot, iat, exp, jti }`, `sig` is base64url
|
|
32
|
+
* HMAC-SHA256 over `atlas_botid.v1.<payload>` keyed by the shared secret.
|
|
33
|
+
*/
|
|
34
|
+
/** The prefix every attestation carries. */
|
|
35
|
+
exports.BOTID_ATTESTATION_PREFIX = 'atlas_botid.v1.';
|
|
36
|
+
/** Atlas refuses attestations that live longer than this, in seconds. */
|
|
37
|
+
exports.BOTID_ATTESTATION_MAX_TTL_SECONDS = 300;
|
|
38
|
+
/** Atlas refuses secrets shorter than this. */
|
|
39
|
+
exports.BOTID_SECRET_MIN_LENGTH = 32;
|
|
40
|
+
/**
|
|
41
|
+
* Sign a BotID verdict for Atlas. Throws when the secret is too short (Atlas
|
|
42
|
+
* would refuse every attestation it signs). A bot verdict is still signed — it
|
|
43
|
+
* is Atlas that refuses it — so your route needs no branching.
|
|
44
|
+
*/
|
|
45
|
+
function createBotIdAttestation(options) {
|
|
46
|
+
const { secret, verdict } = options;
|
|
47
|
+
if (typeof secret !== 'string' || secret.length < exports.BOTID_SECRET_MIN_LENGTH) {
|
|
48
|
+
throw new Error(`The BotID attestation secret must be at least ${exports.BOTID_SECRET_MIN_LENGTH} characters.`);
|
|
49
|
+
}
|
|
50
|
+
const ttl = Math.min(Math.max(Math.floor(options.ttlSeconds ?? 60), 1), exports.BOTID_ATTESTATION_MAX_TTL_SECONDS);
|
|
51
|
+
const iat = Math.floor((options.now ?? Date.now()) / 1000);
|
|
52
|
+
const payload = Buffer.from(JSON.stringify({
|
|
53
|
+
v: 1,
|
|
54
|
+
is_bot: verdict.isBot !== false,
|
|
55
|
+
verified_bot: verdict.isVerifiedBot === true,
|
|
56
|
+
iat,
|
|
57
|
+
exp: iat + ttl,
|
|
58
|
+
jti: (0, node_crypto_1.randomBytes)(18).toString('base64url'),
|
|
59
|
+
}), 'utf8').toString('base64url');
|
|
60
|
+
const sig = (0, node_crypto_1.createHmac)('sha256', secret).update(exports.BOTID_ATTESTATION_PREFIX + payload).digest('base64url');
|
|
61
|
+
return `${exports.BOTID_ATTESTATION_PREFIX}${payload}.${sig}`;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A Web-standard `(request) => Response` route handler (Next.js App Router,
|
|
65
|
+
* Hono, any fetch-style runtime): runs `checkBotId()` and answers
|
|
66
|
+
* `{ token }` with the signed attestation, `no-store`. A BotID failure answers
|
|
67
|
+
* 503 so the client never sends a token that was never checked.
|
|
68
|
+
*/
|
|
69
|
+
function botIdAttestationHandler(options) {
|
|
70
|
+
return async () => {
|
|
71
|
+
let verdict;
|
|
72
|
+
try {
|
|
73
|
+
verdict = await options.checkBotId();
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return new Response(JSON.stringify({ error: 'botid_unavailable' }), {
|
|
77
|
+
status: 503,
|
|
78
|
+
headers: { 'content-type': 'application/json', 'cache-control': 'no-store' },
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
const token = createBotIdAttestation({ secret: options.secret, verdict, ttlSeconds: options.ttlSeconds });
|
|
82
|
+
return new Response(JSON.stringify({ token }), {
|
|
83
|
+
status: 200,
|
|
84
|
+
headers: { 'content-type': 'application/json', 'cache-control': 'no-store' },
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=botid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"botid.js","sourceRoot":"","sources":["../src/botid.ts"],"names":[],"mappings":";;;AA8DA,wDAoBC;AAiBD,0DAiBC;AApHD,6CAAsD;AAEtD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,4CAA4C;AAC/B,QAAA,wBAAwB,GAAG,iBAAiB,CAAC;AAE1D,yEAAyE;AAC5D,QAAA,iCAAiC,GAAG,GAAG,CAAC;AAErD,+CAA+C;AAClC,QAAA,uBAAuB,GAAG,EAAE,CAAC;AAoB1C;;;;GAIG;AACH,SAAgB,sBAAsB,CAAC,OAAsC;IAC3E,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACpC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,+BAAuB,EAAE,CAAC;QAC1E,MAAM,IAAI,KAAK,CAAC,iDAAiD,+BAAuB,cAAc,CAAC,CAAC;IAC1G,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,yCAAiC,CAAC,CAAC;IAC3G,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CACzB,IAAI,CAAC,SAAS,CAAC;QACb,CAAC,EAAE,CAAC;QACJ,MAAM,EAAE,OAAO,CAAC,KAAK,KAAK,KAAK;QAC/B,YAAY,EAAE,OAAO,CAAC,aAAa,KAAK,IAAI;QAC5C,GAAG;QACH,GAAG,EAAE,GAAG,GAAG,GAAG;QACd,GAAG,EAAE,IAAA,yBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;KAC3C,CAAC,EACF,MAAM,CACP,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACxB,MAAM,GAAG,GAAG,IAAA,wBAAU,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,gCAAwB,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACxG,OAAO,GAAG,gCAAwB,GAAG,OAAO,IAAI,GAAG,EAAE,CAAC;AACxD,CAAC;AAWD;;;;;GAKG;AACH,SAAgB,uBAAuB,CAAC,OAAuC;IAC7E,OAAO,KAAK,IAAI,EAAE;QAChB,IAAI,OAAqB,CAAC;QAC1B,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,EAAE;gBAClE,MAAM,EAAE,GAAG;gBACX,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,eAAe,EAAE,UAAU,EAAE;aAC7E,CAAC,CAAC;QACL,CAAC;QACD,MAAM,KAAK,GAAG,sBAAsB,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;QAC1G,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;YAC7C,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,eAAe,EAAE,UAAU,EAAE;SAC7E,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { type RequestFn } from './request';
|
|
2
|
+
import type { Action, ActionTrigger } from './actions';
|
|
3
|
+
import type { ListPage } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* §actions gallery — browse reusable Action templates (first-party and
|
|
6
|
+
* community), install one into the instance as a DISABLED action, keep installed
|
|
7
|
+
* actions up to date, and publish your own templates for review.
|
|
8
|
+
*/
|
|
9
|
+
/** Every trigger a template can target (a superset of the classic three). */
|
|
10
|
+
export type GalleryTrigger = ActionTrigger | 'pre_organization_create' | 'pre_member_add' | 'pre_invitation_create';
|
|
11
|
+
/** A secret a template reads, declared by NAME; values are never part of a template. */
|
|
12
|
+
export interface ActionTemplateSecret {
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
required: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface ActionGalleryEntry {
|
|
18
|
+
object: 'action_template';
|
|
19
|
+
source: 'builtin' | 'community';
|
|
20
|
+
slug: string;
|
|
21
|
+
name: string;
|
|
22
|
+
summary: string;
|
|
23
|
+
trigger: GalleryTrigger;
|
|
24
|
+
category: string;
|
|
25
|
+
tags: string[];
|
|
26
|
+
/** SPDX licence id. */
|
|
27
|
+
license: string;
|
|
28
|
+
author: {
|
|
29
|
+
name: string;
|
|
30
|
+
first_party: boolean;
|
|
31
|
+
};
|
|
32
|
+
verified: boolean;
|
|
33
|
+
featured: boolean;
|
|
34
|
+
install_count: number;
|
|
35
|
+
latest_version: string;
|
|
36
|
+
/** The code sends outbound requests with `api.http`. */
|
|
37
|
+
uses_http: boolean;
|
|
38
|
+
secrets: ActionTemplateSecret[];
|
|
39
|
+
updated_at: number | null;
|
|
40
|
+
}
|
|
41
|
+
export interface ActionGalleryDetail extends ActionGalleryEntry {
|
|
42
|
+
/** Markdown. */
|
|
43
|
+
description: string;
|
|
44
|
+
code: string;
|
|
45
|
+
changelog: string | null;
|
|
46
|
+
repository_url: string | null;
|
|
47
|
+
versions: Array<{
|
|
48
|
+
version: string;
|
|
49
|
+
changelog: string | null;
|
|
50
|
+
released_at: number | null;
|
|
51
|
+
}>;
|
|
52
|
+
}
|
|
53
|
+
export interface ActionGalleryFilter {
|
|
54
|
+
q?: string;
|
|
55
|
+
category?: string;
|
|
56
|
+
trigger?: GalleryTrigger;
|
|
57
|
+
source?: 'builtin' | 'community';
|
|
58
|
+
}
|
|
59
|
+
export interface InstallTemplateBody {
|
|
60
|
+
/** A specific approved version (default: the latest). */
|
|
61
|
+
version?: string;
|
|
62
|
+
/** The action's name (default: the template's). */
|
|
63
|
+
name?: string;
|
|
64
|
+
/** Values for the secrets the template declares. Write-only. */
|
|
65
|
+
secrets?: Record<string, string>;
|
|
66
|
+
}
|
|
67
|
+
export interface ActionGalleryInstallResult {
|
|
68
|
+
object: 'action_gallery_install';
|
|
69
|
+
/** The new action: disabled and not bound to any flow yet. */
|
|
70
|
+
action: Action;
|
|
71
|
+
template: {
|
|
72
|
+
slug: string;
|
|
73
|
+
source: 'builtin' | 'community';
|
|
74
|
+
version: string;
|
|
75
|
+
};
|
|
76
|
+
install_id: string;
|
|
77
|
+
/** Required secrets you have not supplied yet. */
|
|
78
|
+
missing_secrets: string[];
|
|
79
|
+
}
|
|
80
|
+
export interface ActionGalleryInstallation {
|
|
81
|
+
object: 'action_gallery_installation';
|
|
82
|
+
action_id: string;
|
|
83
|
+
action_name: string;
|
|
84
|
+
enabled: boolean;
|
|
85
|
+
trigger: string;
|
|
86
|
+
source: 'builtin' | 'community';
|
|
87
|
+
template_slug: string;
|
|
88
|
+
installed_version: string;
|
|
89
|
+
latest_version: string | null;
|
|
90
|
+
update_available: boolean;
|
|
91
|
+
missing_secrets: string[];
|
|
92
|
+
update_requires_secrets: string[];
|
|
93
|
+
installed_at: number;
|
|
94
|
+
updated_at: number;
|
|
95
|
+
}
|
|
96
|
+
export interface ActionGalleryUpdateResult {
|
|
97
|
+
object: 'action_gallery_update';
|
|
98
|
+
/** false when the action already runs the latest version. */
|
|
99
|
+
updated: boolean;
|
|
100
|
+
action: Action;
|
|
101
|
+
from_version?: string;
|
|
102
|
+
version: string;
|
|
103
|
+
}
|
|
104
|
+
export type ActionTemplateStatus = 'draft' | 'in_review' | 'published' | 'unlisted' | 'rejected' | 'banned';
|
|
105
|
+
export interface ActionTemplateVersion {
|
|
106
|
+
object: 'action_template_version';
|
|
107
|
+
version: string;
|
|
108
|
+
status: 'draft' | 'pending_review' | 'approved' | 'rejected';
|
|
109
|
+
trigger: GalleryTrigger;
|
|
110
|
+
secrets: ActionTemplateSecret[];
|
|
111
|
+
changelog: string | null;
|
|
112
|
+
/** Why staff rejected it, when they did. */
|
|
113
|
+
review_note: string | null;
|
|
114
|
+
code: string;
|
|
115
|
+
submitted_at: number | null;
|
|
116
|
+
reviewed_at: number | null;
|
|
117
|
+
created_at: number;
|
|
118
|
+
}
|
|
119
|
+
/** A template this instance publishes. */
|
|
120
|
+
export interface ActionTemplate {
|
|
121
|
+
object: 'action_template';
|
|
122
|
+
id: string;
|
|
123
|
+
slug: string;
|
|
124
|
+
name: string;
|
|
125
|
+
author_name: string;
|
|
126
|
+
summary: string;
|
|
127
|
+
description: string | null;
|
|
128
|
+
category: string;
|
|
129
|
+
tags: string[];
|
|
130
|
+
trigger: GalleryTrigger;
|
|
131
|
+
license: string;
|
|
132
|
+
repository_url: string | null;
|
|
133
|
+
status: ActionTemplateStatus;
|
|
134
|
+
latest_version: string | null;
|
|
135
|
+
verified: boolean;
|
|
136
|
+
featured: boolean;
|
|
137
|
+
install_count: number;
|
|
138
|
+
view_count: number;
|
|
139
|
+
published_at: number | null;
|
|
140
|
+
created_at: number;
|
|
141
|
+
updated_at: number;
|
|
142
|
+
versions: ActionTemplateVersion[];
|
|
143
|
+
}
|
|
144
|
+
export interface ActionTemplateListing {
|
|
145
|
+
slug?: string;
|
|
146
|
+
name?: string;
|
|
147
|
+
/** Shown as the author on the gallery. */
|
|
148
|
+
author_name?: string;
|
|
149
|
+
summary?: string;
|
|
150
|
+
/** Markdown. */
|
|
151
|
+
description?: string;
|
|
152
|
+
category?: string;
|
|
153
|
+
tags?: string[];
|
|
154
|
+
trigger?: GalleryTrigger;
|
|
155
|
+
/** SPDX id (MIT, Apache-2.0, BSD-3-Clause, ISC, MPL-2.0, …). */
|
|
156
|
+
license?: string;
|
|
157
|
+
repository_url?: string | null;
|
|
158
|
+
}
|
|
159
|
+
export interface NewTemplateVersion {
|
|
160
|
+
/** MAJOR.MINOR.PATCH, higher than every existing version. */
|
|
161
|
+
version: string;
|
|
162
|
+
code: string;
|
|
163
|
+
secrets?: ActionTemplateSecret[];
|
|
164
|
+
changelog?: string;
|
|
165
|
+
/** Send to review right away. */
|
|
166
|
+
submit?: boolean;
|
|
167
|
+
}
|
|
168
|
+
export interface CreateActionTemplateBody extends ActionTemplateListing {
|
|
169
|
+
slug: string;
|
|
170
|
+
name: string;
|
|
171
|
+
author_name: string;
|
|
172
|
+
trigger: GalleryTrigger;
|
|
173
|
+
/** Optionally the first version in the same call. */
|
|
174
|
+
version?: string;
|
|
175
|
+
code?: string;
|
|
176
|
+
secrets?: ActionTemplateSecret[];
|
|
177
|
+
changelog?: string;
|
|
178
|
+
submit?: boolean;
|
|
179
|
+
}
|
|
180
|
+
export declare function actionGalleryResource(request: RequestFn): {
|
|
181
|
+
/** The gallery, best first. */
|
|
182
|
+
list(filter?: ActionGalleryFilter): Promise<ListPage<ActionGalleryEntry>>;
|
|
183
|
+
/** One template with its code, secret names and versions. */
|
|
184
|
+
get(slug: string): Promise<ActionGalleryDetail>;
|
|
185
|
+
/** Install as a new, disabled action. Supply secrets, bind it, then enable it. */
|
|
186
|
+
install(slug: string, body?: InstallTemplateBody, idempotencyKey?: string): Promise<ActionGalleryInstallResult>;
|
|
187
|
+
/** Actions installed from the gallery, with update status. */
|
|
188
|
+
installs(): Promise<ListPage<ActionGalleryInstallation>>;
|
|
189
|
+
/** Move an installed action to its template's latest version. */
|
|
190
|
+
update(actionId: string, body?: {
|
|
191
|
+
secrets?: Record<string, string>;
|
|
192
|
+
}): Promise<ActionGalleryUpdateResult>;
|
|
193
|
+
};
|
|
194
|
+
export declare function actionTemplatesResource(request: RequestFn): {
|
|
195
|
+
list(): Promise<ListPage<ActionTemplate>>;
|
|
196
|
+
create(body: CreateActionTemplateBody, idempotencyKey?: string): Promise<ActionTemplate>;
|
|
197
|
+
get(id: string): Promise<ActionTemplate>;
|
|
198
|
+
update(id: string, body: ActionTemplateListing): Promise<ActionTemplate>;
|
|
199
|
+
delete(id: string): Promise<{
|
|
200
|
+
object: "action_template";
|
|
201
|
+
id: string;
|
|
202
|
+
deleted: true;
|
|
203
|
+
}>;
|
|
204
|
+
addVersion(id: string, body: NewTemplateVersion): Promise<ActionTemplateVersion>;
|
|
205
|
+
submitVersion(id: string, version: string): Promise<ActionTemplateVersion>;
|
|
206
|
+
deleteVersion(id: string, version: string): Promise<{
|
|
207
|
+
object: "action_template_version";
|
|
208
|
+
version: string;
|
|
209
|
+
deleted: true;
|
|
210
|
+
}>;
|
|
211
|
+
/** List an approved template again after unlisting it. */
|
|
212
|
+
publish(id: string): Promise<ActionTemplate>;
|
|
213
|
+
/** Hide a template from the gallery (installs keep working). */
|
|
214
|
+
unlist(id: string): Promise<ActionTemplate>;
|
|
215
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.actionGalleryResource = actionGalleryResource;
|
|
4
|
+
exports.actionTemplatesResource = actionTemplatesResource;
|
|
5
|
+
const request_1 = require("./request");
|
|
6
|
+
function actionGalleryResource(request) {
|
|
7
|
+
return {
|
|
8
|
+
/** The gallery, best first. */
|
|
9
|
+
list(filter = {}) {
|
|
10
|
+
return request({ method: 'GET', path: '/v1/action_gallery', query: { ...filter } });
|
|
11
|
+
},
|
|
12
|
+
/** One template with its code, secret names and versions. */
|
|
13
|
+
get(slug) {
|
|
14
|
+
return request({ method: 'GET', path: `/v1/action_gallery/${(0, request_1.enc)(slug)}` });
|
|
15
|
+
},
|
|
16
|
+
/** Install as a new, disabled action. Supply secrets, bind it, then enable it. */
|
|
17
|
+
install(slug, body = {}, idempotencyKey) {
|
|
18
|
+
return request({ method: 'POST', path: `/v1/action_gallery/${(0, request_1.enc)(slug)}/install`, body, idempotencyKey });
|
|
19
|
+
},
|
|
20
|
+
/** Actions installed from the gallery, with update status. */
|
|
21
|
+
installs() {
|
|
22
|
+
return request({ method: 'GET', path: '/v1/action_gallery_installs' });
|
|
23
|
+
},
|
|
24
|
+
/** Move an installed action to its template's latest version. */
|
|
25
|
+
update(actionId, body = {}) {
|
|
26
|
+
return request({ method: 'POST', path: `/v1/actions/${(0, request_1.enc)(actionId)}/gallery_update`, body });
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function actionTemplatesResource(request) {
|
|
31
|
+
return {
|
|
32
|
+
list() {
|
|
33
|
+
return request({ method: 'GET', path: '/v1/action_templates' });
|
|
34
|
+
},
|
|
35
|
+
create(body, idempotencyKey) {
|
|
36
|
+
return request({ method: 'POST', path: '/v1/action_templates', body, idempotencyKey });
|
|
37
|
+
},
|
|
38
|
+
get(id) {
|
|
39
|
+
return request({ method: 'GET', path: `/v1/action_templates/${(0, request_1.enc)(id)}` });
|
|
40
|
+
},
|
|
41
|
+
update(id, body) {
|
|
42
|
+
return request({ method: 'PATCH', path: `/v1/action_templates/${(0, request_1.enc)(id)}`, body });
|
|
43
|
+
},
|
|
44
|
+
delete(id) {
|
|
45
|
+
return request({ method: 'DELETE', path: `/v1/action_templates/${(0, request_1.enc)(id)}` });
|
|
46
|
+
},
|
|
47
|
+
addVersion(id, body) {
|
|
48
|
+
return request({ method: 'POST', path: `/v1/action_templates/${(0, request_1.enc)(id)}/versions`, body });
|
|
49
|
+
},
|
|
50
|
+
submitVersion(id, version) {
|
|
51
|
+
return request({ method: 'POST', path: `/v1/action_templates/${(0, request_1.enc)(id)}/versions/${(0, request_1.enc)(version)}/submit` });
|
|
52
|
+
},
|
|
53
|
+
deleteVersion(id, version) {
|
|
54
|
+
return request({ method: 'DELETE', path: `/v1/action_templates/${(0, request_1.enc)(id)}/versions/${(0, request_1.enc)(version)}` });
|
|
55
|
+
},
|
|
56
|
+
/** List an approved template again after unlisting it. */
|
|
57
|
+
publish(id) {
|
|
58
|
+
return request({ method: 'POST', path: `/v1/action_templates/${(0, request_1.enc)(id)}/publish` });
|
|
59
|
+
},
|
|
60
|
+
/** Hide a template from the gallery (installs keep working). */
|
|
61
|
+
unlist(id) {
|
|
62
|
+
return request({ method: 'POST', path: `/v1/action_templates/${(0, request_1.enc)(id)}/unlist` });
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=action-gallery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action-gallery.js","sourceRoot":"","sources":["../../src/client/action-gallery.ts"],"names":[],"mappings":"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"}
|
package/dist/client/actions.d.ts
CHANGED
|
@@ -40,15 +40,34 @@ export interface ActionTestEvent {
|
|
|
40
40
|
email?: string;
|
|
41
41
|
emailVerified?: boolean;
|
|
42
42
|
metadata?: Record<string, unknown>;
|
|
43
|
+
/** The user's organization memberships, as `event.user.organizations`. */
|
|
44
|
+
organizations?: Array<{
|
|
45
|
+
id: string;
|
|
46
|
+
slug: string;
|
|
47
|
+
name: string;
|
|
48
|
+
role: string;
|
|
49
|
+
}>;
|
|
43
50
|
};
|
|
44
51
|
connection?: {
|
|
45
52
|
strategy?: string;
|
|
46
53
|
};
|
|
54
|
+
/** `country` is the ISO code `event.request.country` should carry. */
|
|
47
55
|
request?: {
|
|
48
56
|
ip?: string;
|
|
49
57
|
user_agent?: string;
|
|
58
|
+
country?: string;
|
|
50
59
|
};
|
|
51
60
|
}
|
|
61
|
+
/** An outbound request the code queued with `api.http` (a dry run sends nothing). */
|
|
62
|
+
export interface ActionTestHttpRequest {
|
|
63
|
+
method: 'GET' | 'POST';
|
|
64
|
+
/** Query values are masked. */
|
|
65
|
+
url: string;
|
|
66
|
+
/** Header names only; values are never echoed. */
|
|
67
|
+
header_names: string[];
|
|
68
|
+
has_body: boolean;
|
|
69
|
+
save_response_as: string | null;
|
|
70
|
+
}
|
|
52
71
|
/** What an action produced against a sample event — no real data is touched. */
|
|
53
72
|
export interface ActionTestResult {
|
|
54
73
|
object: 'action_test_result';
|
|
@@ -59,6 +78,8 @@ export interface ActionTestResult {
|
|
|
59
78
|
id_token_claims: Record<string, unknown>;
|
|
60
79
|
app_metadata: Record<string, unknown>;
|
|
61
80
|
logs: string[];
|
|
81
|
+
/** What the code queued with `api.http`; sent only on a real post_login / post_user_registration run. */
|
|
82
|
+
http_requests?: ActionTestHttpRequest[];
|
|
62
83
|
error: string | null;
|
|
63
84
|
}
|
|
64
85
|
/** The ordered binding list for a trigger, replaced atomically as a set. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/client/actions.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../../src/client/actions.ts"],"names":[],"mappings":";;AAwFA,0CAkCC;AA1HD,uCAAgD;AAwFhD,SAAgB,eAAe,CAAC,OAAkB;IAChD,OAAO;QACL,IAAI;YACF,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,CAAC,IAAsB,EAAE,cAAuB;YACpD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAC;QAChF,CAAC;QACD,GAAG,CAAC,EAAU;YACZ,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,CAAC,EAAU,EAAE,IAAsB;YACvC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,CAAC,EAAU;YACf,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,IAAA,aAAG,EAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,2EAA2E;QAC3E,IAAI,CAAC,EAAU,EAAE,QAAyB,EAAE;YAC1C,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,IAAA,aAAG,EAAC,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAC3F,CAAC;QACD,oDAAoD;QACpD,WAAW,CAAC,OAAsB;YAChC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,wBAAwB,IAAA,aAAG,EAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QAClF,CAAC;QACD,+CAA+C;QAC/C,WAAW,CAAC,OAAsB,EAAE,SAAmB;YACrD,OAAO,OAAO,CAAC;gBACb,MAAM,EAAE,KAAK;gBACb,IAAI,EAAE,wBAAwB,IAAA,aAAG,EAAC,OAAO,CAAC,EAAE;gBAC5C,IAAI,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE;aAChC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -25,8 +25,39 @@ export interface AttackProtection {
|
|
|
25
25
|
secret_set: boolean;
|
|
26
26
|
managed_by: 'auth_config_and_captcha_secret';
|
|
27
27
|
};
|
|
28
|
+
/** Read-only reflections of auth_config.attackProtection. */
|
|
29
|
+
country_restrictions?: {
|
|
30
|
+
mode: 'off' | 'allow' | 'deny';
|
|
31
|
+
countries: string[];
|
|
32
|
+
sign_up: boolean;
|
|
33
|
+
sign_in: boolean;
|
|
34
|
+
block_unknown: boolean;
|
|
35
|
+
managed_by: 'auth_config';
|
|
36
|
+
};
|
|
37
|
+
device_accounts?: {
|
|
38
|
+
enabled: boolean;
|
|
39
|
+
max_accounts: number;
|
|
40
|
+
window_days: number;
|
|
41
|
+
managed_by: 'auth_config';
|
|
42
|
+
};
|
|
43
|
+
/** Dormant-account reactivation alerts (writable). */
|
|
44
|
+
dormant_accounts?: DormantAccountsSettings;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* When an account idle for `threshold_days` signs in again: an audit entry, the
|
|
48
|
+
* `user.reactivated` webhook, an optional security notice to the user, and —
|
|
49
|
+
* with `require_mfa` — a second-factor step-up (`on_no_factor` decides for an
|
|
50
|
+
* account without one).
|
|
51
|
+
*/
|
|
52
|
+
export interface DormantAccountsSettings {
|
|
53
|
+
enabled: boolean;
|
|
54
|
+
/** 1–3650; default 90. */
|
|
55
|
+
threshold_days: number;
|
|
56
|
+
require_mfa: boolean;
|
|
57
|
+
on_no_factor: 'allow' | 'require_enroll' | 'block';
|
|
58
|
+
notify_user: boolean;
|
|
28
59
|
}
|
|
29
|
-
/**
|
|
60
|
+
/** The writable parts; the rest of the object is read-only. */
|
|
30
61
|
export interface UpdateAttackProtectionBody {
|
|
31
62
|
brute_force?: {
|
|
32
63
|
enabled?: boolean;
|
|
@@ -34,6 +65,7 @@ export interface UpdateAttackProtectionBody {
|
|
|
34
65
|
breached_password?: {
|
|
35
66
|
enabled?: boolean;
|
|
36
67
|
};
|
|
68
|
+
dormant_accounts?: Partial<DormantAccountsSettings>;
|
|
37
69
|
}
|
|
38
70
|
export declare function attackProtectionResource(request: RequestFn): {
|
|
39
71
|
get(): Promise<AttackProtection>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attack-protection.js","sourceRoot":"","sources":["../../src/client/attack-protection.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"attack-protection.js","sourceRoot":"","sources":["../../src/client/attack-protection.ts"],"names":[],"mappings":";;AA8DA,4DASC;AATD,SAAgB,wBAAwB,CAAC,OAAkB;IACzD,OAAO;QACL,GAAG;YACD,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,MAAM,CAAC,IAAgC;YACrC,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,uBAAuB,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3E,CAAC;KACF,CAAC;AACJ,CAAC"}
|