@lunora/flags 0.0.1 → 1.0.0-alpha.2
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/LICENSE.md +105 -0
- package/README.md +80 -28
- package/__assets__/package-og.svg +14 -0
- package/dist/index.d.mts +56 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.mjs +2 -0
- package/dist/packem_shared/createFlags-CAhOHjdv.mjs +99 -0
- package/dist/packem_shared/defineFlags-DAIO8cWQ.mjs +15 -0
- package/dist/packem_shared/types.d-BWygZiSc.d.mts +85 -0
- package/dist/packem_shared/types.d-BWygZiSc.d.ts +85 -0
- package/dist/providers/env.d.mts +43 -0
- package/dist/providers/env.d.ts +43 -0
- package/dist/providers/env.mjs +75 -0
- package/dist/providers/flagship.d.mts +62 -0
- package/dist/providers/flagship.d.ts +62 -0
- package/dist/providers/flagship.mjs +20 -0
- package/dist/providers/memory.d.mts +37 -0
- package/dist/providers/memory.d.ts +37 -0
- package/dist/providers/memory.mjs +16 -0
- package/dist/web.d.mts +1 -0
- package/dist/web.d.ts +1 -0
- package/dist/web.mjs +1 -0
- package/package.json +77 -7
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { F as FlagsProviderFactory } from "../packem_shared/types.d-BWygZiSc.js";
|
|
2
|
+
import '@openfeature/server-sdk';
|
|
3
|
+
/**
|
|
4
|
+
* Flagship provider in **binding mode** (recommended for Workers): evaluations
|
|
5
|
+
* go through the wrangler binding — no HTTP, no auth token.
|
|
6
|
+
*/
|
|
7
|
+
interface FlagshipBindingOptions {
|
|
8
|
+
/**
|
|
9
|
+
* The name of the Flagship binding on the Worker `env` (e.g. `"FLAGS"`). The
|
|
10
|
+
* factory resolves `env[binding]` at request time. Configure a matching
|
|
11
|
+
* `flagship` binding in `wrangler.jsonc` with this binding name and your app id.
|
|
12
|
+
*/
|
|
13
|
+
binding: string;
|
|
14
|
+
/** Max cached entries when `cacheTtl` is set (default 1000). */
|
|
15
|
+
cacheMaxSize?: number;
|
|
16
|
+
/** Opt-in per-context TTL cache, in ms. Enables caching when greater than 0. */
|
|
17
|
+
cacheTtl?: number;
|
|
18
|
+
/** Surface Flagship SDK logs (default false). */
|
|
19
|
+
logging?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Flagship provider in **HTTP mode** (non-binding Workers or other server
|
|
23
|
+
* runtimes): evaluations go to the Flagship API over HTTP.
|
|
24
|
+
*/
|
|
25
|
+
interface FlagshipHttpOptions {
|
|
26
|
+
/** Account id for multi-tenant routing (required with `appId`). */
|
|
27
|
+
accountId?: string;
|
|
28
|
+
/** Flagship app id; the SDK builds the evaluation URL (mutually exclusive with `endpoint`). */
|
|
29
|
+
appId?: string;
|
|
30
|
+
/** Bearer token added as an `Authorization: Bearer` header to every request. */
|
|
31
|
+
authToken?: string;
|
|
32
|
+
/** Base URL override (only used with `appId`). */
|
|
33
|
+
baseUrl?: string;
|
|
34
|
+
cacheMaxSize?: number;
|
|
35
|
+
cacheTtl?: number;
|
|
36
|
+
/** Full evaluation URL (mutually exclusive with `appId`). */
|
|
37
|
+
endpoint?: string;
|
|
38
|
+
logging?: boolean;
|
|
39
|
+
/** Retry attempts on transient errors (default 1, max 10). */
|
|
40
|
+
retries?: number;
|
|
41
|
+
/** Delay between retries in ms (default 1000, max 30000). */
|
|
42
|
+
retryDelay?: number;
|
|
43
|
+
/** Request timeout in ms (default 5000). */
|
|
44
|
+
timeout?: number;
|
|
45
|
+
}
|
|
46
|
+
/** Options for `flagshipProvider` — binding mode or HTTP mode. */
|
|
47
|
+
type FlagshipProviderOptions = FlagshipBindingOptions | FlagshipHttpOptions;
|
|
48
|
+
/**
|
|
49
|
+
* Builds a Cloudflare Flagship OpenFeature provider for `defineFlags({ provider })`.
|
|
50
|
+
* Flagship is Lunora's first-class default; the same `defineFlags` accepts any
|
|
51
|
+
* OpenFeature provider, so apps can swap it out without touching call sites.
|
|
52
|
+
*
|
|
53
|
+
* ```ts
|
|
54
|
+
* // Binding mode (recommended) — reads env.FLAGS at request time:
|
|
55
|
+
* flagshipProvider({ binding: "FLAGS" })
|
|
56
|
+
*
|
|
57
|
+
* // HTTP mode:
|
|
58
|
+
* flagshipProvider({ appId: "app-abc", accountId: "acct", authToken: "tok" })
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
declare const flagshipProvider: (options: FlagshipProviderOptions) => FlagsProviderFactory;
|
|
62
|
+
export { type FlagshipBindingOptions, type FlagshipHttpOptions, type FlagshipProviderOptions, flagshipProvider };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { FlagshipServerProvider } from '@cloudflare/flagship/server';
|
|
2
|
+
|
|
3
|
+
const isBindingOptions = (options) => "binding" in options && typeof options.binding === "string";
|
|
4
|
+
const flagshipProvider = (options) => {
|
|
5
|
+
if (isBindingOptions(options)) {
|
|
6
|
+
const { binding: bindingName, ...rest } = options;
|
|
7
|
+
return (env) => {
|
|
8
|
+
const binding = env[bindingName];
|
|
9
|
+
if (binding === void 0 || binding === null) {
|
|
10
|
+
throw new Error(
|
|
11
|
+
`flagshipProvider: no binding "${bindingName}" found on env. Add a \`flagship\` binding to wrangler.jsonc, e.g. { "flagship": [{ "binding": "${bindingName}", "app_id": "your-app-id" }] }.`
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
return new FlagshipServerProvider({ binding, ...rest });
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
return () => new FlagshipServerProvider(options);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export { flagshipProvider };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { JsonValue } from '@openfeature/server-sdk';
|
|
2
|
+
import { F as FlagsProviderFactory } from "../packem_shared/types.d-BWygZiSc.mjs";
|
|
3
|
+
/**
|
|
4
|
+
* The value a static memory flag can hold — any JSON value (OpenFeature boolean /
|
|
5
|
+
* number / string / structured object). Alias of `JsonValue` for naming clarity.
|
|
6
|
+
*/
|
|
7
|
+
type MemoryFlagValue = JsonValue;
|
|
8
|
+
/**
|
|
9
|
+
* A static, in-memory OpenFeature provider for `defineFlags({ provider })`, built
|
|
10
|
+
* on OpenFeature's own in-memory provider (no extra install). Pass a plain
|
|
11
|
+
* `key → value` map; every read resolves the configured value (reason `STATIC`)
|
|
12
|
+
* or, for an unknown key, the call's default.
|
|
13
|
+
*
|
|
14
|
+
* Ideal for tests, local development, and apps with a handful of static flags
|
|
15
|
+
* checked into the repo — no external flag service, no binding.
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { defineFlags } from "@lunora/flags";
|
|
19
|
+
* import { memoryProvider } from "@lunora/flags/providers/memory";
|
|
20
|
+
*
|
|
21
|
+
* export default defineFlags({
|
|
22
|
+
* provider: memoryProvider({
|
|
23
|
+
* "dark-mode": true,
|
|
24
|
+
* "page-size": 25,
|
|
25
|
+
* "homepage-hero": "control",
|
|
26
|
+
* "rollout": { percent: 10, regions: ["us", "eu"] },
|
|
27
|
+
* }),
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* Targeting (per-context variants) is out of scope for this static provider; for
|
|
32
|
+
* that, wire a real provider (e.g. `flagshipProvider`) or construct a
|
|
33
|
+
* `TypedInMemoryProvider` with `contextEvaluator`s directly via the `defineFlags`
|
|
34
|
+
* escape hatch (`provider: () => new TypedInMemoryProvider(config)`).
|
|
35
|
+
*/
|
|
36
|
+
declare const memoryProvider: (flags: Record<string, MemoryFlagValue>) => FlagsProviderFactory;
|
|
37
|
+
export { type MemoryFlagValue, memoryProvider };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { JsonValue } from '@openfeature/server-sdk';
|
|
2
|
+
import { F as FlagsProviderFactory } from "../packem_shared/types.d-BWygZiSc.js";
|
|
3
|
+
/**
|
|
4
|
+
* The value a static memory flag can hold — any JSON value (OpenFeature boolean /
|
|
5
|
+
* number / string / structured object). Alias of `JsonValue` for naming clarity.
|
|
6
|
+
*/
|
|
7
|
+
type MemoryFlagValue = JsonValue;
|
|
8
|
+
/**
|
|
9
|
+
* A static, in-memory OpenFeature provider for `defineFlags({ provider })`, built
|
|
10
|
+
* on OpenFeature's own in-memory provider (no extra install). Pass a plain
|
|
11
|
+
* `key → value` map; every read resolves the configured value (reason `STATIC`)
|
|
12
|
+
* or, for an unknown key, the call's default.
|
|
13
|
+
*
|
|
14
|
+
* Ideal for tests, local development, and apps with a handful of static flags
|
|
15
|
+
* checked into the repo — no external flag service, no binding.
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { defineFlags } from "@lunora/flags";
|
|
19
|
+
* import { memoryProvider } from "@lunora/flags/providers/memory";
|
|
20
|
+
*
|
|
21
|
+
* export default defineFlags({
|
|
22
|
+
* provider: memoryProvider({
|
|
23
|
+
* "dark-mode": true,
|
|
24
|
+
* "page-size": 25,
|
|
25
|
+
* "homepage-hero": "control",
|
|
26
|
+
* "rollout": { percent: 10, regions: ["us", "eu"] },
|
|
27
|
+
* }),
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* Targeting (per-context variants) is out of scope for this static provider; for
|
|
32
|
+
* that, wire a real provider (e.g. `flagshipProvider`) or construct a
|
|
33
|
+
* `TypedInMemoryProvider` with `contextEvaluator`s directly via the `defineFlags`
|
|
34
|
+
* escape hatch (`provider: () => new TypedInMemoryProvider(config)`).
|
|
35
|
+
*/
|
|
36
|
+
declare const memoryProvider: (flags: Record<string, MemoryFlagValue>) => FlagsProviderFactory;
|
|
37
|
+
export { type MemoryFlagValue, memoryProvider };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { TypedInMemoryProvider } from '@openfeature/server-sdk';
|
|
2
|
+
|
|
3
|
+
const memoryProvider = (flags) => {
|
|
4
|
+
const configuration = {};
|
|
5
|
+
for (const [key, value] of Object.entries(flags)) {
|
|
6
|
+
configuration[key] = {
|
|
7
|
+
defaultVariant: "default",
|
|
8
|
+
disabled: false,
|
|
9
|
+
variants: { default: value }
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
const provider = new TypedInMemoryProvider(configuration);
|
|
13
|
+
return (_environment) => provider;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export { memoryProvider };
|
package/dist/web.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FlagshipClientProvider, type FlagshipClientProviderOptions } from '@cloudflare/flagship/web';
|
package/dist/web.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FlagshipClientProvider, type FlagshipClientProviderOptions } from '@cloudflare/flagship/web';
|
package/dist/web.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FlagshipClientProvider } from '@cloudflare/flagship/web';
|
package/package.json
CHANGED
|
@@ -1,10 +1,80 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/flags",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.0.0-alpha.2",
|
|
4
|
+
"description": "OpenFeature-based feature flags for Lunora — ctx.flags, useFlag, and a first-class Cloudflare Flagship provider with any OpenFeature provider pluggable",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
"cloudflare",
|
|
7
|
+
"feature-flags",
|
|
8
|
+
"flagship",
|
|
9
|
+
"lunora",
|
|
10
|
+
"openfeature",
|
|
11
|
+
"workers"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://lunora.sh",
|
|
14
|
+
"bugs": "https://github.com/anolilab/lunora/issues",
|
|
15
|
+
"license": "FSL-1.1-Apache-2.0",
|
|
16
|
+
"author": {
|
|
17
|
+
"name": "Daniel Bannert",
|
|
18
|
+
"email": "d.bannert@anolilab.de"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/anolilab/lunora.git",
|
|
23
|
+
"directory": "packages/flags"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"./dist",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE.md",
|
|
29
|
+
"__assets__"
|
|
30
|
+
],
|
|
31
|
+
"type": "module",
|
|
32
|
+
"sideEffects": false,
|
|
33
|
+
"main": "./dist/index.mjs",
|
|
34
|
+
"module": "./dist/index.mjs",
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"exports": {
|
|
37
|
+
".": {
|
|
38
|
+
"types": "./dist/index.d.ts",
|
|
39
|
+
"import": "./dist/index.mjs"
|
|
40
|
+
},
|
|
41
|
+
"./providers/flagship": {
|
|
42
|
+
"types": "./dist/providers/flagship.d.ts",
|
|
43
|
+
"import": "./dist/providers/flagship.mjs"
|
|
44
|
+
},
|
|
45
|
+
"./providers/memory": {
|
|
46
|
+
"types": "./dist/providers/memory.d.ts",
|
|
47
|
+
"import": "./dist/providers/memory.mjs"
|
|
48
|
+
},
|
|
49
|
+
"./providers/env": {
|
|
50
|
+
"types": "./dist/providers/env.d.ts",
|
|
51
|
+
"import": "./dist/providers/env.mjs"
|
|
52
|
+
},
|
|
53
|
+
"./web": {
|
|
54
|
+
"types": "./dist/web.d.ts",
|
|
55
|
+
"import": "./dist/web.mjs"
|
|
56
|
+
},
|
|
57
|
+
"./package.json": "./package.json"
|
|
58
|
+
},
|
|
59
|
+
"publishConfig": {
|
|
60
|
+
"access": "public"
|
|
61
|
+
},
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"@openfeature/server-sdk": "^1.20.2"
|
|
64
|
+
},
|
|
65
|
+
"peerDependencies": {
|
|
66
|
+
"@cloudflare/flagship": "^0.4.2",
|
|
67
|
+
"@openfeature/web-sdk": "^1.7.3"
|
|
68
|
+
},
|
|
69
|
+
"peerDependenciesMeta": {
|
|
70
|
+
"@cloudflare/flagship": {
|
|
71
|
+
"optional": true
|
|
72
|
+
},
|
|
73
|
+
"@openfeature/web-sdk": {
|
|
74
|
+
"optional": true
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"engines": {
|
|
78
|
+
"node": "^22.15.0 || >=24.11.0"
|
|
79
|
+
}
|
|
80
|
+
}
|