@adonis-agora/flags 0.0.0-beta-20261112141227
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 +20 -0
- package/LICENSE +21 -0
- package/README.md +16 -0
- package/dist/assets/spa/assets/index-DdmFo7xr.js +12 -0
- package/dist/assets/spa/assets/index-DdmFo7xr.js.map +1 -0
- package/dist/assets/spa/assets/index-DhkcP3Cw.css +2 -0
- package/dist/assets/spa/index.html +26 -0
- package/dist/commands/flags_list.d.ts +9 -0
- package/dist/commands/flags_list.d.ts.map +1 -0
- package/dist/commands/flags_list.js +51 -0
- package/dist/commands/flags_list.js.map +1 -0
- package/dist/commands/flags_ops.d.ts +60 -0
- package/dist/commands/flags_ops.d.ts.map +1 -0
- package/dist/commands/flags_ops.js +253 -0
- package/dist/commands/flags_ops.js.map +1 -0
- package/dist/commands/flags_refs.d.ts +15 -0
- package/dist/commands/flags_refs.d.ts.map +1 -0
- package/dist/commands/flags_refs.js +90 -0
- package/dist/commands/flags_refs.js.map +1 -0
- package/dist/commands/flags_set.d.ts +19 -0
- package/dist/commands/flags_set.d.ts.map +1 -0
- package/dist/commands/flags_set.js +97 -0
- package/dist/commands/flags_set.js.map +1 -0
- package/dist/commands/flags_types.d.ts +18 -0
- package/dist/commands/flags_types.d.ts.map +1 -0
- package/dist/commands/flags_types.js +94 -0
- package/dist/commands/flags_types.js.map +1 -0
- package/dist/commands/flags_work.d.ts +16 -0
- package/dist/commands/flags_work.d.ts.map +1 -0
- package/dist/commands/flags_work.js +71 -0
- package/dist/commands/flags_work.js.map +1 -0
- package/dist/commands/main.d.ts +15 -0
- package/dist/commands/main.d.ts.map +1 -0
- package/dist/commands/main.js +30 -0
- package/dist/commands/main.js.map +1 -0
- package/dist/commands/shared.d.ts +21 -0
- package/dist/commands/shared.d.ts.map +1 -0
- package/dist/commands/shared.js +70 -0
- package/dist/commands/shared.js.map +1 -0
- package/dist/configure.d.ts +11 -0
- package/dist/configure.d.ts.map +1 -0
- package/dist/configure.js +32 -0
- package/dist/configure.js.map +1 -0
- package/dist/providers/dashboard_provider.d.ts +65 -0
- package/dist/providers/dashboard_provider.d.ts.map +1 -0
- package/dist/providers/dashboard_provider.js +340 -0
- package/dist/providers/dashboard_provider.js.map +1 -0
- package/dist/providers/flags_provider.d.ts +30 -0
- package/dist/providers/flags_provider.d.ts.map +1 -0
- package/dist/providers/flags_provider.js +184 -0
- package/dist/providers/flags_provider.js.map +1 -0
- package/dist/services/main.d.ts +17 -0
- package/dist/services/main.d.ts.map +1 -0
- package/dist/services/main.js +20 -0
- package/dist/services/main.js.map +1 -0
- package/dist/src/admin.d.ts +189 -0
- package/dist/src/admin.d.ts.map +1 -0
- package/dist/src/admin.js +539 -0
- package/dist/src/admin.js.map +1 -0
- package/dist/src/analytics/backend.d.ts +18 -0
- package/dist/src/analytics/backend.d.ts.map +1 -0
- package/dist/src/analytics/backend.js +25 -0
- package/dist/src/analytics/backend.js.map +1 -0
- package/dist/src/analytics/clickhouse_backend.d.ts +16 -0
- package/dist/src/analytics/clickhouse_backend.d.ts.map +1 -0
- package/dist/src/analytics/clickhouse_backend.js +48 -0
- package/dist/src/analytics/clickhouse_backend.js.map +1 -0
- package/dist/src/analytics/duckdb.d.ts +39 -0
- package/dist/src/analytics/duckdb.d.ts.map +1 -0
- package/dist/src/analytics/duckdb.js +117 -0
- package/dist/src/analytics/duckdb.js.map +1 -0
- package/dist/src/analytics/lucid_backend.d.ts +16 -0
- package/dist/src/analytics/lucid_backend.d.ts.map +1 -0
- package/dist/src/analytics/lucid_backend.js +45 -0
- package/dist/src/analytics/lucid_backend.js.map +1 -0
- package/dist/src/analytics/metrics.d.ts +50 -0
- package/dist/src/analytics/metrics.d.ts.map +1 -0
- package/dist/src/analytics/metrics.js +42 -0
- package/dist/src/analytics/metrics.js.map +1 -0
- package/dist/src/analytics/results.d.ts +80 -0
- package/dist/src/analytics/results.d.ts.map +1 -0
- package/dist/src/analytics/results.js +143 -0
- package/dist/src/analytics/results.js.map +1 -0
- package/dist/src/dashboard/access_denied_page.d.ts +100 -0
- package/dist/src/dashboard/access_denied_page.d.ts.map +1 -0
- package/dist/src/dashboard/access_denied_page.js +262 -0
- package/dist/src/dashboard/access_denied_page.js.map +1 -0
- package/dist/src/dashboard/actor.d.ts +12 -0
- package/dist/src/dashboard/actor.d.ts.map +1 -0
- package/dist/src/dashboard/actor.js +33 -0
- package/dist/src/dashboard/actor.js.map +1 -0
- package/dist/src/dashboard/authorize_decision.d.ts +48 -0
- package/dist/src/dashboard/authorize_decision.d.ts.map +1 -0
- package/dist/src/dashboard/authorize_decision.js +44 -0
- package/dist/src/dashboard/authorize_decision.js.map +1 -0
- package/dist/src/dashboard/console_authorize.d.ts +77 -0
- package/dist/src/dashboard/console_authorize.d.ts.map +1 -0
- package/dist/src/dashboard/console_authorize.js +104 -0
- package/dist/src/dashboard/console_authorize.js.map +1 -0
- package/dist/src/dashboard/define_config.d.ts +71 -0
- package/dist/src/dashboard/define_config.d.ts.map +1 -0
- package/dist/src/dashboard/define_config.js +18 -0
- package/dist/src/dashboard/define_config.js.map +1 -0
- package/dist/src/dashboard/handlers.d.ts +172 -0
- package/dist/src/dashboard/handlers.d.ts.map +1 -0
- package/dist/src/dashboard/handlers.js +949 -0
- package/dist/src/dashboard/handlers.js.map +1 -0
- package/dist/src/dashboard/index.d.ts +15 -0
- package/dist/src/dashboard/index.d.ts.map +1 -0
- package/dist/src/dashboard/index.js +10 -0
- package/dist/src/dashboard/index.js.map +1 -0
- package/dist/src/dashboard/shape.d.ts +12 -0
- package/dist/src/dashboard/shape.d.ts.map +1 -0
- package/dist/src/dashboard/shape.js +232 -0
- package/dist/src/dashboard/shape.js.map +1 -0
- package/dist/src/dashboard/spa.d.ts +34 -0
- package/dist/src/dashboard/spa.d.ts.map +1 -0
- package/dist/src/dashboard/spa.js +50 -0
- package/dist/src/dashboard/spa.js.map +1 -0
- package/dist/src/declare.d.ts +85 -0
- package/dist/src/declare.d.ts.map +1 -0
- package/dist/src/declare.js +62 -0
- package/dist/src/declare.js.map +1 -0
- package/dist/src/define_config.d.ts +256 -0
- package/dist/src/define_config.d.ts.map +1 -0
- package/dist/src/define_config.js +90 -0
- package/dist/src/define_config.js.map +1 -0
- package/dist/src/durable.d.ts +29 -0
- package/dist/src/durable.d.ts.map +1 -0
- package/dist/src/durable.js +55 -0
- package/dist/src/durable.js.map +1 -0
- package/dist/src/enrichers.d.ts +51 -0
- package/dist/src/enrichers.d.ts.map +1 -0
- package/dist/src/enrichers.js +105 -0
- package/dist/src/enrichers.js.map +1 -0
- package/dist/src/events/buffer.d.ts +38 -0
- package/dist/src/events/buffer.d.ts.map +1 -0
- package/dist/src/events/buffer.js +86 -0
- package/dist/src/events/buffer.js.map +1 -0
- package/dist/src/events/event.d.ts +42 -0
- package/dist/src/events/event.d.ts.map +1 -0
- package/dist/src/events/event.js +82 -0
- package/dist/src/events/event.js.map +1 -0
- package/dist/src/http/browser.d.ts +33 -0
- package/dist/src/http/browser.d.ts.map +1 -0
- package/dist/src/http/browser.js +81 -0
- package/dist/src/http/browser.js.map +1 -0
- package/dist/src/http/browser_api.d.ts +48 -0
- package/dist/src/http/browser_api.d.ts.map +1 -0
- package/dist/src/http/browser_api.js +273 -0
- package/dist/src/http/browser_api.js.map +1 -0
- package/dist/src/http/browser_tokens.d.ts +27 -0
- package/dist/src/http/browser_tokens.d.ts.map +1 -0
- package/dist/src/http/browser_tokens.js +48 -0
- package/dist/src/http/browser_tokens.js.map +1 -0
- package/dist/src/http/control_plane.d.ts +58 -0
- package/dist/src/http/control_plane.d.ts.map +1 -0
- package/dist/src/http/control_plane.js +318 -0
- package/dist/src/http/control_plane.js.map +1 -0
- package/dist/src/http/csrf.d.ts +22 -0
- package/dist/src/http/csrf.d.ts.map +1 -0
- package/dist/src/http/csrf.js +24 -0
- package/dist/src/http/csrf.js.map +1 -0
- package/dist/src/http/edge_tag.d.ts +55 -0
- package/dist/src/http/edge_tag.d.ts.map +1 -0
- package/dist/src/http/edge_tag.js +45 -0
- package/dist/src/http/edge_tag.js.map +1 -0
- package/dist/src/http/flag_middleware.d.ts +27 -0
- package/dist/src/http/flag_middleware.d.ts.map +1 -0
- package/dist/src/http/flag_middleware.js +30 -0
- package/dist/src/http/flag_middleware.js.map +1 -0
- package/dist/src/http/flags_middleware.d.ts +20 -0
- package/dist/src/http/flags_middleware.d.ts.map +1 -0
- package/dist/src/http/flags_middleware.js +20 -0
- package/dist/src/http/flags_middleware.js.map +1 -0
- package/dist/src/http/subject_resolver.d.ts +45 -0
- package/dist/src/http/subject_resolver.d.ts.map +1 -0
- package/dist/src/http/subject_resolver.js +93 -0
- package/dist/src/http/subject_resolver.js.map +1 -0
- package/dist/src/identity.d.ts +82 -0
- package/dist/src/identity.d.ts.map +1 -0
- package/dist/src/identity.js +100 -0
- package/dist/src/identity.js.map +1 -0
- package/dist/src/index.d.ts +41 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +34 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/manager.d.ts +154 -0
- package/dist/src/manager.d.ts.map +1 -0
- package/dist/src/manager.js +333 -0
- package/dist/src/manager.js.map +1 -0
- package/dist/src/openfeature/provider.d.ts +36 -0
- package/dist/src/openfeature/provider.d.ts.map +1 -0
- package/dist/src/openfeature/provider.js +82 -0
- package/dist/src/openfeature/provider.js.map +1 -0
- package/dist/src/relay/relay.d.ts +36 -0
- package/dist/src/relay/relay.d.ts.map +1 -0
- package/dist/src/relay/relay.js +73 -0
- package/dist/src/relay/relay.js.map +1 -0
- package/dist/src/relay/results_cache.d.ts +20 -0
- package/dist/src/relay/results_cache.d.ts.map +1 -0
- package/dist/src/relay/results_cache.js +31 -0
- package/dist/src/relay/results_cache.js.map +1 -0
- package/dist/src/relay/worker.d.ts +66 -0
- package/dist/src/relay/worker.d.ts.map +1 -0
- package/dist/src/relay/worker.js +177 -0
- package/dist/src/relay/worker.js.map +1 -0
- package/dist/src/ruleset_source.d.ts +73 -0
- package/dist/src/ruleset_source.d.ts.map +1 -0
- package/dist/src/ruleset_source.js +128 -0
- package/dist/src/ruleset_source.js.map +1 -0
- package/dist/src/runtime.d.ts +70 -0
- package/dist/src/runtime.d.ts.map +1 -0
- package/dist/src/runtime.js +301 -0
- package/dist/src/runtime.js.map +1 -0
- package/dist/src/schema.d.ts +39 -0
- package/dist/src/schema.d.ts.map +1 -0
- package/dist/src/schema.js +311 -0
- package/dist/src/schema.js.map +1 -0
- package/dist/src/services/accessor.d.ts +5 -0
- package/dist/src/services/accessor.d.ts.map +1 -0
- package/dist/src/services/accessor.js +20 -0
- package/dist/src/services/accessor.js.map +1 -0
- package/dist/src/sinks/clickhouse.d.ts +41 -0
- package/dist/src/sinks/clickhouse.d.ts.map +1 -0
- package/dist/src/sinks/clickhouse.js +117 -0
- package/dist/src/sinks/clickhouse.js.map +1 -0
- package/dist/src/sinks/lucid_sink.d.ts +25 -0
- package/dist/src/sinks/lucid_sink.d.ts.map +1 -0
- package/dist/src/sinks/lucid_sink.js +87 -0
- package/dist/src/sinks/lucid_sink.js.map +1 -0
- package/dist/src/sinks/parquet_sink.d.ts +41 -0
- package/dist/src/sinks/parquet_sink.d.ts.map +1 -0
- package/dist/src/sinks/parquet_sink.js +140 -0
- package/dist/src/sinks/parquet_sink.js.map +1 -0
- package/dist/src/sinks/posthog_sink.d.ts +29 -0
- package/dist/src/sinks/posthog_sink.d.ts.map +1 -0
- package/dist/src/sinks/posthog_sink.js +65 -0
- package/dist/src/sinks/posthog_sink.js.map +1 -0
- package/dist/src/sinks/sink.d.ts +36 -0
- package/dist/src/sinks/sink.d.ts.map +1 -0
- package/dist/src/sinks/sink.js +36 -0
- package/dist/src/sinks/sink.js.map +1 -0
- package/dist/src/sql.d.ts +33 -0
- package/dist/src/sql.d.ts.map +1 -0
- package/dist/src/sql.js +66 -0
- package/dist/src/sql.js.map +1 -0
- package/dist/src/stores/lucid_store.d.ts +55 -0
- package/dist/src/stores/lucid_store.d.ts.map +1 -0
- package/dist/src/stores/lucid_store.js +412 -0
- package/dist/src/stores/lucid_store.js.map +1 -0
- package/dist/src/stores/memory_store.d.ts +38 -0
- package/dist/src/stores/memory_store.d.ts.map +1 -0
- package/dist/src/stores/memory_store.js +166 -0
- package/dist/src/stores/memory_store.js.map +1 -0
- package/dist/src/stores/store.d.ts +166 -0
- package/dist/src/stores/store.d.ts.map +1 -0
- package/dist/src/stores/store.js +67 -0
- package/dist/src/stores/store.js.map +1 -0
- package/dist/src/subject.d.ts +25 -0
- package/dist/src/subject.d.ts.map +1 -0
- package/dist/src/subject.js +30 -0
- package/dist/src/subject.js.map +1 -0
- package/dist/src/testing/index.d.ts +31 -0
- package/dist/src/testing/index.d.ts.map +1 -0
- package/dist/src/testing/index.js +60 -0
- package/dist/src/testing/index.js.map +1 -0
- package/dist/src/topology/browser_token.d.ts +48 -0
- package/dist/src/topology/browser_token.d.ts.map +1 -0
- package/dist/src/topology/browser_token.js +128 -0
- package/dist/src/topology/browser_token.js.map +1 -0
- package/dist/src/topology/remote_source.d.ts +39 -0
- package/dist/src/topology/remote_source.d.ts.map +1 -0
- package/dist/src/topology/remote_source.js +184 -0
- package/dist/src/topology/remote_source.js.map +1 -0
- package/dist/src/topology/token.d.ts +36 -0
- package/dist/src/topology/token.d.ts.map +1 -0
- package/dist/src/topology/token.js +68 -0
- package/dist/src/topology/token.js.map +1 -0
- package/dist/src/topology/verify.d.ts +88 -0
- package/dist/src/topology/verify.d.ts.map +1 -0
- package/dist/src/topology/verify.js +128 -0
- package/dist/src/topology/verify.js.map +1 -0
- package/dist/src/transports/db_transport.d.ts +55 -0
- package/dist/src/transports/db_transport.d.ts.map +1 -0
- package/dist/src/transports/db_transport.js +202 -0
- package/dist/src/transports/db_transport.js.map +1 -0
- package/dist/src/transports/http_transport.d.ts +30 -0
- package/dist/src/transports/http_transport.d.ts.map +1 -0
- package/dist/src/transports/http_transport.js +51 -0
- package/dist/src/transports/http_transport.js.map +1 -0
- package/dist/src/transports/memory_transport.d.ts +29 -0
- package/dist/src/transports/memory_transport.d.ts.map +1 -0
- package/dist/src/transports/memory_transport.js +91 -0
- package/dist/src/transports/memory_transport.js.map +1 -0
- package/dist/src/transports/redis_transport.d.ts +50 -0
- package/dist/src/transports/redis_transport.d.ts.map +1 -0
- package/dist/src/transports/redis_transport.js +107 -0
- package/dist/src/transports/redis_transport.js.map +1 -0
- package/dist/src/transports/transport.d.ts +62 -0
- package/dist/src/transports/transport.d.ts.map +1 -0
- package/dist/src/transports/transport.js +2 -0
- package/dist/src/transports/transport.js.map +1 -0
- package/dist/src/types.d.ts +30 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/usage.d.ts +18 -0
- package/dist/src/usage.d.ts.map +1 -0
- package/dist/src/usage.js +52 -0
- package/dist/src/usage.js.map +1 -0
- package/dist/stubs/config/flags.stub +50 -0
- package/dist/stubs/config/flags_dashboard.stub +35 -0
- package/dist/stubs/database/migrations/create_flags_tables.stub +27 -0
- package/dist/stubs/main.d.ts +3 -0
- package/dist/stubs/main.d.ts.map +1 -0
- package/dist/stubs/main.js +9 -0
- package/dist/stubs/main.js.map +1 -0
- package/package.json +181 -0
- package/skills/flags-basics/SKILL.md +142 -0
- package/skills/flags-deployment/SKILL.md +125 -0
- package/skills/flags-experiments/SKILL.md +99 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { HttpContext } from '@adonisjs/core/http';
|
|
2
|
+
import type { Subject, SubjectLike } from '../subject.js';
|
|
3
|
+
/** The part of `@adonis-agora/authkit-client`'s `Identity` this package reads. */
|
|
4
|
+
export interface AuthkitIdentityLike {
|
|
5
|
+
userId: string;
|
|
6
|
+
email?: string;
|
|
7
|
+
globalRoles?: string[];
|
|
8
|
+
profile?: {
|
|
9
|
+
name?: string;
|
|
10
|
+
};
|
|
11
|
+
orgId?: string | null;
|
|
12
|
+
orgSlug?: string | null;
|
|
13
|
+
orgRole?: string | null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The subject for an authkit identity: the `sub` claim as id — the same person in every app, so a
|
|
17
|
+
* user lands in the same bucket everywhere — and the verified claims as targeting attributes:
|
|
18
|
+
*
|
|
19
|
+
* | Attribute | From |
|
|
20
|
+
* |---|---|
|
|
21
|
+
* | `email`, `emailDomain` | the `email` claim |
|
|
22
|
+
* | `globalRoles` | authkit global roles (an array: `in` matches any) |
|
|
23
|
+
* | `orgId`, `orgSlug`, `orgRole` | the session's active organization |
|
|
24
|
+
*
|
|
25
|
+
* Roll out per organization with `bucketBy: 'orgId'`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function subjectFromIdentity(identity: AuthkitIdentityLike): Subject;
|
|
28
|
+
/** The authkit identity of the request, from `@adonis-agora/authkit-client` (0.x or 1.x). */
|
|
29
|
+
export declare function authkitIdentity(ctx: HttpContext): Promise<AuthkitIdentityLike | null>;
|
|
30
|
+
/**
|
|
31
|
+
* A `subject` resolver for `config/flags.ts` that uses authkit only:
|
|
32
|
+
* `subject: authkitSubject`. The default resolver already prefers authkit when it is installed.
|
|
33
|
+
*/
|
|
34
|
+
export declare function authkitSubject(ctx: HttpContext): Promise<SubjectLike>;
|
|
35
|
+
/**
|
|
36
|
+
* The default subject of `ctx.flags`:
|
|
37
|
+
*
|
|
38
|
+
* 1. the authkit identity (`ctx.authkit`, from `@adonis-agora/authkit-client`), with its claims as
|
|
39
|
+
* attributes — see {@link subjectFromIdentity};
|
|
40
|
+
* 2. otherwise `ctx.auth.user` (`@adonisjs/auth`), checking the request's credentials silently when
|
|
41
|
+
* no middleware authenticated it yet;
|
|
42
|
+
* 3. otherwise anonymous.
|
|
43
|
+
*/
|
|
44
|
+
export declare function defaultSubject(ctx: HttpContext): Promise<SubjectLike>;
|
|
45
|
+
//# sourceMappingURL=subject_resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subject_resolver.d.ts","sourceRoot":"","sources":["../../../src/http/subject_resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAO1D,kFAAkF;AAClF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,OAAO,CAW1E;AAeD,6FAA6F;AAC7F,wBAAsB,eAAe,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAS3F;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAG3E;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAc3E"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The subject for an authkit identity: the `sub` claim as id — the same person in every app, so a
|
|
3
|
+
* user lands in the same bucket everywhere — and the verified claims as targeting attributes:
|
|
4
|
+
*
|
|
5
|
+
* | Attribute | From |
|
|
6
|
+
* |---|---|
|
|
7
|
+
* | `email`, `emailDomain` | the `email` claim |
|
|
8
|
+
* | `globalRoles` | authkit global roles (an array: `in` matches any) |
|
|
9
|
+
* | `orgId`, `orgSlug`, `orgRole` | the session's active organization |
|
|
10
|
+
*
|
|
11
|
+
* Roll out per organization with `bucketBy: 'orgId'`.
|
|
12
|
+
*/
|
|
13
|
+
export function subjectFromIdentity(identity) {
|
|
14
|
+
const attributes = {};
|
|
15
|
+
if (identity.email) {
|
|
16
|
+
attributes.email = identity.email;
|
|
17
|
+
attributes.emailDomain = identity.email.split('@')[1]?.toLowerCase();
|
|
18
|
+
}
|
|
19
|
+
if (identity.globalRoles)
|
|
20
|
+
attributes.globalRoles = identity.globalRoles;
|
|
21
|
+
if (identity.orgId)
|
|
22
|
+
attributes.orgId = identity.orgId;
|
|
23
|
+
if (identity.orgSlug)
|
|
24
|
+
attributes.orgSlug = identity.orgSlug;
|
|
25
|
+
if (identity.orgRole)
|
|
26
|
+
attributes.orgRole = identity.orgRole;
|
|
27
|
+
return { id: identity.userId, type: 'user', attributes };
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The request's authkit surface: `ctx.authkit` (authkit-client 1.x), else `ctx.auth` when it is
|
|
31
|
+
* authkit's authenticator (authkit-client 0.x's `authkit_middleware` puts it there and never sets
|
|
32
|
+
* `ctx.authkit`). `@adonisjs/auth`'s authenticator has no `getIdentity`, so it is never mistaken
|
|
33
|
+
* for it.
|
|
34
|
+
*/
|
|
35
|
+
function authkitOf(ctx) {
|
|
36
|
+
const holder = ctx;
|
|
37
|
+
if (holder.authkit && typeof holder.authkit.getIdentity === 'function')
|
|
38
|
+
return holder.authkit;
|
|
39
|
+
if (holder.auth && typeof holder.auth.getIdentity === 'function')
|
|
40
|
+
return holder.auth;
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
/** The authkit identity of the request, from `@adonis-agora/authkit-client` (0.x or 1.x). */
|
|
44
|
+
export async function authkitIdentity(ctx) {
|
|
45
|
+
const authkit = authkitOf(ctx);
|
|
46
|
+
if (!authkit)
|
|
47
|
+
return null;
|
|
48
|
+
try {
|
|
49
|
+
return await authkit.getIdentity();
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// An unreadable session is an anonymous visitor, not a flags error.
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A `subject` resolver for `config/flags.ts` that uses authkit only:
|
|
58
|
+
* `subject: authkitSubject`. The default resolver already prefers authkit when it is installed.
|
|
59
|
+
*/
|
|
60
|
+
export async function authkitSubject(ctx) {
|
|
61
|
+
const identity = await authkitIdentity(ctx);
|
|
62
|
+
return identity ? subjectFromIdentity(identity) : undefined;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The default subject of `ctx.flags`:
|
|
66
|
+
*
|
|
67
|
+
* 1. the authkit identity (`ctx.authkit`, from `@adonis-agora/authkit-client`), with its claims as
|
|
68
|
+
* attributes — see {@link subjectFromIdentity};
|
|
69
|
+
* 2. otherwise `ctx.auth.user` (`@adonisjs/auth`), checking the request's credentials silently when
|
|
70
|
+
* no middleware authenticated it yet;
|
|
71
|
+
* 3. otherwise anonymous.
|
|
72
|
+
*/
|
|
73
|
+
export async function defaultSubject(ctx) {
|
|
74
|
+
const identity = await authkitIdentity(ctx);
|
|
75
|
+
if (identity)
|
|
76
|
+
return subjectFromIdentity(identity);
|
|
77
|
+
const auth = ctx.auth;
|
|
78
|
+
if (!auth)
|
|
79
|
+
return undefined;
|
|
80
|
+
if (auth.user)
|
|
81
|
+
return auth.user;
|
|
82
|
+
if (typeof auth.check === 'function') {
|
|
83
|
+
try {
|
|
84
|
+
if (await auth.check())
|
|
85
|
+
return (auth.user ?? undefined);
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// A broken credential is an anonymous visitor, not a flags error.
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=subject_resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subject_resolver.js","sourceRoot":"","sources":["../../../src/http/subject_resolver.ts"],"names":[],"mappings":"AAuBA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAA6B;IAC/D,MAAM,UAAU,GAA4B,EAAE,CAAC;IAC/C,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,UAAU,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;QAClC,UAAU,CAAC,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;IACvE,CAAC;IACD,IAAI,QAAQ,CAAC,WAAW;QAAE,UAAU,CAAC,WAAW,GAAG,QAAQ,CAAC,WAAW,CAAC;IACxE,IAAI,QAAQ,CAAC,KAAK;QAAE,UAAU,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC;IACtD,IAAI,QAAQ,CAAC,OAAO;QAAE,UAAU,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IAC5D,IAAI,QAAQ,CAAC,OAAO;QAAE,UAAU,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IAC5D,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAC3D,CAAC;AAED;;;;;GAKG;AACH,SAAS,SAAS,CAAC,GAAgB;IACjC,MAAM,MAAM,GAAG,GAA+D,CAAC;IAC/E,IAAI,MAAM,CAAC,OAAO,IAAI,OAAO,MAAM,CAAC,OAAO,CAAC,WAAW,KAAK,UAAU;QAAE,OAAO,MAAM,CAAC,OAAO,CAAC;IAC9F,IAAI,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,WAAW,KAAK,UAAU;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC;IACrF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,6FAA6F;AAC7F,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAgB;IACpD,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;QACpE,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAgB;IACnD,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IAC5C,OAAO,QAAQ,CAAC,CAAC,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAgB;IACnD,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IAC5C,IAAI,QAAQ;QAAE,OAAO,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,IAAI,GAAI,GAAsC,CAAC,IAAI,CAAC;IAC1D,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC,IAAmB,CAAC;IAC/C,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;QACrC,IAAI,CAAC;YACH,IAAI,MAAM,IAAI,CAAC,KAAK,EAAE;gBAAE,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,SAAS,CAAgB,CAAC;QACzE,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;QACpE,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { HttpContext } from '@adonisjs/core/http';
|
|
2
|
+
import type { AdminAction, AdminAuthorizer } from './admin.js';
|
|
3
|
+
import type { ConsoleAuthorizeResult } from './dashboard/console_authorize.js';
|
|
4
|
+
import type { Actor } from './stores/store.js';
|
|
5
|
+
import type { SubjectLike } from './subject.js';
|
|
6
|
+
/**
|
|
7
|
+
* How flags learns who people are — the one contract between this package and your auth, the way
|
|
8
|
+
* a user provider is for `@adonisjs/auth`. Implement it for any auth setup, or use a built-in:
|
|
9
|
+
* `identities.authkit()` or `identities.adonisAuth()`.
|
|
10
|
+
*
|
|
11
|
+
* | Method | Used by |
|
|
12
|
+
* |---|---|
|
|
13
|
+
* | `subject` | `ctx.flags`, the route guard, Edge, the browser token endpoint |
|
|
14
|
+
* | `actor` | the console: audit log and approvals |
|
|
15
|
+
* | `authorizeConsole` | the console: who may open it |
|
|
16
|
+
* | `can` | every change — console, `node ace flags:*`, the admin API |
|
|
17
|
+
*
|
|
18
|
+
* Options set directly in the configs win over the provider: `subject` and `authorize` in
|
|
19
|
+
* `config/flags.ts`, `actor` and `authorize` in `config/flags_dashboard.ts`.
|
|
20
|
+
*/
|
|
21
|
+
export interface FlagsIdentityProvider {
|
|
22
|
+
/** Who flags are evaluated for in this request. `undefined`: an anonymous visitor. */
|
|
23
|
+
subject(ctx: HttpContext): SubjectLike | Promise<SubjectLike>;
|
|
24
|
+
/**
|
|
25
|
+
* The person acting in the console. `id` is what approvals compare: nobody approves their own
|
|
26
|
+
* change. `undefined`: anonymous, refused in environments that need approval.
|
|
27
|
+
*/
|
|
28
|
+
actor?(ctx: HttpContext): Actor | undefined | Promise<Actor | undefined>;
|
|
29
|
+
/**
|
|
30
|
+
* Who may open the console. Same answers as every Agora console: `true`/`false`,
|
|
31
|
+
* `{ allowed: false, reason: 'unauthenticated' }` (401), `{ redirectTo: '/login' }`.
|
|
32
|
+
*/
|
|
33
|
+
authorizeConsole?(ctx: HttpContext): ConsoleAuthorizeResult | Promise<ConsoleAuthorizeResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Whether `actor` may `read`, `write` or `approve` in an environment. Runs outside HTTP too
|
|
36
|
+
* (commands act as `cli:<os user>`), so load what you need from the actor's id.
|
|
37
|
+
*/
|
|
38
|
+
can?(actor: Actor, action: AdminAction, target: Parameters<AdminAuthorizer>[2]): boolean | Promise<boolean>;
|
|
39
|
+
}
|
|
40
|
+
export interface AuthkitIdentityOptions {
|
|
41
|
+
/** Global role required to open the console. Default `ADMIN`. */
|
|
42
|
+
consoleRole?: string;
|
|
43
|
+
/** Where to send people who are not signed in. Default: answer 401. */
|
|
44
|
+
loginPath?: string;
|
|
45
|
+
/** Who may change what. Default: anyone the console lets in (and every command). */
|
|
46
|
+
can?: FlagsIdentityProvider['can'];
|
|
47
|
+
}
|
|
48
|
+
export interface AdonisAuthIdentityOptions<User = Record<string, unknown>> {
|
|
49
|
+
/** The guard to read. Default: the default guard. */
|
|
50
|
+
guard?: string;
|
|
51
|
+
/** Subject type stored on events. Default `user`. */
|
|
52
|
+
type?: string;
|
|
53
|
+
/** Where to send people who are not signed in. Default: answer 401. */
|
|
54
|
+
loginPath?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Who may open the console, once signed in — typically a Bouncer ability:
|
|
57
|
+
* `(user, ctx) => ctx.bouncer.allows(manageFlags)`. Without it, the console falls back to its
|
|
58
|
+
* default (open outside production, closed in production).
|
|
59
|
+
*/
|
|
60
|
+
canOpenConsole?(user: User, ctx: HttpContext): boolean | Promise<boolean>;
|
|
61
|
+
/** Who may change what. Default: anyone the console lets in (and every command). */
|
|
62
|
+
can?: FlagsIdentityProvider['can'];
|
|
63
|
+
}
|
|
64
|
+
export declare const identities: {
|
|
65
|
+
/**
|
|
66
|
+
* `@adonis-agora/authkit-client`: the session's identity as subject (`sub`, email, global roles,
|
|
67
|
+
* active organization) and as the console actor; the console needs the `ADMIN` global role.
|
|
68
|
+
*/
|
|
69
|
+
authkit(options?: AuthkitIdentityOptions): FlagsIdentityProvider;
|
|
70
|
+
/**
|
|
71
|
+
* `@adonisjs/auth`: `ctx.auth.user` as subject (its `id`) and as the console actor (its `id`, and
|
|
72
|
+
* `fullName`/`name`/`email`). Gate the console with `canOpenConsole` — a Bouncer ability, a role
|
|
73
|
+
* column, anything. Targeting attributes come from `attributes` in `config/flags.ts`.
|
|
74
|
+
*/
|
|
75
|
+
adonisAuth<User = Record<string, unknown>>(options?: AdonisAuthIdentityOptions<User>): FlagsIdentityProvider;
|
|
76
|
+
};
|
|
77
|
+
/** The subject resolver in effect: `config.subject`, else the provider's, else the default. */
|
|
78
|
+
export declare function subjectResolver(config: {
|
|
79
|
+
subject?: ((ctx: HttpContext) => SubjectLike | Promise<SubjectLike>) | undefined;
|
|
80
|
+
identity?: FlagsIdentityProvider | undefined;
|
|
81
|
+
}): (ctx: HttpContext) => Promise<SubjectLike>;
|
|
82
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAE/E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,qBAAqB;IACpC,sFAAsF;IACtF,OAAO,CAAC,GAAG,EAAE,WAAW,GAAG,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9D;;;OAGG;IACH,KAAK,CAAC,CAAC,GAAG,EAAE,WAAW,GAAG,KAAK,GAAG,SAAS,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;IACzE;;;OAGG;IACH,gBAAgB,CAAC,CAAC,GAAG,EAAE,WAAW,GAAG,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC9F;;;OAGG;IACH,GAAG,CAAC,CACF,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,GACrC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/B;AAiBD,MAAM,WAAW,sBAAsB;IACrC,iEAAiE;IACjE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,GAAG,CAAC,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,yBAAyB,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACvE,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,cAAc,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1E,oFAAoF;IACpF,GAAG,CAAC,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAC;CACpC;AAgBD,eAAO,MAAM,UAAU;IACrB;;;OAGG;IACH,OAAO,WAAU,sBAAsB,GAAQ,qBAAqB;IAyBpE;;;;OAIG;IACH,UAAU,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAC9B,yBAAyB,CAAC,IAAI,CAAC,GACvC,qBAAqB;CA6BzB,CAAC;AAEF,+FAA+F;AAC/F,wBAAgB,eAAe,CAAC,MAAM,EAAE;IACtC,OAAO,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,WAAW,KAAK,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,SAAS,CAAC;IACjF,QAAQ,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;CAC9C,GAAG,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,WAAW,CAAC,CAQ7C"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { authkitIdentity, defaultSubject, subjectFromIdentity } from './http/subject_resolver.js';
|
|
2
|
+
function nameOf(user) {
|
|
3
|
+
return [user.fullName, user.name, user.email].find((value) => typeof value === 'string' && value !== '');
|
|
4
|
+
}
|
|
5
|
+
/** The signed-in user of `ctx.auth` (or one guard), checking the request silently. */
|
|
6
|
+
async function signedInUser(ctx, guard) {
|
|
7
|
+
const auth = ctx.auth;
|
|
8
|
+
if (!auth)
|
|
9
|
+
return null;
|
|
10
|
+
const scoped = guard && auth.use ? auth.use(guard) : auth;
|
|
11
|
+
if (scoped.user)
|
|
12
|
+
return scoped.user;
|
|
13
|
+
if (typeof scoped.check !== 'function')
|
|
14
|
+
return null;
|
|
15
|
+
try {
|
|
16
|
+
return (await scoped.check()) ? (scoped.user ?? null) : null;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export const identities = {
|
|
23
|
+
/**
|
|
24
|
+
* `@adonis-agora/authkit-client`: the session's identity as subject (`sub`, email, global roles,
|
|
25
|
+
* active organization) and as the console actor; the console needs the `ADMIN` global role.
|
|
26
|
+
*/
|
|
27
|
+
authkit(options = {}) {
|
|
28
|
+
return {
|
|
29
|
+
async subject(ctx) {
|
|
30
|
+
const identity = await authkitIdentity(ctx);
|
|
31
|
+
return identity ? subjectFromIdentity(identity) : undefined;
|
|
32
|
+
},
|
|
33
|
+
async actor(ctx) {
|
|
34
|
+
const identity = await authkitIdentity(ctx);
|
|
35
|
+
if (!identity)
|
|
36
|
+
return undefined;
|
|
37
|
+
const name = identity.profile?.name ?? identity.email;
|
|
38
|
+
return name ? { id: identity.userId, name } : { id: identity.userId };
|
|
39
|
+
},
|
|
40
|
+
async authorizeConsole(ctx) {
|
|
41
|
+
const identity = await authkitIdentity(ctx);
|
|
42
|
+
if (!identity) {
|
|
43
|
+
return options.loginPath
|
|
44
|
+
? { redirectTo: options.loginPath }
|
|
45
|
+
: { allowed: false, reason: 'unauthenticated' };
|
|
46
|
+
}
|
|
47
|
+
return (identity.globalRoles ?? []).includes(options.consoleRole ?? 'ADMIN');
|
|
48
|
+
},
|
|
49
|
+
...(options.can ? { can: options.can } : {}),
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
/**
|
|
53
|
+
* `@adonisjs/auth`: `ctx.auth.user` as subject (its `id`) and as the console actor (its `id`, and
|
|
54
|
+
* `fullName`/`name`/`email`). Gate the console with `canOpenConsole` — a Bouncer ability, a role
|
|
55
|
+
* column, anything. Targeting attributes come from `attributes` in `config/flags.ts`.
|
|
56
|
+
*/
|
|
57
|
+
adonisAuth(options = {}) {
|
|
58
|
+
return {
|
|
59
|
+
async subject(ctx) {
|
|
60
|
+
const user = await signedInUser(ctx, options.guard);
|
|
61
|
+
if (!user || (typeof user.id !== 'string' && typeof user.id !== 'number'))
|
|
62
|
+
return undefined;
|
|
63
|
+
return { id: user.id, type: options.type ?? 'user' };
|
|
64
|
+
},
|
|
65
|
+
async actor(ctx) {
|
|
66
|
+
const user = await signedInUser(ctx, options.guard);
|
|
67
|
+
if (!user || user.id === undefined || user.id === null)
|
|
68
|
+
return undefined;
|
|
69
|
+
const name = nameOf(user);
|
|
70
|
+
return name ? { id: String(user.id), name } : { id: String(user.id) };
|
|
71
|
+
},
|
|
72
|
+
...(options.canOpenConsole
|
|
73
|
+
? {
|
|
74
|
+
async authorizeConsole(ctx) {
|
|
75
|
+
const user = await signedInUser(ctx, options.guard);
|
|
76
|
+
if (!user) {
|
|
77
|
+
return options.loginPath
|
|
78
|
+
? { redirectTo: options.loginPath }
|
|
79
|
+
: { allowed: false, reason: 'unauthenticated' };
|
|
80
|
+
}
|
|
81
|
+
return options.canOpenConsole(user, ctx);
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
: {}),
|
|
85
|
+
...(options.can ? { can: options.can } : {}),
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
/** The subject resolver in effect: `config.subject`, else the provider's, else the default. */
|
|
90
|
+
export function subjectResolver(config) {
|
|
91
|
+
if (config.subject) {
|
|
92
|
+
const subject = config.subject;
|
|
93
|
+
return async (ctx) => subject(ctx);
|
|
94
|
+
}
|
|
95
|
+
const identity = config.identity;
|
|
96
|
+
if (identity)
|
|
97
|
+
return async (ctx) => identity.subject(ctx);
|
|
98
|
+
return defaultSubject;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export declare const VERSION = "0.1.0";
|
|
2
|
+
export type { EvaluationContext, EvaluationDetails, FlagDefinition, JsonValue, Ruleset, Segment, } from '@adonis-agora/flags-core';
|
|
3
|
+
export { configure } from '../configure.js';
|
|
4
|
+
export { type AdminAction, type AdminAuthorizer, type ApprovalsConfig, checkAgainstDeclarations, definitionFromDeclaration, FlagsAdmin, ForbiddenError, type ProposeResult, type StaleFlag, ValidationError, } from './admin.js';
|
|
5
|
+
export type { AnalyticsBackend } from './analytics/backend.js';
|
|
6
|
+
export { ClickHouseBackend } from './analytics/clickhouse_backend.js';
|
|
7
|
+
export { DuckDbBackend } from './analytics/duckdb.js';
|
|
8
|
+
export { LucidBackend } from './analytics/lucid_backend.js';
|
|
9
|
+
export { type MetricDefinition, type MetricKind, metric } from './analytics/metrics.js';
|
|
10
|
+
export { type Comparison, computeResults, type ExperimentResults, type MetricResult, } from './analytics/results.js';
|
|
11
|
+
export { type FlagDeclaration, type FlagMeta, type FlagType, flag, type InferFlags, } from './declare.js';
|
|
12
|
+
export { analytics, type BrowserConfig, type ControlPlaneConfig, defineConfig, type ExperimentConfig, type FactoryContext, type FlagsConfig, type StandaloneConfig, sinks, stores, type TenantConfig, transports, } from './define_config.js';
|
|
13
|
+
export { DIAGNOSTICS_CHANNELS, type Enricher, enrichers } from './enrichers.js';
|
|
14
|
+
export { EVENT_SCHEMA_VERSION, exposureId, type FlagEvent, uuidv7 } from './events/event.js';
|
|
15
|
+
export { browserToken, registerBrowser } from './http/browser.js';
|
|
16
|
+
export type { BrowserTokenResponse } from './http/browser_tokens.js';
|
|
17
|
+
export { flagsCsrfExceptions } from './http/csrf.js';
|
|
18
|
+
export { type AuthkitIdentityLike, authkitIdentity, authkitSubject, defaultSubject, subjectFromIdentity, } from './http/subject_resolver.js';
|
|
19
|
+
export { type AdonisAuthIdentityOptions, type AuthkitIdentityOptions, type FlagsIdentityProvider, identities, } from './identity.js';
|
|
20
|
+
export { FlagsManager, FlagsScope, type TrackOptions } from './manager.js';
|
|
21
|
+
export { Relay } from './relay/relay.js';
|
|
22
|
+
export { FlagsWorker } from './relay/worker.js';
|
|
23
|
+
export { createRuntime, type FlagsRuntime, lucidContext } from './runtime.js';
|
|
24
|
+
export { createFlagsTables, dropFlagsTables, ensureEventPartitions, FLAGS_TABLES, pruneEvents, } from './schema.js';
|
|
25
|
+
export { ClickHouseSink } from './sinks/clickhouse.js';
|
|
26
|
+
export { LucidSink } from './sinks/lucid_sink.js';
|
|
27
|
+
export { ParquetSink } from './sinks/parquet_sink.js';
|
|
28
|
+
export { PostHogSink } from './sinks/posthog_sink.js';
|
|
29
|
+
export { CallbackSink, MemorySink, type Sink } from './sinks/sink.js';
|
|
30
|
+
export { LucidStore, RULESET_CHANNEL } from './stores/lucid_store.js';
|
|
31
|
+
export { MemoryStore } from './stores/memory_store.js';
|
|
32
|
+
export type { Actor, AuditEntry, ChangeRequest, FlagsStore, RulesetChange, ScheduledChange, } from './stores/store.js';
|
|
33
|
+
export type { Subject, SubjectLike } from './subject.js';
|
|
34
|
+
export { TENANT_SCOPES, type TokenSource, tokens } from './topology/token.js';
|
|
35
|
+
export { type TenantVerifier, type UserVerifier, userVerifiers, type VerifiedTenant, type VerifiedUser, verifiers, } from './topology/verify.js';
|
|
36
|
+
export { DbTransport } from './transports/db_transport.js';
|
|
37
|
+
export { MemoryTransport } from './transports/memory_transport.js';
|
|
38
|
+
export { RedisTransport } from './transports/redis_transport.js';
|
|
39
|
+
export type { Transport } from './transports/transport.js';
|
|
40
|
+
export type { BooleanFlagKey, FlagKey, FlagsList, FlagValue } from './types.js';
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,SAAS,EACT,OAAO,EACP,OAAO,GACR,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,wBAAwB,EACxB,yBAAyB,EACzB,UAAU,EACV,cAAc,EACd,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,EACL,KAAK,UAAU,EACf,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,YAAY,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,IAAI,EACJ,KAAK,UAAU,GAChB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,SAAS,EACT,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,YAAY,EACZ,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,EACL,MAAM,EACN,KAAK,YAAY,EACjB,UAAU,GACX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAE,KAAK,QAAQ,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAClE,YAAY,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EACL,KAAK,mBAAmB,EACxB,eAAe,EACf,cAAc,EACd,cAAc,EACd,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,YAAY,EACZ,WAAW,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,YAAY,EACV,KAAK,EACL,UAAU,EACV,aAAa,EACb,UAAU,EACV,aAAa,EACb,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,aAAa,EACb,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,SAAS,GACV,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,YAAY,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAC3D,YAAY,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const VERSION = '0.1.0';
|
|
2
|
+
export { configure } from '../configure.js';
|
|
3
|
+
export { checkAgainstDeclarations, definitionFromDeclaration, FlagsAdmin, ForbiddenError, ValidationError, } from './admin.js';
|
|
4
|
+
export { ClickHouseBackend } from './analytics/clickhouse_backend.js';
|
|
5
|
+
export { DuckDbBackend } from './analytics/duckdb.js';
|
|
6
|
+
export { LucidBackend } from './analytics/lucid_backend.js';
|
|
7
|
+
export { metric } from './analytics/metrics.js';
|
|
8
|
+
export { computeResults, } from './analytics/results.js';
|
|
9
|
+
export { flag, } from './declare.js';
|
|
10
|
+
export { analytics, defineConfig, sinks, stores, transports, } from './define_config.js';
|
|
11
|
+
export { DIAGNOSTICS_CHANNELS, enrichers } from './enrichers.js';
|
|
12
|
+
export { EVENT_SCHEMA_VERSION, exposureId, uuidv7 } from './events/event.js';
|
|
13
|
+
export { browserToken, registerBrowser } from './http/browser.js';
|
|
14
|
+
export { flagsCsrfExceptions } from './http/csrf.js';
|
|
15
|
+
export { authkitIdentity, authkitSubject, defaultSubject, subjectFromIdentity, } from './http/subject_resolver.js';
|
|
16
|
+
export { identities, } from './identity.js';
|
|
17
|
+
export { FlagsManager, FlagsScope } from './manager.js';
|
|
18
|
+
export { Relay } from './relay/relay.js';
|
|
19
|
+
export { FlagsWorker } from './relay/worker.js';
|
|
20
|
+
export { createRuntime, lucidContext } from './runtime.js';
|
|
21
|
+
export { createFlagsTables, dropFlagsTables, ensureEventPartitions, FLAGS_TABLES, pruneEvents, } from './schema.js';
|
|
22
|
+
export { ClickHouseSink } from './sinks/clickhouse.js';
|
|
23
|
+
export { LucidSink } from './sinks/lucid_sink.js';
|
|
24
|
+
export { ParquetSink } from './sinks/parquet_sink.js';
|
|
25
|
+
export { PostHogSink } from './sinks/posthog_sink.js';
|
|
26
|
+
export { CallbackSink, MemorySink } from './sinks/sink.js';
|
|
27
|
+
export { LucidStore, RULESET_CHANNEL } from './stores/lucid_store.js';
|
|
28
|
+
export { MemoryStore } from './stores/memory_store.js';
|
|
29
|
+
export { TENANT_SCOPES, tokens } from './topology/token.js';
|
|
30
|
+
export { userVerifiers, verifiers, } from './topology/verify.js';
|
|
31
|
+
export { DbTransport } from './transports/db_transport.js';
|
|
32
|
+
export { MemoryTransport } from './transports/memory_transport.js';
|
|
33
|
+
export { RedisTransport } from './transports/redis_transport.js';
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAU/B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAIL,wBAAwB,EACxB,yBAAyB,EACzB,UAAU,EACV,cAAc,EAGd,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAA0C,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAEL,cAAc,GAGf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAIL,IAAI,GAEL,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,SAAS,EAGT,YAAY,EAKZ,KAAK,EACL,MAAM,EAEN,UAAU,GACX,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,oBAAoB,EAAiB,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAkB,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC7F,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAElE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAEL,eAAe,EACf,cAAc,EACd,cAAc,EACd,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAIL,UAAU,GACX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,UAAU,EAAqB,MAAM,cAAc,CAAC;AAC3E,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAqB,YAAY,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,qBAAqB,EACrB,YAAY,EACZ,WAAW,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAa,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAUvD,OAAO,EAAE,aAAa,EAAoB,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC9E,OAAO,EAGL,aAAa,EAGb,SAAS,GACV,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { type EvaluateOptions, type EvaluationContext, type EvaluationDetails, type JsonValue, type Ruleset } from '@adonis-agora/flags-core';
|
|
2
|
+
import type { FlagsAdmin } from './admin.js';
|
|
3
|
+
import { type ExperimentResults } from './analytics/results.js';
|
|
4
|
+
import { type FlagDeclaration } from './declare.js';
|
|
5
|
+
import { type Enricher } from './enrichers.js';
|
|
6
|
+
import type { EventBuffer } from './events/buffer.js';
|
|
7
|
+
import type { RulesetSource } from './ruleset_source.js';
|
|
8
|
+
import type { SqlClient } from './sql.js';
|
|
9
|
+
import { type Subject, type SubjectLike } from './subject.js';
|
|
10
|
+
import type { Transport } from './transports/transport.js';
|
|
11
|
+
import type { BooleanFlagKey, FlagKey, FlagValue } from './types.js';
|
|
12
|
+
import type { UsageCounter } from './usage.js';
|
|
13
|
+
export interface TrackOptions {
|
|
14
|
+
/** Numeric value (revenue, duration). */
|
|
15
|
+
value?: number;
|
|
16
|
+
props?: Record<string, unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* A Lucid transaction: with the `db` transport the event commits or rolls back with it. Other
|
|
19
|
+
* transports send it after the transaction commits.
|
|
20
|
+
*/
|
|
21
|
+
client?: SqlClient & {
|
|
22
|
+
after?(event: 'commit', handler: () => void | Promise<void>): void;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export interface ManagerDeps {
|
|
26
|
+
app: string;
|
|
27
|
+
environment: string;
|
|
28
|
+
declarations: Record<string, FlagDeclaration>;
|
|
29
|
+
source: RulesetSource;
|
|
30
|
+
buffer?: EventBuffer;
|
|
31
|
+
transport?: Transport;
|
|
32
|
+
enrichers?: Enricher[];
|
|
33
|
+
usage?: UsageCounter;
|
|
34
|
+
/** Sticky assignments of a subject: flag key → variant (from the exposures table). */
|
|
35
|
+
sticky?: (subject: string) => Promise<Record<string, string>>;
|
|
36
|
+
/** Extra targeting attributes resolved for every subject (plan, org, …). */
|
|
37
|
+
attributes?: (subject: Subject) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
38
|
+
admin?: FlagsAdmin;
|
|
39
|
+
results?: (experiment: string, environment?: string) => Promise<ExperimentResults | null>;
|
|
40
|
+
forget?: (subject: string) => Promise<void>;
|
|
41
|
+
logger?: {
|
|
42
|
+
warn(message: string): void;
|
|
43
|
+
error(message: string): void;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The entry point: `flags.for(user).enabled('new_player')`. Evaluation is in memory against the
|
|
48
|
+
* ruleset the source keeps fresh; nothing here waits on the database except an opt-in sticky lookup
|
|
49
|
+
* (once per scope).
|
|
50
|
+
*/
|
|
51
|
+
export declare class FlagsManager {
|
|
52
|
+
#private;
|
|
53
|
+
readonly deps: ManagerDeps;
|
|
54
|
+
constructor(deps: ManagerDeps);
|
|
55
|
+
get environment(): string;
|
|
56
|
+
get app(): string;
|
|
57
|
+
get admin(): FlagsAdmin;
|
|
58
|
+
/** Flags declared in code. */
|
|
59
|
+
get declarations(): Record<string, FlagDeclaration<JsonValue>>;
|
|
60
|
+
/** Every known flag: declared in code or created in the console (code wins). */
|
|
61
|
+
effectiveDeclarations(): Record<string, FlagDeclaration<JsonValue> & {
|
|
62
|
+
source: import("./declare.js").DeclarationSource;
|
|
63
|
+
}>;
|
|
64
|
+
/** The ruleset this process evaluates against. */
|
|
65
|
+
ruleset(): Ruleset;
|
|
66
|
+
status(): {
|
|
67
|
+
app: string;
|
|
68
|
+
environment: string;
|
|
69
|
+
source: import("./ruleset_source.js").SourceStatus;
|
|
70
|
+
buffer: {
|
|
71
|
+
pending: number;
|
|
72
|
+
published: number;
|
|
73
|
+
dropped: number;
|
|
74
|
+
} | null;
|
|
75
|
+
transport: {
|
|
76
|
+
transactional: boolean;
|
|
77
|
+
durable: boolean;
|
|
78
|
+
name: string;
|
|
79
|
+
} | null;
|
|
80
|
+
};
|
|
81
|
+
/** Reloads the ruleset now (after an edit in this process, or from a command). */
|
|
82
|
+
refresh(): Promise<boolean>;
|
|
83
|
+
/** A scope for one subject. In HTTP handlers prefer `ctx.flags`, which the middleware builds. */
|
|
84
|
+
for(subject?: SubjectLike, attributes?: Record<string, unknown>): FlagsScope;
|
|
85
|
+
/** A scope whose subject is resolved on the first flag read. */
|
|
86
|
+
forLazy(resolve: () => Promise<SubjectLike> | SubjectLike, attributes?: Record<string, unknown>): FlagsScope;
|
|
87
|
+
/** The declared default: from code, else from the console declaration in the ruleset. */
|
|
88
|
+
declaredDefault(key: string): JsonValue | undefined;
|
|
89
|
+
/** @internal Evaluation with fakes, usage counting and enrichers. */
|
|
90
|
+
evaluateFor<T extends JsonValue>(key: string, fallback: T, context: EvaluationContext, options: EvaluateOptions): EvaluationDetails<T>;
|
|
91
|
+
/** @internal Records an exposure for an experiment assignment. */
|
|
92
|
+
expose(subject: Subject, details: EvaluationDetails): void;
|
|
93
|
+
/** Records a tracked event (a conversion) for a subject. */
|
|
94
|
+
track(subject: SubjectLike, name: string, options?: TrackOptions): Promise<void>;
|
|
95
|
+
/** Experiment results as last computed by the worker (or `null`), for this process's environment by default. */
|
|
96
|
+
results(experiment: string, environment?: string): Promise<ExperimentResults | null>;
|
|
97
|
+
/** Deletes everything stored about a subject in every sink that supports it. */
|
|
98
|
+
forget(subject: SubjectLike): Promise<void>;
|
|
99
|
+
/** @internal */
|
|
100
|
+
attributesFor(subject: Subject | undefined): Promise<Record<string, unknown>>;
|
|
101
|
+
/** @internal */
|
|
102
|
+
stickyFor(subject: Subject | undefined): Promise<Record<string, string>> | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* Replaces flag values for the duration of a test. Every evaluation of a faked key returns the
|
|
105
|
+
* given value; tracked events are dropped. Returns a function that restores real evaluation.
|
|
106
|
+
*
|
|
107
|
+
* ```ts
|
|
108
|
+
* const restore = flags.fake({ checkout_v2: 'b' })
|
|
109
|
+
* // …
|
|
110
|
+
* restore()
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
fake(values: Partial<Record<FlagKey, JsonValue>>): () => void;
|
|
114
|
+
restore(): void;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Flags for one subject. Results are memoized for the life of the scope (one request), so a flag
|
|
118
|
+
* cannot change value halfway through rendering a page. The subject may be given directly or as a
|
|
119
|
+
* resolver that runs on the first read (what `ctx.flags` uses).
|
|
120
|
+
*/
|
|
121
|
+
export declare class FlagsScope {
|
|
122
|
+
#private;
|
|
123
|
+
readonly manager: FlagsManager;
|
|
124
|
+
readonly attributes: Record<string, unknown>;
|
|
125
|
+
constructor(manager: FlagsManager, subject: Subject | undefined | (() => Promise<SubjectLike> | SubjectLike), attributes?: Record<string, unknown>);
|
|
126
|
+
/** The subject this scope evaluates for (resolved on first use). */
|
|
127
|
+
subject(): Promise<Subject | undefined>;
|
|
128
|
+
/** Full evaluation details (value, variant, reason, error). Records an exposure for experiments. */
|
|
129
|
+
details<K extends FlagKey>(key: K): Promise<EvaluationDetails<FlagValue<K>>>;
|
|
130
|
+
/** The flag's value. */
|
|
131
|
+
value<K extends FlagKey>(key: K): Promise<FlagValue<K>>;
|
|
132
|
+
/** Whether a boolean flag is on. */
|
|
133
|
+
enabled<K extends BooleanFlagKey>(key: K): Promise<boolean>;
|
|
134
|
+
disabled<K extends BooleanFlagKey>(key: K): Promise<boolean>;
|
|
135
|
+
/**
|
|
136
|
+
* `true` when a boolean flag is on, or — given variants — when the flag serves one of them.
|
|
137
|
+
* What the Edge `@flag` tag compiles to.
|
|
138
|
+
*/
|
|
139
|
+
matches<K extends FlagKey>(key: K, ...variants: string[]): Promise<boolean>;
|
|
140
|
+
/** The variant name served (experiments). Falls back to the value as a string. */
|
|
141
|
+
variant<K extends FlagKey>(key: K): Promise<string>;
|
|
142
|
+
/**
|
|
143
|
+
* Values of several flags at once — for the frontend. Without `keys`, only flags declared with
|
|
144
|
+
* `client: true` are included, so internal flag names never reach the browser by accident.
|
|
145
|
+
* Experiment exposures are NOT recorded here unless `expose: true`: values sent to a page are not
|
|
146
|
+
* necessarily seen.
|
|
147
|
+
*/
|
|
148
|
+
all(keys?: FlagKey[], options?: {
|
|
149
|
+
expose?: boolean;
|
|
150
|
+
}): Promise<Record<string, JsonValue>>;
|
|
151
|
+
/** Records a tracked event for this scope's subject. */
|
|
152
|
+
track(name: string, options?: TrackOptions): Promise<void>;
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/manager.ts"],"names":[],"mappings":"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"}
|