@csszyx/dynamic 0.9.10 → 0.10.1
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/index.d.mts
CHANGED
|
@@ -28,6 +28,51 @@ interface CSSManifest {
|
|
|
28
28
|
mangleMap?: Record<string, string>;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Purify an UNTRUSTED sz object before it reaches the runtime CSS pipeline.
|
|
33
|
+
*
|
|
34
|
+
* csszyx's `dynamic()` / `useSz` accept sz objects that an app may build from
|
|
35
|
+
* untrusted data (a JSON-driven UI, a CMS schema). Such input controls both the
|
|
36
|
+
* KEYS and the VALUES of the object, which opens three holes the rest of the
|
|
37
|
+
* stack only partially closes: an unknown key produces dead CSS or, via a key
|
|
38
|
+
* like `__proto__`, pollutes the prototype; an unsafe value injects an extra CSS
|
|
39
|
+
* declaration (UI redress / exfil) into the same rule; deep nesting overflows
|
|
40
|
+
* the stack. `purifySz` is the opt-in boundary that drops all three.
|
|
41
|
+
*
|
|
42
|
+
* It is allowlist-based: only keys the compiler actually understands
|
|
43
|
+
* (`SZ_KEY_CATEGORY`, generated from the compiler tables) and valid variant keys
|
|
44
|
+
* survive; every string value must pass {@link isSafeCssValue}; forbidden keys
|
|
45
|
+
* are skipped; depth is bounded by the shared `MAX_SZ_DEPTH`. In `strict` mode
|
|
46
|
+
* (default) it additionally drops values carrying `url()` / `image-set()` /
|
|
47
|
+
* `@import` / `expression()` — vectors the authored-path emitter intentionally
|
|
48
|
+
* allows but which are exfil/legacy risks for untrusted input.
|
|
49
|
+
*
|
|
50
|
+
* Pure, framework-agnostic. Compiled/authored sz does NOT need this — it is for
|
|
51
|
+
* the untrusted runtime boundary only.
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
/** Options controlling `purifySz` strictness and drop reporting. */
|
|
55
|
+
interface PurifySzOptions {
|
|
56
|
+
/**
|
|
57
|
+
* When true (default), also reject values containing `url()`/`image-set()`/
|
|
58
|
+
* `@import`/`expression()`. These are legitimate for AUTHORED sz but are
|
|
59
|
+
* exfiltration / legacy vectors when the value is attacker-controlled.
|
|
60
|
+
*/
|
|
61
|
+
strict?: boolean;
|
|
62
|
+
/** Called for each dropped key/value with its dotted path and a reason. */
|
|
63
|
+
onDrop?: (path: string, reason: string) => void;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Return a cleaned copy of `sz` safe to pass to `dynamic()` / `useSz` from
|
|
67
|
+
* untrusted input. Drops unknown keys, unsafe values, and prototype-polluting
|
|
68
|
+
* keys; bounds nesting depth. See {@link PurifySzOptions}.
|
|
69
|
+
*
|
|
70
|
+
* @param sz - the untrusted sz object.
|
|
71
|
+
* @param options - strictness + drop reporting.
|
|
72
|
+
* @returns a new sz object containing only allowed keys and safe values.
|
|
73
|
+
*/
|
|
74
|
+
declare function purifySz(sz: SzObject, options?: PurifySzOptions): SzObject;
|
|
75
|
+
|
|
31
76
|
/**
|
|
32
77
|
* @csszyx/dynamic — Runtime CSS injection with delta check.
|
|
33
78
|
*
|
|
@@ -88,5 +133,5 @@ declare function preloadManifest(url?: string): Promise<void>;
|
|
|
88
133
|
*/
|
|
89
134
|
declare function cleanup(): void;
|
|
90
135
|
|
|
91
|
-
export { cleanup, dynamic, preloadManifest };
|
|
92
|
-
export type { CSSManifest, Tier };
|
|
136
|
+
export { cleanup, dynamic, preloadManifest, purifySz };
|
|
137
|
+
export type { CSSManifest, PurifySzOptions, Tier };
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import '@csszyx/compiler/browser';
|
|
2
|
-
export { a as cleanup, d as dynamic, b as preloadManifest } from './shared/dynamic.
|
|
2
|
+
export { a as cleanup, d as dynamic, b as preloadManifest, e as purifySz } from './shared/dynamic.CZNnPnjy.mjs';
|
package/dist/react.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, useEffect, createElement, useContext, useCallback } from 'react';
|
|
2
|
-
import { d as dynamic, p as preloadManifest, c as cleanup, r as resetManifest, s as setManifestUrl } from './shared/dynamic.
|
|
2
|
+
import { d as dynamic, p as preloadManifest, c as cleanup, r as resetManifest, s as setManifestUrl } from './shared/dynamic.CZNnPnjy.mjs';
|
|
3
3
|
import '@csszyx/compiler/browser';
|
|
4
4
|
|
|
5
5
|
const CsszyxContext = createContext({
|
|
@@ -1,5 +1,83 @@
|
|
|
1
|
-
import { transform } from '@csszyx/compiler/browser';
|
|
1
|
+
import { MAX_SZ_DEPTH, SzDepthError, isForbiddenSzKey, KNOWN_VARIANTS, getVariantPrefix, SPECIAL_VARIANTS, transform } from '@csszyx/compiler/browser';
|
|
2
2
|
|
|
3
|
+
function isSafeCssValue(value) {
|
|
4
|
+
let quote = null;
|
|
5
|
+
let parenDepth = 0;
|
|
6
|
+
for (let i = 0; i < value.length; i++) {
|
|
7
|
+
const ch = value[i];
|
|
8
|
+
if (value.charCodeAt(i) < 32) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
if (quote !== null) {
|
|
12
|
+
if (ch === "\\") {
|
|
13
|
+
i++;
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (ch === quote) {
|
|
17
|
+
quote = null;
|
|
18
|
+
}
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
switch (ch) {
|
|
22
|
+
case '"':
|
|
23
|
+
case "'":
|
|
24
|
+
quote = ch;
|
|
25
|
+
break;
|
|
26
|
+
case "(":
|
|
27
|
+
parenDepth++;
|
|
28
|
+
break;
|
|
29
|
+
case ")":
|
|
30
|
+
if (parenDepth > 0) {
|
|
31
|
+
parenDepth--;
|
|
32
|
+
}
|
|
33
|
+
break;
|
|
34
|
+
case "{":
|
|
35
|
+
case "}":
|
|
36
|
+
case "<":
|
|
37
|
+
case ">":
|
|
38
|
+
return false;
|
|
39
|
+
case ";":
|
|
40
|
+
if (parenDepth === 0) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return quote === null && parenDepth === 0;
|
|
47
|
+
}
|
|
48
|
+
function isSafeCssPropertyName(name) {
|
|
49
|
+
return /^(?:--[\w-]+|-?[a-z][a-z0-9-]*)$/i.test(name);
|
|
50
|
+
}
|
|
51
|
+
function isUtilityArbitrarySafe(utility) {
|
|
52
|
+
const open = utility.indexOf("[");
|
|
53
|
+
if (open === -1) {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
const close = utility.lastIndexOf("]");
|
|
57
|
+
if (close <= open) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
const inner = utility.slice(open + 1, close);
|
|
61
|
+
if (utility.charCodeAt(0) === 91 && utility.charCodeAt(utility.length - 1) === 93 && inner.includes(":")) {
|
|
62
|
+
const colon = inner.indexOf(":");
|
|
63
|
+
return isSafeCssPropertyName(inner.slice(0, colon)) && isSafeCssValue(inner.slice(colon + 1));
|
|
64
|
+
}
|
|
65
|
+
return isSafeCssValue(inner);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
let warnedUnsafeArbitrary = false;
|
|
69
|
+
function warnUnsafeArbitrary(utility) {
|
|
70
|
+
if (warnedUnsafeArbitrary) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
warnedUnsafeArbitrary = true;
|
|
77
|
+
console.warn(
|
|
78
|
+
`[csszyx] dropped an arbitrary value that could inject CSS: "${utility}". Arbitrary values from untrusted data are not emitted at runtime.`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
3
81
|
const BREAKPOINTS = {
|
|
4
82
|
sm: "40rem",
|
|
5
83
|
md: "48rem",
|
|
@@ -553,6 +631,10 @@ function parseVariants(cls) {
|
|
|
553
631
|
return { tier, pseudoSuffix, selectorPrefix, utility };
|
|
554
632
|
}
|
|
555
633
|
function generateDeclarations(utility) {
|
|
634
|
+
if (!isUtilityArbitrarySafe(utility)) {
|
|
635
|
+
warnUnsafeArbitrary(utility);
|
|
636
|
+
return "";
|
|
637
|
+
}
|
|
556
638
|
if (utility in KEYWORD_RULES) {
|
|
557
639
|
return KEYWORD_RULES[utility];
|
|
558
640
|
}
|
|
@@ -1110,6 +1192,421 @@ function resetManifest() {
|
|
|
1110
1192
|
|
|
1111
1193
|
const isServer = typeof document === "undefined";
|
|
1112
1194
|
|
|
1195
|
+
const SZ_KEY_CATEGORY = /* @__PURE__ */ new Map([
|
|
1196
|
+
["accent", "COLOR"],
|
|
1197
|
+
["align", "PASSTHROUGH"],
|
|
1198
|
+
["animate", "PASSTHROUGH"],
|
|
1199
|
+
["animationDelay", "DURATION"],
|
|
1200
|
+
["appearance", "PASSTHROUGH"],
|
|
1201
|
+
["aspect", "PASSTHROUGH"],
|
|
1202
|
+
["autoCols", "PASSTHROUGH"],
|
|
1203
|
+
["autoRows", "PASSTHROUGH"],
|
|
1204
|
+
["backdropBlur", "PASSTHROUGH"],
|
|
1205
|
+
["backdropBrightness", "UNITLESS"],
|
|
1206
|
+
["backdropContrast", "UNITLESS"],
|
|
1207
|
+
["backdropFilter", "PASSTHROUGH"],
|
|
1208
|
+
["backdropGrayscale", "PASSTHROUGH"],
|
|
1209
|
+
["backdropHueRotate", "UNITLESS"],
|
|
1210
|
+
["backdropInvert", "PASSTHROUGH"],
|
|
1211
|
+
["backdropOpacity", "UNITLESS"],
|
|
1212
|
+
["backdropSaturate", "UNITLESS"],
|
|
1213
|
+
["backdropSepia", "PASSTHROUGH"],
|
|
1214
|
+
["backface", "PASSTHROUGH"],
|
|
1215
|
+
["basis", "SPACING"],
|
|
1216
|
+
["bg", "COLOR"],
|
|
1217
|
+
["bgAttach", "PASSTHROUGH"],
|
|
1218
|
+
["bgBlend", "PASSTHROUGH"],
|
|
1219
|
+
["bgClip", "PASSTHROUGH"],
|
|
1220
|
+
["bgImg", "PASSTHROUGH"],
|
|
1221
|
+
["bgOrigin", "PASSTHROUGH"],
|
|
1222
|
+
["bgPos", "PASSTHROUGH"],
|
|
1223
|
+
["bgRepeat", "PASSTHROUGH"],
|
|
1224
|
+
["bgSize", "PASSTHROUGH"],
|
|
1225
|
+
["blockSize", "SPACING"],
|
|
1226
|
+
["blur", "PASSTHROUGH"],
|
|
1227
|
+
["border", "UNITLESS"],
|
|
1228
|
+
["borderB", "UNITLESS"],
|
|
1229
|
+
["borderBColor", "PASSTHROUGH"],
|
|
1230
|
+
["borderBe", "UNITLESS"],
|
|
1231
|
+
["borderBs", "UNITLESS"],
|
|
1232
|
+
["borderCollapse", "PASSTHROUGH"],
|
|
1233
|
+
["borderColor", "COLOR"],
|
|
1234
|
+
["borderE", "UNITLESS"],
|
|
1235
|
+
["borderL", "UNITLESS"],
|
|
1236
|
+
["borderLColor", "PASSTHROUGH"],
|
|
1237
|
+
["borderR", "UNITLESS"],
|
|
1238
|
+
["borderRColor", "PASSTHROUGH"],
|
|
1239
|
+
["borderS", "UNITLESS"],
|
|
1240
|
+
["borderSpacing", "SPACING"],
|
|
1241
|
+
["borderSpacingX", "SPACING"],
|
|
1242
|
+
["borderSpacingY", "SPACING"],
|
|
1243
|
+
["borderStyle", "PASSTHROUGH"],
|
|
1244
|
+
["borderT", "UNITLESS"],
|
|
1245
|
+
["borderTColor", "PASSTHROUGH"],
|
|
1246
|
+
["borderX", "UNITLESS"],
|
|
1247
|
+
["borderXColor", "PASSTHROUGH"],
|
|
1248
|
+
["borderY", "UNITLESS"],
|
|
1249
|
+
["borderYColor", "PASSTHROUGH"],
|
|
1250
|
+
["bottom", "SPACING"],
|
|
1251
|
+
["box", "PASSTHROUGH"],
|
|
1252
|
+
["boxDecoration", "PASSTHROUGH"],
|
|
1253
|
+
["break", "PASSTHROUGH"],
|
|
1254
|
+
["breakAfter", "PASSTHROUGH"],
|
|
1255
|
+
["breakBefore", "PASSTHROUGH"],
|
|
1256
|
+
["breakInside", "PASSTHROUGH"],
|
|
1257
|
+
["brightness", "UNITLESS"],
|
|
1258
|
+
["caption", "PASSTHROUGH"],
|
|
1259
|
+
["caret", "COLOR"],
|
|
1260
|
+
["clear", "PASSTHROUGH"],
|
|
1261
|
+
["col", "UNITLESS"],
|
|
1262
|
+
["colEnd", "UNITLESS"],
|
|
1263
|
+
["colSpan", "UNITLESS"],
|
|
1264
|
+
["colStart", "UNITLESS"],
|
|
1265
|
+
["color", "COLOR"],
|
|
1266
|
+
["columns", "UNITLESS"],
|
|
1267
|
+
["container", "PASSTHROUGH"],
|
|
1268
|
+
["content", "PASSTHROUGH"],
|
|
1269
|
+
["contrast", "UNITLESS"],
|
|
1270
|
+
["cursor", "PASSTHROUGH"],
|
|
1271
|
+
["decoration", "PASSTHROUGH"],
|
|
1272
|
+
["decorationColor", "COLOR"],
|
|
1273
|
+
["decorationStyle", "PASSTHROUGH"],
|
|
1274
|
+
["decorationThickness", "UNITLESS"],
|
|
1275
|
+
["delay", "DURATION"],
|
|
1276
|
+
["diagonalFractions", "PASSTHROUGH"],
|
|
1277
|
+
["display", "PASSTHROUGH"],
|
|
1278
|
+
["divideColor", "COLOR"],
|
|
1279
|
+
["divideStyle", "PASSTHROUGH"],
|
|
1280
|
+
["divideX", "PASSTHROUGH"],
|
|
1281
|
+
["divideXReverse", "PASSTHROUGH"],
|
|
1282
|
+
["divideY", "PASSTHROUGH"],
|
|
1283
|
+
["divideYReverse", "PASSTHROUGH"],
|
|
1284
|
+
["dropShadow", "PASSTHROUGH"],
|
|
1285
|
+
["dropShadowColor", "COLOR"],
|
|
1286
|
+
["duration", "DURATION"],
|
|
1287
|
+
["ease", "PASSTHROUGH"],
|
|
1288
|
+
["end", "SPACING"],
|
|
1289
|
+
["fieldSizing", "PASSTHROUGH"],
|
|
1290
|
+
["fill", "COLOR"],
|
|
1291
|
+
["filter", "PASSTHROUGH"],
|
|
1292
|
+
["flex", "PASSTHROUGH"],
|
|
1293
|
+
["flexDir", "PASSTHROUGH"],
|
|
1294
|
+
["flexWrap", "PASSTHROUGH"],
|
|
1295
|
+
["float", "PASSTHROUGH"],
|
|
1296
|
+
["fontFamily", "PASSTHROUGH"],
|
|
1297
|
+
["fontFeatures", "PASSTHROUGH"],
|
|
1298
|
+
["fontSmoothing", "PASSTHROUGH"],
|
|
1299
|
+
["fontStretch", "PASSTHROUGH"],
|
|
1300
|
+
["fontStyle", "PASSTHROUGH"],
|
|
1301
|
+
["forcedColorAdjust", "PASSTHROUGH"],
|
|
1302
|
+
["from", "COLOR"],
|
|
1303
|
+
["gap", "SPACING"],
|
|
1304
|
+
["gapX", "SPACING"],
|
|
1305
|
+
["gapY", "SPACING"],
|
|
1306
|
+
["grayscale", "PASSTHROUGH"],
|
|
1307
|
+
["gridCols", "UNITLESS"],
|
|
1308
|
+
["gridFlow", "PASSTHROUGH"],
|
|
1309
|
+
["gridRows", "UNITLESS"],
|
|
1310
|
+
["grow", "UNITLESS"],
|
|
1311
|
+
["h", "SPACING"],
|
|
1312
|
+
["hueRotate", "UNITLESS"],
|
|
1313
|
+
["hyphens", "PASSTHROUGH"],
|
|
1314
|
+
["indent", "SPACING"],
|
|
1315
|
+
["inlineSize", "SPACING"],
|
|
1316
|
+
["inset", "SPACING"],
|
|
1317
|
+
["insetBe", "SPACING"],
|
|
1318
|
+
["insetBs", "SPACING"],
|
|
1319
|
+
["insetE", "SPACING"],
|
|
1320
|
+
["insetRing", "PASSTHROUGH"],
|
|
1321
|
+
["insetRingColor", "PASSTHROUGH"],
|
|
1322
|
+
["insetS", "SPACING"],
|
|
1323
|
+
["insetShadow", "PASSTHROUGH"],
|
|
1324
|
+
["insetShadowColor", "PASSTHROUGH"],
|
|
1325
|
+
["insetX", "SPACING"],
|
|
1326
|
+
["insetY", "SPACING"],
|
|
1327
|
+
["invert", "PASSTHROUGH"],
|
|
1328
|
+
["isolation", "PASSTHROUGH"],
|
|
1329
|
+
["items", "PASSTHROUGH"],
|
|
1330
|
+
["justify", "PASSTHROUGH"],
|
|
1331
|
+
["justifyItems", "PASSTHROUGH"],
|
|
1332
|
+
["justifySelf", "PASSTHROUGH"],
|
|
1333
|
+
["leading", "UNITLESS"],
|
|
1334
|
+
["left", "SPACING"],
|
|
1335
|
+
["lineClamp", "UNITLESS"],
|
|
1336
|
+
["liningNums", "PASSTHROUGH"],
|
|
1337
|
+
["list", "PASSTHROUGH"],
|
|
1338
|
+
["listImg", "PASSTHROUGH"],
|
|
1339
|
+
["listPos", "PASSTHROUGH"],
|
|
1340
|
+
["m", "SPACING"],
|
|
1341
|
+
["mask", "PASSTHROUGH"],
|
|
1342
|
+
["maskClip", "PASSTHROUGH"],
|
|
1343
|
+
["maskFrom", "COLOR"],
|
|
1344
|
+
["maskOrigin", "PASSTHROUGH"],
|
|
1345
|
+
["maskPos", "PASSTHROUGH"],
|
|
1346
|
+
["maskRepeat", "PASSTHROUGH"],
|
|
1347
|
+
["maskShape", "PASSTHROUGH"],
|
|
1348
|
+
["maskSize", "PASSTHROUGH"],
|
|
1349
|
+
["maskTo", "COLOR"],
|
|
1350
|
+
["maskVia", "COLOR"],
|
|
1351
|
+
["maxBlockSize", "SPACING"],
|
|
1352
|
+
["maxH", "SPACING"],
|
|
1353
|
+
["maxInlineSize", "SPACING"],
|
|
1354
|
+
["maxW", "SPACING"],
|
|
1355
|
+
["mb", "SPACING"],
|
|
1356
|
+
["mbe", "SPACING"],
|
|
1357
|
+
["mbs", "SPACING"],
|
|
1358
|
+
["me", "SPACING"],
|
|
1359
|
+
["minBlockSize", "SPACING"],
|
|
1360
|
+
["minH", "SPACING"],
|
|
1361
|
+
["minInlineSize", "SPACING"],
|
|
1362
|
+
["minW", "SPACING"],
|
|
1363
|
+
["mixBlend", "PASSTHROUGH"],
|
|
1364
|
+
["ml", "SPACING"],
|
|
1365
|
+
["mr", "SPACING"],
|
|
1366
|
+
["ms", "SPACING"],
|
|
1367
|
+
["mt", "SPACING"],
|
|
1368
|
+
["mx", "SPACING"],
|
|
1369
|
+
["my", "SPACING"],
|
|
1370
|
+
["notSrOnly", "PASSTHROUGH"],
|
|
1371
|
+
["objectFit", "PASSTHROUGH"],
|
|
1372
|
+
["objectPos", "PASSTHROUGH"],
|
|
1373
|
+
["oldstyleNums", "PASSTHROUGH"],
|
|
1374
|
+
["opacity", "UNITLESS"],
|
|
1375
|
+
["order", "UNITLESS"],
|
|
1376
|
+
["ordinal", "PASSTHROUGH"],
|
|
1377
|
+
["origin", "PASSTHROUGH"],
|
|
1378
|
+
["outline", "UNITLESS"],
|
|
1379
|
+
["outlineColor", "COLOR"],
|
|
1380
|
+
["outlineOffset", "SPACING"],
|
|
1381
|
+
["outlineStyle", "PASSTHROUGH"],
|
|
1382
|
+
["overflow", "PASSTHROUGH"],
|
|
1383
|
+
["overflowX", "PASSTHROUGH"],
|
|
1384
|
+
["overflowY", "PASSTHROUGH"],
|
|
1385
|
+
["overscroll", "PASSTHROUGH"],
|
|
1386
|
+
["overscrollX", "PASSTHROUGH"],
|
|
1387
|
+
["overscrollY", "PASSTHROUGH"],
|
|
1388
|
+
["p", "SPACING"],
|
|
1389
|
+
["pb", "SPACING"],
|
|
1390
|
+
["pbe", "SPACING"],
|
|
1391
|
+
["pbs", "SPACING"],
|
|
1392
|
+
["pe", "SPACING"],
|
|
1393
|
+
["perspective", "PASSTHROUGH"],
|
|
1394
|
+
["perspectiveOrigin", "PASSTHROUGH"],
|
|
1395
|
+
["pl", "SPACING"],
|
|
1396
|
+
["placeContent", "PASSTHROUGH"],
|
|
1397
|
+
["placeItems", "PASSTHROUGH"],
|
|
1398
|
+
["placeSelf", "PASSTHROUGH"],
|
|
1399
|
+
["pointerEvents", "PASSTHROUGH"],
|
|
1400
|
+
["position", "PASSTHROUGH"],
|
|
1401
|
+
["pr", "SPACING"],
|
|
1402
|
+
["proportionalNums", "PASSTHROUGH"],
|
|
1403
|
+
["prose", "PASSTHROUGH"],
|
|
1404
|
+
["proseInvert", "PASSTHROUGH"],
|
|
1405
|
+
["ps", "SPACING"],
|
|
1406
|
+
["pt", "SPACING"],
|
|
1407
|
+
["px", "SPACING"],
|
|
1408
|
+
["py", "SPACING"],
|
|
1409
|
+
["resize", "PASSTHROUGH"],
|
|
1410
|
+
["right", "SPACING"],
|
|
1411
|
+
["ring", "UNITLESS"],
|
|
1412
|
+
["ringColor", "COLOR"],
|
|
1413
|
+
["ringOffset", "SPACING"],
|
|
1414
|
+
["ringOffsetColor", "COLOR"],
|
|
1415
|
+
["rotate", "ANGLE"],
|
|
1416
|
+
["rotateX", "PASSTHROUGH"],
|
|
1417
|
+
["rotateY", "PASSTHROUGH"],
|
|
1418
|
+
["rotateZ", "PASSTHROUGH"],
|
|
1419
|
+
["rounded", "PASSTHROUGH"],
|
|
1420
|
+
["roundedB", "PASSTHROUGH"],
|
|
1421
|
+
["roundedBl", "PASSTHROUGH"],
|
|
1422
|
+
["roundedBr", "PASSTHROUGH"],
|
|
1423
|
+
["roundedE", "PASSTHROUGH"],
|
|
1424
|
+
["roundedEe", "PASSTHROUGH"],
|
|
1425
|
+
["roundedEs", "PASSTHROUGH"],
|
|
1426
|
+
["roundedL", "PASSTHROUGH"],
|
|
1427
|
+
["roundedR", "PASSTHROUGH"],
|
|
1428
|
+
["roundedS", "PASSTHROUGH"],
|
|
1429
|
+
["roundedSe", "PASSTHROUGH"],
|
|
1430
|
+
["roundedSs", "PASSTHROUGH"],
|
|
1431
|
+
["roundedT", "PASSTHROUGH"],
|
|
1432
|
+
["roundedTl", "PASSTHROUGH"],
|
|
1433
|
+
["roundedTr", "PASSTHROUGH"],
|
|
1434
|
+
["row", "UNITLESS"],
|
|
1435
|
+
["rowEnd", "UNITLESS"],
|
|
1436
|
+
["rowSpan", "UNITLESS"],
|
|
1437
|
+
["rowStart", "UNITLESS"],
|
|
1438
|
+
["saturate", "UNITLESS"],
|
|
1439
|
+
["scale", "UNITLESS"],
|
|
1440
|
+
["scaleX", "UNITLESS"],
|
|
1441
|
+
["scaleY", "UNITLESS"],
|
|
1442
|
+
["scaleZ", "PASSTHROUGH"],
|
|
1443
|
+
["scheme", "PASSTHROUGH"],
|
|
1444
|
+
["scroll", "PASSTHROUGH"],
|
|
1445
|
+
["scrollM", "SPACING"],
|
|
1446
|
+
["scrollMb", "SPACING"],
|
|
1447
|
+
["scrollMbe", "SPACING"],
|
|
1448
|
+
["scrollMbs", "SPACING"],
|
|
1449
|
+
["scrollMe", "SPACING"],
|
|
1450
|
+
["scrollMl", "SPACING"],
|
|
1451
|
+
["scrollMr", "SPACING"],
|
|
1452
|
+
["scrollMs", "SPACING"],
|
|
1453
|
+
["scrollMt", "SPACING"],
|
|
1454
|
+
["scrollMx", "SPACING"],
|
|
1455
|
+
["scrollMy", "SPACING"],
|
|
1456
|
+
["scrollP", "SPACING"],
|
|
1457
|
+
["scrollPb", "SPACING"],
|
|
1458
|
+
["scrollPbe", "SPACING"],
|
|
1459
|
+
["scrollPbs", "SPACING"],
|
|
1460
|
+
["scrollPe", "SPACING"],
|
|
1461
|
+
["scrollPl", "SPACING"],
|
|
1462
|
+
["scrollPr", "SPACING"],
|
|
1463
|
+
["scrollPs", "SPACING"],
|
|
1464
|
+
["scrollPt", "SPACING"],
|
|
1465
|
+
["scrollPx", "SPACING"],
|
|
1466
|
+
["scrollPy", "SPACING"],
|
|
1467
|
+
["scrollbar", "PASSTHROUGH"],
|
|
1468
|
+
["scrollbarGutter", "PASSTHROUGH"],
|
|
1469
|
+
["scrollbarThumb", "COLOR"],
|
|
1470
|
+
["scrollbarTrack", "COLOR"],
|
|
1471
|
+
["select", "PASSTHROUGH"],
|
|
1472
|
+
["self", "PASSTHROUGH"],
|
|
1473
|
+
["sepia", "PASSTHROUGH"],
|
|
1474
|
+
["shadow", "PASSTHROUGH"],
|
|
1475
|
+
["shadowColor", "COLOR"],
|
|
1476
|
+
["shrink", "UNITLESS"],
|
|
1477
|
+
["size", "SPACING"],
|
|
1478
|
+
["skewX", "ANGLE"],
|
|
1479
|
+
["skewY", "ANGLE"],
|
|
1480
|
+
["slashedZero", "PASSTHROUGH"],
|
|
1481
|
+
["snapAlign", "PASSTHROUGH"],
|
|
1482
|
+
["snapStop", "PASSTHROUGH"],
|
|
1483
|
+
["snapType", "PASSTHROUGH"],
|
|
1484
|
+
["spaceX", "SPACING"],
|
|
1485
|
+
["spaceXReverse", "PASSTHROUGH"],
|
|
1486
|
+
["spaceY", "SPACING"],
|
|
1487
|
+
["spaceYReverse", "PASSTHROUGH"],
|
|
1488
|
+
["srOnly", "PASSTHROUGH"],
|
|
1489
|
+
["stackedFractions", "PASSTHROUGH"],
|
|
1490
|
+
["start", "SPACING"],
|
|
1491
|
+
["stroke", "COLOR"],
|
|
1492
|
+
["strokeWidth", "UNITLESS"],
|
|
1493
|
+
["tabSize", "UNITLESS"],
|
|
1494
|
+
["tableLayout", "PASSTHROUGH"],
|
|
1495
|
+
["tabularNums", "PASSTHROUGH"],
|
|
1496
|
+
["text", "PASSTHROUGH"],
|
|
1497
|
+
["textAlign", "PASSTHROUGH"],
|
|
1498
|
+
["textOverflow", "PASSTHROUGH"],
|
|
1499
|
+
["textShadow", "PASSTHROUGH"],
|
|
1500
|
+
["textShadowColor", "COLOR"],
|
|
1501
|
+
["textTransform", "PASSTHROUGH"],
|
|
1502
|
+
["textWrap", "PASSTHROUGH"],
|
|
1503
|
+
["to", "COLOR"],
|
|
1504
|
+
["top", "SPACING"],
|
|
1505
|
+
["touch", "PASSTHROUGH"],
|
|
1506
|
+
["tracking", "PASSTHROUGH"],
|
|
1507
|
+
["transform", "PASSTHROUGH"],
|
|
1508
|
+
["transformStyle", "PASSTHROUGH"],
|
|
1509
|
+
["transition", "PASSTHROUGH"],
|
|
1510
|
+
["transitionBehavior", "PASSTHROUGH"],
|
|
1511
|
+
["translate", "PASSTHROUGH"],
|
|
1512
|
+
["translateX", "SPACING"],
|
|
1513
|
+
["translateY", "SPACING"],
|
|
1514
|
+
["translateZ", "PASSTHROUGH"],
|
|
1515
|
+
["truncate", "PASSTHROUGH"],
|
|
1516
|
+
["underlineOffset", "SPACING"],
|
|
1517
|
+
["via", "COLOR"],
|
|
1518
|
+
["visibility", "PASSTHROUGH"],
|
|
1519
|
+
["w", "SPACING"],
|
|
1520
|
+
["weight", "PASSTHROUGH"],
|
|
1521
|
+
["whitespace", "PASSTHROUGH"],
|
|
1522
|
+
["willChange", "PASSTHROUGH"],
|
|
1523
|
+
["wrap", "PASSTHROUGH"],
|
|
1524
|
+
["z", "UNITLESS"],
|
|
1525
|
+
["zoom", "UNITLESS"]
|
|
1526
|
+
]);
|
|
1527
|
+
|
|
1528
|
+
const DANGEROUS_VALUE_RE = /url\s*\(|image-set\s*\(|@import|expression\s*\(/i;
|
|
1529
|
+
function isVariantKey(key) {
|
|
1530
|
+
if (KNOWN_VARIANTS.has(key) || KNOWN_VARIANTS.has(getVariantPrefix(key))) {
|
|
1531
|
+
return true;
|
|
1532
|
+
}
|
|
1533
|
+
if (SPECIAL_VARIANTS.has(key) || SPECIAL_VARIANTS.has(getVariantPrefix(key))) {
|
|
1534
|
+
return true;
|
|
1535
|
+
}
|
|
1536
|
+
if (key.startsWith("@")) return true;
|
|
1537
|
+
if (key.startsWith("[") && key.endsWith("]")) return true;
|
|
1538
|
+
if (/^(?:group|peer)-/.test(key)) return true;
|
|
1539
|
+
if (/^[a-z][a-z-]*-\[.*\]$/.test(key)) return true;
|
|
1540
|
+
return false;
|
|
1541
|
+
}
|
|
1542
|
+
function isValueSafe(value, strict) {
|
|
1543
|
+
if (!isSafeCssValue(value)) return false;
|
|
1544
|
+
if (strict && DANGEROUS_VALUE_RE.test(value)) return false;
|
|
1545
|
+
return true;
|
|
1546
|
+
}
|
|
1547
|
+
const DROP = /* @__PURE__ */ Symbol("drop");
|
|
1548
|
+
function purifyValue(value, strict, onDrop, path, depth) {
|
|
1549
|
+
if (typeof value === "string") {
|
|
1550
|
+
if (isValueSafe(value, strict)) return value;
|
|
1551
|
+
onDrop?.(path, "unsafe-value");
|
|
1552
|
+
return DROP;
|
|
1553
|
+
}
|
|
1554
|
+
if (value === null || typeof value !== "object") {
|
|
1555
|
+
return value;
|
|
1556
|
+
}
|
|
1557
|
+
if (depth >= MAX_SZ_DEPTH) throw new SzDepthError();
|
|
1558
|
+
if (Array.isArray(value)) {
|
|
1559
|
+
const out = [];
|
|
1560
|
+
for (let i = 0; i < value.length; i++) {
|
|
1561
|
+
const cleaned = purifyValue(
|
|
1562
|
+
value[i],
|
|
1563
|
+
strict,
|
|
1564
|
+
onDrop,
|
|
1565
|
+
`${path}[${i}]`,
|
|
1566
|
+
depth + 1
|
|
1567
|
+
);
|
|
1568
|
+
if (cleaned !== DROP) out.push(cleaned);
|
|
1569
|
+
}
|
|
1570
|
+
return out;
|
|
1571
|
+
}
|
|
1572
|
+
return sanitizeObject(value, strict, onDrop, path, depth + 1, false);
|
|
1573
|
+
}
|
|
1574
|
+
function sanitizeObject(input, strict, onDrop, path, depth, applyKeyAllowlist) {
|
|
1575
|
+
if (depth > MAX_SZ_DEPTH) throw new SzDepthError();
|
|
1576
|
+
const out = {};
|
|
1577
|
+
for (const [key, value] of Object.entries(input)) {
|
|
1578
|
+
const keyPath = path ? `${path}.${key}` : key;
|
|
1579
|
+
if (isForbiddenSzKey(key)) {
|
|
1580
|
+
onDrop?.(keyPath, "forbidden-key");
|
|
1581
|
+
continue;
|
|
1582
|
+
}
|
|
1583
|
+
if (applyKeyAllowlist && !SZ_KEY_CATEGORY.has(key)) {
|
|
1584
|
+
if (isVariantKey(key) && value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
1585
|
+
const cleaned2 = sanitizeObject(
|
|
1586
|
+
value,
|
|
1587
|
+
strict,
|
|
1588
|
+
onDrop,
|
|
1589
|
+
keyPath,
|
|
1590
|
+
depth + 1,
|
|
1591
|
+
true
|
|
1592
|
+
);
|
|
1593
|
+
if (Object.keys(cleaned2).length > 0) out[key] = cleaned2;
|
|
1594
|
+
continue;
|
|
1595
|
+
}
|
|
1596
|
+
onDrop?.(keyPath, "unknown-key");
|
|
1597
|
+
continue;
|
|
1598
|
+
}
|
|
1599
|
+
const cleaned = purifyValue(value, strict, onDrop, keyPath, depth);
|
|
1600
|
+
if (cleaned !== DROP) out[key] = cleaned;
|
|
1601
|
+
}
|
|
1602
|
+
return out;
|
|
1603
|
+
}
|
|
1604
|
+
function purifySz(sz, options = {}) {
|
|
1605
|
+
if (!sz || typeof sz !== "object" || Array.isArray(sz)) return {};
|
|
1606
|
+
const strict = options.strict ?? true;
|
|
1607
|
+
return sanitizeObject(sz, strict, options.onDrop, "", 0, true);
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1113
1610
|
function dynamic(szProps) {
|
|
1114
1611
|
const { className } = transform(szProps);
|
|
1115
1612
|
if (!className) {
|
|
@@ -1146,4 +1643,4 @@ function cleanup() {
|
|
|
1146
1643
|
resetManifest();
|
|
1147
1644
|
}
|
|
1148
1645
|
|
|
1149
|
-
export { cleanup as a, preloadManifest as b, cleanup$1 as c, dynamic as d, preloadManifest$1 as p, resetManifest as r, setManifestUrl as s };
|
|
1646
|
+
export { cleanup as a, preloadManifest as b, cleanup$1 as c, dynamic as d, purifySz as e, preloadManifest$1 as p, resetManifest as r, setManifestUrl as s };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@csszyx/dynamic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Runtime CSS injection engine for @csszyx — injects only CSS not already in the pre-built stylesheet",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"node": ">=22.12.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@csszyx/compiler": "0.
|
|
41
|
+
"@csszyx/compiler": "0.10.1"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"react": ">=
|
|
44
|
+
"react": ">=17.0.0"
|
|
45
45
|
},
|
|
46
46
|
"peerDependenciesMeta": {
|
|
47
47
|
"react": {
|