pasika 0.10.127 → 0.10.129

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.
@@ -9646,11 +9646,6 @@ function preludeIdentifiers(node) {
9646
9646
  });
9647
9647
  return names;
9648
9648
  }
9649
- function rawValue(node) {
9650
- if (!node) return "";
9651
- if (node.type === "Raw") return node.value;
9652
- return "";
9653
- }
9654
9649
  function rules(node) {
9655
9650
  const result = [];
9656
9651
  walkNodes(node, (current) => {
@@ -10680,15 +10675,17 @@ var rootVariablesRule = {
10680
10675
  const names = new Set(
10681
10676
  graph.definitions.filter((symbol) => symbol.kind === "theme-token").map((symbol) => symbol.name)
10682
10677
  );
10683
- function isFixedThemeAlias(name, value, visited = /* @__PURE__ */ new Set()) {
10684
- const match = /^var\(\s*(?<target>--[a-z][\w-]*)\s*\)$/u.exec(value.trim());
10685
- const target = match?.groups?.target;
10686
- if (!target || target === name || visited.has(target)) return false;
10687
- const next = themeValues.get(target);
10688
- if (!next) return false;
10689
- if (!/\bvar\s*\(/u.test(next)) return true;
10690
- visited.add(target);
10691
- return isFixedThemeAlias(name, next, visited);
10678
+ function isFixedThemeExpression(name, value, visited = /* @__PURE__ */ new Set([name])) {
10679
+ const references = [...value.matchAll(/\bvar\s*\(\s*(?<target>--[a-z][\w-]*)/giu)].map(
10680
+ (match) => match.groups?.target
10681
+ );
10682
+ if (references.length === 0) return true;
10683
+ return references.every((target) => {
10684
+ if (!target || visited.has(target)) return false;
10685
+ const next = themeValues.get(target);
10686
+ if (!next) return false;
10687
+ return isFixedThemeExpression(target, next, /* @__PURE__ */ new Set([...visited, target]));
10688
+ });
10692
10689
  }
10693
10690
  const mirroredTokens = /* @__PURE__ */ new Set();
10694
10691
  let hasPlainThemeBlocks = false;
@@ -10803,7 +10800,7 @@ var rootVariablesRule = {
10803
10800
  context.report({ node: theme, message: REDUNDANT_INLINE_MESSAGE(name) });
10804
10801
  }
10805
10802
  }
10806
- if (inline === referencesVariable || !inline && isFixedThemeAlias(name, unquoted)) continue;
10803
+ if (inline === referencesVariable || !inline && isFixedThemeExpression(name, unquoted)) continue;
10807
10804
  const offset = (theme.loc?.start.offset ?? 0) + match.index + match[0].indexOf(name);
10808
10805
  const preceding = context.sourceCode.text.slice(0, offset);
10809
10806
  const line = preceding.split("\n").length;
@@ -11217,18 +11214,44 @@ var unusedUtilityRule = {
11217
11214
  import { spawnSync } from "child_process";
11218
11215
  import { existsSync as existsSync12 } from "fs";
11219
11216
  import path78 from "path";
11220
- function applyOperationCount(utility) {
11217
+ function applyOperationCount(utility, textOf) {
11221
11218
  let count = 0;
11222
11219
  for (const apply of atrulesNamed(utility, "apply")) {
11223
- const identifiers = preludeIdentifiers(apply);
11224
- if (identifiers.length > 0) {
11225
- count += identifiers.length;
11226
- continue;
11220
+ const value = textOf(apply).trim().replace(/^@apply\s+/u, "").replace(/;\s*$/u, "");
11221
+ let brackets = 0;
11222
+ let parentheses = 0;
11223
+ let quote;
11224
+ let escaped = false;
11225
+ let inToken = false;
11226
+ for (const character of value) {
11227
+ if (escaped) {
11228
+ escaped = false;
11229
+ inToken = true;
11230
+ continue;
11231
+ }
11232
+ if (character === "\\") {
11233
+ escaped = true;
11234
+ inToken = true;
11235
+ continue;
11236
+ }
11237
+ if (character === '"' || character === "'") {
11238
+ if (!quote) quote = character;
11239
+ else if (quote === character) quote = void 0;
11240
+ } else if (!quote) {
11241
+ if (character === "[") brackets++;
11242
+ if (character === "]") brackets--;
11243
+ if (character === "(") parentheses++;
11244
+ if (character === ")") parentheses--;
11245
+ }
11246
+ if (/\s/u.test(character) && brackets === 0 && parentheses === 0 && !quote) {
11247
+ if (inToken) count++;
11248
+ inToken = false;
11249
+ } else {
11250
+ inToken = true;
11251
+ }
11227
11252
  }
11228
- const prelude = "prelude" in apply ? apply.prelude : void 0;
11229
- const raw = prelude ? rawValue(prelude) : "";
11230
- const rawOperations = raw.trim().split(/\s+/).filter(Boolean);
11231
- count += rawOperations.length > 0 ? rawOperations.length : 1;
11253
+ if (inToken) count++;
11254
+ if (!value.trim()) count++;
11232
11255
  }
11233
11256
  return count;
11234
11257
  }
@@ -11262,39 +11285,58 @@ var themeOperations = [
11262
11285
  { property: "gap", prefix: "gap", namespace: "spacing" },
11263
11286
  { property: "width", prefix: "w", namespace: "spacing" },
11264
11287
  { property: "height", prefix: "h", namespace: "spacing" },
11288
+ { property: "max-height", prefix: "max-h", namespace: "spacing" },
11289
+ { property: "grid-template-columns", prefix: "grid-cols", namespace: "grid-template-columns" },
11290
+ { property: "transition-property", prefix: "transition", namespace: "transition-property" },
11265
11291
  { property: "aspect-ratio", prefix: "aspect", namespace: "aspect" },
11266
11292
  { property: "transition-timing-function", prefix: "ease", namespace: "ease" },
11267
11293
  { property: "zoom", prefix: "zoom", namespace: "zoom" },
11268
11294
  { property: "perspective", prefix: "perspective", namespace: "perspective" },
11269
11295
  { property: "animation", prefix: "animate", namespace: "animate" },
11270
- { property: "box-shadow", prefix: "shadow", namespace: "shadow" }
11296
+ { property: "box-shadow", prefix: "shadow", namespace: "shadow" },
11297
+ { property: "text-shadow", prefix: "text-shadow", namespace: "text-shadow" }
11271
11298
  ];
11272
- var SHADOW_THEME_WORKER = String.raw`
11299
+ var THEME_GENERATOR_WORKER = String.raw`
11273
11300
  import { readFileSync } from "node:fs";
11274
11301
  import { compile } from "tailwindcss";
11275
- const values = JSON.parse(readFileSync(0, "utf8"));
11302
+ const probes = JSON.parse(readFileSync(0, "utf8"));
11276
11303
  const results = [];
11277
- for (const value of values) {
11304
+ for (const probe of probes) {
11278
11305
  try {
11279
- const compiler = await compile(["@theme { --shadow-pasika-probe: ", value, "; } @tailwind utilities;"].join(""));
11280
- const css = compiler.build(["shadow-pasika-probe"]);
11281
- const block = css.match(/\.shadow-pasika-probe\s*\{(?<body>[^}]+)\}/u)?.groups?.body ?? "";
11282
- results.push(/--tw-shadow\s*:/u.test(block) && /box-shadow\s*:/u.test(block));
11306
+ const name = probe.prefix + "-pasika-probe";
11307
+ const css = ["@theme { --", probe.namespace, "-pasika-probe: ", probe.value, "; } @tailwind utilities;"].join("");
11308
+ const compiler = await compile(css);
11309
+ const output = compiler.build([name]);
11310
+ const block = output.match(new RegExp("\\." + name + "\\s*\\{(?<body>[^}]+)\\}", "u"))?.groups?.body ?? "";
11311
+ const property = new RegExp("(?:^|[;\\n])\\s*" + probe.property + "\\s*:", "u");
11312
+ const functionName = probe.property === "filter" ? probe.prefix
11313
+ : probe.property === "backdrop-filter" ? probe.prefix.slice("backdrop-".length) : "";
11314
+ const marker = ["box-shadow", "filter", "backdrop-filter"].includes(probe.property) ? "--tw-" + probe.prefix : "";
11315
+ const recognized = property.test(block)
11316
+ && (!marker || block.includes(marker + ":"))
11317
+ && (!functionName || block.includes(functionName + "("));
11318
+ results.push(recognized);
11283
11319
  } catch {
11284
11320
  results.push(false);
11285
11321
  }
11286
11322
  }
11287
11323
  process.stdout.write(JSON.stringify(results));
11288
11324
  `;
11289
- var shadowSupportCache = /* @__PURE__ */ new Map();
11290
- function themeSupportedShadows(values, cwd) {
11291
- const unique = [...new Set(values)];
11292
- const cacheKey = (value) => `${cwd}\0${value}`;
11293
- const missing = unique.filter((value) => !shadowSupportCache.has(cacheKey(value)));
11325
+ var generatorSupportCache = /* @__PURE__ */ new Map();
11326
+ function generatorProbeKey(candidate) {
11327
+ return JSON.stringify([candidate.prefix, candidate.namespace, candidate.property, candidate.value]);
11328
+ }
11329
+ function requiresGeneratorProbe(candidate) {
11330
+ return candidate.probe === true || ["box-shadow", "text-shadow", "filter", "backdrop-filter"].includes(candidate.property);
11331
+ }
11332
+ function themeSupportedGenerators(candidates, cwd) {
11333
+ const unique = new Map(candidates.map((candidate) => [generatorProbeKey(candidate), candidate]));
11334
+ const cacheKey = (key) => `${cwd}\0${key}`;
11335
+ const missing = [...unique].filter(([key]) => !generatorSupportCache.has(cacheKey(key)));
11294
11336
  if (missing.length > 0) {
11295
- const child = spawnSync(process.execPath, ["--input-type=module", "--eval", SHADOW_THEME_WORKER], {
11337
+ const child = spawnSync(process.execPath, ["--input-type=module", "--eval", THEME_GENERATOR_WORKER], {
11296
11338
  cwd,
11297
- input: JSON.stringify(missing),
11339
+ input: JSON.stringify(missing.map(([, candidate]) => candidate)),
11298
11340
  encoding: "utf8",
11299
11341
  timeout: 3e4,
11300
11342
  maxBuffer: 8 * 1024 * 1024,
@@ -11310,21 +11352,105 @@ function themeSupportedShadows(values, cwd) {
11310
11352
  } catch {
11311
11353
  }
11312
11354
  }
11313
- missing.forEach((value, index) => shadowSupportCache.set(cacheKey(value), supported[index] === true));
11355
+ missing.forEach(([key], index) => generatorSupportCache.set(cacheKey(key), supported[index] === true));
11356
+ }
11357
+ return new Set([...unique.keys()].filter((key) => generatorSupportCache.get(cacheKey(key))));
11358
+ }
11359
+ function singleCssFunction(value) {
11360
+ const match = /^(?<name>[a-z][a-z-]*)\(/u.exec(value);
11361
+ if (!match) return void 0;
11362
+ const name = match.groups?.name;
11363
+ if (!name) return void 0;
11364
+ let depth = 0;
11365
+ for (let index = match[0].length - 1; index < value.length; index++) {
11366
+ if (value[index] === "(") depth++;
11367
+ if (value[index] === ")") {
11368
+ depth--;
11369
+ if (depth === 0 && index !== value.length - 1) return void 0;
11370
+ if (depth < 0) return void 0;
11371
+ }
11372
+ }
11373
+ if (depth !== 0 || !value.endsWith(")")) return void 0;
11374
+ const args = value.slice(match[0].length, -1).trim();
11375
+ return args ? { name, args } : void 0;
11376
+ }
11377
+ function boxShadowNamespace(value) {
11378
+ const layers = [];
11379
+ let depth = 0;
11380
+ let start = 0;
11381
+ for (let index = 0; index < value.length; index++) {
11382
+ if (value[index] === "(") depth++;
11383
+ if (value[index] === ")") depth--;
11384
+ if (depth < 0) return void 0;
11385
+ if (value[index] === "," && depth === 0) {
11386
+ layers.push(value.slice(start, index).trim());
11387
+ start = index + 1;
11388
+ }
11389
+ }
11390
+ if (depth !== 0) return void 0;
11391
+ layers.push(value.slice(start).trim());
11392
+ if (layers.some((layer) => !layer)) return void 0;
11393
+ const inset = layers.map((layer) => /(?:^|\s)inset(?:\s|$)/u.test(layer));
11394
+ if (inset.every(Boolean)) return "inset-shadow";
11395
+ if (inset.some(Boolean)) return void 0;
11396
+ return "shadow";
11397
+ }
11398
+ function decodeArbitraryValue(value) {
11399
+ if (/\\|\burl\(/iu.test(value) || /var\(--[^)]*_/iu.test(value)) return void 0;
11400
+ let quote;
11401
+ let decoded = "";
11402
+ for (const character of value) {
11403
+ if (character === '"' || character === "'") {
11404
+ if (!quote) quote = character;
11405
+ else if (quote === character) quote = void 0;
11406
+ decoded += character;
11407
+ } else if (character === "_") {
11408
+ if (quote) return void 0;
11409
+ decoded += " ";
11410
+ } else {
11411
+ decoded += character;
11412
+ }
11314
11413
  }
11315
- return new Set(unique.filter((value) => shadowSupportCache.get(cacheKey(value))));
11414
+ return quote ? void 0 : decoded.trim();
11415
+ }
11416
+ function arbitraryApplyOperation(prefix, value) {
11417
+ if (prefix === "bg") {
11418
+ return /^(?:repeating-)?(?:linear|radial|conic)-gradient\(/u.test(value) ? { property: "background-image", prefix: "bg", namespace: "background-image" } : void 0;
11419
+ }
11420
+ const matched = themeOperations.filter((operation) => operation.prefix === prefix);
11421
+ return matched.length === 1 ? matched[0] : void 0;
11316
11422
  }
11317
11423
  function themeCandidate(name, utilityText) {
11318
11424
  const source = utilityText.trim();
11319
11425
  const arbitrary = /^@utility\s+[\w-]+\s*\{\s*@apply\s+\[(?<property>[a-z-]+):(?<value>[^\]\r\n;{}]+)\];?\s*\}$/u.exec(
11320
11426
  source
11321
11427
  );
11322
- const typed = /^@utility\s+[\w-]+\s*\{\s*@apply\s+(?<kind>[a-z]+)-\((?<hint>[a-z-]+:)?(?<variable>--[a-z][a-z0-9-]*)\);?\s*\}$/u.exec(
11428
+ const arbitraryApply = /^@utility\s+[\w-]+\s*\{\s*@apply\s+(?<prefix>[a-z][a-z0-9-]*)-\[(?<value>[^\]\r\n;{}]+)\];?\s*\}$/u.exec(source);
11429
+ const typed = /^@utility\s+[\w-]+\s*\{\s*@apply\s+(?<kind>[a-z-]+)-\((?<hint>[a-z-]+:)?(?<variable>--[a-z][a-z0-9-]*)\);?\s*\}$/u.exec(
11323
11430
  source
11324
11431
  );
11325
11432
  const direct = /^@utility\s+[\w-]+\s*\{\s*(?<property>[a-z-]+)\s*:\s*(?<value>[^;{}\r\n]+);?\s*\}$/u.exec(source);
11326
- const property = arbitrary?.groups?.property ?? direct?.groups?.property;
11327
- const matched = themeOperations.find((operation) => {
11433
+ const raw = arbitrary?.groups?.value?.trim() ?? direct?.groups?.value?.trim() ?? arbitraryApply?.groups?.value?.trim() ?? (typed?.groups?.variable ? `var(${typed.groups.variable})` : void 0);
11434
+ if (!raw) return void 0;
11435
+ const cssValue = arbitrary || arbitraryApply ? decodeArbitraryValue(raw) : raw;
11436
+ if (!cssValue) return void 0;
11437
+ const namedOperation = arbitraryApply?.groups?.prefix ? arbitraryApplyOperation(arbitraryApply.groups.prefix, cssValue) : void 0;
11438
+ if (arbitraryApply && !namedOperation) return void 0;
11439
+ const property = arbitrary?.groups?.property ?? direct?.groups?.property ?? namedOperation?.property;
11440
+ const functionValue = property === "filter" || property === "backdrop-filter" ? singleCssFunction(cssValue) : void 0;
11441
+ const shadowNamespace = property === "box-shadow" ? boxShadowNamespace(cssValue) : void 0;
11442
+ if (property === "box-shadow" && !shadowNamespace) return void 0;
11443
+ let inferred;
11444
+ if (functionValue && property) {
11445
+ inferred = {
11446
+ property,
11447
+ prefix: property === "filter" ? functionValue.name : `backdrop-${functionValue.name}`,
11448
+ namespace: property === "filter" ? functionValue.name : `backdrop-${functionValue.name}`
11449
+ };
11450
+ } else if (shadowNamespace === "inset-shadow") {
11451
+ inferred = { property: "box-shadow", prefix: "inset-shadow", namespace: "inset-shadow" };
11452
+ }
11453
+ const matched = inferred ?? namedOperation ?? themeOperations.find((operation) => {
11328
11454
  if (property) return property === operation.property;
11329
11455
  if (typed?.groups?.kind !== operation.prefix) return false;
11330
11456
  const hint = typed.groups.hint;
@@ -11332,25 +11458,21 @@ function themeCandidate(name, utilityText) {
11332
11458
  if (operation.prefix === "font") {
11333
11459
  return hint === (operation.property === "font-family" ? "family-name:" : "number:");
11334
11460
  }
11335
- if (operation.prefix === "bg") {
11336
- return hint === (operation.property === "background-image" ? "image:" : "color:");
11337
- }
11461
+ if (operation.prefix === "bg") return hint === (operation.property === "background-image" ? "image:" : "color:");
11338
11462
  if (["border", "outline", "decoration", "stroke"].includes(operation.prefix)) return hint === "color:";
11339
11463
  return hint === void 0;
11340
11464
  });
11341
11465
  if (!matched) return void 0;
11342
- const value = arbitrary?.groups?.value?.trim() ?? direct?.groups?.value?.trim() ?? (typed?.groups?.variable ? `var(${typed.groups.variable})` : void 0);
11343
- if (!value) return void 0;
11344
- if (arbitrary && (/\\|["']|\burl\(/iu.test(value) || /var\(--[^)]*_/iu.test(value))) return void 0;
11345
- const cssValue = arbitrary ? value.replaceAll("_", " ") : value;
11346
- if (matched.property === "font-size" && cssValue.startsWith("-")) return void 0;
11347
- const stem = name.startsWith(`${matched.prefix}-`) ? name.slice(matched.prefix.length + 1) : void 0;
11466
+ const value = functionValue?.args ?? cssValue;
11467
+ if (matched.property === "font-size" && value.startsWith("-")) return void 0;
11468
+ const stem = name.startsWith(`${matched.prefix}-`) && !/-hash-[0-9a-f]{8,}$/u.test(name) ? name.slice(matched.prefix.length + 1) : void 0;
11348
11469
  return {
11349
11470
  token: stem ? `--${matched.namespace}-${stem}` : "",
11350
11471
  property: matched.property,
11351
- value: cssValue,
11472
+ value,
11352
11473
  prefix: matched.prefix,
11353
- namespace: matched.namespace
11474
+ namespace: matched.namespace,
11475
+ probe: Boolean(arbitraryApply) || matched.property === "transition-property"
11354
11476
  };
11355
11477
  }
11356
11478
  var builtInTextSizes = /* @__PURE__ */ new Set([
@@ -11569,15 +11691,12 @@ var utilityMappingRule = {
11569
11691
  }
11570
11692
  return void 0;
11571
11693
  }
11572
- const shadowCandidates = utilities.map(
11694
+ const generatorCandidates = utilities.map(
11573
11695
  (utility) => themeCandidate(preludeIdentifiers(utility)[0] ?? "unknown", context.sourceCode.getText(utility))
11574
- ).filter((candidate) => candidate?.property === "box-shadow");
11696
+ ).filter((candidate) => Boolean(candidate && requiresGeneratorProbe(candidate)));
11575
11697
  const physicalDir = path78.dirname(context.physicalFilename);
11576
11698
  const tailwindCwd = path78.isAbsolute(physicalDir) && existsSync12(physicalDir) ? physicalDir : context.cwd;
11577
- const themeShadows = themeSupportedShadows(
11578
- shadowCandidates.map((candidate) => candidate.value),
11579
- tailwindCwd
11580
- );
11699
+ const themeGenerators = themeSupportedGenerators(generatorCandidates, tailwindCwd);
11581
11700
  for (const utility of utilities) {
11582
11701
  const name = preludeIdentifiers(utility)[0] ?? "unknown";
11583
11702
  const source = context.sourceCode.getText(utility);
@@ -11597,7 +11716,7 @@ var utilityMappingRule = {
11597
11716
  continue;
11598
11717
  }
11599
11718
  const possibleCandidate = themeCandidate(name, source);
11600
- const candidate = possibleCandidate?.property === "box-shadow" && !themeShadows.has(possibleCandidate.value) ? void 0 : possibleCandidate;
11719
+ const candidate = possibleCandidate && requiresGeneratorProbe(possibleCandidate) && !themeGenerators.has(generatorProbeKey(possibleCandidate)) ? void 0 : possibleCandidate;
11601
11720
  const equivalent = candidate ? matchingThemeToken(candidate) : void 0;
11602
11721
  if (candidate && equivalent && nameCounts.get(name) === 1) {
11603
11722
  context.report({
@@ -11606,7 +11725,7 @@ var utilityMappingRule = {
11606
11725
  });
11607
11726
  continue;
11608
11727
  }
11609
- const operationCount = applyOperationCount(utility);
11728
+ const operationCount = applyOperationCount(utility, (apply) => context.sourceCode.getText(apply));
11610
11729
  if (operationCount !== 1) {
11611
11730
  context.report({
11612
11731
  node: utility,
@@ -12056,6 +12175,8 @@ var PREFIX_NAMESPACES = {
12056
12175
  to: ["color"],
12057
12176
  shadow: ["color", "shadow"],
12058
12177
  "inset-shadow": ["inset-shadow"],
12178
+ "grid-cols": ["grid-template-columns"],
12179
+ transition: ["transition-property"],
12059
12180
  rounded: ["radius"],
12060
12181
  font: ["font"],
12061
12182
  tracking: ["tracking"],
@@ -12206,7 +12327,9 @@ var PREFIX_BUILTINS = {
12206
12327
  accent: ["auto"],
12207
12328
  decoration: ["solid", "double", "dotted", "dashed", "wavy", "none"],
12208
12329
  outline: ["none", "hidden", "dashed", "dotted", "double", "solid"],
12209
- font: ["thin", "extralight", "light", "normal", "medium", "semibold", "bold", "extrabold", "black"]
12330
+ font: ["thin", "extralight", "light", "normal", "medium", "semibold", "bold", "extrabold", "black"],
12331
+ "grid-cols": ["none", "subgrid"],
12332
+ transition: ["none", "all", "colors", "opacity", "shadow", "transform", "discrete", "normal"]
12210
12333
  };
12211
12334
  var DEFAULT_TOKENS = {
12212
12335
  text: ["xs", "sm", "base", "lg", "xl", "2xl", "3xl", "4xl", "5xl", "6xl", "7xl", "8xl", "9xl"],
@@ -12457,6 +12580,14 @@ function readInventory(files) {
12457
12580
  namespace = "inset-shadow";
12458
12581
  token = token.slice("shadow-".length);
12459
12582
  }
12583
+ if (namespace === "grid" && token?.startsWith("template-columns-")) {
12584
+ namespace = "grid-template-columns";
12585
+ token = token.slice("template-columns-".length);
12586
+ }
12587
+ if (namespace === "transition" && token?.startsWith("property-")) {
12588
+ namespace = "transition-property";
12589
+ token = token.slice("property-".length);
12590
+ }
12460
12591
  if (!namespace || !token) continue;
12461
12592
  let set = themeTokensByNamespace.get(namespace);
12462
12593
  if (!set) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pasika",
3
- "version": "0.10.127",
3
+ "version": "0.10.129",
4
4
  "description": "Reusable agent setup package",
5
5
  "repository": {
6
6
  "type": "git",