├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── .np-config.json ├── LICENSE ├── README.md ├── lerna.json ├── package-lock.json ├── package.json ├── packages ├── common │ ├── build.config.ts │ ├── package-lock.json │ ├── package.json │ ├── src │ │ ├── computed.ts │ │ ├── defineComponent.ts │ │ ├── definePlugin.ts │ │ ├── events.ts │ │ ├── fragment.ts │ │ ├── h.ts │ │ ├── index.ts │ │ ├── provide.ts │ │ ├── ref.ts │ │ ├── storybook │ │ │ ├── createStory.ts │ │ │ └── index.ts │ │ ├── types.ts │ │ └── watch.ts │ ├── tsconfig.json │ ├── tsconfig.vite.json │ └── vite.config.ts ├── react │ ├── build.config.ts │ ├── package.json │ ├── pnpm-lock.yaml │ ├── src │ │ ├── __tests__ │ │ │ ├── __snapshots__ │ │ │ │ ├── computed.spec.tsx.snap │ │ │ │ ├── defineComponent.spec.tsx.snap │ │ │ │ ├── definePlugin.spec.tsx.snap │ │ │ │ ├── provide.spec.tsx.snap │ │ │ │ └── ref.spec.tsx.snap │ │ │ ├── computed.spec.tsx │ │ │ ├── defineComponent.spec.tsx │ │ │ ├── definePlugin.spec.tsx │ │ │ ├── h.spec.tsx │ │ │ ├── ref.spec.tsx │ │ │ └── watch.spec.tsx │ │ ├── computed.ts │ │ ├── context.ts │ │ ├── defineComponent.tsx │ │ ├── definePlugin.tsx │ │ ├── events.ts │ │ ├── fragment.ts │ │ ├── h.ts │ │ ├── helpers │ │ │ ├── capitalizeFirst.ts │ │ │ ├── getSlotChildren.ts │ │ │ ├── index.ts │ │ │ ├── normalizeEventName.ts │ │ │ └── unwrapState.ts │ │ ├── index.ts │ │ ├── ref.ts │ │ ├── storybook │ │ │ ├── createStory.ts │ │ │ └── index.ts │ │ ├── types-common.ts │ │ ├── types.ts │ │ └── watch.ts │ ├── tsconfig.json │ ├── tsconfig.vite.json │ └── vite.config.ts └── vue │ ├── build.config.ts │ ├── package.json │ ├── pnpm-lock.yaml │ ├── src │ ├── __tests__ │ │ ├── __snapshots__ │ │ │ └── defineComponent.spec.tsx.snap │ │ ├── defineComponent.spec.tsx │ │ ├── definePlugin.spec.tsx │ │ └── h.spec.ts │ ├── computed.ts │ ├── defineComponent.ts │ ├── definePlugin.ts │ ├── env.d.ts │ ├── events.ts │ ├── fragment.ts │ ├── h.ts │ ├── index.ts │ ├── ref.ts │ ├── storybook │ │ ├── createStory.ts │ │ └── index.ts │ ├── types-common.ts │ ├── types.ts │ └── watch.ts │ ├── tsconfig.json │ ├── tsconfig.vite.json │ └── vite.config.ts ├── pnpm-lock.yaml ├── scripts ├── build.ts ├── postbuild.ts ├── postrelease.ts └── postversion.ts └── tsconfig.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 4 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [package.json] 16 | indent_size = 2 17 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | node: true, 4 | jest: true, 5 | browser: true, 6 | es2021: true 7 | }, 8 | extends: [ 9 | 'standard' 10 | ], 11 | parser: '@typescript-eslint/parser', 12 | parserOptions: { 13 | ecmaVersion: 12, 14 | parser: '@typescript-eslint/parser', 15 | sourceType: 'module', 16 | ecmaFeatures: { 17 | jsx: true, 18 | globalReturn: true 19 | } 20 | }, 21 | plugins: [ 22 | '@typescript-eslint' 23 | ], 24 | rules: { 25 | indent: ['warn', 4], 26 | semi: ['warn', 'always'], 27 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0, 28 | 'no-prototype-builtins': 'off', 29 | 'max-params': 'off', 30 | 'no-undef': 'off', 31 | 'no-unused-vars': 'off', 32 | 'max-nested-callbacks': 'off', 33 | '@typescript-eslint/ban-ts-comment': 'off', 34 | '@typescript-eslint/no-explicit-any': 'off', 35 | '@typescript-eslint/no-non-null-assertion': 'off', 36 | '@typescript-eslint/no-empty-function': 'off', 37 | '@typescript-eslint/explicit-module-boundary-types': 'off', 38 | '@typescript-eslint/no-unused-vars': [ 39 | 'error', 40 | { 41 | varsIgnorePattern: '^(h|Fragment)$' 42 | } 43 | ] 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | lib 12 | dist 13 | dist-ssr 14 | *.local 15 | coverage 16 | 17 | # Editor directories and files 18 | .vscode/* 19 | !.vscode/extensions.json 20 | .idea 21 | .DS_Store 22 | *.suo 23 | *.ntvs* 24 | *.njsproj 25 | *.sln 26 | *.sw? 27 | 28 | -------------------------------------------------------------------------------- /.np-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "yarn": false, 3 | "contents": "./lib" 4 | } 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2022 by Alex Grozav 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED “AS IS” AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | Inkline logo 4 | 5 |

6 | 7 |

Inkline - Unified

8 | 9 |

10 | Unified interface for defining components for Vue and React using a single code base.

Inkline is written and maintained by @alexgrozav. 11 |
12 |
13 | Homepage 14 | · 15 | Documentation 16 | · 17 | Storybook 18 | · 19 | Playground 20 | · 21 | Issue Tracker 22 |

23 | 24 |
25 | 26 |

27 | 28 | npm version 29 | 30 | 31 | Build 32 | 33 | 34 | Downloads 35 | 36 | 37 | Discord 38 | 39 |

40 | 41 | 42 |
43 |
44 | 45 | ## Running locally 46 | 47 | 1. First, install dependencies using `npm install`. 48 | 2. From the root directory, run `npm run test` in the command line. 49 | 50 | ## Setup 51 | 52 | 1. Set an alias in your build system to resolve `@inkline/paper` to either `@inkline/paper/vue` or `@inkline/paper/react`. 53 | 54 | - `@inkline/paper` => `@inkline/paper/vue` 55 | - `@inkline/paper` => `@inkline/paper/react` 56 | 57 | 2. Import the common component definition interface from `@inkline/paper` and decide whether you're creating a library for `vue` or `react` at build time. 58 | 59 | 3. Configure `tsconfig.json` to use the custom `h` and `Fragment` JSX Factory functions. 60 | 61 | ~~~ 62 | { 63 | "compilerOptions": { 64 | "jsx": "preserve", 65 | "jsxFactory": "h", 66 | "jsxFragmentFactory": "Fragment" 67 | } 68 | } 69 | ~~~ 70 | 71 | ## Usage 72 | 73 | ### Create element 74 | ```ts 75 | h(type: string, props: Record, children: (VNode | string)[]): VNode 76 | ``` 77 | 78 | The hoist function `h()` is used to create elements. 79 | 80 | ~~~ts 81 | import { h } from '@inkline/paper'; 82 | 83 | const type = 'button'; 84 | const props = { id: 'button' }; 85 | const children = ['Hello world']; 86 | 87 | const node = h(type, props, children); 88 | ~~~ 89 | 90 | It also serves as a JSX Factory. 91 | 92 | ~~~tsx 93 | import { h } from '@inkline/paper'; 94 | 95 | const node =
Hello world!
96 | ~~~ 97 | 98 | -------- 99 | 100 | ### Define component 101 | ```ts 102 | defineComponent(definition: ComponentDefinition) 103 | ``` 104 | 105 | The `defineComponent()` function is used to set up framework-specific internals and get type annotations. 106 | 107 | ~~~ts 108 | import { defineComponent, h } from '@inkline/paper'; 109 | 110 | const Component = defineComponent({ 111 | render () { 112 | return h('div'); 113 | } 114 | }); 115 | ~~~ 116 | 117 | ~~~tsx 118 | import { defineComponent, h } from '@inkline/paper'; 119 | 120 | const Component = defineComponent({ 121 | render () { 122 | return
; 123 | } 124 | }); 125 | ~~~ 126 | 127 | **Vue.js** 128 | ~~~html 129 | 130 | ~~~ 131 | 132 | **React.js** 133 | ~~~tsx 134 | 135 | ~~~ 136 | 137 | -------- 138 | 139 | ### Render function 140 | ```ts 141 | defineComponent({ render(state: Props & State, ctx: RenderContext): VNode }) 142 | ``` 143 | 144 | The `render()` function is mandatory and is used to return the component markup using hoisting. 145 | 146 | ~~~ts 147 | import { defineComponent, h } from '@inkline/paper'; 148 | 149 | const Component = defineComponent({ 150 | render () { 151 | return h('button', {}, 'Hello world'); 152 | } 153 | }); 154 | ~~~ 155 | 156 | ~~~tsx 157 | import { defineComponent, h } from '@inkline/paper'; 158 | 159 | const Component = defineComponent({ 160 | render () { 161 | return ; 162 | } 163 | }); 164 | ~~~ 165 | 166 | **Vue.js** 167 | ~~~html 168 | 169 | ~~~ 170 | 171 | **React.js** 172 | ~~~tsx 173 | 174 | ~~~ 175 | 176 | -------- 177 | 178 | ### Setup function 179 | ```ts 180 | defineComponent({ setup(props: Props, ctx: SetupContext) }) 181 | ``` 182 | 183 | The `setup()` function is used to prepare functions. 184 | 185 | ~~~ts 186 | import { defineComponent, h } from '@inkline/paper'; 187 | 188 | const Component = defineComponent<{}, { text: string }>({ 189 | setup () { 190 | return { 191 | text: "Hello world" 192 | }; 193 | }, 194 | render (state) { 195 | return h('button', {}, [ 196 | state.text 197 | ]); 198 | } 199 | }); 200 | ~~~ 201 | 202 | ~~~tsx 203 | import { defineComponent, h } from '@inkline/paper'; 204 | 205 | const Component = defineComponent<{}, { text: string }>({ 206 | setup () { 207 | return { 208 | text: "Hello world" 209 | }; 210 | }, 211 | render (state) { 212 | return ; 213 | } 214 | }); 215 | ~~~ 216 | 217 | **Vue.js** 218 | ~~~html 219 | 220 | ~~~ 221 | 222 | **React.js** 223 | ~~~tsx 224 | 225 | ~~~ 226 | 227 | -------- 228 | 229 | ### Reference variables 230 | ```ts 231 | ref(defaultValue: Type) 232 | ``` 233 | 234 | The `ref` variable works similar to the Vue.js `ref`. To access or set the value of a reference variable, access or manipulate its `value` field directly. 235 | 236 | ~~~ts 237 | import { defineComponent, ref, h, Ref } from '@inkline/paper'; 238 | 239 | const Component = defineComponent<{}, { text: Ref, onClick: () => void }>({ 240 | setup () { 241 | const text = ref('Hello world'); 242 | 243 | const onClick = () => { 244 | text.value = 'Bye world'; 245 | } 246 | 247 | return { 248 | text, 249 | onClick 250 | }; 251 | }, 252 | render (state) { 253 | return h('button', { onClick: state.onClick }, [ 254 | state.text.value 255 | ]); 256 | } 257 | }); 258 | ~~~ 259 | 260 | **Vue.js** 261 | ~~~html 262 | 263 | ~~~ 264 | 265 | **React.js** 266 | ~~~tsx 267 | 268 | ~~~ 269 | 270 | -------- 271 | 272 | ### Computed variables 273 | ```ts 274 | computed(() => Type) 275 | ``` 276 | 277 | ~~~ts 278 | import { defineComponent, ref, h, Ref } from '@inkline/paper'; 279 | 280 | const Component = defineComponent<{ value: number; }, { double: Ref }>({ 281 | setup (props) { 282 | const double = computed(() => props.value * 2); 283 | 284 | return { 285 | double 286 | }; 287 | }, 288 | render (state) { 289 | return h('button', {}, [ 290 | state.double.value 291 | ]); 292 | } 293 | }); 294 | ~~~ 295 | 296 | **Vue.js** 297 | ~~~html 298 | 299 | ~~~ 300 | 301 | **React.js** 302 | ~~~tsx 303 | 304 | ~~~ 305 | 306 | -------- 307 | 308 | ### Provide and Inject 309 | ```ts 310 | provide(identifier: string, value: Type) 311 | inject(identifier: string, defaultValue?: Type): Type 312 | ``` 313 | 314 | ~~~ts 315 | import { defineComponent, ref, h, Ref } from '@inkline/paper'; 316 | 317 | const identifier = Symbol('identifier'); 318 | 319 | const Provider = defineComponent<{}, {}>({ 320 | setup (props, ctx) { 321 | ctx.provide(identifier, 'value'); 322 | 323 | return {}; 324 | }, 325 | render (state, ctx) { 326 | return h('div', {}, [ 327 | ctx.slot() 328 | ]); 329 | } 330 | }); 331 | 332 | const Consumer = defineComponent<{}, { value?: string; }>({ 333 | setup (props, ctx) { 334 | const value = inject(identifier, 'defaultValue'); 335 | 336 | return { value }; 337 | }, 338 | render (state, ctx) { 339 | return h('div', {}, [ 340 | `${state.value}` 341 | ]); 342 | } 343 | }); 344 | ~~~ 345 | 346 | **Vue.js** 347 | ~~~html 348 | 349 | 350 | 351 | ~~~ 352 | 353 | **React.js** 354 | ~~~tsx 355 | 356 | 357 | 358 | ~~~ 359 | 360 | -------- 361 | 362 | ### Props 363 | ```ts 364 | defineComponent({ props: ComponentProps }) 365 | ``` 366 | 367 | Define the props using the `props` field, using the same format used in Vue.js. 368 | 369 | The `setup()` function receives the defined prop values with default as fallback. 370 | 371 | ~~~ts 372 | import { defineComponent, h } from '@inkline/paper'; 373 | 374 | const Component = defineComponent<{ text: string }, {}>({ 375 | props: { 376 | text: { 377 | type: String, 378 | default: () => 'Hello world' 379 | } 380 | }, 381 | render (state) { 382 | return h('button', {}, [ 383 | state.text 384 | ]); 385 | } 386 | }); 387 | ~~~ 388 | 389 | **Vue.js** 390 | ~~~html 391 | 392 | ~~~ 393 | 394 | **React.js** 395 | ~~~tsx 396 | 397 | ~~~ 398 | 399 | -------- 400 | 401 | ### Slots 402 | ``` 403 | defineComponent({ slots: string[] })` and `renderContext.slot(slotName) 404 | ``` 405 | 406 | The `slots` array allows you to define multiple slot names for the component. Out of the box, the `default` slot is pre-defined. 407 | 408 | The `slot()` function is available in the render function execution context. 409 | 410 | ~~~ts 411 | import { defineComponent, h } from '@inkline/paper'; 412 | 413 | const Component = defineComponent({ 414 | slots: ['header', 'footer'], 415 | render (state, ctx) { 416 | return h('div', { class: 'card' }, [ 417 | ctx.slot('header'), 418 | ctx.slot(), // Default slot 419 | ctx.slot('footer'), 420 | ]); 421 | } 422 | }); 423 | ~~~ 424 | 425 | **Vue.js** 426 | ~~~html 427 | 428 | 429 | Body 430 | 431 | 432 | ~~~ 433 | 434 | **React.js** 435 | ~~~tsx 436 | 437 | Header 438 | Body 439 | Header 440 | 441 | ~~~ 442 | 443 | -------- 444 | 445 | ### Events 446 | ``` 447 | defineComponent({ emits: string[] })` and `setupContext.emit(eventName, ...args) 448 | ``` 449 | 450 | The `emits` array allows you to define event emitters. 451 | 452 | - for Vue.js, this uses the native `emit()` function 453 | - for React.js, this creates an `on[EventName]` callback 454 | 455 | ~~~ts 456 | import { defineComponent, h } from '@inkline/paper'; 457 | 458 | const Component = defineComponent<{}, { emitChange: () => void }>({ 459 | emits: ['change'], 460 | setup (props, ctx) { 461 | const emitChange = () => { 462 | ctx.emit('change'); 463 | } 464 | 465 | return { emitChange }; 466 | }, 467 | render (state, ctx) { 468 | return h('button', { onClick: state.emitChange }, [ctx.slot()]); 469 | } 470 | }); 471 | ~~~ 472 | 473 | **Vue.js** 474 | ~~~html 475 | 476 | ~~~ 477 | 478 | **React.js** 479 | ~~~tsx 480 | doSomething()} /> 481 | ~~~ 482 | 483 |
484 |
485 | 486 | ## Creator 487 | **Alex Grozav** 488 | 489 | - 490 | - 491 | - 492 | - 493 | 494 | If you use Inkline in your daily work and feel that it has made your life easier, please consider sponsoring me on [Github Sponsors](https://github.com/sponsors/alexgrozav). 💖 495 | 496 | ## Copyright and license 497 | Homepage and documentation copyright 2017-2022 [Inkline Authors](https://github.com/inkline/inkline.io/graphs/contributors). 498 | Docs released under [ISC License](https://github.com/inkline/inkline/blob/master/packages/docs/LICENSE). 499 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "version": "0.0.0" 6 | } 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@inkline/paper", 3 | "description": "Paper is a unified interface for defining components for Vue and React using a single code base.", 4 | "version": "1.5.0", 5 | "author": "Alex Grozav ", 6 | "scripts": { 7 | "bootstrap": "lerna bootstrap", 8 | "pre": "lerna run pre", 9 | "build": "rimraf lib && lerna run build", 10 | "postbuild": "ts-node scripts/postbuild.ts", 11 | "test": "lerna run test", 12 | "prerelease": "npm-run-all test build", 13 | "release": "np", 14 | "postrelease": "ts-node scripts/postrelease.ts", 15 | "postversion": "ts-node scripts/postversion.ts" 16 | }, 17 | "devDependencies": { 18 | "@types/node": "17.0.23", 19 | "@types/shelljs": "0.8.11", 20 | "@typescript-eslint/eslint-plugin": "5.13.0", 21 | "@typescript-eslint/parser": "5.13.0", 22 | "eslint": "8.10.0", 23 | "eslint-config-standard": "16.0.3", 24 | "eslint-plugin-import": "2.25.4", 25 | "eslint-plugin-node": "11.1.0", 26 | "eslint-plugin-promise": "6.0.0", 27 | "lerna": "^4.0.0", 28 | "np": "7.6.0", 29 | "npm-run-all": "4.1.5", 30 | "rimraf": "3.0.2", 31 | "shelljs": "0.8.5", 32 | "ts-node": "10.7.0", 33 | "tsconfig-paths": "3.13.0", 34 | "typescript": "4.6.2", 35 | "vitest": "0.5.9" 36 | }, 37 | "main": "index.cjs", 38 | "module": "index.mjs", 39 | "jsdelivr": "index.cjs", 40 | "unpkg": "index.cjs", 41 | "types": "index.d.ts", 42 | "files": [ 43 | "**/*" 44 | ], 45 | "exports": { 46 | "./react": { 47 | "require": "./react/index.cjs", 48 | "import": "./react/index.mjs", 49 | "types": "./react/index.d.ts" 50 | }, 51 | "./vue": { 52 | "require": "./vue/index.cjs", 53 | "import": "./vue/index.mjs", 54 | "types": "./vue/index.d.ts" 55 | }, 56 | ".": { 57 | "require": "./index.cjs", 58 | "import": "./index.mjs", 59 | "types": "./index.d.ts" 60 | }, 61 | "./*": "./*" 62 | }, 63 | "funding": { 64 | "type": "github", 65 | "url": "https://github.com/sponsors/alexgrozav" 66 | }, 67 | "bugs": { 68 | "url": "https://github.com/inkline/paper/issues" 69 | }, 70 | "homepage": "https://inkline.io", 71 | "keywords": [ 72 | "inkline", 73 | "react", 74 | "reactjs", 75 | "vue", 76 | "vuejs", 77 | "ui", 78 | "ux", 79 | "dx", 80 | "components", 81 | "library", 82 | "framework", 83 | "typescript", 84 | "javascript", 85 | "front end" 86 | ], 87 | "license": "ISC", 88 | "repository": { 89 | "type": "git", 90 | "url": "git+https://github.com/inkline/paper.git" 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /packages/common/build.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | entries: [ 3 | { 4 | builder: 'mkdist', 5 | format: 'esm', 6 | ext: 'mjs', 7 | input: './src', 8 | declaration: true 9 | }, 10 | { 11 | builder: 'mkdist', 12 | format: 'cjs', 13 | ext: 'cjs', 14 | input: './src', 15 | declaration: true 16 | } 17 | ] 18 | }; 19 | -------------------------------------------------------------------------------- /packages/common/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@inkline/paper-common", 3 | "requires": true, 4 | "lockfileVersion": 1, 5 | "dependencies": { 6 | "@ampproject/remapping": { 7 | "version": "2.1.2", 8 | "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", 9 | "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", 10 | "dev": true, 11 | "requires": { 12 | "@jridgewell/trace-mapping": "^0.3.0" 13 | } 14 | }, 15 | "@babel/code-frame": { 16 | "version": "7.16.7", 17 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", 18 | "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", 19 | "dev": true, 20 | "requires": { 21 | "@babel/highlight": "^7.16.7" 22 | } 23 | }, 24 | "@babel/compat-data": { 25 | "version": "7.17.7", 26 | "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz", 27 | "integrity": "sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ==", 28 | "dev": true 29 | }, 30 | "@babel/core": { 31 | "version": "7.17.8", 32 | "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.8.tgz", 33 | "integrity": "sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ==", 34 | "dev": true, 35 | "requires": { 36 | "@ampproject/remapping": "^2.1.0", 37 | "@babel/code-frame": "^7.16.7", 38 | "@babel/generator": "^7.17.7", 39 | "@babel/helper-compilation-targets": "^7.17.7", 40 | "@babel/helper-module-transforms": "^7.17.7", 41 | "@babel/helpers": "^7.17.8", 42 | "@babel/parser": "^7.17.8", 43 | "@babel/template": "^7.16.7", 44 | "@babel/traverse": "^7.17.3", 45 | "@babel/types": "^7.17.0", 46 | "convert-source-map": "^1.7.0", 47 | "debug": "^4.1.0", 48 | "gensync": "^1.0.0-beta.2", 49 | "json5": "^2.1.2", 50 | "semver": "^6.3.0" 51 | } 52 | }, 53 | "@babel/generator": { 54 | "version": "7.17.7", 55 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.7.tgz", 56 | "integrity": "sha512-oLcVCTeIFadUoArDTwpluncplrYBmTCCZZgXCbgNGvOBBiSDDK3eWO4b/+eOTli5tKv1lg+a5/NAXg+nTcei1w==", 57 | "dev": true, 58 | "requires": { 59 | "@babel/types": "^7.17.0", 60 | "jsesc": "^2.5.1", 61 | "source-map": "^0.5.0" 62 | } 63 | }, 64 | "@babel/helper-compilation-targets": { 65 | "version": "7.17.7", 66 | "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.7.tgz", 67 | "integrity": "sha512-UFzlz2jjd8kroj0hmCFV5zr+tQPi1dpC2cRsDV/3IEW8bJfCPrPpmcSN6ZS8RqIq4LXcmpipCQFPddyFA5Yc7w==", 68 | "dev": true, 69 | "requires": { 70 | "@babel/compat-data": "^7.17.7", 71 | "@babel/helper-validator-option": "^7.16.7", 72 | "browserslist": "^4.17.5", 73 | "semver": "^6.3.0" 74 | } 75 | }, 76 | "@babel/helper-environment-visitor": { 77 | "version": "7.16.7", 78 | "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", 79 | "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", 80 | "dev": true, 81 | "requires": { 82 | "@babel/types": "^7.16.7" 83 | } 84 | }, 85 | "@babel/helper-function-name": { 86 | "version": "7.16.7", 87 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", 88 | "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", 89 | "dev": true, 90 | "requires": { 91 | "@babel/helper-get-function-arity": "^7.16.7", 92 | "@babel/template": "^7.16.7", 93 | "@babel/types": "^7.16.7" 94 | } 95 | }, 96 | "@babel/helper-get-function-arity": { 97 | "version": "7.16.7", 98 | "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", 99 | "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", 100 | "dev": true, 101 | "requires": { 102 | "@babel/types": "^7.16.7" 103 | } 104 | }, 105 | "@babel/helper-hoist-variables": { 106 | "version": "7.16.7", 107 | "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", 108 | "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", 109 | "dev": true, 110 | "requires": { 111 | "@babel/types": "^7.16.7" 112 | } 113 | }, 114 | "@babel/helper-module-imports": { 115 | "version": "7.16.7", 116 | "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", 117 | "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", 118 | "dev": true, 119 | "requires": { 120 | "@babel/types": "^7.16.7" 121 | } 122 | }, 123 | "@babel/helper-module-transforms": { 124 | "version": "7.17.7", 125 | "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.7.tgz", 126 | "integrity": "sha512-VmZD99F3gNTYB7fJRDTi+u6l/zxY0BE6OIxPSU7a50s6ZUQkHwSDmV92FfM+oCG0pZRVojGYhkR8I0OGeCVREw==", 127 | "dev": true, 128 | "requires": { 129 | "@babel/helper-environment-visitor": "^7.16.7", 130 | "@babel/helper-module-imports": "^7.16.7", 131 | "@babel/helper-simple-access": "^7.17.7", 132 | "@babel/helper-split-export-declaration": "^7.16.7", 133 | "@babel/helper-validator-identifier": "^7.16.7", 134 | "@babel/template": "^7.16.7", 135 | "@babel/traverse": "^7.17.3", 136 | "@babel/types": "^7.17.0" 137 | } 138 | }, 139 | "@babel/helper-simple-access": { 140 | "version": "7.17.7", 141 | "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", 142 | "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", 143 | "dev": true, 144 | "requires": { 145 | "@babel/types": "^7.17.0" 146 | } 147 | }, 148 | "@babel/helper-split-export-declaration": { 149 | "version": "7.16.7", 150 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", 151 | "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", 152 | "dev": true, 153 | "requires": { 154 | "@babel/types": "^7.16.7" 155 | } 156 | }, 157 | "@babel/helper-validator-identifier": { 158 | "version": "7.16.7", 159 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", 160 | "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", 161 | "dev": true 162 | }, 163 | "@babel/helper-validator-option": { 164 | "version": "7.16.7", 165 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", 166 | "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", 167 | "dev": true 168 | }, 169 | "@babel/helpers": { 170 | "version": "7.17.8", 171 | "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.8.tgz", 172 | "integrity": "sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw==", 173 | "dev": true, 174 | "requires": { 175 | "@babel/template": "^7.16.7", 176 | "@babel/traverse": "^7.17.3", 177 | "@babel/types": "^7.17.0" 178 | } 179 | }, 180 | "@babel/highlight": { 181 | "version": "7.16.10", 182 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", 183 | "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", 184 | "dev": true, 185 | "requires": { 186 | "@babel/helper-validator-identifier": "^7.16.7", 187 | "chalk": "^2.0.0", 188 | "js-tokens": "^4.0.0" 189 | }, 190 | "dependencies": { 191 | "chalk": { 192 | "version": "2.4.2", 193 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 194 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 195 | "dev": true, 196 | "requires": { 197 | "ansi-styles": "^3.2.1", 198 | "escape-string-regexp": "^1.0.5", 199 | "supports-color": "^5.3.0" 200 | } 201 | } 202 | } 203 | }, 204 | "@babel/parser": { 205 | "version": "7.17.8", 206 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", 207 | "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==", 208 | "dev": true 209 | }, 210 | "@babel/standalone": { 211 | "version": "7.17.8", 212 | "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.17.8.tgz", 213 | "integrity": "sha512-tr3SDpVnxR/fzrxyG+HZPAyEA9eTHZIAjy4eqrc7m+KBwsdo1YvTbUfJ6teWHQ177mk6GmdmltsIiOYCcvRPWA==", 214 | "dev": true 215 | }, 216 | "@babel/template": { 217 | "version": "7.16.7", 218 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", 219 | "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", 220 | "dev": true, 221 | "requires": { 222 | "@babel/code-frame": "^7.16.7", 223 | "@babel/parser": "^7.16.7", 224 | "@babel/types": "^7.16.7" 225 | } 226 | }, 227 | "@babel/traverse": { 228 | "version": "7.17.3", 229 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", 230 | "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", 231 | "dev": true, 232 | "requires": { 233 | "@babel/code-frame": "^7.16.7", 234 | "@babel/generator": "^7.17.3", 235 | "@babel/helper-environment-visitor": "^7.16.7", 236 | "@babel/helper-function-name": "^7.16.7", 237 | "@babel/helper-hoist-variables": "^7.16.7", 238 | "@babel/helper-split-export-declaration": "^7.16.7", 239 | "@babel/parser": "^7.17.3", 240 | "@babel/types": "^7.17.0", 241 | "debug": "^4.1.0", 242 | "globals": "^11.1.0" 243 | } 244 | }, 245 | "@babel/types": { 246 | "version": "7.17.0", 247 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", 248 | "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", 249 | "dev": true, 250 | "requires": { 251 | "@babel/helper-validator-identifier": "^7.16.7", 252 | "to-fast-properties": "^2.0.0" 253 | } 254 | }, 255 | "@jridgewell/resolve-uri": { 256 | "version": "3.0.5", 257 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", 258 | "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==", 259 | "dev": true 260 | }, 261 | "@jridgewell/sourcemap-codec": { 262 | "version": "1.4.11", 263 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", 264 | "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==", 265 | "dev": true 266 | }, 267 | "@jridgewell/trace-mapping": { 268 | "version": "0.3.4", 269 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", 270 | "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", 271 | "dev": true, 272 | "requires": { 273 | "@jridgewell/resolve-uri": "^3.0.3", 274 | "@jridgewell/sourcemap-codec": "^1.4.10" 275 | } 276 | }, 277 | "@nodelib/fs.scandir": { 278 | "version": "2.1.5", 279 | "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", 280 | "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", 281 | "dev": true, 282 | "requires": { 283 | "@nodelib/fs.stat": "2.0.5", 284 | "run-parallel": "^1.1.9" 285 | } 286 | }, 287 | "@nodelib/fs.stat": { 288 | "version": "2.0.5", 289 | "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", 290 | "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", 291 | "dev": true 292 | }, 293 | "@nodelib/fs.walk": { 294 | "version": "1.2.8", 295 | "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", 296 | "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", 297 | "dev": true, 298 | "requires": { 299 | "@nodelib/fs.scandir": "2.1.5", 300 | "fastq": "^1.6.0" 301 | } 302 | }, 303 | "@rollup/plugin-alias": { 304 | "version": "3.1.9", 305 | "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-3.1.9.tgz", 306 | "integrity": "sha512-QI5fsEvm9bDzt32k39wpOwZhVzRcL5ydcffUHMyLVaVaLeC70I8TJZ17F1z1eMoLu4E/UOcH9BWVkKpIKdrfiw==", 307 | "dev": true, 308 | "requires": { 309 | "slash": "^3.0.0" 310 | } 311 | }, 312 | "@rollup/plugin-commonjs": { 313 | "version": "21.0.3", 314 | "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.0.3.tgz", 315 | "integrity": "sha512-ThGfwyvcLc6cfP/MWxA5ACF+LZCvsuhUq7V5134Az1oQWsiC7lNpLT4mJI86WQunK7BYmpUiHmMk2Op6OAHs0g==", 316 | "dev": true, 317 | "requires": { 318 | "@rollup/pluginutils": "^3.1.0", 319 | "commondir": "^1.0.1", 320 | "estree-walker": "^2.0.1", 321 | "glob": "^7.1.6", 322 | "is-reference": "^1.2.1", 323 | "magic-string": "^0.25.7", 324 | "resolve": "^1.17.0" 325 | }, 326 | "dependencies": { 327 | "@rollup/pluginutils": { 328 | "version": "3.1.0", 329 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", 330 | "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", 331 | "dev": true, 332 | "requires": { 333 | "@types/estree": "0.0.39", 334 | "estree-walker": "^1.0.1", 335 | "picomatch": "^2.2.2" 336 | }, 337 | "dependencies": { 338 | "estree-walker": { 339 | "version": "1.0.1", 340 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", 341 | "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", 342 | "dev": true 343 | } 344 | } 345 | }, 346 | "magic-string": { 347 | "version": "0.25.9", 348 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", 349 | "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", 350 | "dev": true, 351 | "requires": { 352 | "sourcemap-codec": "^1.4.8" 353 | } 354 | } 355 | } 356 | }, 357 | "@rollup/plugin-json": { 358 | "version": "4.1.0", 359 | "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", 360 | "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", 361 | "dev": true, 362 | "requires": { 363 | "@rollup/pluginutils": "^3.0.8" 364 | }, 365 | "dependencies": { 366 | "@rollup/pluginutils": { 367 | "version": "3.1.0", 368 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", 369 | "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", 370 | "dev": true, 371 | "requires": { 372 | "@types/estree": "0.0.39", 373 | "estree-walker": "^1.0.1", 374 | "picomatch": "^2.2.2" 375 | } 376 | }, 377 | "estree-walker": { 378 | "version": "1.0.1", 379 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", 380 | "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", 381 | "dev": true 382 | } 383 | } 384 | }, 385 | "@rollup/plugin-node-resolve": { 386 | "version": "13.1.3", 387 | "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.1.3.tgz", 388 | "integrity": "sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ==", 389 | "dev": true, 390 | "requires": { 391 | "@rollup/pluginutils": "^3.1.0", 392 | "@types/resolve": "1.17.1", 393 | "builtin-modules": "^3.1.0", 394 | "deepmerge": "^4.2.2", 395 | "is-module": "^1.0.0", 396 | "resolve": "^1.19.0" 397 | }, 398 | "dependencies": { 399 | "@rollup/pluginutils": { 400 | "version": "3.1.0", 401 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", 402 | "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", 403 | "dev": true, 404 | "requires": { 405 | "@types/estree": "0.0.39", 406 | "estree-walker": "^1.0.1", 407 | "picomatch": "^2.2.2" 408 | } 409 | }, 410 | "estree-walker": { 411 | "version": "1.0.1", 412 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", 413 | "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", 414 | "dev": true 415 | } 416 | } 417 | }, 418 | "@rollup/plugin-replace": { 419 | "version": "4.0.0", 420 | "resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-4.0.0.tgz", 421 | "integrity": "sha512-+rumQFiaNac9y64OHtkHGmdjm7us9bo1PlbgQfdihQtuNxzjpaB064HbRnewUOggLQxVCCyINfStkgmBeQpv1g==", 422 | "dev": true, 423 | "requires": { 424 | "@rollup/pluginutils": "^3.1.0", 425 | "magic-string": "^0.25.7" 426 | }, 427 | "dependencies": { 428 | "@rollup/pluginutils": { 429 | "version": "3.1.0", 430 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz", 431 | "integrity": "sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==", 432 | "dev": true, 433 | "requires": { 434 | "@types/estree": "0.0.39", 435 | "estree-walker": "^1.0.1", 436 | "picomatch": "^2.2.2" 437 | } 438 | }, 439 | "estree-walker": { 440 | "version": "1.0.1", 441 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-1.0.1.tgz", 442 | "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", 443 | "dev": true 444 | }, 445 | "magic-string": { 446 | "version": "0.25.9", 447 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", 448 | "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", 449 | "dev": true, 450 | "requires": { 451 | "sourcemap-codec": "^1.4.8" 452 | } 453 | } 454 | } 455 | }, 456 | "@rollup/pluginutils": { 457 | "version": "4.2.0", 458 | "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.0.tgz", 459 | "integrity": "sha512-2WUyJNRkyH5p487pGnn4tWAsxhEFKN/pT8CMgHshd5H+IXkOnKvKZwsz5ZWz+YCXkleZRAU5kwbfgF8CPfDRqA==", 460 | "dev": true, 461 | "requires": { 462 | "estree-walker": "^2.0.1", 463 | "picomatch": "^2.2.2" 464 | } 465 | }, 466 | "@types/estree": { 467 | "version": "0.0.39", 468 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", 469 | "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", 470 | "dev": true 471 | }, 472 | "@types/node": { 473 | "version": "17.0.23", 474 | "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", 475 | "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", 476 | "dev": true 477 | }, 478 | "@types/resolve": { 479 | "version": "1.17.1", 480 | "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", 481 | "integrity": "sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==", 482 | "dev": true, 483 | "requires": { 484 | "@types/node": "*" 485 | } 486 | }, 487 | "ansi-styles": { 488 | "version": "3.2.1", 489 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 490 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 491 | "dev": true, 492 | "requires": { 493 | "color-convert": "^1.9.0" 494 | } 495 | }, 496 | "array-union": { 497 | "version": "2.1.0", 498 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", 499 | "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", 500 | "dev": true 501 | }, 502 | "balanced-match": { 503 | "version": "1.0.2", 504 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 505 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 506 | "dev": true 507 | }, 508 | "brace-expansion": { 509 | "version": "1.1.11", 510 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 511 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 512 | "dev": true, 513 | "requires": { 514 | "balanced-match": "^1.0.0", 515 | "concat-map": "0.0.1" 516 | } 517 | }, 518 | "braces": { 519 | "version": "3.0.2", 520 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 521 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 522 | "dev": true, 523 | "requires": { 524 | "fill-range": "^7.0.1" 525 | } 526 | }, 527 | "browserslist": { 528 | "version": "4.20.2", 529 | "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", 530 | "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", 531 | "dev": true, 532 | "requires": { 533 | "caniuse-lite": "^1.0.30001317", 534 | "electron-to-chromium": "^1.4.84", 535 | "escalade": "^3.1.1", 536 | "node-releases": "^2.0.2", 537 | "picocolors": "^1.0.0" 538 | } 539 | }, 540 | "builtin-modules": { 541 | "version": "3.2.0", 542 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", 543 | "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", 544 | "dev": true 545 | }, 546 | "caniuse-lite": { 547 | "version": "1.0.30001324", 548 | "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001324.tgz", 549 | "integrity": "sha512-/eYp1J6zYh1alySQB4uzYFkLmxxI8tk0kxldbNHXp8+v+rdMKdUBNjRLz7T7fz6Iox+1lIdYpc7rq6ZcXfTukg==", 550 | "dev": true 551 | }, 552 | "color-convert": { 553 | "version": "1.9.3", 554 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 555 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 556 | "dev": true, 557 | "requires": { 558 | "color-name": "1.1.3" 559 | } 560 | }, 561 | "color-name": { 562 | "version": "1.1.3", 563 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 564 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 565 | "dev": true 566 | }, 567 | "commondir": { 568 | "version": "1.0.1", 569 | "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", 570 | "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", 571 | "dev": true 572 | }, 573 | "concat-map": { 574 | "version": "0.0.1", 575 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 576 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 577 | "dev": true 578 | }, 579 | "consola": { 580 | "version": "2.15.3", 581 | "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", 582 | "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==", 583 | "dev": true 584 | }, 585 | "convert-source-map": { 586 | "version": "1.8.0", 587 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", 588 | "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", 589 | "dev": true, 590 | "requires": { 591 | "safe-buffer": "~5.1.1" 592 | } 593 | }, 594 | "debug": { 595 | "version": "4.3.4", 596 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", 597 | "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", 598 | "dev": true, 599 | "requires": { 600 | "ms": "2.1.2" 601 | } 602 | }, 603 | "deepmerge": { 604 | "version": "4.2.2", 605 | "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", 606 | "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", 607 | "dev": true 608 | }, 609 | "defu": { 610 | "version": "5.0.1", 611 | "resolved": "https://registry.npmjs.org/defu/-/defu-5.0.1.tgz", 612 | "integrity": "sha512-EPS1carKg+dkEVy3qNTqIdp2qV7mUP08nIsupfwQpz++slCVRw7qbQyWvSTig+kFPwz2XXp5/kIIkH+CwrJKkQ==", 613 | "dev": true 614 | }, 615 | "dir-glob": { 616 | "version": "3.0.1", 617 | "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", 618 | "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", 619 | "dev": true, 620 | "requires": { 621 | "path-type": "^4.0.0" 622 | } 623 | }, 624 | "electron-to-chromium": { 625 | "version": "1.4.103", 626 | "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz", 627 | "integrity": "sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg==", 628 | "dev": true 629 | }, 630 | "es-module-lexer": { 631 | "version": "0.9.3", 632 | "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", 633 | "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", 634 | "dev": true 635 | }, 636 | "esbuild": { 637 | "version": "0.14.30", 638 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.30.tgz", 639 | "integrity": "sha512-wCecQSBkIjp2xjuXY+wcXS/PpOQo9rFh4NAKPh4Pm9f3fuLcnxkR0rDzA+mYP88FtXIUcXUyYmaIgfrzRl55jA==", 640 | "dev": true, 641 | "requires": { 642 | "esbuild-android-64": "0.14.30", 643 | "esbuild-android-arm64": "0.14.30", 644 | "esbuild-darwin-64": "0.14.30", 645 | "esbuild-darwin-arm64": "0.14.30", 646 | "esbuild-freebsd-64": "0.14.30", 647 | "esbuild-freebsd-arm64": "0.14.30", 648 | "esbuild-linux-32": "0.14.30", 649 | "esbuild-linux-64": "0.14.30", 650 | "esbuild-linux-arm": "0.14.30", 651 | "esbuild-linux-arm64": "0.14.30", 652 | "esbuild-linux-mips64le": "0.14.30", 653 | "esbuild-linux-ppc64le": "0.14.30", 654 | "esbuild-linux-riscv64": "0.14.30", 655 | "esbuild-linux-s390x": "0.14.30", 656 | "esbuild-netbsd-64": "0.14.30", 657 | "esbuild-openbsd-64": "0.14.30", 658 | "esbuild-sunos-64": "0.14.30", 659 | "esbuild-windows-32": "0.14.30", 660 | "esbuild-windows-64": "0.14.30", 661 | "esbuild-windows-arm64": "0.14.30" 662 | } 663 | }, 664 | "esbuild-android-64": { 665 | "version": "0.14.30", 666 | "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.30.tgz", 667 | "integrity": "sha512-vdJ7t8A8msPfKpYUGUV/KaTQRiZ0vDa2XSTlzXVkGGVHLKPeb85PBUtYJcEgw3htW3IdX5i1t1IMdQCwJJgNAg==", 668 | "dev": true, 669 | "optional": true 670 | }, 671 | "esbuild-android-arm64": { 672 | "version": "0.14.30", 673 | "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.30.tgz", 674 | "integrity": "sha512-BdgGfxeA5hBQNErLr7BWJUA8xjflEfyaARICy8e0OJYNSAwDbEzOf8LyiKWSrDcgV129mWhi3VpbNQvOIDEHcg==", 675 | "dev": true, 676 | "optional": true 677 | }, 678 | "esbuild-darwin-64": { 679 | "version": "0.14.30", 680 | "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.30.tgz", 681 | "integrity": "sha512-VRaOXMMrsG5n53pl4qFZQdXy2+E0NoLP/QH3aDUI0+bQP+ZHDmbINKcDy2IX7GVFI9kqPS18iJNAs5a6/G2LZg==", 682 | "dev": true, 683 | "optional": true 684 | }, 685 | "esbuild-darwin-arm64": { 686 | "version": "0.14.30", 687 | "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.30.tgz", 688 | "integrity": "sha512-qDez+fHMOrO9Oc9qjt/x+sy09RJVh62kik5tVybKRLmezeV4qczM9/sAYY57YN0aWLdHbcCj2YqJUWYJNsgKnw==", 689 | "dev": true, 690 | "optional": true 691 | }, 692 | "esbuild-freebsd-64": { 693 | "version": "0.14.30", 694 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.30.tgz", 695 | "integrity": "sha512-mec1jENcImVVagddZlGWsdAUwBnzR5cgnhzCxv+9fSMxKbx1uZYLLUAnLPp8m/i934zrumR1xGjJ5VoWdPlI2w==", 696 | "dev": true, 697 | "optional": true 698 | }, 699 | "esbuild-freebsd-arm64": { 700 | "version": "0.14.30", 701 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.30.tgz", 702 | "integrity": "sha512-cpjbTs6Iok/AfeB0JgTzyUJTMStC1SQULmany5nHx6S4GTkSgaAHuJzZO0GcVWqghI4e0YL/bjXAhN5Mn6feNw==", 703 | "dev": true, 704 | "optional": true 705 | }, 706 | "esbuild-linux-32": { 707 | "version": "0.14.30", 708 | "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.30.tgz", 709 | "integrity": "sha512-liIONVT4F2kZmOMwtwASqZ8WkIjb5HHBR9HUffdHiuotSTF3CyZO+EJf+Og+SYYuuVIvt0qHNSFjBA/iSESteQ==", 710 | "dev": true, 711 | "optional": true 712 | }, 713 | "esbuild-linux-64": { 714 | "version": "0.14.30", 715 | "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.30.tgz", 716 | "integrity": "sha512-LUnpzoMpRqFON5En4qEj6NWiyH6a1K+Y2qYNKrCy5qPTjDoG/EWeqMz69n8Uv7pRuvDKl3FNGJ1dufTrA5i0sw==", 717 | "dev": true, 718 | "optional": true 719 | }, 720 | "esbuild-linux-arm": { 721 | "version": "0.14.30", 722 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.30.tgz", 723 | "integrity": "sha512-97T+bbXnpqf7mfIG49UR7ZSJFGgvc22byn74qw3Kx2GDCBSQoVFjyWuKOHGXp8nXk3XYrdFF+mQ8yQ7aNsgQvg==", 724 | "dev": true, 725 | "optional": true 726 | }, 727 | "esbuild-linux-arm64": { 728 | "version": "0.14.30", 729 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.30.tgz", 730 | "integrity": "sha512-DHZHn6FK5q/KL0fpNT/0jE38Nnyk2rXxKE9WENi95EXtqfOLPgE8tzjTZQNgpr61R95QX4ymQU26ni3IZk8buQ==", 731 | "dev": true, 732 | "optional": true 733 | }, 734 | "esbuild-linux-mips64le": { 735 | "version": "0.14.30", 736 | "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.30.tgz", 737 | "integrity": "sha512-fLUzTFZ7uknC0aPTk7/lM7NmaG/9ZqE3SaHEphcaM009SZK/mDOvZugWi1ss6WGNhk13dUrhkfHcc4FSb9hYhg==", 738 | "dev": true, 739 | "optional": true 740 | }, 741 | "esbuild-linux-ppc64le": { 742 | "version": "0.14.30", 743 | "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.30.tgz", 744 | "integrity": "sha512-2Oudm2WEfj0dNU9bzIl5L/LrsMEmHWsOsYgJJqu8fDyUDgER+J1d33qz3cUdjsJk7gAENayIxDSpsuCszx0w3A==", 745 | "dev": true, 746 | "optional": true 747 | }, 748 | "esbuild-linux-riscv64": { 749 | "version": "0.14.30", 750 | "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.30.tgz", 751 | "integrity": "sha512-RPMucPW47rV4t2jlelaE948iCRtbZf5RhifxSwzlpM1Mqdyu99MMNK0w4jFreGTmLN+oGomxIOxD6n+2E/XqHw==", 752 | "dev": true, 753 | "optional": true 754 | }, 755 | "esbuild-linux-s390x": { 756 | "version": "0.14.30", 757 | "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.30.tgz", 758 | "integrity": "sha512-OZ68r7ok6qO7hdwrwQn2p5jbIRRcUcVaAykB7e0uCA0ODwfeGunILM6phJtq2Oz4dlEEFvd+tSuma3paQKwt+A==", 759 | "dev": true, 760 | "optional": true 761 | }, 762 | "esbuild-netbsd-64": { 763 | "version": "0.14.30", 764 | "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.30.tgz", 765 | "integrity": "sha512-iyejQUKn0TzpPkufq8pSCxOg9NheycQbMbPCmjefTe9wYuUlBt1TcHvdoJnYbQzsAhAh1BNq+s0ycRsIJFZzaQ==", 766 | "dev": true, 767 | "optional": true 768 | }, 769 | "esbuild-openbsd-64": { 770 | "version": "0.14.30", 771 | "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.30.tgz", 772 | "integrity": "sha512-UyK1MTMcy4j5fH260fsE1o6MVgWNhb62eCK2yCKCRazZv8Nqdc2WiP9ygjWidmEdCDS+A6MuVp9ozk9uoQtQpA==", 773 | "dev": true, 774 | "optional": true 775 | }, 776 | "esbuild-sunos-64": { 777 | "version": "0.14.30", 778 | "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.30.tgz", 779 | "integrity": "sha512-aQRtRTNKHB4YuG+xXATe5AoRTNY48IJg5vjE8ElxfmjO9+KdX7MHFkTLhlKevCD6rNANtB3qOlSIeAiXTwHNqw==", 780 | "dev": true, 781 | "optional": true 782 | }, 783 | "esbuild-windows-32": { 784 | "version": "0.14.30", 785 | "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.30.tgz", 786 | "integrity": "sha512-9/fb1tPtpacMqxAXp3fGHowUDg/l9dVch5hKmCLEZC6PdGljh6h372zMdJwYfH0Bd5CCPT0Wx95uycBLJiqpXA==", 787 | "dev": true, 788 | "optional": true 789 | }, 790 | "esbuild-windows-64": { 791 | "version": "0.14.30", 792 | "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.30.tgz", 793 | "integrity": "sha512-DHgITeUhPAnN9I5O6QBa1GVyPOhiYCn4S4TtQr7sO4+X0LNyqnlmA1M0qmGkUdDC1QQfjI8uQ4G/whdWb2pWIQ==", 794 | "dev": true, 795 | "optional": true 796 | }, 797 | "esbuild-windows-arm64": { 798 | "version": "0.14.30", 799 | "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.30.tgz", 800 | "integrity": "sha512-F1kLyQH7zSgjh5eLxogGZN7C9+KNs9m+s7Q6WZoMmCWT/6j998zlaoECHyM8izJRRfsvw2eZlEa1jO6/IOU1AQ==", 801 | "dev": true, 802 | "optional": true 803 | }, 804 | "escalade": { 805 | "version": "3.1.1", 806 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", 807 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", 808 | "dev": true 809 | }, 810 | "escape-string-regexp": { 811 | "version": "1.0.5", 812 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 813 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 814 | "dev": true 815 | }, 816 | "estree-walker": { 817 | "version": "2.0.2", 818 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", 819 | "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", 820 | "dev": true 821 | }, 822 | "fast-glob": { 823 | "version": "3.2.11", 824 | "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", 825 | "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", 826 | "dev": true, 827 | "requires": { 828 | "@nodelib/fs.stat": "^2.0.2", 829 | "@nodelib/fs.walk": "^1.2.3", 830 | "glob-parent": "^5.1.2", 831 | "merge2": "^1.3.0", 832 | "micromatch": "^4.0.4" 833 | } 834 | }, 835 | "fastq": { 836 | "version": "1.13.0", 837 | "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", 838 | "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", 839 | "dev": true, 840 | "requires": { 841 | "reusify": "^1.0.4" 842 | } 843 | }, 844 | "fill-range": { 845 | "version": "7.0.1", 846 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 847 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 848 | "dev": true, 849 | "requires": { 850 | "to-regex-range": "^5.0.1" 851 | } 852 | }, 853 | "fs-extra": { 854 | "version": "10.0.1", 855 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", 856 | "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", 857 | "dev": true, 858 | "requires": { 859 | "graceful-fs": "^4.2.0", 860 | "jsonfile": "^6.0.1", 861 | "universalify": "^2.0.0" 862 | } 863 | }, 864 | "fs.realpath": { 865 | "version": "1.0.0", 866 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 867 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 868 | "dev": true 869 | }, 870 | "fsevents": { 871 | "version": "2.3.2", 872 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 873 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 874 | "dev": true, 875 | "optional": true 876 | }, 877 | "function-bind": { 878 | "version": "1.1.1", 879 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 880 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 881 | "dev": true 882 | }, 883 | "gensync": { 884 | "version": "1.0.0-beta.2", 885 | "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", 886 | "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", 887 | "dev": true 888 | }, 889 | "glob": { 890 | "version": "7.2.0", 891 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", 892 | "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", 893 | "dev": true, 894 | "requires": { 895 | "fs.realpath": "^1.0.0", 896 | "inflight": "^1.0.4", 897 | "inherits": "2", 898 | "minimatch": "^3.0.4", 899 | "once": "^1.3.0", 900 | "path-is-absolute": "^1.0.0" 901 | } 902 | }, 903 | "glob-parent": { 904 | "version": "5.1.2", 905 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 906 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 907 | "dev": true, 908 | "requires": { 909 | "is-glob": "^4.0.1" 910 | } 911 | }, 912 | "globals": { 913 | "version": "11.12.0", 914 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 915 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 916 | "dev": true 917 | }, 918 | "globby": { 919 | "version": "11.1.0", 920 | "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", 921 | "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", 922 | "dev": true, 923 | "requires": { 924 | "array-union": "^2.1.0", 925 | "dir-glob": "^3.0.1", 926 | "fast-glob": "^3.2.9", 927 | "ignore": "^5.2.0", 928 | "merge2": "^1.4.1", 929 | "slash": "^3.0.0" 930 | } 931 | }, 932 | "graceful-fs": { 933 | "version": "4.2.9", 934 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", 935 | "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", 936 | "dev": true 937 | }, 938 | "has": { 939 | "version": "1.0.3", 940 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 941 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 942 | "dev": true, 943 | "requires": { 944 | "function-bind": "^1.1.1" 945 | } 946 | }, 947 | "has-flag": { 948 | "version": "3.0.0", 949 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 950 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 951 | "dev": true 952 | }, 953 | "hookable": { 954 | "version": "5.1.1", 955 | "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.1.1.tgz", 956 | "integrity": "sha512-7qam9XBFb+DijNBthaL1k/7lHU2TEMZkWSyuqmU3sCQze1wFm5w9AlEx30PD7a+QVAjOy6Ec2goFwe1YVyk2uA==", 957 | "dev": true 958 | }, 959 | "ignore": { 960 | "version": "5.2.0", 961 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", 962 | "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", 963 | "dev": true 964 | }, 965 | "inflight": { 966 | "version": "1.0.6", 967 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 968 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 969 | "dev": true, 970 | "requires": { 971 | "once": "^1.3.0", 972 | "wrappy": "1" 973 | } 974 | }, 975 | "inherits": { 976 | "version": "2.0.4", 977 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 978 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 979 | "dev": true 980 | }, 981 | "is-core-module": { 982 | "version": "2.8.1", 983 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", 984 | "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", 985 | "dev": true, 986 | "requires": { 987 | "has": "^1.0.3" 988 | } 989 | }, 990 | "is-extglob": { 991 | "version": "2.1.1", 992 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 993 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 994 | "dev": true 995 | }, 996 | "is-glob": { 997 | "version": "4.0.3", 998 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 999 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 1000 | "dev": true, 1001 | "requires": { 1002 | "is-extglob": "^2.1.1" 1003 | } 1004 | }, 1005 | "is-module": { 1006 | "version": "1.0.0", 1007 | "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", 1008 | "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", 1009 | "dev": true 1010 | }, 1011 | "is-number": { 1012 | "version": "7.0.0", 1013 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 1014 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 1015 | "dev": true 1016 | }, 1017 | "is-reference": { 1018 | "version": "1.2.1", 1019 | "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", 1020 | "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==", 1021 | "dev": true, 1022 | "requires": { 1023 | "@types/estree": "*" 1024 | } 1025 | }, 1026 | "jiti": { 1027 | "version": "1.13.0", 1028 | "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.13.0.tgz", 1029 | "integrity": "sha512-/n9mNxZj/HDSrincJ6RP+L+yXbpnB8FybySBa+IjIaoH9FIxBbrbRT5XUbe8R7zuVM2AQqNMNDDqz0bzx3znOQ==", 1030 | "dev": true 1031 | }, 1032 | "joycon": { 1033 | "version": "3.1.1", 1034 | "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", 1035 | "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", 1036 | "dev": true 1037 | }, 1038 | "js-tokens": { 1039 | "version": "4.0.0", 1040 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 1041 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 1042 | "dev": true 1043 | }, 1044 | "jsesc": { 1045 | "version": "2.5.2", 1046 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", 1047 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", 1048 | "dev": true 1049 | }, 1050 | "json5": { 1051 | "version": "2.2.1", 1052 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", 1053 | "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", 1054 | "dev": true 1055 | }, 1056 | "jsonc-parser": { 1057 | "version": "3.0.0", 1058 | "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", 1059 | "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==", 1060 | "dev": true 1061 | }, 1062 | "jsonfile": { 1063 | "version": "6.1.0", 1064 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", 1065 | "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", 1066 | "dev": true, 1067 | "requires": { 1068 | "graceful-fs": "^4.1.6", 1069 | "universalify": "^2.0.0" 1070 | } 1071 | }, 1072 | "magic-string": { 1073 | "version": "0.26.1", 1074 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.1.tgz", 1075 | "integrity": "sha512-ndThHmvgtieXe8J/VGPjG+Apu7v7ItcD5mhEIvOscWjPF/ccOiLxHaSuCAS2G+3x4GKsAbT8u7zdyamupui8Tg==", 1076 | "dev": true, 1077 | "requires": { 1078 | "sourcemap-codec": "^1.4.8" 1079 | } 1080 | }, 1081 | "merge2": { 1082 | "version": "1.4.1", 1083 | "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", 1084 | "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", 1085 | "dev": true 1086 | }, 1087 | "micromatch": { 1088 | "version": "4.0.5", 1089 | "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", 1090 | "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", 1091 | "dev": true, 1092 | "requires": { 1093 | "braces": "^3.0.2", 1094 | "picomatch": "^2.3.1" 1095 | } 1096 | }, 1097 | "minimatch": { 1098 | "version": "3.1.2", 1099 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1100 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1101 | "dev": true, 1102 | "requires": { 1103 | "brace-expansion": "^1.1.7" 1104 | } 1105 | }, 1106 | "mkdirp": { 1107 | "version": "1.0.4", 1108 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", 1109 | "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", 1110 | "dev": true 1111 | }, 1112 | "mkdist": { 1113 | "version": "0.3.10", 1114 | "resolved": "https://registry.npmjs.org/mkdist/-/mkdist-0.3.10.tgz", 1115 | "integrity": "sha512-Aoc6hjILr2JPUJU2OUvBiD5sZ/CG1FeiXwk6KKPqE0iSTjBCrjrVK/fP5ig+TB3AKHvh2aA2QXXGeXVCJBdSwg==", 1116 | "dev": true, 1117 | "requires": { 1118 | "defu": "^5.0.0", 1119 | "esbuild": "^0.13.8", 1120 | "fs-extra": "^10.0.0", 1121 | "globby": "^11.0.3", 1122 | "jiti": "^1.12.9", 1123 | "mri": "^1.2.0", 1124 | "pathe": "^0.2.0" 1125 | }, 1126 | "dependencies": { 1127 | "esbuild": { 1128 | "version": "0.13.15", 1129 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.13.15.tgz", 1130 | "integrity": "sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw==", 1131 | "dev": true, 1132 | "requires": { 1133 | "esbuild-android-arm64": "0.13.15", 1134 | "esbuild-darwin-64": "0.13.15", 1135 | "esbuild-darwin-arm64": "0.13.15", 1136 | "esbuild-freebsd-64": "0.13.15", 1137 | "esbuild-freebsd-arm64": "0.13.15", 1138 | "esbuild-linux-32": "0.13.15", 1139 | "esbuild-linux-64": "0.13.15", 1140 | "esbuild-linux-arm": "0.13.15", 1141 | "esbuild-linux-arm64": "0.13.15", 1142 | "esbuild-linux-mips64le": "0.13.15", 1143 | "esbuild-linux-ppc64le": "0.13.15", 1144 | "esbuild-netbsd-64": "0.13.15", 1145 | "esbuild-openbsd-64": "0.13.15", 1146 | "esbuild-sunos-64": "0.13.15", 1147 | "esbuild-windows-32": "0.13.15", 1148 | "esbuild-windows-64": "0.13.15", 1149 | "esbuild-windows-arm64": "0.13.15" 1150 | } 1151 | }, 1152 | "esbuild-android-arm64": { 1153 | "version": "0.13.15", 1154 | "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz", 1155 | "integrity": "sha512-m602nft/XXeO8YQPUDVoHfjyRVPdPgjyyXOxZ44MK/agewFFkPa8tUo6lAzSWh5Ui5PB4KR9UIFTSBKh/RrCmg==", 1156 | "dev": true, 1157 | "optional": true 1158 | }, 1159 | "esbuild-darwin-64": { 1160 | "version": "0.13.15", 1161 | "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.13.15.tgz", 1162 | "integrity": "sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ==", 1163 | "dev": true, 1164 | "optional": true 1165 | }, 1166 | "esbuild-darwin-arm64": { 1167 | "version": "0.13.15", 1168 | "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.15.tgz", 1169 | "integrity": "sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ==", 1170 | "dev": true, 1171 | "optional": true 1172 | }, 1173 | "esbuild-freebsd-64": { 1174 | "version": "0.13.15", 1175 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.15.tgz", 1176 | "integrity": "sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA==", 1177 | "dev": true, 1178 | "optional": true 1179 | }, 1180 | "esbuild-freebsd-arm64": { 1181 | "version": "0.13.15", 1182 | "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.15.tgz", 1183 | "integrity": "sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ==", 1184 | "dev": true, 1185 | "optional": true 1186 | }, 1187 | "esbuild-linux-32": { 1188 | "version": "0.13.15", 1189 | "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.13.15.tgz", 1190 | "integrity": "sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g==", 1191 | "dev": true, 1192 | "optional": true 1193 | }, 1194 | "esbuild-linux-64": { 1195 | "version": "0.13.15", 1196 | "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.13.15.tgz", 1197 | "integrity": "sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA==", 1198 | "dev": true, 1199 | "optional": true 1200 | }, 1201 | "esbuild-linux-arm": { 1202 | "version": "0.13.15", 1203 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.13.15.tgz", 1204 | "integrity": "sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA==", 1205 | "dev": true, 1206 | "optional": true 1207 | }, 1208 | "esbuild-linux-arm64": { 1209 | "version": "0.13.15", 1210 | "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.15.tgz", 1211 | "integrity": "sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA==", 1212 | "dev": true, 1213 | "optional": true 1214 | }, 1215 | "esbuild-linux-mips64le": { 1216 | "version": "0.13.15", 1217 | "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.15.tgz", 1218 | "integrity": "sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg==", 1219 | "dev": true, 1220 | "optional": true 1221 | }, 1222 | "esbuild-linux-ppc64le": { 1223 | "version": "0.13.15", 1224 | "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.15.tgz", 1225 | "integrity": "sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ==", 1226 | "dev": true, 1227 | "optional": true 1228 | }, 1229 | "esbuild-netbsd-64": { 1230 | "version": "0.13.15", 1231 | "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.15.tgz", 1232 | "integrity": "sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w==", 1233 | "dev": true, 1234 | "optional": true 1235 | }, 1236 | "esbuild-openbsd-64": { 1237 | "version": "0.13.15", 1238 | "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.15.tgz", 1239 | "integrity": "sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g==", 1240 | "dev": true, 1241 | "optional": true 1242 | }, 1243 | "esbuild-sunos-64": { 1244 | "version": "0.13.15", 1245 | "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.13.15.tgz", 1246 | "integrity": "sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw==", 1247 | "dev": true, 1248 | "optional": true 1249 | }, 1250 | "esbuild-windows-32": { 1251 | "version": "0.13.15", 1252 | "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.13.15.tgz", 1253 | "integrity": "sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw==", 1254 | "dev": true, 1255 | "optional": true 1256 | }, 1257 | "esbuild-windows-64": { 1258 | "version": "0.13.15", 1259 | "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.13.15.tgz", 1260 | "integrity": "sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ==", 1261 | "dev": true, 1262 | "optional": true 1263 | }, 1264 | "esbuild-windows-arm64": { 1265 | "version": "0.13.15", 1266 | "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.15.tgz", 1267 | "integrity": "sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA==", 1268 | "dev": true, 1269 | "optional": true 1270 | } 1271 | } 1272 | }, 1273 | "mlly": { 1274 | "version": "0.4.3", 1275 | "resolved": "https://registry.npmjs.org/mlly/-/mlly-0.4.3.tgz", 1276 | "integrity": "sha512-xezyv7hnfFPuiDS3AiJuWs0OxlvooS++3L2lURvmh/1n7UG4O2Ehz9UkwWgg3wyLEPKGVfJLlr2DjjTCl9UJTg==", 1277 | "dev": true 1278 | }, 1279 | "mri": { 1280 | "version": "1.2.0", 1281 | "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", 1282 | "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", 1283 | "dev": true 1284 | }, 1285 | "ms": { 1286 | "version": "2.1.2", 1287 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1288 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1289 | "dev": true 1290 | }, 1291 | "node-releases": { 1292 | "version": "2.0.2", 1293 | "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", 1294 | "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", 1295 | "dev": true 1296 | }, 1297 | "once": { 1298 | "version": "1.4.0", 1299 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1300 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1301 | "dev": true, 1302 | "requires": { 1303 | "wrappy": "1" 1304 | } 1305 | }, 1306 | "path-is-absolute": { 1307 | "version": "1.0.1", 1308 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1309 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1310 | "dev": true 1311 | }, 1312 | "path-parse": { 1313 | "version": "1.0.7", 1314 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", 1315 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", 1316 | "dev": true 1317 | }, 1318 | "path-type": { 1319 | "version": "4.0.0", 1320 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", 1321 | "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", 1322 | "dev": true 1323 | }, 1324 | "pathe": { 1325 | "version": "0.2.0", 1326 | "resolved": "https://registry.npmjs.org/pathe/-/pathe-0.2.0.tgz", 1327 | "integrity": "sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==", 1328 | "dev": true 1329 | }, 1330 | "picocolors": { 1331 | "version": "1.0.0", 1332 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", 1333 | "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", 1334 | "dev": true 1335 | }, 1336 | "picomatch": { 1337 | "version": "2.3.1", 1338 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 1339 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 1340 | "dev": true 1341 | }, 1342 | "pkg-types": { 1343 | "version": "0.3.2", 1344 | "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-0.3.2.tgz", 1345 | "integrity": "sha512-eBYzX/7NYsQEOR2alWY4rnQB49G62oHzFpoi9Som56aUr8vB8UGcmcIia9v8fpBeuhH3Ltentuk2OGpp4IQV3Q==", 1346 | "dev": true, 1347 | "requires": { 1348 | "jsonc-parser": "^3.0.0", 1349 | "mlly": "^0.3.6", 1350 | "pathe": "^0.2.0" 1351 | }, 1352 | "dependencies": { 1353 | "mlly": { 1354 | "version": "0.3.19", 1355 | "resolved": "https://registry.npmjs.org/mlly/-/mlly-0.3.19.tgz", 1356 | "integrity": "sha512-zMq5n3cOf4fOzA4WoeulxagbAgMChdev3MgP6K51k7M0u2whTXxupfIY4VVzws4vxkiWhwH1rVQcsw7zDGfRhA==", 1357 | "dev": true 1358 | } 1359 | } 1360 | }, 1361 | "pretty-bytes": { 1362 | "version": "6.0.0", 1363 | "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.0.0.tgz", 1364 | "integrity": "sha512-6UqkYefdogmzqAZWzJ7laYeJnaXDy2/J+ZqiiMtS7t7OfpXWTlaeGMwX8U6EFvPV/YWWEKRkS8hKS4k60WHTOg==", 1365 | "dev": true 1366 | }, 1367 | "queue-microtask": { 1368 | "version": "1.2.3", 1369 | "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", 1370 | "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", 1371 | "dev": true 1372 | }, 1373 | "resolve": { 1374 | "version": "1.22.0", 1375 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", 1376 | "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", 1377 | "dev": true, 1378 | "requires": { 1379 | "is-core-module": "^2.8.1", 1380 | "path-parse": "^1.0.7", 1381 | "supports-preserve-symlinks-flag": "^1.0.0" 1382 | } 1383 | }, 1384 | "reusify": { 1385 | "version": "1.0.4", 1386 | "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", 1387 | "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", 1388 | "dev": true 1389 | }, 1390 | "rimraf": { 1391 | "version": "3.0.2", 1392 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 1393 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", 1394 | "dev": true, 1395 | "requires": { 1396 | "glob": "^7.1.3" 1397 | } 1398 | }, 1399 | "rollup": { 1400 | "version": "2.70.1", 1401 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.1.tgz", 1402 | "integrity": "sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA==", 1403 | "dev": true, 1404 | "requires": { 1405 | "fsevents": "~2.3.2" 1406 | } 1407 | }, 1408 | "rollup-plugin-dts": { 1409 | "version": "4.2.0", 1410 | "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-4.2.0.tgz", 1411 | "integrity": "sha512-lx6irWVhz/x4//tIqRhzk4FOqGQ0n37ZM2wpPCn4uafl/EmiV92om7ZdAsq7Bzho6C+Xh5GfsyuP9H+Udv72Lg==", 1412 | "dev": true, 1413 | "requires": { 1414 | "@babel/code-frame": "^7.16.7", 1415 | "magic-string": "^0.26.1" 1416 | } 1417 | }, 1418 | "rollup-plugin-esbuild": { 1419 | "version": "4.8.2", 1420 | "resolved": "https://registry.npmjs.org/rollup-plugin-esbuild/-/rollup-plugin-esbuild-4.8.2.tgz", 1421 | "integrity": "sha512-wsaYNOjzTb6dN1qCIZsMZ7Q0LWiPJklYs2TDI8vJA2LUbvtPUY+17TC8C0vSat3jPMInfR9XWKdA7ttuwkjsGQ==", 1422 | "dev": true, 1423 | "requires": { 1424 | "@rollup/pluginutils": "^4.1.1", 1425 | "debug": "^4.3.3", 1426 | "es-module-lexer": "^0.9.3", 1427 | "joycon": "^3.0.1", 1428 | "jsonc-parser": "^3.0.0" 1429 | } 1430 | }, 1431 | "run-parallel": { 1432 | "version": "1.2.0", 1433 | "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", 1434 | "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", 1435 | "dev": true, 1436 | "requires": { 1437 | "queue-microtask": "^1.2.2" 1438 | } 1439 | }, 1440 | "safe-buffer": { 1441 | "version": "5.1.2", 1442 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1443 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 1444 | "dev": true 1445 | }, 1446 | "scule": { 1447 | "version": "0.2.1", 1448 | "resolved": "https://registry.npmjs.org/scule/-/scule-0.2.1.tgz", 1449 | "integrity": "sha512-M9gnWtn3J0W+UhJOHmBxBTwv8mZCan5i1Himp60t6vvZcor0wr+IM0URKmIglsWJ7bRujNAVVN77fp+uZaWoKg==", 1450 | "dev": true 1451 | }, 1452 | "semver": { 1453 | "version": "6.3.0", 1454 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 1455 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 1456 | "dev": true 1457 | }, 1458 | "slash": { 1459 | "version": "3.0.0", 1460 | "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", 1461 | "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", 1462 | "dev": true 1463 | }, 1464 | "source-map": { 1465 | "version": "0.5.7", 1466 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 1467 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", 1468 | "dev": true 1469 | }, 1470 | "sourcemap-codec": { 1471 | "version": "1.4.8", 1472 | "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", 1473 | "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", 1474 | "dev": true 1475 | }, 1476 | "supports-color": { 1477 | "version": "5.5.0", 1478 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1479 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1480 | "dev": true, 1481 | "requires": { 1482 | "has-flag": "^3.0.0" 1483 | } 1484 | }, 1485 | "supports-preserve-symlinks-flag": { 1486 | "version": "1.0.0", 1487 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 1488 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 1489 | "dev": true 1490 | }, 1491 | "to-fast-properties": { 1492 | "version": "2.0.0", 1493 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", 1494 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", 1495 | "dev": true 1496 | }, 1497 | "to-regex-range": { 1498 | "version": "5.0.1", 1499 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1500 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1501 | "dev": true, 1502 | "requires": { 1503 | "is-number": "^7.0.0" 1504 | } 1505 | }, 1506 | "typescript": { 1507 | "version": "4.6.3", 1508 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", 1509 | "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", 1510 | "dev": true 1511 | }, 1512 | "unbuild": { 1513 | "version": "0.7.2", 1514 | "resolved": "https://registry.npmjs.org/unbuild/-/unbuild-0.7.2.tgz", 1515 | "integrity": "sha512-79Kc8aYyCJiVIJPTRIiQSV99y3m34Kd0E7Y7z9YxvdjERDUBX32J62WmRzuhNfUJffEO4+pRosYSaR0X5wOmyQ==", 1516 | "dev": true, 1517 | "requires": { 1518 | "@rollup/plugin-alias": "^3.1.9", 1519 | "@rollup/plugin-commonjs": "^21.0.2", 1520 | "@rollup/plugin-json": "^4.1.0", 1521 | "@rollup/plugin-node-resolve": "^13.1.3", 1522 | "@rollup/plugin-replace": "^4.0.0", 1523 | "@rollup/pluginutils": "^4.2.0", 1524 | "chalk": "^5.0.1", 1525 | "consola": "^2.15.3", 1526 | "defu": "^5.0.1", 1527 | "esbuild": "^0.14.25", 1528 | "hookable": "^5.1.1", 1529 | "jiti": "^1.13.0", 1530 | "magic-string": "^0.26.1", 1531 | "mkdirp": "^1.0.4", 1532 | "mkdist": "^0.3.10", 1533 | "mlly": "^0.4.3", 1534 | "mri": "^1.2.0", 1535 | "pathe": "^0.2.0", 1536 | "pkg-types": "^0.3.2", 1537 | "pretty-bytes": "^6.0.0", 1538 | "rimraf": "^3.0.2", 1539 | "rollup": "^2.70.0", 1540 | "rollup-plugin-dts": "^4.2.0", 1541 | "rollup-plugin-esbuild": "^4.8.2", 1542 | "scule": "^0.2.1", 1543 | "typescript": "^4.6.2", 1544 | "untyped": "^0.4.0" 1545 | }, 1546 | "dependencies": { 1547 | "chalk": { 1548 | "version": "5.0.1", 1549 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", 1550 | "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", 1551 | "dev": true 1552 | } 1553 | } 1554 | }, 1555 | "universalify": { 1556 | "version": "2.0.0", 1557 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", 1558 | "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", 1559 | "dev": true 1560 | }, 1561 | "untyped": { 1562 | "version": "0.4.4", 1563 | "resolved": "https://registry.npmjs.org/untyped/-/untyped-0.4.4.tgz", 1564 | "integrity": "sha512-sY6u8RedwfLfBis0copfU/fzROieyAndqPs8Kn2PfyzTjtA88vCk81J1b5z+8/VJc+cwfGy23/AqOCpvAbkNVw==", 1565 | "dev": true, 1566 | "requires": { 1567 | "@babel/core": "^7.17.7", 1568 | "@babel/standalone": "^7.17.7", 1569 | "@babel/types": "^7.17.0", 1570 | "scule": "^0.2.1" 1571 | } 1572 | }, 1573 | "wrappy": { 1574 | "version": "1.0.2", 1575 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1576 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1577 | "dev": true 1578 | } 1579 | } 1580 | } 1581 | -------------------------------------------------------------------------------- /packages/common/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@inkline/paper-common", 3 | "description": "Inkline Paper Common package.", 4 | "scripts": { 5 | "build": "unbuild" 6 | }, 7 | "devDependencies": { 8 | "unbuild": "0.7.2" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/inkline/paper.git" 13 | }, 14 | "license": "ISC" 15 | } 16 | -------------------------------------------------------------------------------- /packages/common/src/computed.ts: -------------------------------------------------------------------------------- 1 | import { ComputedFn } from './types'; 2 | 3 | export const computed: ComputedFn = (computeFn) => { 4 | return { 5 | get value () { 6 | return computeFn(); 7 | } 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/common/src/defineComponent.ts: -------------------------------------------------------------------------------- 1 | import { 2 | EmitFn, 3 | HasSlotFn, 4 | RenderContext, 5 | SetupContext, 6 | SlotFn, 7 | DefineComponentFn, InjectFn, ProvideFn 8 | } from './types'; 9 | 10 | export const defineComponent: DefineComponentFn, Record> = (definition) => { 11 | return (props: any) => { 12 | const slot: SlotFn = (name = 'default') => { 13 | console.log(`slot(${name})`); 14 | return []; 15 | }; 16 | 17 | const hasSlot: HasSlotFn = (name = 'default') => { 18 | return slot(name).length > 0; 19 | }; 20 | 21 | const emit: EmitFn = (eventName, ...args) => { 22 | console.log(`emit(${event})`, ...args); 23 | }; 24 | 25 | const provide: ProvideFn = (identifier, value) => { 26 | console.log(`provide(${identifier.toString()}, ${value})`); 27 | return value; 28 | }; 29 | 30 | const inject: InjectFn = (identifier, defaultValue) => { 31 | console.log(`inject(${identifier.toString()}, ${defaultValue})`); 32 | return defaultValue; 33 | }; 34 | 35 | /** 36 | * Setup context 37 | */ 38 | const setupContext: SetupContext = { 39 | emit, 40 | provide, 41 | inject, 42 | hasSlot 43 | }; 44 | 45 | /** 46 | * State and props 47 | */ 48 | const state = definition.setup 49 | ? { ...props, ...definition.setup(props, setupContext) } 50 | : props; 51 | 52 | /** 53 | * Render context 54 | */ 55 | const renderContext: RenderContext = { 56 | slot, 57 | hasSlot 58 | }; 59 | 60 | /** 61 | * Render 62 | */ 63 | return definition.render(state, renderContext); 64 | }; 65 | }; 66 | -------------------------------------------------------------------------------- /packages/common/src/definePlugin.ts: -------------------------------------------------------------------------------- 1 | import { DefinePluginFn } from './types'; 2 | 3 | export type DefineGenericPluginFn = DefinePluginFn; 4 | 5 | export const definePlugin: DefineGenericPluginFn = () => ({}); 6 | -------------------------------------------------------------------------------- /packages/common/src/events.ts: -------------------------------------------------------------------------------- 1 | export enum Events { 2 | onInputChange = 'onChange' 3 | } 4 | -------------------------------------------------------------------------------- /packages/common/src/fragment.ts: -------------------------------------------------------------------------------- 1 | import { FragmentFn } from './types'; 2 | 3 | export const Fragment: FragmentFn = (props) => { 4 | return props.children; 5 | }; 6 | -------------------------------------------------------------------------------- /packages/common/src/h.ts: -------------------------------------------------------------------------------- 1 | import { HoistFn } from './types'; 2 | 3 | export const h: HoistFn = (type, props?, children?) => { 4 | return null; 5 | }; 6 | -------------------------------------------------------------------------------- /packages/common/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './computed'; 2 | export * from './defineComponent'; 3 | export * from './definePlugin'; 4 | export * from './events'; 5 | export * from './fragment'; 6 | export * from './h'; 7 | export * from './provide'; 8 | export * from './ref'; 9 | export * from './types'; 10 | export * from './watch'; 11 | -------------------------------------------------------------------------------- /packages/common/src/provide.ts: -------------------------------------------------------------------------------- 1 | import { InjectFn, ProvideFn } from './types'; 2 | 3 | export const provide: ProvideFn = (identifier, value, dependencies?) => {}; 4 | export const inject: InjectFn = (identifier, defaultValue) => {}; 5 | -------------------------------------------------------------------------------- /packages/common/src/ref.ts: -------------------------------------------------------------------------------- 1 | import { RefFn } from './types'; 2 | 3 | export const ref: RefFn = (initialValue) => { 4 | return { 5 | get value () { 6 | return initialValue; 7 | }, 8 | set value (value) {} 9 | }; 10 | }; 11 | -------------------------------------------------------------------------------- /packages/common/src/storybook/createStory.ts: -------------------------------------------------------------------------------- 1 | import { defineComponent, h, CreateStoryFn } from '../index'; 2 | 3 | export const createStory: CreateStoryFn = (Component, args = {}) => defineComponent({ 4 | render: () => h('div', { 5 | class: `storybook-example ${args.class || ''}` 6 | }, h(Component, args)) 7 | }); 8 | -------------------------------------------------------------------------------- /packages/common/src/storybook/index.ts: -------------------------------------------------------------------------------- 1 | export * from './createStory'; 2 | -------------------------------------------------------------------------------- /packages/common/src/types.ts: -------------------------------------------------------------------------------- 1 | export type Ref = { value: T }; 2 | 3 | export type UnwrapState = { 4 | [key in keyof State]: (State[key] & Ref)['value'] 5 | }; 6 | 7 | /** 8 | * Component definition 9 | */ 10 | 11 | export type ConstructorType = 12 | | NumberConstructor 13 | | StringConstructor 14 | | BooleanConstructor 15 | | ObjectConstructor 16 | | ArrayConstructor; 17 | 18 | export type ComponentProps = { 19 | [key in keyof Props]: 20 | | { type?: NumberConstructor, default?: number | (() => number) } 21 | | { type?: StringConstructor, default?: string | (() => string) } 22 | | { type?: BooleanConstructor, default?: boolean | (() => boolean) } 23 | | { type?: ObjectConstructor, default?: object | (() => object) } 24 | | { type?: ArrayConstructor, default?: unknown[] | (() => unknown[]) } 25 | } 26 | 27 | export type UnwrapProps = { 28 | [key in keyof ComponentProps]: ComponentProps[key]['default'] | null; 29 | } 30 | 31 | export interface EmitFn { 32 | (eventName: string, ...args: any[]): void; 33 | } 34 | 35 | export interface SlotFn { 36 | (name?: string): T; 37 | } 38 | 39 | export interface HasSlotFn { 40 | (name?: string): boolean; 41 | } 42 | 43 | export interface ProvideFn { 44 | (identifier: string | symbol, value: T, dependencies?: any[]): void; 45 | } 46 | 47 | export interface InjectFn { 48 | (identifier: string | symbol, defaultValue?: T | (() => T)): T | undefined 49 | } 50 | 51 | export interface SetupContext { 52 | emit: EmitFn; 53 | hasSlot: HasSlotFn; 54 | provide: ProvideFn; 55 | inject: InjectFn; 56 | } 57 | 58 | export interface RenderContext { 59 | slot: SlotFn; 60 | hasSlot: HasSlotFn; 61 | } 62 | 63 | export interface ComponentDefinition< 64 | Props extends Record = {}, 65 | State extends Record = {}, 66 | VNode = any 67 | > { 68 | name?: string; 69 | slots?: string[]; 70 | emits?: string[]; 71 | props?: ComponentProps; 72 | setup?(props: Props, context: SetupContext): State; 73 | render(state: Props & State, context: RenderContext): VNode; 74 | } 75 | 76 | /** 77 | * Providers 78 | */ 79 | 80 | export interface Providers { 81 | [key: string | symbol]: { 82 | state: any; 83 | setState(newValue: any): void; 84 | notify(newValue: any): void; 85 | }; 86 | } 87 | 88 | export interface RegisterProviderFn { 89 | (identifier: string | symbol, value: T): void; 90 | } 91 | 92 | export interface UpdateProviderFn { 93 | (identifier: string | symbol, value: T): void; 94 | } 95 | 96 | /** 97 | * Function types 98 | */ 99 | 100 | export interface DefineComponentFn { 101 | (definition: ComponentDefinition): ComponentType; 102 | } 103 | 104 | export interface RefFn { 105 | (initialValue: T): Ref; 106 | } 107 | 108 | export interface ComputedFn { 109 | (computeFn: () => T, dependencies?: any[]): Ref; 110 | } 111 | 112 | export interface WatchFn { 113 | (dependency: () => T, callback: (newValue: T) => void): void; 114 | } 115 | 116 | export interface HoistFn { 117 | (type: string | D, props?: Record, ...children: (C | C[] | Record (C | C[])>)[]): T 118 | } 119 | 120 | export interface FragmentFn { 121 | (props: { children?: C | C[] }): C | C[] | undefined; 122 | } 123 | 124 | /** 125 | * Plugin types 126 | */ 127 | 128 | export interface DefinePluginContext { 129 | provide: ProvideFn; 130 | } 131 | 132 | export interface DefinePluginFn { 133 | (setup: (options: Options, context: DefinePluginContext) => void): Plugin; 134 | } 135 | 136 | /** 137 | * Storybook types 138 | */ 139 | 140 | export interface CreateStoryFn { 141 | (component: T, storyArgs?: { class?: string; }): any; 142 | } 143 | -------------------------------------------------------------------------------- /packages/common/src/watch.ts: -------------------------------------------------------------------------------- 1 | import { WatchFn } from './types'; 2 | 3 | export const watch: WatchFn = (dependency, callback) => { 4 | callback(dependency); 5 | }; 6 | -------------------------------------------------------------------------------- /packages/common/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": [ 4 | "src/**/*.ts", 5 | "src/**/*.tsx" 6 | ], 7 | "compilerOptions": { 8 | "rootDir": "src", 9 | "baseUrl": ".", 10 | "types": [], 11 | "jsx": "preserve", 12 | "jsxFactory": "h", 13 | "jsxFragmentFactory": "Fragment", 14 | "paths": { 15 | "@inkline/paper": ["@inkline/paper/src"] 16 | } 17 | }, 18 | "references": [ 19 | { 20 | "path": "./tsconfig.vite.json" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /packages/common/tsconfig.vite.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "types": [ 7 | "vite/client", 8 | "vitest/globals" 9 | ] 10 | }, 11 | "include": [ 12 | "vite.config.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/common/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import { resolve } from 'path'; 3 | import { configDefaults } from 'vitest/config'; 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | plugins: [], 8 | esbuild: { 9 | jsxFactory: 'h', 10 | jsxFragment: 'Fragment', 11 | jsxInject: '' 12 | }, 13 | resolve: { 14 | alias: [ 15 | { 16 | find: /^@inkline\/paper\//, 17 | replacement: `${resolve(__dirname)}/src/` 18 | } 19 | ] 20 | }, 21 | build: { 22 | lib: { 23 | entry: resolve(__dirname, 'src', 'index.ts'), 24 | name: 'InklinePaperVue', 25 | fileName: (format) => `vue.${format}.js` 26 | }, 27 | rollupOptions: { 28 | // make sure to externalize deps that shouldn't be bundled 29 | // into your library 30 | external: [ 31 | 'vue' 32 | ], 33 | output: { 34 | exports: 'named', 35 | // Provide global variables to use in the UMD build 36 | // for externalized deps 37 | globals: { 38 | vue: 'Vue' 39 | } 40 | } 41 | } 42 | }, 43 | test: { 44 | globals: true, 45 | environment: 'jsdom', 46 | exclude: [...configDefaults.exclude, 'lib/**'] 47 | } 48 | }); 49 | -------------------------------------------------------------------------------- /packages/react/build.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | entries: [ 3 | { 4 | builder: 'mkdist', 5 | format: 'esm', 6 | ext: 'mjs', 7 | input: './src', 8 | declaration: true 9 | }, 10 | { 11 | builder: 'mkdist', 12 | format: 'cjs', 13 | ext: 'cjs', 14 | input: './src', 15 | declaration: true 16 | } 17 | ] 18 | }; 19 | -------------------------------------------------------------------------------- /packages/react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@inkline/paper-react", 3 | "description": "Inkline Paper React.js package.", 4 | "scripts": { 5 | "pre": "cp ../common/src/types.ts src/types-common.ts", 6 | "pretest": "npm run pre", 7 | "test": "vitest run", 8 | "test:dev": "vitest", 9 | "prebuild": "npm run pre", 10 | "build": "unbuild" 11 | }, 12 | "devDependencies": { 13 | "@testing-library/react": "12.1.3", 14 | "@vitejs/plugin-react": "1.2.0", 15 | "jsdom": "19.0.0", 16 | "react": "17.0.2", 17 | "react-dom": "17.0.2", 18 | "rimraf": "3.0.2", 19 | "unbuild": "0.7.2", 20 | "vite": "2.8.6", 21 | "vitest": "0.5.9" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "git+https://github.com/inkline/paper.git" 26 | }, 27 | "license": "ISC" 28 | } 29 | -------------------------------------------------------------------------------- /packages/react/src/__tests__/__snapshots__/computed.spec.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1 2 | 3 | exports[`react > computed() > should compute value based on other refs 1`] = ` 4 |
5 | 3 6 |
7 | `; 8 | 9 | exports[`react > computed() > should create a new computed value 1`] = ` 10 |
11 | hello 12 |
13 | `; 14 | 15 | exports[`react > computed() > should update value based on other refs 1`] = ` 16 |
17 | 10 18 |
19 | `; 20 | -------------------------------------------------------------------------------- /packages/react/src/__tests__/__snapshots__/defineComponent.spec.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1 2 | 3 | exports[`react > defineComponent() > context > slot() > should render react component with default slot, multiple children 1`] = ` 4 |
5 | 6 | Child 1 7 | 8 | 9 | Child 2 10 | 11 | 12 | Child 3 13 | 14 |
15 | `; 16 | 17 | exports[`react > defineComponent() > context > slot() > should render react component with default slot, one child 1`] = ` 18 |
19 | 20 | Child 21 | 22 |
23 | `; 24 | 25 | exports[`react > defineComponent() > context > slot() > should render react component with named default slot 1`] = ` 26 |
27 | 28 | Child 29 | 30 |
31 | `; 32 | 33 | exports[`react > defineComponent() > context > slot() > should render react component with named slots 1`] = ` 34 |
35 | 36 | Header 37 | 38 | 39 | Body 40 | 41 | 42 | Footer 43 | 44 |
45 | `; 46 | 47 | exports[`react > defineComponent() > provide/inject() > should overwrite reactive data for deeply nested children 1`] = ` 48 |
49 | 54 |
55 | `; 56 | 57 | exports[`react > defineComponent() > provide/inject() > should provide data to children 1`] = ` 58 |
59 |
60 | value 61 |
62 |
63 | `; 64 | 65 | exports[`react > defineComponent() > provide/inject() > should provide reactive data based on id 1`] = ` 66 |
67 | 72 | 77 |
78 | `; 79 | 80 | exports[`react > defineComponent() > provide/inject() > should provide reactive data based on id 2`] = ` 81 |
82 | 87 | 92 |
93 | `; 94 | 95 | exports[`react > defineComponent() > provide/inject() > should provide reactive data based on id 3`] = ` 96 |
97 | 102 | 107 |
108 | `; 109 | 110 | exports[`react > defineComponent() > provide/inject() > should provide reactive data to children 1`] = ` 111 | 116 | `; 117 | 118 | exports[`react > defineComponent() > should render component 1`] = `
`; 119 | 120 | exports[`react > defineComponent() > should render component with state 1`] = ` 121 | 124 | `; 125 | 126 | exports[`react > defineComponent() > should render component with state and props 1`] = ` 127 | 130 | `; 131 | 132 | exports[`react > defineComponent() > should render component with state, props, and onClick state function 1`] = ` 133 | 136 | `; 137 | -------------------------------------------------------------------------------- /packages/react/src/__tests__/__snapshots__/definePlugin.spec.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1 2 | 3 | exports[`react > definePlugin() > should create a new higher order component 1`] = ` 4 |
5 | Hello world! 6 |
7 | `; 8 | 9 | exports[`react > definePlugin() > should provide data to children 1`] = ` 10 |
11 | light 12 |
13 | `; 14 | 15 | exports[`react > definePlugin() > should provide reactive data to children 1`] = ` 16 |
17 | dark 18 |
19 | `; 20 | -------------------------------------------------------------------------------- /packages/react/src/__tests__/__snapshots__/provide.spec.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1 2 | 3 | exports[`react > provide/inject() > should overwrite reactive data for deeply nested children 1`] = ` 4 |
5 | 10 |
11 | `; 12 | 13 | exports[`react > provide/inject() > should provide data to children 1`] = ` 14 |
15 |
16 | value 17 |
18 |
19 | `; 20 | 21 | exports[`react > provide/inject() > should provide reactive data based on id 1`] = ` 22 |
23 | 28 | 33 |
34 | `; 35 | 36 | exports[`react > provide/inject() > should provide reactive data based on id 2`] = ` 37 |
38 | 43 | 48 |
49 | `; 50 | 51 | exports[`react > provide/inject() > should provide reactive data based on id 3`] = ` 52 |
53 | 58 | 63 |
64 | `; 65 | 66 | exports[`react > provide/inject() > should provide reactive data to children 1`] = ` 67 | 72 | `; 73 | -------------------------------------------------------------------------------- /packages/react/src/__tests__/__snapshots__/ref.spec.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1 2 | 3 | exports[`react > ref() > getter > should return current value 1`] = ` 4 |
5 | hello 6 |
7 | `; 8 | 9 | exports[`react > ref() > setter > should set a new array value 1`] = ` 10 | 13 | `; 14 | 15 | exports[`react > ref() > setter > should set a new object value 1`] = ` 16 | 19 | `; 20 | 21 | exports[`react > ref() > setter > should set a new string value 1`] = ` 22 | 25 | `; 26 | 27 | exports[`react > ref() > should create a reference value 1`] = ` 28 |
29 | hello 30 |
31 | `; 32 | -------------------------------------------------------------------------------- /packages/react/src/__tests__/computed.spec.tsx: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | import { fireEvent, render } from '@testing-library/react'; 3 | import { computed, defineComponent, h, ref } from '../index'; 4 | 5 | describe('react', () => { 6 | describe('computed()', () => { 7 | it('should create a new computed value', () => { 8 | const Component = defineComponent({ 9 | setup () { 10 | const state = computed(() => 'hello'); 11 | 12 | expect(state).toEqual({ 13 | value: 'hello' 14 | }); 15 | 16 | return { state }; 17 | }, 18 | render ({ state }) { 19 | return
{state.value}
; 20 | } 21 | }); 22 | 23 | const wrapper = render(); 24 | expect(wrapper.container.firstChild).toMatchSnapshot(); 25 | }); 26 | 27 | it('should compute value based on other refs', () => { 28 | const Component = defineComponent({ 29 | setup () { 30 | const a = ref(1); 31 | const b = ref(2); 32 | const state = computed(() => a.value + b.value); 33 | 34 | expect(state.value).toEqual(3); 35 | 36 | return { state }; 37 | }, 38 | render ({ state }) { 39 | return
{state.value}
; 40 | } 41 | }); 42 | 43 | const wrapper = render(); 44 | expect(wrapper.container.firstChild).toMatchSnapshot(); 45 | }); 46 | 47 | it('should update value based on other refs', async () => { 48 | const Component = defineComponent({ 49 | setup () { 50 | const a = ref(1); 51 | const b = ref(2); 52 | const state = computed(() => a.value + b.value); 53 | 54 | const onClick = () => { 55 | a.value = 4; 56 | b.value = 6; 57 | }; 58 | 59 | return { state, onClick }; 60 | }, 61 | render ({ state, onClick }) { 62 | return
{state.value}
; 63 | } 64 | }); 65 | 66 | const wrapper = render(); 67 | await fireEvent.click(wrapper.container.firstChild as Element); 68 | 69 | expect(wrapper.container.firstChild).toMatchSnapshot(); 70 | }); 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /packages/react/src/__tests__/defineComponent.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { describe, it, expect, vi } from 'vitest'; 3 | import { 4 | defineComponent, 5 | h, 6 | Fragment, 7 | ref, 8 | Events 9 | } from '../index'; 10 | import { fireEvent, render } from '@testing-library/react'; 11 | 12 | describe('react', () => { 13 | describe('defineComponent()', () => { 14 | it('should render component', () => { 15 | const Component = defineComponent({ 16 | render () { 17 | return
; 18 | } 19 | }); 20 | 21 | const wrapper = render(); 22 | expect(wrapper.container.firstChild).toMatchSnapshot(); 23 | }); 24 | 25 | it('should render component with state', () => { 26 | const Component = defineComponent({ 27 | setup () { 28 | const count = ref(0); 29 | 30 | return { count }; 31 | }, 32 | render (state) { 33 | return ; 34 | } 35 | }); 36 | 37 | const wrapper = render(); 38 | expect(wrapper.container.firstChild).toMatchSnapshot(); 39 | }); 40 | 41 | it('should render component with state and props', () => { 42 | const Component = defineComponent({ 43 | setup (props) { 44 | const count = ref(props.initialValue); 45 | 46 | return { count }; 47 | }, 48 | render (state) { 49 | return ; 50 | } 51 | }); 52 | 53 | const wrapper = render(); 54 | expect(wrapper.container.firstChild).toMatchSnapshot(); 55 | }); 56 | 57 | it('should render component with state, props, and onClick state function', async () => { 58 | const Component = defineComponent({ 59 | setup (props) { 60 | const count = ref(props.initialValue); 61 | 62 | const onClick = () => { 63 | count.value += 1; 64 | }; 65 | 66 | return { count, onClick }; 67 | }, 68 | render (state) { 69 | return ; 70 | } 71 | }); 72 | 73 | const wrapper = render(); 74 | await fireEvent.click(wrapper.container.firstChild as Element); 75 | expect(wrapper.container.firstChild).toMatchSnapshot(); 76 | }); 77 | 78 | describe('context', () => { 79 | describe('slot()', () => { 80 | it('should render react component with default slot, one child', () => { 81 | const Component = defineComponent({ 82 | render (state, ctx) { 83 | return
84 | {ctx.slot()} 85 |
; 86 | } 87 | }); 88 | 89 | const wrapper = render( 90 | Child 91 | ); 92 | expect(wrapper.container.firstChild).toMatchSnapshot(); 93 | }); 94 | 95 | it('should render react component with default slot, multiple children', () => { 96 | const Component = defineComponent({ 97 | render (state, ctx) { 98 | return
99 | {ctx.slot()} 100 |
; 101 | } 102 | }); 103 | 104 | const wrapper = render( 105 | Child 1 106 | Child 2 107 | Child 3 108 | ); 109 | expect(wrapper.container.firstChild).toMatchSnapshot(); 110 | }); 111 | 112 | it('should render react component with named default slot', () => { 113 | const Component = defineComponent({ 114 | render (state, ctx) { 115 | return
116 | {ctx.slot()} 117 |
; 118 | } 119 | }); 120 | 121 | const wrapper = render({{ 122 | default: () => Child 123 | }}); 124 | expect(wrapper.container.firstChild).toMatchSnapshot(); 125 | }); 126 | 127 | it('should render react component with named slots', () => { 128 | const Component = defineComponent({ 129 | slots: [ 130 | 'header', 131 | 'footer' 132 | ], 133 | render (state, ctx) { 134 | return
135 | {ctx.slot('header')} 136 | {ctx.slot()} 137 | {ctx.slot('footer')} 138 |
; 139 | } 140 | }); 141 | 142 | const wrapper = render({{ 143 | header: () => Header, 144 | default: () => Body, 145 | footer: () => Footer 146 | }}); 147 | expect(wrapper.container.firstChild).toMatchSnapshot(); 148 | }); 149 | }); 150 | 151 | describe('emit()', () => { 152 | it('should emit event by attaching on[EventName] callback', async () => { 153 | const Component = defineComponent({ 154 | emits: [ 155 | 'click' 156 | ], 157 | setup (props, ctx) { 158 | const onClick = () => { 159 | ctx.emit('click'); 160 | }; 161 | 162 | return { onClick }; 163 | }, 164 | render (state) { 165 | return ; 166 | } 167 | }); 168 | 169 | const onClick = vi.fn(); 170 | const wrapper = render(); 171 | await fireEvent.click(wrapper.container.firstChild as Element); 172 | expect(onClick).toHaveBeenCalled(); 173 | }); 174 | 175 | it('should emit event with arguments', async () => { 176 | const Component = defineComponent({ 177 | emits: [ 178 | 'click' 179 | ], 180 | setup (props, ctx) { 181 | const onClick = (event: Event) => { 182 | ctx.emit('click', event); 183 | }; 184 | 185 | return { onClick }; 186 | }, 187 | render (state) { 188 | return ; 189 | } 190 | }); 191 | 192 | const onClick = vi.fn(); 193 | const wrapper = render(); 194 | await fireEvent.click(wrapper.container.firstChild as Element); 195 | expect(onClick).toHaveBeenCalled(); 196 | expect(onClick.mock.calls[0][0]).toEqual(expect.any(Object)); 197 | }); 198 | 199 | it('should render component with modelValue and update:modelValue', async () => { 200 | const Component = defineComponent({ 201 | emits: [ 202 | 'update:modelValue' 203 | ], 204 | setup (props, ctx) { 205 | const onClick = () => { 206 | ctx.emit('update:modelValue', props.modelValue + 1); 207 | }; 208 | 209 | return { onClick }; 210 | }, 211 | render (state) { 212 | return ; 213 | } 214 | }); 215 | 216 | let value = 3; 217 | const onUpdate = vi.fn((newValue) => { value = newValue; }); 218 | const wrapper = render(); 219 | 220 | await fireEvent.click(wrapper.container.firstChild as Element); 221 | 222 | expect(onUpdate).toHaveBeenCalled(); 223 | expect(value).toEqual(4); 224 | }); 225 | 226 | it('should render component with input field', async () => { 227 | const Component = defineComponent({ 228 | props: { 229 | modelValue: { 230 | type: String, 231 | default: '' 232 | } 233 | }, 234 | emits: [ 235 | 'update:modelValue' 236 | ], 237 | setup (props, ctx) { 238 | const onChange = (event: Event) => { 239 | ctx.emit('update:modelValue', (event.target as HTMLInputElement).value); 240 | }; 241 | 242 | return { onChange }; 243 | }, 244 | render (state) { 245 | const events = { 246 | [Events.onInputChange]: state.onChange 247 | }; 248 | 249 | return ; 250 | } 251 | }); 252 | 253 | let value = ''; 254 | const onUpdate = vi.fn((newValue) => { value = newValue; }); 255 | const wrapper = render(); 256 | 257 | await fireEvent.change(wrapper.container.firstChild as Element, { target: { value: 'abc' } }); 258 | 259 | expect(onUpdate).toHaveBeenCalled(); 260 | expect(value).toEqual('abc'); 261 | }); 262 | }); 263 | }); 264 | 265 | describe('provide/inject()', () => { 266 | it('should provide data to children', async () => { 267 | const identifier = Symbol('provide-reactive'); 268 | const Provider = defineComponent({ 269 | setup (props, ctx) { 270 | ctx.provide(identifier, 'value', []); 271 | 272 | return {}; 273 | }, 274 | render (state, ctx) { 275 | return
{ctx.slot()}
; 276 | } 277 | }); 278 | 279 | const Consumer = defineComponent({ 280 | setup (props, ctx) { 281 | const providedValue = ctx.inject(identifier); 282 | 283 | return { providedValue }; 284 | }, 285 | render (state) { 286 | return
{state.providedValue}
; 287 | } 288 | }); 289 | 290 | const wrapper = render( 291 | 292 | ); 293 | expect(wrapper.container.firstChild).toMatchSnapshot(); 294 | }); 295 | 296 | it('should provide reactive data to children', async () => { 297 | const identifier = Symbol('provide-reactive'); 298 | const Provider = defineComponent({ 299 | setup (props, ctx) { 300 | const count = ref(0); 301 | const onClick = () => { count.value += 1; }; 302 | 303 | ctx.provide(identifier, count, [count.value]); 304 | 305 | return { onClick }; 306 | }, 307 | render (state, ctx) { 308 | return ; 309 | } 310 | }); 311 | 312 | const Consumer = defineComponent({ 313 | setup (props, ctx) { 314 | const providedValue = ctx.inject(identifier); 315 | 316 | return { providedValue }; 317 | }, 318 | render (state) { 319 | return
{state.providedValue?.value}
; 320 | } 321 | }); 322 | 323 | const wrapper = render( 324 | 325 | ); 326 | await fireEvent.click(wrapper.container.firstChild as Element); 327 | expect(await wrapper.findByText('1')).toBeTruthy(); 328 | expect(wrapper.container.firstChild).toMatchSnapshot(); 329 | }); 330 | 331 | it('should overwrite reactive data for deeply nested children', async () => { 332 | const identifier = Symbol('provide-reactive'); 333 | const ProviderA = defineComponent({ 334 | setup (props, ctx) { 335 | const count = ref(0); 336 | 337 | ctx.provide(identifier, count, [count.value]); 338 | 339 | return {}; 340 | }, 341 | render (state, ctx) { 342 | return
{ctx.slot()}
; 343 | } 344 | }); 345 | 346 | const ProviderB = defineComponent({ 347 | setup (props, ctx) { 348 | const count = ref(1); 349 | const onClick = () => { count.value += 1; }; 350 | 351 | ctx.provide(identifier, count, [count.value]); 352 | 353 | return { onClick }; 354 | }, 355 | render (state, ctx) { 356 | return ; 359 | } 360 | }); 361 | 362 | const Consumer = defineComponent({ 363 | setup (props, ctx) { 364 | const providedValue = ctx.inject(identifier); 365 | 366 | return { providedValue }; 367 | }, 368 | render (state) { 369 | return
{state.providedValue?.value}
; 370 | } 371 | }); 372 | 373 | const wrapper = render( 374 | 375 | 376 | 377 | ); 378 | await fireEvent.click(wrapper.container.querySelector('button') as Element); 379 | expect(await wrapper.findByText('2')).toBeTruthy(); 380 | expect(wrapper.container.firstChild).toMatchSnapshot(); 381 | }); 382 | 383 | it('should provide reactive data based on id', async () => { 384 | const Provider = defineComponent({ 385 | setup (props, ctx) { 386 | const text = ref(props.id); 387 | const onClick = () => { text.value = 'abc'; }; 388 | 389 | ctx.provide(props.id, text, [text.value]); 390 | 391 | return { onClick }; 392 | }, 393 | render (state, ctx) { 394 | return ; 395 | } 396 | }); 397 | 398 | const Consumer = defineComponent({ 399 | setup (props, ctx) { 400 | const providedValue = ctx.inject(props.id); 401 | 402 | return { providedValue }; 403 | }, 404 | render (state) { 405 | return
{state.providedValue?.value}
; 406 | } 407 | }); 408 | 409 | const wrapper = render(
410 | 411 | 412 | 413 | 414 | 415 | 416 |
); 417 | 418 | const buttons = wrapper.container.querySelectorAll('button'); 419 | expect(wrapper.container.firstChild).toMatchSnapshot(); 420 | await fireEvent.click(buttons[0] as Element); 421 | expect(wrapper.container.firstChild).toMatchSnapshot(); 422 | await fireEvent.click(buttons[1] as Element); 423 | expect(wrapper.container.firstChild).toMatchSnapshot(); 424 | }); 425 | }); 426 | }); 427 | }); 428 | -------------------------------------------------------------------------------- /packages/react/src/__tests__/definePlugin.spec.tsx: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | import { render } from '@testing-library/react'; 3 | import { defineComponent, definePlugin, h } from '../index'; 4 | import {useEffect} from "react"; 5 | 6 | describe('react', () => { 7 | describe('definePlugin()', () => { 8 | it('should create a new higher order component', () => { 9 | const Plugin = definePlugin(() => {}); 10 | const Component = defineComponent({ 11 | render () { 12 | return
Hello world!
; 13 | } 14 | }); 15 | 16 | const wrapper = render(); 17 | expect(wrapper.container.firstChild).toMatchSnapshot(); 18 | }); 19 | 20 | it('should be called with plugin options', () => { 21 | const pluginOptions = { 22 | color: 'light' 23 | }; 24 | 25 | const Plugin = definePlugin((options) => { 26 | expect(options).toEqual(pluginOptions); 27 | }); 28 | const Component = defineComponent({ 29 | render () { 30 | return
Hello world!
; 31 | } 32 | }); 33 | 34 | render(); 35 | }); 36 | 37 | it('should provide data to children', () => { 38 | const provideSymbol = Symbol('provide'); 39 | const provideData = { color: 'light' }; 40 | 41 | const Plugin = definePlugin((options, { provide }) => { 42 | provide(provideSymbol, provideData); 43 | }); 44 | const Component = defineComponent({ 45 | setup (props, { inject }) { 46 | const data = inject(provideSymbol); 47 | 48 | return { data }; 49 | }, 50 | render ({ data }) { 51 | return
{data?.color}
; 52 | } 53 | }); 54 | 55 | const wrapper = render(); 56 | expect(wrapper.container.firstChild).toMatchSnapshot(); 57 | }); 58 | 59 | it('should provide reactive data to children', () => { 60 | const provideSymbol = Symbol('provide'); 61 | const provideData = { color: 'light' }; 62 | 63 | const Plugin = definePlugin((options, { provide }) => { 64 | provide(provideSymbol, provideData, [provideData]); 65 | 66 | useEffect(() => { 67 | provideData.color = 'dark'; 68 | }); 69 | }); 70 | const Component = defineComponent({ 71 | setup (props, { inject }) { 72 | const data = inject(provideSymbol); 73 | 74 | return { data }; 75 | }, 76 | render ({ data }) { 77 | return
{data?.color}
; 78 | } 79 | }); 80 | 81 | const wrapper = render(); 82 | expect(wrapper.container.firstChild).toMatchSnapshot(); 83 | }); 84 | }); 85 | }); 86 | -------------------------------------------------------------------------------- /packages/react/src/__tests__/h.spec.tsx: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | import { h } from '../index'; 3 | 4 | describe('react', () => { 5 | describe('h()', () => { 6 | it('should return native element', () => { 7 | const type = 'div'; 8 | const element = h(type); 9 | 10 | expect(element).toBeDefined(); 11 | expect(element!.type).toEqual(type); 12 | }); 13 | 14 | it('should return native element with props', () => { 15 | const type = 'div'; 16 | const props = { id: 'app' }; 17 | const element = h(type, props); 18 | 19 | expect(element).toBeDefined(); 20 | expect(element!.type).toEqual(type); 21 | expect(element!.props).toEqual(props); 22 | }); 23 | 24 | it('should return native element with one child', () => { 25 | const type = 'div'; 26 | const props = { id: 'app' }; 27 | const children = [ 28 | h('span', { key: 0 }) 29 | ]; 30 | const element = h(type, props, children); 31 | 32 | expect(element).toBeDefined(); 33 | expect(element!.type).toEqual('div'); 34 | expect(element!.props).toEqual({ ...props, children }); 35 | }); 36 | 37 | it('should return native element with multiple children', () => { 38 | const type = 'div'; 39 | const props = { id: 'app' }; 40 | const children = [ 41 | h('span', { key: 0 }), 42 | h('span', { key: 1 }), 43 | h('span', { key: 2 }) 44 | ]; 45 | const element = h(type, props, children); 46 | 47 | expect(element).toBeDefined(); 48 | expect(element!.type).toEqual('div'); 49 | expect(element!.props).toEqual({ ...props, children }); 50 | }); 51 | 52 | it('should accept multiple children as spread argument', () => { 53 | const type = 'div'; 54 | const props = { id: 'app' }; 55 | const children = [ 56 | h('span', { key: 0 }), 57 | h('span', { key: 1 }), 58 | h('span', { key: 2 }) 59 | ]; 60 | const element = h(type, props, ...children); 61 | 62 | expect(element).toBeDefined(); 63 | expect(element!.type).toEqual('div'); 64 | expect(element!.props).toEqual({ ...props, children }); 65 | }); 66 | 67 | it('should replace class prop with className', () => { 68 | const type = 'div'; 69 | const props = { class: 'example' }; 70 | const element = h(type, props); 71 | 72 | expect(element).toBeDefined(); 73 | expect(element!.props).toEqual({ className: props.class, children: undefined }); 74 | }); 75 | }); 76 | }); 77 | -------------------------------------------------------------------------------- /packages/react/src/__tests__/ref.spec.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { defineComponent, h, ref } from '../index'; 3 | import { describe, it, expect } from 'vitest'; 4 | import { fireEvent, render } from '@testing-library/react'; 5 | 6 | describe('react', () => { 7 | describe('ref()', () => { 8 | it('should create a reference value', () => { 9 | const Component = defineComponent({ 10 | setup () { 11 | const state = ref('hello'); 12 | 13 | expect(state).toEqual({ 14 | value: 'hello' 15 | }); 16 | 17 | return { state }; 18 | }, 19 | render ({ state }) { 20 | return
{state.value}
; 21 | } 22 | }); 23 | 24 | const wrapper = render(); 25 | expect(wrapper.container.firstChild).toMatchSnapshot(); 26 | }); 27 | 28 | describe('getter', () => { 29 | it('should return current value', () => { 30 | const Component = defineComponent({ 31 | setup () { 32 | const state = ref('hello'); 33 | 34 | expect(state.value).toEqual('hello'); 35 | 36 | return { state }; 37 | }, 38 | render ({ state }) { 39 | return
{state.value}
; 40 | } 41 | }); 42 | 43 | const wrapper = render(); 44 | expect(wrapper.container.firstChild).toMatchSnapshot(); 45 | }); 46 | }); 47 | 48 | describe('setter', () => { 49 | it('should set a new string value', async () => { 50 | const Component = defineComponent({ 51 | setup () { 52 | const state = ref('hello'); 53 | 54 | const onClick = () => { 55 | state.value = 'world'; 56 | }; 57 | 58 | return { state, onClick }; 59 | }, 60 | render ({ state, onClick }) { 61 | return ; 62 | } 63 | }); 64 | 65 | const wrapper = render(); 66 | await fireEvent.click(wrapper.container.firstChild as HTMLElement); 67 | 68 | expect(wrapper.container.firstChild).toMatchSnapshot(); 69 | expect(wrapper.getByText('world')).toBeTruthy(); 70 | }); 71 | 72 | it('should set a new object value', async () => { 73 | const Component = defineComponent({ 74 | setup () { 75 | const state = ref({ field: 'hello' }); 76 | 77 | const onClick = () => { 78 | state.value = { field: 'world' }; 79 | }; 80 | 81 | return { state, onClick }; 82 | }, 83 | render ({ state, onClick }) { 84 | return ; 85 | } 86 | }); 87 | 88 | const wrapper = render(); 89 | await fireEvent.click(wrapper.container.firstChild as HTMLElement); 90 | 91 | expect(wrapper.container.firstChild).toMatchSnapshot(); 92 | expect(wrapper.getByText('world')).toBeTruthy(); 93 | }); 94 | 95 | it('should set a new array value', async () => { 96 | const Component = defineComponent({ 97 | setup () { 98 | const state = ref(['a']); 99 | 100 | const onClick = () => { 101 | state.value = state.value.concat(['b']); 102 | }; 103 | 104 | return { state, onClick }; 105 | }, 106 | render ({ state, onClick }) { 107 | return ; 108 | } 109 | }); 110 | 111 | const wrapper = render(); 112 | await fireEvent.click(wrapper.container.firstChild as HTMLElement); 113 | 114 | expect(wrapper.container.firstChild).toMatchSnapshot(); 115 | expect(wrapper.getByText('a, b')).toBeTruthy(); 116 | }); 117 | }); 118 | }); 119 | }); 120 | -------------------------------------------------------------------------------- /packages/react/src/__tests__/watch.spec.tsx: -------------------------------------------------------------------------------- 1 | import { describe, it, expect, vi } from 'vitest'; 2 | import { fireEvent, render } from '@testing-library/react'; 3 | import { watch, defineComponent, h, ref } from '../index'; 4 | 5 | describe('react', () => { 6 | describe('watch()', () => { 7 | it('should create a new watcher', () => { 8 | const callback = vi.fn(); 9 | const Component = defineComponent({ 10 | setup () { 11 | const state = ref('example'); 12 | 13 | watch(() => state, (newValue) => callback(newValue.value)); 14 | 15 | const onClick = () => { 16 | state.value = 'new'; 17 | }; 18 | 19 | return { state, onClick }; 20 | }, 21 | render ({ state, onClick }) { 22 | return ; 23 | } 24 | }); 25 | 26 | const wrapper = render(); 27 | fireEvent.click(wrapper.container.firstChild as Element); 28 | expect(callback).toHaveBeenCalledOnce(); 29 | expect(callback).toHaveBeenCalledWith('new'); 30 | }); 31 | 32 | it('should trigger watcher every time the value changes', () => { 33 | const callback = vi.fn(); 34 | const Component = defineComponent({ 35 | setup () { 36 | const state = ref(0); 37 | 38 | watch(() => state, (newValue) => callback(newValue.value)); 39 | 40 | const onClick = () => { 41 | state.value = state.value + 1; 42 | }; 43 | 44 | return { state, onClick }; 45 | }, 46 | render ({ state, onClick }) { 47 | return ; 48 | } 49 | }); 50 | 51 | const wrapper = render(); 52 | fireEvent.click(wrapper.container.firstChild as Element); 53 | expect(callback).toHaveBeenNthCalledWith(1, 1); 54 | fireEvent.click(wrapper.container.firstChild as Element); 55 | expect(callback).toHaveBeenNthCalledWith(2, 2); 56 | fireEvent.click(wrapper.container.firstChild as Element); 57 | expect(callback).toHaveBeenNthCalledWith(3, 3); 58 | expect(callback).toHaveBeenCalledTimes(3); 59 | }); 60 | }); 61 | }); 62 | -------------------------------------------------------------------------------- /packages/react/src/computed.ts: -------------------------------------------------------------------------------- 1 | import { ComputedFn } from './types'; 2 | import { useMemo } from 'react'; 3 | 4 | export const computed: ComputedFn = (computeFn, dependencies) => { 5 | const value = useMemo(() => computeFn(), dependencies); 6 | 7 | return { 8 | get value () { 9 | return value; 10 | } 11 | }; 12 | }; 13 | -------------------------------------------------------------------------------- /packages/react/src/context.ts: -------------------------------------------------------------------------------- 1 | import { createContext, Dispatch, SetStateAction } from 'react'; 2 | 3 | interface PaperContextState { 4 | provides: Record; 5 | setProvides: Dispatch>>; 6 | parent: PaperContextState; 7 | } 8 | 9 | export const PaperContext = createContext(null); 10 | -------------------------------------------------------------------------------- /packages/react/src/defineComponent.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ComponentProps, 3 | RenderContext, 4 | SetupContext, 5 | Slots, 6 | EmitFn, 7 | HasSlotFn, 8 | SlotFn, 9 | ProvideFn, 10 | InjectFn, 11 | DefineReactComponentFn, 12 | UnwrapProps 13 | } from './types'; 14 | import { FC, useEffect, useState } from 'react'; 15 | import { getSlotChildren, normalizeEventName, capitalizeFirst } from './helpers'; 16 | import { PaperContext } from './context'; 17 | import { h } from './h'; 18 | 19 | export type ReactFC = FC> & { [key: string]: any }; 20 | 21 | /** 22 | * Define React component using Functional Component and named slots 23 | * 24 | * @param definition universal component definition 25 | */ 26 | export const defineComponent: DefineReactComponentFn = ( 27 | definition 28 | ) => { 29 | const slots: Slots = {}; 30 | 31 | const Component: ReactFC> = function (props) { 32 | /** 33 | * Render slot 34 | * 35 | * @param name 36 | */ 37 | const slot: SlotFn = (name = 'default') => { 38 | const children = Array.isArray(props.children) ? props.children : [props.children]; 39 | 40 | return getSlotChildren(name, slots, children); 41 | }; 42 | 43 | /** 44 | * Helper to check if slots have children provided 45 | * 46 | * @param name 47 | */ 48 | const hasSlot: HasSlotFn = (name = 'default') => { 49 | return slot(name).length > 0; 50 | }; 51 | 52 | /** 53 | * Emit event 54 | * 55 | * @param eventName 56 | * @param args 57 | */ 58 | const emit: EmitFn = (eventName, ...args) => { 59 | props[normalizeEventName(eventName)]?.(...args); 60 | }; 61 | 62 | /** 63 | * Provide value to consumers 64 | * 65 | * @param identifier 66 | * @param value 67 | * @param dependencies 68 | */ 69 | const provide: ProvideFn = (identifier, value, dependencies?) => { 70 | useEffect(() => { 71 | props.ctx.setProvides({ 72 | ...props.ctx.provides, 73 | [identifier]: value 74 | }); 75 | }, dependencies); 76 | }; 77 | 78 | /** 79 | * Inject value from nearest provider 80 | * 81 | * @param identifier 82 | * @param defaultValue 83 | */ 84 | const inject: InjectFn = (identifier, defaultValue) => { 85 | defaultValue = typeof defaultValue === 'function' 86 | ? (defaultValue as () => typeof defaultValue)() 87 | : defaultValue; 88 | 89 | let parent = props.ctx.parent; 90 | while (parent?.parent && !parent.provides.hasOwnProperty(identifier)) { 91 | parent = parent.parent; 92 | } 93 | 94 | if (parent?.provides.hasOwnProperty(identifier)) { 95 | return parent.provides[identifier]; 96 | } 97 | 98 | return defaultValue; 99 | }; 100 | 101 | /** 102 | * Setup context 103 | */ 104 | const setupContext: SetupContext = { 105 | emit, 106 | hasSlot, 107 | provide, 108 | inject 109 | }; 110 | 111 | /** 112 | * State and props 113 | */ 114 | const state = definition.setup 115 | ? { ...props, ...definition.setup(props, setupContext) } 116 | : props; 117 | 118 | /** 119 | * Render context 120 | */ 121 | const renderContext: RenderContext = { 122 | slot, 123 | hasSlot 124 | }; 125 | 126 | /** 127 | * Render 128 | */ 129 | return definition.render(state, renderContext); 130 | }; 131 | 132 | /** 133 | * Default props 134 | */ 135 | if (definition.props) { 136 | Component.defaultProps = Object.keys(definition.props) 137 | .reduce((acc: Partial>, propName) => { 138 | const propType = (definition.props as ComponentProps)[propName]; 139 | 140 | if (typeof propType === 'object' && propType.default) { 141 | (acc as Record)[propName] = typeof propType.default === 'function' 142 | ? propType.default() 143 | : propType.default; 144 | } 145 | 146 | return acc; 147 | }, {}); 148 | } 149 | 150 | /** 151 | * Inject / Provide HOC used to create a parent-child relationship between paper components 152 | */ 153 | const PaperComponent: ReactFC> = (props) => { 154 | const [provides, setProvides] = useState({}); 155 | 156 | return {(parent: any) => 157 | 158 | 159 | 160 | }; 161 | }; 162 | 163 | /** 164 | * Slots 165 | */ 166 | ['default'].concat(definition.slots?.filter((slotName) => slotName !== 'default') || []) 167 | .forEach((name) => { 168 | slots[name] = () => null; 169 | slots[name].key = name; 170 | PaperComponent[capitalizeFirst(name)] = slots[name]; 171 | }); 172 | 173 | return PaperComponent; 174 | }; 175 | -------------------------------------------------------------------------------- /packages/react/src/definePlugin.tsx: -------------------------------------------------------------------------------- 1 | import { DefineReactPluginFn, ProvideFn } from './types'; 2 | import { PaperContext } from './context'; 3 | import { h } from './h'; 4 | import { useEffect, useState } from 'react'; 5 | 6 | export const definePlugin: DefineReactPluginFn = (setup) => ({ children, options }) => { 7 | const [provides, setProvides] = useState({}); 8 | 9 | /** 10 | * Provide value to whole application 11 | * 12 | * @param identifier 13 | * @param value 14 | * @param dependencies 15 | */ 16 | const provide: ProvideFn = (identifier, value, dependencies = []) => { 17 | useEffect(() => { 18 | setProvides({ 19 | ...provides, 20 | [identifier]: value 21 | }); 22 | }, dependencies); 23 | }; 24 | 25 | /** 26 | * Setup the plugin 27 | */ 28 | 29 | setup(options || {}, { provide }); 30 | 31 | /** 32 | * Render the child components array as-is 33 | */ 34 | return 35 | {children} 36 | ; 37 | }; 38 | -------------------------------------------------------------------------------- /packages/react/src/events.ts: -------------------------------------------------------------------------------- 1 | export enum Events { 2 | onInputChange = 'onChange' 3 | } 4 | -------------------------------------------------------------------------------- /packages/react/src/fragment.ts: -------------------------------------------------------------------------------- 1 | import { FragmentFn } from './types-common'; 2 | import { VNode } from './types'; 3 | 4 | /** 5 | * Render child elements using Fragment 6 | * 7 | * @example <> 8 | */ 9 | export const Fragment: FragmentFn = (props, ...args) => { 10 | console.log(props, args) 11 | return props.children; 12 | }; 13 | -------------------------------------------------------------------------------- /packages/react/src/h.ts: -------------------------------------------------------------------------------- 1 | import { createElement, FC } from 'react'; 2 | import { VNode, HoistFn } from './types'; 3 | import { capitalizeFirst } from './helpers'; 4 | 5 | /** 6 | * Render native element or React.js component 7 | * 8 | * @example h('p', { class: 'paragraph' }, 'Hello world') 9 | */ 10 | export const h: HoistFn> = ( 11 | type, 12 | props?, 13 | ...children 14 | ) => { 15 | /** 16 | * Rename class to className 17 | * 18 | * @example h(type, { class: 'element' }) => h(type, { className: 'element' }) 19 | */ 20 | if (props?.class) { 21 | const { class: className, ...properties } = props; 22 | props = properties; 23 | props.className = className; 24 | } 25 | 26 | /** 27 | * Handle passing slots to component when using render function 28 | * 29 | * @example h(Component, {}, { slotName: () => children }); 30 | */ 31 | if (typeof type !== 'string' && typeof children[0] === 'object' && !Array.isArray(children[0]) && !(children[0] as any).$$typeof) { 32 | const slots = children[0] as Record VNode>; 33 | const slotKeys = Object.keys(slots); 34 | 35 | if (slotKeys.length === 1 && slotKeys[0] === 'default') { 36 | children = [slots.default()].flat(); 37 | } else { 38 | children = slotKeys 39 | .map((slotKey) => { 40 | const slotName = capitalizeFirst(slotKey); 41 | const slotComponent = (type as FC & { [key: string]: any })[slotName]; 42 | 43 | return h(slotComponent, { key: slotName }, slots[slotKey]()); 44 | }); 45 | } 46 | } 47 | 48 | return createElement(type, props, ...children); 49 | }; 50 | -------------------------------------------------------------------------------- /packages/react/src/helpers/capitalizeFirst.ts: -------------------------------------------------------------------------------- 1 | export function capitalizeFirst (string: string): string { 2 | return string.charAt(0).toUpperCase() + string.slice(1); 3 | } 4 | -------------------------------------------------------------------------------- /packages/react/src/helpers/getSlotChildren.ts: -------------------------------------------------------------------------------- 1 | import { Slots } from '../types'; 2 | 3 | /** 4 | * Retrieve children for given named slot. If retrieving for 'default' slot, retrieve direct un-slotted children as well 5 | * 6 | * @param name 7 | * @param slots 8 | * @param children 9 | */ 10 | export const getSlotChildren = (name: string, slots: Slots, children: JSX.Element[]): JSX.Element[] => { 11 | const isSlot = (el: JSX.Element) => typeof el.type === 'function' && Object.keys(slots).find((slotName) => el.type === slots[slotName]); 12 | 13 | return children 14 | .filter((el) => { 15 | const matchesNamedSlot = typeof el.type === 'function' && (el.type as any) === slots[name]; 16 | 17 | return name === 'default' ? matchesNamedSlot || !isSlot(el) : matchesNamedSlot; 18 | }) 19 | .map((el) => { 20 | return isSlot(el) ? el.props?.children || [] : el; 21 | }) 22 | .flat(); 23 | }; 24 | -------------------------------------------------------------------------------- /packages/react/src/helpers/index.ts: -------------------------------------------------------------------------------- 1 | export * from './capitalizeFirst'; 2 | export * from './getSlotChildren'; 3 | export * from './normalizeEventName'; 4 | export * from './unwrapState'; 5 | -------------------------------------------------------------------------------- /packages/react/src/helpers/normalizeEventName.ts: -------------------------------------------------------------------------------- 1 | import { capitalizeFirst } from './capitalizeFirst'; 2 | 3 | export const normalizeEventName = (name: string): string => { 4 | return `on${name.split(':').map((part) => capitalizeFirst(part)).join('')}`; 5 | }; 6 | -------------------------------------------------------------------------------- /packages/react/src/helpers/unwrapState.ts: -------------------------------------------------------------------------------- 1 | import { UnwrapState } from '../types'; 2 | 3 | export function unwrapState> (state: State): UnwrapState { 4 | const newState: Record = {}; 5 | 6 | Object.keys(state || {}).forEach((stateKey) => { 7 | if ( 8 | typeof state[stateKey] !== 'function' && 9 | typeof state[stateKey] === 'object' && 10 | (state[stateKey].hasOwnProperty('value') || state[stateKey].hasOwnProperty('_value')) 11 | ) { 12 | newState[stateKey] = state[stateKey].value; 13 | } else { 14 | newState[stateKey] = state[stateKey]; 15 | } 16 | }); 17 | 18 | return newState as UnwrapState; 19 | } 20 | -------------------------------------------------------------------------------- /packages/react/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './computed'; 2 | export * from './defineComponent'; 3 | export * from './definePlugin'; 4 | export * from './events'; 5 | export * from './fragment'; 6 | export * from './h'; 7 | export * from './helpers'; 8 | export * from './ref'; 9 | export * from './types'; 10 | export * from './watch'; 11 | -------------------------------------------------------------------------------- /packages/react/src/ref.ts: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import { RefFn } from './types'; 3 | 4 | export const ref: RefFn = (initialValue) => { 5 | const [state, setState] = useState(initialValue); 6 | 7 | return { 8 | get value () { 9 | return state; 10 | }, 11 | set value (value) { 12 | setState(value); 13 | } 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /packages/react/src/storybook/createStory.ts: -------------------------------------------------------------------------------- 1 | import { CreateStoryFn, h, ReactFC } from '../index'; 2 | 3 | export const createStory: CreateStoryFn> = (Component, storyArgs = {}) => 4 | (args: Record) => h('div', { 5 | class: `storybook-example ${storyArgs.class || ''}` 6 | }, h(Component, args)); 7 | -------------------------------------------------------------------------------- /packages/react/src/storybook/index.ts: -------------------------------------------------------------------------------- 1 | export * from './createStory'; 2 | -------------------------------------------------------------------------------- /packages/react/src/types-common.ts: -------------------------------------------------------------------------------- 1 | export type Ref = { value: T }; 2 | 3 | export type UnwrapState = { 4 | [key in keyof State]: (State[key] & Ref)['value'] 5 | }; 6 | 7 | /** 8 | * Component definition 9 | */ 10 | 11 | export type ConstructorType = 12 | | NumberConstructor 13 | | StringConstructor 14 | | BooleanConstructor 15 | | ObjectConstructor 16 | | ArrayConstructor; 17 | 18 | export type ComponentProps = { 19 | [key in keyof Props]: 20 | | { type?: NumberConstructor, default?: number | (() => number) } 21 | | { type?: StringConstructor, default?: string | (() => string) } 22 | | { type?: BooleanConstructor, default?: boolean | (() => boolean) } 23 | | { type?: ObjectConstructor, default?: object | (() => object) } 24 | | { type?: ArrayConstructor, default?: unknown[] | (() => unknown[]) } 25 | } 26 | 27 | export type UnwrapProps = { 28 | [key in keyof ComponentProps]: ComponentProps[key]['default'] | null; 29 | } 30 | 31 | export interface EmitFn { 32 | (eventName: string, ...args: any[]): void; 33 | } 34 | 35 | export interface SlotFn { 36 | (name?: string): T; 37 | } 38 | 39 | export interface HasSlotFn { 40 | (name?: string): boolean; 41 | } 42 | 43 | export interface ProvideFn { 44 | (identifier: string | symbol, value: T, dependencies?: any[]): void; 45 | } 46 | 47 | export interface InjectFn { 48 | (identifier: string | symbol, defaultValue?: T | (() => T)): T | undefined 49 | } 50 | 51 | export interface SetupContext { 52 | emit: EmitFn; 53 | hasSlot: HasSlotFn; 54 | provide: ProvideFn; 55 | inject: InjectFn; 56 | } 57 | 58 | export interface RenderContext { 59 | slot: SlotFn; 60 | hasSlot: HasSlotFn; 61 | } 62 | 63 | export interface ComponentDefinition< 64 | Props extends Record = {}, 65 | State extends Record = {}, 66 | VNode = any 67 | > { 68 | name?: string; 69 | slots?: string[]; 70 | emits?: string[]; 71 | props?: ComponentProps; 72 | setup?(props: Props, context: SetupContext): State; 73 | render(state: Props & State, context: RenderContext): VNode; 74 | } 75 | 76 | /** 77 | * Providers 78 | */ 79 | 80 | export interface Providers { 81 | [key: string | symbol]: { 82 | state: any; 83 | setState(newValue: any): void; 84 | notify(newValue: any): void; 85 | }; 86 | } 87 | 88 | export interface RegisterProviderFn { 89 | (identifier: string | symbol, value: T): void; 90 | } 91 | 92 | export interface UpdateProviderFn { 93 | (identifier: string | symbol, value: T): void; 94 | } 95 | 96 | /** 97 | * Function types 98 | */ 99 | 100 | export interface DefineComponentFn { 101 | (definition: ComponentDefinition): ComponentType; 102 | } 103 | 104 | export interface RefFn { 105 | (initialValue: T): Ref; 106 | } 107 | 108 | export interface ComputedFn { 109 | (computeFn: () => T, dependencies?: any[]): Ref; 110 | } 111 | 112 | export interface WatchFn { 113 | (dependency: () => T, callback: (newValue: T) => void): void; 114 | } 115 | 116 | export interface HoistFn { 117 | (type: string | D, props?: Record, ...children: (C | C[] | Record (C | C[])>)[]): T 118 | } 119 | 120 | export interface FragmentFn { 121 | (props: { children?: C | C[] }): C | C[] | undefined; 122 | } 123 | 124 | /** 125 | * Plugin types 126 | */ 127 | 128 | export interface DefinePluginContext { 129 | provide: ProvideFn; 130 | } 131 | 132 | export interface DefinePluginFn { 133 | (setup: (options: Options, context: DefinePluginContext) => void): Plugin; 134 | } 135 | 136 | /** 137 | * Storybook types 138 | */ 139 | 140 | export interface CreateStoryFn { 141 | (component: T, storyArgs?: { class?: string; }): any; 142 | } 143 | -------------------------------------------------------------------------------- /packages/react/src/types.ts: -------------------------------------------------------------------------------- 1 | import { DefineComponentFn, DefinePluginFn } from './types-common'; 2 | import { FunctionComponent } from 'react'; 3 | 4 | export * from './types-common'; 5 | 6 | export type VNode = JSX.Element | null; 7 | 8 | export type Slots = { 9 | [key: string]: { 10 | (): null; 11 | key?: string; 12 | } 13 | }; 14 | 15 | export type DefineReactComponentFn< 16 | Props = Record, 17 | State = Record 18 | > = DefineComponentFn & { [key: string]: any; }> 19 | 20 | export type DefineReactPluginFn = DefinePluginFn, Options>; 21 | -------------------------------------------------------------------------------- /packages/react/src/watch.ts: -------------------------------------------------------------------------------- 1 | import { WatchFn } from './types'; 2 | import { useEffect, useRef } from 'react'; 3 | 4 | export const watch: WatchFn = (dependency, callback) => { 5 | const mounted = useRef(false); 6 | 7 | useEffect(() => { 8 | if (!mounted.current) { 9 | mounted.current = true; 10 | return; 11 | } 12 | 13 | callback(dependency()); 14 | }, [dependency()]); 15 | }; 16 | -------------------------------------------------------------------------------- /packages/react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": [ 4 | "src/**/*.ts", 5 | "src/**/*.tsx" 6 | ], 7 | "compilerOptions": { 8 | "rootDir": "src", 9 | "baseUrl": ".", 10 | "jsx": "preserve", 11 | "jsxFactory": "h", 12 | "jsxFragmentFactory": "Fragment", 13 | "types": [ 14 | "@types/react" 15 | ], 16 | "paths": { 17 | "@inkline/paper": ["@inkline/paper/src"] 18 | } 19 | }, 20 | "references": [ 21 | { 22 | "path": "./tsconfig.vite.json" 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /packages/react/tsconfig.vite.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "types": [ 7 | "vite/client", 8 | "vitest/globals" 9 | ] 10 | }, 11 | "include": [ 12 | "vite.config.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/react/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import { resolve } from 'path'; 3 | import { configDefaults } from 'vitest/config'; 4 | import react from '@vitejs/plugin-react'; 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [ 9 | react({ 10 | jsxRuntime: 'classic' 11 | }) 12 | ], 13 | esbuild: { 14 | jsxFactory: 'h', 15 | jsxFragment: 'Fragment', 16 | jsxInject: '' 17 | }, 18 | resolve: { 19 | alias: [ 20 | { 21 | find: /^@inkline\/paper\//, 22 | replacement: `${resolve(__dirname)}/src/` 23 | } 24 | ] 25 | }, 26 | build: { 27 | lib: { 28 | entry: resolve(__dirname, 'src', 'index.ts'), 29 | name: 'InklinePaperReact', 30 | fileName: (format) => `react.${format}.js` 31 | }, 32 | rollupOptions: { 33 | // make sure to externalize deps that shouldn't be bundled 34 | // into your library 35 | external: [ 36 | 'react' 37 | ], 38 | output: { 39 | exports: 'named', 40 | // Provide global variables to use in the UMD build 41 | // for externalized deps 42 | globals: { 43 | react: 'React' 44 | } 45 | } 46 | } 47 | }, 48 | test: { 49 | globals: true, 50 | environment: 'jsdom', 51 | exclude: [...configDefaults.exclude, 'lib/**'] 52 | } 53 | }); 54 | -------------------------------------------------------------------------------- /packages/vue/build.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | entries: [ 3 | { 4 | builder: 'mkdist', 5 | format: 'esm', 6 | ext: 'mjs', 7 | input: './src', 8 | declaration: true 9 | }, 10 | { 11 | builder: 'mkdist', 12 | format: 'cjs', 13 | ext: 'cjs', 14 | input: './src', 15 | declaration: true 16 | } 17 | ] 18 | }; 19 | -------------------------------------------------------------------------------- /packages/vue/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@inkline/paper-vue", 3 | "description": "Inkline Paper Vue.js package.", 4 | "scripts": { 5 | "pre": "cp ../common/src/types.ts src/types-common.ts", 6 | "pretest": "npm run pre", 7 | "test": "vitest run", 8 | "test:dev": "vitest", 9 | "prebuild": "npm run pre", 10 | "build": "unbuild" 11 | }, 12 | "devDependencies": { 13 | "@testing-library/vue": "6.5.1", 14 | "@vitejs/plugin-vue": "2.2.4", 15 | "@vue/compiler-sfc": "3.2.31", 16 | "@vue/runtime-core": "3.2.31", 17 | "jsdom": "^19.0.0", 18 | "unbuild": "0.7.2", 19 | "vite": "2.8.6", 20 | "vitest": "0.5.9", 21 | "vue": "3.2.31" 22 | }, 23 | "peerDependencies": { 24 | "vue": "*" 25 | }, 26 | "repository": { 27 | "type": "git", 28 | "url": "git+https://github.com/inkline/paper.git" 29 | }, 30 | "license": "ISC" 31 | } 32 | -------------------------------------------------------------------------------- /packages/vue/src/__tests__/__snapshots__/defineComponent.spec.tsx.snap: -------------------------------------------------------------------------------- 1 | // Vitest Snapshot v1 2 | 3 | exports[`vue > defineComponent() > context > provide/inject() > should provide data to children 1`] = ` 4 | "
5 |
value
6 |
" 7 | `; 8 | 9 | exports[`vue > defineComponent() > context > provide/inject() > should provide reactive data to children 1`] = ` 10 | "" 13 | `; 14 | 15 | exports[`vue > defineComponent() > context > slot() > should render react component with default slot, multiple children 1`] = ` 16 |
17 | 18 | 19 | Child 1 20 | 21 | 22 | 23 | 24 | Child 2 25 | 26 | 27 | 28 | 29 | Child 3 30 | 31 | 32 |
33 | `; 34 | 35 | exports[`vue > defineComponent() > context > slot() > should render react component with default slot, one child 1`] = ` 36 |
37 | 38 | Child 39 | 40 |
41 | `; 42 | 43 | exports[`vue > defineComponent() > context > slot() > should render react component with named slots 1`] = ` 44 |
45 | 46 | 47 | 48 | Header 49 | 50 | 51 | 52 | 53 | 54 | 55 | Body 56 | 57 | 58 | 59 | 60 | 61 | 62 | Footer 63 | 64 | 65 | 66 |
67 | `; 68 | 69 | exports[`vue > defineComponent() > should render a component with state and props 1`] = `""`; 70 | 71 | exports[`vue > defineComponent() > should render a component with state, props, and onClick state function 1`] = `""`; 72 | 73 | exports[`vue > defineComponent() > should render a vue component with state 1`] = `""`; 74 | -------------------------------------------------------------------------------- /packages/vue/src/__tests__/defineComponent.spec.tsx: -------------------------------------------------------------------------------- 1 | import { describe, it, expect, vi } from 'vitest'; 2 | import { render, fireEvent } from '@testing-library/vue'; 3 | import { defineComponent, h, ref, Events } from '../index'; 4 | 5 | describe('vue', () => { 6 | describe('defineComponent()', () => { 7 | it('should render component', () => { 8 | const componentDefinition = defineComponent({ 9 | render () { 10 | return
; 11 | } 12 | }); 13 | 14 | expect(componentDefinition).toEqual(componentDefinition); 15 | }); 16 | 17 | it('should render a vue component with state', () => { 18 | const Component = defineComponent({ 19 | setup () { 20 | const count = ref(0); 21 | 22 | return { count }; 23 | }, 24 | render (state) { 25 | return ; 28 | } 29 | }); 30 | 31 | const wrapper = render(Component); 32 | expect(wrapper.html()).toMatchSnapshot(); 33 | }); 34 | 35 | it('should render a component with state and props', () => { 36 | const Component = defineComponent({ 37 | props: { 38 | initialValue: { 39 | type: Number, 40 | default: 0 41 | } 42 | }, 43 | setup (props) { 44 | const count = ref(props.initialValue); 45 | 46 | return { count }; 47 | }, 48 | render (state) { 49 | return ; 50 | } 51 | }); 52 | 53 | const wrapper = render(Component, { 54 | props: { 55 | initialValue: 1 56 | } 57 | }); 58 | expect(wrapper.html()).toMatchSnapshot(); 59 | }); 60 | 61 | it('should render a component with state, props, and onClick state function', async () => { 62 | const Component = defineComponent({ 63 | props: { 64 | initialValue: { 65 | type: Number, 66 | default: 0 67 | } 68 | }, 69 | setup (props) { 70 | const count = ref(props.initialValue); 71 | 72 | const onClick = () => { 73 | count.value += 1; 74 | }; 75 | 76 | return { count, onClick }; 77 | }, 78 | render (state) { 79 | return ; 80 | } 81 | }); 82 | 83 | const wrapper = render(Component, { 84 | props: { 85 | initialValue: 1 86 | } 87 | }); 88 | await fireEvent.click(wrapper.container.firstChild as Element); 89 | expect(wrapper.html()).toMatchSnapshot(); 90 | }); 91 | 92 | describe('context', () => { 93 | describe('slot()', () => { 94 | it('should render react component with default slot, one child', () => { 95 | const Component = defineComponent({ 96 | render (state, ctx) { 97 | return
{ctx.slot()}
; 98 | } 99 | }); 100 | 101 | const wrapper = render(Component, { 102 | slots: { 103 | default: 'Child' 104 | } 105 | }); 106 | expect(wrapper.container.firstChild).toMatchSnapshot(); 107 | }); 108 | 109 | it('should render react component with default slot, multiple children', () => { 110 | const Component = defineComponent({ 111 | render (state, ctx) { 112 | return
113 | {ctx.slot()} 114 |
; 115 | } 116 | }); 117 | 118 | const wrapper = render(Component, { 119 | slots: { 120 | default: [ 121 | 'Child 1', 122 | 'Child 2', 123 | 'Child 3' 124 | ] 125 | } 126 | }); 127 | expect(wrapper.container.firstChild).toMatchSnapshot(); 128 | }); 129 | 130 | it('should render react component with named slots', () => { 131 | const Component = defineComponent({ 132 | slots: [ 133 | 'header', 134 | 'footer' 135 | ], 136 | emits: [ 137 | 'onUpdateModelValue' 138 | ], 139 | render (state, ctx) { 140 | return
141 | {ctx.slot('header')} 142 | {ctx.slot()} 143 | {ctx.slot('footer')} 144 |
; 145 | } 146 | }); 147 | 148 | const wrapper = render(Component, { 149 | slots: { 150 | header: ['Header'], 151 | default: ['Body'], 152 | footer: ['Footer'] 153 | } 154 | }); 155 | expect(wrapper.container.firstChild).toMatchSnapshot(); 156 | }); 157 | }); 158 | 159 | describe('emit()', () => { 160 | it('should emit event by using native emit', async () => { 161 | const Component = defineComponent({ 162 | emits: [ 163 | 'click' 164 | ], 165 | setup (props, ctx) { 166 | const onClick = () => { 167 | ctx.emit('click'); 168 | }; 169 | 170 | return { onClick }; 171 | }, 172 | render (state) { 173 | return ; 174 | } 175 | }); 176 | 177 | const wrapper = render(Component); 178 | await fireEvent.click(wrapper.container.firstChild as Element); 179 | 180 | expect(wrapper.emitted().click).toBeTruthy(); 181 | }); 182 | 183 | it('should emit event with arguments', async () => { 184 | const Component = defineComponent({ 185 | emits: [ 186 | 'click' 187 | ], 188 | setup (props, ctx) { 189 | const onClick = (event: Event) => { 190 | ctx.emit('click', event); 191 | }; 192 | 193 | return { onClick }; 194 | }, 195 | render (state) { 196 | return ; 197 | } 198 | }); 199 | 200 | const wrapper = render(Component); 201 | await fireEvent.click(wrapper.container.firstChild as Element); 202 | 203 | expect(wrapper.emitted().click).toBeTruthy(); 204 | expect(wrapper.emitted().click[0]).toEqual(expect.any(Object)); 205 | }); 206 | 207 | it('should render component with modelValue and update:modelValue', async () => { 208 | const Component = defineComponent({ 209 | props: { 210 | modelValue: { 211 | type: Number, 212 | default: 0 213 | } 214 | }, 215 | emits: [ 216 | 'update:modelValue' 217 | ], 218 | setup (props, ctx) { 219 | const onClick = () => { 220 | ctx.emit('update:modelValue', props.modelValue + 1); 221 | }; 222 | 223 | return { onClick }; 224 | }, 225 | render (state) { 226 | return ; 227 | } 228 | }); 229 | 230 | let value = 3; 231 | const onUpdate = vi.fn((newValue) => { value = newValue; }); 232 | const wrapper = render(Component, { 233 | props: { 234 | modelValue: value, 235 | 'onUpdate:modelValue': onUpdate 236 | } 237 | }); 238 | 239 | await fireEvent.click(wrapper.container.firstChild as Element); 240 | 241 | expect(onUpdate).toHaveBeenCalled(); 242 | expect(value).toEqual(4); 243 | }); 244 | 245 | it('should render component with input field', async () => { 246 | const Component = defineComponent({ 247 | props: { 248 | modelValue: { 249 | type: String, 250 | default: '' 251 | } 252 | }, 253 | emits: [ 254 | 'update:modelValue' 255 | ], 256 | setup (props, ctx) { 257 | const onChange = (event: Event) => { 258 | ctx.emit('update:modelValue', (event.target as HTMLInputElement).value); 259 | }; 260 | 261 | return { onChange }; 262 | }, 263 | render (state) { 264 | const events = { 265 | [Events.onInputChange]: state.onChange 266 | }; 267 | 268 | return ; 269 | } 270 | }); 271 | 272 | let value = ''; 273 | const onUpdate = vi.fn((newValue) => { value = newValue; }); 274 | const wrapper = render(Component, { 275 | props: { 276 | modelValue: value, 277 | 'onUpdate:modelValue': onUpdate 278 | } 279 | }); 280 | 281 | await fireEvent.update(wrapper.container.firstChild as Element, 'abc'); 282 | 283 | expect(onUpdate).toHaveBeenCalled(); 284 | expect(value).toEqual('abc'); 285 | }); 286 | }); 287 | 288 | describe('provide/inject()', () => { 289 | it('should provide data to children', async () => { 290 | const identifier = Symbol('provide'); 291 | const Provider = defineComponent({ 292 | setup (props, ctx) { 293 | ctx.provide(identifier, 'value'); 294 | 295 | return {}; 296 | }, 297 | render (state, ctx) { 298 | return
{ctx.slot()}
; 299 | } 300 | }); 301 | 302 | const Consumer = defineComponent({ 303 | setup (props, ctx) { 304 | const providedValue = ctx.inject(identifier); 305 | 306 | return { providedValue }; 307 | }, 308 | render (state) { 309 | return
{state.providedValue}
; 310 | } 311 | }); 312 | 313 | const wrapper = render(Provider, { 314 | slots: { 315 | default: Consumer 316 | } 317 | }); 318 | expect(wrapper.html()).toMatchSnapshot(); 319 | }); 320 | 321 | it('should provide reactive data to children', async () => { 322 | const identifier = Symbol('provide-reactive'); 323 | const Provider = defineComponent({ 324 | setup (props, ctx) { 325 | const count = ref(0); 326 | const onClick = () => { count.value += 1; }; 327 | 328 | ctx.provide(identifier, count); 329 | 330 | return { onClick }; 331 | }, 332 | render (state, ctx) { 333 | return ; 334 | } 335 | }); 336 | 337 | const Consumer = defineComponent({ 338 | setup (props, ctx) { 339 | const providedValue = ctx.inject(identifier); 340 | 341 | return { providedValue }; 342 | }, 343 | render (state) { 344 | return
{state.providedValue?.value}
; 345 | } 346 | }); 347 | 348 | const wrapper = render(Provider, { 349 | slots: { 350 | default: Consumer 351 | } 352 | }); 353 | await fireEvent.click(wrapper.container.firstChild as Element); 354 | expect(wrapper.findByText('1')).toBeTruthy(); 355 | expect(wrapper.html()).toMatchSnapshot(); 356 | }); 357 | }); 358 | }); 359 | }); 360 | }); 361 | -------------------------------------------------------------------------------- /packages/vue/src/__tests__/definePlugin.spec.tsx: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | import { definePlugin } from '../index'; 3 | import { createApp } from 'vue'; 4 | 5 | describe('vue', () => { 6 | describe('definePlugin()', () => { 7 | it('should create a new vue plugin', () => { 8 | const Plugin = definePlugin(() => {}); 9 | 10 | expect(Plugin).toHaveProperty('install'); 11 | expect(Plugin.install).toBeInstanceOf(Function); 12 | }); 13 | 14 | it('should be installable', () => { 15 | const app = createApp({}); 16 | const Inkline = definePlugin(() => {}); 17 | 18 | expect(() => app.use(Inkline)).not.toThrow(); 19 | }); 20 | 21 | it('should pass plugin options', () => { 22 | const pluginOptions = { color: 'light' }; 23 | const app = createApp({}); 24 | const Inkline = definePlugin((options) => { 25 | expect(options).toEqual(pluginOptions); 26 | }); 27 | 28 | app.use(Inkline, pluginOptions); 29 | }); 30 | 31 | it('should provide data to children', () => { 32 | const provideSymbol = Symbol('provided'); 33 | const provideData = { color: 'light' }; 34 | 35 | const app = createApp({}); 36 | const Inkline = definePlugin((options, { provide }) => { 37 | provide(provideSymbol, provideData); 38 | }); 39 | 40 | app.use(Inkline); 41 | 42 | expect(app.config.globalProperties).toHaveProperty(`$${provideSymbol.description}`, provideData); 43 | }); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /packages/vue/src/__tests__/h.spec.ts: -------------------------------------------------------------------------------- 1 | import { describe, it, expect } from 'vitest'; 2 | import { h } from '../index'; 3 | 4 | describe('vue', () => { 5 | describe('h()', () => { 6 | it('should return a vNode', () => { 7 | const type = 'div'; 8 | const props = { id: 'app' }; 9 | const children = [ 10 | h('span') 11 | ]; 12 | const vNode = h(type, props, children); 13 | 14 | expect(vNode).toHaveProperty('target'); 15 | expect(vNode).toHaveProperty('el'); 16 | expect(vNode.type).toEqual(type); 17 | expect(vNode.props).toEqual(props); 18 | expect(vNode.children).toEqual(children); 19 | }); 20 | 21 | it('should return native element', () => { 22 | const type = 'div'; 23 | const vNode = h(type); 24 | 25 | expect(vNode).toBeDefined(); 26 | expect(vNode.type).toEqual(type); 27 | }); 28 | 29 | it('should return native vNode with props', () => { 30 | const type = 'div'; 31 | const props = { id: 'app' }; 32 | const vNode = h(type, props); 33 | 34 | expect(vNode).toBeDefined(); 35 | expect(vNode.type).toEqual(type); 36 | expect(vNode.props).toEqual(props); 37 | }); 38 | 39 | it('should return native vNode with one child', () => { 40 | const type = 'div'; 41 | const props = { id: 'app' }; 42 | const children = [ 43 | h('span', { key: 0 }) 44 | ]; 45 | const vNode = h(type, props, children); 46 | 47 | expect(vNode).toBeDefined(); 48 | expect(vNode.type).toEqual('div'); 49 | expect(vNode.props).toEqual(props); 50 | expect(vNode.children).toEqual(children); 51 | }); 52 | 53 | it('should return native vNode with multiple children', () => { 54 | const type = 'div'; 55 | const props = { id: 'app' }; 56 | const children = [ 57 | h('span', { key: 0 }), 58 | h('span', { key: 1 }), 59 | h('span', { key: 2 }) 60 | ]; 61 | const vNode = h(type, props, children); 62 | 63 | expect(vNode).toBeDefined(); 64 | expect(vNode.type).toEqual('div'); 65 | expect(vNode.props).toEqual(props); 66 | expect(vNode.children).toEqual(children); 67 | }); 68 | 69 | it('should accept multiple children as spread argument', () => { 70 | const type = 'div'; 71 | const props = { id: 'app' }; 72 | const children = [ 73 | h('span', { key: 0 }), 74 | h('span', { key: 1 }), 75 | h('span', { key: 2 }) 76 | ]; 77 | const vNode = h(type, props, ...children); 78 | 79 | expect(vNode).toBeDefined(); 80 | expect(vNode.type).toEqual('div'); 81 | expect(vNode.props).toEqual(props); 82 | expect(vNode.children).toEqual(children); 83 | }); 84 | }); 85 | }); 86 | -------------------------------------------------------------------------------- /packages/vue/src/computed.ts: -------------------------------------------------------------------------------- 1 | import { computed as nativeComputed } from 'vue'; 2 | import { ComputedFn } from './types'; 3 | 4 | export const computed: ComputedFn = (computeFn) => nativeComputed(computeFn); 5 | -------------------------------------------------------------------------------- /packages/vue/src/defineComponent.ts: -------------------------------------------------------------------------------- 1 | import { SetupContext as VueSetupContext } from 'vue'; 2 | import { SetupContext, RenderContext, DefineVueComponentFn, SlotFn, HasSlotFn } from './types'; 3 | import { provide as nativeProvide, inject as nativeInject } from 'vue'; 4 | import { InjectFn, ProvideFn } from './types'; 5 | 6 | /** 7 | * Define Vue component using Composition API and setup() 8 | * 9 | * @param definition universal component definition 10 | */ 11 | 12 | export const defineComponent: DefineVueComponentFn = (definition) => { 13 | return { 14 | name: definition.name || '', 15 | emits: definition.emits || [], 16 | slots: definition.slots || [], 17 | props: definition.props || {}, 18 | setup (props, { attrs, slots, emit }: VueSetupContext) { 19 | /** 20 | * Render slot 21 | * 22 | * @param name 23 | */ 24 | const slot: SlotFn = (name = 'default') => { 25 | return slots[name]?.(); 26 | }; 27 | 28 | /** 29 | * Helper to check if slots have children provided 30 | * 31 | * @param name 32 | */ 33 | const hasSlot: HasSlotFn = (name = 'default') => { 34 | return !!slots[name]; 35 | }; 36 | 37 | /** 38 | * Wrapper for native Vue provide function 39 | * 40 | * @param identifier 41 | * @param value 42 | */ 43 | const provide: ProvideFn = (identifier, value) => nativeProvide(identifier, value); 44 | 45 | /** 46 | * Wrapper for native Vue inject function 47 | * 48 | * @param identifier 49 | * @param defaultValue 50 | */ 51 | const inject: InjectFn = (identifier, defaultValue?) => nativeInject(identifier, defaultValue); 52 | 53 | /** 54 | * Setup context 55 | */ 56 | const setupContext: SetupContext = { 57 | emit, 58 | provide, 59 | inject, 60 | hasSlot 61 | }; 62 | 63 | /** 64 | * State and props 65 | */ 66 | let state = { 67 | ...attrs, 68 | ...props 69 | }; 70 | 71 | if (definition.setup) { 72 | state = Object.assign(state, definition.setup(state, setupContext)); 73 | } 74 | 75 | /** 76 | * Render context 77 | */ 78 | const renderContext: RenderContext = { 79 | slot, 80 | hasSlot 81 | }; 82 | 83 | /** 84 | * Render 85 | */ 86 | return () => definition.render(state, renderContext); 87 | } 88 | }; 89 | }; 90 | -------------------------------------------------------------------------------- /packages/vue/src/definePlugin.ts: -------------------------------------------------------------------------------- 1 | import { DefineVuePluginFn } from './types'; 2 | 3 | export const definePlugin: DefineVuePluginFn = (setup) => ({ 4 | install (app, options) { 5 | /** 6 | * Register components provided through options globally 7 | */ 8 | 9 | for (const componentIndex in options?.components) { 10 | if (options.components[componentIndex].name) { 11 | app.component(options.components[componentIndex].name, options.components[componentIndex]); 12 | } 13 | } 14 | 15 | /** 16 | * Setup the plugin 17 | */ 18 | 19 | setup(options, { 20 | provide: (identifier, data) => { 21 | app.config.globalProperties[`$${typeof identifier === 'symbol' ? identifier.description : identifier}`] = data; 22 | app.provide(identifier, data); 23 | } 24 | }); 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /packages/vue/src/env.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.vue' { 2 | import type { DefineComponent } from 'vue'; 3 | // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types 4 | const component: DefineComponent<{}, {}, any>; 5 | export default component; 6 | } 7 | -------------------------------------------------------------------------------- /packages/vue/src/events.ts: -------------------------------------------------------------------------------- 1 | export enum Events { 2 | onInputChange = 'onInput' 3 | } 4 | -------------------------------------------------------------------------------- /packages/vue/src/fragment.ts: -------------------------------------------------------------------------------- 1 | import { FragmentFn } from './types-common'; 2 | import { VNode } from './types'; 3 | 4 | /** 5 | * Render child elements using Fragment 6 | * 7 | * @example <> 8 | */ 9 | export const Fragment: FragmentFn = (props) => { 10 | return props.children; 11 | }; 12 | -------------------------------------------------------------------------------- /packages/vue/src/h.ts: -------------------------------------------------------------------------------- 1 | import { h as createElement, VNode } from 'vue'; 2 | import { HoistFn } from './types'; 3 | import { Component, DefineComponent } from '@vue/runtime-core'; 4 | 5 | /** 6 | * Render native element or Vue.js component 7 | * 8 | * @example h('p', { class: 'paragraph' }, 'Hello world!') 9 | * @example h(Component, { color: 'primary' }, { default: () => 'Hello world!' }) 10 | */ 11 | export const h: HoistFn> = ( 12 | type, 13 | props?, 14 | ...children 15 | ) => { 16 | return createElement(type as DefineComponent, props, ...children); 17 | }; 18 | -------------------------------------------------------------------------------- /packages/vue/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './computed'; 2 | export * from './defineComponent'; 3 | export * from './definePlugin'; 4 | export * from './events'; 5 | export * from './fragment'; 6 | export * from './h'; 7 | export * from './ref'; 8 | export * from './types'; 9 | export * from './watch'; 10 | -------------------------------------------------------------------------------- /packages/vue/src/ref.ts: -------------------------------------------------------------------------------- 1 | import { ref as nativeRef } from 'vue'; 2 | import { RefFn } from './types'; 3 | 4 | export const ref: RefFn = (value) => nativeRef(value); 5 | -------------------------------------------------------------------------------- /packages/vue/src/storybook/createStory.ts: -------------------------------------------------------------------------------- 1 | import { CreateStoryFn, defineComponent, h } from '../index'; 2 | import { Component } from '@vue/runtime-core'; 3 | 4 | export const createStory: CreateStoryFn = (component, storyArgs = {}) => (args: Record) => defineComponent({ 5 | render: () => h('div', { 6 | class: `storybook-example ${storyArgs.class || ''}` 7 | }, h(component, args)) 8 | }); 9 | -------------------------------------------------------------------------------- /packages/vue/src/storybook/index.ts: -------------------------------------------------------------------------------- 1 | export * from './createStory'; 2 | -------------------------------------------------------------------------------- /packages/vue/src/types-common.ts: -------------------------------------------------------------------------------- 1 | export type Ref = { value: T }; 2 | 3 | export type UnwrapState = { 4 | [key in keyof State]: (State[key] & Ref)['value'] 5 | }; 6 | 7 | /** 8 | * Component definition 9 | */ 10 | 11 | export type ConstructorType = 12 | | NumberConstructor 13 | | StringConstructor 14 | | BooleanConstructor 15 | | ObjectConstructor 16 | | ArrayConstructor; 17 | 18 | export type ComponentProps = { 19 | [key in keyof Props]: 20 | | { type?: NumberConstructor, default?: number | (() => number) } 21 | | { type?: StringConstructor, default?: string | (() => string) } 22 | | { type?: BooleanConstructor, default?: boolean | (() => boolean) } 23 | | { type?: ObjectConstructor, default?: object | (() => object) } 24 | | { type?: ArrayConstructor, default?: unknown[] | (() => unknown[]) } 25 | } 26 | 27 | export type UnwrapProps = { 28 | [key in keyof ComponentProps]: ComponentProps[key]['default'] | null; 29 | } 30 | 31 | export interface EmitFn { 32 | (eventName: string, ...args: any[]): void; 33 | } 34 | 35 | export interface SlotFn { 36 | (name?: string): T; 37 | } 38 | 39 | export interface HasSlotFn { 40 | (name?: string): boolean; 41 | } 42 | 43 | export interface ProvideFn { 44 | (identifier: string | symbol, value: T, dependencies?: any[]): void; 45 | } 46 | 47 | export interface InjectFn { 48 | (identifier: string | symbol, defaultValue?: T | (() => T)): T | undefined 49 | } 50 | 51 | export interface SetupContext { 52 | emit: EmitFn; 53 | hasSlot: HasSlotFn; 54 | provide: ProvideFn; 55 | inject: InjectFn; 56 | } 57 | 58 | export interface RenderContext { 59 | slot: SlotFn; 60 | hasSlot: HasSlotFn; 61 | } 62 | 63 | export interface ComponentDefinition< 64 | Props extends Record = {}, 65 | State extends Record = {}, 66 | VNode = any 67 | > { 68 | name?: string; 69 | slots?: string[]; 70 | emits?: string[]; 71 | props?: ComponentProps; 72 | setup?(props: Props, context: SetupContext): State; 73 | render(state: Props & State, context: RenderContext): VNode; 74 | } 75 | 76 | /** 77 | * Providers 78 | */ 79 | 80 | export interface Providers { 81 | [key: string | symbol]: { 82 | state: any; 83 | setState(newValue: any): void; 84 | notify(newValue: any): void; 85 | }; 86 | } 87 | 88 | export interface RegisterProviderFn { 89 | (identifier: string | symbol, value: T): void; 90 | } 91 | 92 | export interface UpdateProviderFn { 93 | (identifier: string | symbol, value: T): void; 94 | } 95 | 96 | /** 97 | * Function types 98 | */ 99 | 100 | export interface DefineComponentFn { 101 | (definition: ComponentDefinition): ComponentType; 102 | } 103 | 104 | export interface RefFn { 105 | (initialValue: T): Ref; 106 | } 107 | 108 | export interface ComputedFn { 109 | (computeFn: () => T, dependencies?: any[]): Ref; 110 | } 111 | 112 | export interface WatchFn { 113 | (dependency: () => T, callback: (newValue: T) => void): void; 114 | } 115 | 116 | export interface HoistFn { 117 | (type: string | D, props?: Record, ...children: (C | C[] | Record (C | C[])>)[]): T 118 | } 119 | 120 | export interface FragmentFn { 121 | (props: { children?: C | C[] }): C | C[] | undefined; 122 | } 123 | 124 | /** 125 | * Plugin types 126 | */ 127 | 128 | export interface DefinePluginContext { 129 | provide: ProvideFn; 130 | } 131 | 132 | export interface DefinePluginFn { 133 | (setup: (options: Options, context: DefinePluginContext) => void): Plugin; 134 | } 135 | 136 | /** 137 | * Storybook types 138 | */ 139 | 140 | export interface CreateStoryFn { 141 | (component: T, storyArgs?: { class?: string; }): any; 142 | } 143 | -------------------------------------------------------------------------------- /packages/vue/src/types.ts: -------------------------------------------------------------------------------- 1 | import { DefineComponentFn, DefinePluginFn } from './types-common'; 2 | import { Plugin, VNode } from 'vue'; 3 | import { Component } from '@vue/runtime-core'; 4 | 5 | export * from './types-common'; 6 | 7 | export { VNode } from 'vue'; 8 | 9 | export type DefineVueComponentFn< 10 | State = Record, 11 | Props = Record 12 | > = DefineComponentFn 13 | 14 | export type DefineVuePluginFn = DefinePluginFn }>; 15 | -------------------------------------------------------------------------------- /packages/vue/src/watch.ts: -------------------------------------------------------------------------------- 1 | import { watch as nativeWatch } from 'vue'; 2 | import { WatchFn } from './types'; 3 | 4 | export const watch: WatchFn = (dependency, callback) => nativeWatch(dependency, callback); 5 | -------------------------------------------------------------------------------- /packages/vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "include": [ 4 | "src/**/*.ts", 5 | "src/**/*.tsx" 6 | ], 7 | "compilerOptions": { 8 | "target": "esnext", 9 | "useDefineForClassFields": true, 10 | "module": "esnext", 11 | "moduleResolution": "node", 12 | "strict": true, 13 | "jsx": "preserve", 14 | "jsxFactory": "h", 15 | "jsxFragmentFactory": "Fragment", 16 | "skipLibCheck": true, 17 | "sourceMap": true, 18 | "resolveJsonModule": true, 19 | "esModuleInterop": true, 20 | "lib": ["esnext", "dom"], 21 | "baseUrl": ".", 22 | "rootDir": "src", 23 | "outDir": "lib", 24 | "paths": { 25 | "@inkline/paper/*": ["./src/*"] 26 | }, 27 | "types": [ 28 | "vue", 29 | "vite/client" 30 | ] 31 | }, 32 | "references": [ 33 | { 34 | "path": "./tsconfig.vite.json" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /packages/vue/tsconfig.vite.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "types": [ 7 | "vite/client", 8 | "vitest/globals" 9 | ] 10 | }, 11 | "include": [ 12 | "vite.config.ts" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /packages/vue/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import { resolve } from 'path'; 3 | import { configDefaults } from 'vitest/config'; 4 | import vue from '@vitejs/plugin-vue'; 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [ 9 | vue() 10 | ], 11 | esbuild: { 12 | jsxFactory: 'h', 13 | jsxFragment: 'Fragment', 14 | jsxInject: '' 15 | }, 16 | resolve: { 17 | alias: [ 18 | { 19 | find: /^@inkline\/paper\//, 20 | replacement: `${resolve(__dirname)}/src/` 21 | } 22 | ] 23 | }, 24 | build: { 25 | lib: { 26 | entry: resolve(__dirname, 'src', 'index.ts'), 27 | name: 'InklinePaperVue', 28 | fileName: (format) => `vue.${format}.js` 29 | }, 30 | rollupOptions: { 31 | // make sure to externalize deps that shouldn't be bundled 32 | // into your library 33 | external: [ 34 | 'vue' 35 | ], 36 | output: { 37 | exports: 'named', 38 | // Provide global variables to use in the UMD build 39 | // for externalized deps 40 | globals: { 41 | vue: 'Vue' 42 | } 43 | } 44 | } 45 | }, 46 | test: { 47 | globals: true, 48 | environment: 'jsdom', 49 | exclude: [...configDefaults.exclude, 'lib/**'] 50 | } 51 | }); 52 | -------------------------------------------------------------------------------- /scripts/build.ts: -------------------------------------------------------------------------------- 1 | import * as shell from 'shelljs'; 2 | import { resolve } from 'path'; 3 | 4 | /** 5 | * Change directory to root 6 | */ 7 | 8 | shell.cd(resolve(__dirname, '..')); 9 | 10 | /** 11 | * Copy files to lib folder 12 | */ 13 | 14 | shell.mkdir('lib'); 15 | 16 | shell.cp('./README.md', 'lib'); 17 | shell.cp('./LICENSE', 'lib'); 18 | shell.cp('-R', './src/*', 'lib'); 19 | -------------------------------------------------------------------------------- /scripts/postbuild.ts: -------------------------------------------------------------------------------- 1 | import * as shell from 'shelljs'; 2 | import { resolve } from 'path'; 3 | 4 | /** 5 | * Change directory to root 6 | */ 7 | 8 | shell.cd(resolve(__dirname, '..')); 9 | 10 | /** 11 | * Copy files to lib folder 12 | */ 13 | 14 | shell.mkdir('lib'); 15 | shell.cp('-r', 'packages/common/dist/*', 'lib'); 16 | shell.rm('-r', 'packages/common/dist'); 17 | 18 | [ 19 | 'react', 20 | 'vue' 21 | ].forEach((packageName) => { 22 | shell.mkdir(`lib/${packageName}`); 23 | shell.cp('-r', `packages/${packageName}/dist/*`, `lib/${packageName}`); 24 | shell.rm('-r', `packages/${packageName}/dist`); 25 | }); 26 | 27 | shell.rm('-r', 'lib/**/__tests__'); 28 | 29 | shell.cp('./README.md', 'lib'); 30 | shell.cp('./LICENSE', 'lib'); 31 | -------------------------------------------------------------------------------- /scripts/postrelease.ts: -------------------------------------------------------------------------------- 1 | import * as shell from 'shelljs'; 2 | import { resolve } from 'path'; 3 | 4 | /** 5 | * Change directory to root 6 | */ 7 | 8 | shell.cd(resolve(__dirname, '..')); 9 | 10 | /** 11 | * Remove build files 12 | */ 13 | 14 | shell.rm('-R', ['./lib']); 15 | -------------------------------------------------------------------------------- /scripts/postversion.ts: -------------------------------------------------------------------------------- 1 | import * as shell from 'shelljs'; 2 | import { resolve } from 'path'; 3 | 4 | /** 5 | * Change directory to root 6 | */ 7 | 8 | shell.cd(resolve(__dirname, '..')); 9 | 10 | /** 11 | * Copy package.json to lib 12 | */ 13 | 14 | shell.cp('./package.json', './lib/package.json'); 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "useDefineForClassFields": true, 5 | "module": "esnext", 6 | "moduleResolution": "node", 7 | "strict": true, 8 | "jsx": "preserve", 9 | "sourceMap": true, 10 | "resolveJsonModule": true, 11 | "esModuleInterop": true, 12 | "lib": ["esnext", "dom"], 13 | "baseUrl": ".", 14 | "rootDir": "src", 15 | "outDir": "lib", 16 | "typeRoots": [], 17 | "types": [ 18 | "@types/shelljs", 19 | "vite/client", 20 | "vitest/globals" 21 | ] 22 | }, 23 | "include": [ 24 | "packages/**/*.ts", 25 | "packages/**/*.d.ts", 26 | "packages/**/*.tsx", 27 | "packages/**/*.vue" 28 | ], 29 | "references": [ 30 | { 31 | "path": "./tsconfig.vite.json" 32 | }, 33 | { 34 | "path": "./packages/common/tsconfig.json" 35 | }, 36 | { 37 | "path": "./packages/react/tsconfig.json" 38 | }, 39 | { 40 | "path": "./packages/vue/tsconfig.json" 41 | } 42 | ], 43 | "ts-node": { 44 | "transpileOnly": true, 45 | "compilerOptions": { 46 | "module": "commonjs" 47 | }, 48 | "require": ["tsconfig-paths/register"] 49 | } 50 | } 51 | --------------------------------------------------------------------------------