@core-sdk/feature-flags-sdk 0.1.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/dist/cache.d.ts +14 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +26 -0
- package/dist/client.d.ts +31 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +145 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/normalize.d.ts +10 -0
- package/dist/normalize.d.ts.map +1 -0
- package/dist/normalize.js +54 -0
- package/dist/paths.d.ts +6 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +17 -0
- package/dist/types.d.ts +31 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +32 -0
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface CacheEntry<T> {
|
|
2
|
+
value: T;
|
|
3
|
+
expiresAt: number;
|
|
4
|
+
}
|
|
5
|
+
export declare class TtlMemoryCache<T> {
|
|
6
|
+
private readonly ttlMs;
|
|
7
|
+
private readonly store;
|
|
8
|
+
constructor(ttlMs: number);
|
|
9
|
+
get(key: string): T | undefined;
|
|
10
|
+
set(key: string, value: T): void;
|
|
11
|
+
delete(key: string): void;
|
|
12
|
+
clear(): void;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,cAAc,CAAC,CAAC;IAGf,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFlC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;gBAE7B,KAAK,EAAE,MAAM;IAE1C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAU/B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAIhC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB,KAAK,IAAI,IAAI;CAGd"}
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export class TtlMemoryCache {
|
|
2
|
+
ttlMs;
|
|
3
|
+
store = new Map();
|
|
4
|
+
constructor(ttlMs) {
|
|
5
|
+
this.ttlMs = ttlMs;
|
|
6
|
+
}
|
|
7
|
+
get(key) {
|
|
8
|
+
const e = this.store.get(key);
|
|
9
|
+
if (!e)
|
|
10
|
+
return undefined;
|
|
11
|
+
if (Date.now() > e.expiresAt) {
|
|
12
|
+
this.store.delete(key);
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
return e.value;
|
|
16
|
+
}
|
|
17
|
+
set(key, value) {
|
|
18
|
+
this.store.set(key, { value, expiresAt: Date.now() + this.ttlMs });
|
|
19
|
+
}
|
|
20
|
+
delete(key) {
|
|
21
|
+
this.store.delete(key);
|
|
22
|
+
}
|
|
23
|
+
clear() {
|
|
24
|
+
this.store.clear();
|
|
25
|
+
}
|
|
26
|
+
}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type EvaluateFlagResult, type EvaluationContext } from "@core-sdk/feature-flags-core";
|
|
2
|
+
import type { FeatureFlagRecord, FeatureFlagsSdkConfig } from "./types.js";
|
|
3
|
+
export declare class FeatureFlagsClient {
|
|
4
|
+
private readonly config;
|
|
5
|
+
private readonly fetchImpl;
|
|
6
|
+
private readonly cache;
|
|
7
|
+
constructor(config: FeatureFlagsSdkConfig);
|
|
8
|
+
private headers;
|
|
9
|
+
private parseJson;
|
|
10
|
+
/**
|
|
11
|
+
* Load all flags for project into memory cache.
|
|
12
|
+
*/
|
|
13
|
+
bootstrap(): Promise<FeatureFlagRecord[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Cached definition by key; fetches detail endpoint on miss.
|
|
16
|
+
*/
|
|
17
|
+
getFlag(flagKey: string): Promise<FeatureFlagRecord | undefined>;
|
|
18
|
+
evaluate(flagKey: string, context?: EvaluationContext): EvaluateFlagResult;
|
|
19
|
+
evaluateAsync(flagKey: string, context?: EvaluationContext): Promise<EvaluateFlagResult>;
|
|
20
|
+
isEnabled(flagKey: string, context?: EvaluationContext): Promise<boolean>;
|
|
21
|
+
/**
|
|
22
|
+
* Change history for a flag (pass-through JSON — shape depends on API).
|
|
23
|
+
*/
|
|
24
|
+
getHistory(flagKey: string): Promise<unknown>;
|
|
25
|
+
/**
|
|
26
|
+
* Specific version snapshot (for rollback preview on client).
|
|
27
|
+
*/
|
|
28
|
+
getVersionDetail(flagKey: string, version: number): Promise<unknown>;
|
|
29
|
+
invalidate(flagKey?: string): void;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACvB,MAAM,8BAA8B,CAAC;AAStC,OAAO,KAAK,EACV,iBAAiB,EACjB,qBAAqB,EAEtB,MAAM,YAAY,CAAC;AAiBpB,qBAAa,kBAAkB;IAIjB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAHnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;gBAE7B,MAAM,EAAE,qBAAqB;YAO5C,OAAO;YAQP,SAAS;IAUvB;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAsB/C;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IA2BtE,QAAQ,CACN,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,iBAAsB,GAC9B,kBAAkB;IAUf,aAAa,CACjB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,kBAAkB,CAAC;IAQxB,SAAS,CACb,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,OAAO,CAAC;IAUnB;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAanD;;OAEG;IACG,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAc1E,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI;CAOnC"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { evaluateFlag, } from "@core-sdk/feature-flags-core";
|
|
2
|
+
import { TtlMemoryCache } from "./cache.js";
|
|
3
|
+
import { flagDetailPath, flagHistoryPath, flagsCollectionPath, flagVersionPath, } from "./paths.js";
|
|
4
|
+
import { parseFlagRecord, unwrapFlagList } from "./normalize.js";
|
|
5
|
+
function defaultFetch() {
|
|
6
|
+
const f = globalThis.fetch;
|
|
7
|
+
if (typeof f !== "function") {
|
|
8
|
+
throw new Error("fetch is not available; pass fetchImpl in config");
|
|
9
|
+
}
|
|
10
|
+
return f.bind(globalThis);
|
|
11
|
+
}
|
|
12
|
+
function toDefinition(rec) {
|
|
13
|
+
return {
|
|
14
|
+
enabled: rec.enabled,
|
|
15
|
+
rules: rec.rules,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export class FeatureFlagsClient {
|
|
19
|
+
config;
|
|
20
|
+
fetchImpl;
|
|
21
|
+
cache;
|
|
22
|
+
constructor(config) {
|
|
23
|
+
this.config = config;
|
|
24
|
+
this.fetchImpl = config.fetchImpl ?? defaultFetch();
|
|
25
|
+
this.cache = new TtlMemoryCache(config.cacheTtlMs ?? 60_000);
|
|
26
|
+
}
|
|
27
|
+
async headers() {
|
|
28
|
+
const extra = this.config.getHeaders ? await this.config.getHeaders() : {};
|
|
29
|
+
return {
|
|
30
|
+
Accept: "application/json",
|
|
31
|
+
...extra,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
async parseJson(res) {
|
|
35
|
+
const text = await res.text();
|
|
36
|
+
if (!text)
|
|
37
|
+
return null;
|
|
38
|
+
try {
|
|
39
|
+
return JSON.parse(text);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
throw new Error(`Invalid JSON response (${res.status})`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Load all flags for project into memory cache.
|
|
47
|
+
*/
|
|
48
|
+
async bootstrap() {
|
|
49
|
+
const url = flagsCollectionPath(this.config.baseUrl, this.config.projectKey);
|
|
50
|
+
const res = await this.fetchImpl(url, { headers: await this.headers() });
|
|
51
|
+
if (!res.ok) {
|
|
52
|
+
throw new Error(`bootstrap failed: ${res.status}`);
|
|
53
|
+
}
|
|
54
|
+
const json = await this.parseJson(res);
|
|
55
|
+
const rows = unwrapFlagList(json);
|
|
56
|
+
const list = [];
|
|
57
|
+
for (const row of rows) {
|
|
58
|
+
const rec = parseFlagRecord(row);
|
|
59
|
+
if (rec) {
|
|
60
|
+
this.cache.set(rec.key, rec);
|
|
61
|
+
list.push(rec);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return list;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Cached definition by key; fetches detail endpoint on miss.
|
|
68
|
+
*/
|
|
69
|
+
async getFlag(flagKey) {
|
|
70
|
+
const hit = this.cache.get(flagKey);
|
|
71
|
+
if (hit)
|
|
72
|
+
return hit;
|
|
73
|
+
const url = flagDetailPath(this.config.baseUrl, this.config.projectKey, flagKey);
|
|
74
|
+
const res = await this.fetchImpl(url, { headers: await this.headers() });
|
|
75
|
+
if (res.status === 404)
|
|
76
|
+
return undefined;
|
|
77
|
+
if (!res.ok) {
|
|
78
|
+
throw new Error(`getFlag failed: ${res.status}`);
|
|
79
|
+
}
|
|
80
|
+
const json = await this.parseJson(res);
|
|
81
|
+
const raw = json && typeof json === "object" && "data" in json
|
|
82
|
+
? json.data
|
|
83
|
+
: json;
|
|
84
|
+
const rec = parseFlagRecord(raw);
|
|
85
|
+
if (rec) {
|
|
86
|
+
this.cache.set(rec.key, rec);
|
|
87
|
+
return rec;
|
|
88
|
+
}
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
evaluate(flagKey, context = {}) {
|
|
92
|
+
const rec = this.cache.get(flagKey);
|
|
93
|
+
if (!rec) {
|
|
94
|
+
throw new Error(`Flag not in cache: ${flagKey}; call bootstrap() or getFlag() first`);
|
|
95
|
+
}
|
|
96
|
+
return evaluateFlag(toDefinition(rec), context);
|
|
97
|
+
}
|
|
98
|
+
async evaluateAsync(flagKey, context = {}) {
|
|
99
|
+
const rec = (await this.getFlag(flagKey)) ?? this.cache.get(flagKey);
|
|
100
|
+
if (!rec) {
|
|
101
|
+
throw new Error(`Unknown flag: ${flagKey}`);
|
|
102
|
+
}
|
|
103
|
+
return evaluateFlag(toDefinition(rec), context);
|
|
104
|
+
}
|
|
105
|
+
async isEnabled(flagKey, context = {}) {
|
|
106
|
+
try {
|
|
107
|
+
const r = await this.evaluateAsync(flagKey, context);
|
|
108
|
+
return r.enabled;
|
|
109
|
+
}
|
|
110
|
+
catch (e) {
|
|
111
|
+
console.error(`Error evaluating flag ${flagKey}:`, e);
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Change history for a flag (pass-through JSON — shape depends on API).
|
|
117
|
+
*/
|
|
118
|
+
async getHistory(flagKey) {
|
|
119
|
+
const url = flagHistoryPath(this.config.baseUrl, this.config.projectKey, flagKey);
|
|
120
|
+
const res = await this.fetchImpl(url, { headers: await this.headers() });
|
|
121
|
+
if (!res.ok) {
|
|
122
|
+
throw new Error(`getHistory failed: ${res.status}`);
|
|
123
|
+
}
|
|
124
|
+
return this.parseJson(res);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Specific version snapshot (for rollback preview on client).
|
|
128
|
+
*/
|
|
129
|
+
async getVersionDetail(flagKey, version) {
|
|
130
|
+
const url = flagVersionPath(this.config.baseUrl, this.config.projectKey, flagKey, version);
|
|
131
|
+
const res = await this.fetchImpl(url, { headers: await this.headers() });
|
|
132
|
+
if (!res.ok) {
|
|
133
|
+
throw new Error(`getVersionDetail failed: ${res.status}`);
|
|
134
|
+
}
|
|
135
|
+
return this.parseJson(res);
|
|
136
|
+
}
|
|
137
|
+
invalidate(flagKey) {
|
|
138
|
+
if (flagKey === undefined) {
|
|
139
|
+
this.cache.clear();
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
this.cache.delete(flagKey);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EACV,iBAAiB,EACjB,qBAAqB,EACrB,YAAY,EACZ,gBAAgB,EAChB,SAAS,GACV,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { FeatureFlagsClient } from "./client.js";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { FeatureFlagRecord } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parse one flag object from API JSON.
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseFlagRecord(raw: unknown): FeatureFlagRecord | null;
|
|
6
|
+
/**
|
|
7
|
+
* Extract array from list response (raw array or `{ data: [] }`).
|
|
8
|
+
*/
|
|
9
|
+
export declare function unwrapFlagList(json: unknown): unknown[];
|
|
10
|
+
//# sourceMappingURL=normalize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../src/normalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA8BpD;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,iBAAiB,GAAG,IAAI,CAOtE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,EAAE,CAKvD"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
function isObject(v) {
|
|
2
|
+
return v !== null && typeof v === "object" && !Array.isArray(v);
|
|
3
|
+
}
|
|
4
|
+
function asRules(v) {
|
|
5
|
+
if (!Array.isArray(v))
|
|
6
|
+
return [];
|
|
7
|
+
const out = [];
|
|
8
|
+
for (const item of v) {
|
|
9
|
+
if (!isObject(item))
|
|
10
|
+
continue;
|
|
11
|
+
const id = item.id;
|
|
12
|
+
const field = item.field;
|
|
13
|
+
const operator = item.operator;
|
|
14
|
+
if (typeof id !== "string" || typeof field !== "string" || typeof operator !== "string") {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (!["eq", "neq", "contains", "in"].includes(operator))
|
|
18
|
+
continue;
|
|
19
|
+
const active = item.active === false ? false : true;
|
|
20
|
+
out.push({
|
|
21
|
+
id,
|
|
22
|
+
field,
|
|
23
|
+
operator: operator,
|
|
24
|
+
value: item.value,
|
|
25
|
+
active,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Parse one flag object from API JSON.
|
|
32
|
+
*/
|
|
33
|
+
export function parseFlagRecord(raw) {
|
|
34
|
+
if (!isObject(raw))
|
|
35
|
+
return null;
|
|
36
|
+
const key = raw.key;
|
|
37
|
+
if (typeof key !== "string" || key.length === 0)
|
|
38
|
+
return null;
|
|
39
|
+
const enabled = Boolean(raw.enabled);
|
|
40
|
+
const rules = asRules(raw.rules);
|
|
41
|
+
return { key, enabled, rules };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Extract array from list response (raw array or `{ data: [] }`).
|
|
45
|
+
*/
|
|
46
|
+
export function unwrapFlagList(json) {
|
|
47
|
+
if (Array.isArray(json))
|
|
48
|
+
return json;
|
|
49
|
+
if (isObject(json) && Array.isArray(json.data))
|
|
50
|
+
return json.data;
|
|
51
|
+
if (isObject(json) && Array.isArray(json.flags))
|
|
52
|
+
return json.flags;
|
|
53
|
+
return [];
|
|
54
|
+
}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Internal route builders — consumers only pass baseUrl + projectKey. */
|
|
2
|
+
export declare function flagsCollectionPath(baseUrl: string, projectKey: string): string;
|
|
3
|
+
export declare function flagDetailPath(baseUrl: string, projectKey: string, flagKey: string): string;
|
|
4
|
+
export declare function flagHistoryPath(baseUrl: string, projectKey: string, flagKey: string): string;
|
|
5
|
+
export declare function flagVersionPath(baseUrl: string, projectKey: string, flagKey: string, version: number): string;
|
|
6
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAE1E,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,MAAM,CAGR;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,MAAM,CAKR;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,MAAM,CAKR;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,MAAM,CAKR"}
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Internal route builders — consumers only pass baseUrl + projectKey. */
|
|
2
|
+
export function flagsCollectionPath(baseUrl, projectKey) {
|
|
3
|
+
const b = baseUrl.replace(/\/$/, "");
|
|
4
|
+
return `${b}/projects/${encodeURIComponent(projectKey)}/flags`;
|
|
5
|
+
}
|
|
6
|
+
export function flagDetailPath(baseUrl, projectKey, flagKey) {
|
|
7
|
+
const b = baseUrl.replace(/\/$/, "");
|
|
8
|
+
return `${b}/projects/${encodeURIComponent(projectKey)}/flags/${encodeURIComponent(flagKey)}`;
|
|
9
|
+
}
|
|
10
|
+
export function flagHistoryPath(baseUrl, projectKey, flagKey) {
|
|
11
|
+
const b = baseUrl.replace(/\/$/, "");
|
|
12
|
+
return `${b}/projects/${encodeURIComponent(projectKey)}/flags/${encodeURIComponent(flagKey)}/history`;
|
|
13
|
+
}
|
|
14
|
+
export function flagVersionPath(baseUrl, projectKey, flagKey, version) {
|
|
15
|
+
const b = baseUrl.replace(/\/$/, "");
|
|
16
|
+
return `${b}/projects/${encodeURIComponent(projectKey)}/flags/${encodeURIComponent(flagKey)}/versions/${version}`;
|
|
17
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { DeclarativeRule } from "@core-sdk/feature-flags-core";
|
|
2
|
+
/**
|
|
3
|
+
* Normalized flag row after bootstrap / get — enough for evaluateFlag.
|
|
4
|
+
*/
|
|
5
|
+
export interface FeatureFlagRecord {
|
|
6
|
+
readonly key: string;
|
|
7
|
+
readonly enabled: boolean;
|
|
8
|
+
readonly rules: readonly DeclarativeRule[];
|
|
9
|
+
}
|
|
10
|
+
export type HttpFetch = (input: string, init?: RequestInit) => Promise<Response>;
|
|
11
|
+
export interface FeatureFlagsSdkConfig {
|
|
12
|
+
readonly baseUrl: string;
|
|
13
|
+
readonly projectKey: string;
|
|
14
|
+
/** Default globalThis.fetch */
|
|
15
|
+
readonly fetchImpl?: HttpFetch;
|
|
16
|
+
/** Extra headers (e.g. Authorization) */
|
|
17
|
+
readonly getHeaders?: () => Record<string, string> | Promise<Record<string, string>>;
|
|
18
|
+
/** Cache TTL for in-memory flag definitions (default 60_000) */
|
|
19
|
+
readonly cacheTtlMs?: number;
|
|
20
|
+
}
|
|
21
|
+
/** Loose API body — server may wrap in `{ data }`. */
|
|
22
|
+
export type FlagListJson = unknown;
|
|
23
|
+
export interface HistoryEntryJson {
|
|
24
|
+
readonly id?: string;
|
|
25
|
+
readonly at?: string;
|
|
26
|
+
readonly action?: string;
|
|
27
|
+
readonly version?: number;
|
|
28
|
+
readonly summaryNote?: string;
|
|
29
|
+
readonly [key: string]: unknown;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,SAAS,eAAe,EAAE,CAAC;CAC5C;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEjF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,+BAA+B;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B,yCAAyC;IACzC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrF,gEAAgE;IAChE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,sDAAsD;AACtD,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC;AAEnC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@core-sdk/feature-flags-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "HTTP client + cache for feature flags; uses @core-sdk/feature-flags-core for evaluation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc -p tsconfig.build.json",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@core-sdk/feature-flags-core": "0.1.1"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"typescript": "^5.7.3",
|
|
27
|
+
"vitest": "^3.0.9"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18"
|
|
31
|
+
}
|
|
32
|
+
}
|