flagmint-js-sdk 2.2.1 → 2.2.2-rc.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/flagmint.cjs.js +125 -20
- package/dist/flagmint.cjs.js.map +1 -1
- package/dist/flagmint.es.js +125 -20
- package/dist/flagmint.es.js.map +1 -1
- package/dist/flagmint.umd.js +125 -20
- package/dist/flagmint.umd.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/sdk/core/config-sync/evaluateSdkFlag.d.ts +24 -1
- package/dist/sdk/core/config-sync/index.d.ts +4 -2
- package/dist/sdk/core/config-sync/piiHash.d.ts +53 -0
- package/dist/sdk/core/config-sync/rulesStore.d.ts +3 -0
- package/dist/sdk/core/config-sync/types.d.ts +12 -2
- package/package.json +1 -1
package/dist/flagmint.umd.js
CHANGED
|
@@ -39095,7 +39095,7 @@ var __publicField = (obj, key, value) => {
|
|
|
39095
39095
|
this.connectPromise = new Promise((resolve, reject) => {
|
|
39096
39096
|
this.connectResolve = resolve;
|
|
39097
39097
|
this.connectReject = reject;
|
|
39098
|
-
const sdkVersion = "2.2.
|
|
39098
|
+
const sdkVersion = "2.2.2-rc.0";
|
|
39099
39099
|
const platform2 = typeof window !== "undefined" ? "browser" : "nodejs";
|
|
39100
39100
|
const wrapperName = this.configOptions?.wrapper?.name || "native-js";
|
|
39101
39101
|
const wrapperVersion = this.configOptions?.wrapper?.version || "none";
|
|
@@ -41781,7 +41781,7 @@ var __publicField = (obj, key, value) => {
|
|
|
41781
41781
|
const hkdf = (hash2, ikm, salt, info, length) => expand(hash2, extract(hash2, ikm, salt), info, length);
|
|
41782
41782
|
const ASL_HKDF_INFO = "flagmint-asl-config-sync-mac-v1";
|
|
41783
41783
|
const ASL_KEY_AGREEMENT = "x25519-hkdf-sha256";
|
|
41784
|
-
const textEncoder$
|
|
41784
|
+
const textEncoder$2 = new TextEncoder();
|
|
41785
41785
|
function generateAslClientKeyPair() {
|
|
41786
41786
|
const privateKey = x25519.utils.randomSecretKey();
|
|
41787
41787
|
const publicKey = x25519.getPublicKey(privateKey);
|
|
@@ -41812,7 +41812,7 @@ var __publicField = (obj, key, value) => {
|
|
|
41812
41812
|
sha256,
|
|
41813
41813
|
shared,
|
|
41814
41814
|
salt,
|
|
41815
|
-
textEncoder$
|
|
41815
|
+
textEncoder$2.encode(ASL_HKDF_INFO),
|
|
41816
41816
|
32
|
|
41817
41817
|
);
|
|
41818
41818
|
return { configMacKey };
|
|
@@ -41822,7 +41822,7 @@ var __publicField = (obj, key, value) => {
|
|
|
41822
41822
|
return;
|
|
41823
41823
|
key2.fill(0);
|
|
41824
41824
|
}
|
|
41825
|
-
const textEncoder = new TextEncoder();
|
|
41825
|
+
const textEncoder$1 = new TextEncoder();
|
|
41826
41826
|
function canonicalizeForSigning(value) {
|
|
41827
41827
|
return JSON.stringify(sortValue(value));
|
|
41828
41828
|
}
|
|
@@ -41839,12 +41839,12 @@ var __publicField = (obj, key, value) => {
|
|
|
41839
41839
|
return sorted;
|
|
41840
41840
|
}
|
|
41841
41841
|
function normalizeMacKey(secret) {
|
|
41842
|
-
return typeof secret === "string" ? textEncoder.encode(secret) : secret;
|
|
41842
|
+
return typeof secret === "string" ? textEncoder$1.encode(secret) : secret;
|
|
41843
41843
|
}
|
|
41844
41844
|
function signConfigPayload(body, secret) {
|
|
41845
41845
|
const { signature: _ignored, ...unsigned } = body;
|
|
41846
41846
|
const canonical = canonicalizeForSigning(unsigned);
|
|
41847
|
-
const mac = hmac(sha256, normalizeMacKey(secret), textEncoder.encode(canonical));
|
|
41847
|
+
const mac = hmac(sha256, normalizeMacKey(secret), textEncoder$1.encode(canonical));
|
|
41848
41848
|
return bytesToHex$1(mac);
|
|
41849
41849
|
}
|
|
41850
41850
|
function timingSafeEqualBytes(a, b) {
|
|
@@ -41866,13 +41866,93 @@ var __publicField = (obj, key, value) => {
|
|
|
41866
41866
|
} catch {
|
|
41867
41867
|
return false;
|
|
41868
41868
|
}
|
|
41869
|
-
const a = textEncoder.encode(body.signature);
|
|
41870
|
-
const b = textEncoder.encode(expected);
|
|
41869
|
+
const a = textEncoder$1.encode(body.signature);
|
|
41870
|
+
const b = textEncoder$1.encode(expected);
|
|
41871
41871
|
return timingSafeEqualBytes(a, b);
|
|
41872
41872
|
}
|
|
41873
41873
|
function isConfigPayloadExpired(expiresAt, now = Date.now()) {
|
|
41874
41874
|
return !Number.isFinite(expiresAt) || now >= expiresAt;
|
|
41875
41875
|
}
|
|
41876
|
+
const PII_VALUE_ENCODING = "hmac-v1";
|
|
41877
|
+
const textEncoder = new TextEncoder();
|
|
41878
|
+
const HASH_HEX_PATTERN = /^[0-9a-f]{64}$/;
|
|
41879
|
+
function normalizePiiString(value) {
|
|
41880
|
+
return value.trim().toLowerCase();
|
|
41881
|
+
}
|
|
41882
|
+
function hashPiiValue(value, salt) {
|
|
41883
|
+
const mac = hmac(
|
|
41884
|
+
sha256,
|
|
41885
|
+
textEncoder.encode(salt),
|
|
41886
|
+
textEncoder.encode(normalizePiiString(value))
|
|
41887
|
+
);
|
|
41888
|
+
return bytesToHex$1(mac);
|
|
41889
|
+
}
|
|
41890
|
+
function isPiiAttribute(attribute, piiAttributes) {
|
|
41891
|
+
if (!attribute || piiAttributes.length === 0)
|
|
41892
|
+
return false;
|
|
41893
|
+
const attr = attribute.trim();
|
|
41894
|
+
if (!attr)
|
|
41895
|
+
return false;
|
|
41896
|
+
for (const key2 of piiAttributes) {
|
|
41897
|
+
if (!key2)
|
|
41898
|
+
continue;
|
|
41899
|
+
if (attr === key2)
|
|
41900
|
+
return true;
|
|
41901
|
+
if (attr.endsWith(`.${key2}`))
|
|
41902
|
+
return true;
|
|
41903
|
+
}
|
|
41904
|
+
return false;
|
|
41905
|
+
}
|
|
41906
|
+
function piiWireOptionsFromPayload(payload) {
|
|
41907
|
+
if (!payload)
|
|
41908
|
+
return null;
|
|
41909
|
+
const salt = typeof payload.piiSalt === "string" ? payload.piiSalt : "";
|
|
41910
|
+
if (!salt)
|
|
41911
|
+
return null;
|
|
41912
|
+
const encoding = typeof payload.piiValueEncoding === "string" ? payload.piiValueEncoding : PII_VALUE_ENCODING;
|
|
41913
|
+
if (encoding !== PII_VALUE_ENCODING)
|
|
41914
|
+
return null;
|
|
41915
|
+
const attrs = Array.isArray(payload.piiAttributes) ? payload.piiAttributes.filter((k) => typeof k === "string") : [];
|
|
41916
|
+
return {
|
|
41917
|
+
piiAttributes: attrs,
|
|
41918
|
+
piiSalt: salt,
|
|
41919
|
+
piiValueEncoding: PII_VALUE_ENCODING
|
|
41920
|
+
};
|
|
41921
|
+
}
|
|
41922
|
+
function applyPiiHashToFlatContext(context, options) {
|
|
41923
|
+
if (!options || !options.piiSalt || !options.piiAttributes.length || options.piiValueEncoding !== PII_VALUE_ENCODING) {
|
|
41924
|
+
return context;
|
|
41925
|
+
}
|
|
41926
|
+
let changed = false;
|
|
41927
|
+
const out = { ...context };
|
|
41928
|
+
for (const [key2, value] of Object.entries(context)) {
|
|
41929
|
+
if (!isPiiAttribute(key2, options.piiAttributes))
|
|
41930
|
+
continue;
|
|
41931
|
+
if (typeof value === "string") {
|
|
41932
|
+
if (HASH_HEX_PATTERN.test(value))
|
|
41933
|
+
continue;
|
|
41934
|
+
out[key2] = hashPiiValue(value, options.piiSalt);
|
|
41935
|
+
changed = true;
|
|
41936
|
+
continue;
|
|
41937
|
+
}
|
|
41938
|
+
if (Array.isArray(value)) {
|
|
41939
|
+
let arrayChanged = false;
|
|
41940
|
+
const next = value.map((entry) => {
|
|
41941
|
+
if (typeof entry !== "string")
|
|
41942
|
+
return entry;
|
|
41943
|
+
if (HASH_HEX_PATTERN.test(entry))
|
|
41944
|
+
return entry;
|
|
41945
|
+
arrayChanged = true;
|
|
41946
|
+
return hashPiiValue(entry, options.piiSalt);
|
|
41947
|
+
});
|
|
41948
|
+
if (arrayChanged) {
|
|
41949
|
+
out[key2] = next;
|
|
41950
|
+
changed = true;
|
|
41951
|
+
}
|
|
41952
|
+
}
|
|
41953
|
+
}
|
|
41954
|
+
return changed ? out : context;
|
|
41955
|
+
}
|
|
41876
41956
|
function createEmptyRulesState() {
|
|
41877
41957
|
return {
|
|
41878
41958
|
version: 0,
|
|
@@ -41880,7 +41960,8 @@ var __publicField = (obj, key, value) => {
|
|
|
41880
41960
|
flags: /* @__PURE__ */ new Map(),
|
|
41881
41961
|
segments: /* @__PURE__ */ new Map(),
|
|
41882
41962
|
ready: false,
|
|
41883
|
-
needsFullConfig: true
|
|
41963
|
+
needsFullConfig: true,
|
|
41964
|
+
piiWire: null
|
|
41884
41965
|
};
|
|
41885
41966
|
}
|
|
41886
41967
|
function cloneState(state) {
|
|
@@ -41890,7 +41971,12 @@ var __publicField = (obj, key, value) => {
|
|
|
41890
41971
|
flags: new Map(state.flags),
|
|
41891
41972
|
segments: new Map(state.segments),
|
|
41892
41973
|
ready: state.ready,
|
|
41893
|
-
needsFullConfig: state.needsFullConfig
|
|
41974
|
+
needsFullConfig: state.needsFullConfig,
|
|
41975
|
+
piiWire: state.piiWire ? {
|
|
41976
|
+
piiAttributes: [...state.piiWire.piiAttributes],
|
|
41977
|
+
piiSalt: state.piiWire.piiSalt,
|
|
41978
|
+
piiValueEncoding: state.piiWire.piiValueEncoding
|
|
41979
|
+
} : null
|
|
41894
41980
|
};
|
|
41895
41981
|
}
|
|
41896
41982
|
function segmentsFromRecord(record) {
|
|
@@ -41923,7 +42009,8 @@ var __publicField = (obj, key, value) => {
|
|
|
41923
42009
|
flags,
|
|
41924
42010
|
segments: segmentsFromRecord(action.segments),
|
|
41925
42011
|
ready: true,
|
|
41926
|
-
needsFullConfig: false
|
|
42012
|
+
needsFullConfig: false,
|
|
42013
|
+
piiWire: piiWireOptionsFromPayload(action)
|
|
41927
42014
|
};
|
|
41928
42015
|
}
|
|
41929
42016
|
function applyPatch(state, action) {
|
|
@@ -41935,13 +42022,15 @@ var __publicField = (obj, key, value) => {
|
|
|
41935
42022
|
if (flag?.key)
|
|
41936
42023
|
flags.set(flag.key, flag);
|
|
41937
42024
|
}
|
|
42025
|
+
const nextPii = piiWireOptionsFromPayload(action) ?? state.piiWire;
|
|
41938
42026
|
return {
|
|
41939
42027
|
version: action.toVersion,
|
|
41940
42028
|
expiresAt: typeof action.expiresAt === "number" ? action.expiresAt : state.expiresAt,
|
|
41941
42029
|
flags,
|
|
41942
42030
|
segments: applySegmentUpserts(state.segments, action.segments),
|
|
41943
42031
|
ready: true,
|
|
41944
|
-
needsFullConfig: false
|
|
42032
|
+
needsFullConfig: false,
|
|
42033
|
+
piiWire: nextPii
|
|
41945
42034
|
};
|
|
41946
42035
|
}
|
|
41947
42036
|
function reduceRules(state, action, now = Date.now()) {
|
|
@@ -42118,11 +42207,17 @@ var __publicField = (obj, key, value) => {
|
|
|
42118
42207
|
this.state.segments.forEach((segment, id) => {
|
|
42119
42208
|
segments[id] = segment;
|
|
42120
42209
|
});
|
|
42210
|
+
const pii = this.state.piiWire;
|
|
42121
42211
|
return {
|
|
42122
42212
|
version: this.state.version,
|
|
42123
42213
|
expiresAt: this.state.expiresAt,
|
|
42124
42214
|
flags: Array.from(this.state.flags.values()),
|
|
42125
|
-
segments
|
|
42215
|
+
segments,
|
|
42216
|
+
...pii ? {
|
|
42217
|
+
piiAttributes: [...pii.piiAttributes],
|
|
42218
|
+
piiSalt: pii.piiSalt,
|
|
42219
|
+
piiValueEncoding: pii.piiValueEncoding
|
|
42220
|
+
} : {}
|
|
42126
42221
|
};
|
|
42127
42222
|
}
|
|
42128
42223
|
hydrateFromSnapshot(snapshot, now = Date.now()) {
|
|
@@ -42138,7 +42233,8 @@ var __publicField = (obj, key, value) => {
|
|
|
42138
42233
|
flags,
|
|
42139
42234
|
segments: segmentsFromRecord(snapshot.segments),
|
|
42140
42235
|
ready: !expired && flags.size > 0,
|
|
42141
|
-
needsFullConfig: expired || flags.size === 0
|
|
42236
|
+
needsFullConfig: expired || flags.size === 0,
|
|
42237
|
+
piiWire: piiWireOptionsFromPayload(snapshot)
|
|
42142
42238
|
};
|
|
42143
42239
|
}
|
|
42144
42240
|
}
|
|
@@ -42902,8 +42998,13 @@ var __publicField = (obj, key, value) => {
|
|
|
42902
42998
|
}
|
|
42903
42999
|
return context;
|
|
42904
43000
|
}
|
|
42905
|
-
function
|
|
42906
|
-
const
|
|
43001
|
+
function prepareContextForLocalEval(context, pii) {
|
|
43002
|
+
const prepared = prepareContextForEvaluator(context);
|
|
43003
|
+
const flat = flattenEvaluationContext(prepared);
|
|
43004
|
+
return applyPiiHashToFlatContext(flat, pii);
|
|
43005
|
+
}
|
|
43006
|
+
function evaluateSdkFlag(flag, context, segments, pii) {
|
|
43007
|
+
const evalContext = prepareContextForLocalEval(context, pii);
|
|
42907
43008
|
const variationsById = {};
|
|
42908
43009
|
for (const v of flag.variations || []) {
|
|
42909
43010
|
if (v?.id)
|
|
@@ -42963,7 +43064,7 @@ var __publicField = (obj, key, value) => {
|
|
|
42963
43064
|
}
|
|
42964
43065
|
function evaluateAllSdkFlags(flags, context, segments, options) {
|
|
42965
43066
|
const list = flags instanceof Map ? Array.from(flags.values()) : flags;
|
|
42966
|
-
const prepared =
|
|
43067
|
+
const prepared = prepareContextForLocalEval(context, options?.pii);
|
|
42967
43068
|
const out = {};
|
|
42968
43069
|
for (const flag of list) {
|
|
42969
43070
|
if (!flag?.key)
|
|
@@ -42972,7 +43073,7 @@ var __publicField = (obj, key, value) => {
|
|
|
42972
43073
|
out[flag.key] = coerceType(flag.default_value, flag.type);
|
|
42973
43074
|
continue;
|
|
42974
43075
|
}
|
|
42975
|
-
out[flag.key] = evaluateSdkFlag(flag, prepared, segments);
|
|
43076
|
+
out[flag.key] = evaluateSdkFlag(flag, prepared, segments, null);
|
|
42976
43077
|
}
|
|
42977
43078
|
return out;
|
|
42978
43079
|
}
|
|
@@ -43417,7 +43518,8 @@ var __publicField = (obj, key, value) => {
|
|
|
43417
43518
|
value = evaluateSdkFlag(
|
|
43418
43519
|
flag,
|
|
43419
43520
|
this.context,
|
|
43420
|
-
this.rulesStore.getState().segments
|
|
43521
|
+
this.rulesStore.getState().segments,
|
|
43522
|
+
this.rulesStore.getState().piiWire
|
|
43421
43523
|
) ?? fallback;
|
|
43422
43524
|
}
|
|
43423
43525
|
} else {
|
|
@@ -43897,7 +43999,7 @@ var __publicField = (obj, key, value) => {
|
|
|
43897
43999
|
state.flags,
|
|
43898
44000
|
context ?? this.context,
|
|
43899
44001
|
state.segments,
|
|
43900
|
-
{ failClosedDefaultsOnly: failClosed }
|
|
44002
|
+
{ failClosedDefaultsOnly: failClosed, pii: state.piiWire }
|
|
43901
44003
|
);
|
|
43902
44004
|
}
|
|
43903
44005
|
analyticsMapFromRulesStore() {
|
|
@@ -44026,6 +44128,7 @@ var __publicField = (obj, key, value) => {
|
|
|
44026
44128
|
exports2.LongPollingTransport = LongPollingTransport;
|
|
44027
44129
|
exports2.RulesStore = RulesStore;
|
|
44028
44130
|
exports2.SseTransport = SseTransport;
|
|
44131
|
+
exports2.applyPiiHashToFlatContext = applyPiiHashToFlatContext;
|
|
44029
44132
|
exports2.applyRolloutStrategy = applyRolloutStrategy;
|
|
44030
44133
|
exports2.asyncCache = cacheHelper_async;
|
|
44031
44134
|
exports2.canonicalizeForSigning = canonicalizeForSigning;
|
|
@@ -44043,11 +44146,13 @@ var __publicField = (obj, key, value) => {
|
|
|
44043
44146
|
exports2.flattenEvaluationContext = flattenEvaluationContext;
|
|
44044
44147
|
exports2.generateAslClientKeyPair = generateAslClientKeyPair;
|
|
44045
44148
|
exports2.hashPercent = hashPercent;
|
|
44149
|
+
exports2.hashPiiValue = hashPiiValue;
|
|
44046
44150
|
exports2.hashToPercentage = hashToPercentage;
|
|
44047
44151
|
exports2.isConfigPayloadExpired = isConfigPayloadExpired;
|
|
44048
44152
|
exports2.isInSegment = isInSegment;
|
|
44049
44153
|
exports2.performAslHandshake = performAslHandshake;
|
|
44050
44154
|
exports2.pickVariant = pickVariant;
|
|
44155
|
+
exports2.prepareContextForLocalEval = prepareContextForLocalEval;
|
|
44051
44156
|
exports2.reduceRules = reduceRules;
|
|
44052
44157
|
exports2.signConfigPayload = signConfigPayload;
|
|
44053
44158
|
exports2.stringHash = stringHash;
|