tailwind-styled-v4 5.0.9 → 5.0.10
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 +15 -1
- package/dist/{analyzeWorkspace-DuJKh7Ty.d.mts → analyzeWorkspace-BS5O4rhC.d.mts} +47 -2
- package/dist/{analyzeWorkspace-Ct_NTAWt.d.ts → analyzeWorkspace-DDOQdzzI.d.ts} +47 -2
- package/dist/analyzer.d.mts +5 -3
- package/dist/analyzer.d.ts +5 -3
- package/dist/analyzer.js +563 -468
- package/dist/analyzer.js.map +1 -1
- package/dist/analyzer.mjs +562 -467
- package/dist/analyzer.mjs.map +1 -1
- package/dist/animate.d.mts +4 -7
- package/dist/animate.d.ts +4 -7
- package/dist/animate.js +171 -265
- package/dist/animate.js.map +1 -1
- package/dist/animate.mjs +165 -264
- package/dist/animate.mjs.map +1 -1
- package/dist/atomic.d.mts +22 -1
- package/dist/atomic.d.ts +22 -1
- package/dist/atomic.js +221 -165
- package/dist/atomic.js.map +1 -1
- package/dist/atomic.mjs +200 -165
- package/dist/atomic.mjs.map +1 -1
- package/dist/cli.d.mts +60 -1
- package/dist/cli.d.ts +60 -1
- package/dist/cli.js +1261 -1517
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +1238 -1513
- package/dist/cli.mjs.map +1 -1
- package/dist/compiler.d.mts +38 -7
- package/dist/compiler.d.ts +38 -7
- package/dist/compiler.js +174 -197
- package/dist/compiler.js.map +1 -1
- package/dist/compiler.mjs +151 -194
- package/dist/compiler.mjs.map +1 -1
- package/dist/devtools.js +7 -31
- package/dist/devtools.js.map +1 -1
- package/dist/devtools.mjs +7 -31
- package/dist/devtools.mjs.map +1 -1
- package/dist/engine.d.mts +134 -63
- package/dist/engine.d.ts +134 -63
- package/dist/engine.js +2863 -2482
- package/dist/engine.js.map +1 -1
- package/dist/engine.mjs +2852 -2485
- package/dist/engine.mjs.map +1 -1
- package/dist/{index-eWAocnD2.d.mts → index-NDINUhLN.d.mts} +3 -1
- package/dist/{index-eWAocnD2.d.ts → index-NDINUhLN.d.ts} +3 -1
- package/dist/index.d.mts +45 -32
- package/dist/index.d.ts +45 -32
- package/dist/index.js +271 -158
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +251 -158
- package/dist/index.mjs.map +1 -1
- package/dist/{liveTokenEngine-DSUk88P6.d.ts → liveTokenEngine-CN9ian1R.d.ts} +1 -1
- package/dist/{liveTokenEngine-CX5_0c4q.d.mts → liveTokenEngine-DKoWRtqH.d.mts} +1 -1
- package/dist/next.js +20 -39
- package/dist/next.js.map +1 -1
- package/dist/next.mjs +18 -37
- package/dist/next.mjs.map +1 -1
- package/dist/plugin-api.d.mts +8 -2
- package/dist/plugin-api.d.ts +8 -2
- package/dist/plugin-api.js +14 -2
- package/dist/plugin-api.js.map +1 -1
- package/dist/plugin-api.mjs +14 -3
- package/dist/plugin-api.mjs.map +1 -1
- package/dist/plugin-registry.js +51 -11
- package/dist/plugin-registry.js.map +1 -1
- package/dist/plugin-registry.mjs +51 -11
- package/dist/plugin-registry.mjs.map +1 -1
- package/dist/plugin.d.mts +5 -7
- package/dist/plugin.d.ts +5 -7
- package/dist/plugin.js +16 -15
- package/dist/plugin.js.map +1 -1
- package/dist/plugin.mjs +16 -16
- package/dist/plugin.mjs.map +1 -1
- package/dist/rspack.js +17 -38
- package/dist/rspack.js.map +1 -1
- package/dist/rspack.mjs +15 -36
- package/dist/rspack.mjs.map +1 -1
- package/dist/runtime.d.mts +2 -2
- package/dist/runtime.d.ts +2 -2
- package/dist/scanner.d.mts +10 -1
- package/dist/scanner.d.ts +10 -1
- package/dist/scanner.js +298 -124
- package/dist/scanner.js.map +1 -1
- package/dist/scanner.mjs +296 -124
- package/dist/scanner.mjs.map +1 -1
- package/dist/shared.d.mts +1 -1
- package/dist/shared.d.ts +1 -1
- package/dist/shared.js +104 -176
- package/dist/shared.js.map +1 -1
- package/dist/shared.mjs +85 -176
- package/dist/shared.mjs.map +1 -1
- package/dist/storybook-addon.d.mts +1 -1
- package/dist/storybook-addon.d.ts +1 -1
- package/dist/svelte.d.mts +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/svelte.js +166 -3
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +143 -1
- package/dist/svelte.mjs.map +1 -1
- package/dist/syntax.js +21 -21
- package/dist/syntax.js.map +1 -1
- package/dist/syntax.mjs +21 -21
- package/dist/syntax.mjs.map +1 -1
- package/dist/testing.js +9 -1
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +9 -1
- package/dist/testing.mjs.map +1 -1
- package/dist/theme.d.mts +2 -2
- package/dist/theme.d.ts +2 -2
- package/dist/theme.js +40 -112
- package/dist/theme.js.map +1 -1
- package/dist/theme.mjs +37 -110
- package/dist/theme.mjs.map +1 -1
- package/dist/turbopackLoader.js +79 -124
- package/dist/turbopackLoader.js.map +1 -1
- package/dist/turbopackLoader.mjs +63 -122
- package/dist/turbopackLoader.mjs.map +1 -1
- package/dist/tw.js +1256 -1517
- package/dist/tw.js.map +1 -1
- package/dist/tw.mjs +1236 -1513
- package/dist/tw.mjs.map +1 -1
- package/dist/vite.js +1783 -823
- package/dist/vite.js.map +1 -1
- package/dist/vite.mjs +1767 -821
- package/dist/vite.mjs.map +1 -1
- package/dist/vue.d.mts +1 -1
- package/dist/vue.d.ts +1 -1
- package/dist/vue.js +165 -4
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +141 -1
- package/dist/vue.mjs.map +1 -1
- package/dist/webpackLoader.js +65 -108
- package/dist/webpackLoader.js.map +1 -1
- package/dist/webpackLoader.mjs +45 -104
- package/dist/webpackLoader.mjs.map +1 -1
- package/native/tailwind-styled-native.node +0 -0
- package/package.json +22 -24
package/dist/testing.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../packages/domain/testing/src/index.ts"],"names":[],"mappings":"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","file":"testing.mjs","sourcesContent":["/**\r\n * tailwind-styled-v4 — Testing Utilities\r\n *\r\n * Integrasi dengan Jest / Vitest untuk test komponen tw().\r\n *\r\n * @example\r\n * // vitest.config.ts\r\n * import { tailwindStyledSetup } from '@tailwind-styled/testing'\r\n * export default defineConfig({ test: { setupFiles: ['@tailwind-styled/testing/setup'] } })\r\n *\r\n * // Button.test.ts\r\n * import { render } from '@testing-library/react'\r\n * import { expectClasses, getVariantClass } from '@tailwind-styled/testing'\r\n *\r\n * test('Button renders primary variant', () => {\r\n * const { container } = render(<Button intent=\"primary\" />)\r\n * expectClasses(container.firstChild, ['bg-blue-500', 'text-white'])\r\n * })\r\n */\r\n\r\n// ─── Jest/Vitest custom matchers ─────────────────────────────────────────────\r\n\r\n/**\r\n * Custom matcher: toHaveClass\r\n * Dipakai langsung atau via expect.extend(tailwindMatchers)\r\n *\r\n * @example\r\n * expect(element).toHaveClass('bg-blue-500')\r\n */\r\nexport function toHaveClass(className: string) {\r\n return (value: { classList?: { contains: (name: string) => boolean } }) => {\r\n const pass = Boolean(value?.classList?.contains(className))\r\n return {\r\n pass,\r\n message: () => `expected element ${pass ? \"not \" : \"\"}to contain class '${className}'`,\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Custom matcher: toHaveClasses\r\n * Cek beberapa class sekaligus\r\n *\r\n * @example\r\n * expect(element).toHaveClasses(['px-4', 'py-2', 'rounded'])\r\n */\r\nexport function toHaveClasses(classNames: string[]) {\r\n return (value: Element | null | undefined) => {\r\n if (!value) return { pass: false, message: () => \"element is null or undefined\" }\r\n const missing = classNames.filter((c) => !value.classList.contains(c))\r\n const pass = missing.length === 0\r\n return {\r\n pass,\r\n message: () =>\r\n pass\r\n ? `expected element not to have all classes: ${classNames.join(\", \")}`\r\n : `expected element to have classes: ${missing.join(\", \")}`,\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Custom matcher: toNotHaveClass\r\n *\r\n * @example\r\n * expect(element).toNotHaveClass('hidden')\r\n */\r\nexport function toNotHaveClass(className: string) {\r\n return (value: Element | null | undefined) => {\r\n if (!value) return { pass: false, message: () => \"element is null or undefined\" }\r\n const pass = !value.classList.contains(className)\r\n return {\r\n pass,\r\n message: () => `expected element ${pass ? \"\" : \"not \"}to have class '${className}'`,\r\n }\r\n }\r\n}\r\n\r\n/** Semua matchers — pakai dengan expect.extend(tailwindMatchers) */\r\nexport const tailwindMatchers = { toHaveClass, toHaveClasses, toNotHaveClass }\r\n\r\n// ─── Helper utilities ────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Assert element punya semua class yang diharapkan.\r\n * Lebih ergonomis dari `expect(el).toHaveClasses([...])` untuk banyak class.\r\n *\r\n * @example\r\n * const { container } = render(<Button intent=\"primary\" size=\"lg\" />)\r\n * expectClasses(container.firstChild, ['bg-blue-500', 'text-white', 'h-12'])\r\n */\r\nexport function expectClasses(element: Element | null | undefined, classes: string[]): void {\r\n if (!element) throw new Error(\"expectClasses: element is null or undefined\")\r\n const missing = classes.filter((c) => !element.classList.contains(c))\r\n if (missing.length > 0) {\r\n throw new Error(\r\n `Expected element to have classes: ${missing.join(\", \")}\\n` +\r\n ` Actual classes: ${element.className}`\r\n )\r\n }\r\n}\r\n\r\n/**\r\n * Assert element tidak punya class tertentu.\r\n *\r\n * @example\r\n * expectNoClasses(container.firstChild, ['opacity-50', 'cursor-not-allowed'])\r\n */\r\nexport function expectNoClasses(element: Element | null | undefined, classes: string[]): void {\r\n if (!element) throw new Error(\"expectNoClasses: element is null or undefined\")\r\n const found = classes.filter((c) => element.classList.contains(c))\r\n if (found.length > 0) {\r\n throw new Error(\r\n `Expected element NOT to have classes: ${found.join(\", \")}\\n` +\r\n ` Actual classes: ${element.className}`\r\n )\r\n }\r\n}\r\n\r\n/**\r\n * Extract class list dari element sebagai sorted array.\r\n * Berguna untuk snapshot testing.\r\n *\r\n * @example\r\n * expect(getClassList(element)).toMatchSnapshot()\r\n */\r\nexport function getClassList(element: Element | null | undefined): string[] {\r\n if (!element) return []\r\n return Array.from(element.classList).sort()\r\n}\r\n\r\n// ─── Variant snapshot helpers ────────────────────────────────────────────────\r\n\r\n/**\r\n * Buat snapshot dari semua kombinasi variant.\r\n * Berguna untuk regression testing pada styled components.\r\n *\r\n * @example\r\n * const buttonVariants = snapshotVariants(\r\n * (props) => {\r\n * const { container } = render(<Button {...props} />)\r\n * return container.firstChild?.className ?? ''\r\n * },\r\n * [\r\n * { intent: 'primary', size: 'sm' },\r\n * { intent: 'primary', size: 'lg' },\r\n * { intent: 'danger', size: 'sm' },\r\n * ]\r\n * )\r\n * expect(buttonVariants).toMatchSnapshot()\r\n */\r\nexport function snapshotVariants<T>(render: (variant: T) => string, variants: T[]) {\r\n return variants.map((variant) => ({\r\n variant,\r\n output: render(variant),\r\n }))\r\n}\r\n\r\n/**\r\n * Generate semua kombinasi dari variant matrix.\r\n *\r\n * @example\r\n * const combinations = expandVariantMatrix({\r\n * intent: ['primary', 'danger'],\r\n * size: ['sm', 'md', 'lg'],\r\n * disabled: [true, false],\r\n * })\r\n * // → 2 × 3 × 2 = 12 kombinasi\r\n */\r\nexport function expandVariantMatrix(\r\n matrix: Record<string, Array<string | number | boolean>>\r\n): Array<Record<string, string | number | boolean>> {\r\n const keys = Object.keys(matrix)\r\n if (keys.length === 0) return [{}]\r\n\r\n const result: Array<Record<string, string | number | boolean>> = []\r\n\r\n function walk(index: number, current: Record<string, string | number | boolean>) {\r\n if (index >= keys.length) {\r\n result.push({ ...current })\r\n return\r\n }\r\n const key = keys[index]!\r\n for (const value of matrix[key] ?? []) {\r\n current[key] = value\r\n walk(index + 1, current)\r\n }\r\n }\r\n\r\n walk(0, {})\r\n return result\r\n}\r\n\r\n/**\r\n * Test semua kombinasi variant sekaligus — no missing coverage.\r\n *\r\n * @example\r\n * testAllVariants(\r\n * Button,\r\n * { intent: ['primary','danger'], size: ['sm','lg'] },\r\n * (el, variant) => {\r\n * expect(el).not.toBeNull()\r\n * if (variant.intent === 'primary') expectClasses(el, ['bg-blue-500'])\r\n * }\r\n * )\r\n */\r\nexport function testAllVariants(\r\n matrix: Record<string, Array<string | number | boolean>>,\r\n testFn: (variant: Record<string, string | number | boolean>) => void\r\n): void {\r\n const combinations = expandVariantMatrix(matrix)\r\n for (const variant of combinations) {\r\n testFn(variant)\r\n }\r\n}\r\n\r\n// ─── CSS-in-JS output assertions ─────────────────────────────────────────────\r\n\r\n/**\r\n * Bandingkan dua class string secara semantik (urutan tidak penting).\r\n *\r\n * @example\r\n * expectClassesEqual('px-4 py-2 bg-blue-500', 'bg-blue-500 px-4 py-2') // pass\r\n */\r\nexport function expectClassesEqual(actual: string, expected: string): void {\r\n const actualSet = new Set(actual.trim().split(/\\s+/).filter(Boolean))\r\n const expectedSet = new Set(expected.trim().split(/\\s+/).filter(Boolean))\r\n\r\n const missing = [...expectedSet].filter((c) => !actualSet.has(c))\r\n const extra = [...actualSet].filter((c) => !expectedSet.has(c))\r\n\r\n if (missing.length > 0 || extra.length > 0) {\r\n const parts: string[] = []\r\n if (missing.length > 0) parts.push(`Missing: ${missing.join(\", \")}`)\r\n if (extra.length > 0) parts.push(`Extra: ${extra.join(\", \")}`)\r\n throw new Error(`Class mismatch:\\n ${parts.join(\"\\n \")}`)\r\n }\r\n}\r\n\r\n// ─── Engine metrics matchers ──────────────────────────────────────────────────\r\n\r\nexport interface EngineMetricsSnapshot {\r\n totalFiles?: number\r\n uniqueClasses?: number\r\n buildTimeMs?: number\r\n cssBytes?: number\r\n cacheHits?: number\r\n cacheMisses?: number\r\n incrementalRuns?: number\r\n fullRescans?: number\r\n}\r\n\r\n/**\r\n * Assert engine metrics snapshot meets minimum thresholds.\r\n *\r\n * @example\r\n * const result = await engine.build()\r\n * expectEngineMetrics(metrics.snapshot(), {\r\n * totalFiles: 10,\r\n * buildTimeMs: 5000, // max\r\n * })\r\n */\r\nexport function expectEngineMetrics(\r\n metrics: EngineMetricsSnapshot,\r\n expectations: {\r\n minFiles?: number\r\n maxBuildTimeMs?: number\r\n minUniqueClasses?: number\r\n cacheHitRateMin?: number // 0–1\r\n }\r\n): void {\r\n if (expectations.minFiles !== undefined) {\r\n const actual = metrics.totalFiles ?? 0\r\n if (actual < expectations.minFiles) {\r\n throw new Error(\r\n `Engine metrics: expected at least ${expectations.minFiles} files, got ${actual}`\r\n )\r\n }\r\n }\r\n\r\n if (expectations.maxBuildTimeMs !== undefined) {\r\n const actual = metrics.buildTimeMs ?? 0\r\n if (actual > expectations.maxBuildTimeMs) {\r\n throw new Error(\r\n `Engine metrics: build took ${actual}ms, expected ≤ ${expectations.maxBuildTimeMs}ms`\r\n )\r\n }\r\n }\r\n\r\n if (expectations.minUniqueClasses !== undefined) {\r\n const actual = metrics.uniqueClasses ?? 0\r\n if (actual < expectations.minUniqueClasses) {\r\n throw new Error(\r\n `Engine metrics: expected at least ${expectations.minUniqueClasses} unique classes, got ${actual}`\r\n )\r\n }\r\n }\r\n\r\n if (expectations.cacheHitRateMin !== undefined) {\r\n const hits = metrics.cacheHits ?? 0\r\n const total = hits + (metrics.cacheMisses ?? 0)\r\n const rate = total > 0 ? hits / total : 0\r\n if (rate < expectations.cacheHitRateMin) {\r\n throw new Error(\r\n `Engine metrics: cache hit rate ${(rate * 100).toFixed(1)}%, expected ≥ ${(expectations.cacheHitRateMin * 100).toFixed(1)}%`\r\n )\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Custom Jest/Vitest matcher: toHaveEngineMetrics\r\n *\r\n * @example\r\n * expect(metrics).toHaveEngineMetrics({ minFiles: 1 })\r\n */\r\nexport function toHaveEngineMetrics(expectations: Parameters<typeof expectEngineMetrics>[1]) {\r\n return (metrics: EngineMetricsSnapshot) => {\r\n try {\r\n expectEngineMetrics(metrics, expectations)\r\n return { pass: true, message: () => \"engine metrics matched expectations\" }\r\n } catch (e: unknown) {\r\n const msg = e instanceof Error ? e.message : String(e)\r\n return { pass: false, message: () => msg }\r\n }\r\n }\r\n}\r\n\r\n/** All matchers including engine metrics */\r\nexport const tailwindMatchersWithMetrics = {\r\n toHaveClass,\r\n toHaveClasses,\r\n toNotHaveClass,\r\n toHaveEngineMetrics,\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../packages/domain/testing/src/index.ts"],"names":[],"mappings":"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","file":"testing.mjs","sourcesContent":["/**\r\n * tailwind-styled-v4 — Testing Utilities\r\n *\r\n * Integrasi dengan Jest / Vitest untuk test komponen tw().\r\n *\r\n * @example\r\n * // vitest.config.ts\r\n * import { tailwindStyledSetup } from '@tailwind-styled/testing'\r\n * export default defineConfig({ test: { setupFiles: ['@tailwind-styled/testing/setup'] } })\r\n *\r\n * // Button.test.ts\r\n * import { render } from '@testing-library/react'\r\n * import { expectClasses, getVariantClass } from '@tailwind-styled/testing'\r\n *\r\n * test('Button renders primary variant', () => {\r\n * const { container } = render(<Button intent=\"primary\" />)\r\n * expectClasses(container.firstChild, ['bg-blue-500', 'text-white'])\r\n * })\r\n */\r\n\r\n// ─── Jest/Vitest custom matchers ─────────────────────────────────────────────\r\n\r\n/**\r\n * Custom matcher: toHaveClass\r\n * Dipakai langsung atau via expect.extend(tailwindMatchers)\r\n *\r\n * @example\r\n * expect(element).toHaveClass('bg-blue-500')\r\n */\r\nexport function toHaveClass(className: string) {\r\n return (value: { classList?: { contains: (name: string) => boolean } }) => {\r\n const pass = Boolean(value?.classList?.contains(className))\r\n return {\r\n pass,\r\n message: () => `expected element ${pass ? \"not \" : \"\"}to contain class '${className}'`,\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Custom matcher: toHaveClasses\r\n * Cek beberapa class sekaligus\r\n *\r\n * @example\r\n * expect(element).toHaveClasses(['px-4', 'py-2', 'rounded'])\r\n */\r\nexport function toHaveClasses(classNames: string[]) {\r\n return (value: Element | null | undefined) => {\r\n if (!value) return { pass: false, message: () => \"element is null or undefined\" }\r\n const missing = classNames.filter((c) => !value.classList.contains(c))\r\n const pass = missing.length === 0\r\n return {\r\n pass,\r\n message: () =>\r\n pass\r\n ? `expected element not to have all classes: ${classNames.join(\", \")}`\r\n : `expected element to have classes: ${missing.join(\", \")}`,\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Custom matcher: toNotHaveClass\r\n *\r\n * @example\r\n * expect(element).toNotHaveClass('hidden')\r\n */\r\nexport function toNotHaveClass(className: string) {\r\n return (value: Element | null | undefined) => {\r\n if (!value) return { pass: false, message: () => \"element is null or undefined\" }\r\n const pass = !value.classList.contains(className)\r\n return {\r\n pass,\r\n message: () => `expected element ${pass ? \"\" : \"not \"}to have class '${className}'`,\r\n }\r\n }\r\n}\r\n\r\n/** Semua matchers — pakai dengan expect.extend(tailwindMatchers) */\r\nexport const tailwindMatchers = { toHaveClass, toHaveClasses, toNotHaveClass }\r\n\r\n// ─── Helper utilities ────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Assert element punya semua class yang diharapkan.\r\n * Lebih ergonomis dari `expect(el).toHaveClasses([...])` untuk banyak class.\r\n *\r\n * @example\r\n * const { container } = render(<Button intent=\"primary\" size=\"lg\" />)\r\n * expectClasses(container.firstChild, ['bg-blue-500', 'text-white', 'h-12'])\r\n */\r\nexport function expectClasses(element: Element | null | undefined, classes: string[]): void {\r\n if (!element) throw new Error(\"expectClasses: element is null or undefined\")\r\n const missing = classes.filter((c) => !element.classList.contains(c))\r\n if (missing.length > 0) {\r\n throw new Error(\r\n `Expected element to have classes: ${missing.join(\", \")}\\n` +\r\n ` Actual classes: ${element.className}`\r\n )\r\n }\r\n}\r\n\r\n/**\r\n * Assert element tidak punya class tertentu.\r\n *\r\n * @example\r\n * expectNoClasses(container.firstChild, ['opacity-50', 'cursor-not-allowed'])\r\n */\r\nexport function expectNoClasses(element: Element | null | undefined, classes: string[]): void {\r\n if (!element) throw new Error(\"expectNoClasses: element is null or undefined\")\r\n const found = classes.filter((c) => element.classList.contains(c))\r\n if (found.length > 0) {\r\n throw new Error(\r\n `Expected element NOT to have classes: ${found.join(\", \")}\\n` +\r\n ` Actual classes: ${element.className}`\r\n )\r\n }\r\n}\r\n\r\n/**\r\n * Extract class list dari element sebagai sorted array.\r\n * Berguna untuk snapshot testing.\r\n *\r\n * @example\r\n * expect(getClassList(element)).toMatchSnapshot()\r\n */\r\nexport function getClassList(element: Element | null | undefined): string[] {\r\n if (!element) return []\r\n // classList mungkin tidak iterable di test environment (mock object)\r\n // Fallback ke parsing className string jika Array.from gagal atau hasilkan []\r\n try {\r\n const list = Array.from(element.classList)\r\n if (list.length > 0) return list.sort()\r\n } catch {}\r\n // Fallback: parse dari className string\r\n if (element.className && typeof element.className === \"string\") {\r\n return element.className.trim().split(/\\s+/).filter(Boolean).sort()\r\n }\r\n return []\r\n}\r\n\r\n// ─── Variant snapshot helpers ────────────────────────────────────────────────\r\n\r\n/**\r\n * Buat snapshot dari semua kombinasi variant.\r\n * Berguna untuk regression testing pada styled components.\r\n *\r\n * @example\r\n * const buttonVariants = snapshotVariants(\r\n * (props) => {\r\n * const { container } = render(<Button {...props} />)\r\n * return container.firstChild?.className ?? ''\r\n * },\r\n * [\r\n * { intent: 'primary', size: 'sm' },\r\n * { intent: 'primary', size: 'lg' },\r\n * { intent: 'danger', size: 'sm' },\r\n * ]\r\n * )\r\n * expect(buttonVariants).toMatchSnapshot()\r\n */\r\nexport function snapshotVariants<T>(render: (variant: T) => string, variants: T[]) {\r\n return variants.map((variant) => ({\r\n variant,\r\n output: render(variant),\r\n }))\r\n}\r\n\r\n/**\r\n * Generate semua kombinasi dari variant matrix.\r\n *\r\n * @example\r\n * const combinations = expandVariantMatrix({\r\n * intent: ['primary', 'danger'],\r\n * size: ['sm', 'md', 'lg'],\r\n * disabled: [true, false],\r\n * })\r\n * // → 2 × 3 × 2 = 12 kombinasi\r\n */\r\nexport function expandVariantMatrix(\r\n matrix: Record<string, Array<string | number | boolean>>\r\n): Array<Record<string, string | number | boolean>> {\r\n const keys = Object.keys(matrix)\r\n if (keys.length === 0) return [{}]\r\n\r\n const result: Array<Record<string, string | number | boolean>> = []\r\n\r\n function walk(index: number, current: Record<string, string | number | boolean>) {\r\n if (index >= keys.length) {\r\n result.push({ ...current })\r\n return\r\n }\r\n const key = keys[index]!\r\n for (const value of matrix[key] ?? []) {\r\n current[key] = value\r\n walk(index + 1, current)\r\n }\r\n }\r\n\r\n walk(0, {})\r\n return result\r\n}\r\n\r\n/**\r\n * Test semua kombinasi variant sekaligus — no missing coverage.\r\n *\r\n * @example\r\n * testAllVariants(\r\n * Button,\r\n * { intent: ['primary','danger'], size: ['sm','lg'] },\r\n * (el, variant) => {\r\n * expect(el).not.toBeNull()\r\n * if (variant.intent === 'primary') expectClasses(el, ['bg-blue-500'])\r\n * }\r\n * )\r\n */\r\nexport function testAllVariants(\r\n matrix: Record<string, Array<string | number | boolean>>,\r\n testFn: (variant: Record<string, string | number | boolean>) => void\r\n): void {\r\n const combinations = expandVariantMatrix(matrix)\r\n for (const variant of combinations) {\r\n testFn(variant)\r\n }\r\n}\r\n\r\n// ─── CSS-in-JS output assertions ─────────────────────────────────────────────\r\n\r\n/**\r\n * Bandingkan dua class string secara semantik (urutan tidak penting).\r\n *\r\n * @example\r\n * expectClassesEqual('px-4 py-2 bg-blue-500', 'bg-blue-500 px-4 py-2') // pass\r\n */\r\nexport function expectClassesEqual(actual: string, expected: string): void {\r\n const actualSet = new Set(actual.trim().split(/\\s+/).filter(Boolean))\r\n const expectedSet = new Set(expected.trim().split(/\\s+/).filter(Boolean))\r\n\r\n const missing = [...expectedSet].filter((c) => !actualSet.has(c))\r\n const extra = [...actualSet].filter((c) => !expectedSet.has(c))\r\n\r\n if (missing.length > 0 || extra.length > 0) {\r\n const parts: string[] = []\r\n if (missing.length > 0) parts.push(`Missing: ${missing.join(\", \")}`)\r\n if (extra.length > 0) parts.push(`Extra: ${extra.join(\", \")}`)\r\n throw new Error(`Class mismatch:\\n ${parts.join(\"\\n \")}`)\r\n }\r\n}\r\n\r\n// ─── Engine metrics matchers ──────────────────────────────────────────────────\r\n\r\nexport interface EngineMetricsSnapshot {\r\n totalFiles?: number\r\n uniqueClasses?: number\r\n buildTimeMs?: number\r\n cssBytes?: number\r\n cacheHits?: number\r\n cacheMisses?: number\r\n incrementalRuns?: number\r\n fullRescans?: number\r\n}\r\n\r\n/**\r\n * Assert engine metrics snapshot meets minimum thresholds.\r\n *\r\n * @example\r\n * const result = await engine.build()\r\n * expectEngineMetrics(metrics.snapshot(), {\r\n * totalFiles: 10,\r\n * buildTimeMs: 5000, // max\r\n * })\r\n */\r\nexport function expectEngineMetrics(\r\n metrics: EngineMetricsSnapshot,\r\n expectations: {\r\n minFiles?: number\r\n maxBuildTimeMs?: number\r\n minUniqueClasses?: number\r\n cacheHitRateMin?: number // 0–1\r\n }\r\n): void {\r\n if (expectations.minFiles !== undefined) {\r\n const actual = metrics.totalFiles ?? 0\r\n if (actual < expectations.minFiles) {\r\n throw new Error(\r\n `Engine metrics: expected at least ${expectations.minFiles} files, got ${actual}`\r\n )\r\n }\r\n }\r\n\r\n if (expectations.maxBuildTimeMs !== undefined) {\r\n const actual = metrics.buildTimeMs ?? 0\r\n if (actual > expectations.maxBuildTimeMs) {\r\n throw new Error(\r\n `Engine metrics: build took ${actual}ms, expected ≤ ${expectations.maxBuildTimeMs}ms`\r\n )\r\n }\r\n }\r\n\r\n if (expectations.minUniqueClasses !== undefined) {\r\n const actual = metrics.uniqueClasses ?? 0\r\n if (actual < expectations.minUniqueClasses) {\r\n throw new Error(\r\n `Engine metrics: expected at least ${expectations.minUniqueClasses} unique classes, got ${actual}`\r\n )\r\n }\r\n }\r\n\r\n if (expectations.cacheHitRateMin !== undefined) {\r\n const hits = metrics.cacheHits ?? 0\r\n const total = hits + (metrics.cacheMisses ?? 0)\r\n const rate = total > 0 ? hits / total : 0\r\n if (rate < expectations.cacheHitRateMin) {\r\n throw new Error(\r\n `Engine metrics: cache hit rate ${(rate * 100).toFixed(1)}%, expected ≥ ${(expectations.cacheHitRateMin * 100).toFixed(1)}%`\r\n )\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Custom Jest/Vitest matcher: toHaveEngineMetrics\r\n *\r\n * @example\r\n * expect(metrics).toHaveEngineMetrics({ minFiles: 1 })\r\n */\r\nexport function toHaveEngineMetrics(expectations: Parameters<typeof expectEngineMetrics>[1]) {\r\n return (metrics: EngineMetricsSnapshot) => {\r\n try {\r\n expectEngineMetrics(metrics, expectations)\r\n return { pass: true, message: () => \"engine metrics matched expectations\" }\r\n } catch (e: unknown) {\r\n const msg = e instanceof Error ? e.message : String(e)\r\n return { pass: false, message: () => msg }\r\n }\r\n }\r\n}\r\n\r\n/** All matchers including engine metrics */\r\nexport const tailwindMatchersWithMetrics = {\r\n toHaveClass,\r\n toHaveClasses,\r\n toNotHaveClass,\r\n toHaveEngineMetrics,\r\n}"]}
|
package/dist/theme.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { L as LiveTokenEngineBridge, a as LiveTokenSet, T as TokenSubscriber, b as applyTokenSet, c as createUseTokens, g as generateTokenCssString, d as getToken, e as getTokens, l as liveToken, f as liveTokenEngine, s as setToken, h as setTokens, i as subscribeTokens, t as tokenRef, j as tokenVar } from './liveTokenEngine-
|
|
1
|
+
export { L as LiveTokenEngineBridge, a as LiveTokenSet, T as TokenSubscriber, b as applyTokenSet, c as createUseTokens, g as generateTokenCssString, d as getToken, e as getTokens, l as liveToken, f as liveTokenEngine, s as setToken, h as setTokens, i as subscribeTokens, t as tokenRef, j as tokenVar } from './liveTokenEngine-DKoWRtqH.mjs';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
export { T as TokenMap } from './index-
|
|
3
|
+
export { T as TokenMap } from './index-NDINUhLN.mjs';
|
|
4
4
|
|
|
5
5
|
declare const TokenConfigSchema: z.ZodObject<{
|
|
6
6
|
name: z.ZodString;
|
package/dist/theme.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { L as LiveTokenEngineBridge, a as LiveTokenSet, T as TokenSubscriber, b as applyTokenSet, c as createUseTokens, g as generateTokenCssString, d as getToken, e as getTokens, l as liveToken, f as liveTokenEngine, s as setToken, h as setTokens, i as subscribeTokens, t as tokenRef, j as tokenVar } from './liveTokenEngine-
|
|
1
|
+
export { L as LiveTokenEngineBridge, a as LiveTokenSet, T as TokenSubscriber, b as applyTokenSet, c as createUseTokens, g as generateTokenCssString, d as getToken, e as getTokens, l as liveToken, f as liveTokenEngine, s as setToken, h as setTokens, i as subscribeTokens, t as tokenRef, j as tokenVar } from './liveTokenEngine-CN9ian1R.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
export { T as TokenMap } from './index-
|
|
3
|
+
export { T as TokenMap } from './index-NDINUhLN.js';
|
|
4
4
|
|
|
5
5
|
declare const TokenConfigSchema: z.ZodObject<{
|
|
6
6
|
name: z.ZodString;
|
package/dist/theme.js
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
var React = require('react');
|
|
4
4
|
var path = require('path');
|
|
5
5
|
var url = require('url');
|
|
6
|
+
require('crypto');
|
|
7
|
+
var fs = require('fs');
|
|
8
|
+
var module$1 = require('module');
|
|
6
9
|
var zod = require('zod');
|
|
7
10
|
|
|
8
11
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
@@ -10,14 +13,10 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
10
13
|
|
|
11
14
|
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
12
15
|
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
16
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
13
17
|
|
|
14
18
|
/* tailwind-styled-v4 v5.0.4 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
|
|
15
|
-
|
|
16
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
17
|
-
}) : x)(function(x) {
|
|
18
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
19
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
20
|
-
});
|
|
19
|
+
|
|
21
20
|
var TOKEN_ENGINE_KEY = "__TW_TOKEN_ENGINE__";
|
|
22
21
|
function tokenVar(name) {
|
|
23
22
|
const normalized = name.replace(/[^a-zA-Z0-9-]/g, "-").toLowerCase();
|
|
@@ -185,38 +184,6 @@ globalTokenEngine[TOKEN_ENGINE_KEY] = liveTokenEngine;
|
|
|
185
184
|
if (typeof window !== "undefined") {
|
|
186
185
|
window.__TW_TOKEN_ENGINE__ = liveTokenEngine;
|
|
187
186
|
}
|
|
188
|
-
|
|
189
|
-
// packages/domain/shared/src/index.ts
|
|
190
|
-
var isBrowser = typeof window !== "undefined" || typeof document !== "undefined";
|
|
191
|
-
var nodeModuleRef = null;
|
|
192
|
-
function getNodeModuleRef() {
|
|
193
|
-
if (isBrowser) return null;
|
|
194
|
-
if (nodeModuleRef !== null) return nodeModuleRef;
|
|
195
|
-
try {
|
|
196
|
-
const test = typeof __require === "function" ? __require("module") : null;
|
|
197
|
-
nodeModuleRef = test;
|
|
198
|
-
return test;
|
|
199
|
-
} catch {
|
|
200
|
-
nodeModuleRef = null;
|
|
201
|
-
return null;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
var _nodeFs = null;
|
|
205
|
-
var _nodePath = null;
|
|
206
|
-
function getNodeFs() {
|
|
207
|
-
if (isBrowser) throw new Error("node:fs not available in browser");
|
|
208
|
-
const nodeRequire = getNodeModuleRef();
|
|
209
|
-
if (!nodeRequire) throw new Error("require not available");
|
|
210
|
-
if (!_nodeFs) _nodeFs = nodeRequire.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('theme.js', document.baseURI).href)))("node:fs");
|
|
211
|
-
return _nodeFs;
|
|
212
|
-
}
|
|
213
|
-
function getNodePath() {
|
|
214
|
-
if (isBrowser) throw new Error("node:path not available in browser");
|
|
215
|
-
const nodeRequire = getNodeModuleRef();
|
|
216
|
-
if (!nodeRequire) throw new Error("require not available");
|
|
217
|
-
if (!_nodePath) _nodePath = nodeRequire.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('theme.js', document.baseURI).href)))("node:path");
|
|
218
|
-
return _nodePath;
|
|
219
|
-
}
|
|
220
187
|
function createDebugLogger(namespace, label) {
|
|
221
188
|
const prefix = `[${namespace}]`;
|
|
222
189
|
return (msg) => {
|
|
@@ -226,17 +193,12 @@ function createDebugLogger(namespace, label) {
|
|
|
226
193
|
};
|
|
227
194
|
}
|
|
228
195
|
function loadNativeBinding(options) {
|
|
229
|
-
if (isBrowser) {
|
|
230
|
-
return { binding: null, loadErrors: [{ path: "", message: "Native bindings not available in browser" }] };
|
|
231
|
-
}
|
|
232
196
|
const { runtimeDir, candidates, isValid } = options;
|
|
233
197
|
const loadErrors = [];
|
|
234
|
-
const path2 = getNodePath();
|
|
235
|
-
const fs = getNodeFs();
|
|
236
198
|
for (const candidate of candidates) {
|
|
237
|
-
const candidatePath =
|
|
199
|
+
const candidatePath = path__default.default.resolve(runtimeDir, candidate);
|
|
238
200
|
try {
|
|
239
|
-
if (!
|
|
201
|
+
if (!fs__default.default.existsSync(candidatePath) && !fs__default.default.existsSync(candidatePath + ".node")) {
|
|
240
202
|
continue;
|
|
241
203
|
}
|
|
242
204
|
const mod = requireNativeModule(candidatePath);
|
|
@@ -250,54 +212,44 @@ function loadNativeBinding(options) {
|
|
|
250
212
|
}
|
|
251
213
|
return { binding: null, loadErrors };
|
|
252
214
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
});
|
|
257
|
-
const nodeRequire = getNodeModuleRef();
|
|
258
|
-
if (!nodeRequire) return (() => {
|
|
259
|
-
throw new Error("require not available");
|
|
260
|
-
});
|
|
261
|
-
return nodeRequire.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('theme.js', document.baseURI).href)));
|
|
262
|
-
}
|
|
263
|
-
var _require = getRequire();
|
|
264
|
-
function requireNativeModule(path2) {
|
|
265
|
-
return _require(path2);
|
|
215
|
+
var _require = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('theme.js', document.baseURI).href)));
|
|
216
|
+
function requireNativeModule(p) {
|
|
217
|
+
return _require(p);
|
|
266
218
|
}
|
|
267
219
|
function resolveNativeBindingCandidates(options) {
|
|
268
|
-
|
|
269
|
-
|
|
220
|
+
const {
|
|
221
|
+
envVarNames = ["TW_NATIVE_PATH", "TWS_NATIVE_PATH"],
|
|
222
|
+
includeDefaultCandidates = true,
|
|
223
|
+
enforceNodeExtensionForEnvPath = false
|
|
224
|
+
} = options;
|
|
225
|
+
const runtimeDir = options.runtimeDir || process.cwd();
|
|
270
226
|
const candidates = [];
|
|
271
|
-
const path2 = getNodePath();
|
|
272
|
-
const fs = getNodeFs();
|
|
273
227
|
for (const envVar of envVarNames) {
|
|
274
228
|
const envPath = process.env[envVar];
|
|
275
229
|
if (envPath) {
|
|
276
|
-
|
|
277
|
-
candidates.push(envPath + ".node");
|
|
278
|
-
} else {
|
|
279
|
-
candidates.push(envPath);
|
|
280
|
-
}
|
|
230
|
+
candidates.push(enforceNodeExtensionForEnvPath && !envPath.endsWith(".node") ? envPath + ".node" : envPath);
|
|
281
231
|
}
|
|
282
232
|
}
|
|
283
233
|
if (!includeDefaultCandidates) return candidates;
|
|
284
|
-
if (
|
|
234
|
+
if (fs__default.default.existsSync(runtimeDir)) {
|
|
285
235
|
try {
|
|
286
|
-
const
|
|
287
|
-
|
|
288
|
-
if (entry.endsWith(".node")) {
|
|
289
|
-
candidates.push(entry);
|
|
290
|
-
}
|
|
236
|
+
for (const entry of fs__default.default.readdirSync(runtimeDir)) {
|
|
237
|
+
if (entry.endsWith(".node")) candidates.push(entry);
|
|
291
238
|
}
|
|
292
239
|
} catch {
|
|
293
240
|
}
|
|
294
241
|
}
|
|
295
|
-
const
|
|
296
|
-
const
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
242
|
+
const BINARY_NAMES = ["tailwind-styled-native", "tailwind_styled_parser"];
|
|
243
|
+
const napiPlatform = process.platform === "linux" && process.arch === "x64" ? "linux-x64-gnu" : process.platform === "linux" && process.arch === "arm64" ? "linux-arm64-gnu" : `${process.platform}-${process.arch}`;
|
|
244
|
+
for (const bin of BINARY_NAMES) {
|
|
245
|
+
candidates.push(path__default.default.resolve(runtimeDir, `${bin}.node`));
|
|
246
|
+
candidates.push(path__default.default.resolve(runtimeDir, `${bin}.${napiPlatform}.node`));
|
|
247
|
+
candidates.push(path__default.default.resolve(runtimeDir, "..", "..", "..", "..", "native", `${bin}.node`));
|
|
248
|
+
candidates.push(path__default.default.resolve(runtimeDir, "..", "..", "..", "..", "native", `${bin}.${napiPlatform}.node`));
|
|
249
|
+
candidates.push(path__default.default.resolve(runtimeDir, "..", "..", "..", "native", `${bin}.node`));
|
|
250
|
+
candidates.push(path__default.default.resolve(process.cwd(), "native", `${bin}.node`));
|
|
251
|
+
candidates.push(path__default.default.resolve(process.cwd(), "native", `${bin}.${napiPlatform}.node`));
|
|
252
|
+
}
|
|
301
253
|
return Array.from(new Set(candidates));
|
|
302
254
|
}
|
|
303
255
|
|
|
@@ -391,28 +343,16 @@ function createTheme(contract, name, values, asRoot = false) {
|
|
|
391
343
|
if (native?.compileTheme) {
|
|
392
344
|
const result = native.compileTheme(JSON.stringify(values), asRoot ? "light" : name, "");
|
|
393
345
|
if (result) {
|
|
394
|
-
const
|
|
346
|
+
const flatVars = {};
|
|
395
347
|
for (const token of result.tokens) {
|
|
396
|
-
|
|
348
|
+
flatVars[token.cssVar] = token.value;
|
|
397
349
|
}
|
|
398
|
-
return { name, contract, values, css: result.css, vars:
|
|
350
|
+
return { name, contract, values, css: result.css, vars: flatVars, selector: result.selector };
|
|
399
351
|
}
|
|
400
352
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
for (const token in values[group]) {
|
|
405
|
-
const varName = `--${group}-${token}`;
|
|
406
|
-
const value = values[group][token];
|
|
407
|
-
flatVars[varName] = value;
|
|
408
|
-
cssLines.push(` ${varName}: ${value};`);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
const selector = asRoot ? ":root" : `[data-theme="${name}"]`;
|
|
412
|
-
const css = `${selector} {
|
|
413
|
-
${cssLines.join("\n")}
|
|
414
|
-
}`;
|
|
415
|
-
return { name, contract, values, css, vars: flatVars, selector };
|
|
353
|
+
throw new Error(
|
|
354
|
+
"FATAL: Native binding 'compileTheme' is required but not available. Run 'npm run build:rust' to build the native module."
|
|
355
|
+
);
|
|
416
356
|
}
|
|
417
357
|
var ThemeRegistry = class {
|
|
418
358
|
themes = /* @__PURE__ */ new Map();
|
|
@@ -505,21 +445,9 @@ function compileDesignTokens(tokens, prefix = "") {
|
|
|
505
445
|
const result = native.compileTheme(JSON.stringify(tokens), "default", prefix);
|
|
506
446
|
if (result) return result.css;
|
|
507
447
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
const varPath = path2 ? `${path2}-${key}` : key;
|
|
512
|
-
if (typeof value === "string") {
|
|
513
|
-
vars.push(` --${varPath}: ${value};`);
|
|
514
|
-
} else {
|
|
515
|
-
flatten(value, varPath);
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
flatten(tokens, prefix);
|
|
520
|
-
return `:root {
|
|
521
|
-
${vars.join("\n")}
|
|
522
|
-
}`;
|
|
448
|
+
throw new Error(
|
|
449
|
+
"FATAL: Native binding 'compileTheme' is required but not available. Run 'npm run build:rust' to build the native module."
|
|
450
|
+
);
|
|
523
451
|
}
|
|
524
452
|
|
|
525
453
|
exports.LiveTokenUpdateSchema = LiveTokenUpdateSchema;
|