openpencil/packages/scene-graph/package.json
Danila Poyarkov 69dba7002f
refactor: define OpenPencil plugin data in one typed registry (#878)
* fix: validate parsed JSON at untrusted boundaries with Valibot

Clipboard HTML, library revisions from shared storage, MCP and automation
WebSocket messages, the MCP discovery file, sidecar output and AI/MCP tool
arguments were JSON.parse'd and cast to their expected types, so a
malformed payload reached the document or crashed paste. They now go
through v.pipe(v.string(), v.parseJson(), Schema), which reports bad JSON
and a wrong shape as the same validation failure.

The path_set tool rejects an invalid VectorNetwork and shares its parser
with create_vector. The CLI library catalog validates its files and runs
revisions through the same size, identity and content-hash checks as the
app; reading image bytes as index-keyed records also stops them coming
back empty. Hand-rolled typeof readers for plugin data, document metadata,
caches and preferences become schemas with their behaviour preserved, and
readCacheJSON takes a schema for its payload.

open-pencil/no-unvalidated-json-parse rejects type assertions on
JSON.parse results other than `as unknown` in src and packages/*/src.

* refactor: validate parsed JSON in tests and tooling

Extend open-pencil/no-unvalidated-json-parse beyond source: tests, helpers and repo tooling now parse JSON through Valibot schemas instead of asserting a type. The shared fixture reader returns a validated object; its old array annotation never matched the fixtures.

* refactor: define OpenPencil plugin data in one typed registry

Every plugin-data key OpenPencil writes is now a field of OPEN_PENCIL_PLUGIN_DATA in scene-graph, with the Valibot schema that reads it; readPluginData and withPluginData replace per-key constants, JSON.parse and hand-matched pluginId/key filters across fig, core, and vue. Moving OkHCL onto it fixes picking a colour rewriting the layer's other plugin data as OkHCL entries.
2026-10-04 17:32:18 +00:00

215 lines
6 KiB
JSON

{
"name": "@open-pencil/scene-graph",
"version": "0.15.1",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/open-pencil/open-pencil.git",
"directory": "packages/scene-graph"
},
"files": [
"dist",
"src",
"README.md"
],
"type": "module",
"sideEffects": false,
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"bun": "./src/index.ts",
"import": "./dist/index.js",
"default": "./dist/index.js"
},
"./arrow-caps": {
"types": "./dist/arrow-caps.d.ts",
"bun": "./src/arrow-caps.ts",
"import": "./dist/arrow-caps.js",
"default": "./dist/arrow-caps.js"
},
"./copy": {
"types": "./dist/copy.d.ts",
"bun": "./src/copy.ts",
"import": "./dist/copy.js",
"default": "./dist/copy.js"
},
"./node-defaults": {
"types": "./dist/node-defaults.d.ts",
"bun": "./src/node-defaults.ts",
"import": "./dist/node-defaults.js",
"default": "./dist/node-defaults.js"
},
"./instances": {
"types": "./dist/instances.d.ts",
"bun": "./src/instances.ts",
"import": "./dist/instances.js",
"default": "./dist/instances.js"
},
"./snap": {
"types": "./dist/snap.d.ts",
"bun": "./src/snap.ts",
"import": "./dist/snap.js",
"default": "./dist/snap.js"
},
"./source-metadata": {
"types": "./dist/source-metadata.d.ts",
"bun": "./src/source-metadata.ts",
"import": "./dist/source-metadata.js",
"default": "./dist/source-metadata.js"
},
"./undo": {
"types": "./dist/undo.d.ts",
"bun": "./src/undo.ts",
"import": "./dist/undo.js",
"default": "./dist/undo.js"
},
"./variant-name": {
"types": "./dist/variant-name.d.ts",
"bun": "./src/variant-name.ts",
"import": "./dist/variant-name.js",
"default": "./dist/variant-name.js"
},
"./variant-properties": {
"types": "./dist/variant-properties.d.ts",
"bun": "./src/variant-properties.ts",
"import": "./dist/variant-properties.js",
"default": "./dist/variant-properties.js"
},
"./vector-network": {
"types": "./dist/vector-network.d.ts",
"bun": "./src/vector-network.ts",
"import": "./dist/vector-network.js",
"default": "./dist/vector-network.js"
},
"./guides": {
"types": "./dist/guides.d.ts",
"bun": "./src/guides.ts",
"import": "./dist/guides.js",
"default": "./dist/guides.js"
},
"./layout-guides": {
"types": "./dist/layout-guides.d.ts",
"bun": "./src/layout-guides.ts",
"import": "./dist/layout-guides.js",
"default": "./dist/layout-guides.js"
},
"./types": {
"types": "./dist/types.d.ts",
"bun": "./src/types.ts",
"import": "./dist/types.js",
"default": "./dist/types.js"
},
"./primitives": {
"types": "./dist/primitives.d.ts",
"bun": "./src/primitives.ts",
"import": "./dist/primitives.js",
"default": "./dist/primitives.js"
},
"./constants": {
"types": "./dist/constants.d.ts",
"bun": "./src/constants.ts",
"import": "./dist/constants.js",
"default": "./dist/constants.js"
},
"./hit-test": {
"types": "./dist/hit-test.d.ts",
"bun": "./src/hit-test.ts",
"import": "./dist/hit-test.js",
"default": "./dist/hit-test.js"
},
"./preview": {
"types": "./dist/preview.d.ts",
"bun": "./src/preview.ts",
"import": "./dist/preview.js",
"default": "./dist/preview.js"
},
"./text-picture": {
"types": "./dist/text-picture.d.ts",
"bun": "./src/text-picture.ts",
"import": "./dist/text-picture.js",
"default": "./dist/text-picture.js"
},
"./variables": {
"types": "./dist/variables.d.ts",
"bun": "./src/variables.ts",
"import": "./dist/variables.js",
"default": "./dist/variables.js"
},
"./images": {
"types": "./dist/images.d.ts",
"bun": "./src/images.ts",
"import": "./dist/images.js",
"default": "./dist/images.js"
},
"./coordinate": {
"types": "./dist/coordinate.d.ts",
"bun": "./src/coordinate.ts",
"import": "./dist/coordinate.js",
"default": "./dist/coordinate.js"
},
"./matrix": {
"types": "./dist/matrix.d.ts",
"bun": "./src/matrix.ts",
"import": "./dist/matrix.js",
"default": "./dist/matrix.js"
},
"./geometry": {
"types": "./dist/geometry.d.ts",
"bun": "./src/geometry.ts",
"import": "./dist/geometry.js",
"default": "./dist/geometry.js"
},
"./resize": {
"types": "./dist/resize.d.ts",
"bun": "./src/resize.ts",
"import": "./dist/resize.js",
"default": "./dist/resize.js"
},
"./parse-path": {
"types": "./dist/parse-path.d.ts",
"bun": "./src/parse-path.ts",
"import": "./dist/parse-path.js",
"default": "./dist/parse-path.js"
},
"./color": {
"types": "./dist/color.d.ts",
"bun": "./src/color/index.ts",
"import": "./dist/color.js",
"default": "./dist/color.js"
},
"./text-direction": {
"types": "./dist/text-direction.d.ts",
"bun": "./src/text-direction.ts",
"import": "./dist/text-direction.js",
"default": "./dist/text-direction.js"
}
},
"publishConfig": {
"access": "public",
"provenance": true
},
"scripts": {
"build": "bunx tsdown --config tsdown.config.ts",
"check": "bun run typecheck && bun run test && bun run build && bun run smoke:dist",
"prepack": "bun run build",
"smoke:dist": "bun scripts/smoke-dist.ts",
"test": "bun test tests",
"typecheck": "bunx tsc --noEmit -p tsconfig.test.json"
},
"dependencies": {
"culori": "^4.0.2",
"es-toolkit": "^1.52.0",
"nanoevents": "^9.1.0",
"svgpath": "^2.6.0",
"valibot": "^1.5.0"
},
"devDependencies": {
"@types/bun": "^1.3.14",
"@types/culori": "^4.0.1",
"tsdown": "^0.22.14",
"typescript": "~5.8.3"
}
}