From 2ba720e0599d50402d319035d785ceb1df0f37ca Mon Sep 17 00:00:00 2001 From: smontlouis Date: Mon, 17 Aug 2026 18:15:45 +0200 Subject: [PATCH] chore(release): prepare runtime packages 0.1.0 --- .changeset/README.md | 11 + .changeset/config.json | 13 + .github/workflows/release.yml | 50 +++ docs/PUBLISHING.md | 40 ++ package.json | 4 + packages/avatar-core/README.md | 4 +- packages/avatar-core/package.json | 22 +- packages/avatar-react/README.md | 9 +- packages/avatar-react/package.json | 22 +- packages/avatar-web/LICENSE | 10 + packages/avatar-web/README.md | 4 +- packages/avatar-web/package.json | 23 +- pnpm-lock.yaml | 354 ++++++++++++++++-- .../export/__tests__/exporter-test.ts | 23 +- 14 files changed, 548 insertions(+), 41 deletions(-) create mode 100644 .changeset/README.md create mode 100644 .changeset/config.json create mode 100644 .github/workflows/release.yml create mode 100644 docs/PUBLISHING.md create mode 100644 packages/avatar-web/LICENSE diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000..f07625b --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,11 @@ +# Changesets + +Every user-visible package change must include a changeset created with `pnpm changeset`. + +The three runtime packages use one fixed version while the public API stabilizes. Select: + +- `patch` for compatible fixes and documentation corrections; +- `minor` for compatible features and for breaking changes while the version is below `1.0.0`; +- `major` only after the packages have reached `1.0.0`. + +Merging the generated release pull request publishes the versions recorded in that pull request. diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..d9b3c41 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [ + ["@bible-strong/avatar-core", "@bible-strong/avatar-react", "@bible-strong/avatar-web"] + ], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..6c7bf0e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,50 @@ +name: Release + +on: + push: + branches: + - main + +permissions: + contents: write + pull-requests: write + id-token: write + +concurrency: + group: release + cancel-in-progress: false + +jobs: + release: + name: Version or publish packages + runs-on: ubuntu-latest + timeout-minutes: 20 + + steps: + - name: Check out repository + uses: actions/checkout@v6 + + - name: Set up Node.js + uses: actions/setup-node@v6 + with: + node-version: '24.15.0' + registry-url: 'https://registry.npmjs.org' + + - name: Install pnpm + run: npm install --global pnpm@10.34.5 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Validate project + run: pnpm check + + - name: Create release pull request or publish + uses: changesets/action@v1 + with: + publish: pnpm release + version: pnpm version-packages + title: 'chore(release): publish runtime packages' + commit: 'chore(release): publish runtime packages' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/docs/PUBLISHING.md b/docs/PUBLISHING.md new file mode 100644 index 0000000..087a778 --- /dev/null +++ b/docs/PUBLISHING.md @@ -0,0 +1,40 @@ +# Publishing the runtime packages + +The runtime is published as three public npm packages: + +- `@bible-strong/avatar-core` contains the validation, playback and renderer-neutral scene APIs; +- `@bible-strong/avatar-react` depends on core and provides the React 19 integration; +- `@bible-strong/avatar-web` depends on core and provides the direct DOM/ESM integration. + +All three packages keep the same version during the `0.x` stabilization period. Semantic Versioning +is applied as follows: + +- a compatible fix increments the patch version (`0.1.0` to `0.1.1`); +- a compatible feature increments the minor version (`0.1.0` to `0.2.0`); +- a breaking change also increments the minor version while below `1.0.0`; +- after `1.0.0`, a breaking change increments the major version. + +## Normal release flow + +1. Add a changeset to every pull request that changes a published API with `pnpm changeset`. +2. Merge changes into `main`. +3. The release workflow updates or creates a release pull request containing version and changelog + changes. +4. Review and merge that release pull request. +5. The workflow validates, builds and publishes every unpublished version to npm. + +Publication uses npm trusted publishing through GitHub Actions OIDC. It does not require a stored +`NPM_TOKEN`. Each npm package must trust the `release.yml` workflow in the +`smontlouis/bible-strong-avatar-lab` repository. + +## Local verification + +Run the complete project checks and verify real consumer projects against packed tarballs: + +```sh +pnpm check +pnpm packages:smoke +``` + +Do not run `npm publish` from an individual package for routine releases. The initial `0.1.0` +bootstrap publication is the only manual release. diff --git a/package.json b/package.json index 7f59a74..105dbc4 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,9 @@ "format:check": "prettier --check .", "packages:build": "pnpm --filter './packages/*' build", "packages:smoke": "node scripts/smoke-packages.mjs", + "changeset": "changeset", + "version-packages": "changeset version", + "release": "pnpm packages:build && changeset publish", "check": "pnpm engine:check && pnpm format:check && pnpm typecheck && pnpm test && pnpm packages:build && pnpm build" }, "dependencies": { @@ -52,6 +55,7 @@ "devDependencies": { "@babel/core": "^7.29.0", "@babel/parser": "^7.28.6", + "@changesets/cli": "^3.0.0", "@rolldown/plugin-babel": "^0.2.3", "@tailwindcss/vite": "^4.3.3", "@testing-library/react": "^16.3.2", diff --git a/packages/avatar-core/README.md b/packages/avatar-core/README.md index f7108a4..f17f5fc 100644 --- a/packages/avatar-core/README.md +++ b/packages/avatar-core/README.md @@ -76,5 +76,5 @@ Application integrations are kept in separate packages: `@bible-strong/avatar-re React 19, while `@bible-strong/avatar-web` mounts the same definition directly into the DOM. Both depend on this package and use the same playback and scene implementation. -This package is private while copyright ownership, Apache-2.0 relicensing and repository metadata -are confirmed. Local tarballs are for verification only and must not be published. +The package follows Semantic Versioning. While it remains below `1.0.0`, breaking API changes +increment the minor version and fixes increment the patch version. diff --git a/packages/avatar-core/package.json b/packages/avatar-core/package.json index 45bfb70..9974de4 100644 --- a/packages/avatar-core/package.json +++ b/packages/avatar-core/package.json @@ -2,8 +2,24 @@ "name": "@bible-strong/avatar-core", "version": "0.1.0", "description": "Framework-independent runtime for Bible Strong procedural avatars.", + "keywords": [ + "avatar", + "svg", + "animation", + "renderer", + "typescript" + ], + "author": "Stéphane Montlouis-Calixte", "license": "AGPL-3.0-only", - "private": true, + "homepage": "https://github.com/smontlouis/bible-strong-avatar-lab#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/smontlouis/bible-strong-avatar-lab.git", + "directory": "packages/avatar-core" + }, + "bugs": { + "url": "https://github.com/smontlouis/bible-strong-avatar-lab/issues" + }, "type": "module", "sideEffects": false, "files": [ @@ -36,8 +52,12 @@ }, "scripts": { "build": "vite build --config vite.config.ts && tsc -p tsconfig.build.json", + "prepack": "pnpm build", "typecheck": "tsc -p tsconfig.json --noEmit" }, + "publishConfig": { + "access": "public" + }, "dependencies": { "ajv": "^8.20.0" }, diff --git a/packages/avatar-react/README.md b/packages/avatar-react/README.md index 2afd232..52008a5 100644 --- a/packages/avatar-react/README.md +++ b/packages/avatar-react/README.md @@ -9,9 +9,6 @@ dependencies; `@bible-strong/avatar-core` is installed as a normal dependency. pnpm add @bible-strong/avatar-react react react-dom ``` -The packages are currently private. This registry command will work after publication; use the -workspace packages or locally packed tarballs for development verification in the meantime. - Import the package stylesheet once in the application entry point: ```tsx @@ -123,6 +120,6 @@ that reference changes. The stylesheet exposes `.bs-avatar` and `.bs-avatar__svg`. Consumer `className` and `style` are applied to the outer wrapper. -The public component never exposes Studio IDs or document types. This package is private while -copyright ownership, Apache-2.0 relicensing and repository metadata are confirmed. Local tarballs -are for verification only and must not be published. +The public component never exposes Studio IDs or document types. The package follows Semantic +Versioning. While it remains below `1.0.0`, breaking API changes increment the minor version and +fixes increment the patch version. diff --git a/packages/avatar-react/package.json b/packages/avatar-react/package.json index 99168a8..411dada 100644 --- a/packages/avatar-react/package.json +++ b/packages/avatar-react/package.json @@ -2,8 +2,24 @@ "name": "@bible-strong/avatar-react", "version": "0.1.0", "description": "React 19 renderer for Bible Strong procedural avatars.", + "keywords": [ + "avatar", + "svg", + "animation", + "react", + "typescript" + ], + "author": "Stéphane Montlouis-Calixte", "license": "AGPL-3.0-only", - "private": true, + "homepage": "https://github.com/smontlouis/bible-strong-avatar-lab#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/smontlouis/bible-strong-avatar-lab.git", + "directory": "packages/avatar-react" + }, + "bugs": { + "url": "https://github.com/smontlouis/bible-strong-avatar-lab/issues" + }, "type": "module", "sideEffects": [ "**/*.css" @@ -22,8 +38,12 @@ }, "scripts": { "build": "vite build --config vite.config.ts && tsc -p tsconfig.build.json", + "prepack": "pnpm build", "typecheck": "tsc -p tsconfig.json --noEmit" }, + "publishConfig": { + "access": "public" + }, "dependencies": { "@bible-strong/avatar-core": "workspace:^" }, diff --git a/packages/avatar-web/LICENSE b/packages/avatar-web/LICENSE new file mode 100644 index 0000000..804af0b --- /dev/null +++ b/packages/avatar-web/LICENSE @@ -0,0 +1,10 @@ +Copyright (C) 2026 Stéphane Montlouis-Calixte + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU +Affero General Public License as published by the Free Software Foundation, version 3. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Affero General Public License for more details. + +The complete license text is available at . diff --git a/packages/avatar-web/README.md b/packages/avatar-web/README.md index 2556663..94d41d0 100644 --- a/packages/avatar-web/README.md +++ b/packages/avatar-web/README.md @@ -24,5 +24,5 @@ avatar.stop() For a browser project without a bundler, load an ESM build through an import map or CDN and fetch the definition JSON before calling `createAvatar`. -This package is private while copyright ownership, Apache-2.0 relicensing and repository metadata -are confirmed. Local tarballs are for verification only and must not be published. +The package follows Semantic Versioning. While it remains below `1.0.0`, breaking API changes +increment the minor version and fixes increment the patch version. diff --git a/packages/avatar-web/package.json b/packages/avatar-web/package.json index 76a9102..78386ee 100644 --- a/packages/avatar-web/package.json +++ b/packages/avatar-web/package.json @@ -2,8 +2,25 @@ "name": "@bible-strong/avatar-web", "version": "0.1.0", "description": "Framework-independent DOM renderer for Bible Strong procedural avatars.", + "keywords": [ + "avatar", + "svg", + "animation", + "dom", + "esm", + "typescript" + ], + "author": "Stéphane Montlouis-Calixte", "license": "AGPL-3.0-only", - "private": true, + "homepage": "https://github.com/smontlouis/bible-strong-avatar-lab#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/smontlouis/bible-strong-avatar-lab.git", + "directory": "packages/avatar-web" + }, + "bugs": { + "url": "https://github.com/smontlouis/bible-strong-avatar-lab/issues" + }, "type": "module", "sideEffects": false, "files": [ @@ -19,8 +36,12 @@ }, "scripts": { "build": "vite build --config vite.config.ts && tsc -p tsconfig.build.json", + "prepack": "pnpm build", "typecheck": "tsc -p tsconfig.json --noEmit" }, + "publishConfig": { + "access": "public" + }, "dependencies": { "@bible-strong/avatar-core": "workspace:^" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fcf958e..d8eac6e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -57,12 +57,15 @@ importers: '@babel/parser': specifier: ^7.28.6 version: 7.29.8 + '@changesets/cli': + specifier: ^3.0.0 + version: 3.0.0 '@rolldown/plugin-babel': specifier: ^0.2.3 - version: 0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)) + version: 0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)) '@tailwindcss/vite': specifier: ^4.3.3 - version: 4.3.3(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)) + version: 4.3.3(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)) '@testing-library/react': specifier: ^16.3.2 version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -77,7 +80,7 @@ importers: version: 19.2.4(@types/react@19.2.18) '@vitejs/plugin-react': specifier: ^6.0.2 - version: 6.0.5(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)) + version: 6.0.5(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)) babel-plugin-react-compiler: specifier: ^1.0.0 version: 1.0.0 @@ -98,10 +101,10 @@ importers: version: 6.0.3 vite: specifier: ^8.0.13 - version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0) + version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0) vitest: specifier: ^4.1.10 - version: 4.1.10(@types/node@24.13.3)(jsdom@30.0.1)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)) + version: 4.1.10(@types/node@24.13.3)(jsdom@30.0.1)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)) examples/react-vite-consumer: dependencies: @@ -113,7 +116,7 @@ importers: version: link:../../packages/avatar-react '@vitejs/plugin-react': specifier: ^6.0.2 - version: 6.0.5(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)) + version: 6.0.5(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)) react: specifier: 19.2.3 version: 19.2.3 @@ -125,7 +128,7 @@ importers: version: 6.0.3 vite: specifier: ^8.0.13 - version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0) + version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0) devDependencies: '@types/react': specifier: ^19.2.14 @@ -145,7 +148,7 @@ importers: version: 6.0.3 vite: specifier: ^8.0.13 - version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0) + version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0) packages/avatar-core: dependencies: @@ -158,7 +161,7 @@ importers: version: 6.0.3 vite: specifier: ^8.0.13 - version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0) + version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0) packages/avatar-react: dependencies: @@ -183,7 +186,7 @@ importers: version: 6.0.3 vite: specifier: ^8.0.13 - version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0) + version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0) packages/avatar-web: dependencies: @@ -196,7 +199,7 @@ importers: version: 6.0.3 vite: specifier: ^8.0.13 - version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0) + version: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0) packages: @@ -310,6 +313,75 @@ packages: resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} hasBin: true + '@changesets/apply-release-plan@8.0.0': + resolution: {integrity: sha512-kUd2pbf1w5/AYmBMb0Tt+rkIPCjFJdT0SZMrkOjJT/WV/QbtmvkyB5jkV0oaNPheavprZk+SfUiozUti7TIL2w==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/assemble-release-plan@7.0.0': + resolution: {integrity: sha512-oEW8BxdA604kGGtDSCiHr5w9Tv4UWe9I2k61IBNZzCOE1kbYaJj4v+lFQNgcEZFkUc2pV/+hASErGDvpJOZCTg==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/changelog-git@1.0.0': + resolution: {integrity: sha512-3Dst2Ime2Op5nd4XmWJLPIgp11ZFqJqSkVug9izK6TDcIV4YlhPS4ECbEVR+eGI0bk0r1ItogD4j2Oli87bJrA==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/cli@3.0.0': + resolution: {integrity: sha512-V7Gm+GP5OT3mJinMI2YcJD/JyO/a4WChnaMCCzTRhWHgu1zhtsyY7zCjP6n5W6zsgSjJKs+yPmvtREvE0F2g8A==} + engines: {node: ^22.11 || ^24 || >=26, npm: '>=10.9.0', pnpm: '>=10.0.0', yarn: '>=4.5.2'} + hasBin: true + + '@changesets/config@4.0.0': + resolution: {integrity: sha512-mw95/YrkOuhZZxfnVAA4bSXOFUi+KlhzOBTM8C4x777NhUU6HWIl9Z+K+nME+E4PVsv5NQVQwTfiHihAS1A/ow==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/errors@1.0.0': + resolution: {integrity: sha512-ElN/mEzn6zmETgjwf5MclCMa9ef59sAR0lfO8VSYIsiRvbC2FbLB/92EoYw10Sl0kGixxHFiJZUSv7dA+YpR8g==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/format@0.1.2': + resolution: {integrity: sha512-Caez5XtNXCFS/G5bwyav3wuXL0tMxVd2ZGbaumWbzN08tyzO21asCw7JZhNtVsAZDCvDRUzZN+Iit9SyRITSYA==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/get-dependents-graph@3.0.0': + resolution: {integrity: sha512-ji/t5wFA1zREKXRUePE6Qi+Qu2UgxCeSSGQrphezwvQZrp49B7sJ+8+wvM0tA7zPeSxYKCojDy3WWgrl+s+awg==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/git@4.0.0': + resolution: {integrity: sha512-uIEswpPUgzBBqrC0qg13byNaPorzhf05LE2T+gRizEKCXvMsJC6NPJp5iNDSV/gYj4Viqh09UiOF5E7XWeH5lQ==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/parse@1.0.0': + resolution: {integrity: sha512-P0iaMb9p9CRYZiTgAllEIF9AUMQHIy1G72tKlcIqJp61icZSsKQNiOPdxAMZG8m/DvZwt/oz5xEbTpike//dWg==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/pre@3.0.0': + resolution: {integrity: sha512-Zm/6YliV/a2oeWTqHJf6KxLrQwgcK1i/BRDl2m0EKZvbnxV5fG9QRhwJJGshjsZTUTS6dkfURQ2K6aAvgNw/3Q==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/read@1.0.0': + resolution: {integrity: sha512-8TdE2PwG6yArPt5Ozej83Z6iHz1G8BDBKvIEKZ455MccR4K3GNbLR2XqjBxa+5yLFnEd3xAOPXYboBg1pt8stQ==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/should-skip-package@1.0.0': + resolution: {integrity: sha512-pwqoJmbONn1XgXmZXPEExgAaT+HdZLjALFTDgIm+PnS5KeO2nLtzA2/Q+4aMFY14kFMuXKG30MObhvDzWgzDgg==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/types@7.0.0': + resolution: {integrity: sha512-c5GoiQyt3pxiXjrWSNoP8/GRf4kG+VnKzovx1OQM8dYYALlSwgedmkPmJ+ZqGxqwg9D3Bkj85Uo4KLd5BN3A0w==} + engines: {node: ^22.11 || ^24 || >=26} + + '@changesets/write@1.0.0': + resolution: {integrity: sha512-xCK3/4C7Z7muQB/wguE6HcbjtY9iOtaK9orZKE+7xi573cMGD8rLZz7qlo6IvK7s+SIUIKajzj1l+F1QuP97tw==} + engines: {node: ^22.11 || ^24 || >=26} + + '@clack/core@1.4.3': + resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==} + engines: {node: '>= 20.12.0'} + + '@clack/prompts@1.7.0': + resolution: {integrity: sha512-y7/yvZ2TPAnR9+jnc00klvNNLkJiXFFrQA/hlLCcxA9a2A4zQIOimyFQ9XfwYKiGD1fb5GY8vbKIIgO8d5Tb2A==} + engines: {node: '>= 20.12.0'} + '@csstools/color-helpers@6.1.0': resolution: {integrity: sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==} engines: {node: '>=20.19.0'} @@ -386,9 +458,25 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@manypkg/find-root@3.1.0': + resolution: {integrity: sha512-BcSqCyKhBVZ5YkSzOiheMCV41kqAFptW6xGqYSTjkVTl9XQpr+pqHhwgGCOHQtjDCv7Is6EFyA14Sm5GVbVABA==} + engines: {node: '>=20.0.0'} + + '@manypkg/get-packages@3.1.0': + resolution: {integrity: sha512-0TbBVyvPrP7xGYBI/cP8UP+yl/z+HtbTttAD7FMAJgn/kXOTwh5/60TsqP9ZYY710forNfyV0N8P/IE/ujGZJg==} + engines: {node: '>=20.0.0'} + + '@manypkg/tools@2.1.2': + resolution: {integrity: sha512-6QEf6yqFbETdwGITKq57aYoPfX/3K8XFNwsAlx0C1M7o8cb79sv1M3w+tWuWvIcSbNqrLF7OD7YpZMVVz335hQ==} + engines: {node: '>=20.0.0'} + '@oxc-project/types@0.144.0': resolution: {integrity: sha512-nuhZIOLuI6TFQ32I/WnUx+SCPY7SdSKwgnFHydAuoS1+Z4BRcaP+RRJmGzl9lw+0OFF7UmaESf7KQRXaNLHypg==} + '@pnpm/deps.graph-sequencer@1100.0.1': + resolution: {integrity: sha512-pOr5+q1fLYKwFN3LAJuGZEnfXDcQ73zqgDHMtGy+K+uIoUqyY+6MeDCWFwfu+4EFuq76I5EPFofoNAI+Bmmq4A==} + engines: {node: '>=22.13'} + '@rolldown/binding-android-arm64@1.2.4': resolution: {integrity: sha512-jHC2cnyKz5xU2fhECtFl8OZ83cYNt13GZQD+0uMJ/X3o+ijmd56okHhTUwxVSHPx1IRVIJEZ1/1pPzeLCU6XKA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -769,6 +857,10 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + cac@7.0.0: + resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} + engines: {node: '>=20.19.0'} + caniuse-lite@1.0.30001809: resolution: {integrity: sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==} @@ -848,9 +940,18 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-string-truncated-width@3.0.3: + resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} + + fast-string-width@3.0.2: + resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + fast-uri@3.1.5: resolution: {integrity: sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==} + fast-wrap-ansi@0.2.2: + resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -887,6 +988,13 @@ packages: resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + human-id@4.2.0: + resolution: {integrity: sha512-K3GbkIWqyvvlpfhBPlbEvD97TtqBpAYA4kt+cn2lD2x2HuohzZCibcA2nOlnJT6exqvJLggoB5nv2dNf192nEA==} + hasBin: true + + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} @@ -894,6 +1002,9 @@ packages: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true + jju@1.4.0: + resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -919,6 +1030,12 @@ packages: engines: {node: '>=6'} hasBin: true + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + launch-editor@2.14.1: + resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==} + lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} engines: {node: '>= 12.0.0'} @@ -1122,6 +1239,9 @@ packages: resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==} engines: {node: '>=12.20.0'} + package-manager-detector@1.8.0: + resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==} + parse5@8.0.1: resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} @@ -1193,9 +1313,21 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + shell-quote@1.10.0: + resolution: {integrity: sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==} + engines: {node: '>= 0.4'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -1394,6 +1526,11 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} + engines: {node: '>= 14.6'} + hasBin: true + snapshots: '@asamuzakjp/css-color@6.0.7': @@ -1540,6 +1677,122 @@ snapshots: dependencies: css-tree: 3.2.1 + '@changesets/apply-release-plan@8.0.0': + dependencies: + '@changesets/config': 4.0.0 + '@changesets/format': 0.1.2 + '@changesets/git': 4.0.0 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + import-meta-resolve: 4.2.0 + jsonc-parser: 3.3.1 + semver: 7.8.5 + + '@changesets/assemble-release-plan@7.0.0': + dependencies: + '@changesets/errors': 1.0.0 + '@changesets/get-dependents-graph': 3.0.0 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + semver: 7.8.5 + + '@changesets/changelog-git@1.0.0': + dependencies: + '@changesets/types': 7.0.0 + + '@changesets/cli@3.0.0': + dependencies: + '@changesets/apply-release-plan': 8.0.0 + '@changesets/assemble-release-plan': 7.0.0 + '@changesets/changelog-git': 1.0.0 + '@changesets/config': 4.0.0 + '@changesets/errors': 1.0.0 + '@changesets/get-dependents-graph': 3.0.0 + '@changesets/git': 4.0.0 + '@changesets/pre': 3.0.0 + '@changesets/read': 1.0.0 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + '@changesets/write': 1.0.0 + '@clack/prompts': 1.7.0 + '@manypkg/get-packages': 3.1.0 + '@pnpm/deps.graph-sequencer': 1100.0.1 + cac: 7.0.0 + import-meta-resolve: 4.2.0 + launch-editor: 2.14.1 + package-manager-detector: 1.8.0 + semver: 7.8.5 + tinyexec: 1.3.0 + + '@changesets/config@4.0.0': + dependencies: + '@changesets/get-dependents-graph': 3.0.0 + '@changesets/should-skip-package': 1.0.0 + '@changesets/types': 7.0.0 + '@manypkg/get-packages': 3.1.0 + picomatch: 4.0.5 + + '@changesets/errors@1.0.0': {} + + '@changesets/format@0.1.2': + dependencies: + package-manager-detector: 1.8.0 + tinyexec: 1.3.0 + + '@changesets/get-dependents-graph@3.0.0': + dependencies: + '@changesets/types': 7.0.0 + semver: 7.8.5 + + '@changesets/git@4.0.0': + dependencies: + '@changesets/errors': 1.0.0 + '@changesets/types': 7.0.0 + '@manypkg/get-packages': 3.1.0 + picomatch: 4.0.5 + tinyexec: 1.3.0 + + '@changesets/parse@1.0.0': + dependencies: + '@changesets/types': 7.0.0 + yaml: 2.9.0 + + '@changesets/pre@3.0.0': + dependencies: + '@changesets/errors': 1.0.0 + '@changesets/types': 7.0.0 + '@manypkg/get-packages': 3.1.0 + + '@changesets/read@1.0.0': + dependencies: + '@changesets/git': 4.0.0 + '@changesets/parse': 1.0.0 + '@changesets/types': 7.0.0 + + '@changesets/should-skip-package@1.0.0': + dependencies: + '@changesets/types': 7.0.0 + + '@changesets/types@7.0.0': {} + + '@changesets/write@1.0.0': + dependencies: + '@changesets/format': 0.1.2 + '@changesets/types': 7.0.0 + human-id: 4.2.0 + + '@clack/core@1.4.3': + dependencies: + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + + '@clack/prompts@1.7.0': + dependencies: + '@clack/core': 1.4.3 + fast-string-width: 3.0.2 + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + '@csstools/color-helpers@6.1.0': {} '@csstools/css-calc@3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': @@ -1602,8 +1855,25 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@manypkg/find-root@3.1.0': + dependencies: + '@manypkg/tools': 2.1.2 + + '@manypkg/get-packages@3.1.0': + dependencies: + '@manypkg/find-root': 3.1.0 + '@manypkg/tools': 2.1.2 + + '@manypkg/tools@2.1.2': + dependencies: + jju: 1.4.0 + tinyglobby: 0.2.17 + yaml: 2.9.0 + '@oxc-project/types@0.144.0': {} + '@pnpm/deps.graph-sequencer@1100.0.1': {} + '@rolldown/binding-android-arm64@1.2.4': optional: true @@ -1646,14 +1916,14 @@ snapshots: '@rolldown/binding-win32-x64-msvc@1.2.4': optional: true - '@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))': + '@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))': dependencies: '@babel/core': 7.29.7 picomatch: 4.0.5 rolldown: 1.2.4 optionalDependencies: '@babel/runtime': 7.29.7 - vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0) + vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0) '@rolldown/pluginutils@1.0.1': {} @@ -1720,12 +1990,12 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.3.3 '@tailwindcss/oxide-win32-x64-msvc': 4.3.3 - '@tailwindcss/vite@4.3.3(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))': + '@tailwindcss/vite@4.3.3(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))': dependencies: '@tailwindcss/node': 4.3.3 '@tailwindcss/oxide': 4.3.3 tailwindcss: 4.3.3 - vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0) + vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0) '@testing-library/dom@10.4.1': dependencies: @@ -1779,12 +2049,12 @@ snapshots: optionalDependencies: react: 19.2.3 - '@vitejs/plugin-react@6.0.5(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))': + '@vitejs/plugin-react@6.0.5(@rolldown/plugin-babel@0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)))(babel-plugin-react-compiler@1.0.0)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))': dependencies: '@rolldown/pluginutils': 1.0.1 - vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0) + vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0) optionalDependencies: - '@rolldown/plugin-babel': 0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)) + '@rolldown/plugin-babel': 0.2.3(@babel/core@7.29.7)(@babel/runtime@7.29.7)(rolldown@1.2.4)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)) babel-plugin-react-compiler: 1.0.0 '@vitest/expect@4.1.10': @@ -1796,13 +2066,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.1 - '@vitest/mocker@4.1.10(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0))': + '@vitest/mocker@4.1.10(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.10 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0) + vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0) '@vitest/pretty-format@4.1.10': dependencies: @@ -1863,6 +2133,8 @@ snapshots: node-releases: 2.0.53 update-browserslist-db: 1.3.1(browserslist@4.28.8) + cac@7.0.0: {} + caniuse-lite@1.0.30001809: {} chai@6.2.2: {} @@ -1922,8 +2194,18 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-string-truncated-width@3.0.3: {} + + fast-string-width@3.0.2: + dependencies: + fast-string-truncated-width: 3.0.3 + fast-uri@3.1.5: {} + fast-wrap-ansi@0.2.2: + dependencies: + fast-string-width: 3.0.2 + fdir@6.5.0(picomatch@4.0.5): optionalDependencies: picomatch: 4.0.5 @@ -1950,10 +2232,16 @@ snapshots: transitivePeerDependencies: - '@noble/hashes' + human-id@4.2.0: {} + + import-meta-resolve@4.2.0: {} + is-potential-custom-element-name@1.0.1: {} jiti@2.7.0: {} + jju@1.4.0: {} + js-tokens@4.0.0: {} jsdom@30.0.1: @@ -1988,6 +2276,13 @@ snapshots: json5@2.2.3: {} + jsonc-parser@3.3.1: {} + + launch-editor@2.14.1: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.10.0 + lightningcss-android-arm64@1.32.0: optional: true @@ -2126,6 +2421,8 @@ snapshots: obug@2.1.4: {} + package-manager-detector@1.8.0: {} + parse5@8.0.1: dependencies: entities: 8.0.0 @@ -2198,8 +2495,14 @@ snapshots: semver@6.3.1: {} + semver@7.8.5: {} + + shell-quote@1.10.0: {} + siginfo@2.0.0: {} + sisteransi@1.0.5: {} + source-map-js@1.2.1: {} stackback@0.0.2: {} @@ -2257,7 +2560,7 @@ snapshots: dependencies: react: 19.2.3 - vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0): + vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0): dependencies: lightningcss: 1.33.0 picomatch: 4.0.5 @@ -2268,11 +2571,12 @@ snapshots: '@types/node': 24.13.3 fsevents: 2.3.3 jiti: 2.7.0 + yaml: 2.9.0 - vitest@4.1.10(@types/node@24.13.3)(jsdom@30.0.1)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)): + vitest@4.1.10(@types/node@24.13.3)(jsdom@30.0.1)(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)): dependencies: '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)) + '@vitest/mocker': 4.1.10(vite@8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.10 '@vitest/runner': 4.1.10 '@vitest/snapshot': 4.1.10 @@ -2289,7 +2593,7 @@ snapshots: tinyexec: 1.3.0 tinyglobby: 0.2.17 tinyrainbow: 3.1.1 - vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0) + vite: 8.2.1(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.13.3 @@ -2331,3 +2635,5 @@ snapshots: xmlchars@2.2.0: {} yallist@3.1.1: {} + + yaml@2.9.0: {} diff --git a/src/features/export/__tests__/exporter-test.ts b/src/features/export/__tests__/exporter-test.ts index eeaeda4..c64aacb 100644 --- a/src/features/export/__tests__/exporter-test.ts +++ b/src/features/export/__tests__/exporter-test.ts @@ -17,6 +17,24 @@ import { loadStudioDocument } from '@/features/studio/studioDocument' import { initialExpressions } from '@/features/avatar/presets' import { createInitialSequences } from '@/features/animation/sequences' +const storedZipFileNames = (archive: Uint8Array) => { + const names: string[] = [] + const decoder = new TextDecoder() + const view = new DataView(archive.buffer, archive.byteOffset, archive.byteLength) + let offset = 0 + + while (offset + 30 <= archive.byteLength && view.getUint32(offset, true) === 0x04034b50) { + const contentLength = view.getUint32(offset + 18, true) + const nameLength = view.getUint16(offset + 26, true) + const extraLength = view.getUint16(offset + 28, true) + const nameStart = offset + 30 + names.push(decoder.decode(archive.subarray(nameStart, nameStart + nameLength))) + offset = nameStart + nameLength + extraLength + contentLength + } + + return names +} + describe('avatar export', () => { const avatar = createAvatar('Strobi') const animations = createInitialSequences().filter(item => @@ -149,10 +167,7 @@ describe('avatar export', () => { await generateJavaScriptEsmPackage(definition.value, 'Strobi').arrayBuffer() ) const contents = new TextDecoder().decode(archive) - expect(contents).toContain('strobi.avatar.json') - expect(contents).toContain('index.html') - expect(contents).not.toContain('avatar.js') - expect(contents).toContain('README.md') + expect(storedZipFileNames(archive)).toEqual(['strobi.avatar.json', 'index.html', 'README.md']) expect(contents).toContain('esm.sh/@bible-strong/avatar-web@0.1.0') expect(contents).not.toContain('AvatarProceduralEngine') })