├── .github └── workflows │ ├── build-and-test.yml │ └── npm-publish.yml ├── .gitignore ├── .npmignore ├── .prettierrc.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── src ├── definitions │ ├── Alias.ts │ ├── GroupProperties.ts │ ├── JSONSignatures.ts │ ├── JSONTokenTree.ts │ ├── TokenSignature.ts │ └── tokenTypes.ts ├── index.ts └── utils │ ├── captureAliasPath.ts │ ├── extractAliasPath.ts │ ├── matchIsAliasValue.ts │ ├── matchIsGroup.ts │ ├── matchIsToken.ts │ └── matchIsTokenTypeName.ts ├── tests ├── definitions │ └── jsonTokenTree.spec.ts ├── tsconfig.json └── utils │ ├── captureAliasPath.spec.ts │ ├── extractAlias.spec.ts │ ├── matchIsAliasValue.spec.ts │ ├── matchIsGroup.spec.ts │ ├── matchIsToken.spec.ts │ └── matchIsTokenTypeName.spec.ts ├── tsconfig.json └── vite.config.ts /.github/workflows/build-and-test.yml: -------------------------------------------------------------------------------- 1 | name: Build and Test 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build-and-test: 11 | runs-on: ubuntu-latest 12 | 13 | strategy: 14 | matrix: 15 | node-version: [20.x, 22.x, 24.x] 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - name: Use Node.js ${{ matrix.node-version }} 21 | uses: actions/setup-node@v4 22 | with: 23 | node-version: ${{ matrix.node-version }} 24 | cache: 'npm' 25 | 26 | - name: Install dependencies 27 | run: npm ci 28 | 29 | - name: Build 30 | run: npm run build 31 | 32 | - name: Run tests 33 | run: npm test -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish Package to NPM 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | version: 7 | description: 'Version to publish (e.g., 1.0.0, patch, minor, major)' 8 | required: true 9 | default: 'patch' 10 | tag: 11 | description: 'NPM tag (e.g., latest, beta, next)' 12 | required: true 13 | default: 'latest' 14 | 15 | jobs: 16 | publish: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v4 20 | with: 21 | # This ensures complete repo history for version management 22 | fetch-depth: 0 23 | 24 | - name: Setup Node.js 25 | uses: actions/setup-node@v4 26 | with: 27 | node-version: '20.x' 28 | registry-url: 'https://registry.npmjs.org' 29 | cache: 'npm' 30 | 31 | - name: Install dependencies 32 | run: npm ci 33 | 34 | - name: Set custom version 35 | id: set-version 36 | run: | 37 | # For semantic versioning keywords (patch, minor, major) 38 | if [[ "${{ github.event.inputs.version }}" =~ ^(patch|minor|major)$ ]]; then 39 | npm version ${{ github.event.inputs.version }} --no-git-tag-version 40 | # For explicit versions (e.g., 1.0.0) 41 | else 42 | npm version ${{ github.event.inputs.version }} --no-git-tag-version --allow-same-version 43 | fi 44 | echo "new_version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT 45 | 46 | - name: Build package 47 | run: npm run build 48 | 49 | - name: Run tests 50 | run: npm test 51 | 52 | - name: Publish to NPM 53 | run: npm publish --tag ${{ github.event.inputs.tag }} 54 | env: 55 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 56 | 57 | - name: Create Git tag 58 | run: | 59 | git config --local user.email "hello@nclsndr.com" 60 | git config --local user.name "nclsndr" 61 | git tag -a v${{ steps.set-version.outputs.new_version }} -m "Release v${{ steps.set-version.outputs.new_version }}" 62 | git push origin v${{ steps.set-version.outputs.new_version }} 63 | env: 64 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | .idea 4 | .vscode 5 | 6 | .env.* 7 | .npmrc 8 | 9 | node_modules 10 | dist 11 | coverage 12 | 13 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .idea 2 | coverage 3 | node_modules 4 | src 5 | tests 6 | 7 | .prettierrc.json 8 | vite.config.ts 9 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true 3 | } 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Design Tokens Format Module 2 | 3 | Thank you for your interest in contributing to the Design Tokens Format Module! This document provides guidelines and instructions to help you get started. 4 | 5 | ## Getting Started 6 | 7 | ### Prerequisites 8 | 9 | - Node.js (preferably the latest LTS version) 10 | - npm 11 | 12 | ### Setup 13 | 14 | 1. Fork the repository on GitHub 15 | 2. Clone your fork locally 16 | ```bash 17 | git clone https://github.com/YOUR-USERNAME/design-tokens-format-module.git 18 | cd design-tokens-format-module 19 | ``` 20 | 3. Add the original repository as an upstream remote 21 | ```bash 22 | git remote add upstream https://github.com/nclsndr/design-tokens-format-module.git 23 | ``` 24 | 4. Install dependencies 25 | ```bash 26 | npm install 27 | ``` 28 | 29 | ## Development Workflow 30 | 31 | 1. Create a new branch for your feature or bugfix 32 | ```bash 33 | git checkout -b feature/your-feature-name 34 | ``` 35 | or 36 | ```bash 37 | git checkout -b fix/issue-you-are-fixing 38 | ``` 39 | 40 | 2. Make your changes and commit them using [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) 41 | 42 | We follow the Conventional Commits specification which provides a standardized format for commit messages: 43 | ``` 44 | ([optional scope]): 45 | 46 | [optional body] 47 | 48 | [optional footer(s)] 49 | ``` 50 | 51 | Common types include: 52 | - `feat`: A new feature 53 | - `fix`: A bug fix 54 | - `docs`: Documentation changes 55 | - `style`: Changes that don't affect the code's meaning (formatting, etc.) 56 | - `refactor`: Code changes that neither fix a bug nor add a feature 57 | - `test`: Adding or correcting tests 58 | - `chore`: Changes to the build process or auxiliary tools 59 | 60 | 3. Keep your branch updated with the upstream main branch 61 | ```bash 62 | git pull upstream main 63 | ``` 64 | 65 | ## Code Style and Formatting 66 | 67 | This project uses Prettier for code formatting. The configuration is defined in `.prettierrc.json`. 68 | 69 | ### Formatting Your Code 70 | 71 | Before submitting a pull request, make sure your code is properly formatted: 72 | 73 | ```bash 74 | # Format all files 75 | npm run format 76 | 77 | # Check formatting without modifying files 78 | npx prettier --check . 79 | ``` 80 | 81 | ## Testing 82 | 83 | The project uses Vitest for testing. Make sure to add tests for any new features or bug fixes. 84 | 85 | ### Running Tests 86 | 87 | ```bash 88 | # Run tests in watch mode during development 89 | npm run test 90 | 91 | # Run tests once (e.g., before submitting a PR) 92 | npm run test -- --run 93 | ``` 94 | 95 | ### Test Coverage 96 | 97 | To generate a test coverage report: 98 | 99 | ```bash 100 | npm run test -- --coverage 101 | ``` 102 | 103 | ## Building 104 | 105 | The project uses TypeScript for type safety and transpilation. 106 | 107 | ### Building the Project 108 | 109 | ```bash 110 | npm run build 111 | ``` 112 | 113 | This command cleans the `dist` directory and rebuilds the project according to the TypeScript configuration. 114 | 115 | ### Type Checking 116 | 117 | To run the TypeScript compiler without emitting files (useful for checking types): 118 | 119 | ```bash 120 | npm run tsc 121 | ``` 122 | 123 | ## Pull Requests 124 | 125 | 1. Push your changes to your fork 126 | ```bash 127 | git push origin your-branch-name 128 | ``` 129 | 130 | 2. Open a pull request against the main repository's `main` branch 131 | 132 | 3. Ensure your PR includes: 133 | - A clear description of the changes 134 | - Any relevant issue numbers (use "#123" to link to issue 123) 135 | - Updated or new tests covering your changes 136 | - Documentation updates if needed 137 | 138 | 4. Before opening a PR, make sure: 139 | - Tests pass: `npm run test -- --run` 140 | - The build succeeds: `npm run build` 141 | - Code is properly formatted: `npm run format` 142 | 143 | ## Code of Conduct 144 | 145 | Please be respectful and considerate of others when contributing to this project. We strive to maintain a welcoming and inclusive environment for everyone. 146 | 147 | ## Questions? 148 | 149 | If you have any questions or need help, feel free to open an issue or reach out to @nclsndr. 150 | 151 | Thank you for contributing to the Design Tokens Format Module! -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Nico Andre 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Design Tokens Format Module 2 | 3 | *— A TypeScript implementation of the [Design Tokens Format Module](https://tr.designtokens.org/format/) specification along with some utility functions* 4 | 5 | ## Abstract 6 | 7 | This packages aims to provide the most agnostic JavaScript/TypeScript definitions from the [Design Tokens Format Module](https://tr.designtokens.org/format/) specification, for library developers and tooling creators. 8 | 9 | Join the conversation on the [W3C Design Tokens Community Group](https://github.com/design-tokens/community-group) repository. 10 | 11 | > ⚠️ Please note, the DTCG specification is NOT stable yet, breaking changes might occur in the future. 12 | 13 | ## Installation 14 | 15 | ### Using npm 16 | 17 | ```bash 18 | npm install design-tokens-format-module 19 | ``` 20 | 21 | ### Using yarn 22 | 23 | ```bash 24 | yarn add design-tokens-format-module 25 | ``` 26 | 27 | ### Using pnpm 28 | 29 | ```bash 30 | pnpm add design-tokens-format-module 31 | ``` 32 | 33 | ## Usage 34 | 35 | This module provides all the type definitions and the most basic helpers required to work with a JSON design token tree. 36 | 37 | ### Token tree 38 | 39 | Constrain a JSON object that represents a design token tree. 40 | 41 | ```typescript 42 | import { JSONTokenTree } from 'design-tokens-format-module'; 43 | 44 | const tokenTree = { 45 | color: { 46 | primary: { 47 | $type: 'color', 48 | $value: { 49 | colorSpace: 'srgb', 50 | components: [1, 0, 1], 51 | alpha: 1, 52 | }, 53 | }, 54 | }, 55 | spacing: { 56 | small: { 57 | $type: 'dimension', 58 | $value: { 59 | value: 8, 60 | unit: 'px', 61 | }, 62 | }, 63 | }, 64 | } satisfies JSONTokenTree; 65 | ``` 66 | 67 | ### Design Token 68 | 69 | Each design token type is available as a TypeScript namespace. 70 | 71 | ```typescript 72 | import { 73 | Color // Dimension, FontFamily... 74 | } from 'design-tokens-format-module'; 75 | 76 | declare function parseColorToken(token: unknown): Color.Token; 77 | declare function parseColorValue(tokens: unknown): Color.Value; 78 | declare function matchIsColorTokenTypeName( 79 | name: string, 80 | ): name is Color.TypeName; 81 | ``` 82 | 83 | #### Design token type names 84 | 85 | All token type names are available as a constant. 86 | 87 | ```typescript 88 | import { tokenTypeNames } from 'design-tokens-format-module'; 89 | 90 | for(const tokenTypeName of tokenTypeNames) { 91 | // color, dimension... 92 | } 93 | ``` 94 | 95 | ### All token types 96 | 97 | All token type signatures are available within a type union. 98 | 99 | ```typescript 100 | import { DesignToken } from 'design-tokens-format-module'; 101 | 102 | declare function parseDesignToken(token: unknown): DesignToken; 103 | ``` 104 | 105 | ### Matchers 106 | 107 | JSON values can be evaluated against the token signature 108 | 109 | ```typescript 110 | import { matchIsToken, matchIsTokenTypeName, matchIsAliasValue } from 'design-tokens-format-module'; 111 | 112 | function validateToken(token: unknown) { 113 | if (matchIsToken(token)) { 114 | const isValidType = matchIsTokenTypeName(token.$type ?? ''); 115 | if(matchIsAliasValue(token.$value)) { 116 | // ... 117 | } 118 | } 119 | // ... 120 | } 121 | ``` 122 | 123 | ### Alias utils 124 | 125 | Alias values can be validated and parsed. 126 | 127 | ```ts 128 | import { captureAliasPath } from 'design-tokens-format-module'; 129 | 130 | const result = captureAliasPath('{path.to.token}'); 131 | 132 | if(result.status === 'ok') { 133 | result.value // string[] 134 | } else { 135 | switch (result.error.tag) { 136 | case 'TYPE_ERROR': { 137 | result.error.message // Expected a string value. Got [x]. 138 | break; 139 | } 140 | case 'FORMAT_ERROR': { 141 | result.error.message // Expected an alias value. Got [x]. 142 | break; 143 | } 144 | } 145 | } 146 | ``` 147 | 148 | ### Enum-like constants 149 | 150 | Some token types have a fixed set of values. These are available as constants. 151 | 152 | ```typescript 153 | import { fontWeightValues, strokeStyleStringValues, strokeStyleLineCapValues } from 'design-tokens-format-module'; 154 | ``` 155 | 156 | ## Previous versions 157 | 158 | The packages goal has shifted from being a generic parser — which requires way more feedback — to a reliable source of truth for the DTCG implementations in the JavaScript land. 159 | 160 | > The features and APIs available before version 0.9.0 has been relocated to a [new location](https://github.com/nclsndr/design-tokens-tools/tree/main/packages/w3c-design-tokens-parser) where they get revamped and improved. 161 | 162 | ## Contributing 163 | 164 | If you find any typos, errors, or additional improvements, feel free to contribute to the project. 165 | 166 | ### Development 167 | 168 | Install dependencies. 169 | 170 | ```bash 171 | npm install 172 | ``` 173 | 174 | Run test in watch mode. 175 | 176 | ```bash 177 | npm run test 178 | ``` 179 | 180 | Please add tests to cover the new functionality or bug fix you are working upon. 181 | 182 | ### Before opening a PR 183 | 184 | We expect the tests and the build to pass for a PR to be reviewed and merged. 185 | 186 | ```bash 187 | npm run test --run 188 | ``` 189 | 190 | ```bash 191 | npm run build 192 | ``` 193 | 194 | ## API 195 | 196 | ### `AliasValue` (type) 197 | 198 | ```ts 199 | type AliasValue = `{${string}}`; 200 | ``` 201 | 202 | ### `Json` (namespace) 203 | 204 | ```ts 205 | namespace Json { 206 | export type Value = JSONValue; 207 | export type Object = JSONObject; 208 | export type Array = JSONArray; 209 | export type Primitive = string | number | boolean | null; 210 | } 211 | ``` 212 | ### JSONTokenTree (type) 213 | 214 | ```ts 215 | type JSONTokenTree = { 216 | [key: string]: DesignToken | JSONTokenTree | GroupProperties; 217 | } & GroupProperties; 218 | ``` 219 | 220 | ### `Color`,`Dimension`, ... (namespace) 221 | 222 | ```ts 223 | namespace TokenTypeName { 224 | export type TypeName = TypeName; 225 | export type Value = Value; 226 | export type Token = Token; 227 | } 228 | ``` 229 | 230 | ### `DesignToken` (type) 231 | 232 | ```ts 233 | type DesignToken = 234 | | ColorToken 235 | | DimensionToken 236 | // | ... 237 | ``` 238 | 239 | ### `TokenTypeName` (type) 240 | 241 | ```ts 242 | type TokenTypeName = 243 | | 'color' 244 | | 'dimension' 245 | // | ... 246 | ``` 247 | 248 | 249 | ### `captureAliasPath` (function) 250 | 251 | ```ts 252 | const CAPTURE_ALIAS_PATH_ERRORS = { 253 | TYPE_ERROR: 'Expected a string value.', 254 | // ... 255 | } as const; 256 | 257 | type ValidationError = { 258 | [k in keyof Writable]?: { 259 | message: string; 260 | }; 261 | }; 262 | 263 | type Result = 264 | | { 265 | status: 'ok'; 266 | value: T; 267 | error?: undefined; 268 | } 269 | | { 270 | status: 'error'; 271 | error: E; 272 | value?: undefined; 273 | }; 274 | 275 | declare function captureAliasPath( 276 | value: unknown, 277 | ): Result, ValidationError>; 278 | declare function captureAliasPath( 279 | value: unknown, 280 | asString: AsString, 281 | ): Result, ValidationError>; 282 | ``` 283 | 284 | Usage 285 | 286 | ```ts 287 | const result = captureAliasPath('{path.to.token}'); 288 | 289 | if(result.status === 'ok') { 290 | result.value // string[] 291 | } else { 292 | switch (result.error.tag) { 293 | case 'TYPE_ERROR': { 294 | result.error.message // Expected a string value. Got [x]. 295 | break; 296 | } 297 | case 'FORMAT_ERROR': { 298 | result.error.message // Expected an alias value. Got [x]. 299 | break; 300 | } 301 | } 302 | } 303 | ``` 304 | 305 | 306 | ### `matchIsAliasValue` (function) 307 | 308 | ```ts 309 | declare function matchIsAliasValue(candidate: unknown): candidate is AliasValue; 310 | ``` 311 | 312 | ### `matchIsGroup` (function) 313 | 314 | ```ts 315 | declare function matchIsGroup(candidate: unknown): candidate is JSONTokenTree; 316 | ``` 317 | 318 | ### `matchIsToken` (function) 319 | 320 | ```ts 321 | declare function matchIsToken(candidate: unknown): candidate is DesignToken; 322 | ``` 323 | 324 | ### `matchIsTokenTypeName` (function) 325 | 326 | ```ts 327 | declare function matchIsTokenTypeName(candidate: unknown): candidate is TokenTypeName; 328 | ``` 329 | 330 | 331 | ### `ALIAS_PATH_SEPARATOR` (constant) 332 | 333 | ```ts 334 | const ALIAS_PATH_SEPARATOR = '.'; 335 | ``` 336 | 337 | ### `tokenTypeNames` (constant) 338 | 339 | ```ts 340 | const tokenTypeNames = [ 341 | 'color', 342 | 'dimension', 343 | // ... 344 | ] as const; 345 | ``` 346 | 347 | ### `fontWeightValues` (constant) 348 | 349 | ```ts 350 | const fontWeightValues = [ 351 | 100, 352 | 'thin', 353 | 'hairline', 354 | // ... 355 | ] as const; 356 | ``` 357 | 358 | ### `strokeStyleStringValues` (constant) 359 | 360 | ```ts 361 | const strokeStyleStringValues = [ 362 | 'solid', 363 | 'dashed', 364 | // ... 365 | ] as const; 366 | ``` 367 | 368 | ### `strokeStyleLineCapValues` (constant) 369 | 370 | ```ts 371 | const strokeStyleLineCapValues = [ 372 | 'round', 373 | 'butt', 374 | // ... 375 | ] as const; 376 | ``` 377 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "design-tokens-format-module", 3 | "version": "0.11.1", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "design-tokens-format-module", 9 | "version": "0.11.1", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "@types/node": "^20.14.10", 13 | "@vitest/coverage-v8": "^2.1.9", 14 | "prettier": "^3.5.3", 15 | "typescript": "^5.8.3", 16 | "vitest": "^2.1.9" 17 | } 18 | }, 19 | "node_modules/@ampproject/remapping": { 20 | "version": "2.3.0", 21 | "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", 22 | "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", 23 | "dev": true, 24 | "license": "Apache-2.0", 25 | "dependencies": { 26 | "@jridgewell/gen-mapping": "^0.3.5", 27 | "@jridgewell/trace-mapping": "^0.3.24" 28 | }, 29 | "engines": { 30 | "node": ">=6.0.0" 31 | } 32 | }, 33 | "node_modules/@babel/helper-string-parser": { 34 | "version": "7.27.1", 35 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", 36 | "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", 37 | "dev": true, 38 | "license": "MIT", 39 | "engines": { 40 | "node": ">=6.9.0" 41 | } 42 | }, 43 | "node_modules/@babel/helper-validator-identifier": { 44 | "version": "7.27.1", 45 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", 46 | "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", 47 | "dev": true, 48 | "license": "MIT", 49 | "engines": { 50 | "node": ">=6.9.0" 51 | } 52 | }, 53 | "node_modules/@babel/parser": { 54 | "version": "7.27.2", 55 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz", 56 | "integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==", 57 | "dev": true, 58 | "license": "MIT", 59 | "dependencies": { 60 | "@babel/types": "^7.27.1" 61 | }, 62 | "bin": { 63 | "parser": "bin/babel-parser.js" 64 | }, 65 | "engines": { 66 | "node": ">=6.0.0" 67 | } 68 | }, 69 | "node_modules/@babel/types": { 70 | "version": "7.27.1", 71 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz", 72 | "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==", 73 | "dev": true, 74 | "license": "MIT", 75 | "dependencies": { 76 | "@babel/helper-string-parser": "^7.27.1", 77 | "@babel/helper-validator-identifier": "^7.27.1" 78 | }, 79 | "engines": { 80 | "node": ">=6.9.0" 81 | } 82 | }, 83 | "node_modules/@bcoe/v8-coverage": { 84 | "version": "0.2.3", 85 | "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", 86 | "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", 87 | "dev": true, 88 | "license": "MIT" 89 | }, 90 | "node_modules/@esbuild/aix-ppc64": { 91 | "version": "0.21.5", 92 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", 93 | "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", 94 | "cpu": [ 95 | "ppc64" 96 | ], 97 | "dev": true, 98 | "license": "MIT", 99 | "optional": true, 100 | "os": [ 101 | "aix" 102 | ], 103 | "engines": { 104 | "node": ">=12" 105 | } 106 | }, 107 | "node_modules/@esbuild/android-arm": { 108 | "version": "0.21.5", 109 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", 110 | "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", 111 | "cpu": [ 112 | "arm" 113 | ], 114 | "dev": true, 115 | "license": "MIT", 116 | "optional": true, 117 | "os": [ 118 | "android" 119 | ], 120 | "engines": { 121 | "node": ">=12" 122 | } 123 | }, 124 | "node_modules/@esbuild/android-arm64": { 125 | "version": "0.21.5", 126 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", 127 | "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", 128 | "cpu": [ 129 | "arm64" 130 | ], 131 | "dev": true, 132 | "license": "MIT", 133 | "optional": true, 134 | "os": [ 135 | "android" 136 | ], 137 | "engines": { 138 | "node": ">=12" 139 | } 140 | }, 141 | "node_modules/@esbuild/android-x64": { 142 | "version": "0.21.5", 143 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", 144 | "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", 145 | "cpu": [ 146 | "x64" 147 | ], 148 | "dev": true, 149 | "license": "MIT", 150 | "optional": true, 151 | "os": [ 152 | "android" 153 | ], 154 | "engines": { 155 | "node": ">=12" 156 | } 157 | }, 158 | "node_modules/@esbuild/darwin-arm64": { 159 | "version": "0.21.5", 160 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", 161 | "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", 162 | "cpu": [ 163 | "arm64" 164 | ], 165 | "dev": true, 166 | "license": "MIT", 167 | "optional": true, 168 | "os": [ 169 | "darwin" 170 | ], 171 | "engines": { 172 | "node": ">=12" 173 | } 174 | }, 175 | "node_modules/@esbuild/darwin-x64": { 176 | "version": "0.21.5", 177 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", 178 | "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", 179 | "cpu": [ 180 | "x64" 181 | ], 182 | "dev": true, 183 | "license": "MIT", 184 | "optional": true, 185 | "os": [ 186 | "darwin" 187 | ], 188 | "engines": { 189 | "node": ">=12" 190 | } 191 | }, 192 | "node_modules/@esbuild/freebsd-arm64": { 193 | "version": "0.21.5", 194 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", 195 | "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", 196 | "cpu": [ 197 | "arm64" 198 | ], 199 | "dev": true, 200 | "license": "MIT", 201 | "optional": true, 202 | "os": [ 203 | "freebsd" 204 | ], 205 | "engines": { 206 | "node": ">=12" 207 | } 208 | }, 209 | "node_modules/@esbuild/freebsd-x64": { 210 | "version": "0.21.5", 211 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", 212 | "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", 213 | "cpu": [ 214 | "x64" 215 | ], 216 | "dev": true, 217 | "license": "MIT", 218 | "optional": true, 219 | "os": [ 220 | "freebsd" 221 | ], 222 | "engines": { 223 | "node": ">=12" 224 | } 225 | }, 226 | "node_modules/@esbuild/linux-arm": { 227 | "version": "0.21.5", 228 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", 229 | "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", 230 | "cpu": [ 231 | "arm" 232 | ], 233 | "dev": true, 234 | "license": "MIT", 235 | "optional": true, 236 | "os": [ 237 | "linux" 238 | ], 239 | "engines": { 240 | "node": ">=12" 241 | } 242 | }, 243 | "node_modules/@esbuild/linux-arm64": { 244 | "version": "0.21.5", 245 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", 246 | "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", 247 | "cpu": [ 248 | "arm64" 249 | ], 250 | "dev": true, 251 | "license": "MIT", 252 | "optional": true, 253 | "os": [ 254 | "linux" 255 | ], 256 | "engines": { 257 | "node": ">=12" 258 | } 259 | }, 260 | "node_modules/@esbuild/linux-ia32": { 261 | "version": "0.21.5", 262 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", 263 | "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", 264 | "cpu": [ 265 | "ia32" 266 | ], 267 | "dev": true, 268 | "license": "MIT", 269 | "optional": true, 270 | "os": [ 271 | "linux" 272 | ], 273 | "engines": { 274 | "node": ">=12" 275 | } 276 | }, 277 | "node_modules/@esbuild/linux-loong64": { 278 | "version": "0.21.5", 279 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", 280 | "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", 281 | "cpu": [ 282 | "loong64" 283 | ], 284 | "dev": true, 285 | "license": "MIT", 286 | "optional": true, 287 | "os": [ 288 | "linux" 289 | ], 290 | "engines": { 291 | "node": ">=12" 292 | } 293 | }, 294 | "node_modules/@esbuild/linux-mips64el": { 295 | "version": "0.21.5", 296 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", 297 | "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", 298 | "cpu": [ 299 | "mips64el" 300 | ], 301 | "dev": true, 302 | "license": "MIT", 303 | "optional": true, 304 | "os": [ 305 | "linux" 306 | ], 307 | "engines": { 308 | "node": ">=12" 309 | } 310 | }, 311 | "node_modules/@esbuild/linux-ppc64": { 312 | "version": "0.21.5", 313 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", 314 | "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", 315 | "cpu": [ 316 | "ppc64" 317 | ], 318 | "dev": true, 319 | "license": "MIT", 320 | "optional": true, 321 | "os": [ 322 | "linux" 323 | ], 324 | "engines": { 325 | "node": ">=12" 326 | } 327 | }, 328 | "node_modules/@esbuild/linux-riscv64": { 329 | "version": "0.21.5", 330 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", 331 | "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", 332 | "cpu": [ 333 | "riscv64" 334 | ], 335 | "dev": true, 336 | "license": "MIT", 337 | "optional": true, 338 | "os": [ 339 | "linux" 340 | ], 341 | "engines": { 342 | "node": ">=12" 343 | } 344 | }, 345 | "node_modules/@esbuild/linux-s390x": { 346 | "version": "0.21.5", 347 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", 348 | "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", 349 | "cpu": [ 350 | "s390x" 351 | ], 352 | "dev": true, 353 | "license": "MIT", 354 | "optional": true, 355 | "os": [ 356 | "linux" 357 | ], 358 | "engines": { 359 | "node": ">=12" 360 | } 361 | }, 362 | "node_modules/@esbuild/linux-x64": { 363 | "version": "0.21.5", 364 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", 365 | "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", 366 | "cpu": [ 367 | "x64" 368 | ], 369 | "dev": true, 370 | "license": "MIT", 371 | "optional": true, 372 | "os": [ 373 | "linux" 374 | ], 375 | "engines": { 376 | "node": ">=12" 377 | } 378 | }, 379 | "node_modules/@esbuild/netbsd-x64": { 380 | "version": "0.21.5", 381 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", 382 | "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", 383 | "cpu": [ 384 | "x64" 385 | ], 386 | "dev": true, 387 | "license": "MIT", 388 | "optional": true, 389 | "os": [ 390 | "netbsd" 391 | ], 392 | "engines": { 393 | "node": ">=12" 394 | } 395 | }, 396 | "node_modules/@esbuild/openbsd-x64": { 397 | "version": "0.21.5", 398 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", 399 | "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", 400 | "cpu": [ 401 | "x64" 402 | ], 403 | "dev": true, 404 | "license": "MIT", 405 | "optional": true, 406 | "os": [ 407 | "openbsd" 408 | ], 409 | "engines": { 410 | "node": ">=12" 411 | } 412 | }, 413 | "node_modules/@esbuild/sunos-x64": { 414 | "version": "0.21.5", 415 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", 416 | "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", 417 | "cpu": [ 418 | "x64" 419 | ], 420 | "dev": true, 421 | "license": "MIT", 422 | "optional": true, 423 | "os": [ 424 | "sunos" 425 | ], 426 | "engines": { 427 | "node": ">=12" 428 | } 429 | }, 430 | "node_modules/@esbuild/win32-arm64": { 431 | "version": "0.21.5", 432 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", 433 | "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", 434 | "cpu": [ 435 | "arm64" 436 | ], 437 | "dev": true, 438 | "license": "MIT", 439 | "optional": true, 440 | "os": [ 441 | "win32" 442 | ], 443 | "engines": { 444 | "node": ">=12" 445 | } 446 | }, 447 | "node_modules/@esbuild/win32-ia32": { 448 | "version": "0.21.5", 449 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", 450 | "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", 451 | "cpu": [ 452 | "ia32" 453 | ], 454 | "dev": true, 455 | "license": "MIT", 456 | "optional": true, 457 | "os": [ 458 | "win32" 459 | ], 460 | "engines": { 461 | "node": ">=12" 462 | } 463 | }, 464 | "node_modules/@esbuild/win32-x64": { 465 | "version": "0.21.5", 466 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", 467 | "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", 468 | "cpu": [ 469 | "x64" 470 | ], 471 | "dev": true, 472 | "license": "MIT", 473 | "optional": true, 474 | "os": [ 475 | "win32" 476 | ], 477 | "engines": { 478 | "node": ">=12" 479 | } 480 | }, 481 | "node_modules/@isaacs/cliui": { 482 | "version": "8.0.2", 483 | "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", 484 | "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", 485 | "dev": true, 486 | "license": "ISC", 487 | "dependencies": { 488 | "string-width": "^5.1.2", 489 | "string-width-cjs": "npm:string-width@^4.2.0", 490 | "strip-ansi": "^7.0.1", 491 | "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", 492 | "wrap-ansi": "^8.1.0", 493 | "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" 494 | }, 495 | "engines": { 496 | "node": ">=12" 497 | } 498 | }, 499 | "node_modules/@istanbuljs/schema": { 500 | "version": "0.1.3", 501 | "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", 502 | "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", 503 | "dev": true, 504 | "license": "MIT", 505 | "engines": { 506 | "node": ">=8" 507 | } 508 | }, 509 | "node_modules/@jridgewell/gen-mapping": { 510 | "version": "0.3.8", 511 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", 512 | "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", 513 | "dev": true, 514 | "license": "MIT", 515 | "dependencies": { 516 | "@jridgewell/set-array": "^1.2.1", 517 | "@jridgewell/sourcemap-codec": "^1.4.10", 518 | "@jridgewell/trace-mapping": "^0.3.24" 519 | }, 520 | "engines": { 521 | "node": ">=6.0.0" 522 | } 523 | }, 524 | "node_modules/@jridgewell/resolve-uri": { 525 | "version": "3.1.2", 526 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 527 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 528 | "dev": true, 529 | "license": "MIT", 530 | "engines": { 531 | "node": ">=6.0.0" 532 | } 533 | }, 534 | "node_modules/@jridgewell/set-array": { 535 | "version": "1.2.1", 536 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", 537 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", 538 | "dev": true, 539 | "license": "MIT", 540 | "engines": { 541 | "node": ">=6.0.0" 542 | } 543 | }, 544 | "node_modules/@jridgewell/sourcemap-codec": { 545 | "version": "1.5.0", 546 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 547 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", 548 | "dev": true, 549 | "license": "MIT" 550 | }, 551 | "node_modules/@jridgewell/trace-mapping": { 552 | "version": "0.3.25", 553 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 554 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 555 | "dev": true, 556 | "license": "MIT", 557 | "dependencies": { 558 | "@jridgewell/resolve-uri": "^3.1.0", 559 | "@jridgewell/sourcemap-codec": "^1.4.14" 560 | } 561 | }, 562 | "node_modules/@pkgjs/parseargs": { 563 | "version": "0.11.0", 564 | "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", 565 | "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", 566 | "dev": true, 567 | "license": "MIT", 568 | "optional": true, 569 | "engines": { 570 | "node": ">=14" 571 | } 572 | }, 573 | "node_modules/@rollup/rollup-android-arm-eabi": { 574 | "version": "4.40.2", 575 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.2.tgz", 576 | "integrity": "sha512-JkdNEq+DFxZfUwxvB58tHMHBHVgX23ew41g1OQinthJ+ryhdRk67O31S7sYw8u2lTjHUPFxwar07BBt1KHp/hg==", 577 | "cpu": [ 578 | "arm" 579 | ], 580 | "dev": true, 581 | "license": "MIT", 582 | "optional": true, 583 | "os": [ 584 | "android" 585 | ] 586 | }, 587 | "node_modules/@rollup/rollup-android-arm64": { 588 | "version": "4.40.2", 589 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.2.tgz", 590 | "integrity": "sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw==", 591 | "cpu": [ 592 | "arm64" 593 | ], 594 | "dev": true, 595 | "license": "MIT", 596 | "optional": true, 597 | "os": [ 598 | "android" 599 | ] 600 | }, 601 | "node_modules/@rollup/rollup-darwin-arm64": { 602 | "version": "4.40.2", 603 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.2.tgz", 604 | "integrity": "sha512-Gzf1Hn2Aoe8VZzevHostPX23U7N5+4D36WJNHK88NZHCJr7aVMG4fadqkIf72eqVPGjGc0HJHNuUaUcxiR+N/w==", 605 | "cpu": [ 606 | "arm64" 607 | ], 608 | "dev": true, 609 | "license": "MIT", 610 | "optional": true, 611 | "os": [ 612 | "darwin" 613 | ] 614 | }, 615 | "node_modules/@rollup/rollup-darwin-x64": { 616 | "version": "4.40.2", 617 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.2.tgz", 618 | "integrity": "sha512-47N4hxa01a4x6XnJoskMKTS8XZ0CZMd8YTbINbi+w03A2w4j1RTlnGHOz/P0+Bg1LaVL6ufZyNprSg+fW5nYQQ==", 619 | "cpu": [ 620 | "x64" 621 | ], 622 | "dev": true, 623 | "license": "MIT", 624 | "optional": true, 625 | "os": [ 626 | "darwin" 627 | ] 628 | }, 629 | "node_modules/@rollup/rollup-freebsd-arm64": { 630 | "version": "4.40.2", 631 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.2.tgz", 632 | "integrity": "sha512-8t6aL4MD+rXSHHZUR1z19+9OFJ2rl1wGKvckN47XFRVO+QL/dUSpKA2SLRo4vMg7ELA8pzGpC+W9OEd1Z/ZqoQ==", 633 | "cpu": [ 634 | "arm64" 635 | ], 636 | "dev": true, 637 | "license": "MIT", 638 | "optional": true, 639 | "os": [ 640 | "freebsd" 641 | ] 642 | }, 643 | "node_modules/@rollup/rollup-freebsd-x64": { 644 | "version": "4.40.2", 645 | "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.2.tgz", 646 | "integrity": "sha512-C+AyHBzfpsOEYRFjztcYUFsH4S7UsE9cDtHCtma5BK8+ydOZYgMmWg1d/4KBytQspJCld8ZIujFMAdKG1xyr4Q==", 647 | "cpu": [ 648 | "x64" 649 | ], 650 | "dev": true, 651 | "license": "MIT", 652 | "optional": true, 653 | "os": [ 654 | "freebsd" 655 | ] 656 | }, 657 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 658 | "version": "4.40.2", 659 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.2.tgz", 660 | "integrity": "sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==", 661 | "cpu": [ 662 | "arm" 663 | ], 664 | "dev": true, 665 | "license": "MIT", 666 | "optional": true, 667 | "os": [ 668 | "linux" 669 | ] 670 | }, 671 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 672 | "version": "4.40.2", 673 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.2.tgz", 674 | "integrity": "sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==", 675 | "cpu": [ 676 | "arm" 677 | ], 678 | "dev": true, 679 | "license": "MIT", 680 | "optional": true, 681 | "os": [ 682 | "linux" 683 | ] 684 | }, 685 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 686 | "version": "4.40.2", 687 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.2.tgz", 688 | "integrity": "sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==", 689 | "cpu": [ 690 | "arm64" 691 | ], 692 | "dev": true, 693 | "license": "MIT", 694 | "optional": true, 695 | "os": [ 696 | "linux" 697 | ] 698 | }, 699 | "node_modules/@rollup/rollup-linux-arm64-musl": { 700 | "version": "4.40.2", 701 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.2.tgz", 702 | "integrity": "sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==", 703 | "cpu": [ 704 | "arm64" 705 | ], 706 | "dev": true, 707 | "license": "MIT", 708 | "optional": true, 709 | "os": [ 710 | "linux" 711 | ] 712 | }, 713 | "node_modules/@rollup/rollup-linux-loongarch64-gnu": { 714 | "version": "4.40.2", 715 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.2.tgz", 716 | "integrity": "sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==", 717 | "cpu": [ 718 | "loong64" 719 | ], 720 | "dev": true, 721 | "license": "MIT", 722 | "optional": true, 723 | "os": [ 724 | "linux" 725 | ] 726 | }, 727 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 728 | "version": "4.40.2", 729 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.2.tgz", 730 | "integrity": "sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==", 731 | "cpu": [ 732 | "ppc64" 733 | ], 734 | "dev": true, 735 | "license": "MIT", 736 | "optional": true, 737 | "os": [ 738 | "linux" 739 | ] 740 | }, 741 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 742 | "version": "4.40.2", 743 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.2.tgz", 744 | "integrity": "sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==", 745 | "cpu": [ 746 | "riscv64" 747 | ], 748 | "dev": true, 749 | "license": "MIT", 750 | "optional": true, 751 | "os": [ 752 | "linux" 753 | ] 754 | }, 755 | "node_modules/@rollup/rollup-linux-riscv64-musl": { 756 | "version": "4.40.2", 757 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.2.tgz", 758 | "integrity": "sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==", 759 | "cpu": [ 760 | "riscv64" 761 | ], 762 | "dev": true, 763 | "license": "MIT", 764 | "optional": true, 765 | "os": [ 766 | "linux" 767 | ] 768 | }, 769 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 770 | "version": "4.40.2", 771 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.2.tgz", 772 | "integrity": "sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==", 773 | "cpu": [ 774 | "s390x" 775 | ], 776 | "dev": true, 777 | "license": "MIT", 778 | "optional": true, 779 | "os": [ 780 | "linux" 781 | ] 782 | }, 783 | "node_modules/@rollup/rollup-linux-x64-gnu": { 784 | "version": "4.40.2", 785 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.2.tgz", 786 | "integrity": "sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==", 787 | "cpu": [ 788 | "x64" 789 | ], 790 | "dev": true, 791 | "license": "MIT", 792 | "optional": true, 793 | "os": [ 794 | "linux" 795 | ] 796 | }, 797 | "node_modules/@rollup/rollup-linux-x64-musl": { 798 | "version": "4.40.2", 799 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.2.tgz", 800 | "integrity": "sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==", 801 | "cpu": [ 802 | "x64" 803 | ], 804 | "dev": true, 805 | "license": "MIT", 806 | "optional": true, 807 | "os": [ 808 | "linux" 809 | ] 810 | }, 811 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 812 | "version": "4.40.2", 813 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.2.tgz", 814 | "integrity": "sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==", 815 | "cpu": [ 816 | "arm64" 817 | ], 818 | "dev": true, 819 | "license": "MIT", 820 | "optional": true, 821 | "os": [ 822 | "win32" 823 | ] 824 | }, 825 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 826 | "version": "4.40.2", 827 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.2.tgz", 828 | "integrity": "sha512-dt1llVSGEsGKvzeIO76HToiYPNPYPkmjhMHhP00T9S4rDern8P2ZWvWAQUEJ+R1UdMWJ/42i/QqJ2WV765GZcA==", 829 | "cpu": [ 830 | "ia32" 831 | ], 832 | "dev": true, 833 | "license": "MIT", 834 | "optional": true, 835 | "os": [ 836 | "win32" 837 | ] 838 | }, 839 | "node_modules/@rollup/rollup-win32-x64-msvc": { 840 | "version": "4.40.2", 841 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.2.tgz", 842 | "integrity": "sha512-bwspbWB04XJpeElvsp+DCylKfF4trJDa2Y9Go8O6A7YLX2LIKGcNK/CYImJN6ZP4DcuOHB4Utl3iCbnR62DudA==", 843 | "cpu": [ 844 | "x64" 845 | ], 846 | "dev": true, 847 | "license": "MIT", 848 | "optional": true, 849 | "os": [ 850 | "win32" 851 | ] 852 | }, 853 | "node_modules/@types/estree": { 854 | "version": "1.0.7", 855 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", 856 | "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", 857 | "dev": true, 858 | "license": "MIT" 859 | }, 860 | "node_modules/@types/node": { 861 | "version": "20.17.46", 862 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.46.tgz", 863 | "integrity": "sha512-0PQHLhZPWOxGW4auogW0eOQAuNIlCYvibIpG67ja0TOJ6/sehu+1en7sfceUn+QQtx4Rk3GxbLNwPh0Cav7TWw==", 864 | "dev": true, 865 | "license": "MIT", 866 | "dependencies": { 867 | "undici-types": "~6.19.2" 868 | } 869 | }, 870 | "node_modules/@vitest/coverage-v8": { 871 | "version": "2.1.9", 872 | "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-2.1.9.tgz", 873 | "integrity": "sha512-Z2cOr0ksM00MpEfyVE8KXIYPEcBFxdbLSs56L8PO0QQMxt/6bDj45uQfxoc96v05KW3clk7vvgP0qfDit9DmfQ==", 874 | "dev": true, 875 | "license": "MIT", 876 | "dependencies": { 877 | "@ampproject/remapping": "^2.3.0", 878 | "@bcoe/v8-coverage": "^0.2.3", 879 | "debug": "^4.3.7", 880 | "istanbul-lib-coverage": "^3.2.2", 881 | "istanbul-lib-report": "^3.0.1", 882 | "istanbul-lib-source-maps": "^5.0.6", 883 | "istanbul-reports": "^3.1.7", 884 | "magic-string": "^0.30.12", 885 | "magicast": "^0.3.5", 886 | "std-env": "^3.8.0", 887 | "test-exclude": "^7.0.1", 888 | "tinyrainbow": "^1.2.0" 889 | }, 890 | "funding": { 891 | "url": "https://opencollective.com/vitest" 892 | }, 893 | "peerDependencies": { 894 | "@vitest/browser": "2.1.9", 895 | "vitest": "2.1.9" 896 | }, 897 | "peerDependenciesMeta": { 898 | "@vitest/browser": { 899 | "optional": true 900 | } 901 | } 902 | }, 903 | "node_modules/@vitest/expect": { 904 | "version": "2.1.9", 905 | "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", 906 | "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", 907 | "dev": true, 908 | "license": "MIT", 909 | "dependencies": { 910 | "@vitest/spy": "2.1.9", 911 | "@vitest/utils": "2.1.9", 912 | "chai": "^5.1.2", 913 | "tinyrainbow": "^1.2.0" 914 | }, 915 | "funding": { 916 | "url": "https://opencollective.com/vitest" 917 | } 918 | }, 919 | "node_modules/@vitest/mocker": { 920 | "version": "2.1.9", 921 | "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", 922 | "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", 923 | "dev": true, 924 | "license": "MIT", 925 | "dependencies": { 926 | "@vitest/spy": "2.1.9", 927 | "estree-walker": "^3.0.3", 928 | "magic-string": "^0.30.12" 929 | }, 930 | "funding": { 931 | "url": "https://opencollective.com/vitest" 932 | }, 933 | "peerDependencies": { 934 | "msw": "^2.4.9", 935 | "vite": "^5.0.0" 936 | }, 937 | "peerDependenciesMeta": { 938 | "msw": { 939 | "optional": true 940 | }, 941 | "vite": { 942 | "optional": true 943 | } 944 | } 945 | }, 946 | "node_modules/@vitest/pretty-format": { 947 | "version": "2.1.9", 948 | "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", 949 | "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", 950 | "dev": true, 951 | "license": "MIT", 952 | "dependencies": { 953 | "tinyrainbow": "^1.2.0" 954 | }, 955 | "funding": { 956 | "url": "https://opencollective.com/vitest" 957 | } 958 | }, 959 | "node_modules/@vitest/runner": { 960 | "version": "2.1.9", 961 | "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", 962 | "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", 963 | "dev": true, 964 | "license": "MIT", 965 | "dependencies": { 966 | "@vitest/utils": "2.1.9", 967 | "pathe": "^1.1.2" 968 | }, 969 | "funding": { 970 | "url": "https://opencollective.com/vitest" 971 | } 972 | }, 973 | "node_modules/@vitest/snapshot": { 974 | "version": "2.1.9", 975 | "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", 976 | "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", 977 | "dev": true, 978 | "license": "MIT", 979 | "dependencies": { 980 | "@vitest/pretty-format": "2.1.9", 981 | "magic-string": "^0.30.12", 982 | "pathe": "^1.1.2" 983 | }, 984 | "funding": { 985 | "url": "https://opencollective.com/vitest" 986 | } 987 | }, 988 | "node_modules/@vitest/spy": { 989 | "version": "2.1.9", 990 | "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", 991 | "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", 992 | "dev": true, 993 | "license": "MIT", 994 | "dependencies": { 995 | "tinyspy": "^3.0.2" 996 | }, 997 | "funding": { 998 | "url": "https://opencollective.com/vitest" 999 | } 1000 | }, 1001 | "node_modules/@vitest/utils": { 1002 | "version": "2.1.9", 1003 | "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", 1004 | "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", 1005 | "dev": true, 1006 | "license": "MIT", 1007 | "dependencies": { 1008 | "@vitest/pretty-format": "2.1.9", 1009 | "loupe": "^3.1.2", 1010 | "tinyrainbow": "^1.2.0" 1011 | }, 1012 | "funding": { 1013 | "url": "https://opencollective.com/vitest" 1014 | } 1015 | }, 1016 | "node_modules/ansi-regex": { 1017 | "version": "6.1.0", 1018 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", 1019 | "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", 1020 | "dev": true, 1021 | "license": "MIT", 1022 | "engines": { 1023 | "node": ">=12" 1024 | }, 1025 | "funding": { 1026 | "url": "https://github.com/chalk/ansi-regex?sponsor=1" 1027 | } 1028 | }, 1029 | "node_modules/ansi-styles": { 1030 | "version": "6.2.1", 1031 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", 1032 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", 1033 | "dev": true, 1034 | "license": "MIT", 1035 | "engines": { 1036 | "node": ">=12" 1037 | }, 1038 | "funding": { 1039 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 1040 | } 1041 | }, 1042 | "node_modules/assertion-error": { 1043 | "version": "2.0.1", 1044 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", 1045 | "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", 1046 | "dev": true, 1047 | "license": "MIT", 1048 | "engines": { 1049 | "node": ">=12" 1050 | } 1051 | }, 1052 | "node_modules/balanced-match": { 1053 | "version": "1.0.2", 1054 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1055 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1056 | "dev": true, 1057 | "license": "MIT" 1058 | }, 1059 | "node_modules/brace-expansion": { 1060 | "version": "2.0.1", 1061 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 1062 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 1063 | "dev": true, 1064 | "license": "MIT", 1065 | "dependencies": { 1066 | "balanced-match": "^1.0.0" 1067 | } 1068 | }, 1069 | "node_modules/cac": { 1070 | "version": "6.7.14", 1071 | "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", 1072 | "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", 1073 | "dev": true, 1074 | "license": "MIT", 1075 | "engines": { 1076 | "node": ">=8" 1077 | } 1078 | }, 1079 | "node_modules/chai": { 1080 | "version": "5.2.0", 1081 | "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz", 1082 | "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==", 1083 | "dev": true, 1084 | "license": "MIT", 1085 | "dependencies": { 1086 | "assertion-error": "^2.0.1", 1087 | "check-error": "^2.1.1", 1088 | "deep-eql": "^5.0.1", 1089 | "loupe": "^3.1.0", 1090 | "pathval": "^2.0.0" 1091 | }, 1092 | "engines": { 1093 | "node": ">=12" 1094 | } 1095 | }, 1096 | "node_modules/check-error": { 1097 | "version": "2.1.1", 1098 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", 1099 | "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", 1100 | "dev": true, 1101 | "license": "MIT", 1102 | "engines": { 1103 | "node": ">= 16" 1104 | } 1105 | }, 1106 | "node_modules/color-convert": { 1107 | "version": "2.0.1", 1108 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 1109 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 1110 | "dev": true, 1111 | "license": "MIT", 1112 | "dependencies": { 1113 | "color-name": "~1.1.4" 1114 | }, 1115 | "engines": { 1116 | "node": ">=7.0.0" 1117 | } 1118 | }, 1119 | "node_modules/color-name": { 1120 | "version": "1.1.4", 1121 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 1122 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 1123 | "dev": true, 1124 | "license": "MIT" 1125 | }, 1126 | "node_modules/cross-spawn": { 1127 | "version": "7.0.6", 1128 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 1129 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 1130 | "dev": true, 1131 | "license": "MIT", 1132 | "dependencies": { 1133 | "path-key": "^3.1.0", 1134 | "shebang-command": "^2.0.0", 1135 | "which": "^2.0.1" 1136 | }, 1137 | "engines": { 1138 | "node": ">= 8" 1139 | } 1140 | }, 1141 | "node_modules/debug": { 1142 | "version": "4.4.0", 1143 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 1144 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 1145 | "dev": true, 1146 | "license": "MIT", 1147 | "dependencies": { 1148 | "ms": "^2.1.3" 1149 | }, 1150 | "engines": { 1151 | "node": ">=6.0" 1152 | }, 1153 | "peerDependenciesMeta": { 1154 | "supports-color": { 1155 | "optional": true 1156 | } 1157 | } 1158 | }, 1159 | "node_modules/deep-eql": { 1160 | "version": "5.0.2", 1161 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", 1162 | "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", 1163 | "dev": true, 1164 | "license": "MIT", 1165 | "engines": { 1166 | "node": ">=6" 1167 | } 1168 | }, 1169 | "node_modules/eastasianwidth": { 1170 | "version": "0.2.0", 1171 | "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", 1172 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", 1173 | "dev": true, 1174 | "license": "MIT" 1175 | }, 1176 | "node_modules/emoji-regex": { 1177 | "version": "9.2.2", 1178 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", 1179 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", 1180 | "dev": true, 1181 | "license": "MIT" 1182 | }, 1183 | "node_modules/es-module-lexer": { 1184 | "version": "1.7.0", 1185 | "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", 1186 | "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", 1187 | "dev": true, 1188 | "license": "MIT" 1189 | }, 1190 | "node_modules/esbuild": { 1191 | "version": "0.21.5", 1192 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", 1193 | "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", 1194 | "dev": true, 1195 | "hasInstallScript": true, 1196 | "license": "MIT", 1197 | "bin": { 1198 | "esbuild": "bin/esbuild" 1199 | }, 1200 | "engines": { 1201 | "node": ">=12" 1202 | }, 1203 | "optionalDependencies": { 1204 | "@esbuild/aix-ppc64": "0.21.5", 1205 | "@esbuild/android-arm": "0.21.5", 1206 | "@esbuild/android-arm64": "0.21.5", 1207 | "@esbuild/android-x64": "0.21.5", 1208 | "@esbuild/darwin-arm64": "0.21.5", 1209 | "@esbuild/darwin-x64": "0.21.5", 1210 | "@esbuild/freebsd-arm64": "0.21.5", 1211 | "@esbuild/freebsd-x64": "0.21.5", 1212 | "@esbuild/linux-arm": "0.21.5", 1213 | "@esbuild/linux-arm64": "0.21.5", 1214 | "@esbuild/linux-ia32": "0.21.5", 1215 | "@esbuild/linux-loong64": "0.21.5", 1216 | "@esbuild/linux-mips64el": "0.21.5", 1217 | "@esbuild/linux-ppc64": "0.21.5", 1218 | "@esbuild/linux-riscv64": "0.21.5", 1219 | "@esbuild/linux-s390x": "0.21.5", 1220 | "@esbuild/linux-x64": "0.21.5", 1221 | "@esbuild/netbsd-x64": "0.21.5", 1222 | "@esbuild/openbsd-x64": "0.21.5", 1223 | "@esbuild/sunos-x64": "0.21.5", 1224 | "@esbuild/win32-arm64": "0.21.5", 1225 | "@esbuild/win32-ia32": "0.21.5", 1226 | "@esbuild/win32-x64": "0.21.5" 1227 | } 1228 | }, 1229 | "node_modules/estree-walker": { 1230 | "version": "3.0.3", 1231 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", 1232 | "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", 1233 | "dev": true, 1234 | "license": "MIT", 1235 | "dependencies": { 1236 | "@types/estree": "^1.0.0" 1237 | } 1238 | }, 1239 | "node_modules/expect-type": { 1240 | "version": "1.2.1", 1241 | "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.1.tgz", 1242 | "integrity": "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==", 1243 | "dev": true, 1244 | "license": "Apache-2.0", 1245 | "engines": { 1246 | "node": ">=12.0.0" 1247 | } 1248 | }, 1249 | "node_modules/foreground-child": { 1250 | "version": "3.3.1", 1251 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", 1252 | "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", 1253 | "dev": true, 1254 | "license": "ISC", 1255 | "dependencies": { 1256 | "cross-spawn": "^7.0.6", 1257 | "signal-exit": "^4.0.1" 1258 | }, 1259 | "engines": { 1260 | "node": ">=14" 1261 | }, 1262 | "funding": { 1263 | "url": "https://github.com/sponsors/isaacs" 1264 | } 1265 | }, 1266 | "node_modules/fsevents": { 1267 | "version": "2.3.3", 1268 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 1269 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 1270 | "dev": true, 1271 | "hasInstallScript": true, 1272 | "license": "MIT", 1273 | "optional": true, 1274 | "os": [ 1275 | "darwin" 1276 | ], 1277 | "engines": { 1278 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 1279 | } 1280 | }, 1281 | "node_modules/glob": { 1282 | "version": "10.4.5", 1283 | "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", 1284 | "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", 1285 | "dev": true, 1286 | "license": "ISC", 1287 | "dependencies": { 1288 | "foreground-child": "^3.1.0", 1289 | "jackspeak": "^3.1.2", 1290 | "minimatch": "^9.0.4", 1291 | "minipass": "^7.1.2", 1292 | "package-json-from-dist": "^1.0.0", 1293 | "path-scurry": "^1.11.1" 1294 | }, 1295 | "bin": { 1296 | "glob": "dist/esm/bin.mjs" 1297 | }, 1298 | "funding": { 1299 | "url": "https://github.com/sponsors/isaacs" 1300 | } 1301 | }, 1302 | "node_modules/has-flag": { 1303 | "version": "4.0.0", 1304 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", 1305 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", 1306 | "dev": true, 1307 | "license": "MIT", 1308 | "engines": { 1309 | "node": ">=8" 1310 | } 1311 | }, 1312 | "node_modules/html-escaper": { 1313 | "version": "2.0.2", 1314 | "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", 1315 | "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", 1316 | "dev": true, 1317 | "license": "MIT" 1318 | }, 1319 | "node_modules/is-fullwidth-code-point": { 1320 | "version": "3.0.0", 1321 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1322 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1323 | "dev": true, 1324 | "license": "MIT", 1325 | "engines": { 1326 | "node": ">=8" 1327 | } 1328 | }, 1329 | "node_modules/isexe": { 1330 | "version": "2.0.0", 1331 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1332 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1333 | "dev": true, 1334 | "license": "ISC" 1335 | }, 1336 | "node_modules/istanbul-lib-coverage": { 1337 | "version": "3.2.2", 1338 | "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", 1339 | "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", 1340 | "dev": true, 1341 | "license": "BSD-3-Clause", 1342 | "engines": { 1343 | "node": ">=8" 1344 | } 1345 | }, 1346 | "node_modules/istanbul-lib-report": { 1347 | "version": "3.0.1", 1348 | "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", 1349 | "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", 1350 | "dev": true, 1351 | "license": "BSD-3-Clause", 1352 | "dependencies": { 1353 | "istanbul-lib-coverage": "^3.0.0", 1354 | "make-dir": "^4.0.0", 1355 | "supports-color": "^7.1.0" 1356 | }, 1357 | "engines": { 1358 | "node": ">=10" 1359 | } 1360 | }, 1361 | "node_modules/istanbul-lib-source-maps": { 1362 | "version": "5.0.6", 1363 | "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", 1364 | "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", 1365 | "dev": true, 1366 | "license": "BSD-3-Clause", 1367 | "dependencies": { 1368 | "@jridgewell/trace-mapping": "^0.3.23", 1369 | "debug": "^4.1.1", 1370 | "istanbul-lib-coverage": "^3.0.0" 1371 | }, 1372 | "engines": { 1373 | "node": ">=10" 1374 | } 1375 | }, 1376 | "node_modules/istanbul-reports": { 1377 | "version": "3.1.7", 1378 | "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", 1379 | "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", 1380 | "dev": true, 1381 | "license": "BSD-3-Clause", 1382 | "dependencies": { 1383 | "html-escaper": "^2.0.0", 1384 | "istanbul-lib-report": "^3.0.0" 1385 | }, 1386 | "engines": { 1387 | "node": ">=8" 1388 | } 1389 | }, 1390 | "node_modules/jackspeak": { 1391 | "version": "3.4.3", 1392 | "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", 1393 | "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", 1394 | "dev": true, 1395 | "license": "BlueOak-1.0.0", 1396 | "dependencies": { 1397 | "@isaacs/cliui": "^8.0.2" 1398 | }, 1399 | "funding": { 1400 | "url": "https://github.com/sponsors/isaacs" 1401 | }, 1402 | "optionalDependencies": { 1403 | "@pkgjs/parseargs": "^0.11.0" 1404 | } 1405 | }, 1406 | "node_modules/loupe": { 1407 | "version": "3.1.3", 1408 | "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz", 1409 | "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==", 1410 | "dev": true, 1411 | "license": "MIT" 1412 | }, 1413 | "node_modules/lru-cache": { 1414 | "version": "10.4.3", 1415 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", 1416 | "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", 1417 | "dev": true, 1418 | "license": "ISC" 1419 | }, 1420 | "node_modules/magic-string": { 1421 | "version": "0.30.17", 1422 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", 1423 | "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", 1424 | "dev": true, 1425 | "license": "MIT", 1426 | "dependencies": { 1427 | "@jridgewell/sourcemap-codec": "^1.5.0" 1428 | } 1429 | }, 1430 | "node_modules/magicast": { 1431 | "version": "0.3.5", 1432 | "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", 1433 | "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", 1434 | "dev": true, 1435 | "license": "MIT", 1436 | "dependencies": { 1437 | "@babel/parser": "^7.25.4", 1438 | "@babel/types": "^7.25.4", 1439 | "source-map-js": "^1.2.0" 1440 | } 1441 | }, 1442 | "node_modules/make-dir": { 1443 | "version": "4.0.0", 1444 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", 1445 | "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", 1446 | "dev": true, 1447 | "license": "MIT", 1448 | "dependencies": { 1449 | "semver": "^7.5.3" 1450 | }, 1451 | "engines": { 1452 | "node": ">=10" 1453 | }, 1454 | "funding": { 1455 | "url": "https://github.com/sponsors/sindresorhus" 1456 | } 1457 | }, 1458 | "node_modules/minimatch": { 1459 | "version": "9.0.5", 1460 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 1461 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 1462 | "dev": true, 1463 | "license": "ISC", 1464 | "dependencies": { 1465 | "brace-expansion": "^2.0.1" 1466 | }, 1467 | "engines": { 1468 | "node": ">=16 || 14 >=14.17" 1469 | }, 1470 | "funding": { 1471 | "url": "https://github.com/sponsors/isaacs" 1472 | } 1473 | }, 1474 | "node_modules/minipass": { 1475 | "version": "7.1.2", 1476 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", 1477 | "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", 1478 | "dev": true, 1479 | "license": "ISC", 1480 | "engines": { 1481 | "node": ">=16 || 14 >=14.17" 1482 | } 1483 | }, 1484 | "node_modules/ms": { 1485 | "version": "2.1.3", 1486 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1487 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1488 | "dev": true, 1489 | "license": "MIT" 1490 | }, 1491 | "node_modules/nanoid": { 1492 | "version": "3.3.11", 1493 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", 1494 | "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", 1495 | "dev": true, 1496 | "funding": [ 1497 | { 1498 | "type": "github", 1499 | "url": "https://github.com/sponsors/ai" 1500 | } 1501 | ], 1502 | "license": "MIT", 1503 | "bin": { 1504 | "nanoid": "bin/nanoid.cjs" 1505 | }, 1506 | "engines": { 1507 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 1508 | } 1509 | }, 1510 | "node_modules/package-json-from-dist": { 1511 | "version": "1.0.1", 1512 | "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", 1513 | "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", 1514 | "dev": true, 1515 | "license": "BlueOak-1.0.0" 1516 | }, 1517 | "node_modules/path-key": { 1518 | "version": "3.1.1", 1519 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1520 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1521 | "dev": true, 1522 | "license": "MIT", 1523 | "engines": { 1524 | "node": ">=8" 1525 | } 1526 | }, 1527 | "node_modules/path-scurry": { 1528 | "version": "1.11.1", 1529 | "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", 1530 | "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", 1531 | "dev": true, 1532 | "license": "BlueOak-1.0.0", 1533 | "dependencies": { 1534 | "lru-cache": "^10.2.0", 1535 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" 1536 | }, 1537 | "engines": { 1538 | "node": ">=16 || 14 >=14.18" 1539 | }, 1540 | "funding": { 1541 | "url": "https://github.com/sponsors/isaacs" 1542 | } 1543 | }, 1544 | "node_modules/pathe": { 1545 | "version": "1.1.2", 1546 | "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", 1547 | "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", 1548 | "dev": true, 1549 | "license": "MIT" 1550 | }, 1551 | "node_modules/pathval": { 1552 | "version": "2.0.0", 1553 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", 1554 | "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", 1555 | "dev": true, 1556 | "license": "MIT", 1557 | "engines": { 1558 | "node": ">= 14.16" 1559 | } 1560 | }, 1561 | "node_modules/picocolors": { 1562 | "version": "1.1.1", 1563 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", 1564 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", 1565 | "dev": true, 1566 | "license": "ISC" 1567 | }, 1568 | "node_modules/postcss": { 1569 | "version": "8.5.3", 1570 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", 1571 | "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", 1572 | "dev": true, 1573 | "funding": [ 1574 | { 1575 | "type": "opencollective", 1576 | "url": "https://opencollective.com/postcss/" 1577 | }, 1578 | { 1579 | "type": "tidelift", 1580 | "url": "https://tidelift.com/funding/github/npm/postcss" 1581 | }, 1582 | { 1583 | "type": "github", 1584 | "url": "https://github.com/sponsors/ai" 1585 | } 1586 | ], 1587 | "license": "MIT", 1588 | "dependencies": { 1589 | "nanoid": "^3.3.8", 1590 | "picocolors": "^1.1.1", 1591 | "source-map-js": "^1.2.1" 1592 | }, 1593 | "engines": { 1594 | "node": "^10 || ^12 || >=14" 1595 | } 1596 | }, 1597 | "node_modules/prettier": { 1598 | "version": "3.5.3", 1599 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", 1600 | "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", 1601 | "dev": true, 1602 | "license": "MIT", 1603 | "bin": { 1604 | "prettier": "bin/prettier.cjs" 1605 | }, 1606 | "engines": { 1607 | "node": ">=14" 1608 | }, 1609 | "funding": { 1610 | "url": "https://github.com/prettier/prettier?sponsor=1" 1611 | } 1612 | }, 1613 | "node_modules/rollup": { 1614 | "version": "4.40.2", 1615 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.2.tgz", 1616 | "integrity": "sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==", 1617 | "dev": true, 1618 | "license": "MIT", 1619 | "dependencies": { 1620 | "@types/estree": "1.0.7" 1621 | }, 1622 | "bin": { 1623 | "rollup": "dist/bin/rollup" 1624 | }, 1625 | "engines": { 1626 | "node": ">=18.0.0", 1627 | "npm": ">=8.0.0" 1628 | }, 1629 | "optionalDependencies": { 1630 | "@rollup/rollup-android-arm-eabi": "4.40.2", 1631 | "@rollup/rollup-android-arm64": "4.40.2", 1632 | "@rollup/rollup-darwin-arm64": "4.40.2", 1633 | "@rollup/rollup-darwin-x64": "4.40.2", 1634 | "@rollup/rollup-freebsd-arm64": "4.40.2", 1635 | "@rollup/rollup-freebsd-x64": "4.40.2", 1636 | "@rollup/rollup-linux-arm-gnueabihf": "4.40.2", 1637 | "@rollup/rollup-linux-arm-musleabihf": "4.40.2", 1638 | "@rollup/rollup-linux-arm64-gnu": "4.40.2", 1639 | "@rollup/rollup-linux-arm64-musl": "4.40.2", 1640 | "@rollup/rollup-linux-loongarch64-gnu": "4.40.2", 1641 | "@rollup/rollup-linux-powerpc64le-gnu": "4.40.2", 1642 | "@rollup/rollup-linux-riscv64-gnu": "4.40.2", 1643 | "@rollup/rollup-linux-riscv64-musl": "4.40.2", 1644 | "@rollup/rollup-linux-s390x-gnu": "4.40.2", 1645 | "@rollup/rollup-linux-x64-gnu": "4.40.2", 1646 | "@rollup/rollup-linux-x64-musl": "4.40.2", 1647 | "@rollup/rollup-win32-arm64-msvc": "4.40.2", 1648 | "@rollup/rollup-win32-ia32-msvc": "4.40.2", 1649 | "@rollup/rollup-win32-x64-msvc": "4.40.2", 1650 | "fsevents": "~2.3.2" 1651 | } 1652 | }, 1653 | "node_modules/semver": { 1654 | "version": "7.7.2", 1655 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", 1656 | "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", 1657 | "dev": true, 1658 | "license": "ISC", 1659 | "bin": { 1660 | "semver": "bin/semver.js" 1661 | }, 1662 | "engines": { 1663 | "node": ">=10" 1664 | } 1665 | }, 1666 | "node_modules/shebang-command": { 1667 | "version": "2.0.0", 1668 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1669 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1670 | "dev": true, 1671 | "license": "MIT", 1672 | "dependencies": { 1673 | "shebang-regex": "^3.0.0" 1674 | }, 1675 | "engines": { 1676 | "node": ">=8" 1677 | } 1678 | }, 1679 | "node_modules/shebang-regex": { 1680 | "version": "3.0.0", 1681 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1682 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1683 | "dev": true, 1684 | "license": "MIT", 1685 | "engines": { 1686 | "node": ">=8" 1687 | } 1688 | }, 1689 | "node_modules/siginfo": { 1690 | "version": "2.0.0", 1691 | "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", 1692 | "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", 1693 | "dev": true, 1694 | "license": "ISC" 1695 | }, 1696 | "node_modules/signal-exit": { 1697 | "version": "4.1.0", 1698 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", 1699 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", 1700 | "dev": true, 1701 | "license": "ISC", 1702 | "engines": { 1703 | "node": ">=14" 1704 | }, 1705 | "funding": { 1706 | "url": "https://github.com/sponsors/isaacs" 1707 | } 1708 | }, 1709 | "node_modules/source-map-js": { 1710 | "version": "1.2.1", 1711 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", 1712 | "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", 1713 | "dev": true, 1714 | "license": "BSD-3-Clause", 1715 | "engines": { 1716 | "node": ">=0.10.0" 1717 | } 1718 | }, 1719 | "node_modules/stackback": { 1720 | "version": "0.0.2", 1721 | "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", 1722 | "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", 1723 | "dev": true, 1724 | "license": "MIT" 1725 | }, 1726 | "node_modules/std-env": { 1727 | "version": "3.9.0", 1728 | "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", 1729 | "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", 1730 | "dev": true, 1731 | "license": "MIT" 1732 | }, 1733 | "node_modules/string-width": { 1734 | "version": "5.1.2", 1735 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", 1736 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", 1737 | "dev": true, 1738 | "license": "MIT", 1739 | "dependencies": { 1740 | "eastasianwidth": "^0.2.0", 1741 | "emoji-regex": "^9.2.2", 1742 | "strip-ansi": "^7.0.1" 1743 | }, 1744 | "engines": { 1745 | "node": ">=12" 1746 | }, 1747 | "funding": { 1748 | "url": "https://github.com/sponsors/sindresorhus" 1749 | } 1750 | }, 1751 | "node_modules/string-width-cjs": { 1752 | "name": "string-width", 1753 | "version": "4.2.3", 1754 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 1755 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 1756 | "dev": true, 1757 | "license": "MIT", 1758 | "dependencies": { 1759 | "emoji-regex": "^8.0.0", 1760 | "is-fullwidth-code-point": "^3.0.0", 1761 | "strip-ansi": "^6.0.1" 1762 | }, 1763 | "engines": { 1764 | "node": ">=8" 1765 | } 1766 | }, 1767 | "node_modules/string-width-cjs/node_modules/ansi-regex": { 1768 | "version": "5.0.1", 1769 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1770 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1771 | "dev": true, 1772 | "license": "MIT", 1773 | "engines": { 1774 | "node": ">=8" 1775 | } 1776 | }, 1777 | "node_modules/string-width-cjs/node_modules/emoji-regex": { 1778 | "version": "8.0.0", 1779 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 1780 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 1781 | "dev": true, 1782 | "license": "MIT" 1783 | }, 1784 | "node_modules/string-width-cjs/node_modules/strip-ansi": { 1785 | "version": "6.0.1", 1786 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1787 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1788 | "dev": true, 1789 | "license": "MIT", 1790 | "dependencies": { 1791 | "ansi-regex": "^5.0.1" 1792 | }, 1793 | "engines": { 1794 | "node": ">=8" 1795 | } 1796 | }, 1797 | "node_modules/strip-ansi": { 1798 | "version": "7.1.0", 1799 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", 1800 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", 1801 | "dev": true, 1802 | "license": "MIT", 1803 | "dependencies": { 1804 | "ansi-regex": "^6.0.1" 1805 | }, 1806 | "engines": { 1807 | "node": ">=12" 1808 | }, 1809 | "funding": { 1810 | "url": "https://github.com/chalk/strip-ansi?sponsor=1" 1811 | } 1812 | }, 1813 | "node_modules/strip-ansi-cjs": { 1814 | "name": "strip-ansi", 1815 | "version": "6.0.1", 1816 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 1817 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 1818 | "dev": true, 1819 | "license": "MIT", 1820 | "dependencies": { 1821 | "ansi-regex": "^5.0.1" 1822 | }, 1823 | "engines": { 1824 | "node": ">=8" 1825 | } 1826 | }, 1827 | "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { 1828 | "version": "5.0.1", 1829 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 1830 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 1831 | "dev": true, 1832 | "license": "MIT", 1833 | "engines": { 1834 | "node": ">=8" 1835 | } 1836 | }, 1837 | "node_modules/supports-color": { 1838 | "version": "7.2.0", 1839 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", 1840 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", 1841 | "dev": true, 1842 | "license": "MIT", 1843 | "dependencies": { 1844 | "has-flag": "^4.0.0" 1845 | }, 1846 | "engines": { 1847 | "node": ">=8" 1848 | } 1849 | }, 1850 | "node_modules/test-exclude": { 1851 | "version": "7.0.1", 1852 | "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", 1853 | "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", 1854 | "dev": true, 1855 | "license": "ISC", 1856 | "dependencies": { 1857 | "@istanbuljs/schema": "^0.1.2", 1858 | "glob": "^10.4.1", 1859 | "minimatch": "^9.0.4" 1860 | }, 1861 | "engines": { 1862 | "node": ">=18" 1863 | } 1864 | }, 1865 | "node_modules/tinybench": { 1866 | "version": "2.9.0", 1867 | "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", 1868 | "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", 1869 | "dev": true, 1870 | "license": "MIT" 1871 | }, 1872 | "node_modules/tinyexec": { 1873 | "version": "0.3.2", 1874 | "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", 1875 | "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", 1876 | "dev": true, 1877 | "license": "MIT" 1878 | }, 1879 | "node_modules/tinypool": { 1880 | "version": "1.0.2", 1881 | "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz", 1882 | "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==", 1883 | "dev": true, 1884 | "license": "MIT", 1885 | "engines": { 1886 | "node": "^18.0.0 || >=20.0.0" 1887 | } 1888 | }, 1889 | "node_modules/tinyrainbow": { 1890 | "version": "1.2.0", 1891 | "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", 1892 | "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", 1893 | "dev": true, 1894 | "license": "MIT", 1895 | "engines": { 1896 | "node": ">=14.0.0" 1897 | } 1898 | }, 1899 | "node_modules/tinyspy": { 1900 | "version": "3.0.2", 1901 | "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", 1902 | "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", 1903 | "dev": true, 1904 | "license": "MIT", 1905 | "engines": { 1906 | "node": ">=14.0.0" 1907 | } 1908 | }, 1909 | "node_modules/typescript": { 1910 | "version": "5.8.3", 1911 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", 1912 | "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", 1913 | "dev": true, 1914 | "license": "Apache-2.0", 1915 | "bin": { 1916 | "tsc": "bin/tsc", 1917 | "tsserver": "bin/tsserver" 1918 | }, 1919 | "engines": { 1920 | "node": ">=14.17" 1921 | } 1922 | }, 1923 | "node_modules/undici-types": { 1924 | "version": "6.19.8", 1925 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", 1926 | "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", 1927 | "dev": true, 1928 | "license": "MIT" 1929 | }, 1930 | "node_modules/vite": { 1931 | "version": "5.4.19", 1932 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz", 1933 | "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==", 1934 | "dev": true, 1935 | "license": "MIT", 1936 | "dependencies": { 1937 | "esbuild": "^0.21.3", 1938 | "postcss": "^8.4.43", 1939 | "rollup": "^4.20.0" 1940 | }, 1941 | "bin": { 1942 | "vite": "bin/vite.js" 1943 | }, 1944 | "engines": { 1945 | "node": "^18.0.0 || >=20.0.0" 1946 | }, 1947 | "funding": { 1948 | "url": "https://github.com/vitejs/vite?sponsor=1" 1949 | }, 1950 | "optionalDependencies": { 1951 | "fsevents": "~2.3.3" 1952 | }, 1953 | "peerDependencies": { 1954 | "@types/node": "^18.0.0 || >=20.0.0", 1955 | "less": "*", 1956 | "lightningcss": "^1.21.0", 1957 | "sass": "*", 1958 | "sass-embedded": "*", 1959 | "stylus": "*", 1960 | "sugarss": "*", 1961 | "terser": "^5.4.0" 1962 | }, 1963 | "peerDependenciesMeta": { 1964 | "@types/node": { 1965 | "optional": true 1966 | }, 1967 | "less": { 1968 | "optional": true 1969 | }, 1970 | "lightningcss": { 1971 | "optional": true 1972 | }, 1973 | "sass": { 1974 | "optional": true 1975 | }, 1976 | "sass-embedded": { 1977 | "optional": true 1978 | }, 1979 | "stylus": { 1980 | "optional": true 1981 | }, 1982 | "sugarss": { 1983 | "optional": true 1984 | }, 1985 | "terser": { 1986 | "optional": true 1987 | } 1988 | } 1989 | }, 1990 | "node_modules/vite-node": { 1991 | "version": "2.1.9", 1992 | "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz", 1993 | "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==", 1994 | "dev": true, 1995 | "license": "MIT", 1996 | "dependencies": { 1997 | "cac": "^6.7.14", 1998 | "debug": "^4.3.7", 1999 | "es-module-lexer": "^1.5.4", 2000 | "pathe": "^1.1.2", 2001 | "vite": "^5.0.0" 2002 | }, 2003 | "bin": { 2004 | "vite-node": "vite-node.mjs" 2005 | }, 2006 | "engines": { 2007 | "node": "^18.0.0 || >=20.0.0" 2008 | }, 2009 | "funding": { 2010 | "url": "https://opencollective.com/vitest" 2011 | } 2012 | }, 2013 | "node_modules/vitest": { 2014 | "version": "2.1.9", 2015 | "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz", 2016 | "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==", 2017 | "dev": true, 2018 | "license": "MIT", 2019 | "dependencies": { 2020 | "@vitest/expect": "2.1.9", 2021 | "@vitest/mocker": "2.1.9", 2022 | "@vitest/pretty-format": "^2.1.9", 2023 | "@vitest/runner": "2.1.9", 2024 | "@vitest/snapshot": "2.1.9", 2025 | "@vitest/spy": "2.1.9", 2026 | "@vitest/utils": "2.1.9", 2027 | "chai": "^5.1.2", 2028 | "debug": "^4.3.7", 2029 | "expect-type": "^1.1.0", 2030 | "magic-string": "^0.30.12", 2031 | "pathe": "^1.1.2", 2032 | "std-env": "^3.8.0", 2033 | "tinybench": "^2.9.0", 2034 | "tinyexec": "^0.3.1", 2035 | "tinypool": "^1.0.1", 2036 | "tinyrainbow": "^1.2.0", 2037 | "vite": "^5.0.0", 2038 | "vite-node": "2.1.9", 2039 | "why-is-node-running": "^2.3.0" 2040 | }, 2041 | "bin": { 2042 | "vitest": "vitest.mjs" 2043 | }, 2044 | "engines": { 2045 | "node": "^18.0.0 || >=20.0.0" 2046 | }, 2047 | "funding": { 2048 | "url": "https://opencollective.com/vitest" 2049 | }, 2050 | "peerDependencies": { 2051 | "@edge-runtime/vm": "*", 2052 | "@types/node": "^18.0.0 || >=20.0.0", 2053 | "@vitest/browser": "2.1.9", 2054 | "@vitest/ui": "2.1.9", 2055 | "happy-dom": "*", 2056 | "jsdom": "*" 2057 | }, 2058 | "peerDependenciesMeta": { 2059 | "@edge-runtime/vm": { 2060 | "optional": true 2061 | }, 2062 | "@types/node": { 2063 | "optional": true 2064 | }, 2065 | "@vitest/browser": { 2066 | "optional": true 2067 | }, 2068 | "@vitest/ui": { 2069 | "optional": true 2070 | }, 2071 | "happy-dom": { 2072 | "optional": true 2073 | }, 2074 | "jsdom": { 2075 | "optional": true 2076 | } 2077 | } 2078 | }, 2079 | "node_modules/which": { 2080 | "version": "2.0.2", 2081 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2082 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2083 | "dev": true, 2084 | "license": "ISC", 2085 | "dependencies": { 2086 | "isexe": "^2.0.0" 2087 | }, 2088 | "bin": { 2089 | "node-which": "bin/node-which" 2090 | }, 2091 | "engines": { 2092 | "node": ">= 8" 2093 | } 2094 | }, 2095 | "node_modules/why-is-node-running": { 2096 | "version": "2.3.0", 2097 | "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", 2098 | "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", 2099 | "dev": true, 2100 | "license": "MIT", 2101 | "dependencies": { 2102 | "siginfo": "^2.0.0", 2103 | "stackback": "0.0.2" 2104 | }, 2105 | "bin": { 2106 | "why-is-node-running": "cli.js" 2107 | }, 2108 | "engines": { 2109 | "node": ">=8" 2110 | } 2111 | }, 2112 | "node_modules/wrap-ansi": { 2113 | "version": "8.1.0", 2114 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", 2115 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", 2116 | "dev": true, 2117 | "license": "MIT", 2118 | "dependencies": { 2119 | "ansi-styles": "^6.1.0", 2120 | "string-width": "^5.0.1", 2121 | "strip-ansi": "^7.0.1" 2122 | }, 2123 | "engines": { 2124 | "node": ">=12" 2125 | }, 2126 | "funding": { 2127 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 2128 | } 2129 | }, 2130 | "node_modules/wrap-ansi-cjs": { 2131 | "name": "wrap-ansi", 2132 | "version": "7.0.0", 2133 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 2134 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 2135 | "dev": true, 2136 | "license": "MIT", 2137 | "dependencies": { 2138 | "ansi-styles": "^4.0.0", 2139 | "string-width": "^4.1.0", 2140 | "strip-ansi": "^6.0.0" 2141 | }, 2142 | "engines": { 2143 | "node": ">=10" 2144 | }, 2145 | "funding": { 2146 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 2147 | } 2148 | }, 2149 | "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { 2150 | "version": "5.0.1", 2151 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 2152 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 2153 | "dev": true, 2154 | "license": "MIT", 2155 | "engines": { 2156 | "node": ">=8" 2157 | } 2158 | }, 2159 | "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { 2160 | "version": "4.3.0", 2161 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 2162 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 2163 | "dev": true, 2164 | "license": "MIT", 2165 | "dependencies": { 2166 | "color-convert": "^2.0.1" 2167 | }, 2168 | "engines": { 2169 | "node": ">=8" 2170 | }, 2171 | "funding": { 2172 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 2173 | } 2174 | }, 2175 | "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { 2176 | "version": "8.0.0", 2177 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 2178 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 2179 | "dev": true, 2180 | "license": "MIT" 2181 | }, 2182 | "node_modules/wrap-ansi-cjs/node_modules/string-width": { 2183 | "version": "4.2.3", 2184 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2185 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2186 | "dev": true, 2187 | "license": "MIT", 2188 | "dependencies": { 2189 | "emoji-regex": "^8.0.0", 2190 | "is-fullwidth-code-point": "^3.0.0", 2191 | "strip-ansi": "^6.0.1" 2192 | }, 2193 | "engines": { 2194 | "node": ">=8" 2195 | } 2196 | }, 2197 | "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { 2198 | "version": "6.0.1", 2199 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2200 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2201 | "dev": true, 2202 | "license": "MIT", 2203 | "dependencies": { 2204 | "ansi-regex": "^5.0.1" 2205 | }, 2206 | "engines": { 2207 | "node": ">=8" 2208 | } 2209 | } 2210 | } 2211 | } 2212 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "design-tokens-format-module", 3 | "description": "A Typescript implementation of the Design Tokens Format Module specification", 4 | "keywords": [ 5 | "design token format module", 6 | "design tokens", 7 | "design system", 8 | "dtcg" 9 | ], 10 | "version": "0.11.1", 11 | "homepage": "https://github.com/nclsndr/design-tokens-format-module", 12 | "license": "MIT", 13 | "author": "Nico Andre", 14 | "type": "module", 15 | "scripts": { 16 | "test": "tsc --project tests/tsconfig.json || true && vitest", 17 | "build": "rm -rf dist && tsc --project tsconfig.json", 18 | "format": "prettier --write .", 19 | "tsc": "tsc" 20 | }, 21 | "main": "./dist/index.js", 22 | "exports": { 23 | ".": "./dist/index.js" 24 | }, 25 | "devDependencies": { 26 | "@types/node": "^20.14.10", 27 | "@vitest/coverage-v8": "^2.1.9", 28 | "prettier": "^3.5.3", 29 | "typescript": "^5.8.3", 30 | "vitest": "^2.1.9" 31 | } 32 | } -------------------------------------------------------------------------------- /src/definitions/Alias.ts: -------------------------------------------------------------------------------- 1 | export type AliasValue = `{${string}}`; 2 | 3 | export type WithAliasValue = T | AliasValue; 4 | 5 | export const ALIAS_PATH_SEPARATOR = '.'; 6 | -------------------------------------------------------------------------------- /src/definitions/GroupProperties.ts: -------------------------------------------------------------------------------- 1 | import type { JSONObject } from './JSONSignatures.js'; 2 | import type { TokenTypeName } from './tokenTypes.js'; 3 | 4 | export type GroupProperties = { 5 | $type?: TokenTypeName; 6 | $description?: string; 7 | $extensions?: JSONObject; 8 | }; 9 | -------------------------------------------------------------------------------- /src/definitions/JSONSignatures.ts: -------------------------------------------------------------------------------- 1 | export type JSONPrimitiveValue = string | number | boolean | null; 2 | export type JSONObject = { 3 | [name: string]: JSONValue; 4 | }; 5 | export type JSONArray = JSONValue[]; 6 | export type JSONValue = JSONPrimitiveValue | JSONArray | JSONObject; 7 | 8 | export type JSONValuePath = Array; 9 | 10 | export namespace Json { 11 | export type Value = JSONValue; 12 | export type Object = JSONObject; 13 | export type Array = JSONArray; 14 | export type Primitive = string | number | boolean | null; 15 | export type ValuePath = JSONValuePath; 16 | } 17 | -------------------------------------------------------------------------------- /src/definitions/JSONTokenTree.ts: -------------------------------------------------------------------------------- 1 | import type { DesignToken } from './tokenTypes.js'; 2 | import type { GroupProperties } from './GroupProperties.js'; 3 | 4 | export type JSONTokenTree = 5 | | (GroupProperties & { 6 | [key: string]: DesignToken | JSONTokenTree | GroupProperties; 7 | }) 8 | | DesignToken; 9 | -------------------------------------------------------------------------------- /src/definitions/TokenSignature.ts: -------------------------------------------------------------------------------- 1 | import type { JSONObject, JSONValue } from './JSONSignatures.js'; 2 | 3 | export type TokenSignature = { 4 | $value: Value; 5 | $type?: Type; 6 | $deprecated?: boolean | string; 7 | $description?: string; 8 | $extensions?: JSONObject; 9 | }; 10 | -------------------------------------------------------------------------------- /src/definitions/tokenTypes.ts: -------------------------------------------------------------------------------- 1 | import type { WithAliasValue } from './Alias.js'; 2 | import type { TokenSignature } from './TokenSignature.js'; 3 | 4 | // Type declaration following the https://tr.designtokens.org/format specification 5 | 6 | // 8.1 Color, following the https://tr.designtokens.org/color specification 7 | const colorTypeName = 'color'; 8 | export const colorSpaceValues = [ 9 | 'srgb', 10 | 'srgb-linear', 11 | 'hsl', 12 | 'hwb', 13 | 'lab', 14 | 'lch', 15 | 'oklab', 16 | 'oklch', 17 | 'display-p3', 18 | 'a98-rgb', 19 | 'prophoto-rgb', 20 | 'rec2020', 21 | 'xyz-d65', 22 | 'xyz-d50', 23 | ] as const; 24 | export namespace Color { 25 | export type TypeName = typeof colorTypeName; 26 | 27 | export type RawValue = { 28 | colorSpace: typeof colorSpaceValues[number]; 29 | components: [number | 'none', number | 'none', number | 'none']; 30 | alpha?: number; 31 | hex?: `#${string}`; 32 | }; 33 | export type Value = WithAliasValue; 34 | export type Token = TokenSignature; 35 | } 36 | 37 | // 8.2 Dimension 38 | const dimensionTypeName = 'dimension'; 39 | export namespace Dimension { 40 | export type TypeName = typeof dimensionTypeName; 41 | export type RawValue = { value: number; unit: 'px' | 'rem' }; 42 | export type Value = WithAliasValue; 43 | export type Token = TokenSignature; 44 | } 45 | 46 | // 8.3 Font Family 47 | const fontFamilyTypeName = 'fontFamily'; 48 | export namespace FontFamily { 49 | export type TypeName = typeof fontFamilyTypeName; 50 | export type RawValue = string | Array; 51 | export type Value = WithAliasValue; 52 | export type Token = TokenSignature; 53 | } 54 | 55 | // 8.4 Font Weight 56 | const fontWeightTypeName = 'fontWeight'; 57 | export const fontWeightValues = [ 58 | 'thin', 59 | 'hairline', 60 | 'extra-light', 61 | 'ultra-light', 62 | 'light', 63 | 'normal', 64 | 'regular', 65 | 'book', 66 | 'medium', 67 | 'semi-bold', 68 | 'demi-bold', 69 | 'bold', 70 | 'extra-bold', 71 | 'ultra-bold', 72 | 'black', 73 | 'heavy', 74 | 'extra-black', 75 | 'ultra-black', 76 | ] as const; 77 | export namespace FontWeight { 78 | export type TypeName = typeof fontWeightTypeName; 79 | export type RawValue = (typeof fontWeightValues)[number] | number; 80 | export type Value = WithAliasValue; 81 | export type Token = TokenSignature; 82 | } 83 | 84 | // 8.5 Duration 85 | const durationTypeName = 'duration'; 86 | export namespace Duration { 87 | export type TypeName = typeof durationTypeName; 88 | export type RawValue = { value: number; unit: 'ms' | 's' }; 89 | export type Value = WithAliasValue; 90 | export type Token = TokenSignature; 91 | } 92 | 93 | // 8.6 Cubic Bezier 94 | const cubicBezierTypeName = 'cubicBezier'; 95 | export namespace CubicBezier { 96 | export type TypeName = typeof cubicBezierTypeName; 97 | export type RawValue = [number, number, number, number]; 98 | export type Value = WithAliasValue; 99 | export type Token = TokenSignature; 100 | } 101 | 102 | // 8.7 Number 103 | const numberTypeName = 'number'; 104 | export namespace Number { 105 | export type TypeName = typeof numberTypeName; 106 | export type RawValue = number; 107 | export type Value = WithAliasValue; 108 | export type Token = TokenSignature; 109 | } 110 | 111 | /* 112 | 9. Composite Types 113 | https://tr.designtokens.org/format/#composite-types 114 | */ 115 | // 9.2 Stroke Style 116 | const strokeStyleTypeName = 'strokeStyle'; 117 | export const strokeStyleStringValues = [ 118 | 'solid', 119 | 'dashed', 120 | 'dotted', 121 | 'double', 122 | 'groove', 123 | 'ridge', 124 | 'outset', 125 | 'inset', 126 | ] as const; 127 | export const strokeStyleLineCapValues = ['round', 'butt', 'square'] as const; 128 | export namespace StrokeStyle { 129 | export type TypeName = typeof strokeStyleTypeName; 130 | export type RawValue = 131 | | (typeof strokeStyleStringValues)[number] 132 | | { 133 | dashArray: Dimension.Value[]; 134 | lineCap: (typeof strokeStyleLineCapValues)[number]; 135 | }; 136 | export type Value = WithAliasValue; 137 | export type Token = TokenSignature; 138 | } 139 | 140 | // 9.3 Border 141 | const borderTypeName = 'border'; 142 | export namespace Border { 143 | export type TypeName = typeof borderTypeName; 144 | export type RawValue = { 145 | color: Color.Value; 146 | width: Dimension.Value; 147 | style: StrokeStyle.Value; 148 | }; 149 | export type Value = WithAliasValue; 150 | export type Token = TokenSignature; 151 | } 152 | 153 | // 9.4 Transition 154 | const transitionTypeName = 'transition'; 155 | export namespace Transition { 156 | export type TypeName = typeof transitionTypeName; 157 | export type RawValue = { 158 | duration: Duration.Value; 159 | delay: Duration.Value; 160 | timingFunction: CubicBezier.Value; 161 | }; 162 | export type Value = WithAliasValue; 163 | export type Token = TokenSignature; 164 | } 165 | 166 | // 9.5 Shadow 167 | const shadowTypeName = 'shadow'; 168 | export namespace Shadow { 169 | export type TypeName = typeof shadowTypeName; 170 | export type RawValue = 171 | | Array<{ 172 | color: Color.Value; 173 | offsetX: Dimension.Value; 174 | offsetY: Dimension.Value; 175 | blur: Dimension.Value; 176 | spread: Dimension.Value; 177 | inset?: boolean; 178 | }> 179 | | { 180 | color: Color.Value; 181 | offsetX: Dimension.Value; 182 | offsetY: Dimension.Value; 183 | blur: Dimension.Value; 184 | spread: Dimension.Value; 185 | inset?: boolean; 186 | }; 187 | export type Value = WithAliasValue; 188 | export type Token = TokenSignature; 189 | } 190 | 191 | // 9.6 Gradient 192 | const gradientTypeName = 'gradient'; 193 | export namespace Gradient { 194 | export type TypeName = typeof gradientTypeName; 195 | export type RawValue = Array<{ 196 | color: Color.Value; 197 | position: Number.Value; 198 | }>; 199 | export type Value = WithAliasValue; 200 | export type Token = TokenSignature; 201 | } 202 | 203 | // 9.7 Typography 204 | const typographyTypeName = 'typography'; 205 | export namespace Typography { 206 | export type TypeName = typeof typographyTypeName; 207 | export type RawValue = { 208 | fontFamily: FontFamily.Value; 209 | fontSize: Dimension.Value; 210 | fontWeight: FontWeight.Value; 211 | letterSpacing: Dimension.Value; 212 | lineHeight: Number.Value; 213 | }; 214 | export type Value = WithAliasValue; 215 | export type Token = TokenSignature; 216 | } 217 | 218 | /* ------------------------------------------ 219 | Mapping Exports 220 | --------------------------------------------- */ 221 | export const tokenTypeNames = [ 222 | colorTypeName, 223 | dimensionTypeName, 224 | fontFamilyTypeName, 225 | fontWeightTypeName, 226 | durationTypeName, 227 | cubicBezierTypeName, 228 | numberTypeName, 229 | strokeStyleTypeName, 230 | borderTypeName, 231 | transitionTypeName, 232 | shadowTypeName, 233 | gradientTypeName, 234 | typographyTypeName, 235 | ] as const; 236 | 237 | export const tokenTypeNamesMapping = tokenTypeNames.reduce<{ 238 | [T in TokenTypeName]: T; 239 | }>((acc: any, t) => { 240 | acc[t] = t; 241 | return acc; 242 | }, {} as any); 243 | 244 | export type TokenTypeName = 245 | | Color.TypeName 246 | | Dimension.TypeName 247 | | FontFamily.TypeName 248 | | FontWeight.TypeName 249 | | Duration.TypeName 250 | | CubicBezier.TypeName 251 | | Number.TypeName 252 | | StrokeStyle.TypeName 253 | | Border.TypeName 254 | | Transition.TypeName 255 | | Shadow.TypeName 256 | | Gradient.TypeName 257 | | Typography.TypeName; 258 | 259 | export type DesignToken = 260 | | Color.Token 261 | | Dimension.Token 262 | | FontFamily.Token 263 | | FontWeight.Token 264 | | Duration.Token 265 | | CubicBezier.Token 266 | | Number.Token 267 | | StrokeStyle.Token 268 | | Border.Token 269 | | Transition.Token 270 | | Shadow.Token 271 | | Gradient.Token 272 | | Typography.Token; 273 | 274 | export type PickTokenByType = { 275 | color: Color.Token; 276 | dimension: Dimension.Token; 277 | fontFamily: FontFamily.Token; 278 | fontWeight: FontWeight.Token; 279 | duration: Duration.Token; 280 | cubicBezier: CubicBezier.Token; 281 | number: Number.Token; 282 | strokeStyle: StrokeStyle.Token; 283 | border: Border.Token; 284 | transition: Transition.Token; 285 | shadow: Shadow.Token; 286 | gradient: Gradient.Token; 287 | typography: Typography.Token; 288 | }[T]; 289 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | type AliasValue, 3 | type WithAliasValue, 4 | ALIAS_PATH_SEPARATOR, 5 | } from './definitions/Alias.js'; 6 | export { type GroupProperties } from './definitions/GroupProperties.js'; 7 | export { type Json } from './definitions/JSONSignatures.js'; 8 | export { type JSONTokenTree } from './definitions/JSONTokenTree.js'; 9 | export { type TokenSignature } from './definitions/TokenSignature.js'; 10 | export { 11 | type Color, 12 | type Dimension, 13 | type FontFamily, 14 | type FontWeight, 15 | type Duration, 16 | type CubicBezier, 17 | type Number, 18 | type StrokeStyle, 19 | type Border, 20 | type Transition, 21 | type Shadow, 22 | type Gradient, 23 | type Typography, 24 | // Aggregated types 25 | type DesignToken, 26 | type TokenTypeName, 27 | // Utils 28 | type PickTokenByType, 29 | // Types constants 30 | tokenTypeNames, 31 | tokenTypeNamesMapping, 32 | // Enum-like values 33 | colorSpaceValues, 34 | fontWeightValues, 35 | strokeStyleStringValues, 36 | strokeStyleLineCapValues, 37 | } from './definitions/tokenTypes.js'; 38 | 39 | export { 40 | captureAliasPath, 41 | CAPTURE_ALIAS_PATH_ERRORS, 42 | } from './utils/captureAliasPath.js'; 43 | export { 44 | extractAliasPathAsString, 45 | extractAliasPathAsArray, 46 | } from './utils/extractAliasPath.js'; 47 | export { matchIsAliasValue } from './utils/matchIsAliasValue.js'; 48 | export { matchIsGroup } from './utils/matchIsGroup.js'; 49 | export { matchIsToken } from './utils/matchIsToken.js'; 50 | export { matchIsTokenTypeName } from './utils/matchIsTokenTypeName.js'; 51 | -------------------------------------------------------------------------------- /src/utils/captureAliasPath.ts: -------------------------------------------------------------------------------- 1 | import { 2 | extractAliasPathAsArray, 3 | extractAliasPathAsString, 4 | } from './extractAliasPath.js'; 5 | import { matchIsAliasValue } from './matchIsAliasValue.js'; 6 | 7 | export const CAPTURE_ALIAS_PATH_ERRORS = [ 8 | 'TYPE_ERROR', 9 | 'FORMAT_ERROR', 10 | ] as const; 11 | 12 | type ValidationError = { 13 | tag: (typeof CAPTURE_ALIAS_PATH_ERRORS)[number]; 14 | message: string; 15 | }; 16 | 17 | type Result = 18 | | { 19 | status: 'ok'; 20 | value: T; 21 | } 22 | | { 23 | status: 'error'; 24 | error: E; 25 | }; 26 | 27 | export function captureAliasPath( 28 | value: unknown, 29 | ): Result, ValidationError>; 30 | export function captureAliasPath( 31 | value: unknown, 32 | asString: AsString, 33 | ): Result, ValidationError>; 34 | export function captureAliasPath( 35 | value: unknown, 36 | asString?: AsString, 37 | ): Result, ValidationError> { 38 | if (typeof value !== 'string') { 39 | return { 40 | status: 'error', 41 | error: { 42 | tag: 'TYPE_ERROR', 43 | message: `Expected a string value. Got ${typeof value}.`, 44 | }, 45 | }; 46 | } 47 | 48 | if (!matchIsAliasValue(value)) { 49 | return { 50 | status: 'error', 51 | error: { 52 | tag: 'FORMAT_ERROR', 53 | message: `Expected a string value enclosed in curly braces, using dot notation: {path.to.token}. Got ${JSON.stringify(value)}.`, 54 | }, 55 | }; 56 | } 57 | 58 | return { 59 | status: 'ok', 60 | value: (asString !== true 61 | ? extractAliasPathAsArray(value) 62 | : extractAliasPathAsString(value)) as any, 63 | }; 64 | } 65 | -------------------------------------------------------------------------------- /src/utils/extractAliasPath.ts: -------------------------------------------------------------------------------- 1 | import { ALIAS_PATH_SEPARATOR, AliasValue } from '../definitions/Alias.js'; 2 | 3 | function makeExtractAliasPath(hasString: boolean) { 4 | return function extractAliasPath(aliasValue: AliasValue) { 5 | const stringPath = aliasValue.slice(1).slice(0, -1); 6 | return hasString ? stringPath : stringPath.split(ALIAS_PATH_SEPARATOR); 7 | }; 8 | } 9 | 10 | export const extractAliasPathAsString = makeExtractAliasPath(true); 11 | export const extractAliasPathAsArray = makeExtractAliasPath(false); 12 | -------------------------------------------------------------------------------- /src/utils/matchIsAliasValue.ts: -------------------------------------------------------------------------------- 1 | import { AliasValue } from '../definitions/Alias.js'; 2 | 3 | export function matchIsAliasValue(candidate: unknown): candidate is AliasValue { 4 | return ( 5 | typeof candidate === 'string' && 6 | candidate.startsWith('{') && 7 | candidate.endsWith('}') 8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /src/utils/matchIsGroup.ts: -------------------------------------------------------------------------------- 1 | import { JSONTokenTree } from '../definitions/JSONTokenTree.js'; 2 | 3 | export function matchIsGroup(value: unknown): value is JSONTokenTree { 4 | return ( 5 | typeof value === 'object' && 6 | value !== null && 7 | !Array.isArray(value) && 8 | !('$value' in value) 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /src/utils/matchIsToken.ts: -------------------------------------------------------------------------------- 1 | import { TokenSignature } from '../definitions/TokenSignature.js'; 2 | import { TokenTypeName } from '../definitions/tokenTypes.js'; 3 | import { JSONValue } from '../definitions/JSONSignatures.js'; 4 | 5 | export function matchIsToken( 6 | value: unknown, 7 | ): value is TokenSignature { 8 | return ( 9 | typeof value === 'object' && 10 | value !== null && 11 | !Array.isArray(value) && 12 | '$value' in value 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /src/utils/matchIsTokenTypeName.ts: -------------------------------------------------------------------------------- 1 | import { TokenTypeName, tokenTypeNames } from '../definitions/tokenTypes.js'; 2 | 3 | export function matchIsTokenTypeName(value: unknown): value is TokenTypeName { 4 | return ( 5 | typeof value === 'string' && tokenTypeNames.includes(value as TokenTypeName) 6 | ); 7 | } 8 | -------------------------------------------------------------------------------- /tests/definitions/jsonTokenTree.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | 3 | import { JSONTokenTree } from '../../src/definitions/JSONTokenTree.js'; 4 | 5 | describe('JSONTokenTree', () => { 6 | it('should accept a literal token tree', () => { 7 | const tree: JSONTokenTree = { 8 | colors: { 9 | $type: 'color', 10 | blue: { 11 | $value: '#0000ff', 12 | }, 13 | lighten: { 14 | blue: { 15 | $value: '{colors.blue}', 16 | }, 17 | }, 18 | }, 19 | red: { 20 | $type: 'color', 21 | $value: { 22 | colorSpace: 'srgb', 23 | components: [0, 0, 0], 24 | }, 25 | }, 26 | }; 27 | 28 | expect(tree).toBeDefined(); 29 | }); 30 | it('should accept any of the token values when $type is not provided at the token level', () => { 31 | const tree: JSONTokenTree = { 32 | colors: { 33 | $type: 'color', 34 | blue: { 35 | $value: 'an invalid value', 36 | }, 37 | }, 38 | // @ts-expect-error 39 | red: { 40 | $type: 'color', 41 | $value: 'an invalid value', 42 | }, 43 | }; 44 | 45 | expect(tree).toBeDefined(); 46 | }); 47 | it('should accept a description and extensions at the root level', () => { 48 | const tree: JSONTokenTree = { 49 | $description: 'A description of the token tree', 50 | $extensions: { 51 | 'com.example': true, 52 | }, 53 | }; 54 | 55 | expect(tree).toBeDefined(); 56 | }); 57 | it('should accept a token at the root level', () => { 58 | const tree: JSONTokenTree = { 59 | $type: 'color', 60 | $value: { 61 | colorSpace: 'srgb', 62 | components: [0, 0, 0], 63 | alpha: 1, 64 | hex: '#000000', 65 | }, 66 | }; 67 | 68 | expect(tree).toBeDefined(); 69 | }); 70 | }); 71 | -------------------------------------------------------------------------------- /tests/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "module": "NodeNext", 5 | "moduleResolution": "NodeNext", 6 | "rootDir": "../", 7 | "noEmit": true 8 | }, 9 | "include": [".", "../src"], 10 | "exclude": ["../dist"] 11 | } 12 | -------------------------------------------------------------------------------- /tests/utils/captureAliasPath.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | 3 | import { captureAliasPath } from '../../src/utils/captureAliasPath.js'; 4 | 5 | describe('captureAliasPath', () => { 6 | it('should return the alias path as a string when asString option is true', () => { 7 | expect(captureAliasPath('{alias.path}', true)).toStrictEqual({ 8 | status: 'ok', 9 | value: 'alias.path', 10 | }); 11 | }); 12 | it('should return the alias path as an array when asString option is false', () => { 13 | expect(captureAliasPath('{alias.path}', false)).toStrictEqual({ 14 | status: 'ok', 15 | value: ['alias', 'path'], 16 | }); 17 | }); 18 | it('should return the alias path as an array when no option is provided', () => { 19 | expect(captureAliasPath('{alias.path}')).toStrictEqual({ 20 | status: 'ok', 21 | value: ['alias', 'path'], 22 | }); 23 | }); 24 | it('should return an error when the value is not a string', () => { 25 | expect(captureAliasPath(123)).toStrictEqual({ 26 | status: 'error', 27 | error: { 28 | tag: 'TYPE_ERROR', 29 | message: 'Expected a string value. Got number.', 30 | }, 31 | }); 32 | }); 33 | it('should return an error when the value is not an alias', () => { 34 | expect(captureAliasPath('alias.path')).toStrictEqual({ 35 | status: 'error', 36 | error: { 37 | tag: 'FORMAT_ERROR', 38 | message: 39 | 'Expected a string value enclosed in curly braces, using dot notation: {path.to.token}. Got "alias.path".', 40 | }, 41 | }); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /tests/utils/extractAlias.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | 3 | import { 4 | extractAliasPathAsArray, 5 | extractAliasPathAsString, 6 | } from '../../src/utils/extractAliasPath.js'; 7 | 8 | describe('extractAlias', () => { 9 | describe('extractAliasPathAsString', () => { 10 | it('should return the alias path as a string', () => { 11 | expect(extractAliasPathAsString('{alias.path}')).toBe('alias.path'); 12 | }); 13 | }); 14 | describe('extractAliasPathAsArray', () => { 15 | it('should return the alias path as an array', () => { 16 | expect(extractAliasPathAsArray('{alias.path}')).toEqual([ 17 | 'alias', 18 | 'path', 19 | ]); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /tests/utils/matchIsAliasValue.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | 3 | import { matchIsAliasValue } from '../../src/utils/matchIsAliasValue.js'; 4 | 5 | describe.concurrent('matchIsAliasValue', () => { 6 | it('should return true if the value is an alias', () => { 7 | expect(matchIsAliasValue('{foo}')).toBe(true); 8 | }); 9 | it('should return false if the value is a string with no heading "{" character', () => { 10 | expect(matchIsAliasValue('foo')).toBe(false); 11 | }); 12 | it('should return false if the value is a number', () => { 13 | expect(matchIsAliasValue(1)).toBe(false); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /tests/utils/matchIsGroup.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | 3 | import { matchIsGroup } from '../../src/utils/matchIsGroup.js'; 4 | 5 | describe.concurrent('matchIsGroup', () => { 6 | it('should return true if the value is an object without the "$value" property', () => { 7 | expect(matchIsGroup({ foo: 'bar' })).toBe(true); 8 | }); 9 | it('should return false if the value is an object with the "$value" property', () => { 10 | expect(matchIsGroup({ $value: 'any' })).toBe(false); 11 | }); 12 | it('should return false if the value is a string', () => { 13 | expect(matchIsGroup('a string')).toBe(false); 14 | }); 15 | it('should return false if the value is an array', () => { 16 | expect(matchIsGroup([])).toBe(false); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /tests/utils/matchIsToken.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | 3 | import { matchIsToken } from '../../src/utils/matchIsToken.js'; 4 | 5 | describe.concurrent('matchIsToken', () => { 6 | it('should return true if the value is an object with the "$value" property', () => { 7 | expect(matchIsToken({ $value: 'any' })).toBe(true); 8 | }); 9 | it('should return false if the value is an object without the "$value" property', () => { 10 | expect(matchIsToken({ foo: 'bar' })).toBe(false); 11 | }); 12 | it('should return false if the value is a string', () => { 13 | expect(matchIsToken('a string')).toBe(false); 14 | }); 15 | it('should return false if the value is an array', () => { 16 | expect(matchIsToken([])).toBe(false); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /tests/utils/matchIsTokenTypeName.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | 3 | import { tokenTypeNames } from '../../src/definitions/tokenTypes.js'; 4 | 5 | import { matchIsTokenTypeName } from '../../src/utils/matchIsTokenTypeName.js'; 6 | 7 | describe.concurrent('matchIsTokenTypeName', () => { 8 | it('should return true if the value is a token type name', () => { 9 | for (const type of tokenTypeNames) { 10 | expect(matchIsTokenTypeName(type)).toBe(true); 11 | } 12 | }); 13 | it('should return false if the value is not a token type name', () => { 14 | expect(matchIsTokenTypeName('not a token type name')).toBe(false); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strict": true, 4 | "exactOptionalPropertyTypes": true, 5 | "forceConsistentCasingInFileNames": true, 6 | "esModuleInterop": true, 7 | "skipLibCheck": true, 8 | "target": "es2022", 9 | "moduleDetection": "force", 10 | "isolatedModules": true, 11 | "noImplicitOverride": true, 12 | 13 | "module": "NodeNext", 14 | "moduleResolution": "NodeNext", 15 | "declaration": true, 16 | 17 | "lib": ["es2022"], 18 | 19 | "rootDir": "./src", 20 | "outDir": "./dist" 21 | }, 22 | "include": ["./src"], 23 | "exclude": ["./dist", "vite.config.ts", "./tests", "./**/*.spec.ts"] 24 | } 25 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config'; 2 | 3 | export default defineConfig({ 4 | test: { 5 | globals: false, 6 | }, 7 | }); 8 | --------------------------------------------------------------------------------