@askrjs/lucide 0.0.5 → 0.0.7

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.
@@ -1 +1 @@
1
- {"version":3,"file":"create-icon.d.ts","names":[],"sources":["../src/create-icon.tsx"],"mappings":";;iBAIgB,WAAW,qBAAqB,UAAU;gBAC7B,+CAAS"}
1
+ {"version":3,"file":"create-icon.d.ts","names":[],"sources":["../src/create-icon.tsx"],"mappings":";;iBA6CgB,WAAW,qBAAqB,UAAU;gBAG7B,+CAAS"}
@@ -1,12 +1,39 @@
1
1
  import { jsx } from "@askrjs/askr/jsx-runtime";
2
2
  import { IconBase } from "@askrjs/askr/foundations/icon";
3
3
  //#region src/create-icon.tsx
4
+ const SAFE_TAGS = /* @__PURE__ */ new Set([
5
+ "circle",
6
+ "ellipse",
7
+ "g",
8
+ "line",
9
+ "path",
10
+ "polygon",
11
+ "polyline",
12
+ "rect"
13
+ ]);
14
+ const URL_ATTRIBUTE = /^(?:href|src|xlink:href)$/i;
15
+ const URL_VALUE = /url\s*\(/i;
16
+ function copyDefinition(iconNode) {
17
+ if (!Array.isArray(iconNode)) throw new TypeError("icon definition must be an array");
18
+ return iconNode.map((entry) => {
19
+ if (!Array.isArray(entry) || entry.length !== 2 || !SAFE_TAGS.has(entry[0])) throw new TypeError("icon definition contains an unsafe SVG element");
20
+ const attributes = entry[1];
21
+ if (!attributes || typeof attributes !== "object" || Array.isArray(attributes)) throw new TypeError("icon definition attributes must be an object");
22
+ const copied = Object.create(null);
23
+ for (const [name, value] of Object.entries(attributes)) {
24
+ if (/^on/i.test(name) || /^(?:__proto__|constructor|prototype)$/i.test(name) || URL_ATTRIBUTE.test(name) || typeof value !== "string" || URL_VALUE.test(value)) throw new TypeError("icon definition contains an unsafe SVG attribute");
25
+ copied[name] = value;
26
+ }
27
+ return [entry[0], Object.freeze(copied)];
28
+ });
29
+ }
4
30
  function createIcon(displayName, iconNode) {
31
+ const definition = Object.freeze(copyDefinition(iconNode));
5
32
  function Icon({ ...rest }) {
6
33
  return IconBase({
7
34
  ...rest,
8
35
  iconName: displayName,
9
- children: iconNode.map(([tag, attrs], i) => jsx(tag, attrs, i))
36
+ children: definition.map(([tag, attrs], i) => jsx(tag, attrs, i))
10
37
  });
11
38
  }
12
39
  Icon.displayName = displayName;
@@ -1 +1 @@
1
- {"version":3,"file":"create-icon.js","names":["createSvgNode"],"sources":["../src/create-icon.tsx"],"sourcesContent":["import { jsx as createSvgNode } from \"@askrjs/askr/jsx-runtime\";\nimport { IconBase } from \"@askrjs/askr/foundations/icon\";\nimport type { IconNode, IconProps } from \"./types\";\n\nexport function createIcon(displayName: string, iconNode: IconNode) {\n function Icon({ ...rest }: IconProps) {\n return IconBase({\n ...rest,\n iconName: displayName,\n children: iconNode.map(([tag, attrs], i) =>\n createSvgNode(tag, attrs as Record<string, unknown>, i),\n ),\n });\n }\n\n Icon.displayName = displayName;\n return Icon;\n}\n"],"mappings":";;;AAIA,SAAgB,WAAW,aAAqB,UAAoB;CAClE,SAAS,KAAK,EAAE,GAAG,QAAmB;EACpC,OAAO,SAAS;GACd,GAAG;GACH,UAAU;GACV,UAAU,SAAS,KAAK,CAAC,KAAK,QAAQ,MACpCA,IAAc,KAAK,OAAkC,CAAC,CACxD;EACF,CAAC;CACH;CAEA,KAAK,cAAc;CACnB,OAAO;AACT"}
1
+ {"version":3,"file":"create-icon.js","names":["createSvgNode"],"sources":["../src/create-icon.tsx"],"sourcesContent":["import { jsx as createSvgNode } from \"@askrjs/askr/jsx-runtime\";\nimport { IconBase } from \"@askrjs/askr/foundations/icon\";\nimport type { IconNode, IconProps } from \"./types\";\n\nconst SAFE_TAGS = new Set([\n \"circle\",\n \"ellipse\",\n \"g\",\n \"line\",\n \"path\",\n \"polygon\",\n \"polyline\",\n \"rect\",\n]);\nconst URL_ATTRIBUTE = /^(?:href|src|xlink:href)$/i;\nconst URL_VALUE = /url\\s*\\(/i;\n\nfunction copyDefinition(iconNode: IconNode): IconNode {\n if (!Array.isArray(iconNode)) throw new TypeError(\"icon definition must be an array\");\n\n return iconNode.map((entry) => {\n if (!Array.isArray(entry) || entry.length !== 2 || !SAFE_TAGS.has(entry[0])) {\n throw new TypeError(\"icon definition contains an unsafe SVG element\");\n }\n const attributes = entry[1];\n if (!attributes || typeof attributes !== \"object\" || Array.isArray(attributes)) {\n throw new TypeError(\"icon definition attributes must be an object\");\n }\n const copied = Object.create(null) as Record<string, string>;\n for (const [name, value] of Object.entries(attributes)) {\n if (\n /^on/i.test(name) ||\n /^(?:__proto__|constructor|prototype)$/i.test(name) ||\n URL_ATTRIBUTE.test(name) ||\n typeof value !== \"string\" ||\n URL_VALUE.test(value)\n ) {\n throw new TypeError(\"icon definition contains an unsafe SVG attribute\");\n }\n copied[name] = value;\n }\n return [entry[0], Object.freeze(copied)] as const;\n });\n}\n\nexport function createIcon(displayName: string, iconNode: IconNode) {\n const definition = Object.freeze(copyDefinition(iconNode));\n\n function Icon({ ...rest }: IconProps) {\n return IconBase({\n ...rest,\n iconName: displayName,\n children: definition.map(([tag, attrs], i) =>\n createSvgNode(tag, attrs as Record<string, unknown>, i),\n ),\n });\n }\n\n Icon.displayName = displayName;\n return Icon;\n}\n"],"mappings":";;;AAIA,MAAM,4BAAY,IAAI,IAAI;CACxB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AACD,MAAM,gBAAgB;AACtB,MAAM,YAAY;AAElB,SAAS,eAAe,UAA8B;CACpD,IAAI,CAAC,MAAM,QAAQ,QAAQ,GAAG,MAAM,IAAI,UAAU,kCAAkC;CAEpF,OAAO,SAAS,KAAK,UAAU;EAC7B,IAAI,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,KAAK,CAAC,UAAU,IAAI,MAAM,EAAE,GACxE,MAAM,IAAI,UAAU,gDAAgD;EAEtE,MAAM,aAAa,MAAM;EACzB,IAAI,CAAC,cAAc,OAAO,eAAe,YAAY,MAAM,QAAQ,UAAU,GAC3E,MAAM,IAAI,UAAU,8CAA8C;EAEpE,MAAM,SAAS,OAAO,OAAO,IAAI;EACjC,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,UAAU,GAAG;GACtD,IACE,OAAO,KAAK,IAAI,KAChB,yCAAyC,KAAK,IAAI,KAClD,cAAc,KAAK,IAAI,KACvB,OAAO,UAAU,YACjB,UAAU,KAAK,KAAK,GAEpB,MAAM,IAAI,UAAU,kDAAkD;GAExE,OAAO,QAAQ;EACjB;EACA,OAAO,CAAC,MAAM,IAAI,OAAO,OAAO,MAAM,CAAC;CACzC,CAAC;AACH;AAEA,SAAgB,WAAW,aAAqB,UAAoB;CAClE,MAAM,aAAa,OAAO,OAAO,eAAe,QAAQ,CAAC;CAEzD,SAAS,KAAK,EAAE,GAAG,QAAmB;EACpC,OAAO,SAAS;GACd,GAAG;GACH,UAAU;GACV,UAAU,WAAW,KAAK,CAAC,KAAK,QAAQ,MACtCA,IAAc,KAAK,OAAkC,CAAC,CACxD;EACF,CAAC;CACH;CAEA,KAAK,cAAc;CACnB,OAAO;AACT"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askrjs/lucide",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "Thin Askr wrappers for the Lucide SVG icon set",
5
5
  "keywords": [
6
6
  "askr",
@@ -53,16 +53,19 @@
53
53
  "lint": "vp lint .",
54
54
  "typecheck": "npm run test:types",
55
55
  "test:publint": "publint",
56
- "pack:check": "npm pack --ignore-scripts --dry-run --json",
57
- "check": "npm run lint && npm run typecheck && npm test && npm run build && npm run test:publint && npm run pack:check",
56
+ "pack:check": "node tests/package-artifacts.js",
57
+ "test:installed": "node tests/installed-smoke.js",
58
+ "check": "npm run lint && npm run typecheck && npm run test:coverage && npm run build && npm run test:installed && npm run test:publint && npm run pack:check",
58
59
  "prepack": "npm run build",
59
60
  "prepublishOnly": "npm run check",
60
61
  "test": "npm run test:unit",
62
+ "test:coverage": "vp test run -c vitest.config.ts --coverage",
61
63
  "test:types": "npm run generate && tsc -p tsconfig.build.json --noEmit",
62
64
  "test:unit": "vp test run -c vitest.config.ts"
63
65
  },
64
66
  "devDependencies": {
65
67
  "@askrjs/askr": ">=0.0.52 <0.1.0",
68
+ "@vitest/coverage-v8": "^4.1.10",
66
69
  "jsdom": "^29.1.1",
67
70
  "lucide": "1.25.0",
68
71
  "publint": "^0.3.21",
@@ -73,6 +76,7 @@
73
76
  "@askrjs/askr": ">=0.0.52 <0.1.0"
74
77
  },
75
78
  "engines": {
76
- "node": ">=20.19.0"
77
- }
79
+ "node": ">=24.0.0"
80
+ },
81
+ "packageManager": "npm@12.0.1"
78
82
  }