@variantlab/react-native 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/qr.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/deep-link/validate.ts","../src/deep-link/encode.ts","../src/qr.ts"],"names":[],"mappings":"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","file":"qr.js","sourcesContent":["/**\n * Validate a candidate share payload before applying it.\n *\n * Share payloads come from untrusted input — a deep link, a QR code,\n * a clipboard paste — so we treat them as adversarial. The validator\n * walks the structure with `Object.create(null)` semantics in mind:\n *\n * - Reject prototype-pollution keys (`__proto__`, `constructor`,\n * `prototype`) anywhere in the tree.\n * - Enforce strict id regexes on every override key/value so a\n * malformed payload cannot smuggle non-printable bytes into a\n * `setVariant` call.\n * - Cap the override count and total decoded size to bound memory.\n * - Honor an optional `expires` field so QR codes shared earlier\n * in the day cannot be replayed forever.\n *\n * The validator returns a `ValidationResult` discriminated union\n * instead of throwing because callers (deep-link handler, QR scanner)\n * almost always want to silently surface a failure to the UI rather\n * than treat it as a runtime error.\n */\nimport type { SharePayload, ValidationFailure, ValidationResult } from \"./types.js\";\n\n/** Match the same id regex as `experiments.json`. */\nconst ID_RE = /^[a-z0-9][a-z0-9-]{0,63}$/;\nconst POLLUTION_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n\nconst MAX_OVERRIDES = 100;\nconst MAX_PAYLOAD_BYTES = 1024;\n\nexport function validatePayload(input: unknown, now: number = Date.now()): ValidationResult {\n if (input === null || typeof input !== \"object\" || Array.isArray(input)) {\n return fail(\"not-an-object\");\n }\n\n if (hasPollution(input)) return fail(\"prototype-pollution\");\n\n const obj = input as Record<string, unknown>;\n\n if (obj.v !== 1) return fail(\"bad-version\");\n\n const overrides = obj.overrides;\n if (overrides === null || typeof overrides !== \"object\" || Array.isArray(overrides)) {\n return fail(\"missing-overrides\");\n }\n\n const overrideEntries = Object.entries(overrides as Record<string, unknown>);\n if (overrideEntries.length > MAX_OVERRIDES) return fail(\"overrides-too-large\");\n\n const safeOverrides: Record<string, string> = Object.create(null) as Record<string, string>;\n for (const [key, value] of overrideEntries) {\n if (POLLUTION_KEYS.has(key)) return fail(\"prototype-pollution\");\n if (!ID_RE.test(key)) return fail(\"bad-override-key\");\n if (typeof value !== \"string\") return fail(\"bad-override-value\");\n if (!ID_RE.test(value)) return fail(\"bad-override-value\");\n safeOverrides[key] = value;\n }\n\n let context: SharePayload[\"context\"];\n if (obj.context !== undefined) {\n if (obj.context === null || typeof obj.context !== \"object\" || Array.isArray(obj.context)) {\n return fail(\"bad-context\");\n }\n const sanitized = sanitizeContext(obj.context as Record<string, unknown>);\n if (sanitized === null) return fail(\"bad-context\");\n context = sanitized;\n }\n\n let expires: number | undefined;\n if (obj.expires !== undefined) {\n if (typeof obj.expires !== \"number\" || !Number.isFinite(obj.expires)) {\n return fail(\"bad-context\");\n }\n if (obj.expires < now) return fail(\"expired\");\n expires = obj.expires;\n }\n\n // Re-stringify with the sanitized fields and check the encoded size.\n const reStringified = JSON.stringify({\n v: 1,\n overrides: safeOverrides,\n ...(context !== undefined ? { context } : {}),\n ...(expires !== undefined ? { expires } : {}),\n });\n if (reStringified.length > MAX_PAYLOAD_BYTES) return fail(\"payload-too-large\");\n\n const payload: SharePayload = {\n v: 1,\n overrides: safeOverrides,\n ...(context !== undefined ? { context } : {}),\n ...(expires !== undefined ? { expires } : {}),\n };\n return { ok: true, payload };\n}\n\nfunction hasPollution(input: unknown): boolean {\n if (input === null || typeof input !== \"object\") return false;\n if (Array.isArray(input)) {\n for (const item of input) if (hasPollution(item)) return true;\n return false;\n }\n for (const key of Object.keys(input as object)) {\n if (POLLUTION_KEYS.has(key)) return true;\n if (hasPollution((input as Record<string, unknown>)[key])) return true;\n }\n return false;\n}\n\nfunction sanitizeContext(input: Record<string, unknown>): SharePayload[\"context\"] | null {\n const out: Record<string, unknown> = Object.create(null) as Record<string, unknown>;\n for (const key of Object.keys(input)) {\n if (POLLUTION_KEYS.has(key)) return null;\n const value = input[key];\n if (value === undefined) continue;\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\") {\n out[key] = value;\n continue;\n }\n if (\n key === \"attributes\" &&\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value)\n ) {\n const attrs: Record<string, unknown> = Object.create(null) as Record<string, unknown>;\n for (const aKey of Object.keys(value as object)) {\n if (POLLUTION_KEYS.has(aKey)) return null;\n const aVal = (value as Record<string, unknown>)[aKey];\n if (typeof aVal === \"string\" || typeof aVal === \"number\" || typeof aVal === \"boolean\") {\n attrs[aKey] = aVal;\n } else {\n return null;\n }\n }\n out[key] = attrs;\n continue;\n }\n return null;\n }\n return out as SharePayload[\"context\"];\n}\n\nfunction fail(reason: ValidationFailure): ValidationResult {\n return { ok: false, reason };\n}\n","/**\n * Encode and decode share payloads for deep links and QR codes.\n *\n * The wire format is documented in `docs/features/qr-sharing.md`:\n *\n * 1. Serialise the payload as compact JSON.\n * 2. Optionally gzip-like compress (deferred — we ship plain base64\n * first; the wire format is forward-compatible because the prefix\n * byte tells the decoder which mode was used).\n * 3. Base64url-encode the bytes (RFC 4648 §5: `+` → `-`, `/` → `_`,\n * no `=` padding).\n *\n * We implement base64url by hand because we cannot rely on\n * `globalThis.btoa` / `Buffer` being present on every RN runtime,\n * and pulling in a base64 polyfill would burst the bundle budget.\n * The encoder/decoder operates on UTF-8 byte arrays via `TextEncoder`\n * / `TextDecoder`, both of which ship in Hermes.\n *\n * The format prefix byte is `0` for \"raw JSON\" and reserved for future\n * compression schemes (`1` = deflate-raw, `2` = brotli, etc.). On\n * decode we tolerate a missing prefix to keep older clients working.\n */\nimport type { SharePayload, ValidationResult } from \"./types.js\";\nimport { validatePayload } from \"./validate.js\";\n\nconst PREFIX_RAW = 0;\n\n/**\n * Encode a payload to its on-the-wire base64url string. Throws on\n * the rare case where validation fails on a payload constructed by\n * the caller themselves — that's a developer error worth surfacing.\n */\nexport function encodeSharePayload(payload: SharePayload): string {\n const validated = validatePayload(payload);\n if (!validated.ok) {\n throw new Error(`Cannot encode invalid share payload: ${validated.reason}`);\n }\n const json = JSON.stringify(validated.payload);\n const utf8 = new TextEncoder().encode(json);\n const framed = new Uint8Array(utf8.length + 1);\n framed[0] = PREFIX_RAW;\n framed.set(utf8, 1);\n return bytesToBase64Url(framed);\n}\n\n/**\n * Decode a base64url string back into a validated payload. Returns\n * a `ValidationResult` so callers can branch on `ok` rather than\n * wrap the call in try/catch.\n */\nexport function decodeSharePayload(encoded: string, now?: number): ValidationResult {\n let bytes: Uint8Array;\n try {\n bytes = base64UrlToBytes(encoded);\n } catch {\n return { ok: false, reason: \"not-an-object\" };\n }\n if (bytes.length === 0) return { ok: false, reason: \"not-an-object\" };\n\n // Detect prefix; tolerate missing prefix for forward compatibility.\n let jsonBytes: Uint8Array;\n if (bytes[0] === PREFIX_RAW) {\n jsonBytes = bytes.subarray(1);\n } else {\n jsonBytes = bytes;\n }\n\n let parsed: unknown;\n try {\n const json = new TextDecoder(\"utf-8\", { fatal: true }).decode(jsonBytes);\n parsed = JSON.parse(json);\n } catch {\n return { ok: false, reason: \"not-an-object\" };\n }\n\n return validatePayload(parsed, now);\n}\n\n// ---------- base64url ------------------------------------------------------\n\nconst ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_\";\n\nconst DECODE_TABLE: Int8Array = (() => {\n const table = new Int8Array(128);\n table.fill(-1);\n for (let i = 0; i < ALPHABET.length; i++) {\n table[ALPHABET.charCodeAt(i)] = i;\n }\n // Accept the standard b64 variants too so links pasted from a\n // non-url-safe encoder still decode.\n table[\"+\".charCodeAt(0)] = 62;\n table[\"/\".charCodeAt(0)] = 63;\n return table;\n})();\n\nexport function bytesToBase64Url(bytes: Uint8Array): string {\n let out = \"\";\n let i = 0;\n for (; i + 3 <= bytes.length; i += 3) {\n const b0 = bytes[i] as number;\n const b1 = bytes[i + 1] as number;\n const b2 = bytes[i + 2] as number;\n out += ALPHABET[b0 >> 2];\n out += ALPHABET[((b0 & 0x03) << 4) | (b1 >> 4)];\n out += ALPHABET[((b1 & 0x0f) << 2) | (b2 >> 6)];\n out += ALPHABET[b2 & 0x3f];\n }\n if (i < bytes.length) {\n const b0 = bytes[i] as number;\n out += ALPHABET[b0 >> 2];\n if (i + 1 < bytes.length) {\n const b1 = bytes[i + 1] as number;\n out += ALPHABET[((b0 & 0x03) << 4) | (b1 >> 4)];\n out += ALPHABET[(b1 & 0x0f) << 2];\n } else {\n out += ALPHABET[(b0 & 0x03) << 4];\n }\n }\n return out;\n}\n\nexport function base64UrlToBytes(input: string): Uint8Array {\n // Strip optional `=` padding from standard base64.\n let s = input;\n while (s.length > 0 && s[s.length - 1] === \"=\") s = s.slice(0, -1);\n if (s.length === 0) return new Uint8Array(0);\n\n const remainder = s.length & 3;\n if (remainder === 1) throw new Error(\"Invalid base64url length\");\n\n const fullGroups = (s.length - remainder) >> 2;\n const outLen = fullGroups * 3 + (remainder === 0 ? 0 : remainder - 1);\n const out = new Uint8Array(outLen);\n\n let outIdx = 0;\n let i = 0;\n for (let g = 0; g < fullGroups; g++, i += 4) {\n const c0 = decodeChar(s.charCodeAt(i));\n const c1 = decodeChar(s.charCodeAt(i + 1));\n const c2 = decodeChar(s.charCodeAt(i + 2));\n const c3 = decodeChar(s.charCodeAt(i + 3));\n out[outIdx++] = (c0 << 2) | (c1 >> 4);\n out[outIdx++] = ((c1 & 0x0f) << 4) | (c2 >> 2);\n out[outIdx++] = ((c2 & 0x03) << 6) | c3;\n }\n if (remainder >= 2) {\n const c0 = decodeChar(s.charCodeAt(i));\n const c1 = decodeChar(s.charCodeAt(i + 1));\n out[outIdx++] = (c0 << 2) | (c1 >> 4);\n if (remainder === 3) {\n const c2 = decodeChar(s.charCodeAt(i + 2));\n out[outIdx++] = ((c1 & 0x0f) << 4) | (c2 >> 2);\n }\n }\n return out;\n}\n\nfunction decodeChar(code: number): number {\n if (code >= 128) throw new Error(\"Invalid base64url character\");\n const v = DECODE_TABLE[code] ?? -1;\n if (v < 0) throw new Error(\"Invalid base64url character\");\n return v;\n}\n","/**\n * `@variantlab/react-native/qr` — QR code sharing helpers.\n *\n * Exposes two tiny helpers: one to turn a variantlab `SharePayload`\n * into an `otpauth://`-style URL that can be rendered as a QR code,\n * and one to consume such a URL when it's scanned back in. The actual\n * QR rendering is **not** included in this package — `react-native-svg`\n * is a huge optional peer, and the Phase 1 kickoff prompt in\n * `docs/phases/phase-1-kickoff-prompts.md` §6.5 says to ship a\n * renderer-agnostic stub:\n *\n * import QRCode from \"react-native-qrcode-svg\";\n * import { buildQrUrl } from \"@variantlab/react-native/qr\";\n *\n * const url = buildQrUrl(engine, { v: 1, overrides: { hero: \"b\" } });\n * <QRCode value={url} size={220} />\n *\n * The URL format is `variantlab://apply?d=<base64url>` where the\n * base64url payload is identical to the deep-link encoder. That means\n * a QR code and a deep link are interchangeable: scanning a QR is\n * literally equivalent to tapping a shared URL.\n *\n * A richer QR feature (signing with HMAC, scan validation, in-overlay\n * scanner) is scheduled for Phase 2. This entrypoint exists today so\n * the wire format is stable and tree-shakeable from day one.\n */\n\nimport { decodeSharePayload, encodeSharePayload } from \"./deep-link/encode.js\";\nimport type { SharePayload, ValidationResult } from \"./deep-link/types.js\";\n\n/** The scheme used for variantlab's own share URLs. */\nexport const VARIANTLAB_URL_SCHEME = \"variantlab\";\n/** The canonical path that applies a share payload. */\nexport const VARIANTLAB_APPLY_PATH = \"apply\";\n\n/**\n * Build a `variantlab://apply?d=...` URL from a share payload.\n *\n * Safe to call with any well-formed payload — invalid payloads throw\n * (see `encodeSharePayload`). Pair the return value with any\n * off-the-shelf `<QRCode />` component.\n */\nexport function buildQrUrl(payload: SharePayload): string {\n const encoded = encodeSharePayload(payload);\n return `${VARIANTLAB_URL_SCHEME}://${VARIANTLAB_APPLY_PATH}?d=${encoded}`;\n}\n\n/**\n * Parse a scanned QR URL and return the validated payload. Mirrors\n * the deep-link handler's tolerance: we accept both\n * `variantlab://apply?d=...` and any other scheme whose query string\n * carries a `d=` parameter, so host apps can reuse their own URL\n * scheme (e.g. `myapp://variantlab?d=...`).\n *\n * Returns a `ValidationResult` rather than throwing, matching\n * `decodeSharePayload`.\n */\nexport function parseQrUrl(url: string, now?: number): ValidationResult {\n const q = extractDataParam(url);\n if (q === null) return { ok: false, reason: \"not-an-object\" };\n return decodeSharePayload(q, now);\n}\n\n/**\n * Extracts the `d` query parameter from a URL string without relying\n * on `URL` (RN's URL polyfill is historically flaky). Returns `null`\n * if the URL has no `d=` param.\n */\nfunction extractDataParam(url: string): string | null {\n const q = url.indexOf(\"?\");\n if (q < 0) return null;\n const hashEnd = url.indexOf(\"#\", q);\n const query = hashEnd < 0 ? url.slice(q + 1) : url.slice(q + 1, hashEnd);\n for (const pair of query.split(\"&\")) {\n const eq = pair.indexOf(\"=\");\n if (eq < 0) continue;\n const key = pair.slice(0, eq);\n if (key !== \"d\") continue;\n try {\n return decodeURIComponent(pair.slice(eq + 1));\n } catch {\n return null;\n }\n }\n return null;\n}\n"]}
@@ -0,0 +1,36 @@
1
+ import { VariantContext } from '@variantlab/core';
2
+
3
+ /**
4
+ * Share-payload types used by `encode.ts`, `validate.ts`, and the deep
5
+ * link handler. Mirrors the on-the-wire format from `qr-sharing.md`.
6
+ *
7
+ * The wire format is intentionally tiny: a JSON document that base64url-
8
+ * encodes (and optionally compresses) into a URL query parameter. We
9
+ * version it via `v` so a future format can be added without breaking
10
+ * existing scanners.
11
+ */
12
+
13
+ /** Supported payload schema versions. Currently only `1`. */
14
+ type ShareVersion = 1;
15
+ /** A decoded share payload. */
16
+ interface SharePayload {
17
+ /** Schema version. */
18
+ readonly v: ShareVersion;
19
+ /** Map of experiment id → variant id to apply. */
20
+ readonly overrides: Readonly<Record<string, string>>;
21
+ /** Optional context overrides applied via `engine.updateContext`. */
22
+ readonly context?: Partial<VariantContext>;
23
+ /** Optional Unix-ms expiry. Payloads past this are rejected. */
24
+ readonly expires?: number;
25
+ }
26
+ /** Lightweight result of validating a candidate payload. */
27
+ type ValidationResult = {
28
+ readonly ok: true;
29
+ readonly payload: SharePayload;
30
+ } | {
31
+ readonly ok: false;
32
+ readonly reason: ValidationFailure;
33
+ };
34
+ type ValidationFailure = "not-an-object" | "bad-version" | "missing-overrides" | "overrides-too-large" | "bad-override-key" | "bad-override-value" | "bad-context" | "expired" | "payload-too-large" | "prototype-pollution";
35
+
36
+ export type { SharePayload as S, ValidationResult as V, ValidationFailure as a, ShareVersion as b };
@@ -0,0 +1,36 @@
1
+ import { VariantContext } from '@variantlab/core';
2
+
3
+ /**
4
+ * Share-payload types used by `encode.ts`, `validate.ts`, and the deep
5
+ * link handler. Mirrors the on-the-wire format from `qr-sharing.md`.
6
+ *
7
+ * The wire format is intentionally tiny: a JSON document that base64url-
8
+ * encodes (and optionally compresses) into a URL query parameter. We
9
+ * version it via `v` so a future format can be added without breaking
10
+ * existing scanners.
11
+ */
12
+
13
+ /** Supported payload schema versions. Currently only `1`. */
14
+ type ShareVersion = 1;
15
+ /** A decoded share payload. */
16
+ interface SharePayload {
17
+ /** Schema version. */
18
+ readonly v: ShareVersion;
19
+ /** Map of experiment id → variant id to apply. */
20
+ readonly overrides: Readonly<Record<string, string>>;
21
+ /** Optional context overrides applied via `engine.updateContext`. */
22
+ readonly context?: Partial<VariantContext>;
23
+ /** Optional Unix-ms expiry. Payloads past this are rejected. */
24
+ readonly expires?: number;
25
+ }
26
+ /** Lightweight result of validating a candidate payload. */
27
+ type ValidationResult = {
28
+ readonly ok: true;
29
+ readonly payload: SharePayload;
30
+ } | {
31
+ readonly ok: false;
32
+ readonly reason: ValidationFailure;
33
+ };
34
+ type ValidationFailure = "not-an-object" | "bad-version" | "missing-overrides" | "overrides-too-large" | "bad-override-key" | "bad-override-value" | "bad-context" | "expired" | "payload-too-large" | "prototype-pollution";
35
+
36
+ export type { SharePayload as S, ValidationResult as V, ValidationFailure as a, ShareVersion as b };
package/package.json ADDED
@@ -0,0 +1,124 @@
1
+ {
2
+ "name": "@variantlab/react-native",
3
+ "version": "0.1.0",
4
+ "description": "React Native and Expo bindings for variantlab.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "main": "./dist/index.cjs",
9
+ "module": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "import": {
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/index.js"
16
+ },
17
+ "require": {
18
+ "types": "./dist/index.d.cts",
19
+ "default": "./dist/index.cjs"
20
+ }
21
+ },
22
+ "./debug": {
23
+ "import": {
24
+ "types": "./dist/debug.d.ts",
25
+ "default": "./dist/debug.js"
26
+ },
27
+ "require": {
28
+ "types": "./dist/debug.d.cts",
29
+ "default": "./dist/debug.cjs"
30
+ }
31
+ },
32
+ "./qr": {
33
+ "import": {
34
+ "types": "./dist/qr.d.ts",
35
+ "default": "./dist/qr.js"
36
+ },
37
+ "require": {
38
+ "types": "./dist/qr.d.cts",
39
+ "default": "./dist/qr.cjs"
40
+ }
41
+ },
42
+ "./package.json": "./package.json"
43
+ },
44
+ "files": [
45
+ "dist",
46
+ "README.md"
47
+ ],
48
+ "publishConfig": {
49
+ "access": "public",
50
+ "provenance": false
51
+ },
52
+ "keywords": [
53
+ "ab-testing",
54
+ "experiments",
55
+ "feature-flags",
56
+ "variants",
57
+ "variantlab",
58
+ "react-native",
59
+ "expo"
60
+ ],
61
+ "repository": {
62
+ "type": "git",
63
+ "url": "git+https://github.com/variantlab/variantlab.git",
64
+ "directory": "packages/react-native"
65
+ },
66
+ "bugs": {
67
+ "url": "https://github.com/variantlab/variantlab/issues"
68
+ },
69
+ "homepage": "https://github.com/variantlab/variantlab#readme",
70
+ "engines": {
71
+ "node": ">=18.17"
72
+ },
73
+ "dependencies": {
74
+ "@variantlab/core": "0.1.0",
75
+ "@variantlab/react": "0.1.0"
76
+ },
77
+ "peerDependencies": {
78
+ "@react-native-async-storage/async-storage": "*",
79
+ "expo-constants": "*",
80
+ "expo-localization": "*",
81
+ "expo-secure-store": "*",
82
+ "react": "^18.2.0 || ^19.0.0",
83
+ "react-native": ">=0.74.0",
84
+ "react-native-mmkv": "*",
85
+ "react-native-safe-area-context": "*",
86
+ "react-native-svg": "*"
87
+ },
88
+ "peerDependenciesMeta": {
89
+ "@react-native-async-storage/async-storage": {
90
+ "optional": true
91
+ },
92
+ "react-native-mmkv": {
93
+ "optional": true
94
+ },
95
+ "expo-secure-store": {
96
+ "optional": true
97
+ },
98
+ "expo-localization": {
99
+ "optional": true
100
+ },
101
+ "expo-constants": {
102
+ "optional": true
103
+ },
104
+ "react-native-safe-area-context": {
105
+ "optional": true
106
+ },
107
+ "react-native-svg": {
108
+ "optional": true
109
+ }
110
+ },
111
+ "devDependencies": {
112
+ "@types/react": "^19.0.0",
113
+ "@types/react-dom": "^19.0.0",
114
+ "react": "^19.0.0",
115
+ "react-dom": "^19.0.0"
116
+ },
117
+ "scripts": {
118
+ "build": "tsup",
119
+ "typecheck": "tsc --noEmit",
120
+ "test": "pnpm --dir ../.. exec vitest run --project react-native",
121
+ "test:coverage": "pnpm --dir ../.. exec vitest run --coverage --project react-native",
122
+ "clean": "rm -rf dist"
123
+ }
124
+ }