diff --git a/api/request.ts b/api/request.ts new file mode 100644 index 0000000..a4c63e5 --- /dev/null +++ b/api/request.ts @@ -0,0 +1,3 @@ +export const baseUrl = 'http://localhost:9092/api' //后端接口文档 +export const testUrl = 'http://123.249.108.160:8888/api' //自己组的服务器接口地址 +export const suiUrl = 'http://154.8.193.216:9092/api' //隋宇霏的接口地址 \ No newline at end of file diff --git a/main.js b/main.js index cb25a2f..b2b3543 100644 --- a/main.js +++ b/main.js @@ -1,8 +1,6 @@ - // #ifndef VUE3 import Vue from 'vue' import App from './App' - Vue.config.productionTip = false App.mpType = 'app' @@ -11,13 +9,16 @@ const app = new Vue({ ...App }) app.$mount() + // #endif // #ifdef VUE3 +import pinia from './store' import { createSSRApp } from 'vue' import App from './App.vue' export function createApp() { const app = createSSRApp(App) + app.use(pinia) return { app } diff --git a/manifest.json b/manifest.json index 47aca51..49dc1a3 100644 --- a/manifest.json +++ b/manifest.json @@ -50,7 +50,7 @@ /* 快应用特有相关 */ "mp-weixin" : { /* 小程序特有相关 */ - "appid" : "wxbcb1cf9951fa17c8", + "appid" : "wx3f968a09e31d6bed", "setting" : { "urlCheck" : false }, diff --git a/node_modules/.bin/vue-demi-fix b/node_modules/.bin/vue-demi-fix new file mode 100644 index 0000000..e05d388 --- /dev/null +++ b/node_modules/.bin/vue-demi-fix @@ -0,0 +1,15 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -x "$basedir/node" ]; then + "$basedir/node" "$basedir/../vue-demi/bin/vue-demi-fix.js" "$@" + ret=$? +else + node "$basedir/../vue-demi/bin/vue-demi-fix.js" "$@" + ret=$? +fi +exit $ret diff --git a/node_modules/.bin/vue-demi-fix.cmd b/node_modules/.bin/vue-demi-fix.cmd new file mode 100644 index 0000000..8f40137 --- /dev/null +++ b/node_modules/.bin/vue-demi-fix.cmd @@ -0,0 +1,17 @@ +@ECHO off +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +"%_prog%" "%dp0%\..\vue-demi\bin\vue-demi-fix.js" %* +ENDLOCAL +EXIT /b %errorlevel% +:find_dp0 +SET dp0=%~dp0 +EXIT /b diff --git a/node_modules/.bin/vue-demi-fix.ps1 b/node_modules/.bin/vue-demi-fix.ps1 new file mode 100644 index 0000000..0972a40 --- /dev/null +++ b/node_modules/.bin/vue-demi-fix.ps1 @@ -0,0 +1,18 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + & "$basedir/node$exe" "$basedir/../vue-demi/bin/vue-demi-fix.js" $args + $ret=$LASTEXITCODE +} else { + & "node$exe" "$basedir/../vue-demi/bin/vue-demi-fix.js" $args + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/.bin/vue-demi-switch b/node_modules/.bin/vue-demi-switch new file mode 100644 index 0000000..6f80ef6 --- /dev/null +++ b/node_modules/.bin/vue-demi-switch @@ -0,0 +1,15 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -x "$basedir/node" ]; then + "$basedir/node" "$basedir/../vue-demi/bin/vue-demi-switch.js" "$@" + ret=$? +else + node "$basedir/../vue-demi/bin/vue-demi-switch.js" "$@" + ret=$? +fi +exit $ret diff --git a/node_modules/.bin/vue-demi-switch.cmd b/node_modules/.bin/vue-demi-switch.cmd new file mode 100644 index 0000000..d355008 --- /dev/null +++ b/node_modules/.bin/vue-demi-switch.cmd @@ -0,0 +1,17 @@ +@ECHO off +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +"%_prog%" "%dp0%\..\vue-demi\bin\vue-demi-switch.js" %* +ENDLOCAL +EXIT /b %errorlevel% +:find_dp0 +SET dp0=%~dp0 +EXIT /b diff --git a/node_modules/.bin/vue-demi-switch.ps1 b/node_modules/.bin/vue-demi-switch.ps1 new file mode 100644 index 0000000..4ffe298 --- /dev/null +++ b/node_modules/.bin/vue-demi-switch.ps1 @@ -0,0 +1,18 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + & "$basedir/node$exe" "$basedir/../vue-demi/bin/vue-demi-switch.js" $args + $ret=$LASTEXITCODE +} else { + & "node$exe" "$basedir/../vue-demi/bin/vue-demi-switch.js" $args + $ret=$LASTEXITCODE +} +exit $ret diff --git a/node_modules/@vue/devtools-api/lib/cjs/api/api.js b/node_modules/@vue/devtools-api/lib/cjs/api/api.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/cjs/api/api.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@vue/devtools-api/lib/cjs/api/app.js b/node_modules/@vue/devtools-api/lib/cjs/api/app.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/cjs/api/app.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@vue/devtools-api/lib/cjs/api/component.js b/node_modules/@vue/devtools-api/lib/cjs/api/component.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/cjs/api/component.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@vue/devtools-api/lib/cjs/api/context.js b/node_modules/@vue/devtools-api/lib/cjs/api/context.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/cjs/api/context.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@vue/devtools-api/lib/cjs/api/hooks.js b/node_modules/@vue/devtools-api/lib/cjs/api/hooks.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/cjs/api/hooks.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@vue/devtools-api/lib/cjs/api/index.js b/node_modules/@vue/devtools-api/lib/cjs/api/index.js new file mode 100644 index 0000000..22f7589 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/cjs/api/index.js @@ -0,0 +1,22 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +__exportStar(require("./api.js"), exports); +__exportStar(require("./app.js"), exports); +__exportStar(require("./component.js"), exports); +__exportStar(require("./context.js"), exports); +__exportStar(require("./hooks.js"), exports); +__exportStar(require("./util.js"), exports); diff --git a/node_modules/@vue/devtools-api/lib/cjs/api/util.js b/node_modules/@vue/devtools-api/lib/cjs/api/util.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/cjs/api/util.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@vue/devtools-api/lib/cjs/const.js b/node_modules/@vue/devtools-api/lib/cjs/const.js new file mode 100644 index 0000000..84d408c --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/cjs/const.js @@ -0,0 +1,5 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.HOOK_PLUGIN_SETTINGS_SET = exports.HOOK_SETUP = void 0; +exports.HOOK_SETUP = 'devtools-plugin:setup'; +exports.HOOK_PLUGIN_SETTINGS_SET = 'plugin:settings:set'; diff --git a/node_modules/@vue/devtools-api/lib/cjs/env.js b/node_modules/@vue/devtools-api/lib/cjs/env.js new file mode 100644 index 0000000..e6c7ebd --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/cjs/env.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isProxyAvailable = exports.getTarget = exports.getDevtoolsGlobalHook = void 0; +function getDevtoolsGlobalHook() { + return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__; +} +exports.getDevtoolsGlobalHook = getDevtoolsGlobalHook; +function getTarget() { + // @ts-expect-error navigator and windows are not available in all environments + return (typeof navigator !== 'undefined' && typeof window !== 'undefined') + ? window + : typeof globalThis !== 'undefined' + ? globalThis + : {}; +} +exports.getTarget = getTarget; +exports.isProxyAvailable = typeof Proxy === 'function'; diff --git a/node_modules/@vue/devtools-api/lib/cjs/index.js b/node_modules/@vue/devtools-api/lib/cjs/index.js new file mode 100644 index 0000000..f8b5fc3 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/cjs/index.js @@ -0,0 +1,45 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.setupDevtoolsPlugin = void 0; +const env_js_1 = require("./env.js"); +const const_js_1 = require("./const.js"); +const proxy_js_1 = require("./proxy.js"); +__exportStar(require("./api/index.js"), exports); +__exportStar(require("./plugin.js"), exports); +__exportStar(require("./time.js"), exports); +function setupDevtoolsPlugin(pluginDescriptor, setupFn) { + const descriptor = pluginDescriptor; + const target = (0, env_js_1.getTarget)(); + const hook = (0, env_js_1.getDevtoolsGlobalHook)(); + const enableProxy = env_js_1.isProxyAvailable && descriptor.enableEarlyProxy; + if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) { + hook.emit(const_js_1.HOOK_SETUP, pluginDescriptor, setupFn); + } + else { + const proxy = enableProxy ? new proxy_js_1.ApiProxy(descriptor, hook) : null; + const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || []; + list.push({ + pluginDescriptor: descriptor, + setupFn, + proxy, + }); + if (proxy) { + setupFn(proxy.proxiedTarget); + } + } +} +exports.setupDevtoolsPlugin = setupDevtoolsPlugin; diff --git a/node_modules/@vue/devtools-api/lib/cjs/plugin.js b/node_modules/@vue/devtools-api/lib/cjs/plugin.js new file mode 100644 index 0000000..c8ad2e5 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/cjs/plugin.js @@ -0,0 +1,2 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/node_modules/@vue/devtools-api/lib/cjs/proxy.js b/node_modules/@vue/devtools-api/lib/cjs/proxy.js new file mode 100644 index 0000000..731c9ac --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/cjs/proxy.js @@ -0,0 +1,111 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.ApiProxy = void 0; +const const_js_1 = require("./const.js"); +const time_js_1 = require("./time.js"); +class ApiProxy { + constructor(plugin, hook) { + this.target = null; + this.targetQueue = []; + this.onQueue = []; + this.plugin = plugin; + this.hook = hook; + const defaultSettings = {}; + if (plugin.settings) { + for (const id in plugin.settings) { + const item = plugin.settings[id]; + defaultSettings[id] = item.defaultValue; + } + } + const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`; + let currentSettings = Object.assign({}, defaultSettings); + try { + const raw = localStorage.getItem(localSettingsSaveId); + const data = JSON.parse(raw); + Object.assign(currentSettings, data); + } + catch (e) { + // noop + } + this.fallbacks = { + getSettings() { + return currentSettings; + }, + setSettings(value) { + try { + localStorage.setItem(localSettingsSaveId, JSON.stringify(value)); + } + catch (e) { + // noop + } + currentSettings = value; + }, + now() { + return (0, time_js_1.now)(); + }, + }; + if (hook) { + hook.on(const_js_1.HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => { + if (pluginId === this.plugin.id) { + this.fallbacks.setSettings(value); + } + }); + } + this.proxiedOn = new Proxy({}, { + get: (_target, prop) => { + if (this.target) { + return this.target.on[prop]; + } + else { + return (...args) => { + this.onQueue.push({ + method: prop, + args, + }); + }; + } + }, + }); + this.proxiedTarget = new Proxy({}, { + get: (_target, prop) => { + if (this.target) { + return this.target[prop]; + } + else if (prop === 'on') { + return this.proxiedOn; + } + else if (Object.keys(this.fallbacks).includes(prop)) { + return (...args) => { + this.targetQueue.push({ + method: prop, + args, + resolve: () => { }, + }); + return this.fallbacks[prop](...args); + }; + } + else { + return (...args) => { + return new Promise((resolve) => { + this.targetQueue.push({ + method: prop, + args, + resolve, + }); + }); + }; + } + }, + }); + } + async setRealTarget(target) { + this.target = target; + for (const item of this.onQueue) { + this.target.on[item.method](...item.args); + } + for (const item of this.targetQueue) { + item.resolve(await this.target[item.method](...item.args)); + } + } +} +exports.ApiProxy = ApiProxy; diff --git a/node_modules/@vue/devtools-api/lib/cjs/time.js b/node_modules/@vue/devtools-api/lib/cjs/time.js new file mode 100644 index 0000000..78d7f67 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/cjs/time.js @@ -0,0 +1,28 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.now = exports.isPerformanceSupported = void 0; +let supported; +let perf; +function isPerformanceSupported() { + var _a; + if (supported !== undefined) { + return supported; + } + if (typeof window !== 'undefined' && window.performance) { + supported = true; + perf = window.performance; + } + else if (typeof globalThis !== 'undefined' && ((_a = globalThis.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) { + supported = true; + perf = globalThis.perf_hooks.performance; + } + else { + supported = false; + } + return supported; +} +exports.isPerformanceSupported = isPerformanceSupported; +function now() { + return isPerformanceSupported() ? perf.now() : Date.now(); +} +exports.now = now; diff --git a/node_modules/@vue/devtools-api/lib/esm/api/api.d.ts b/node_modules/@vue/devtools-api/lib/esm/api/api.d.ts new file mode 100644 index 0000000..2e5494c --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/api/api.d.ts @@ -0,0 +1,108 @@ +import type { ComponentBounds, Hookable } from './hooks.js'; +import type { Context } from './context.js'; +import type { ComponentInstance, ComponentState, StateBase } from './component.js'; +import type { App } from './app.js'; +import type { ID } from './util.js'; +export interface DevtoolsPluginApi { + on: Hookable; + notifyComponentUpdate: (instance?: ComponentInstance) => void; + addTimelineLayer: (options: TimelineLayerOptions) => void; + addTimelineEvent: (options: TimelineEventOptions) => void; + addInspector: (options: CustomInspectorOptions) => void; + sendInspectorTree: (inspectorId: string) => void; + sendInspectorState: (inspectorId: string) => void; + selectInspectorNode: (inspectorId: string, nodeId: string) => void; + getComponentBounds: (instance: ComponentInstance) => Promise; + getComponentName: (instance: ComponentInstance) => Promise; + getComponentInstances: (app: App) => Promise; + highlightElement: (instance: ComponentInstance) => void; + unhighlightElement: () => void; + getSettings: (pluginId?: string) => TSettings; + now: () => number; + /** + * @private + */ + setSettings: (values: TSettings) => void; +} +export interface AppRecord { + id: string; + name: string; + instanceMap: Map; + rootInstance: ComponentInstance; +} +export interface TimelineLayerOptions { + id: string; + label: string; + color: number; + skipScreenshots?: boolean; + groupsOnly?: boolean; + ignoreNoDurationGroups?: boolean; + screenshotOverlayRender?: (event: TimelineEvent & ScreenshotOverlayEvent, ctx: ScreenshotOverlayRenderContext) => ScreenshotOverlayRenderResult | Promise; +} +export interface ScreenshotOverlayEvent { + layerId: string; + renderMeta: any; +} +export interface ScreenshotOverlayRenderContext { + screenshot: ScreenshotData; + events: (TimelineEvent & ScreenshotOverlayEvent)[]; + index: number; +} +export type ScreenshotOverlayRenderResult = HTMLElement | string | false; +export interface ScreenshotData { + time: number; +} +export interface TimelineEventOptions { + layerId: string; + event: TimelineEvent; + all?: boolean; +} +export interface TimelineEvent { + time: number; + data: TData; + logType?: 'default' | 'warning' | 'error'; + meta?: TMeta; + groupId?: ID; + title?: string; + subtitle?: string; +} +export interface TimelineMarkerOptions { + id: string; + time: number; + color: number; + label: string; + all?: boolean; +} +export interface CustomInspectorOptions { + id: string; + label: string; + icon?: string; + treeFilterPlaceholder?: string; + stateFilterPlaceholder?: string; + noSelectionText?: string; + actions?: { + icon: string; + tooltip?: string; + action: () => void | Promise; + }[]; + nodeActions?: { + icon: string; + tooltip?: string; + action: (nodeId: string) => void | Promise; + }[]; +} +export interface CustomInspectorNode { + id: string; + label: string; + children?: CustomInspectorNode[]; + tags?: InspectorNodeTag[]; +} +export interface InspectorNodeTag { + label: string; + textColor: number; + backgroundColor: number; + tooltip?: string; +} +export interface CustomInspectorState { + [key: string]: (StateBase | Omit)[]; +} diff --git a/node_modules/@vue/devtools-api/lib/esm/api/api.js b/node_modules/@vue/devtools-api/lib/esm/api/api.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/api/api.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/@vue/devtools-api/lib/esm/api/app.d.ts b/node_modules/@vue/devtools-api/lib/esm/api/app.d.ts new file mode 100644 index 0000000..a10f02f --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/api/app.d.ts @@ -0,0 +1 @@ +export type App = any; diff --git a/node_modules/@vue/devtools-api/lib/esm/api/app.js b/node_modules/@vue/devtools-api/lib/esm/api/app.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/api/app.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/@vue/devtools-api/lib/esm/api/component.d.ts b/node_modules/@vue/devtools-api/lib/esm/api/component.d.ts new file mode 100644 index 0000000..84fcba7 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/api/component.d.ts @@ -0,0 +1,78 @@ +import type { InspectorNodeTag } from './api.js'; +import type { ID } from './util.js'; +export type ComponentInstance = any; +export interface ComponentTreeNode { + uid: ID; + id: string; + name: string; + renderKey: string | number; + inactive: boolean; + isFragment: boolean; + hasChildren: boolean; + children: ComponentTreeNode[]; + domOrder?: number[]; + consoleId?: string; + isRouterView?: boolean; + macthedRouteSegment?: string; + tags: InspectorNodeTag[]; + autoOpen: boolean; + meta?: any; +} +export interface InspectedComponentData { + id: string; + name: string; + file: string; + state: ComponentState[]; + functional?: boolean; +} +export interface StateBase { + key: string; + value: any; + editable?: boolean; + objectType?: 'ref' | 'reactive' | 'computed' | 'other'; + raw?: string; +} +export interface ComponentStateBase extends StateBase { + type: string; +} +export interface ComponentPropState extends ComponentStateBase { + meta?: { + type: string; + required: boolean; + /** Vue 1 only */ + mode?: 'default' | 'sync' | 'once'; + }; +} +export type ComponentBuiltinCustomStateTypes = 'function' | 'map' | 'set' | 'reference' | 'component' | 'component-definition' | 'router' | 'store'; +export interface ComponentCustomState extends ComponentStateBase { + value: CustomState; +} +export interface CustomState { + _custom: { + type: ComponentBuiltinCustomStateTypes | string; + objectType?: string; + display?: string; + tooltip?: string; + value?: any; + abstract?: boolean; + file?: string; + uid?: number; + readOnly?: boolean; + /** Configure immediate child fields */ + fields?: { + abstract?: boolean; + }; + id?: any; + actions?: { + icon: string; + tooltip?: string; + action: () => void | Promise; + }[]; + /** internal */ + _reviveId?: number; + }; +} +export type ComponentState = ComponentStateBase | ComponentPropState | ComponentCustomState; +export interface ComponentDevtoolsOptions { + hide?: boolean; +} diff --git a/node_modules/@vue/devtools-api/lib/esm/api/component.js b/node_modules/@vue/devtools-api/lib/esm/api/component.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/api/component.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/@vue/devtools-api/lib/esm/api/context.d.ts b/node_modules/@vue/devtools-api/lib/esm/api/context.d.ts new file mode 100644 index 0000000..29388f1 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/api/context.d.ts @@ -0,0 +1,5 @@ +import type { AppRecord } from './api.js'; +export interface Context { + currentTab: string; + currentAppRecord: AppRecord; +} diff --git a/node_modules/@vue/devtools-api/lib/esm/api/context.js b/node_modules/@vue/devtools-api/lib/esm/api/context.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/api/context.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/@vue/devtools-api/lib/esm/api/hooks.d.ts b/node_modules/@vue/devtools-api/lib/esm/api/hooks.d.ts new file mode 100644 index 0000000..4e5d7cc --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/api/hooks.d.ts @@ -0,0 +1,180 @@ +import type { ComponentDevtoolsOptions, ComponentInstance, ComponentTreeNode, InspectedComponentData } from './component.js'; +import type { App } from './app.js'; +import type { CustomInspectorNode, CustomInspectorState, TimelineEvent } from './api.js'; +export declare const enum Hooks { + TRANSFORM_CALL = "transformCall", + GET_APP_RECORD_NAME = "getAppRecordName", + GET_APP_ROOT_INSTANCE = "getAppRootInstance", + REGISTER_APPLICATION = "registerApplication", + WALK_COMPONENT_TREE = "walkComponentTree", + VISIT_COMPONENT_TREE = "visitComponentTree", + WALK_COMPONENT_PARENTS = "walkComponentParents", + INSPECT_COMPONENT = "inspectComponent", + GET_COMPONENT_BOUNDS = "getComponentBounds", + GET_COMPONENT_NAME = "getComponentName", + GET_COMPONENT_INSTANCES = "getComponentInstances", + GET_ELEMENT_COMPONENT = "getElementComponent", + GET_COMPONENT_ROOT_ELEMENTS = "getComponentRootElements", + EDIT_COMPONENT_STATE = "editComponentState", + GET_COMPONENT_DEVTOOLS_OPTIONS = "getAppDevtoolsOptions", + GET_COMPONENT_RENDER_CODE = "getComponentRenderCode", + INSPECT_TIMELINE_EVENT = "inspectTimelineEvent", + TIMELINE_CLEARED = "timelineCleared", + GET_INSPECTOR_TREE = "getInspectorTree", + GET_INSPECTOR_STATE = "getInspectorState", + EDIT_INSPECTOR_STATE = "editInspectorState", + SET_PLUGIN_SETTINGS = "setPluginSettings" +} +export interface ComponentBounds { + left: number; + top: number; + width: number; + height: number; +} +export interface HookPayloads { + [Hooks.TRANSFORM_CALL]: { + callName: string; + inArgs: any[]; + outArgs: any[]; + }; + [Hooks.GET_APP_RECORD_NAME]: { + app: App; + name: string; + }; + [Hooks.GET_APP_ROOT_INSTANCE]: { + app: App; + root: ComponentInstance; + }; + [Hooks.REGISTER_APPLICATION]: { + app: App; + }; + [Hooks.WALK_COMPONENT_TREE]: { + componentInstance: ComponentInstance; + componentTreeData: ComponentTreeNode[]; + maxDepth: number; + filter: string; + recursively: boolean; + }; + [Hooks.VISIT_COMPONENT_TREE]: { + app: App; + componentInstance: ComponentInstance; + treeNode: ComponentTreeNode; + filter: string; + }; + [Hooks.WALK_COMPONENT_PARENTS]: { + componentInstance: ComponentInstance; + parentInstances: ComponentInstance[]; + }; + [Hooks.INSPECT_COMPONENT]: { + app: App; + componentInstance: ComponentInstance; + instanceData: InspectedComponentData; + }; + [Hooks.GET_COMPONENT_BOUNDS]: { + componentInstance: ComponentInstance; + bounds: ComponentBounds; + }; + [Hooks.GET_COMPONENT_NAME]: { + componentInstance: ComponentInstance; + name: string; + }; + [Hooks.GET_COMPONENT_INSTANCES]: { + app: App; + componentInstances: ComponentInstance[]; + }; + [Hooks.GET_ELEMENT_COMPONENT]: { + element: HTMLElement | any; + componentInstance: ComponentInstance; + }; + [Hooks.GET_COMPONENT_ROOT_ELEMENTS]: { + componentInstance: ComponentInstance; + rootElements: (HTMLElement | any)[]; + }; + [Hooks.EDIT_COMPONENT_STATE]: { + app: App; + componentInstance: ComponentInstance; + path: string[]; + type: string; + state: EditStatePayload; + set: (object: any, path?: string | (string[]), value?: any, cb?: (object: any, field: string, value: any) => void) => void; + }; + [Hooks.GET_COMPONENT_DEVTOOLS_OPTIONS]: { + componentInstance: ComponentInstance; + options: ComponentDevtoolsOptions; + }; + [Hooks.GET_COMPONENT_RENDER_CODE]: { + componentInstance: ComponentInstance; + code: string; + }; + [Hooks.INSPECT_TIMELINE_EVENT]: { + app: App; + layerId: string; + event: TimelineEvent; + all?: boolean; + data: any; + }; + [Hooks.TIMELINE_CLEARED]: Record; + [Hooks.GET_INSPECTOR_TREE]: { + app: App; + inspectorId: string; + filter: string; + rootNodes: CustomInspectorNode[]; + }; + [Hooks.GET_INSPECTOR_STATE]: { + app: App; + inspectorId: string; + nodeId: string; + state: CustomInspectorState; + }; + [Hooks.EDIT_INSPECTOR_STATE]: { + app: App; + inspectorId: string; + nodeId: string; + path: string[]; + type: string; + state: EditStatePayload; + set: (object: any, path?: string | (string[]), value?: any, cb?: (object: any, field: string, value: any) => void) => void; + }; + [Hooks.SET_PLUGIN_SETTINGS]: { + app: App; + pluginId: string; + key: string; + newValue: any; + oldValue: any; + settings: any; + }; +} +export type EditStatePayload = { + value: any; + newKey?: string | null; + remove?: undefined | false; +} | { + value?: undefined; + newKey?: undefined; + remove: true; +}; +export type HookHandler = (payload: TPayload, ctx: TContext) => void | Promise; +export interface Hookable { + transformCall: (handler: HookHandler) => any; + getAppRecordName: (handler: HookHandler) => any; + getAppRootInstance: (handler: HookHandler) => any; + registerApplication: (handler: HookHandler) => any; + walkComponentTree: (handler: HookHandler) => any; + visitComponentTree: (handler: HookHandler) => any; + walkComponentParents: (handler: HookHandler) => any; + inspectComponent: (handler: HookHandler) => any; + getComponentBounds: (handler: HookHandler) => any; + getComponentName: (handler: HookHandler) => any; + getComponentInstances: (handler: HookHandler) => any; + getElementComponent: (handler: HookHandler) => any; + getComponentRootElements: (handler: HookHandler) => any; + editComponentState: (handler: HookHandler) => any; + getComponentDevtoolsOptions: (handler: HookHandler) => any; + getComponentRenderCode: (handler: HookHandler) => any; + inspectTimelineEvent: (handler: HookHandler) => any; + timelineCleared: (handler: HookHandler) => any; + getInspectorTree: (handler: HookHandler) => any; + getInspectorState: (handler: HookHandler) => any; + editInspectorState: (handler: HookHandler) => any; + setPluginSettings: (handler: HookHandler) => any; +} diff --git a/node_modules/@vue/devtools-api/lib/esm/api/hooks.js b/node_modules/@vue/devtools-api/lib/esm/api/hooks.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/api/hooks.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/@vue/devtools-api/lib/esm/api/index.d.ts b/node_modules/@vue/devtools-api/lib/esm/api/index.d.ts new file mode 100644 index 0000000..70d09d2 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/api/index.d.ts @@ -0,0 +1,6 @@ +export * from './api.js'; +export * from './app.js'; +export * from './component.js'; +export * from './context.js'; +export * from './hooks.js'; +export * from './util.js'; diff --git a/node_modules/@vue/devtools-api/lib/esm/api/index.js b/node_modules/@vue/devtools-api/lib/esm/api/index.js new file mode 100644 index 0000000..70d09d2 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/api/index.js @@ -0,0 +1,6 @@ +export * from './api.js'; +export * from './app.js'; +export * from './component.js'; +export * from './context.js'; +export * from './hooks.js'; +export * from './util.js'; diff --git a/node_modules/@vue/devtools-api/lib/esm/api/util.d.ts b/node_modules/@vue/devtools-api/lib/esm/api/util.d.ts new file mode 100644 index 0000000..f8ca920 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/api/util.d.ts @@ -0,0 +1,4 @@ +export type ID = number | string; +export interface WithId { + id: ID; +} diff --git a/node_modules/@vue/devtools-api/lib/esm/api/util.js b/node_modules/@vue/devtools-api/lib/esm/api/util.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/api/util.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/@vue/devtools-api/lib/esm/const.d.ts b/node_modules/@vue/devtools-api/lib/esm/const.d.ts new file mode 100644 index 0000000..289b254 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/const.d.ts @@ -0,0 +1,2 @@ +export declare const HOOK_SETUP = "devtools-plugin:setup"; +export declare const HOOK_PLUGIN_SETTINGS_SET = "plugin:settings:set"; diff --git a/node_modules/@vue/devtools-api/lib/esm/const.js b/node_modules/@vue/devtools-api/lib/esm/const.js new file mode 100644 index 0000000..872ea3e --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/const.js @@ -0,0 +1,2 @@ +export const HOOK_SETUP = 'devtools-plugin:setup'; +export const HOOK_PLUGIN_SETTINGS_SET = 'plugin:settings:set'; diff --git a/node_modules/@vue/devtools-api/lib/esm/env.d.ts b/node_modules/@vue/devtools-api/lib/esm/env.d.ts new file mode 100644 index 0000000..045d95f --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/env.d.ts @@ -0,0 +1,15 @@ +import type { ApiProxy } from './proxy.js'; +import type { PluginDescriptor, SetupFunction } from './index.js'; +export interface PluginQueueItem { + pluginDescriptor: PluginDescriptor; + setupFn: SetupFunction; + proxy?: ApiProxy; +} +interface GlobalTarget { + __VUE_DEVTOOLS_PLUGINS__?: PluginQueueItem[]; + __VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__?: boolean; +} +export declare function getDevtoolsGlobalHook(): any; +export declare function getTarget(): GlobalTarget; +export declare const isProxyAvailable: boolean; +export {}; diff --git a/node_modules/@vue/devtools-api/lib/esm/env.js b/node_modules/@vue/devtools-api/lib/esm/env.js new file mode 100644 index 0000000..a7a74b1 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/env.js @@ -0,0 +1,12 @@ +export function getDevtoolsGlobalHook() { + return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__; +} +export function getTarget() { + // @ts-expect-error navigator and windows are not available in all environments + return (typeof navigator !== 'undefined' && typeof window !== 'undefined') + ? window + : typeof globalThis !== 'undefined' + ? globalThis + : {}; +} +export const isProxyAvailable = typeof Proxy === 'function'; diff --git a/node_modules/@vue/devtools-api/lib/esm/index.d.ts b/node_modules/@vue/devtools-api/lib/esm/index.d.ts new file mode 100644 index 0000000..162518b --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/index.d.ts @@ -0,0 +1,18 @@ +import type { DevtoolsPluginApi } from './api/index.js'; +import type { ExtractSettingsTypes, PluginDescriptor, PluginSettingsItem } from './plugin.js'; +export * from './api/index.js'; +export * from './plugin.js'; +export * from './time.js'; +export { PluginQueueItem } from './env.js'; +type Cast = A extends B ? A : B; +type Narrowable = string | number | bigint | boolean; +type Narrow = Cast; +})>; +type Exact = { + [K in keyof C]: K extends keyof T ? T[K] : never; +}; +export type SetupFunction = (api: DevtoolsPluginApi) => void; +export declare function setupDevtoolsPlugin, TSettings = ExtractSettingsTypes ? S : Record : Record>>(pluginDescriptor: Narrow, setupFn: SetupFunction): void; diff --git a/node_modules/@vue/devtools-api/lib/esm/index.js b/node_modules/@vue/devtools-api/lib/esm/index.js new file mode 100644 index 0000000..c7a50ec --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/index.js @@ -0,0 +1,27 @@ +import { getDevtoolsGlobalHook, getTarget, isProxyAvailable } from './env.js'; +import { HOOK_SETUP } from './const.js'; +import { ApiProxy } from './proxy.js'; +export * from './api/index.js'; +export * from './plugin.js'; +export * from './time.js'; +export function setupDevtoolsPlugin(pluginDescriptor, setupFn) { + const descriptor = pluginDescriptor; + const target = getTarget(); + const hook = getDevtoolsGlobalHook(); + const enableProxy = isProxyAvailable && descriptor.enableEarlyProxy; + if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) { + hook.emit(HOOK_SETUP, pluginDescriptor, setupFn); + } + else { + const proxy = enableProxy ? new ApiProxy(descriptor, hook) : null; + const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || []; + list.push({ + pluginDescriptor: descriptor, + setupFn, + proxy, + }); + if (proxy) { + setupFn(proxy.proxiedTarget); + } + } +} diff --git a/node_modules/@vue/devtools-api/lib/esm/plugin.d.ts b/node_modules/@vue/devtools-api/lib/esm/plugin.d.ts new file mode 100644 index 0000000..52322ca --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/plugin.d.ts @@ -0,0 +1,47 @@ +import type { App } from './api/index.js'; +export interface PluginDescriptor { + id: string; + label: string; + app: App; + packageName?: string; + homepage?: string; + componentStateTypes?: string[]; + logo?: string; + disableAppScope?: boolean; + disablePluginScope?: boolean; + /** + * Run the plugin setup and expose the api even if the devtools is not opened yet. + * Useful to record timeline events early. + */ + enableEarlyProxy?: boolean; + settings?: Record; +} +export type PluginSettingsItem = { + label: string; + description?: string; +} & ({ + type: 'boolean'; + defaultValue: boolean; +} | { + type: 'choice'; + defaultValue: string | number; + options: { + value: string | number; + label: string; + }[]; + component?: 'select' | 'button-group'; +} | { + type: 'text'; + defaultValue: string; +}); +type InferSettingsType = [T] extends [{ + type: 'boolean'; +}] ? boolean : [T] extends [{ + type: 'choice'; +}] ? T['options'][number]['value'] : [T] extends [{ + type: 'text'; +}] ? string : unknown; +export type ExtractSettingsTypes> = { + [K in keyof O]: InferSettingsType; +}; +export {}; diff --git a/node_modules/@vue/devtools-api/lib/esm/plugin.js b/node_modules/@vue/devtools-api/lib/esm/plugin.js new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/plugin.js @@ -0,0 +1 @@ +export {}; diff --git a/node_modules/@vue/devtools-api/lib/esm/proxy.d.ts b/node_modules/@vue/devtools-api/lib/esm/proxy.d.ts new file mode 100644 index 0000000..38ff867 --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/proxy.d.ts @@ -0,0 +1,20 @@ +import type { Context, DevtoolsPluginApi, Hookable } from './api/index.js'; +import type { PluginDescriptor } from './plugin.js'; +interface QueueItem { + method: string; + args: any[]; + resolve?: (value?: any) => void; +} +export declare class ApiProxy = DevtoolsPluginApi> { + target: TTarget | null; + targetQueue: QueueItem[]; + proxiedTarget: TTarget; + onQueue: QueueItem[]; + proxiedOn: Hookable; + plugin: PluginDescriptor; + hook: any; + fallbacks: Record; + constructor(plugin: PluginDescriptor, hook: any); + setRealTarget(target: TTarget): Promise; +} +export {}; diff --git a/node_modules/@vue/devtools-api/lib/esm/proxy.js b/node_modules/@vue/devtools-api/lib/esm/proxy.js new file mode 100644 index 0000000..3cce0ff --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/proxy.js @@ -0,0 +1,107 @@ +import { HOOK_PLUGIN_SETTINGS_SET } from './const.js'; +import { now } from './time.js'; +export class ApiProxy { + constructor(plugin, hook) { + this.target = null; + this.targetQueue = []; + this.onQueue = []; + this.plugin = plugin; + this.hook = hook; + const defaultSettings = {}; + if (plugin.settings) { + for (const id in plugin.settings) { + const item = plugin.settings[id]; + defaultSettings[id] = item.defaultValue; + } + } + const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`; + let currentSettings = Object.assign({}, defaultSettings); + try { + const raw = localStorage.getItem(localSettingsSaveId); + const data = JSON.parse(raw); + Object.assign(currentSettings, data); + } + catch (e) { + // noop + } + this.fallbacks = { + getSettings() { + return currentSettings; + }, + setSettings(value) { + try { + localStorage.setItem(localSettingsSaveId, JSON.stringify(value)); + } + catch (e) { + // noop + } + currentSettings = value; + }, + now() { + return now(); + }, + }; + if (hook) { + hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => { + if (pluginId === this.plugin.id) { + this.fallbacks.setSettings(value); + } + }); + } + this.proxiedOn = new Proxy({}, { + get: (_target, prop) => { + if (this.target) { + return this.target.on[prop]; + } + else { + return (...args) => { + this.onQueue.push({ + method: prop, + args, + }); + }; + } + }, + }); + this.proxiedTarget = new Proxy({}, { + get: (_target, prop) => { + if (this.target) { + return this.target[prop]; + } + else if (prop === 'on') { + return this.proxiedOn; + } + else if (Object.keys(this.fallbacks).includes(prop)) { + return (...args) => { + this.targetQueue.push({ + method: prop, + args, + resolve: () => { }, + }); + return this.fallbacks[prop](...args); + }; + } + else { + return (...args) => { + return new Promise((resolve) => { + this.targetQueue.push({ + method: prop, + args, + resolve, + }); + }); + }; + } + }, + }); + } + async setRealTarget(target) { + this.target = target; + for (const item of this.onQueue) { + this.target.on[item.method](...item.args); + } + for (const item of this.targetQueue) { + item.resolve(await this.target[item.method](...item.args)); + } + } +} diff --git a/node_modules/@vue/devtools-api/lib/esm/time.d.ts b/node_modules/@vue/devtools-api/lib/esm/time.d.ts new file mode 100644 index 0000000..1aebade --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/time.d.ts @@ -0,0 +1,2 @@ +export declare function isPerformanceSupported(): boolean; +export declare function now(): number; diff --git a/node_modules/@vue/devtools-api/lib/esm/time.js b/node_modules/@vue/devtools-api/lib/esm/time.js new file mode 100644 index 0000000..fd15ffe --- /dev/null +++ b/node_modules/@vue/devtools-api/lib/esm/time.js @@ -0,0 +1,23 @@ +let supported; +let perf; +export function isPerformanceSupported() { + var _a; + if (supported !== undefined) { + return supported; + } + if (typeof window !== 'undefined' && window.performance) { + supported = true; + perf = window.performance; + } + else if (typeof globalThis !== 'undefined' && ((_a = globalThis.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) { + supported = true; + perf = globalThis.perf_hooks.performance; + } + else { + supported = false; + } + return supported; +} +export function now() { + return isPerformanceSupported() ? perf.now() : Date.now(); +} diff --git a/node_modules/@vue/devtools-api/package.json b/node_modules/@vue/devtools-api/package.json new file mode 100644 index 0000000..979b575 --- /dev/null +++ b/node_modules/@vue/devtools-api/package.json @@ -0,0 +1,67 @@ +{ + "_from": "@vue/devtools-api@^6.6.3", + "_id": "@vue/devtools-api@6.6.4", + "_inBundle": false, + "_integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "_location": "/@vue/devtools-api", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "@vue/devtools-api@^6.6.3", + "name": "@vue/devtools-api", + "escapedName": "@vue%2fdevtools-api", + "scope": "@vue", + "rawSpec": "^6.6.3", + "saveSpec": null, + "fetchSpec": "^6.6.3" + }, + "_requiredBy": [ + "/pinia" + ], + "_resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "_shasum": "cbe97fe0162b365edc1dba80e173f90492535343", + "_spec": "@vue/devtools-api@^6.6.3", + "_where": "D:\\FeiYi\\node_modules\\pinia", + "author": { + "name": "Guillaume Chau" + }, + "browser": "lib/esm/index.js", + "bugs": { + "url": "https://github.com/vuejs/vue-devtools/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Interact with the Vue devtools from the page", + "devDependencies": { + "@types/node": "^20.11.16", + "@types/webpack-env": "^1.15.1", + "typescript": "^5.3.3" + }, + "files": [ + "lib/cjs", + "lib/esm" + ], + "homepage": "https://github.com/vuejs/vue-devtools#readme", + "license": "MIT", + "main": "lib/cjs/index.js", + "module": "lib/esm/index.js", + "name": "@vue/devtools-api", + "publishConfig": { + "access": "public" + }, + "repository": { + "url": "git+https://github.com/vuejs/vue-devtools.git", + "type": "git", + "directory": "packages/api" + }, + "scripts": { + "build": "rimraf lib && yarn build:esm && yarn build:cjs", + "build:cjs": "tsc --module commonjs --outDir lib/cjs", + "build:esm": "tsc --module es2015 --outDir lib/esm -d", + "build:watch": "yarn tsc --module es2015 --outDir lib/esm -d -w --sourceMap" + }, + "sideEffects": false, + "types": "lib/esm/index.d.ts", + "version": "6.6.4" +} diff --git a/node_modules/mitt/LICENSE b/node_modules/mitt/LICENSE new file mode 100644 index 0000000..84c52fe --- /dev/null +++ b/node_modules/mitt/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Jason Miller + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/mitt/README.md b/node_modules/mitt/README.md new file mode 100644 index 0000000..0219f3a --- /dev/null +++ b/node_modules/mitt/README.md @@ -0,0 +1,205 @@ +

+ mitt +
+
npm + build status + gzip size +

+ +# Mitt + +> Tiny 200b functional event emitter / pubsub. + +- **Microscopic:** weighs less than 200 bytes gzipped +- **Useful:** a wildcard `"*"` event type listens to all events +- **Familiar:** same names & ideas as [Node's EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter) +- **Functional:** methods don't rely on `this` +- **Great Name:** somehow [mitt](https://npm.im/mitt) wasn't taken + +Mitt was made for the browser, but works in any JavaScript runtime. It has no dependencies and supports IE9+. + +## Table of Contents + +- [Install](#install) +- [Usage](#usage) +- [Examples & Demos](#examples--demos) +- [API](#api) +- [Contribute](#contribute) +- [License](#license) + +## Install + +This project uses [node](http://nodejs.org) and [npm](https://npmjs.com). Go check them out if you don't have them locally installed. + +```sh +$ npm install --save mitt +``` + +Then with a module bundler like [rollup](http://rollupjs.org/) or [webpack](https://webpack.js.org/), use as you would anything else: + +```javascript +// using ES6 modules +import mitt from 'mitt' + +// using CommonJS modules +var mitt = require('mitt') +``` + +The [UMD](https://github.com/umdjs/umd) build is also available on [unpkg](https://unpkg.com): + +```html + +``` + +You can find the library on `window.mitt`. + +## Usage + +```js +import mitt from 'mitt' + +const emitter = mitt() + +// listen to an event +emitter.on('foo', e => console.log('foo', e) ) + +// listen to all events +emitter.on('*', (type, e) => console.log(type, e) ) + +// fire an event +emitter.emit('foo', { a: 'b' }) + +// clearing all events +emitter.all.clear() + +// working with handler references: +function onFoo() {} +emitter.on('foo', onFoo) // listen +emitter.off('foo', onFoo) // unlisten +``` + +### Typescript + +Set `"strict": true` in your tsconfig.json to get improved type inference for `mitt` instance methods. + +```ts +import mitt from 'mitt'; + +type Events = { + foo: string; + bar?: number; +}; + +const emitter = mitt(); // inferred as Emitter + +emitter.on('foo', (e) => {}); // 'e' has inferred type 'string' + +emitter.emit('foo', 42); // Error: Argument of type 'number' is not assignable to parameter of type 'string'. (2345) +``` + +Alternatively, you can use the provided `Emitter` type: + +```ts +import mitt, { Emitter } from 'mitt'; + +type Events = { + foo: string; + bar?: number; +}; + +const emitter: Emitter = mitt(); +``` + +## Examples & Demos + + + Preact + Mitt Codepen Demo +
+ preact + mitt preview +
+ +* * * + +## API + + + +#### Table of Contents + +- [mitt](#mitt) +- [all](#all) +- [on](#on) + - [Parameters](#parameters) +- [off](#off) + - [Parameters](#parameters-1) +- [emit](#emit) + - [Parameters](#parameters-2) + +### mitt + +Mitt: Tiny (~200b) functional event emitter / pubsub. + +Returns **Mitt** + +### all + +A Map of event names to registered handler functions. + +### on + +Register an event handler for the given type. + +#### Parameters + +- `type` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [symbol](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Symbol))** Type of event to listen for, or `'*'` for all events +- `handler` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)** Function to call in response to given event + +### off + +Remove an event handler for the given type. +If `handler` is omitted, all handlers of the given type are removed. + +#### Parameters + +- `type` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [symbol](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Symbol))** Type of event to unregister `handler` from, or `'*'` +- `handler` **[Function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?** Handler function to remove + +### emit + +Invoke all handlers for the given type. +If present, `'*'` handlers are invoked after type-matched handlers. + +Note: Manually firing '\*' handlers is not supported. + +#### Parameters + +- `type` **([string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) \| [symbol](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Symbol))** The event type to invoke +- `evt` **Any?** Any value (object is recommended and powerful), passed to each handler + +## Contribute + +First off, thanks for taking the time to contribute! +Now, take a moment to be sure your contributions make sense to everyone else. + +### Reporting Issues + +Found a problem? Want a new feature? First of all see if your issue or idea has [already been reported](../../issues). +If don't, just open a [new clear and descriptive issue](../../issues/new). + +### Submitting pull requests + +Pull requests are the greatest contributions, so be sure they are focused in scope, and do avoid unrelated commits. + +- Fork it! +- Clone your fork: `git clone https://github.com//mitt` +- Navigate to the newly cloned directory: `cd mitt` +- Create a new branch for the new feature: `git checkout -b my-new-feature` +- Install the tools necessary for development: `npm install` +- Make your changes. +- Commit your changes: `git commit -am 'Add some feature'` +- Push to the branch: `git push origin my-new-feature` +- Submit a pull request with full remarks documenting your changes. + +## License + +[MIT License](https://opensource.org/licenses/MIT) © [Jason Miller](https://jasonformat.com/) diff --git a/node_modules/mitt/dist/mitt.js b/node_modules/mitt/dist/mitt.js new file mode 100644 index 0000000..b30a31a --- /dev/null +++ b/node_modules/mitt/dist/mitt.js @@ -0,0 +1,2 @@ +module.exports=function(n){return{all:n=n||new Map,on:function(e,t){var i=n.get(e);i?i.push(t):n.set(e,[t])},off:function(e,t){var i=n.get(e);i&&(t?i.splice(i.indexOf(t)>>>0,1):n.set(e,[]))},emit:function(e,t){var i=n.get(e);i&&i.slice().map(function(n){n(t)}),(i=n.get("*"))&&i.slice().map(function(n){n(e,t)})}}}; +//# sourceMappingURL=mitt.js.map diff --git a/node_modules/mitt/dist/mitt.js.map b/node_modules/mitt/dist/mitt.js.map new file mode 100644 index 0000000..d726004 --- /dev/null +++ b/node_modules/mitt/dist/mitt.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mitt.js","sources":["../src/index.ts"],"sourcesContent":["export type EventType = string | symbol;\n\n// An event handler can take an optional event argument\n// and should not return a value\nexport type Handler = (event: T) => void;\nexport type WildcardHandler> = (\n\ttype: keyof T,\n\tevent: T[keyof T]\n) => void;\n\n// An array of all currently registered event handlers for a type\nexport type EventHandlerList = Array>;\nexport type WildCardEventHandlerList> = Array<\n\tWildcardHandler\n>;\n\n// A map of event types and their corresponding event handlers.\nexport type EventHandlerMap> = Map<\n\tkeyof Events | '*',\n\tEventHandlerList | WildCardEventHandlerList\n>;\n\nexport interface Emitter> {\n\tall: EventHandlerMap;\n\n\ton(type: Key, handler: Handler): void;\n\ton(type: '*', handler: WildcardHandler): void;\n\n\toff(\n\t\ttype: Key,\n\t\thandler?: Handler\n\t): void;\n\toff(type: '*', handler: WildcardHandler): void;\n\n\temit(type: Key, event: Events[Key]): void;\n\temit(\n\t\ttype: undefined extends Events[Key] ? Key : never\n\t): void;\n}\n\n/**\n * Mitt: Tiny (~200b) functional event emitter / pubsub.\n * @name mitt\n * @returns {Mitt}\n */\nexport default function mitt>(\n\tall?: EventHandlerMap\n): Emitter {\n\ttype GenericEventHandler =\n\t\t| Handler\n\t\t| WildcardHandler;\n\tall = all || new Map();\n\n\treturn {\n\t\t/**\n\t\t * A Map of event names to registered handler functions.\n\t\t */\n\t\tall,\n\n\t\t/**\n\t\t * Register an event handler for the given type.\n\t\t * @param {string|symbol} type Type of event to listen for, or `'*'` for all events\n\t\t * @param {Function} handler Function to call in response to given event\n\t\t * @memberOf mitt\n\t\t */\n\t\ton(type: Key, handler: GenericEventHandler) {\n\t\t\tconst handlers: Array | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\thandlers.push(handler);\n\t\t\t} else {\n\t\t\t\tall!.set(type, [handler] as EventHandlerList);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Remove an event handler for the given type.\n\t\t * If `handler` is omitted, all handlers of the given type are removed.\n\t\t * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler)\n\t\t * @param {Function} [handler] Handler function to remove\n\t\t * @memberOf mitt\n\t\t */\n\t\toff(type: Key, handler?: GenericEventHandler) {\n\t\t\tconst handlers: Array | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\tif (handler) {\n\t\t\t\t\thandlers.splice(handlers.indexOf(handler) >>> 0, 1);\n\t\t\t\t} else {\n\t\t\t\t\tall!.set(type, []);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Invoke all handlers for the given type.\n\t\t * If present, `'*'` handlers are invoked after type-matched handlers.\n\t\t *\n\t\t * Note: Manually firing '*' handlers is not supported.\n\t\t *\n\t\t * @param {string|symbol} type The event type to invoke\n\t\t * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler\n\t\t * @memberOf mitt\n\t\t */\n\t\temit(type: Key, evt?: Events[Key]) {\n\t\t\tlet handlers = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as EventHandlerList)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(evt!);\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\thandlers = all!.get('*');\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as WildCardEventHandlerList)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(type, evt!);\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n}\n"],"names":["all","Map","on","type","handler","handlers","get","push","set","off","splice","indexOf","emit","evt","slice","map"],"mappings":"wBA8CCA,GAOA,MAAO,CAINA,IANDA,EAAMA,GAAO,IAAIC,IAchBC,YAA6BC,EAAWC,GACvC,IAAMC,EAAmDL,EAAKM,IAAIH,GAC9DE,EACHA,EAASE,KAAKH,GAEdJ,EAAKQ,IAAIL,EAAM,CAACC,KAWlBK,aAA8BN,EAAWC,GACxC,IAAMC,EAAmDL,EAAKM,IAAIH,GAC9DE,IACCD,EACHC,EAASK,OAAOL,EAASM,QAAQP,KAAa,EAAG,GAEjDJ,EAAKQ,IAAIL,EAAM,MAelBS,cAA+BT,EAAWU,GACzC,IAAIR,EAAWL,EAAKM,IAAIH,GACpBE,GACFA,EACCS,QACAC,IAAI,SAACX,GACLA,EAAQS,MAIXR,EAAWL,EAAKM,IAAI,OAElBD,EACCS,QACAC,IAAI,SAACX,GACLA,EAAQD,EAAMU"} \ No newline at end of file diff --git a/node_modules/mitt/dist/mitt.mjs b/node_modules/mitt/dist/mitt.mjs new file mode 100644 index 0000000..5a2e73a --- /dev/null +++ b/node_modules/mitt/dist/mitt.mjs @@ -0,0 +1,2 @@ +export default function(n){return{all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e])},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]))},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e)}),(i=n.get("*"))&&i.slice().map(function(n){n(t,e)})}}} +//# sourceMappingURL=mitt.mjs.map diff --git a/node_modules/mitt/dist/mitt.mjs.map b/node_modules/mitt/dist/mitt.mjs.map new file mode 100644 index 0000000..c4204e8 --- /dev/null +++ b/node_modules/mitt/dist/mitt.mjs.map @@ -0,0 +1 @@ +{"version":3,"file":"mitt.mjs","sources":["../src/index.ts"],"sourcesContent":["export type EventType = string | symbol;\n\n// An event handler can take an optional event argument\n// and should not return a value\nexport type Handler = (event: T) => void;\nexport type WildcardHandler> = (\n\ttype: keyof T,\n\tevent: T[keyof T]\n) => void;\n\n// An array of all currently registered event handlers for a type\nexport type EventHandlerList = Array>;\nexport type WildCardEventHandlerList> = Array<\n\tWildcardHandler\n>;\n\n// A map of event types and their corresponding event handlers.\nexport type EventHandlerMap> = Map<\n\tkeyof Events | '*',\n\tEventHandlerList | WildCardEventHandlerList\n>;\n\nexport interface Emitter> {\n\tall: EventHandlerMap;\n\n\ton(type: Key, handler: Handler): void;\n\ton(type: '*', handler: WildcardHandler): void;\n\n\toff(\n\t\ttype: Key,\n\t\thandler?: Handler\n\t): void;\n\toff(type: '*', handler: WildcardHandler): void;\n\n\temit(type: Key, event: Events[Key]): void;\n\temit(\n\t\ttype: undefined extends Events[Key] ? Key : never\n\t): void;\n}\n\n/**\n * Mitt: Tiny (~200b) functional event emitter / pubsub.\n * @name mitt\n * @returns {Mitt}\n */\nexport default function mitt>(\n\tall?: EventHandlerMap\n): Emitter {\n\ttype GenericEventHandler =\n\t\t| Handler\n\t\t| WildcardHandler;\n\tall = all || new Map();\n\n\treturn {\n\t\t/**\n\t\t * A Map of event names to registered handler functions.\n\t\t */\n\t\tall,\n\n\t\t/**\n\t\t * Register an event handler for the given type.\n\t\t * @param {string|symbol} type Type of event to listen for, or `'*'` for all events\n\t\t * @param {Function} handler Function to call in response to given event\n\t\t * @memberOf mitt\n\t\t */\n\t\ton(type: Key, handler: GenericEventHandler) {\n\t\t\tconst handlers: Array | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\thandlers.push(handler);\n\t\t\t} else {\n\t\t\t\tall!.set(type, [handler] as EventHandlerList);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Remove an event handler for the given type.\n\t\t * If `handler` is omitted, all handlers of the given type are removed.\n\t\t * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler)\n\t\t * @param {Function} [handler] Handler function to remove\n\t\t * @memberOf mitt\n\t\t */\n\t\toff(type: Key, handler?: GenericEventHandler) {\n\t\t\tconst handlers: Array | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\tif (handler) {\n\t\t\t\t\thandlers.splice(handlers.indexOf(handler) >>> 0, 1);\n\t\t\t\t} else {\n\t\t\t\t\tall!.set(type, []);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Invoke all handlers for the given type.\n\t\t * If present, `'*'` handlers are invoked after type-matched handlers.\n\t\t *\n\t\t * Note: Manually firing '*' handlers is not supported.\n\t\t *\n\t\t * @param {string|symbol} type The event type to invoke\n\t\t * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler\n\t\t * @memberOf mitt\n\t\t */\n\t\temit(type: Key, evt?: Events[Key]) {\n\t\t\tlet handlers = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as EventHandlerList)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(evt!);\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\thandlers = all!.get('*');\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as WildCardEventHandlerList)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(type, evt!);\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n}\n"],"names":["all","Map","on","type","handler","handlers","get","push","set","off","splice","indexOf","emit","evt","slice","map"],"mappings":"wBA8CCA,GAOA,MAAO,CAINA,IANDA,EAAMA,GAAO,IAAIC,IAchBC,YAA6BC,EAAWC,GACvC,IAAMC,EAAmDL,EAAKM,IAAIH,GAC9DE,EACHA,EAASE,KAAKH,GAEdJ,EAAKQ,IAAIL,EAAM,CAACC,KAWlBK,aAA8BN,EAAWC,GACxC,IAAMC,EAAmDL,EAAKM,IAAIH,GAC9DE,IACCD,EACHC,EAASK,OAAOL,EAASM,QAAQP,KAAa,EAAG,GAEjDJ,EAAKQ,IAAIL,EAAM,MAelBS,cAA+BT,EAAWU,GACzC,IAAIR,EAAWL,EAAKM,IAAIH,GACpBE,GACFA,EACCS,QACAC,IAAI,SAACX,GACLA,EAAQS,MAIXR,EAAWL,EAAKM,IAAI,OAElBD,EACCS,QACAC,IAAI,SAACX,GACLA,EAAQD,EAAMU"} \ No newline at end of file diff --git a/node_modules/mitt/dist/mitt.umd.js b/node_modules/mitt/dist/mitt.umd.js new file mode 100644 index 0000000..6820e65 --- /dev/null +++ b/node_modules/mitt/dist/mitt.umd.js @@ -0,0 +1,2 @@ +!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):(e=e||self).mitt=n()}(this,function(){return function(e){return{all:e=e||new Map,on:function(n,t){var f=e.get(n);f?f.push(t):e.set(n,[t])},off:function(n,t){var f=e.get(n);f&&(t?f.splice(f.indexOf(t)>>>0,1):e.set(n,[]))},emit:function(n,t){var f=e.get(n);f&&f.slice().map(function(e){e(t)}),(f=e.get("*"))&&f.slice().map(function(e){e(n,t)})}}}}); +//# sourceMappingURL=mitt.umd.js.map diff --git a/node_modules/mitt/dist/mitt.umd.js.map b/node_modules/mitt/dist/mitt.umd.js.map new file mode 100644 index 0000000..ebb8e62 --- /dev/null +++ b/node_modules/mitt/dist/mitt.umd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mitt.umd.js","sources":["../src/index.ts"],"sourcesContent":["export type EventType = string | symbol;\n\n// An event handler can take an optional event argument\n// and should not return a value\nexport type Handler = (event: T) => void;\nexport type WildcardHandler> = (\n\ttype: keyof T,\n\tevent: T[keyof T]\n) => void;\n\n// An array of all currently registered event handlers for a type\nexport type EventHandlerList = Array>;\nexport type WildCardEventHandlerList> = Array<\n\tWildcardHandler\n>;\n\n// A map of event types and their corresponding event handlers.\nexport type EventHandlerMap> = Map<\n\tkeyof Events | '*',\n\tEventHandlerList | WildCardEventHandlerList\n>;\n\nexport interface Emitter> {\n\tall: EventHandlerMap;\n\n\ton(type: Key, handler: Handler): void;\n\ton(type: '*', handler: WildcardHandler): void;\n\n\toff(\n\t\ttype: Key,\n\t\thandler?: Handler\n\t): void;\n\toff(type: '*', handler: WildcardHandler): void;\n\n\temit(type: Key, event: Events[Key]): void;\n\temit(\n\t\ttype: undefined extends Events[Key] ? Key : never\n\t): void;\n}\n\n/**\n * Mitt: Tiny (~200b) functional event emitter / pubsub.\n * @name mitt\n * @returns {Mitt}\n */\nexport default function mitt>(\n\tall?: EventHandlerMap\n): Emitter {\n\ttype GenericEventHandler =\n\t\t| Handler\n\t\t| WildcardHandler;\n\tall = all || new Map();\n\n\treturn {\n\t\t/**\n\t\t * A Map of event names to registered handler functions.\n\t\t */\n\t\tall,\n\n\t\t/**\n\t\t * Register an event handler for the given type.\n\t\t * @param {string|symbol} type Type of event to listen for, or `'*'` for all events\n\t\t * @param {Function} handler Function to call in response to given event\n\t\t * @memberOf mitt\n\t\t */\n\t\ton(type: Key, handler: GenericEventHandler) {\n\t\t\tconst handlers: Array | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\thandlers.push(handler);\n\t\t\t} else {\n\t\t\t\tall!.set(type, [handler] as EventHandlerList);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Remove an event handler for the given type.\n\t\t * If `handler` is omitted, all handlers of the given type are removed.\n\t\t * @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler)\n\t\t * @param {Function} [handler] Handler function to remove\n\t\t * @memberOf mitt\n\t\t */\n\t\toff(type: Key, handler?: GenericEventHandler) {\n\t\t\tconst handlers: Array | undefined = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\tif (handler) {\n\t\t\t\t\thandlers.splice(handlers.indexOf(handler) >>> 0, 1);\n\t\t\t\t} else {\n\t\t\t\t\tall!.set(type, []);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Invoke all handlers for the given type.\n\t\t * If present, `'*'` handlers are invoked after type-matched handlers.\n\t\t *\n\t\t * Note: Manually firing '*' handlers is not supported.\n\t\t *\n\t\t * @param {string|symbol} type The event type to invoke\n\t\t * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler\n\t\t * @memberOf mitt\n\t\t */\n\t\temit(type: Key, evt?: Events[Key]) {\n\t\t\tlet handlers = all!.get(type);\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as EventHandlerList)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(evt!);\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\thandlers = all!.get('*');\n\t\t\tif (handlers) {\n\t\t\t\t(handlers as WildCardEventHandlerList)\n\t\t\t\t\t.slice()\n\t\t\t\t\t.map((handler) => {\n\t\t\t\t\t\thandler(type, evt!);\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t};\n}\n"],"names":["all","Map","on","type","handler","handlers","get","push","set","off","splice","indexOf","emit","evt","slice","map"],"mappings":"6LA8CCA,GAOA,MAAO,CAINA,IANDA,EAAMA,GAAO,IAAIC,IAchBC,YAA6BC,EAAWC,GACvC,IAAMC,EAAmDL,EAAKM,IAAIH,GAC9DE,EACHA,EAASE,KAAKH,GAEdJ,EAAKQ,IAAIL,EAAM,CAACC,KAWlBK,aAA8BN,EAAWC,GACxC,IAAMC,EAAmDL,EAAKM,IAAIH,GAC9DE,IACCD,EACHC,EAASK,OAAOL,EAASM,QAAQP,KAAa,EAAG,GAEjDJ,EAAKQ,IAAIL,EAAM,MAelBS,cAA+BT,EAAWU,GACzC,IAAIR,EAAWL,EAAKM,IAAIH,GACpBE,GACFA,EACCS,QACAC,IAAI,SAACX,GACLA,EAAQS,MAIXR,EAAWL,EAAKM,IAAI,OAElBD,EACCS,QACAC,IAAI,SAACX,GACLA,EAAQD,EAAMU"} \ No newline at end of file diff --git a/node_modules/mitt/index.d.ts b/node_modules/mitt/index.d.ts new file mode 100644 index 0000000..37b63e2 --- /dev/null +++ b/node_modules/mitt/index.d.ts @@ -0,0 +1,21 @@ +export declare type EventType = string | symbol; +export declare type Handler = (event: T) => void; +export declare type WildcardHandler> = (type: keyof T, event: T[keyof T]) => void; +export declare type EventHandlerList = Array>; +export declare type WildCardEventHandlerList> = Array>; +export declare type EventHandlerMap> = Map | WildCardEventHandlerList>; +export interface Emitter> { + all: EventHandlerMap; + on(type: Key, handler: Handler): void; + on(type: '*', handler: WildcardHandler): void; + off(type: Key, handler?: Handler): void; + off(type: '*', handler: WildcardHandler): void; + emit(type: Key, event: Events[Key]): void; + emit(type: undefined extends Events[Key] ? Key : never): void; +} +/** + * Mitt: Tiny (~200b) functional event emitter / pubsub. + * @name mitt + * @returns {Mitt} + */ +export default function mitt>(all?: EventHandlerMap): Emitter; diff --git a/node_modules/mitt/package.json b/node_modules/mitt/package.json new file mode 100644 index 0000000..6688567 --- /dev/null +++ b/node_modules/mitt/package.json @@ -0,0 +1,117 @@ +{ + "_from": "mitt", + "_id": "mitt@3.0.1", + "_inBundle": false, + "_integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "_location": "/mitt", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "mitt", + "name": "mitt", + "escapedName": "mitt", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz", + "_shasum": "ea36cf0cc30403601ae074c8f77b7092cdab36d1", + "_spec": "mitt", + "_where": "D:\\FeiYi", + "authors": [ + "Jason Miller " + ], + "bugs": { + "url": "https://github.com/developit/mitt/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Tiny 200b functional Event Emitter / pubsub.", + "devDependencies": { + "@types/chai": "^4.2.11", + "@types/mocha": "^7.0.2", + "@types/sinon": "^9.0.4", + "@types/sinon-chai": "^3.2.4", + "@typescript-eslint/eslint-plugin": "^5.61.0", + "@typescript-eslint/parser": "^5.61.0", + "chai": "^4.2.0", + "documentation": "^14.0.2", + "eslint": "^7.32.0", + "eslint-config-developit": "^1.2.0", + "eslint-plugin-compat": "^4.1.4", + "esm": "^3.2.25", + "microbundle": "^0.12.3", + "mocha": "^8.0.1", + "npm-run-all": "^4.1.5", + "prettier": "^2.8.8", + "rimraf": "^3.0.2", + "sinon": "^9.0.2", + "sinon-chai": "^3.5.0", + "ts-node": "^10.9.1", + "typescript": "^4.9.5" + }, + "exports": { + "types": "./index.d.ts", + "module": "./dist/mitt.mjs", + "import": "./dist/mitt.mjs", + "require": "./dist/mitt.js", + "default": "./dist/mitt.mjs" + }, + "files": [ + "dist", + "index.d.ts" + ], + "homepage": "https://github.com/developit/mitt", + "jsnext:main": "dist/mitt.mjs", + "keywords": [ + "events", + "eventemitter", + "emitter", + "pubsub" + ], + "license": "MIT", + "main": "dist/mitt.js", + "mocha": { + "extension": [ + "ts" + ], + "require": [ + "ts-node/register", + "esm" + ], + "spec": [ + "test/*_test.ts" + ] + }, + "module": "dist/mitt.mjs", + "name": "mitt", + "prettier": { + "singleQuote": true, + "trailingComma": "none" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/developit/mitt.git" + }, + "scripts": { + "build": "npm-run-all --silent clean -p bundle -s docs", + "bundle": "microbundle -f es,cjs,umd", + "clean": "rimraf dist", + "docs": "documentation readme src/index.ts --section API -q --parse-extension ts", + "lint": "eslint src test --ext ts --ext js", + "mocha": "mocha test", + "release": "npm run -s build -s && npm t && git commit -am $npm_package_version && git tag $npm_package_version && git push && git push --tags && npm publish", + "test": "npm-run-all --silent typecheck lint mocha test-types", + "test-types": "tsc test/test-types-compilation.ts --noEmit --strict", + "typecheck": "tsc --noEmit" + }, + "source": "src/index.ts", + "typings": "index.d.ts", + "umd:main": "dist/mitt.umd.js", + "version": "3.0.1" +} diff --git a/node_modules/pinia/LICENSE b/node_modules/pinia/LICENSE new file mode 100644 index 0000000..0c77562 --- /dev/null +++ b/node_modules/pinia/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2019-present Eduardo San Martin Morote + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/pinia/README.md b/node_modules/pinia/README.md new file mode 100644 index 0000000..d73d322 --- /dev/null +++ b/node_modules/pinia/README.md @@ -0,0 +1,24 @@ +

+ + Pinia logo + +

+ +# Pinia + +> Intuitive, type safe and flexible Store for Vue + +## 👉 [Demo with Vue 3 on StackBlitz](https://stackblitz.com/github/piniajs/example-vue-3-vite) + +## Help me keep working on this project 💚 + +- [Become a Sponsor on GitHub](https://github.com/sponsors/posva) +- [One-time donation via PayPal](https://paypal.me/posva) + +## Documentation + +To learn more about Pinia, check [its documentation](https://pinia.vuejs.org). + +## License + +[MIT](http://opensource.org/licenses/MIT) diff --git a/node_modules/pinia/dist/pinia.cjs b/node_modules/pinia/dist/pinia.cjs new file mode 100644 index 0000000..ef29d38 --- /dev/null +++ b/node_modules/pinia/dist/pinia.cjs @@ -0,0 +1,2060 @@ +/*! + * pinia v2.2.5 + * (c) 2024 Eduardo San Martin Morote + * @license MIT + */ +'use strict'; + +var vueDemi = require('vue-demi'); +var devtoolsApi = require('@vue/devtools-api'); + +/** + * setActivePinia must be called to handle SSR at the top of functions like + * `fetch`, `setup`, `serverPrefetch` and others + */ +let activePinia; +/** + * Sets or unsets the active pinia. Used in SSR and internally when calling + * actions and getters + * + * @param pinia - Pinia instance + */ +// @ts-expect-error: cannot constrain the type of the return +const setActivePinia = (pinia) => (activePinia = pinia); +/** + * Get the currently active pinia if there is any. + */ +const getActivePinia = () => (vueDemi.hasInjectionContext() && vueDemi.inject(piniaSymbol)) || activePinia; +const piniaSymbol = ((process.env.NODE_ENV !== 'production') ? Symbol('pinia') : /* istanbul ignore next */ Symbol()); + +function isPlainObject( +// eslint-disable-next-line @typescript-eslint/no-explicit-any +o) { + return (o && + typeof o === 'object' && + Object.prototype.toString.call(o) === '[object Object]' && + typeof o.toJSON !== 'function'); +} +// type DeepReadonly = { readonly [P in keyof T]: DeepReadonly } +// TODO: can we change these to numbers? +/** + * Possible types for SubscriptionCallback + */ +exports.MutationType = void 0; +(function (MutationType) { + /** + * Direct mutation of the state: + * + * - `store.name = 'new name'` + * - `store.$state.name = 'new name'` + * - `store.list.push('new item')` + */ + MutationType["direct"] = "direct"; + /** + * Mutated the state with `$patch` and an object + * + * - `store.$patch({ name: 'newName' })` + */ + MutationType["patchObject"] = "patch object"; + /** + * Mutated the state with `$patch` and a function + * + * - `store.$patch(state => state.name = 'newName')` + */ + MutationType["patchFunction"] = "patch function"; + // maybe reset? for $state = {} and $reset +})(exports.MutationType || (exports.MutationType = {})); + +const IS_CLIENT = typeof window !== 'undefined'; + +/* + * FileSaver.js A saveAs() FileSaver implementation. + * + * Originally by Eli Grey, adapted as an ESM module by Eduardo San Martin + * Morote. + * + * License : MIT + */ +// The one and only way of getting global scope in all environments +// https://stackoverflow.com/q/3277182/1008999 +const _global = /*#__PURE__*/ (() => typeof window === 'object' && window.window === window + ? window + : typeof self === 'object' && self.self === self + ? self + : typeof global === 'object' && global.global === global + ? global + : typeof globalThis === 'object' + ? globalThis + : { HTMLElement: null })(); +function bom(blob, { autoBom = false } = {}) { + // prepend BOM for UTF-8 XML and text/* types (including HTML) + // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF + if (autoBom && + /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { + return new Blob([String.fromCharCode(0xfeff), blob], { type: blob.type }); + } + return blob; +} +function download(url, name, opts) { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'blob'; + xhr.onload = function () { + saveAs(xhr.response, name, opts); + }; + xhr.onerror = function () { + console.error('could not download file'); + }; + xhr.send(); +} +function corsEnabled(url) { + const xhr = new XMLHttpRequest(); + // use sync to avoid popup blocker + xhr.open('HEAD', url, false); + try { + xhr.send(); + } + catch (e) { } + return xhr.status >= 200 && xhr.status <= 299; +} +// `a.click()` doesn't work for all browsers (#465) +function click(node) { + try { + node.dispatchEvent(new MouseEvent('click')); + } + catch (e) { + const evt = document.createEvent('MouseEvents'); + evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null); + node.dispatchEvent(evt); + } +} +const _navigator = typeof navigator === 'object' ? navigator : { userAgent: '' }; +// Detect WebView inside a native macOS app by ruling out all browsers +// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too +// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos +const isMacOSWebView = /*#__PURE__*/ (() => /Macintosh/.test(_navigator.userAgent) && + /AppleWebKit/.test(_navigator.userAgent) && + !/Safari/.test(_navigator.userAgent))(); +const saveAs = !IS_CLIENT + ? () => { } // noop + : // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView or mini program + typeof HTMLAnchorElement !== 'undefined' && + 'download' in HTMLAnchorElement.prototype && + !isMacOSWebView + ? downloadSaveAs + : // Use msSaveOrOpenBlob as a second approach + 'msSaveOrOpenBlob' in _navigator + ? msSaveAs + : // Fallback to using FileReader and a popup + fileSaverSaveAs; +function downloadSaveAs(blob, name = 'download', opts) { + const a = document.createElement('a'); + a.download = name; + a.rel = 'noopener'; // tabnabbing + // TODO: detect chrome extensions & packaged apps + // a.target = '_blank' + if (typeof blob === 'string') { + // Support regular links + a.href = blob; + if (a.origin !== location.origin) { + if (corsEnabled(a.href)) { + download(blob, name, opts); + } + else { + a.target = '_blank'; + click(a); + } + } + else { + click(a); + } + } + else { + // Support blobs + a.href = URL.createObjectURL(blob); + setTimeout(function () { + URL.revokeObjectURL(a.href); + }, 4e4); // 40s + setTimeout(function () { + click(a); + }, 0); + } +} +function msSaveAs(blob, name = 'download', opts) { + if (typeof blob === 'string') { + if (corsEnabled(blob)) { + download(blob, name, opts); + } + else { + const a = document.createElement('a'); + a.href = blob; + a.target = '_blank'; + setTimeout(function () { + click(a); + }); + } + } + else { + // @ts-ignore: works on windows + navigator.msSaveOrOpenBlob(bom(blob, opts), name); + } +} +function fileSaverSaveAs(blob, name, opts, popup) { + // Open a popup immediately do go around popup blocker + // Mostly only available on user interaction and the fileReader is async so... + popup = popup || open('', '_blank'); + if (popup) { + popup.document.title = popup.document.body.innerText = 'downloading...'; + } + if (typeof blob === 'string') + return download(blob, name, opts); + const force = blob.type === 'application/octet-stream'; + const isSafari = /constructor/i.test(String(_global.HTMLElement)) || 'safari' in _global; + const isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent); + if ((isChromeIOS || (force && isSafari) || isMacOSWebView) && + typeof FileReader !== 'undefined') { + // Safari doesn't allow downloading of blob URLs + const reader = new FileReader(); + reader.onloadend = function () { + let url = reader.result; + if (typeof url !== 'string') { + popup = null; + throw new Error('Wrong reader.result type'); + } + url = isChromeIOS + ? url + : url.replace(/^data:[^;]*;/, 'data:attachment/file;'); + if (popup) { + popup.location.href = url; + } + else { + location.assign(url); + } + popup = null; // reverse-tabnabbing #460 + }; + reader.readAsDataURL(blob); + } + else { + const url = URL.createObjectURL(blob); + if (popup) + popup.location.assign(url); + else + location.href = url; + popup = null; // reverse-tabnabbing #460 + setTimeout(function () { + URL.revokeObjectURL(url); + }, 4e4); // 40s + } +} + +/** + * Shows a toast or console.log + * + * @param message - message to log + * @param type - different color of the tooltip + */ +function toastMessage(message, type) { + const piniaMessage = '🍍 ' + message; + if (typeof __VUE_DEVTOOLS_TOAST__ === 'function') { + // No longer available :( + __VUE_DEVTOOLS_TOAST__(piniaMessage, type); + } + else if (type === 'error') { + console.error(piniaMessage); + } + else if (type === 'warn') { + console.warn(piniaMessage); + } + else { + console.log(piniaMessage); + } +} +function isPinia(o) { + return '_a' in o && 'install' in o; +} + +/** + * This file contain devtools actions, they are not Pinia actions. + */ +// --- +function checkClipboardAccess() { + if (!('clipboard' in navigator)) { + toastMessage(`Your browser doesn't support the Clipboard API`, 'error'); + return true; + } +} +function checkNotFocusedError(error) { + if (error instanceof Error && + error.message.toLowerCase().includes('document is not focused')) { + toastMessage('You need to activate the "Emulate a focused page" setting in the "Rendering" panel of devtools.', 'warn'); + return true; + } + return false; +} +async function actionGlobalCopyState(pinia) { + if (checkClipboardAccess()) + return; + try { + await navigator.clipboard.writeText(JSON.stringify(pinia.state.value)); + toastMessage('Global state copied to clipboard.'); + } + catch (error) { + if (checkNotFocusedError(error)) + return; + toastMessage(`Failed to serialize the state. Check the console for more details.`, 'error'); + console.error(error); + } +} +async function actionGlobalPasteState(pinia) { + if (checkClipboardAccess()) + return; + try { + loadStoresState(pinia, JSON.parse(await navigator.clipboard.readText())); + toastMessage('Global state pasted from clipboard.'); + } + catch (error) { + if (checkNotFocusedError(error)) + return; + toastMessage(`Failed to deserialize the state from clipboard. Check the console for more details.`, 'error'); + console.error(error); + } +} +async function actionGlobalSaveState(pinia) { + try { + saveAs(new Blob([JSON.stringify(pinia.state.value)], { + type: 'text/plain;charset=utf-8', + }), 'pinia-state.json'); + } + catch (error) { + toastMessage(`Failed to export the state as JSON. Check the console for more details.`, 'error'); + console.error(error); + } +} +let fileInput; +function getFileOpener() { + if (!fileInput) { + fileInput = document.createElement('input'); + fileInput.type = 'file'; + fileInput.accept = '.json'; + } + function openFile() { + return new Promise((resolve, reject) => { + fileInput.onchange = async () => { + const files = fileInput.files; + if (!files) + return resolve(null); + const file = files.item(0); + if (!file) + return resolve(null); + return resolve({ text: await file.text(), file }); + }; + // @ts-ignore: TODO: changed from 4.3 to 4.4 + fileInput.oncancel = () => resolve(null); + fileInput.onerror = reject; + fileInput.click(); + }); + } + return openFile; +} +async function actionGlobalOpenStateFile(pinia) { + try { + const open = getFileOpener(); + const result = await open(); + if (!result) + return; + const { text, file } = result; + loadStoresState(pinia, JSON.parse(text)); + toastMessage(`Global state imported from "${file.name}".`); + } + catch (error) { + toastMessage(`Failed to import the state from JSON. Check the console for more details.`, 'error'); + console.error(error); + } +} +function loadStoresState(pinia, state) { + for (const key in state) { + const storeState = pinia.state.value[key]; + // store is already instantiated, patch it + if (storeState) { + Object.assign(storeState, state[key]); + } + else { + // store is not instantiated, set the initial state + pinia.state.value[key] = state[key]; + } + } +} + +function formatDisplay(display) { + return { + _custom: { + display, + }, + }; +} +const PINIA_ROOT_LABEL = '🍍 Pinia (root)'; +const PINIA_ROOT_ID = '_root'; +function formatStoreForInspectorTree(store) { + return isPinia(store) + ? { + id: PINIA_ROOT_ID, + label: PINIA_ROOT_LABEL, + } + : { + id: store.$id, + label: store.$id, + }; +} +function formatStoreForInspectorState(store) { + if (isPinia(store)) { + const storeNames = Array.from(store._s.keys()); + const storeMap = store._s; + const state = { + state: storeNames.map((storeId) => ({ + editable: true, + key: storeId, + value: store.state.value[storeId], + })), + getters: storeNames + .filter((id) => storeMap.get(id)._getters) + .map((id) => { + const store = storeMap.get(id); + return { + editable: false, + key: id, + value: store._getters.reduce((getters, key) => { + getters[key] = store[key]; + return getters; + }, {}), + }; + }), + }; + return state; + } + const state = { + state: Object.keys(store.$state).map((key) => ({ + editable: true, + key, + value: store.$state[key], + })), + }; + // avoid adding empty getters + if (store._getters && store._getters.length) { + state.getters = store._getters.map((getterName) => ({ + editable: false, + key: getterName, + value: store[getterName], + })); + } + if (store._customProperties.size) { + state.customProperties = Array.from(store._customProperties).map((key) => ({ + editable: true, + key, + value: store[key], + })); + } + return state; +} +function formatEventData(events) { + if (!events) + return {}; + if (Array.isArray(events)) { + // TODO: handle add and delete for arrays and objects + return events.reduce((data, event) => { + data.keys.push(event.key); + data.operations.push(event.type); + data.oldValue[event.key] = event.oldValue; + data.newValue[event.key] = event.newValue; + return data; + }, { + oldValue: {}, + keys: [], + operations: [], + newValue: {}, + }); + } + else { + return { + operation: formatDisplay(events.type), + key: formatDisplay(events.key), + oldValue: events.oldValue, + newValue: events.newValue, + }; + } +} +function formatMutationType(type) { + switch (type) { + case exports.MutationType.direct: + return 'mutation'; + case exports.MutationType.patchFunction: + return '$patch'; + case exports.MutationType.patchObject: + return '$patch'; + default: + return 'unknown'; + } +} + +// timeline can be paused when directly changing the state +let isTimelineActive = true; +const componentStateTypes = []; +const MUTATIONS_LAYER_ID = 'pinia:mutations'; +const INSPECTOR_ID = 'pinia'; +const { assign: assign$1 } = Object; +/** + * Gets the displayed name of a store in devtools + * + * @param id - id of the store + * @returns a formatted string + */ +const getStoreType = (id) => '🍍 ' + id; +/** + * Add the pinia plugin without any store. Allows displaying a Pinia plugin tab + * as soon as it is added to the application. + * + * @param app - Vue application + * @param pinia - pinia instance + */ +function registerPiniaDevtools(app, pinia) { + devtoolsApi.setupDevtoolsPlugin({ + id: 'dev.esm.pinia', + label: 'Pinia 🍍', + logo: 'https://pinia.vuejs.org/logo.svg', + packageName: 'pinia', + homepage: 'https://pinia.vuejs.org', + componentStateTypes, + app, + }, (api) => { + if (typeof api.now !== 'function') { + toastMessage('You seem to be using an outdated version of Vue Devtools. Are you still using the Beta release instead of the stable one? You can find the links at https://devtools.vuejs.org/guide/installation.html.'); + } + api.addTimelineLayer({ + id: MUTATIONS_LAYER_ID, + label: `Pinia 🍍`, + color: 0xe5df88, + }); + api.addInspector({ + id: INSPECTOR_ID, + label: 'Pinia 🍍', + icon: 'storage', + treeFilterPlaceholder: 'Search stores', + actions: [ + { + icon: 'content_copy', + action: () => { + actionGlobalCopyState(pinia); + }, + tooltip: 'Serialize and copy the state', + }, + { + icon: 'content_paste', + action: async () => { + await actionGlobalPasteState(pinia); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + }, + tooltip: 'Replace the state with the content of your clipboard', + }, + { + icon: 'save', + action: () => { + actionGlobalSaveState(pinia); + }, + tooltip: 'Save the state as a JSON file', + }, + { + icon: 'folder_open', + action: async () => { + await actionGlobalOpenStateFile(pinia); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + }, + tooltip: 'Import the state from a JSON file', + }, + ], + nodeActions: [ + { + icon: 'restore', + tooltip: 'Reset the state (with "$reset")', + action: (nodeId) => { + const store = pinia._s.get(nodeId); + if (!store) { + toastMessage(`Cannot reset "${nodeId}" store because it wasn't found.`, 'warn'); + } + else if (typeof store.$reset !== 'function') { + toastMessage(`Cannot reset "${nodeId}" store because it doesn't have a "$reset" method implemented.`, 'warn'); + } + else { + store.$reset(); + toastMessage(`Store "${nodeId}" reset.`); + } + }, + }, + ], + }); + api.on.inspectComponent((payload, ctx) => { + const proxy = (payload.componentInstance && + payload.componentInstance.proxy); + if (proxy && proxy._pStores) { + const piniaStores = payload.componentInstance.proxy._pStores; + Object.values(piniaStores).forEach((store) => { + payload.instanceData.state.push({ + type: getStoreType(store.$id), + key: 'state', + editable: true, + value: store._isOptionsAPI + ? { + _custom: { + value: vueDemi.toRaw(store.$state), + actions: [ + { + icon: 'restore', + tooltip: 'Reset the state of this store', + action: () => store.$reset(), + }, + ], + }, + } + : // NOTE: workaround to unwrap transferred refs + Object.keys(store.$state).reduce((state, key) => { + state[key] = store.$state[key]; + return state; + }, {}), + }); + if (store._getters && store._getters.length) { + payload.instanceData.state.push({ + type: getStoreType(store.$id), + key: 'getters', + editable: false, + value: store._getters.reduce((getters, key) => { + try { + getters[key] = store[key]; + } + catch (error) { + // @ts-expect-error: we just want to show it in devtools + getters[key] = error; + } + return getters; + }, {}), + }); + } + }); + } + }); + api.on.getInspectorTree((payload) => { + if (payload.app === app && payload.inspectorId === INSPECTOR_ID) { + let stores = [pinia]; + stores = stores.concat(Array.from(pinia._s.values())); + payload.rootNodes = (payload.filter + ? stores.filter((store) => '$id' in store + ? store.$id + .toLowerCase() + .includes(payload.filter.toLowerCase()) + : PINIA_ROOT_LABEL.toLowerCase().includes(payload.filter.toLowerCase())) + : stores).map(formatStoreForInspectorTree); + } + }); + // Expose pinia instance as $pinia to window + globalThis.$pinia = pinia; + api.on.getInspectorState((payload) => { + if (payload.app === app && payload.inspectorId === INSPECTOR_ID) { + const inspectedStore = payload.nodeId === PINIA_ROOT_ID + ? pinia + : pinia._s.get(payload.nodeId); + if (!inspectedStore) { + // this could be the selected store restored for a different project + // so it's better not to say anything here + return; + } + if (inspectedStore) { + // Expose selected store as $store to window + if (payload.nodeId !== PINIA_ROOT_ID) + globalThis.$store = vueDemi.toRaw(inspectedStore); + payload.state = formatStoreForInspectorState(inspectedStore); + } + } + }); + api.on.editInspectorState((payload, ctx) => { + if (payload.app === app && payload.inspectorId === INSPECTOR_ID) { + const inspectedStore = payload.nodeId === PINIA_ROOT_ID + ? pinia + : pinia._s.get(payload.nodeId); + if (!inspectedStore) { + return toastMessage(`store "${payload.nodeId}" not found`, 'error'); + } + const { path } = payload; + if (!isPinia(inspectedStore)) { + // access only the state + if (path.length !== 1 || + !inspectedStore._customProperties.has(path[0]) || + path[0] in inspectedStore.$state) { + path.unshift('$state'); + } + } + else { + // Root access, we can omit the `.value` because the devtools API does it for us + path.unshift('state'); + } + isTimelineActive = false; + payload.set(inspectedStore, path, payload.state.value); + isTimelineActive = true; + } + }); + api.on.editComponentState((payload) => { + if (payload.type.startsWith('🍍')) { + const storeId = payload.type.replace(/^🍍\s*/, ''); + const store = pinia._s.get(storeId); + if (!store) { + return toastMessage(`store "${storeId}" not found`, 'error'); + } + const { path } = payload; + if (path[0] !== 'state') { + return toastMessage(`Invalid path for store "${storeId}":\n${path}\nOnly state can be modified.`); + } + // rewrite the first entry to be able to directly set the state as + // well as any other path + path[0] = '$state'; + isTimelineActive = false; + payload.set(store, path, payload.state.value); + isTimelineActive = true; + } + }); + }); +} +function addStoreToDevtools(app, store) { + if (!componentStateTypes.includes(getStoreType(store.$id))) { + componentStateTypes.push(getStoreType(store.$id)); + } + devtoolsApi.setupDevtoolsPlugin({ + id: 'dev.esm.pinia', + label: 'Pinia 🍍', + logo: 'https://pinia.vuejs.org/logo.svg', + packageName: 'pinia', + homepage: 'https://pinia.vuejs.org', + componentStateTypes, + app, + settings: { + logStoreChanges: { + label: 'Notify about new/deleted stores', + type: 'boolean', + defaultValue: true, + }, + // useEmojis: { + // label: 'Use emojis in messages ⚡️', + // type: 'boolean', + // defaultValue: true, + // }, + }, + }, (api) => { + // gracefully handle errors + const now = typeof api.now === 'function' ? api.now.bind(api) : Date.now; + store.$onAction(({ after, onError, name, args }) => { + const groupId = runningActionId++; + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: '🛫 ' + name, + subtitle: 'start', + data: { + store: formatDisplay(store.$id), + action: formatDisplay(name), + args, + }, + groupId, + }, + }); + after((result) => { + activeAction = undefined; + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: '🛬 ' + name, + subtitle: 'end', + data: { + store: formatDisplay(store.$id), + action: formatDisplay(name), + args, + result, + }, + groupId, + }, + }); + }); + onError((error) => { + activeAction = undefined; + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + logType: 'error', + title: '💥 ' + name, + subtitle: 'end', + data: { + store: formatDisplay(store.$id), + action: formatDisplay(name), + args, + error, + }, + groupId, + }, + }); + }); + }, true); + store._customProperties.forEach((name) => { + vueDemi.watch(() => vueDemi.unref(store[name]), (newValue, oldValue) => { + api.notifyComponentUpdate(); + api.sendInspectorState(INSPECTOR_ID); + if (isTimelineActive) { + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: 'Change', + subtitle: name, + data: { + newValue, + oldValue, + }, + groupId: activeAction, + }, + }); + } + }, { deep: true }); + }); + store.$subscribe(({ events, type }, state) => { + api.notifyComponentUpdate(); + api.sendInspectorState(INSPECTOR_ID); + if (!isTimelineActive) + return; + // rootStore.state[store.id] = state + const eventData = { + time: now(), + title: formatMutationType(type), + data: assign$1({ store: formatDisplay(store.$id) }, formatEventData(events)), + groupId: activeAction, + }; + if (type === exports.MutationType.patchFunction) { + eventData.subtitle = '⤵️'; + } + else if (type === exports.MutationType.patchObject) { + eventData.subtitle = '🧩'; + } + else if (events && !Array.isArray(events)) { + eventData.subtitle = events.type; + } + if (events) { + eventData.data['rawEvent(s)'] = { + _custom: { + display: 'DebuggerEvent', + type: 'object', + tooltip: 'raw DebuggerEvent[]', + value: events, + }, + }; + } + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: eventData, + }); + }, { detached: true, flush: 'sync' }); + const hotUpdate = store._hotUpdate; + store._hotUpdate = vueDemi.markRaw((newStore) => { + hotUpdate(newStore); + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: '🔥 ' + store.$id, + subtitle: 'HMR update', + data: { + store: formatDisplay(store.$id), + info: formatDisplay(`HMR update`), + }, + }, + }); + // update the devtools too + api.notifyComponentUpdate(); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + }); + const { $dispose } = store; + store.$dispose = () => { + $dispose(); + api.notifyComponentUpdate(); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + api.getSettings().logStoreChanges && + toastMessage(`Disposed "${store.$id}" store 🗑`); + }; + // trigger an update so it can display new registered stores + api.notifyComponentUpdate(); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + api.getSettings().logStoreChanges && + toastMessage(`"${store.$id}" store installed 🆕`); + }); +} +let runningActionId = 0; +let activeAction; +/** + * Patches a store to enable action grouping in devtools by wrapping the store with a Proxy that is passed as the + * context of all actions, allowing us to set `runningAction` on each access and effectively associating any state + * mutation to the action. + * + * @param store - store to patch + * @param actionNames - list of actionst to patch + */ +function patchActionForGrouping(store, actionNames, wrapWithProxy) { + // original actions of the store as they are given by pinia. We are going to override them + const actions = actionNames.reduce((storeActions, actionName) => { + // use toRaw to avoid tracking #541 + storeActions[actionName] = vueDemi.toRaw(store)[actionName]; + return storeActions; + }, {}); + for (const actionName in actions) { + store[actionName] = function () { + // the running action id is incremented in a before action hook + const _actionId = runningActionId; + const trackedStore = wrapWithProxy + ? new Proxy(store, { + get(...args) { + activeAction = _actionId; + return Reflect.get(...args); + }, + set(...args) { + activeAction = _actionId; + return Reflect.set(...args); + }, + }) + : store; + // For Setup Stores we need https://github.com/tc39/proposal-async-context + activeAction = _actionId; + const retValue = actions[actionName].apply(trackedStore, arguments); + // this is safer as async actions in Setup Stores would associate mutations done outside of the action + activeAction = undefined; + return retValue; + }; + } +} +/** + * pinia.use(devtoolsPlugin) + */ +function devtoolsPlugin({ app, store, options }) { + // HMR module + if (store.$id.startsWith('__hot:')) { + return; + } + // detect option api vs setup api + store._isOptionsAPI = !!options.state; + // Do not overwrite actions mocked by @pinia/testing (#2298) + if (!store._p._testing) { + patchActionForGrouping(store, Object.keys(options.actions), store._isOptionsAPI); + // Upgrade the HMR to also update the new actions + const originalHotUpdate = store._hotUpdate; + vueDemi.toRaw(store)._hotUpdate = function (newStore) { + originalHotUpdate.apply(this, arguments); + patchActionForGrouping(store, Object.keys(newStore._hmrPayload.actions), !!store._isOptionsAPI); + }; + } + addStoreToDevtools(app, + // FIXME: is there a way to allow the assignment from Store to StoreGeneric? + store); +} + +/** + * Creates a Pinia instance to be used by the application + */ +function createPinia() { + const scope = vueDemi.effectScope(true); + // NOTE: here we could check the window object for a state and directly set it + // if there is anything like it with Vue 3 SSR + const state = scope.run(() => vueDemi.ref({})); + let _p = []; + // plugins added before calling app.use(pinia) + let toBeInstalled = []; + const pinia = vueDemi.markRaw({ + install(app) { + // this allows calling useStore() outside of a component setup after + // installing pinia's plugin + setActivePinia(pinia); + if (!vueDemi.isVue2) { + pinia._a = app; + app.provide(piniaSymbol, pinia); + app.config.globalProperties.$pinia = pinia; + /* istanbul ignore else */ + if ((((process.env.NODE_ENV !== 'production') || false) && !(process.env.NODE_ENV === 'test')) && IS_CLIENT) { + registerPiniaDevtools(app, pinia); + } + toBeInstalled.forEach((plugin) => _p.push(plugin)); + toBeInstalled = []; + } + }, + use(plugin) { + if (!this._a && !vueDemi.isVue2) { + toBeInstalled.push(plugin); + } + else { + _p.push(plugin); + } + return this; + }, + _p, + // it's actually undefined here + // @ts-expect-error + _a: null, + _e: scope, + _s: new Map(), + state, + }); + // pinia devtools rely on dev only features so they cannot be forced unless + // the dev build of Vue is used. Avoid old browsers like IE11. + if ((((process.env.NODE_ENV !== 'production') || false) && !(process.env.NODE_ENV === 'test')) && typeof Proxy !== 'undefined') { + pinia.use(devtoolsPlugin); + } + return pinia; +} +/** + * Dispose a Pinia instance by stopping its effectScope and removing the state, plugins and stores. This is mostly + * useful in tests, with both a testing pinia or a regular pinia and in applications that use multiple pinia instances. + * Once disposed, the pinia instance cannot be used anymore. + * + * @param pinia - pinia instance + */ +function disposePinia(pinia) { + pinia._e.stop(); + pinia._s.clear(); + pinia._p.splice(0); + pinia.state.value = {}; + // @ts-expect-error: non valid + pinia._a = null; +} + +/** + * Checks if a function is a `StoreDefinition`. + * + * @param fn - object to test + * @returns true if `fn` is a StoreDefinition + */ +const isUseStore = (fn) => { + return typeof fn === 'function' && typeof fn.$id === 'string'; +}; +/** + * Mutates in place `newState` with `oldState` to _hot update_ it. It will + * remove any key not existing in `newState` and recursively merge plain + * objects. + * + * @param newState - new state object to be patched + * @param oldState - old state that should be used to patch newState + * @returns - newState + */ +function patchObject(newState, oldState) { + // no need to go through symbols because they cannot be serialized anyway + for (const key in oldState) { + const subPatch = oldState[key]; + // skip the whole sub tree + if (!(key in newState)) { + continue; + } + const targetValue = newState[key]; + if (isPlainObject(targetValue) && + isPlainObject(subPatch) && + !vueDemi.isRef(subPatch) && + !vueDemi.isReactive(subPatch)) { + newState[key] = patchObject(targetValue, subPatch); + } + else { + // objects are either a bit more complex (e.g. refs) or primitives, so we + // just set the whole thing + if (vueDemi.isVue2) { + vueDemi.set(newState, key, subPatch); + } + else { + newState[key] = subPatch; + } + } + } + return newState; +} +/** + * Creates an _accept_ function to pass to `import.meta.hot` in Vite applications. + * + * @example + * ```js + * const useUser = defineStore(...) + * if (import.meta.hot) { + * import.meta.hot.accept(acceptHMRUpdate(useUser, import.meta.hot)) + * } + * ``` + * + * @param initialUseStore - return of the defineStore to hot update + * @param hot - `import.meta.hot` + */ +function acceptHMRUpdate(initialUseStore, hot) { + // strip as much as possible from iife.prod + if (!(process.env.NODE_ENV !== 'production')) { + return () => { }; + } + return (newModule) => { + const pinia = hot.data.pinia || initialUseStore._pinia; + if (!pinia) { + // this store is still not used + return; + } + // preserve the pinia instance across loads + hot.data.pinia = pinia; + // console.log('got data', newStore) + for (const exportName in newModule) { + const useStore = newModule[exportName]; + // console.log('checking for', exportName) + if (isUseStore(useStore) && pinia._s.has(useStore.$id)) { + // console.log('Accepting update for', useStore.$id) + const id = useStore.$id; + if (id !== initialUseStore.$id) { + console.warn(`The id of the store changed from "${initialUseStore.$id}" to "${id}". Reloading.`); + // return import.meta.hot.invalidate() + return hot.invalidate(); + } + const existingStore = pinia._s.get(id); + if (!existingStore) { + console.log(`[Pinia]: skipping hmr because store doesn't exist yet`); + return; + } + useStore(pinia, existingStore); + } + } + }; +} + +const noop = () => { }; +function addSubscription(subscriptions, callback, detached, onCleanup = noop) { + subscriptions.push(callback); + const removeSubscription = () => { + const idx = subscriptions.indexOf(callback); + if (idx > -1) { + subscriptions.splice(idx, 1); + onCleanup(); + } + }; + if (!detached && vueDemi.getCurrentScope()) { + vueDemi.onScopeDispose(removeSubscription); + } + return removeSubscription; +} +function triggerSubscriptions(subscriptions, ...args) { + subscriptions.slice().forEach((callback) => { + callback(...args); + }); +} + +const fallbackRunWithContext = (fn) => fn(); +/** + * Marks a function as an action for `$onAction` + * @internal + */ +const ACTION_MARKER = Symbol(); +/** + * Action name symbol. Allows to add a name to an action after defining it + * @internal + */ +const ACTION_NAME = Symbol(); +function mergeReactiveObjects(target, patchToApply) { + // Handle Map instances + if (target instanceof Map && patchToApply instanceof Map) { + patchToApply.forEach((value, key) => target.set(key, value)); + } + else if (target instanceof Set && patchToApply instanceof Set) { + // Handle Set instances + patchToApply.forEach(target.add, target); + } + // no need to go through symbols because they cannot be serialized anyway + for (const key in patchToApply) { + if (!patchToApply.hasOwnProperty(key)) + continue; + const subPatch = patchToApply[key]; + const targetValue = target[key]; + if (isPlainObject(targetValue) && + isPlainObject(subPatch) && + target.hasOwnProperty(key) && + !vueDemi.isRef(subPatch) && + !vueDemi.isReactive(subPatch)) { + // NOTE: here I wanted to warn about inconsistent types but it's not possible because in setup stores one might + // start the value of a property as a certain type e.g. a Map, and then for some reason, during SSR, change that + // to `undefined`. When trying to hydrate, we want to override the Map with `undefined`. + target[key] = mergeReactiveObjects(targetValue, subPatch); + } + else { + // @ts-expect-error: subPatch is a valid value + target[key] = subPatch; + } + } + return target; +} +const skipHydrateSymbol = (process.env.NODE_ENV !== 'production') + ? Symbol('pinia:skipHydration') + : /* istanbul ignore next */ Symbol(); +const skipHydrateMap = /*#__PURE__*/ new WeakMap(); +/** + * Tells Pinia to skip the hydration process of a given object. This is useful in setup stores (only) when you return a + * stateful object in the store but it isn't really state. e.g. returning a router instance in a setup store. + * + * @param obj - target object + * @returns obj + */ +function skipHydrate(obj) { + return vueDemi.isVue2 + ? // in @vue/composition-api, the refs are sealed so defineProperty doesn't work... + /* istanbul ignore next */ skipHydrateMap.set(obj, 1) && obj + : Object.defineProperty(obj, skipHydrateSymbol, {}); +} +/** + * Returns whether a value should be hydrated + * + * @param obj - target variable + * @returns true if `obj` should be hydrated + */ +function shouldHydrate(obj) { + return vueDemi.isVue2 + ? /* istanbul ignore next */ !skipHydrateMap.has(obj) + : !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol); +} +const { assign } = Object; +function isComputed(o) { + return !!(vueDemi.isRef(o) && o.effect); +} +function createOptionsStore(id, options, pinia, hot) { + const { state, actions, getters } = options; + const initialState = pinia.state.value[id]; + let store; + function setup() { + if (!initialState && (!(process.env.NODE_ENV !== 'production') || !hot)) { + /* istanbul ignore if */ + if (vueDemi.isVue2) { + vueDemi.set(pinia.state.value, id, state ? state() : {}); + } + else { + pinia.state.value[id] = state ? state() : {}; + } + } + // avoid creating a state in pinia.state.value + const localState = (process.env.NODE_ENV !== 'production') && hot + ? // use ref() to unwrap refs inside state TODO: check if this is still necessary + vueDemi.toRefs(vueDemi.ref(state ? state() : {}).value) + : vueDemi.toRefs(pinia.state.value[id]); + return assign(localState, actions, Object.keys(getters || {}).reduce((computedGetters, name) => { + if ((process.env.NODE_ENV !== 'production') && name in localState) { + console.warn(`[🍍]: A getter cannot have the same name as another state property. Rename one of them. Found with "${name}" in store "${id}".`); + } + computedGetters[name] = vueDemi.markRaw(vueDemi.computed(() => { + setActivePinia(pinia); + // it was created just before + const store = pinia._s.get(id); + // allow cross using stores + /* istanbul ignore if */ + if (vueDemi.isVue2 && !store._r) + return; + // @ts-expect-error + // return getters![name].call(context, context) + // TODO: avoid reading the getter while assigning with a global variable + return getters[name].call(store, store); + })); + return computedGetters; + }, {})); + } + store = createSetupStore(id, setup, options, pinia, hot, true); + return store; +} +function createSetupStore($id, setup, options = {}, pinia, hot, isOptionsStore) { + let scope; + const optionsForPlugin = assign({ actions: {} }, options); + /* istanbul ignore if */ + if ((process.env.NODE_ENV !== 'production') && !pinia._e.active) { + throw new Error('Pinia destroyed'); + } + // watcher options for $subscribe + const $subscribeOptions = { deep: true }; + /* istanbul ignore else */ + if ((process.env.NODE_ENV !== 'production') && !vueDemi.isVue2) { + $subscribeOptions.onTrigger = (event) => { + /* istanbul ignore else */ + if (isListening) { + debuggerEvents = event; + // avoid triggering this while the store is being built and the state is being set in pinia + } + else if (isListening == false && !store._hotUpdating) { + // let patch send all the events together later + /* istanbul ignore else */ + if (Array.isArray(debuggerEvents)) { + debuggerEvents.push(event); + } + else { + console.error('🍍 debuggerEvents should be an array. This is most likely an internal Pinia bug.'); + } + } + }; + } + // internal state + let isListening; // set to true at the end + let isSyncListening; // set to true at the end + let subscriptions = []; + let actionSubscriptions = []; + let debuggerEvents; + const initialState = pinia.state.value[$id]; + // avoid setting the state for option stores if it is set + // by the setup + if (!isOptionsStore && !initialState && (!(process.env.NODE_ENV !== 'production') || !hot)) { + /* istanbul ignore if */ + if (vueDemi.isVue2) { + vueDemi.set(pinia.state.value, $id, {}); + } + else { + pinia.state.value[$id] = {}; + } + } + const hotState = vueDemi.ref({}); + // avoid triggering too many listeners + // https://github.com/vuejs/pinia/issues/1129 + let activeListener; + function $patch(partialStateOrMutator) { + let subscriptionMutation; + isListening = isSyncListening = false; + // reset the debugger events since patches are sync + /* istanbul ignore else */ + if ((process.env.NODE_ENV !== 'production')) { + debuggerEvents = []; + } + if (typeof partialStateOrMutator === 'function') { + partialStateOrMutator(pinia.state.value[$id]); + subscriptionMutation = { + type: exports.MutationType.patchFunction, + storeId: $id, + events: debuggerEvents, + }; + } + else { + mergeReactiveObjects(pinia.state.value[$id], partialStateOrMutator); + subscriptionMutation = { + type: exports.MutationType.patchObject, + payload: partialStateOrMutator, + storeId: $id, + events: debuggerEvents, + }; + } + const myListenerId = (activeListener = Symbol()); + vueDemi.nextTick().then(() => { + if (activeListener === myListenerId) { + isListening = true; + } + }); + isSyncListening = true; + // because we paused the watcher, we need to manually call the subscriptions + triggerSubscriptions(subscriptions, subscriptionMutation, pinia.state.value[$id]); + } + const $reset = isOptionsStore + ? function $reset() { + const { state } = options; + const newState = state ? state() : {}; + // we use a patch to group all changes into one single subscription + this.$patch(($state) => { + // @ts-expect-error: FIXME: shouldn't error? + assign($state, newState); + }); + } + : /* istanbul ignore next */ + (process.env.NODE_ENV !== 'production') + ? () => { + throw new Error(`🍍: Store "${$id}" is built using the setup syntax and does not implement $reset().`); + } + : noop; + function $dispose() { + scope.stop(); + subscriptions = []; + actionSubscriptions = []; + pinia._s.delete($id); + } + /** + * Helper that wraps function so it can be tracked with $onAction + * @param fn - action to wrap + * @param name - name of the action + */ + const action = (fn, name = '') => { + if (ACTION_MARKER in fn) { + fn[ACTION_NAME] = name; + return fn; + } + const wrappedAction = function () { + setActivePinia(pinia); + const args = Array.from(arguments); + const afterCallbackList = []; + const onErrorCallbackList = []; + function after(callback) { + afterCallbackList.push(callback); + } + function onError(callback) { + onErrorCallbackList.push(callback); + } + // @ts-expect-error + triggerSubscriptions(actionSubscriptions, { + args, + name: wrappedAction[ACTION_NAME], + store, + after, + onError, + }); + let ret; + try { + ret = fn.apply(this && this.$id === $id ? this : store, args); + // handle sync errors + } + catch (error) { + triggerSubscriptions(onErrorCallbackList, error); + throw error; + } + if (ret instanceof Promise) { + return ret + .then((value) => { + triggerSubscriptions(afterCallbackList, value); + return value; + }) + .catch((error) => { + triggerSubscriptions(onErrorCallbackList, error); + return Promise.reject(error); + }); + } + // trigger after callbacks + triggerSubscriptions(afterCallbackList, ret); + return ret; + }; + wrappedAction[ACTION_MARKER] = true; + wrappedAction[ACTION_NAME] = name; // will be set later + // @ts-expect-error: we are intentionally limiting the returned type to just Fn + // because all the added properties are internals that are exposed through `$onAction()` only + return wrappedAction; + }; + const _hmrPayload = /*#__PURE__*/ vueDemi.markRaw({ + actions: {}, + getters: {}, + state: [], + hotState, + }); + const partialStore = { + _p: pinia, + // _s: scope, + $id, + $onAction: addSubscription.bind(null, actionSubscriptions), + $patch, + $reset, + $subscribe(callback, options = {}) { + const removeSubscription = addSubscription(subscriptions, callback, options.detached, () => stopWatcher()); + const stopWatcher = scope.run(() => vueDemi.watch(() => pinia.state.value[$id], (state) => { + if (options.flush === 'sync' ? isSyncListening : isListening) { + callback({ + storeId: $id, + type: exports.MutationType.direct, + events: debuggerEvents, + }, state); + } + }, assign({}, $subscribeOptions, options))); + return removeSubscription; + }, + $dispose, + }; + /* istanbul ignore if */ + if (vueDemi.isVue2) { + // start as non ready + partialStore._r = false; + } + const store = vueDemi.reactive((process.env.NODE_ENV !== 'production') || ((((process.env.NODE_ENV !== 'production') || false) && !(process.env.NODE_ENV === 'test')) && IS_CLIENT) + ? assign({ + _hmrPayload, + _customProperties: vueDemi.markRaw(new Set()), // devtools custom properties + }, partialStore + // must be added later + // setupStore + ) + : partialStore); + // store the partial store now so the setup of stores can instantiate each other before they are finished without + // creating infinite loops. + pinia._s.set($id, store); + const runWithContext = (pinia._a && pinia._a.runWithContext) || fallbackRunWithContext; + // TODO: idea create skipSerialize that marks properties as non serializable and they are skipped + const setupStore = runWithContext(() => pinia._e.run(() => (scope = vueDemi.effectScope()).run(() => setup({ action })))); + // overwrite existing actions to support $onAction + for (const key in setupStore) { + const prop = setupStore[key]; + if ((vueDemi.isRef(prop) && !isComputed(prop)) || vueDemi.isReactive(prop)) { + // mark it as a piece of state to be serialized + if ((process.env.NODE_ENV !== 'production') && hot) { + vueDemi.set(hotState.value, key, vueDemi.toRef(setupStore, key)); + // createOptionStore directly sets the state in pinia.state.value so we + // can just skip that + } + else if (!isOptionsStore) { + // in setup stores we must hydrate the state and sync pinia state tree with the refs the user just created + if (initialState && shouldHydrate(prop)) { + if (vueDemi.isRef(prop)) { + prop.value = initialState[key]; + } + else { + // probably a reactive object, lets recursively assign + // @ts-expect-error: prop is unknown + mergeReactiveObjects(prop, initialState[key]); + } + } + // transfer the ref to the pinia state to keep everything in sync + /* istanbul ignore if */ + if (vueDemi.isVue2) { + vueDemi.set(pinia.state.value[$id], key, prop); + } + else { + pinia.state.value[$id][key] = prop; + } + } + /* istanbul ignore else */ + if ((process.env.NODE_ENV !== 'production')) { + _hmrPayload.state.push(key); + } + // action + } + else if (typeof prop === 'function') { + const actionValue = (process.env.NODE_ENV !== 'production') && hot ? prop : action(prop, key); + // this a hot module replacement store because the hotUpdate method needs + // to do it with the right context + /* istanbul ignore if */ + if (vueDemi.isVue2) { + vueDemi.set(setupStore, key, actionValue); + } + else { + // @ts-expect-error + setupStore[key] = actionValue; + } + /* istanbul ignore else */ + if ((process.env.NODE_ENV !== 'production')) { + _hmrPayload.actions[key] = prop; + } + // list actions so they can be used in plugins + // @ts-expect-error + optionsForPlugin.actions[key] = prop; + } + else if ((process.env.NODE_ENV !== 'production')) { + // add getters for devtools + if (isComputed(prop)) { + _hmrPayload.getters[key] = isOptionsStore + ? // @ts-expect-error + options.getters[key] + : prop; + if (IS_CLIENT) { + const getters = setupStore._getters || + // @ts-expect-error: same + (setupStore._getters = vueDemi.markRaw([])); + getters.push(key); + } + } + } + } + // add the state, getters, and action properties + /* istanbul ignore if */ + if (vueDemi.isVue2) { + Object.keys(setupStore).forEach((key) => { + vueDemi.set(store, key, setupStore[key]); + }); + } + else { + assign(store, setupStore); + // allows retrieving reactive objects with `storeToRefs()`. Must be called after assigning to the reactive object. + // Make `storeToRefs()` work with `reactive()` #799 + assign(vueDemi.toRaw(store), setupStore); + } + // use this instead of a computed with setter to be able to create it anywhere + // without linking the computed lifespan to wherever the store is first + // created. + Object.defineProperty(store, '$state', { + get: () => ((process.env.NODE_ENV !== 'production') && hot ? hotState.value : pinia.state.value[$id]), + set: (state) => { + /* istanbul ignore if */ + if ((process.env.NODE_ENV !== 'production') && hot) { + throw new Error('cannot set hotState'); + } + $patch(($state) => { + // @ts-expect-error: FIXME: shouldn't error? + assign($state, state); + }); + }, + }); + // add the hotUpdate before plugins to allow them to override it + /* istanbul ignore else */ + if ((process.env.NODE_ENV !== 'production')) { + store._hotUpdate = vueDemi.markRaw((newStore) => { + store._hotUpdating = true; + newStore._hmrPayload.state.forEach((stateKey) => { + if (stateKey in store.$state) { + const newStateTarget = newStore.$state[stateKey]; + const oldStateSource = store.$state[stateKey]; + if (typeof newStateTarget === 'object' && + isPlainObject(newStateTarget) && + isPlainObject(oldStateSource)) { + patchObject(newStateTarget, oldStateSource); + } + else { + // transfer the ref + newStore.$state[stateKey] = oldStateSource; + } + } + // patch direct access properties to allow store.stateProperty to work as + // store.$state.stateProperty + vueDemi.set(store, stateKey, vueDemi.toRef(newStore.$state, stateKey)); + }); + // remove deleted state properties + Object.keys(store.$state).forEach((stateKey) => { + if (!(stateKey in newStore.$state)) { + vueDemi.del(store, stateKey); + } + }); + // avoid devtools logging this as a mutation + isListening = false; + isSyncListening = false; + pinia.state.value[$id] = vueDemi.toRef(newStore._hmrPayload, 'hotState'); + isSyncListening = true; + vueDemi.nextTick().then(() => { + isListening = true; + }); + for (const actionName in newStore._hmrPayload.actions) { + const actionFn = newStore[actionName]; + vueDemi.set(store, actionName, action(actionFn, actionName)); + } + // TODO: does this work in both setup and option store? + for (const getterName in newStore._hmrPayload.getters) { + const getter = newStore._hmrPayload.getters[getterName]; + const getterValue = isOptionsStore + ? // special handling of options api + vueDemi.computed(() => { + setActivePinia(pinia); + return getter.call(store, store); + }) + : getter; + vueDemi.set(store, getterName, getterValue); + } + // remove deleted getters + Object.keys(store._hmrPayload.getters).forEach((key) => { + if (!(key in newStore._hmrPayload.getters)) { + vueDemi.del(store, key); + } + }); + // remove old actions + Object.keys(store._hmrPayload.actions).forEach((key) => { + if (!(key in newStore._hmrPayload.actions)) { + vueDemi.del(store, key); + } + }); + // update the values used in devtools and to allow deleting new properties later on + store._hmrPayload = newStore._hmrPayload; + store._getters = newStore._getters; + store._hotUpdating = false; + }); + } + if ((((process.env.NODE_ENV !== 'production') || false) && !(process.env.NODE_ENV === 'test')) && IS_CLIENT) { + const nonEnumerable = { + writable: true, + configurable: true, + // avoid warning on devtools trying to display this property + enumerable: false, + }; + ['_p', '_hmrPayload', '_getters', '_customProperties'].forEach((p) => { + Object.defineProperty(store, p, assign({ value: store[p] }, nonEnumerable)); + }); + } + /* istanbul ignore if */ + if (vueDemi.isVue2) { + // mark the store as ready before plugins + store._r = true; + } + // apply all plugins + pinia._p.forEach((extender) => { + /* istanbul ignore else */ + if ((((process.env.NODE_ENV !== 'production') || false) && !(process.env.NODE_ENV === 'test')) && IS_CLIENT) { + const extensions = scope.run(() => extender({ + store: store, + app: pinia._a, + pinia, + options: optionsForPlugin, + })); + Object.keys(extensions || {}).forEach((key) => store._customProperties.add(key)); + assign(store, extensions); + } + else { + assign(store, scope.run(() => extender({ + store: store, + app: pinia._a, + pinia, + options: optionsForPlugin, + }))); + } + }); + if ((process.env.NODE_ENV !== 'production') && + store.$state && + typeof store.$state === 'object' && + typeof store.$state.constructor === 'function' && + !store.$state.constructor.toString().includes('[native code]')) { + console.warn(`[🍍]: The "state" must be a plain object. It cannot be\n` + + `\tstate: () => new MyClass()\n` + + `Found in store "${store.$id}".`); + } + // only apply hydrate to option stores with an initial state in pinia + if (initialState && + isOptionsStore && + options.hydrate) { + options.hydrate(store.$state, initialState); + } + isListening = true; + isSyncListening = true; + return store; +} +// allows unused stores to be tree shaken +/*! #__NO_SIDE_EFFECTS__ */ +function defineStore( +// TODO: add proper types from above +idOrOptions, setup, setupOptions) { + let id; + let options; + const isSetupStore = typeof setup === 'function'; + if (typeof idOrOptions === 'string') { + id = idOrOptions; + // the option store setup will contain the actual options in this case + options = isSetupStore ? setupOptions : setup; + } + else { + options = idOrOptions; + id = idOrOptions.id; + if ((process.env.NODE_ENV !== 'production') && typeof id !== 'string') { + throw new Error(`[🍍]: "defineStore()" must be passed a store id as its first argument.`); + } + } + function useStore(pinia, hot) { + const hasContext = vueDemi.hasInjectionContext(); + pinia = + // in test mode, ignore the argument provided as we can always retrieve a + // pinia instance with getActivePinia() + ((process.env.NODE_ENV === 'test') && activePinia && activePinia._testing ? null : pinia) || + (hasContext ? vueDemi.inject(piniaSymbol, null) : null); + if (pinia) + setActivePinia(pinia); + if ((process.env.NODE_ENV !== 'production') && !activePinia) { + throw new Error(`[🍍]: "getActivePinia()" was called but there was no active Pinia. Are you trying to use a store before calling "app.use(pinia)"?\n` + + `See https://pinia.vuejs.org/core-concepts/outside-component-usage.html for help.\n` + + `This will fail in production.`); + } + pinia = activePinia; + if (!pinia._s.has(id)) { + // creating the store registers it in `pinia._s` + if (isSetupStore) { + createSetupStore(id, setup, options, pinia); + } + else { + createOptionsStore(id, options, pinia); + } + /* istanbul ignore else */ + if ((process.env.NODE_ENV !== 'production')) { + // @ts-expect-error: not the right inferred type + useStore._pinia = pinia; + } + } + const store = pinia._s.get(id); + if ((process.env.NODE_ENV !== 'production') && hot) { + const hotId = '__hot:' + id; + const newStore = isSetupStore + ? createSetupStore(hotId, setup, options, pinia, true) + : createOptionsStore(hotId, assign({}, options), pinia, true); + hot._hotUpdate(newStore); + // cleanup the state properties and the store from the cache + delete pinia.state.value[hotId]; + pinia._s.delete(hotId); + } + if ((process.env.NODE_ENV !== 'production') && IS_CLIENT) { + const currentInstance = vueDemi.getCurrentInstance(); + // save stores in instances to access them devtools + if (currentInstance && + currentInstance.proxy && + // avoid adding stores that are just built for hot module replacement + !hot) { + const vm = currentInstance.proxy; + const cache = '_pStores' in vm ? vm._pStores : (vm._pStores = {}); + cache[id] = store; + } + } + // StoreGeneric cannot be casted towards Store + return store; + } + useStore.$id = id; + return useStore; +} + +let mapStoreSuffix = 'Store'; +/** + * Changes the suffix added by `mapStores()`. Can be set to an empty string. + * Defaults to `"Store"`. Make sure to extend the MapStoresCustomization + * interface if you are using TypeScript. + * + * @param suffix - new suffix + */ +function setMapStoreSuffix(suffix // could be 'Store' but that would be annoying for JS +) { + mapStoreSuffix = suffix; +} +/** + * Allows using stores without the composition API (`setup()`) by generating an + * object to be spread in the `computed` field of a component. It accepts a list + * of store definitions. + * + * @example + * ```js + * export default { + * computed: { + * // other computed properties + * ...mapStores(useUserStore, useCartStore) + * }, + * + * created() { + * this.userStore // store with id "user" + * this.cartStore // store with id "cart" + * } + * } + * ``` + * + * @param stores - list of stores to map to an object + */ +function mapStores(...stores) { + if ((process.env.NODE_ENV !== 'production') && Array.isArray(stores[0])) { + console.warn(`[🍍]: Directly pass all stores to "mapStores()" without putting them in an array:\n` + + `Replace\n` + + `\tmapStores([useAuthStore, useCartStore])\n` + + `with\n` + + `\tmapStores(useAuthStore, useCartStore)\n` + + `This will fail in production if not fixed.`); + stores = stores[0]; + } + return stores.reduce((reduced, useStore) => { + // @ts-expect-error: $id is added by defineStore + reduced[useStore.$id + mapStoreSuffix] = function () { + return useStore(this.$pinia); + }; + return reduced; + }, {}); +} +/** + * Allows using state and getters from one store without using the composition + * API (`setup()`) by generating an object to be spread in the `computed` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ +function mapState(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + reduced[key] = function () { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key]; + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function () { + const store = useStore(this.$pinia); + const storeKey = keysOrMapper[key]; + // for some reason TS is unable to infer the type of storeKey to be a + // function + return typeof storeKey === 'function' + ? storeKey.call(this, store) + : // @ts-expect-error: FIXME: should work? + store[storeKey]; + }; + return reduced; + }, {}); +} +/** + * Alias for `mapState()`. You should use `mapState()` instead. + * @deprecated use `mapState()` instead. + */ +const mapGetters = mapState; +/** + * Allows directly using actions from your store without using the composition + * API (`setup()`) by generating an object to be spread in the `methods` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ +function mapActions(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function (...args) { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key](...args); + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function (...args) { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[keysOrMapper[key]](...args); + }; + return reduced; + }, {}); +} +/** + * Allows using state and getters from one store without using the composition + * API (`setup()`) by generating an object to be spread in the `computed` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ +function mapWritableState(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + // @ts-ignore + reduced[key] = { + get() { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key]; + }, + set(value) { + // @ts-expect-error: FIXME: should work? + return (useStore(this.$pinia)[key] = value); + }, + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-ignore + reduced[key] = { + get() { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[keysOrMapper[key]]; + }, + set(value) { + // @ts-expect-error: FIXME: should work? + return (useStore(this.$pinia)[keysOrMapper[key]] = value); + }, + }; + return reduced; + }, {}); +} + +/** + * Creates an object of references with all the state, getters, and plugin-added + * state properties of the store. Similar to `toRefs()` but specifically + * designed for Pinia stores so methods and non reactive properties are + * completely ignored. + * + * @param store - store to extract the refs from + */ +function storeToRefs(store) { + // See https://github.com/vuejs/pinia/issues/852 + // It's easier to just use toRefs() even if it includes more stuff + if (vueDemi.isVue2) { + // @ts-expect-error: toRefs include methods and others + return vueDemi.toRefs(store); + } + else { + const rawStore = vueDemi.toRaw(store); + const refs = {}; + for (const key in rawStore) { + const value = rawStore[key]; + if (vueDemi.isRef(value) || vueDemi.isReactive(value)) { + // @ts-expect-error: the key is state or getter + refs[key] = + // --- + vueDemi.toRef(store, key); + } + } + return refs; + } +} + +/** + * Vue 2 Plugin that must be installed for pinia to work. Note **you don't need + * this plugin if you are using Nuxt.js**. Use the `buildModule` instead: + * https://pinia.vuejs.org/ssr/nuxt.html. + * + * @example + * ```js + * import Vue from 'vue' + * import { PiniaVuePlugin, createPinia } from 'pinia' + * + * Vue.use(PiniaVuePlugin) + * const pinia = createPinia() + * + * new Vue({ + * el: '#app', + * // ... + * pinia, + * }) + * ``` + * + * @param _Vue - `Vue` imported from 'vue'. + */ +const PiniaVuePlugin = function (_Vue) { + // Equivalent of + // app.config.globalProperties.$pinia = pinia + _Vue.mixin({ + beforeCreate() { + const options = this.$options; + if (options.pinia) { + const pinia = options.pinia; + // HACK: taken from provide(): https://github.com/vuejs/composition-api/blob/main/src/apis/inject.ts#L31 + /* istanbul ignore else */ + if (!this._provided) { + const provideCache = {}; + Object.defineProperty(this, '_provided', { + get: () => provideCache, + set: (v) => Object.assign(provideCache, v), + }); + } + this._provided[piniaSymbol] = pinia; + // propagate the pinia instance in an SSR friendly way + // avoid adding it to nuxt twice + /* istanbul ignore else */ + if (!this.$pinia) { + this.$pinia = pinia; + } + pinia._a = this; + if (IS_CLIENT) { + // this allows calling useStore() outside of a component setup after + // installing pinia's plugin + setActivePinia(pinia); + } + if ((((process.env.NODE_ENV !== 'production') || false) && !(process.env.NODE_ENV === 'test')) && IS_CLIENT) { + registerPiniaDevtools(pinia._a, pinia); + } + } + else if (!this.$pinia && options.parent && options.parent.$pinia) { + this.$pinia = options.parent.$pinia; + } + }, + destroyed() { + delete this._pStores; + }, + }); +}; + +exports.PiniaVuePlugin = PiniaVuePlugin; +exports.acceptHMRUpdate = acceptHMRUpdate; +exports.createPinia = createPinia; +exports.defineStore = defineStore; +exports.disposePinia = disposePinia; +exports.getActivePinia = getActivePinia; +exports.mapActions = mapActions; +exports.mapGetters = mapGetters; +exports.mapState = mapState; +exports.mapStores = mapStores; +exports.mapWritableState = mapWritableState; +exports.setActivePinia = setActivePinia; +exports.setMapStoreSuffix = setMapStoreSuffix; +exports.shouldHydrate = shouldHydrate; +exports.skipHydrate = skipHydrate; +exports.storeToRefs = storeToRefs; diff --git a/node_modules/pinia/dist/pinia.d.ts b/node_modules/pinia/dist/pinia.d.ts new file mode 100644 index 0000000..fbd63c7 --- /dev/null +++ b/node_modules/pinia/dist/pinia.d.ts @@ -0,0 +1,1072 @@ +import { App } from 'vue-demi'; +import { ComputedRef } from 'vue-demi'; +import type { DebuggerEvent } from 'vue-demi'; +import { EffectScope } from 'vue-demi'; +import type { Plugin as Plugin_2 } from 'vue-demi'; +import { Ref } from 'vue-demi'; +import { ToRef } from 'vue-demi'; +import { ToRefs } from 'vue-demi'; +import { UnwrapRef } from 'vue-demi'; +import type { WatchOptions } from 'vue-demi'; +import { WritableComputedRef } from 'vue-demi'; + +/** + * Creates an _accept_ function to pass to `import.meta.hot` in Vite applications. + * + * @example + * ```js + * const useUser = defineStore(...) + * if (import.meta.hot) { + * import.meta.hot.accept(acceptHMRUpdate(useUser, import.meta.hot)) + * } + * ``` + * + * @param initialUseStore - return of the defineStore to hot update + * @param hot - `import.meta.hot` + */ +export declare function acceptHMRUpdate = _GettersTree, A = _ActionsTree>(initialUseStore: StoreDefinition, hot: any): (newModule: any) => any; + +/** + * Type of an object of Actions. For internal usage only. + * For internal use **only** + */ +export declare type _ActionsTree = Record; + +export declare type _Awaited = T extends null | undefined ? T : T extends object & { + then(onfulfilled: infer F): any; +} ? F extends (value: infer V, ...args: any) => any ? _Awaited : never : T; + +/** + * Creates a Pinia instance to be used by the application + */ +export declare function createPinia(): Pinia; + +/** + * Recursive `Partial`. Used by {@link Store['$patch']}. + * + * For internal use **only** + */ +export declare type _DeepPartial = { + [K in keyof T]?: _DeepPartial; +}; + +/** + * Options parameter of `defineStore()` for setup stores. Can be extended to + * augment stores with the plugin API. @see {@link DefineStoreOptionsBase}. + */ +export declare interface DefineSetupStoreOptions extends DefineStoreOptionsBase> { + /** + * Extracted actions. Added by useStore(). SHOULD NOT be added by the user when + * creating the store. Can be used in plugins to get the list of actions in a + * store defined with a setup function. Note this is always defined + */ + actions?: A; +} + +/** + * Creates a `useStore` function that retrieves the store instance + * + * @param id - id of the store (must be unique) + * @param options - options to define the store + */ +export declare function defineStore = {}, A = {}>(id: Id, options: Omit, 'id'>): StoreDefinition; + +/** + * Creates a `useStore` function that retrieves the store instance + * + * @param options - options to define the store + */ +export declare function defineStore = {}, A = {}>(options: DefineStoreOptions): StoreDefinition; + +/** + * Creates a `useStore` function that retrieves the store instance + * + * @param id - id of the store (must be unique) + * @param storeSetup - function that defines the store + * @param options - extra options + */ +export declare function defineStore(id: Id, storeSetup: (helpers: SetupStoreHelpers) => SS, options?: DefineSetupStoreOptions, _ExtractGettersFromSetupStore, _ExtractActionsFromSetupStore>): StoreDefinition, _ExtractGettersFromSetupStore, _ExtractActionsFromSetupStore>; + +/** + * Options parameter of `defineStore()` for option stores. Can be extended to + * augment stores with the plugin API. @see {@link DefineStoreOptionsBase}. + */ +export declare interface DefineStoreOptions extends DefineStoreOptionsBase> { + /** + * Unique string key to identify the store across the application. + */ + id: Id; + /** + * Function to create a fresh state. **Must be an arrow function** to ensure + * correct typings! + */ + state?: () => S; + /** + * Optional object of getters. + */ + getters?: G & ThisType & _StoreWithGetters & PiniaCustomProperties> & _GettersTree; + /** + * Optional object of actions. + */ + actions?: A & ThisType & _StoreWithState & _StoreWithGetters & PiniaCustomProperties>; + /** + * Allows hydrating the store during SSR when complex state (like client side only refs) are used in the store + * definition and copying the value from `pinia.state` isn't enough. + * + * @example + * If in your `state`, you use any `customRef`s, any `computed`s, or any `ref`s that have a different value on + * Server and Client, you need to manually hydrate them. e.g., a custom ref that is stored in the local + * storage: + * + * ```ts + * const useStore = defineStore('main', { + * state: () => ({ + * n: useLocalStorage('key', 0) + * }), + * hydrate(storeState, initialState) { + * // @ts-expect-error: https://github.com/microsoft/TypeScript/issues/43826 + * storeState.n = useLocalStorage('key', 0) + * } + * }) + * ``` + * + * @param storeState - the current state in the store + * @param initialState - initialState + */ + hydrate?(storeState: UnwrapRef, initialState: UnwrapRef): void; +} + +/** + * Options passed to `defineStore()` that are common between option and setup + * stores. Extend this interface if you want to add custom options to both kinds + * of stores. + */ +export declare interface DefineStoreOptionsBase { +} + +/** + * Available `options` when creating a pinia plugin. + */ +export declare interface DefineStoreOptionsInPlugin extends Omit, 'id' | 'actions'> { + /** + * Extracted object of actions. Added by useStore() when the store is built + * using the setup API, otherwise uses the one passed to `defineStore()`. + * Defaults to an empty object if no actions are defined. + */ + actions: A; +} + +/** + * Dispose a Pinia instance by stopping its effectScope and removing the state, plugins and stores. This is mostly + * useful in tests, with both a testing pinia or a regular pinia and in applications that use multiple pinia instances. + * Once disposed, the pinia instance cannot be used anymore. + * + * @param pinia - pinia instance + */ +export declare function disposePinia(pinia: Pinia): void; + +/** + * For internal use **only** + */ +export declare type _ExtractActionsFromSetupStore = SS extends undefined | void ? {} : Pick>; + +/** + * Type that enables refactoring through IDE. + * For internal use **only** + */ +export declare type _ExtractActionsFromSetupStore_Keys = keyof { + [K in keyof SS as SS[K] extends _Method ? K : never]: any; +}; + +/** + * For internal use **only** + */ +export declare type _ExtractGettersFromSetupStore = SS extends undefined | void ? {} : Pick>; + +/** + * Type that enables refactoring through IDE. + * For internal use **only** + */ +export declare type _ExtractGettersFromSetupStore_Keys = keyof { + [K in keyof SS as SS[K] extends ComputedRef ? K : never]: any; +}; + +/** + * For internal use **only** + */ +export declare type _ExtractStateFromSetupStore = SS extends undefined | void ? {} : Pick>; + +/** + * Type that enables refactoring through IDE. + * For internal use **only** + */ +export declare type _ExtractStateFromSetupStore_Keys = keyof { + [K in keyof SS as SS[K] extends _Method | ComputedRef ? never : K]: any; +}; + +/** + * Get the currently active pinia if there is any. + */ +export declare const getActivePinia: () => Pinia | undefined; + +/** + * Type of an object of Getters that infers the argument. For internal usage only. + * For internal use **only** + */ +export declare type _GettersTree = Record & UnwrapRef>) => any) | (() => any)>; + +/** + * Internal utility type + */ +declare type _IfEquals = (() => T extends X ? 1 : 2) extends () => T extends Y ? 1 : 2 ? A : B; + +/** + * Internal utility type + */ +declare type _IsReadonly = _IfEquals<{ + [P in K]: T[P]; +}, { + -readonly [P in K]: T[P]; +}, false, // Property is not readonly if they are the same +true>; + +/** + * Allows directly using actions from your store without using the composition + * API (`setup()`) by generating an object to be spread in the `methods` field + * of a component. The values of the object are the actions while the keys are + * the names of the resulting methods. + * + * @example + * ```js + * export default { + * methods: { + * // other methods properties + * // useCounterStore has two actions named `increment` and `setCount` + * ...mapActions(useCounterStore, { more: 'increment', setIt: 'setCount' }) + * }, + * + * created() { + * this.more() + * this.setIt(2) + * } + * } + * ``` + * + * @param useStore - store to map from + * @param keyMapper - object to define new names for the actions + */ +export declare function mapActions, A, KeyMapper extends Record>(useStore: StoreDefinition, keyMapper: KeyMapper): _MapActionsObjectReturn; + +/** + * Allows directly using actions from your store without using the composition + * API (`setup()`) by generating an object to be spread in the `methods` field + * of a component. + * + * @example + * ```js + * export default { + * methods: { + * // other methods properties + * ...mapActions(useCounterStore, ['increment', 'setCount']) + * }, + * + * created() { + * this.increment() + * this.setCount(2) // pass arguments as usual + * } + * } + * ``` + * + * @param useStore - store to map from + * @param keys - array of action names to map + */ +export declare function mapActions, A>(useStore: StoreDefinition, keys: Array): _MapActionsReturn; + +/** + * For internal use **only** + */ +export declare type _MapActionsObjectReturn> = { + [key in keyof T]: A[T[key]]; +}; + +/** + * For internal use **only** + */ +export declare type _MapActionsReturn = { + [key in keyof A]: A[key]; +}; + +/** + * Alias for `mapState()`. You should use `mapState()` instead. + * @deprecated use `mapState()` instead. + */ +export declare const mapGetters: typeof mapState; + +/** + * Allows using state and getters from one store without using the composition + * API (`setup()`) by generating an object to be spread in the `computed` field + * of a component. The values of the object are the state properties/getters + * while the keys are the names of the resulting computed properties. + * Optionally, you can also pass a custom function that will receive the store + * as its first argument. Note that while it has access to the component + * instance via `this`, it won't be typed. + * + * @example + * ```js + * export default { + * computed: { + * // other computed properties + * // useCounterStore has a state property named `count` and a getter `double` + * ...mapState(useCounterStore, { + * n: 'count', + * triple: store => store.n * 3, + * // note we can't use an arrow function if we want to use `this` + * custom(store) { + * return this.someComponentValue + store.n + * }, + * doubleN: 'double' + * }) + * }, + * + * created() { + * this.n // 2 + * this.doubleN // 4 + * } + * } + * ``` + * + * @param useStore - store to map from + * @param keyMapper - object of state properties or getters + */ +export declare function mapState | { + [key: string]: ComputedRef; +}, A, KeyMapper extends Record) => any)>>(useStore: StoreDefinition, keyMapper: KeyMapper): _MapStateObjectReturn; + +/** + * Allows using state and getters from one store without using the composition + * API (`setup()`) by generating an object to be spread in the `computed` field + * of a component. + * + * @example + * ```js + * export default { + * computed: { + * // other computed properties + * ...mapState(useCounterStore, ['count', 'double']) + * }, + * + * created() { + * this.count // 2 + * this.double // 4 + * } + * } + * ``` + * + * @param useStore - store to map from + * @param keys - array of state properties or getters + */ +export declare function mapState | { + [key: string]: ComputedRef; +}, A, Keys extends keyof S | keyof G>(useStore: StoreDefinition, keys: readonly Keys[]): _MapStateReturn; + +/** + * For internal use **only** + */ +export declare type _MapStateObjectReturn | { + [key: string]: ComputedRef; +}, A, T extends Record) => any)> = {}> = { + [key in keyof T]: () => T[key] extends (store: any) => infer R ? R : T[key] extends keyof Store ? Store[T[key]] : never; +}; + +/** + * For internal use **only** + */ +export declare type _MapStateReturn | { + [key: string]: ComputedRef; +}, Keys extends keyof S | keyof G = keyof S | keyof G> = { + [key in Keys]: key extends keyof Store ? () => Store[key] : never; +}; + +/** + * Allows using stores without the composition API (`setup()`) by generating an + * object to be spread in the `computed` field of a component. It accepts a list + * of store definitions. + * + * @example + * ```js + * export default { + * computed: { + * // other computed properties + * ...mapStores(useUserStore, useCartStore) + * }, + * + * created() { + * this.userStore // store with id "user" + * this.cartStore // store with id "cart" + * } + * } + * ``` + * + * @param stores - list of stores to map to an object + */ +export declare function mapStores(...stores: [...Stores]): _Spread; + +/** + * Interface to allow customizing map helpers. Extend this interface with the + * following properties: + * + * - `suffix`: string. Affects the suffix of `mapStores()`, defaults to `Store`. + */ +export declare interface MapStoresCustomization { +} + +/** + * Same as `mapState()` but creates computed setters as well so the state can be + * modified. Differently from `mapState()`, only `state` properties can be + * added. + * + * @param useStore - store to map from + * @param keyMapper - object of state properties + */ +export declare function mapWritableState, A, KeyMapper extends Record>(useStore: StoreDefinition, keyMapper: KeyMapper): _MapWritableStateObjectReturn; + +/** + * Allows using state and getters from one store without using the composition + * API (`setup()`) by generating an object to be spread in the `computed` field + * of a component. + * + * @param useStore - store to map from + * @param keys - array of state properties + */ +export declare function mapWritableState, A, Keys extends keyof S>(useStore: StoreDefinition, keys: readonly Keys[]): { + [K in Keys]: { + get: () => S[K]; + set: (value: S[K]) => any; + }; +}; + +/** + * For internal use **only** + */ +export declare type _MapWritableStateObjectReturn> = { + [key in keyof T]: { + get: () => S[T[key]]; + set: (value: S[T[key]]) => any; + }; +}; + +/** + * For internal use **only** + */ +export declare type _MapWritableStateReturn = { + [key in keyof S]: { + get: () => S[key]; + set: (value: S[key]) => any; + }; +}; + +/** + * Generic type for a function that can infer arguments and return type + * + * For internal use **only** + */ +export declare type _Method = (...args: any[]) => any; + +/** + * Possible types for SubscriptionCallback + */ +export declare enum MutationType { + /** + * Direct mutation of the state: + * + * - `store.name = 'new name'` + * - `store.$state.name = 'new name'` + * - `store.list.push('new item')` + */ + direct = "direct", + /** + * Mutated the state with `$patch` and an object + * + * - `store.$patch({ name: 'newName' })` + */ + patchObject = "patch object", + /** + * Mutated the state with `$patch` and a function + * + * - `store.$patch(state => state.name = 'newName')` + */ + patchFunction = "patch function" +} + +/** + * Every application must own its own pinia to be able to create stores + */ +export declare interface Pinia { + install: (app: App) => void; + /** + * root state + */ + state: Ref>; + /** + * Adds a store plugin to extend every store + * + * @param plugin - store plugin to add + */ + use(plugin: PiniaPlugin): Pinia; + /* Excluded from this release type: _p */ + /* Excluded from this release type: _a */ + /* Excluded from this release type: _e */ + /* Excluded from this release type: _s */ + /* Excluded from this release type: _testing */ +} + +/** + * Interface to be extended by the user when they add properties through plugins. + */ +export declare interface PiniaCustomProperties, A = _ActionsTree> { +} + +/** + * Properties that are added to every `store.$state` by `pinia.use()`. + */ +export declare interface PiniaCustomStateProperties { +} + +/** + * Plugin to extend every store. + */ +export declare interface PiniaPlugin { + /** + * Plugin to extend every store. Returns an object to extend the store or + * nothing. + * + * @param context - Context + */ + (context: PiniaPluginContext): Partial | void; +} + +/** + * Context argument passed to Pinia plugins. + */ +export declare interface PiniaPluginContext, A = _ActionsTree> { + /** + * pinia instance. + */ + pinia: Pinia; + /** + * Current app created with `Vue.createApp()`. + */ + app: App; + /** + * Current store being extended. + */ + store: Store; + /** + * Initial options defining the store when calling `defineStore()`. + */ + options: DefineStoreOptionsInPlugin; +} + +/** + * Plugin to extend every store. + * @deprecated use PiniaPlugin instead + */ +export declare type PiniaStorePlugin = PiniaPlugin; + +/** + * Vue 2 Plugin that must be installed for pinia to work. Note **you don't need + * this plugin if you are using Nuxt.js**. Use the `buildModule` instead: + * https://pinia.vuejs.org/ssr/nuxt.html. + * + * @example + * ```js + * import Vue from 'vue' + * import { PiniaVuePlugin, createPinia } from 'pinia' + * + * Vue.use(PiniaVuePlugin) + * const pinia = createPinia() + * + * new Vue({ + * el: '#app', + * // ... + * pinia, + * }) + * ``` + * + * @param _Vue - `Vue` imported from 'vue'. + */ +export declare const PiniaVuePlugin: Plugin_2; + +declare interface _SetActivePinia { + (pinia: Pinia): Pinia; + (pinia: undefined): undefined; + (pinia: Pinia | undefined): Pinia | undefined; +} + +/** + * Sets or unsets the active pinia. Used in SSR and internally when calling + * actions and getters + * + * @param pinia - Pinia instance + */ +export declare const setActivePinia: _SetActivePinia; + +/** + * Changes the suffix added by `mapStores()`. Can be set to an empty string. + * Defaults to `"Store"`. Make sure to extend the MapStoresCustomization + * interface if you are using TypeScript. + * + * @param suffix - new suffix + */ +export declare function setMapStoreSuffix(suffix: MapStoresCustomization extends Record<'suffix', infer Suffix> ? Suffix : string): void; + +/** + * Return type of `defineStore()` with a setup function. + * - `Id` is a string literal of the store's name + * - `SS` is the return type of the setup function + * @see {@link StoreDefinition} + */ +export declare interface SetupStoreDefinition extends StoreDefinition, _ExtractGettersFromSetupStore, _ExtractActionsFromSetupStore> { +} + +declare interface SetupStoreHelpers { + action: (fn: Fn) => Fn; +} + +/** + * Returns whether a value should be hydrated + * + * @param obj - target variable + * @returns true if `obj` should be hydrated + */ +export declare function shouldHydrate(obj: any): boolean; + +/** + * Tells Pinia to skip the hydration process of a given object. This is useful in setup stores (only) when you return a + * stateful object in the store but it isn't really state. e.g. returning a router instance in a setup store. + * + * @param obj - target object + * @returns obj + */ +export declare function skipHydrate(obj: T): T; + +/** + * For internal use **only**. + */ +export declare type _Spread = A extends [infer L, ...infer R] ? _StoreObject & _Spread : unknown; + +/** + * Generic state of a Store + */ +export declare type StateTree = Record; + +/** + * Store type to build a store. + */ +export declare type Store = _StoreWithState & UnwrapRef & _StoreWithGetters & (_ActionsTree extends A ? {} : A) & PiniaCustomProperties & PiniaCustomStateProperties; + +/** + * Extract the actions of a store type. Works with both a Setup Store or an + * Options Store. + */ +export declare type StoreActions = SS extends Store, infer A> ? A : _ExtractActionsFromSetupStore; + +/** + * Return type of `defineStore()`. Function that allows instantiating a store. + */ +export declare interface StoreDefinition, A = _ActionsTree> { + /** + * Returns a store, creates it if necessary. + * + * @param pinia - Pinia instance to retrieve the store + * @param hot - dev only hot module replacement + */ + (pinia?: Pinia | null | undefined, hot?: StoreGeneric): Store; + /** + * Id of the store. Used by map helpers. + */ + $id: Id; + /* Excluded from this release type: _pinia */ +} + +/** + * Generic and type-unsafe version of Store. Doesn't fail on access with + * strings, making it much easier to write generic functions that do not care + * about the kind of store that is passed. + */ +export declare type StoreGeneric = Store, _ActionsTree>; + +/** + * Extract the getters of a store type. Works with both a Setup Store or an + * Options Store. + */ +export declare type StoreGetters = SS extends Store ? _StoreWithGetters : _ExtractGettersFromSetupStore; + +/** + * For internal use **only**. + */ +export declare type _StoreObject = S extends StoreDefinition ? { + [Id in `${Ids}${MapStoresCustomization extends Record<'suffix', infer Suffix> ? Suffix : 'Store'}`]: () => Store ? Suffix : 'Store'}` ? RealId : string, State, Getters, Actions>; +} : {}; + +/** + * Argument of `store.$onAction()` + */ +export declare type StoreOnActionListener = (context: StoreOnActionListenerContext) => void; + +/** + * Context object passed to callbacks of `store.$onAction(context => {})` + * TODO: should have only the Id, the Store and Actions to generate the proper object + */ +export declare type StoreOnActionListenerContext = _ActionsTree extends A ? _StoreOnActionListenerContext : { + [Name in keyof A]: Name extends string ? _StoreOnActionListenerContext, Name, A> : never; +}[keyof A]; + +/** + * Actual type for {@link StoreOnActionListenerContext}. Exists for refactoring + * purposes. For internal use only. + * For internal use **only** + */ +export declare interface _StoreOnActionListenerContext { + /** + * Name of the action + */ + name: ActionName; + /** + * Store that is invoking the action + */ + store: Store; + /** + * Parameters passed to the action + */ + args: A extends Record ? Parameters : unknown[]; + /** + * Sets up a hook once the action is finished. It receives the return value + * of the action, if it's a Promise, it will be unwrapped. + */ + after: (callback: A extends Record ? (resolvedReturn: _Awaited>) => void : () => void) => void; + /** + * Sets up a hook if the action fails. Return `false` to catch the error and + * stop it from propagating. + */ + onError: (callback: (error: unknown) => void) => void; +} + +/** + * Properties of a store. + */ +export declare interface StoreProperties { + /** + * Unique identifier of the store + */ + $id: Id; + /* Excluded from this release type: _p */ + /* Excluded from this release type: _getters */ + /* Excluded from this release type: _isOptionsAPI */ + /** + * Used by devtools plugin to retrieve properties added with plugins. Removed + * in production. Can be used by the user to add property keys of the store + * that should be displayed in devtools. + */ + _customProperties: Set; + /* Excluded from this release type: _hotUpdate */ + /* Excluded from this release type: _hotUpdating */ + /* Excluded from this release type: _hmrPayload */ +} + +/** + * Extract the state of a store type. Works with both a Setup Store or an + * Options Store. Note this unwraps refs. + */ +export declare type StoreState = SS extends Store, _ActionsTree> ? UnwrapRef : _ExtractStateFromSetupStore; + +/** + * Extracts the return type for `storeToRefs`. + * Will convert any `getters` into `ComputedRef`. + */ +declare type StoreToRefs = SS extends unknown ? _ToStateRefs & ToRefs>> & _ToComputedRefs> : never; + +/** + * Creates an object of references with all the state, getters, and plugin-added + * state properties of the store. Similar to `toRefs()` but specifically + * designed for Pinia stores so methods and non reactive properties are + * completely ignored. + * + * @param store - store to extract the refs from + */ +export declare function storeToRefs(store: SS): StoreToRefs; + +/** + * Store augmented for actions. For internal usage only. + * For internal use **only** + */ +export declare type _StoreWithActions = { + [k in keyof A]: A[k] extends (...args: infer P) => infer R ? (...args: P) => R : never; +}; + +/** + * Store augmented with getters. For internal usage only. + * For internal use **only** + */ +export declare type _StoreWithGetters = _StoreWithGetters_Readonly & _StoreWithGetters_Writable; + +/** + * Store augmented with readonly getters. For internal usage **only**. + */ +declare type _StoreWithGetters_Readonly = { + readonly [K in keyof G as G[K] extends (...args: any[]) => any ? K : ComputedRef extends G[K] ? K : never]: G[K] extends (...args: any[]) => infer R ? R : UnwrapRef; +}; + +/** + * Store augmented with writable getters. For internal usage **only**. + */ +declare type _StoreWithGetters_Writable = { + [K in keyof G as G[K] extends WritableComputedRef ? K : never]: G[K] extends WritableComputedRef ? R : never; +}; + +/** + * Base store with state and functions. Should not be used directly. + */ +export declare interface _StoreWithState extends StoreProperties { + /** + * State of the Store. Setting it will internally call `$patch()` to update the state. + */ + $state: UnwrapRef & PiniaCustomStateProperties; + /** + * Applies a state patch to current state. Allows passing nested values + * + * @param partialState - patch to apply to the state + */ + $patch(partialState: _DeepPartial>): void; + /** + * Group multiple changes into one function. Useful when mutating objects like + * Sets or arrays and applying an object patch isn't practical, e.g. appending + * to an array. The function passed to `$patch()` **must be synchronous**. + * + * @param stateMutator - function that mutates `state`, cannot be asynchronous + */ + $patch) => any>(stateMutator: ReturnType extends Promise ? never : F): void; + /** + * Resets the store to its initial state by building a new state object. + */ + $reset(): void; + /** + * Setups a callback to be called whenever the state changes. It also returns a function to remove the callback. Note + * that when calling `store.$subscribe()` inside of a component, it will be automatically cleaned up when the + * component gets unmounted unless `detached` is set to true. + * + * @param callback - callback passed to the watcher + * @param options - `watch` options + `detached` to detach the subscription from the context (usually a component) + * this is called from. Note that the `flush` option does not affect calls to `store.$patch()`. + * @returns function that removes the watcher + */ + $subscribe(callback: SubscriptionCallback, options?: { + detached?: boolean; + } & WatchOptions): () => void; + /** + * Setups a callback to be called every time an action is about to get + * invoked. The callback receives an object with all the relevant information + * of the invoked action: + * - `store`: the store it is invoked on + * - `name`: The name of the action + * - `args`: The parameters passed to the action + * + * On top of these, it receives two functions that allow setting up a callback + * once the action finishes or when it fails. + * + * It also returns a function to remove the callback. Note than when calling + * `store.$onAction()` inside of a component, it will be automatically cleaned + * up when the component gets unmounted unless `detached` is set to true. + * + * @example + * + *```js + *store.$onAction(({ after, onError }) => { + * // Here you could share variables between all of the hooks as well as + * // setting up watchers and clean them up + * after((resolvedValue) => { + * // can be used to cleanup side effects + * . // `resolvedValue` is the value returned by the action, if it's a + * . // Promise, it will be the resolved value instead of the Promise + * }) + * onError((error) => { + * // can be used to pass up errors + * }) + *}) + *``` + * + * @param callback - callback called before every action + * @param detached - detach the subscription from the context this is called from + * @returns function that removes the watcher + */ + $onAction(callback: StoreOnActionListener, detached?: boolean): () => void; + /** + * Stops the associated effect scope of the store and remove it from the store + * registry. Plugins can override this method to cleanup any added effects. + * e.g. devtools plugin stops displaying disposed stores from devtools. + * Note this doesn't delete the state of the store, you have to do it manually with + * `delete pinia.state.value[store.$id]` if you want to. If you don't and the + * store is used again, it will reuse the previous state. + */ + $dispose(): void; + /* Excluded from this release type: _r */ +} + +/** + * Callback of a subscription + */ +export declare type SubscriptionCallback = ( +/** + * Object with information relative to the store mutation that triggered the + * subscription. + */ +mutation: SubscriptionCallbackMutation, +/** + * State of the store when the subscription is triggered. Same as + * `store.$state`. + */ +state: UnwrapRef) => void; + +/** + * Context object passed to a subscription callback. + */ +export declare type SubscriptionCallbackMutation = SubscriptionCallbackMutationDirect | SubscriptionCallbackMutationPatchObject | SubscriptionCallbackMutationPatchFunction; + +/** + * Base type for the context passed to a subscription callback. Internal type. + */ +export declare interface _SubscriptionCallbackMutationBase { + /** + * Type of the mutation. + */ + type: MutationType; + /** + * `id` of the store doing the mutation. + */ + storeId: string; + /** + * 🔴 DEV ONLY, DO NOT use for production code. Different mutation calls. Comes from + * https://vuejs.org/guide/extras/reactivity-in-depth.html#reactivity-debugging and allows to track mutations in + * devtools and plugins **during development only**. + */ + events?: DebuggerEvent[] | DebuggerEvent; +} + +/** + * Context passed to a subscription callback when directly mutating the state of + * a store with `store.someState = newValue` or `store.$state.someState = + * newValue`. + */ +export declare interface SubscriptionCallbackMutationDirect extends _SubscriptionCallbackMutationBase { + type: MutationType.direct; + events: DebuggerEvent; +} + +/** + * Context passed to a subscription callback when `store.$patch()` is called + * with a function. + */ +export declare interface SubscriptionCallbackMutationPatchFunction extends _SubscriptionCallbackMutationBase { + type: MutationType.patchFunction; + events: DebuggerEvent[]; +} + +/** + * Context passed to a subscription callback when `store.$patch()` is called + * with an object. + */ +export declare interface SubscriptionCallbackMutationPatchObject extends _SubscriptionCallbackMutationBase { + type: MutationType.patchObject; + events: DebuggerEvent[]; + /** + * Object passed to `store.$patch()`. + */ + payload: _DeepPartial>; +} + +/** + * Extracts the getters of a store while keeping writable and readonly properties. **Internal type DO NOT USE**. + */ +declare type _ToComputedRefs = { + [K in keyof SS]: true extends _IsReadonly ? ComputedRef : WritableComputedRef; +}; + +/** + * Extracts the refs of a state object from a store. If the state value is a Ref or type that extends ref, it will be kept as is. + * Otherwise, it will be converted into a Ref. **Internal type DO NOT USE**. + */ +declare type _ToStateRefs = SS extends Store, _ActionsTree> ? UnwrappedState extends _UnwrapAll> ? { + [K in Key]: ToRef; +} : ToRefs : ToRefs>; + +/** + * Type that enables refactoring through IDE. + * For internal use **only** + */ +export declare type _UnwrapAll = { + [K in keyof SS]: UnwrapRef; +}; + +export { } + +// Extensions of Vue types to be appended manually +// https://github.com/microsoft/rushstack/issues/2090 +// https://github.com/microsoft/rushstack/issues/1709 + +// @ts-ignore: works on Vue 2, fails in Vue 3 +declare module 'vue/types/vue' { + interface Vue { + /** + * Currently installed pinia instance. + */ + $pinia: Pinia + + /** + * Cache of stores instantiated by the current instance. Used by map + * helpers. Used internally by Pinia. + * + * @internal + */ + _pStores?: Record + } +} + +// @ts-ignore: works on Vue 2, fails in Vue 3 +declare module 'vue/types/options' { + interface ComponentOptions { + /** + * Pinia instance to install in your application. Should be passed to the + * root Vue. + */ + pinia?: Pinia + } +} + +/** + * NOTE: Used to be `@vue/runtime-core` but it break types from time to time. Then, in Vue docs, we started recommending + * to use `vue` instead of `@vue/runtime-core` but that broke others' types so we reverted it. Now, local types do not + * work if we use `@vue/runtime-core` so we are using `vue` again. + */ +// @ts-ignore: works on Vue 3, fails in Vue 2 +declare module 'vue' { + // This seems to be needed to not break auto import types based on the order + // https://github.com/vuejs/pinia/pull/2730 + interface GlobalComponents {} + interface ComponentCustomProperties { + /** + * Access to the application's Pinia + */ + $pinia: Pinia + + /** + * Cache of stores instantiated by the current instance. Used by devtools to + * list currently used stores. Used internally by Pinia. + * + * @internal + */ + _pStores?: Record + } +} + +// normally this is only needed in .d.ts files +export {} diff --git a/node_modules/pinia/dist/pinia.esm-browser.js b/node_modules/pinia/dist/pinia.esm-browser.js new file mode 100644 index 0000000..6d4a215 --- /dev/null +++ b/node_modules/pinia/dist/pinia.esm-browser.js @@ -0,0 +1,2035 @@ +/*! + * pinia v2.2.5 + * (c) 2024 Eduardo San Martin Morote + * @license MIT + */ +import { hasInjectionContext, inject, toRaw, watch, unref, markRaw, effectScope, ref, isVue2, isRef, isReactive, set, getCurrentScope, onScopeDispose, getCurrentInstance, reactive, toRef, del, nextTick, computed, toRefs } from 'vue-demi'; +import { setupDevtoolsPlugin } from '@vue/devtools-api'; + +/** + * setActivePinia must be called to handle SSR at the top of functions like + * `fetch`, `setup`, `serverPrefetch` and others + */ +let activePinia; +/** + * Sets or unsets the active pinia. Used in SSR and internally when calling + * actions and getters + * + * @param pinia - Pinia instance + */ +// @ts-expect-error: cannot constrain the type of the return +const setActivePinia = (pinia) => (activePinia = pinia); +/** + * Get the currently active pinia if there is any. + */ +const getActivePinia = () => (hasInjectionContext() && inject(piniaSymbol)) || activePinia; +const piniaSymbol = (Symbol('pinia') ); + +function isPlainObject( +// eslint-disable-next-line @typescript-eslint/no-explicit-any +o) { + return (o && + typeof o === 'object' && + Object.prototype.toString.call(o) === '[object Object]' && + typeof o.toJSON !== 'function'); +} +// type DeepReadonly = { readonly [P in keyof T]: DeepReadonly } +// TODO: can we change these to numbers? +/** + * Possible types for SubscriptionCallback + */ +var MutationType; +(function (MutationType) { + /** + * Direct mutation of the state: + * + * - `store.name = 'new name'` + * - `store.$state.name = 'new name'` + * - `store.list.push('new item')` + */ + MutationType["direct"] = "direct"; + /** + * Mutated the state with `$patch` and an object + * + * - `store.$patch({ name: 'newName' })` + */ + MutationType["patchObject"] = "patch object"; + /** + * Mutated the state with `$patch` and a function + * + * - `store.$patch(state => state.name = 'newName')` + */ + MutationType["patchFunction"] = "patch function"; + // maybe reset? for $state = {} and $reset +})(MutationType || (MutationType = {})); + +const IS_CLIENT = typeof window !== 'undefined'; + +/* + * FileSaver.js A saveAs() FileSaver implementation. + * + * Originally by Eli Grey, adapted as an ESM module by Eduardo San Martin + * Morote. + * + * License : MIT + */ +// The one and only way of getting global scope in all environments +// https://stackoverflow.com/q/3277182/1008999 +const _global = /*#__PURE__*/ (() => typeof window === 'object' && window.window === window + ? window + : typeof self === 'object' && self.self === self + ? self + : typeof global === 'object' && global.global === global + ? global + : typeof globalThis === 'object' + ? globalThis + : { HTMLElement: null })(); +function bom(blob, { autoBom = false } = {}) { + // prepend BOM for UTF-8 XML and text/* types (including HTML) + // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF + if (autoBom && + /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { + return new Blob([String.fromCharCode(0xfeff), blob], { type: blob.type }); + } + return blob; +} +function download(url, name, opts) { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'blob'; + xhr.onload = function () { + saveAs(xhr.response, name, opts); + }; + xhr.onerror = function () { + console.error('could not download file'); + }; + xhr.send(); +} +function corsEnabled(url) { + const xhr = new XMLHttpRequest(); + // use sync to avoid popup blocker + xhr.open('HEAD', url, false); + try { + xhr.send(); + } + catch (e) { } + return xhr.status >= 200 && xhr.status <= 299; +} +// `a.click()` doesn't work for all browsers (#465) +function click(node) { + try { + node.dispatchEvent(new MouseEvent('click')); + } + catch (e) { + const evt = document.createEvent('MouseEvents'); + evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null); + node.dispatchEvent(evt); + } +} +const _navigator = typeof navigator === 'object' ? navigator : { userAgent: '' }; +// Detect WebView inside a native macOS app by ruling out all browsers +// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too +// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos +const isMacOSWebView = /*#__PURE__*/ (() => /Macintosh/.test(_navigator.userAgent) && + /AppleWebKit/.test(_navigator.userAgent) && + !/Safari/.test(_navigator.userAgent))(); +const saveAs = !IS_CLIENT + ? () => { } // noop + : // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView or mini program + typeof HTMLAnchorElement !== 'undefined' && + 'download' in HTMLAnchorElement.prototype && + !isMacOSWebView + ? downloadSaveAs + : // Use msSaveOrOpenBlob as a second approach + 'msSaveOrOpenBlob' in _navigator + ? msSaveAs + : // Fallback to using FileReader and a popup + fileSaverSaveAs; +function downloadSaveAs(blob, name = 'download', opts) { + const a = document.createElement('a'); + a.download = name; + a.rel = 'noopener'; // tabnabbing + // TODO: detect chrome extensions & packaged apps + // a.target = '_blank' + if (typeof blob === 'string') { + // Support regular links + a.href = blob; + if (a.origin !== location.origin) { + if (corsEnabled(a.href)) { + download(blob, name, opts); + } + else { + a.target = '_blank'; + click(a); + } + } + else { + click(a); + } + } + else { + // Support blobs + a.href = URL.createObjectURL(blob); + setTimeout(function () { + URL.revokeObjectURL(a.href); + }, 4e4); // 40s + setTimeout(function () { + click(a); + }, 0); + } +} +function msSaveAs(blob, name = 'download', opts) { + if (typeof blob === 'string') { + if (corsEnabled(blob)) { + download(blob, name, opts); + } + else { + const a = document.createElement('a'); + a.href = blob; + a.target = '_blank'; + setTimeout(function () { + click(a); + }); + } + } + else { + // @ts-ignore: works on windows + navigator.msSaveOrOpenBlob(bom(blob, opts), name); + } +} +function fileSaverSaveAs(blob, name, opts, popup) { + // Open a popup immediately do go around popup blocker + // Mostly only available on user interaction and the fileReader is async so... + popup = popup || open('', '_blank'); + if (popup) { + popup.document.title = popup.document.body.innerText = 'downloading...'; + } + if (typeof blob === 'string') + return download(blob, name, opts); + const force = blob.type === 'application/octet-stream'; + const isSafari = /constructor/i.test(String(_global.HTMLElement)) || 'safari' in _global; + const isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent); + if ((isChromeIOS || (force && isSafari) || isMacOSWebView) && + typeof FileReader !== 'undefined') { + // Safari doesn't allow downloading of blob URLs + const reader = new FileReader(); + reader.onloadend = function () { + let url = reader.result; + if (typeof url !== 'string') { + popup = null; + throw new Error('Wrong reader.result type'); + } + url = isChromeIOS + ? url + : url.replace(/^data:[^;]*;/, 'data:attachment/file;'); + if (popup) { + popup.location.href = url; + } + else { + location.assign(url); + } + popup = null; // reverse-tabnabbing #460 + }; + reader.readAsDataURL(blob); + } + else { + const url = URL.createObjectURL(blob); + if (popup) + popup.location.assign(url); + else + location.href = url; + popup = null; // reverse-tabnabbing #460 + setTimeout(function () { + URL.revokeObjectURL(url); + }, 4e4); // 40s + } +} + +/** + * Shows a toast or console.log + * + * @param message - message to log + * @param type - different color of the tooltip + */ +function toastMessage(message, type) { + const piniaMessage = '🍍 ' + message; + if (typeof __VUE_DEVTOOLS_TOAST__ === 'function') { + // No longer available :( + __VUE_DEVTOOLS_TOAST__(piniaMessage, type); + } + else if (type === 'error') { + console.error(piniaMessage); + } + else if (type === 'warn') { + console.warn(piniaMessage); + } + else { + console.log(piniaMessage); + } +} +function isPinia(o) { + return '_a' in o && 'install' in o; +} + +/** + * This file contain devtools actions, they are not Pinia actions. + */ +// --- +function checkClipboardAccess() { + if (!('clipboard' in navigator)) { + toastMessage(`Your browser doesn't support the Clipboard API`, 'error'); + return true; + } +} +function checkNotFocusedError(error) { + if (error instanceof Error && + error.message.toLowerCase().includes('document is not focused')) { + toastMessage('You need to activate the "Emulate a focused page" setting in the "Rendering" panel of devtools.', 'warn'); + return true; + } + return false; +} +async function actionGlobalCopyState(pinia) { + if (checkClipboardAccess()) + return; + try { + await navigator.clipboard.writeText(JSON.stringify(pinia.state.value)); + toastMessage('Global state copied to clipboard.'); + } + catch (error) { + if (checkNotFocusedError(error)) + return; + toastMessage(`Failed to serialize the state. Check the console for more details.`, 'error'); + console.error(error); + } +} +async function actionGlobalPasteState(pinia) { + if (checkClipboardAccess()) + return; + try { + loadStoresState(pinia, JSON.parse(await navigator.clipboard.readText())); + toastMessage('Global state pasted from clipboard.'); + } + catch (error) { + if (checkNotFocusedError(error)) + return; + toastMessage(`Failed to deserialize the state from clipboard. Check the console for more details.`, 'error'); + console.error(error); + } +} +async function actionGlobalSaveState(pinia) { + try { + saveAs(new Blob([JSON.stringify(pinia.state.value)], { + type: 'text/plain;charset=utf-8', + }), 'pinia-state.json'); + } + catch (error) { + toastMessage(`Failed to export the state as JSON. Check the console for more details.`, 'error'); + console.error(error); + } +} +let fileInput; +function getFileOpener() { + if (!fileInput) { + fileInput = document.createElement('input'); + fileInput.type = 'file'; + fileInput.accept = '.json'; + } + function openFile() { + return new Promise((resolve, reject) => { + fileInput.onchange = async () => { + const files = fileInput.files; + if (!files) + return resolve(null); + const file = files.item(0); + if (!file) + return resolve(null); + return resolve({ text: await file.text(), file }); + }; + // @ts-ignore: TODO: changed from 4.3 to 4.4 + fileInput.oncancel = () => resolve(null); + fileInput.onerror = reject; + fileInput.click(); + }); + } + return openFile; +} +async function actionGlobalOpenStateFile(pinia) { + try { + const open = getFileOpener(); + const result = await open(); + if (!result) + return; + const { text, file } = result; + loadStoresState(pinia, JSON.parse(text)); + toastMessage(`Global state imported from "${file.name}".`); + } + catch (error) { + toastMessage(`Failed to import the state from JSON. Check the console for more details.`, 'error'); + console.error(error); + } +} +function loadStoresState(pinia, state) { + for (const key in state) { + const storeState = pinia.state.value[key]; + // store is already instantiated, patch it + if (storeState) { + Object.assign(storeState, state[key]); + } + else { + // store is not instantiated, set the initial state + pinia.state.value[key] = state[key]; + } + } +} + +function formatDisplay(display) { + return { + _custom: { + display, + }, + }; +} +const PINIA_ROOT_LABEL = '🍍 Pinia (root)'; +const PINIA_ROOT_ID = '_root'; +function formatStoreForInspectorTree(store) { + return isPinia(store) + ? { + id: PINIA_ROOT_ID, + label: PINIA_ROOT_LABEL, + } + : { + id: store.$id, + label: store.$id, + }; +} +function formatStoreForInspectorState(store) { + if (isPinia(store)) { + const storeNames = Array.from(store._s.keys()); + const storeMap = store._s; + const state = { + state: storeNames.map((storeId) => ({ + editable: true, + key: storeId, + value: store.state.value[storeId], + })), + getters: storeNames + .filter((id) => storeMap.get(id)._getters) + .map((id) => { + const store = storeMap.get(id); + return { + editable: false, + key: id, + value: store._getters.reduce((getters, key) => { + getters[key] = store[key]; + return getters; + }, {}), + }; + }), + }; + return state; + } + const state = { + state: Object.keys(store.$state).map((key) => ({ + editable: true, + key, + value: store.$state[key], + })), + }; + // avoid adding empty getters + if (store._getters && store._getters.length) { + state.getters = store._getters.map((getterName) => ({ + editable: false, + key: getterName, + value: store[getterName], + })); + } + if (store._customProperties.size) { + state.customProperties = Array.from(store._customProperties).map((key) => ({ + editable: true, + key, + value: store[key], + })); + } + return state; +} +function formatEventData(events) { + if (!events) + return {}; + if (Array.isArray(events)) { + // TODO: handle add and delete for arrays and objects + return events.reduce((data, event) => { + data.keys.push(event.key); + data.operations.push(event.type); + data.oldValue[event.key] = event.oldValue; + data.newValue[event.key] = event.newValue; + return data; + }, { + oldValue: {}, + keys: [], + operations: [], + newValue: {}, + }); + } + else { + return { + operation: formatDisplay(events.type), + key: formatDisplay(events.key), + oldValue: events.oldValue, + newValue: events.newValue, + }; + } +} +function formatMutationType(type) { + switch (type) { + case MutationType.direct: + return 'mutation'; + case MutationType.patchFunction: + return '$patch'; + case MutationType.patchObject: + return '$patch'; + default: + return 'unknown'; + } +} + +// timeline can be paused when directly changing the state +let isTimelineActive = true; +const componentStateTypes = []; +const MUTATIONS_LAYER_ID = 'pinia:mutations'; +const INSPECTOR_ID = 'pinia'; +const { assign: assign$1 } = Object; +/** + * Gets the displayed name of a store in devtools + * + * @param id - id of the store + * @returns a formatted string + */ +const getStoreType = (id) => '🍍 ' + id; +/** + * Add the pinia plugin without any store. Allows displaying a Pinia plugin tab + * as soon as it is added to the application. + * + * @param app - Vue application + * @param pinia - pinia instance + */ +function registerPiniaDevtools(app, pinia) { + setupDevtoolsPlugin({ + id: 'dev.esm.pinia', + label: 'Pinia 🍍', + logo: 'https://pinia.vuejs.org/logo.svg', + packageName: 'pinia', + homepage: 'https://pinia.vuejs.org', + componentStateTypes, + app, + }, (api) => { + if (typeof api.now !== 'function') { + toastMessage('You seem to be using an outdated version of Vue Devtools. Are you still using the Beta release instead of the stable one? You can find the links at https://devtools.vuejs.org/guide/installation.html.'); + } + api.addTimelineLayer({ + id: MUTATIONS_LAYER_ID, + label: `Pinia 🍍`, + color: 0xe5df88, + }); + api.addInspector({ + id: INSPECTOR_ID, + label: 'Pinia 🍍', + icon: 'storage', + treeFilterPlaceholder: 'Search stores', + actions: [ + { + icon: 'content_copy', + action: () => { + actionGlobalCopyState(pinia); + }, + tooltip: 'Serialize and copy the state', + }, + { + icon: 'content_paste', + action: async () => { + await actionGlobalPasteState(pinia); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + }, + tooltip: 'Replace the state with the content of your clipboard', + }, + { + icon: 'save', + action: () => { + actionGlobalSaveState(pinia); + }, + tooltip: 'Save the state as a JSON file', + }, + { + icon: 'folder_open', + action: async () => { + await actionGlobalOpenStateFile(pinia); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + }, + tooltip: 'Import the state from a JSON file', + }, + ], + nodeActions: [ + { + icon: 'restore', + tooltip: 'Reset the state (with "$reset")', + action: (nodeId) => { + const store = pinia._s.get(nodeId); + if (!store) { + toastMessage(`Cannot reset "${nodeId}" store because it wasn't found.`, 'warn'); + } + else if (typeof store.$reset !== 'function') { + toastMessage(`Cannot reset "${nodeId}" store because it doesn't have a "$reset" method implemented.`, 'warn'); + } + else { + store.$reset(); + toastMessage(`Store "${nodeId}" reset.`); + } + }, + }, + ], + }); + api.on.inspectComponent((payload, ctx) => { + const proxy = (payload.componentInstance && + payload.componentInstance.proxy); + if (proxy && proxy._pStores) { + const piniaStores = payload.componentInstance.proxy._pStores; + Object.values(piniaStores).forEach((store) => { + payload.instanceData.state.push({ + type: getStoreType(store.$id), + key: 'state', + editable: true, + value: store._isOptionsAPI + ? { + _custom: { + value: toRaw(store.$state), + actions: [ + { + icon: 'restore', + tooltip: 'Reset the state of this store', + action: () => store.$reset(), + }, + ], + }, + } + : // NOTE: workaround to unwrap transferred refs + Object.keys(store.$state).reduce((state, key) => { + state[key] = store.$state[key]; + return state; + }, {}), + }); + if (store._getters && store._getters.length) { + payload.instanceData.state.push({ + type: getStoreType(store.$id), + key: 'getters', + editable: false, + value: store._getters.reduce((getters, key) => { + try { + getters[key] = store[key]; + } + catch (error) { + // @ts-expect-error: we just want to show it in devtools + getters[key] = error; + } + return getters; + }, {}), + }); + } + }); + } + }); + api.on.getInspectorTree((payload) => { + if (payload.app === app && payload.inspectorId === INSPECTOR_ID) { + let stores = [pinia]; + stores = stores.concat(Array.from(pinia._s.values())); + payload.rootNodes = (payload.filter + ? stores.filter((store) => '$id' in store + ? store.$id + .toLowerCase() + .includes(payload.filter.toLowerCase()) + : PINIA_ROOT_LABEL.toLowerCase().includes(payload.filter.toLowerCase())) + : stores).map(formatStoreForInspectorTree); + } + }); + // Expose pinia instance as $pinia to window + globalThis.$pinia = pinia; + api.on.getInspectorState((payload) => { + if (payload.app === app && payload.inspectorId === INSPECTOR_ID) { + const inspectedStore = payload.nodeId === PINIA_ROOT_ID + ? pinia + : pinia._s.get(payload.nodeId); + if (!inspectedStore) { + // this could be the selected store restored for a different project + // so it's better not to say anything here + return; + } + if (inspectedStore) { + // Expose selected store as $store to window + if (payload.nodeId !== PINIA_ROOT_ID) + globalThis.$store = toRaw(inspectedStore); + payload.state = formatStoreForInspectorState(inspectedStore); + } + } + }); + api.on.editInspectorState((payload, ctx) => { + if (payload.app === app && payload.inspectorId === INSPECTOR_ID) { + const inspectedStore = payload.nodeId === PINIA_ROOT_ID + ? pinia + : pinia._s.get(payload.nodeId); + if (!inspectedStore) { + return toastMessage(`store "${payload.nodeId}" not found`, 'error'); + } + const { path } = payload; + if (!isPinia(inspectedStore)) { + // access only the state + if (path.length !== 1 || + !inspectedStore._customProperties.has(path[0]) || + path[0] in inspectedStore.$state) { + path.unshift('$state'); + } + } + else { + // Root access, we can omit the `.value` because the devtools API does it for us + path.unshift('state'); + } + isTimelineActive = false; + payload.set(inspectedStore, path, payload.state.value); + isTimelineActive = true; + } + }); + api.on.editComponentState((payload) => { + if (payload.type.startsWith('🍍')) { + const storeId = payload.type.replace(/^🍍\s*/, ''); + const store = pinia._s.get(storeId); + if (!store) { + return toastMessage(`store "${storeId}" not found`, 'error'); + } + const { path } = payload; + if (path[0] !== 'state') { + return toastMessage(`Invalid path for store "${storeId}":\n${path}\nOnly state can be modified.`); + } + // rewrite the first entry to be able to directly set the state as + // well as any other path + path[0] = '$state'; + isTimelineActive = false; + payload.set(store, path, payload.state.value); + isTimelineActive = true; + } + }); + }); +} +function addStoreToDevtools(app, store) { + if (!componentStateTypes.includes(getStoreType(store.$id))) { + componentStateTypes.push(getStoreType(store.$id)); + } + setupDevtoolsPlugin({ + id: 'dev.esm.pinia', + label: 'Pinia 🍍', + logo: 'https://pinia.vuejs.org/logo.svg', + packageName: 'pinia', + homepage: 'https://pinia.vuejs.org', + componentStateTypes, + app, + settings: { + logStoreChanges: { + label: 'Notify about new/deleted stores', + type: 'boolean', + defaultValue: true, + }, + // useEmojis: { + // label: 'Use emojis in messages ⚡️', + // type: 'boolean', + // defaultValue: true, + // }, + }, + }, (api) => { + // gracefully handle errors + const now = typeof api.now === 'function' ? api.now.bind(api) : Date.now; + store.$onAction(({ after, onError, name, args }) => { + const groupId = runningActionId++; + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: '🛫 ' + name, + subtitle: 'start', + data: { + store: formatDisplay(store.$id), + action: formatDisplay(name), + args, + }, + groupId, + }, + }); + after((result) => { + activeAction = undefined; + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: '🛬 ' + name, + subtitle: 'end', + data: { + store: formatDisplay(store.$id), + action: formatDisplay(name), + args, + result, + }, + groupId, + }, + }); + }); + onError((error) => { + activeAction = undefined; + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + logType: 'error', + title: '💥 ' + name, + subtitle: 'end', + data: { + store: formatDisplay(store.$id), + action: formatDisplay(name), + args, + error, + }, + groupId, + }, + }); + }); + }, true); + store._customProperties.forEach((name) => { + watch(() => unref(store[name]), (newValue, oldValue) => { + api.notifyComponentUpdate(); + api.sendInspectorState(INSPECTOR_ID); + if (isTimelineActive) { + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: 'Change', + subtitle: name, + data: { + newValue, + oldValue, + }, + groupId: activeAction, + }, + }); + } + }, { deep: true }); + }); + store.$subscribe(({ events, type }, state) => { + api.notifyComponentUpdate(); + api.sendInspectorState(INSPECTOR_ID); + if (!isTimelineActive) + return; + // rootStore.state[store.id] = state + const eventData = { + time: now(), + title: formatMutationType(type), + data: assign$1({ store: formatDisplay(store.$id) }, formatEventData(events)), + groupId: activeAction, + }; + if (type === MutationType.patchFunction) { + eventData.subtitle = '⤵️'; + } + else if (type === MutationType.patchObject) { + eventData.subtitle = '🧩'; + } + else if (events && !Array.isArray(events)) { + eventData.subtitle = events.type; + } + if (events) { + eventData.data['rawEvent(s)'] = { + _custom: { + display: 'DebuggerEvent', + type: 'object', + tooltip: 'raw DebuggerEvent[]', + value: events, + }, + }; + } + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: eventData, + }); + }, { detached: true, flush: 'sync' }); + const hotUpdate = store._hotUpdate; + store._hotUpdate = markRaw((newStore) => { + hotUpdate(newStore); + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: '🔥 ' + store.$id, + subtitle: 'HMR update', + data: { + store: formatDisplay(store.$id), + info: formatDisplay(`HMR update`), + }, + }, + }); + // update the devtools too + api.notifyComponentUpdate(); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + }); + const { $dispose } = store; + store.$dispose = () => { + $dispose(); + api.notifyComponentUpdate(); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + api.getSettings().logStoreChanges && + toastMessage(`Disposed "${store.$id}" store 🗑`); + }; + // trigger an update so it can display new registered stores + api.notifyComponentUpdate(); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + api.getSettings().logStoreChanges && + toastMessage(`"${store.$id}" store installed 🆕`); + }); +} +let runningActionId = 0; +let activeAction; +/** + * Patches a store to enable action grouping in devtools by wrapping the store with a Proxy that is passed as the + * context of all actions, allowing us to set `runningAction` on each access and effectively associating any state + * mutation to the action. + * + * @param store - store to patch + * @param actionNames - list of actionst to patch + */ +function patchActionForGrouping(store, actionNames, wrapWithProxy) { + // original actions of the store as they are given by pinia. We are going to override them + const actions = actionNames.reduce((storeActions, actionName) => { + // use toRaw to avoid tracking #541 + storeActions[actionName] = toRaw(store)[actionName]; + return storeActions; + }, {}); + for (const actionName in actions) { + store[actionName] = function () { + // the running action id is incremented in a before action hook + const _actionId = runningActionId; + const trackedStore = wrapWithProxy + ? new Proxy(store, { + get(...args) { + activeAction = _actionId; + return Reflect.get(...args); + }, + set(...args) { + activeAction = _actionId; + return Reflect.set(...args); + }, + }) + : store; + // For Setup Stores we need https://github.com/tc39/proposal-async-context + activeAction = _actionId; + const retValue = actions[actionName].apply(trackedStore, arguments); + // this is safer as async actions in Setup Stores would associate mutations done outside of the action + activeAction = undefined; + return retValue; + }; + } +} +/** + * pinia.use(devtoolsPlugin) + */ +function devtoolsPlugin({ app, store, options }) { + // HMR module + if (store.$id.startsWith('__hot:')) { + return; + } + // detect option api vs setup api + store._isOptionsAPI = !!options.state; + // Do not overwrite actions mocked by @pinia/testing (#2298) + if (!store._p._testing) { + patchActionForGrouping(store, Object.keys(options.actions), store._isOptionsAPI); + // Upgrade the HMR to also update the new actions + const originalHotUpdate = store._hotUpdate; + toRaw(store)._hotUpdate = function (newStore) { + originalHotUpdate.apply(this, arguments); + patchActionForGrouping(store, Object.keys(newStore._hmrPayload.actions), !!store._isOptionsAPI); + }; + } + addStoreToDevtools(app, + // FIXME: is there a way to allow the assignment from Store to StoreGeneric? + store); +} + +/** + * Creates a Pinia instance to be used by the application + */ +function createPinia() { + const scope = effectScope(true); + // NOTE: here we could check the window object for a state and directly set it + // if there is anything like it with Vue 3 SSR + const state = scope.run(() => ref({})); + let _p = []; + // plugins added before calling app.use(pinia) + let toBeInstalled = []; + const pinia = markRaw({ + install(app) { + // this allows calling useStore() outside of a component setup after + // installing pinia's plugin + setActivePinia(pinia); + if (!isVue2) { + pinia._a = app; + app.provide(piniaSymbol, pinia); + app.config.globalProperties.$pinia = pinia; + /* istanbul ignore else */ + if (IS_CLIENT) { + registerPiniaDevtools(app, pinia); + } + toBeInstalled.forEach((plugin) => _p.push(plugin)); + toBeInstalled = []; + } + }, + use(plugin) { + if (!this._a && !isVue2) { + toBeInstalled.push(plugin); + } + else { + _p.push(plugin); + } + return this; + }, + _p, + // it's actually undefined here + // @ts-expect-error + _a: null, + _e: scope, + _s: new Map(), + state, + }); + // pinia devtools rely on dev only features so they cannot be forced unless + // the dev build of Vue is used. Avoid old browsers like IE11. + if (typeof Proxy !== 'undefined') { + pinia.use(devtoolsPlugin); + } + return pinia; +} +/** + * Dispose a Pinia instance by stopping its effectScope and removing the state, plugins and stores. This is mostly + * useful in tests, with both a testing pinia or a regular pinia and in applications that use multiple pinia instances. + * Once disposed, the pinia instance cannot be used anymore. + * + * @param pinia - pinia instance + */ +function disposePinia(pinia) { + pinia._e.stop(); + pinia._s.clear(); + pinia._p.splice(0); + pinia.state.value = {}; + // @ts-expect-error: non valid + pinia._a = null; +} + +/** + * Checks if a function is a `StoreDefinition`. + * + * @param fn - object to test + * @returns true if `fn` is a StoreDefinition + */ +const isUseStore = (fn) => { + return typeof fn === 'function' && typeof fn.$id === 'string'; +}; +/** + * Mutates in place `newState` with `oldState` to _hot update_ it. It will + * remove any key not existing in `newState` and recursively merge plain + * objects. + * + * @param newState - new state object to be patched + * @param oldState - old state that should be used to patch newState + * @returns - newState + */ +function patchObject(newState, oldState) { + // no need to go through symbols because they cannot be serialized anyway + for (const key in oldState) { + const subPatch = oldState[key]; + // skip the whole sub tree + if (!(key in newState)) { + continue; + } + const targetValue = newState[key]; + if (isPlainObject(targetValue) && + isPlainObject(subPatch) && + !isRef(subPatch) && + !isReactive(subPatch)) { + newState[key] = patchObject(targetValue, subPatch); + } + else { + // objects are either a bit more complex (e.g. refs) or primitives, so we + // just set the whole thing + if (isVue2) { + set(newState, key, subPatch); + } + else { + newState[key] = subPatch; + } + } + } + return newState; +} +/** + * Creates an _accept_ function to pass to `import.meta.hot` in Vite applications. + * + * @example + * ```js + * const useUser = defineStore(...) + * if (import.meta.hot) { + * import.meta.hot.accept(acceptHMRUpdate(useUser, import.meta.hot)) + * } + * ``` + * + * @param initialUseStore - return of the defineStore to hot update + * @param hot - `import.meta.hot` + */ +function acceptHMRUpdate(initialUseStore, hot) { + return (newModule) => { + const pinia = hot.data.pinia || initialUseStore._pinia; + if (!pinia) { + // this store is still not used + return; + } + // preserve the pinia instance across loads + hot.data.pinia = pinia; + // console.log('got data', newStore) + for (const exportName in newModule) { + const useStore = newModule[exportName]; + // console.log('checking for', exportName) + if (isUseStore(useStore) && pinia._s.has(useStore.$id)) { + // console.log('Accepting update for', useStore.$id) + const id = useStore.$id; + if (id !== initialUseStore.$id) { + console.warn(`The id of the store changed from "${initialUseStore.$id}" to "${id}". Reloading.`); + // return import.meta.hot.invalidate() + return hot.invalidate(); + } + const existingStore = pinia._s.get(id); + if (!existingStore) { + console.log(`[Pinia]: skipping hmr because store doesn't exist yet`); + return; + } + useStore(pinia, existingStore); + } + } + }; +} + +const noop = () => { }; +function addSubscription(subscriptions, callback, detached, onCleanup = noop) { + subscriptions.push(callback); + const removeSubscription = () => { + const idx = subscriptions.indexOf(callback); + if (idx > -1) { + subscriptions.splice(idx, 1); + onCleanup(); + } + }; + if (!detached && getCurrentScope()) { + onScopeDispose(removeSubscription); + } + return removeSubscription; +} +function triggerSubscriptions(subscriptions, ...args) { + subscriptions.slice().forEach((callback) => { + callback(...args); + }); +} + +const fallbackRunWithContext = (fn) => fn(); +/** + * Marks a function as an action for `$onAction` + * @internal + */ +const ACTION_MARKER = Symbol(); +/** + * Action name symbol. Allows to add a name to an action after defining it + * @internal + */ +const ACTION_NAME = Symbol(); +function mergeReactiveObjects(target, patchToApply) { + // Handle Map instances + if (target instanceof Map && patchToApply instanceof Map) { + patchToApply.forEach((value, key) => target.set(key, value)); + } + else if (target instanceof Set && patchToApply instanceof Set) { + // Handle Set instances + patchToApply.forEach(target.add, target); + } + // no need to go through symbols because they cannot be serialized anyway + for (const key in patchToApply) { + if (!patchToApply.hasOwnProperty(key)) + continue; + const subPatch = patchToApply[key]; + const targetValue = target[key]; + if (isPlainObject(targetValue) && + isPlainObject(subPatch) && + target.hasOwnProperty(key) && + !isRef(subPatch) && + !isReactive(subPatch)) { + // NOTE: here I wanted to warn about inconsistent types but it's not possible because in setup stores one might + // start the value of a property as a certain type e.g. a Map, and then for some reason, during SSR, change that + // to `undefined`. When trying to hydrate, we want to override the Map with `undefined`. + target[key] = mergeReactiveObjects(targetValue, subPatch); + } + else { + // @ts-expect-error: subPatch is a valid value + target[key] = subPatch; + } + } + return target; +} +const skipHydrateSymbol = Symbol('pinia:skipHydration') + ; +const skipHydrateMap = /*#__PURE__*/ new WeakMap(); +/** + * Tells Pinia to skip the hydration process of a given object. This is useful in setup stores (only) when you return a + * stateful object in the store but it isn't really state. e.g. returning a router instance in a setup store. + * + * @param obj - target object + * @returns obj + */ +function skipHydrate(obj) { + return isVue2 + ? // in @vue/composition-api, the refs are sealed so defineProperty doesn't work... + /* istanbul ignore next */ skipHydrateMap.set(obj, 1) && obj + : Object.defineProperty(obj, skipHydrateSymbol, {}); +} +/** + * Returns whether a value should be hydrated + * + * @param obj - target variable + * @returns true if `obj` should be hydrated + */ +function shouldHydrate(obj) { + return isVue2 + ? /* istanbul ignore next */ !skipHydrateMap.has(obj) + : !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol); +} +const { assign } = Object; +function isComputed(o) { + return !!(isRef(o) && o.effect); +} +function createOptionsStore(id, options, pinia, hot) { + const { state, actions, getters } = options; + const initialState = pinia.state.value[id]; + let store; + function setup() { + if (!initialState && (!hot)) { + /* istanbul ignore if */ + if (isVue2) { + set(pinia.state.value, id, state ? state() : {}); + } + else { + pinia.state.value[id] = state ? state() : {}; + } + } + // avoid creating a state in pinia.state.value + const localState = hot + ? // use ref() to unwrap refs inside state TODO: check if this is still necessary + toRefs(ref(state ? state() : {}).value) + : toRefs(pinia.state.value[id]); + return assign(localState, actions, Object.keys(getters || {}).reduce((computedGetters, name) => { + if (name in localState) { + console.warn(`[🍍]: A getter cannot have the same name as another state property. Rename one of them. Found with "${name}" in store "${id}".`); + } + computedGetters[name] = markRaw(computed(() => { + setActivePinia(pinia); + // it was created just before + const store = pinia._s.get(id); + // allow cross using stores + /* istanbul ignore if */ + if (isVue2 && !store._r) + return; + // @ts-expect-error + // return getters![name].call(context, context) + // TODO: avoid reading the getter while assigning with a global variable + return getters[name].call(store, store); + })); + return computedGetters; + }, {})); + } + store = createSetupStore(id, setup, options, pinia, hot, true); + return store; +} +function createSetupStore($id, setup, options = {}, pinia, hot, isOptionsStore) { + let scope; + const optionsForPlugin = assign({ actions: {} }, options); + /* istanbul ignore if */ + if (!pinia._e.active) { + throw new Error('Pinia destroyed'); + } + // watcher options for $subscribe + const $subscribeOptions = { deep: true }; + /* istanbul ignore else */ + if (!isVue2) { + $subscribeOptions.onTrigger = (event) => { + /* istanbul ignore else */ + if (isListening) { + debuggerEvents = event; + // avoid triggering this while the store is being built and the state is being set in pinia + } + else if (isListening == false && !store._hotUpdating) { + // let patch send all the events together later + /* istanbul ignore else */ + if (Array.isArray(debuggerEvents)) { + debuggerEvents.push(event); + } + else { + console.error('🍍 debuggerEvents should be an array. This is most likely an internal Pinia bug.'); + } + } + }; + } + // internal state + let isListening; // set to true at the end + let isSyncListening; // set to true at the end + let subscriptions = []; + let actionSubscriptions = []; + let debuggerEvents; + const initialState = pinia.state.value[$id]; + // avoid setting the state for option stores if it is set + // by the setup + if (!isOptionsStore && !initialState && (!hot)) { + /* istanbul ignore if */ + if (isVue2) { + set(pinia.state.value, $id, {}); + } + else { + pinia.state.value[$id] = {}; + } + } + const hotState = ref({}); + // avoid triggering too many listeners + // https://github.com/vuejs/pinia/issues/1129 + let activeListener; + function $patch(partialStateOrMutator) { + let subscriptionMutation; + isListening = isSyncListening = false; + // reset the debugger events since patches are sync + /* istanbul ignore else */ + { + debuggerEvents = []; + } + if (typeof partialStateOrMutator === 'function') { + partialStateOrMutator(pinia.state.value[$id]); + subscriptionMutation = { + type: MutationType.patchFunction, + storeId: $id, + events: debuggerEvents, + }; + } + else { + mergeReactiveObjects(pinia.state.value[$id], partialStateOrMutator); + subscriptionMutation = { + type: MutationType.patchObject, + payload: partialStateOrMutator, + storeId: $id, + events: debuggerEvents, + }; + } + const myListenerId = (activeListener = Symbol()); + nextTick().then(() => { + if (activeListener === myListenerId) { + isListening = true; + } + }); + isSyncListening = true; + // because we paused the watcher, we need to manually call the subscriptions + triggerSubscriptions(subscriptions, subscriptionMutation, pinia.state.value[$id]); + } + const $reset = isOptionsStore + ? function $reset() { + const { state } = options; + const newState = state ? state() : {}; + // we use a patch to group all changes into one single subscription + this.$patch(($state) => { + // @ts-expect-error: FIXME: shouldn't error? + assign($state, newState); + }); + } + : /* istanbul ignore next */ + () => { + throw new Error(`🍍: Store "${$id}" is built using the setup syntax and does not implement $reset().`); + } + ; + function $dispose() { + scope.stop(); + subscriptions = []; + actionSubscriptions = []; + pinia._s.delete($id); + } + /** + * Helper that wraps function so it can be tracked with $onAction + * @param fn - action to wrap + * @param name - name of the action + */ + const action = (fn, name = '') => { + if (ACTION_MARKER in fn) { + fn[ACTION_NAME] = name; + return fn; + } + const wrappedAction = function () { + setActivePinia(pinia); + const args = Array.from(arguments); + const afterCallbackList = []; + const onErrorCallbackList = []; + function after(callback) { + afterCallbackList.push(callback); + } + function onError(callback) { + onErrorCallbackList.push(callback); + } + // @ts-expect-error + triggerSubscriptions(actionSubscriptions, { + args, + name: wrappedAction[ACTION_NAME], + store, + after, + onError, + }); + let ret; + try { + ret = fn.apply(this && this.$id === $id ? this : store, args); + // handle sync errors + } + catch (error) { + triggerSubscriptions(onErrorCallbackList, error); + throw error; + } + if (ret instanceof Promise) { + return ret + .then((value) => { + triggerSubscriptions(afterCallbackList, value); + return value; + }) + .catch((error) => { + triggerSubscriptions(onErrorCallbackList, error); + return Promise.reject(error); + }); + } + // trigger after callbacks + triggerSubscriptions(afterCallbackList, ret); + return ret; + }; + wrappedAction[ACTION_MARKER] = true; + wrappedAction[ACTION_NAME] = name; // will be set later + // @ts-expect-error: we are intentionally limiting the returned type to just Fn + // because all the added properties are internals that are exposed through `$onAction()` only + return wrappedAction; + }; + const _hmrPayload = /*#__PURE__*/ markRaw({ + actions: {}, + getters: {}, + state: [], + hotState, + }); + const partialStore = { + _p: pinia, + // _s: scope, + $id, + $onAction: addSubscription.bind(null, actionSubscriptions), + $patch, + $reset, + $subscribe(callback, options = {}) { + const removeSubscription = addSubscription(subscriptions, callback, options.detached, () => stopWatcher()); + const stopWatcher = scope.run(() => watch(() => pinia.state.value[$id], (state) => { + if (options.flush === 'sync' ? isSyncListening : isListening) { + callback({ + storeId: $id, + type: MutationType.direct, + events: debuggerEvents, + }, state); + } + }, assign({}, $subscribeOptions, options))); + return removeSubscription; + }, + $dispose, + }; + /* istanbul ignore if */ + if (isVue2) { + // start as non ready + partialStore._r = false; + } + const store = reactive(assign({ + _hmrPayload, + _customProperties: markRaw(new Set()), // devtools custom properties + }, partialStore + // must be added later + // setupStore + ) + ); + // store the partial store now so the setup of stores can instantiate each other before they are finished without + // creating infinite loops. + pinia._s.set($id, store); + const runWithContext = (pinia._a && pinia._a.runWithContext) || fallbackRunWithContext; + // TODO: idea create skipSerialize that marks properties as non serializable and they are skipped + const setupStore = runWithContext(() => pinia._e.run(() => (scope = effectScope()).run(() => setup({ action })))); + // overwrite existing actions to support $onAction + for (const key in setupStore) { + const prop = setupStore[key]; + if ((isRef(prop) && !isComputed(prop)) || isReactive(prop)) { + // mark it as a piece of state to be serialized + if (hot) { + set(hotState.value, key, toRef(setupStore, key)); + // createOptionStore directly sets the state in pinia.state.value so we + // can just skip that + } + else if (!isOptionsStore) { + // in setup stores we must hydrate the state and sync pinia state tree with the refs the user just created + if (initialState && shouldHydrate(prop)) { + if (isRef(prop)) { + prop.value = initialState[key]; + } + else { + // probably a reactive object, lets recursively assign + // @ts-expect-error: prop is unknown + mergeReactiveObjects(prop, initialState[key]); + } + } + // transfer the ref to the pinia state to keep everything in sync + /* istanbul ignore if */ + if (isVue2) { + set(pinia.state.value[$id], key, prop); + } + else { + pinia.state.value[$id][key] = prop; + } + } + /* istanbul ignore else */ + { + _hmrPayload.state.push(key); + } + // action + } + else if (typeof prop === 'function') { + const actionValue = hot ? prop : action(prop, key); + // this a hot module replacement store because the hotUpdate method needs + // to do it with the right context + /* istanbul ignore if */ + if (isVue2) { + set(setupStore, key, actionValue); + } + else { + // @ts-expect-error + setupStore[key] = actionValue; + } + /* istanbul ignore else */ + { + _hmrPayload.actions[key] = prop; + } + // list actions so they can be used in plugins + // @ts-expect-error + optionsForPlugin.actions[key] = prop; + } + else { + // add getters for devtools + if (isComputed(prop)) { + _hmrPayload.getters[key] = isOptionsStore + ? // @ts-expect-error + options.getters[key] + : prop; + if (IS_CLIENT) { + const getters = setupStore._getters || + // @ts-expect-error: same + (setupStore._getters = markRaw([])); + getters.push(key); + } + } + } + } + // add the state, getters, and action properties + /* istanbul ignore if */ + if (isVue2) { + Object.keys(setupStore).forEach((key) => { + set(store, key, setupStore[key]); + }); + } + else { + assign(store, setupStore); + // allows retrieving reactive objects with `storeToRefs()`. Must be called after assigning to the reactive object. + // Make `storeToRefs()` work with `reactive()` #799 + assign(toRaw(store), setupStore); + } + // use this instead of a computed with setter to be able to create it anywhere + // without linking the computed lifespan to wherever the store is first + // created. + Object.defineProperty(store, '$state', { + get: () => (hot ? hotState.value : pinia.state.value[$id]), + set: (state) => { + /* istanbul ignore if */ + if (hot) { + throw new Error('cannot set hotState'); + } + $patch(($state) => { + // @ts-expect-error: FIXME: shouldn't error? + assign($state, state); + }); + }, + }); + // add the hotUpdate before plugins to allow them to override it + /* istanbul ignore else */ + { + store._hotUpdate = markRaw((newStore) => { + store._hotUpdating = true; + newStore._hmrPayload.state.forEach((stateKey) => { + if (stateKey in store.$state) { + const newStateTarget = newStore.$state[stateKey]; + const oldStateSource = store.$state[stateKey]; + if (typeof newStateTarget === 'object' && + isPlainObject(newStateTarget) && + isPlainObject(oldStateSource)) { + patchObject(newStateTarget, oldStateSource); + } + else { + // transfer the ref + newStore.$state[stateKey] = oldStateSource; + } + } + // patch direct access properties to allow store.stateProperty to work as + // store.$state.stateProperty + set(store, stateKey, toRef(newStore.$state, stateKey)); + }); + // remove deleted state properties + Object.keys(store.$state).forEach((stateKey) => { + if (!(stateKey in newStore.$state)) { + del(store, stateKey); + } + }); + // avoid devtools logging this as a mutation + isListening = false; + isSyncListening = false; + pinia.state.value[$id] = toRef(newStore._hmrPayload, 'hotState'); + isSyncListening = true; + nextTick().then(() => { + isListening = true; + }); + for (const actionName in newStore._hmrPayload.actions) { + const actionFn = newStore[actionName]; + set(store, actionName, action(actionFn, actionName)); + } + // TODO: does this work in both setup and option store? + for (const getterName in newStore._hmrPayload.getters) { + const getter = newStore._hmrPayload.getters[getterName]; + const getterValue = isOptionsStore + ? // special handling of options api + computed(() => { + setActivePinia(pinia); + return getter.call(store, store); + }) + : getter; + set(store, getterName, getterValue); + } + // remove deleted getters + Object.keys(store._hmrPayload.getters).forEach((key) => { + if (!(key in newStore._hmrPayload.getters)) { + del(store, key); + } + }); + // remove old actions + Object.keys(store._hmrPayload.actions).forEach((key) => { + if (!(key in newStore._hmrPayload.actions)) { + del(store, key); + } + }); + // update the values used in devtools and to allow deleting new properties later on + store._hmrPayload = newStore._hmrPayload; + store._getters = newStore._getters; + store._hotUpdating = false; + }); + } + if (IS_CLIENT) { + const nonEnumerable = { + writable: true, + configurable: true, + // avoid warning on devtools trying to display this property + enumerable: false, + }; + ['_p', '_hmrPayload', '_getters', '_customProperties'].forEach((p) => { + Object.defineProperty(store, p, assign({ value: store[p] }, nonEnumerable)); + }); + } + /* istanbul ignore if */ + if (isVue2) { + // mark the store as ready before plugins + store._r = true; + } + // apply all plugins + pinia._p.forEach((extender) => { + /* istanbul ignore else */ + if (IS_CLIENT) { + const extensions = scope.run(() => extender({ + store: store, + app: pinia._a, + pinia, + options: optionsForPlugin, + })); + Object.keys(extensions || {}).forEach((key) => store._customProperties.add(key)); + assign(store, extensions); + } + else { + assign(store, scope.run(() => extender({ + store: store, + app: pinia._a, + pinia, + options: optionsForPlugin, + }))); + } + }); + if (store.$state && + typeof store.$state === 'object' && + typeof store.$state.constructor === 'function' && + !store.$state.constructor.toString().includes('[native code]')) { + console.warn(`[🍍]: The "state" must be a plain object. It cannot be\n` + + `\tstate: () => new MyClass()\n` + + `Found in store "${store.$id}".`); + } + // only apply hydrate to option stores with an initial state in pinia + if (initialState && + isOptionsStore && + options.hydrate) { + options.hydrate(store.$state, initialState); + } + isListening = true; + isSyncListening = true; + return store; +} +// allows unused stores to be tree shaken +/*! #__NO_SIDE_EFFECTS__ */ +function defineStore( +// TODO: add proper types from above +idOrOptions, setup, setupOptions) { + let id; + let options; + const isSetupStore = typeof setup === 'function'; + if (typeof idOrOptions === 'string') { + id = idOrOptions; + // the option store setup will contain the actual options in this case + options = isSetupStore ? setupOptions : setup; + } + else { + options = idOrOptions; + id = idOrOptions.id; + if (typeof id !== 'string') { + throw new Error(`[🍍]: "defineStore()" must be passed a store id as its first argument.`); + } + } + function useStore(pinia, hot) { + const hasContext = hasInjectionContext(); + pinia = + // in test mode, ignore the argument provided as we can always retrieve a + // pinia instance with getActivePinia() + (pinia) || + (hasContext ? inject(piniaSymbol, null) : null); + if (pinia) + setActivePinia(pinia); + if (!activePinia) { + throw new Error(`[🍍]: "getActivePinia()" was called but there was no active Pinia. Are you trying to use a store before calling "app.use(pinia)"?\n` + + `See https://pinia.vuejs.org/core-concepts/outside-component-usage.html for help.\n` + + `This will fail in production.`); + } + pinia = activePinia; + if (!pinia._s.has(id)) { + // creating the store registers it in `pinia._s` + if (isSetupStore) { + createSetupStore(id, setup, options, pinia); + } + else { + createOptionsStore(id, options, pinia); + } + /* istanbul ignore else */ + { + // @ts-expect-error: not the right inferred type + useStore._pinia = pinia; + } + } + const store = pinia._s.get(id); + if (hot) { + const hotId = '__hot:' + id; + const newStore = isSetupStore + ? createSetupStore(hotId, setup, options, pinia, true) + : createOptionsStore(hotId, assign({}, options), pinia, true); + hot._hotUpdate(newStore); + // cleanup the state properties and the store from the cache + delete pinia.state.value[hotId]; + pinia._s.delete(hotId); + } + if (IS_CLIENT) { + const currentInstance = getCurrentInstance(); + // save stores in instances to access them devtools + if (currentInstance && + currentInstance.proxy && + // avoid adding stores that are just built for hot module replacement + !hot) { + const vm = currentInstance.proxy; + const cache = '_pStores' in vm ? vm._pStores : (vm._pStores = {}); + cache[id] = store; + } + } + // StoreGeneric cannot be casted towards Store + return store; + } + useStore.$id = id; + return useStore; +} + +let mapStoreSuffix = 'Store'; +/** + * Changes the suffix added by `mapStores()`. Can be set to an empty string. + * Defaults to `"Store"`. Make sure to extend the MapStoresCustomization + * interface if you are using TypeScript. + * + * @param suffix - new suffix + */ +function setMapStoreSuffix(suffix // could be 'Store' but that would be annoying for JS +) { + mapStoreSuffix = suffix; +} +/** + * Allows using stores without the composition API (`setup()`) by generating an + * object to be spread in the `computed` field of a component. It accepts a list + * of store definitions. + * + * @example + * ```js + * export default { + * computed: { + * // other computed properties + * ...mapStores(useUserStore, useCartStore) + * }, + * + * created() { + * this.userStore // store with id "user" + * this.cartStore // store with id "cart" + * } + * } + * ``` + * + * @param stores - list of stores to map to an object + */ +function mapStores(...stores) { + if (Array.isArray(stores[0])) { + console.warn(`[🍍]: Directly pass all stores to "mapStores()" without putting them in an array:\n` + + `Replace\n` + + `\tmapStores([useAuthStore, useCartStore])\n` + + `with\n` + + `\tmapStores(useAuthStore, useCartStore)\n` + + `This will fail in production if not fixed.`); + stores = stores[0]; + } + return stores.reduce((reduced, useStore) => { + // @ts-expect-error: $id is added by defineStore + reduced[useStore.$id + mapStoreSuffix] = function () { + return useStore(this.$pinia); + }; + return reduced; + }, {}); +} +/** + * Allows using state and getters from one store without using the composition + * API (`setup()`) by generating an object to be spread in the `computed` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ +function mapState(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + reduced[key] = function () { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key]; + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function () { + const store = useStore(this.$pinia); + const storeKey = keysOrMapper[key]; + // for some reason TS is unable to infer the type of storeKey to be a + // function + return typeof storeKey === 'function' + ? storeKey.call(this, store) + : // @ts-expect-error: FIXME: should work? + store[storeKey]; + }; + return reduced; + }, {}); +} +/** + * Alias for `mapState()`. You should use `mapState()` instead. + * @deprecated use `mapState()` instead. + */ +const mapGetters = mapState; +/** + * Allows directly using actions from your store without using the composition + * API (`setup()`) by generating an object to be spread in the `methods` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ +function mapActions(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function (...args) { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key](...args); + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function (...args) { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[keysOrMapper[key]](...args); + }; + return reduced; + }, {}); +} +/** + * Allows using state and getters from one store without using the composition + * API (`setup()`) by generating an object to be spread in the `computed` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ +function mapWritableState(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + // @ts-ignore + reduced[key] = { + get() { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key]; + }, + set(value) { + // @ts-expect-error: FIXME: should work? + return (useStore(this.$pinia)[key] = value); + }, + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-ignore + reduced[key] = { + get() { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[keysOrMapper[key]]; + }, + set(value) { + // @ts-expect-error: FIXME: should work? + return (useStore(this.$pinia)[keysOrMapper[key]] = value); + }, + }; + return reduced; + }, {}); +} + +/** + * Creates an object of references with all the state, getters, and plugin-added + * state properties of the store. Similar to `toRefs()` but specifically + * designed for Pinia stores so methods and non reactive properties are + * completely ignored. + * + * @param store - store to extract the refs from + */ +function storeToRefs(store) { + // See https://github.com/vuejs/pinia/issues/852 + // It's easier to just use toRefs() even if it includes more stuff + if (isVue2) { + // @ts-expect-error: toRefs include methods and others + return toRefs(store); + } + else { + const rawStore = toRaw(store); + const refs = {}; + for (const key in rawStore) { + const value = rawStore[key]; + if (isRef(value) || isReactive(value)) { + // @ts-expect-error: the key is state or getter + refs[key] = + // --- + toRef(store, key); + } + } + return refs; + } +} + +/** + * Vue 2 Plugin that must be installed for pinia to work. Note **you don't need + * this plugin if you are using Nuxt.js**. Use the `buildModule` instead: + * https://pinia.vuejs.org/ssr/nuxt.html. + * + * @example + * ```js + * import Vue from 'vue' + * import { PiniaVuePlugin, createPinia } from 'pinia' + * + * Vue.use(PiniaVuePlugin) + * const pinia = createPinia() + * + * new Vue({ + * el: '#app', + * // ... + * pinia, + * }) + * ``` + * + * @param _Vue - `Vue` imported from 'vue'. + */ +const PiniaVuePlugin = function (_Vue) { + // Equivalent of + // app.config.globalProperties.$pinia = pinia + _Vue.mixin({ + beforeCreate() { + const options = this.$options; + if (options.pinia) { + const pinia = options.pinia; + // HACK: taken from provide(): https://github.com/vuejs/composition-api/blob/main/src/apis/inject.ts#L31 + /* istanbul ignore else */ + if (!this._provided) { + const provideCache = {}; + Object.defineProperty(this, '_provided', { + get: () => provideCache, + set: (v) => Object.assign(provideCache, v), + }); + } + this._provided[piniaSymbol] = pinia; + // propagate the pinia instance in an SSR friendly way + // avoid adding it to nuxt twice + /* istanbul ignore else */ + if (!this.$pinia) { + this.$pinia = pinia; + } + pinia._a = this; + if (IS_CLIENT) { + // this allows calling useStore() outside of a component setup after + // installing pinia's plugin + setActivePinia(pinia); + } + if (IS_CLIENT) { + registerPiniaDevtools(pinia._a, pinia); + } + } + else if (!this.$pinia && options.parent && options.parent.$pinia) { + this.$pinia = options.parent.$pinia; + } + }, + destroyed() { + delete this._pStores; + }, + }); +}; + +export { MutationType, PiniaVuePlugin, acceptHMRUpdate, createPinia, defineStore, disposePinia, getActivePinia, mapActions, mapGetters, mapState, mapStores, mapWritableState, setActivePinia, setMapStoreSuffix, shouldHydrate, skipHydrate, storeToRefs }; diff --git a/node_modules/pinia/dist/pinia.iife.js b/node_modules/pinia/dist/pinia.iife.js new file mode 100644 index 0000000..be79e83 --- /dev/null +++ b/node_modules/pinia/dist/pinia.iife.js @@ -0,0 +1,2222 @@ +/*! + * pinia v2.2.5 + * (c) 2024 Eduardo San Martin Morote + * @license MIT + */ +var Pinia = (function (exports, vueDemi) { + 'use strict'; + + /** + * setActivePinia must be called to handle SSR at the top of functions like + * `fetch`, `setup`, `serverPrefetch` and others + */ + let activePinia; + /** + * Sets or unsets the active pinia. Used in SSR and internally when calling + * actions and getters + * + * @param pinia - Pinia instance + */ + // @ts-expect-error: cannot constrain the type of the return + const setActivePinia = (pinia) => (activePinia = pinia); + /** + * Get the currently active pinia if there is any. + */ + const getActivePinia = () => (vueDemi.hasInjectionContext() && vueDemi.inject(piniaSymbol)) || activePinia; + const piniaSymbol = (Symbol('pinia') ); + + function getDevtoolsGlobalHook() { + return getTarget().__VUE_DEVTOOLS_GLOBAL_HOOK__; + } + function getTarget() { + // @ts-expect-error navigator and windows are not available in all environments + return (typeof navigator !== 'undefined' && typeof window !== 'undefined') + ? window + : typeof globalThis !== 'undefined' + ? globalThis + : {}; + } + const isProxyAvailable = typeof Proxy === 'function'; + + const HOOK_SETUP = 'devtools-plugin:setup'; + const HOOK_PLUGIN_SETTINGS_SET = 'plugin:settings:set'; + + let supported; + let perf; + function isPerformanceSupported() { + var _a; + if (supported !== undefined) { + return supported; + } + if (typeof window !== 'undefined' && window.performance) { + supported = true; + perf = window.performance; + } + else if (typeof globalThis !== 'undefined' && ((_a = globalThis.perf_hooks) === null || _a === void 0 ? void 0 : _a.performance)) { + supported = true; + perf = globalThis.perf_hooks.performance; + } + else { + supported = false; + } + return supported; + } + function now() { + return isPerformanceSupported() ? perf.now() : Date.now(); + } + + class ApiProxy { + constructor(plugin, hook) { + this.target = null; + this.targetQueue = []; + this.onQueue = []; + this.plugin = plugin; + this.hook = hook; + const defaultSettings = {}; + if (plugin.settings) { + for (const id in plugin.settings) { + const item = plugin.settings[id]; + defaultSettings[id] = item.defaultValue; + } + } + const localSettingsSaveId = `__vue-devtools-plugin-settings__${plugin.id}`; + let currentSettings = Object.assign({}, defaultSettings); + try { + const raw = localStorage.getItem(localSettingsSaveId); + const data = JSON.parse(raw); + Object.assign(currentSettings, data); + } + catch (e) { + // noop + } + this.fallbacks = { + getSettings() { + return currentSettings; + }, + setSettings(value) { + try { + localStorage.setItem(localSettingsSaveId, JSON.stringify(value)); + } + catch (e) { + // noop + } + currentSettings = value; + }, + now() { + return now(); + }, + }; + if (hook) { + hook.on(HOOK_PLUGIN_SETTINGS_SET, (pluginId, value) => { + if (pluginId === this.plugin.id) { + this.fallbacks.setSettings(value); + } + }); + } + this.proxiedOn = new Proxy({}, { + get: (_target, prop) => { + if (this.target) { + return this.target.on[prop]; + } + else { + return (...args) => { + this.onQueue.push({ + method: prop, + args, + }); + }; + } + }, + }); + this.proxiedTarget = new Proxy({}, { + get: (_target, prop) => { + if (this.target) { + return this.target[prop]; + } + else if (prop === 'on') { + return this.proxiedOn; + } + else if (Object.keys(this.fallbacks).includes(prop)) { + return (...args) => { + this.targetQueue.push({ + method: prop, + args, + resolve: () => { }, + }); + return this.fallbacks[prop](...args); + }; + } + else { + return (...args) => { + return new Promise((resolve) => { + this.targetQueue.push({ + method: prop, + args, + resolve, + }); + }); + }; + } + }, + }); + } + async setRealTarget(target) { + this.target = target; + for (const item of this.onQueue) { + this.target.on[item.method](...item.args); + } + for (const item of this.targetQueue) { + item.resolve(await this.target[item.method](...item.args)); + } + } + } + + function setupDevtoolsPlugin(pluginDescriptor, setupFn) { + const descriptor = pluginDescriptor; + const target = getTarget(); + const hook = getDevtoolsGlobalHook(); + const enableProxy = isProxyAvailable && descriptor.enableEarlyProxy; + if (hook && (target.__VUE_DEVTOOLS_PLUGIN_API_AVAILABLE__ || !enableProxy)) { + hook.emit(HOOK_SETUP, pluginDescriptor, setupFn); + } + else { + const proxy = enableProxy ? new ApiProxy(descriptor, hook) : null; + const list = target.__VUE_DEVTOOLS_PLUGINS__ = target.__VUE_DEVTOOLS_PLUGINS__ || []; + list.push({ + pluginDescriptor: descriptor, + setupFn, + proxy, + }); + if (proxy) { + setupFn(proxy.proxiedTarget); + } + } + } + + function isPlainObject( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + o) { + return (o && + typeof o === 'object' && + Object.prototype.toString.call(o) === '[object Object]' && + typeof o.toJSON !== 'function'); + } + // type DeepReadonly = { readonly [P in keyof T]: DeepReadonly } + // TODO: can we change these to numbers? + /** + * Possible types for SubscriptionCallback + */ + exports.MutationType = void 0; + (function (MutationType) { + /** + * Direct mutation of the state: + * + * - `store.name = 'new name'` + * - `store.$state.name = 'new name'` + * - `store.list.push('new item')` + */ + MutationType["direct"] = "direct"; + /** + * Mutated the state with `$patch` and an object + * + * - `store.$patch({ name: 'newName' })` + */ + MutationType["patchObject"] = "patch object"; + /** + * Mutated the state with `$patch` and a function + * + * - `store.$patch(state => state.name = 'newName')` + */ + MutationType["patchFunction"] = "patch function"; + // maybe reset? for $state = {} and $reset + })(exports.MutationType || (exports.MutationType = {})); + + const IS_CLIENT = typeof window !== 'undefined'; + + /* + * FileSaver.js A saveAs() FileSaver implementation. + * + * Originally by Eli Grey, adapted as an ESM module by Eduardo San Martin + * Morote. + * + * License : MIT + */ + // The one and only way of getting global scope in all environments + // https://stackoverflow.com/q/3277182/1008999 + const _global = /*#__PURE__*/ (() => typeof window === 'object' && window.window === window + ? window + : typeof self === 'object' && self.self === self + ? self + : typeof global === 'object' && global.global === global + ? global + : typeof globalThis === 'object' + ? globalThis + : { HTMLElement: null })(); + function bom(blob, { autoBom = false } = {}) { + // prepend BOM for UTF-8 XML and text/* types (including HTML) + // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF + if (autoBom && + /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { + return new Blob([String.fromCharCode(0xfeff), blob], { type: blob.type }); + } + return blob; + } + function download(url, name, opts) { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'blob'; + xhr.onload = function () { + saveAs(xhr.response, name, opts); + }; + xhr.onerror = function () { + console.error('could not download file'); + }; + xhr.send(); + } + function corsEnabled(url) { + const xhr = new XMLHttpRequest(); + // use sync to avoid popup blocker + xhr.open('HEAD', url, false); + try { + xhr.send(); + } + catch (e) { } + return xhr.status >= 200 && xhr.status <= 299; + } + // `a.click()` doesn't work for all browsers (#465) + function click(node) { + try { + node.dispatchEvent(new MouseEvent('click')); + } + catch (e) { + const evt = document.createEvent('MouseEvents'); + evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null); + node.dispatchEvent(evt); + } + } + const _navigator = typeof navigator === 'object' ? navigator : { userAgent: '' }; + // Detect WebView inside a native macOS app by ruling out all browsers + // We just need to check for 'Safari' because all other browsers (besides Firefox) include that too + // https://www.whatismybrowser.com/guides/the-latest-user-agent/macos + const isMacOSWebView = /*#__PURE__*/ (() => /Macintosh/.test(_navigator.userAgent) && + /AppleWebKit/.test(_navigator.userAgent) && + !/Safari/.test(_navigator.userAgent))(); + const saveAs = !IS_CLIENT + ? () => { } // noop + : // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView or mini program + typeof HTMLAnchorElement !== 'undefined' && + 'download' in HTMLAnchorElement.prototype && + !isMacOSWebView + ? downloadSaveAs + : // Use msSaveOrOpenBlob as a second approach + 'msSaveOrOpenBlob' in _navigator + ? msSaveAs + : // Fallback to using FileReader and a popup + fileSaverSaveAs; + function downloadSaveAs(blob, name = 'download', opts) { + const a = document.createElement('a'); + a.download = name; + a.rel = 'noopener'; // tabnabbing + // TODO: detect chrome extensions & packaged apps + // a.target = '_blank' + if (typeof blob === 'string') { + // Support regular links + a.href = blob; + if (a.origin !== location.origin) { + if (corsEnabled(a.href)) { + download(blob, name, opts); + } + else { + a.target = '_blank'; + click(a); + } + } + else { + click(a); + } + } + else { + // Support blobs + a.href = URL.createObjectURL(blob); + setTimeout(function () { + URL.revokeObjectURL(a.href); + }, 4e4); // 40s + setTimeout(function () { + click(a); + }, 0); + } + } + function msSaveAs(blob, name = 'download', opts) { + if (typeof blob === 'string') { + if (corsEnabled(blob)) { + download(blob, name, opts); + } + else { + const a = document.createElement('a'); + a.href = blob; + a.target = '_blank'; + setTimeout(function () { + click(a); + }); + } + } + else { + // @ts-ignore: works on windows + navigator.msSaveOrOpenBlob(bom(blob, opts), name); + } + } + function fileSaverSaveAs(blob, name, opts, popup) { + // Open a popup immediately do go around popup blocker + // Mostly only available on user interaction and the fileReader is async so... + popup = popup || open('', '_blank'); + if (popup) { + popup.document.title = popup.document.body.innerText = 'downloading...'; + } + if (typeof blob === 'string') + return download(blob, name, opts); + const force = blob.type === 'application/octet-stream'; + const isSafari = /constructor/i.test(String(_global.HTMLElement)) || 'safari' in _global; + const isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent); + if ((isChromeIOS || (force && isSafari) || isMacOSWebView) && + typeof FileReader !== 'undefined') { + // Safari doesn't allow downloading of blob URLs + const reader = new FileReader(); + reader.onloadend = function () { + let url = reader.result; + if (typeof url !== 'string') { + popup = null; + throw new Error('Wrong reader.result type'); + } + url = isChromeIOS + ? url + : url.replace(/^data:[^;]*;/, 'data:attachment/file;'); + if (popup) { + popup.location.href = url; + } + else { + location.assign(url); + } + popup = null; // reverse-tabnabbing #460 + }; + reader.readAsDataURL(blob); + } + else { + const url = URL.createObjectURL(blob); + if (popup) + popup.location.assign(url); + else + location.href = url; + popup = null; // reverse-tabnabbing #460 + setTimeout(function () { + URL.revokeObjectURL(url); + }, 4e4); // 40s + } + } + + /** + * Shows a toast or console.log + * + * @param message - message to log + * @param type - different color of the tooltip + */ + function toastMessage(message, type) { + const piniaMessage = '🍍 ' + message; + if (typeof __VUE_DEVTOOLS_TOAST__ === 'function') { + // No longer available :( + __VUE_DEVTOOLS_TOAST__(piniaMessage, type); + } + else if (type === 'error') { + console.error(piniaMessage); + } + else if (type === 'warn') { + console.warn(piniaMessage); + } + else { + console.log(piniaMessage); + } + } + function isPinia(o) { + return '_a' in o && 'install' in o; + } + + /** + * This file contain devtools actions, they are not Pinia actions. + */ + // --- + function checkClipboardAccess() { + if (!('clipboard' in navigator)) { + toastMessage(`Your browser doesn't support the Clipboard API`, 'error'); + return true; + } + } + function checkNotFocusedError(error) { + if (error instanceof Error && + error.message.toLowerCase().includes('document is not focused')) { + toastMessage('You need to activate the "Emulate a focused page" setting in the "Rendering" panel of devtools.', 'warn'); + return true; + } + return false; + } + async function actionGlobalCopyState(pinia) { + if (checkClipboardAccess()) + return; + try { + await navigator.clipboard.writeText(JSON.stringify(pinia.state.value)); + toastMessage('Global state copied to clipboard.'); + } + catch (error) { + if (checkNotFocusedError(error)) + return; + toastMessage(`Failed to serialize the state. Check the console for more details.`, 'error'); + console.error(error); + } + } + async function actionGlobalPasteState(pinia) { + if (checkClipboardAccess()) + return; + try { + loadStoresState(pinia, JSON.parse(await navigator.clipboard.readText())); + toastMessage('Global state pasted from clipboard.'); + } + catch (error) { + if (checkNotFocusedError(error)) + return; + toastMessage(`Failed to deserialize the state from clipboard. Check the console for more details.`, 'error'); + console.error(error); + } + } + async function actionGlobalSaveState(pinia) { + try { + saveAs(new Blob([JSON.stringify(pinia.state.value)], { + type: 'text/plain;charset=utf-8', + }), 'pinia-state.json'); + } + catch (error) { + toastMessage(`Failed to export the state as JSON. Check the console for more details.`, 'error'); + console.error(error); + } + } + let fileInput; + function getFileOpener() { + if (!fileInput) { + fileInput = document.createElement('input'); + fileInput.type = 'file'; + fileInput.accept = '.json'; + } + function openFile() { + return new Promise((resolve, reject) => { + fileInput.onchange = async () => { + const files = fileInput.files; + if (!files) + return resolve(null); + const file = files.item(0); + if (!file) + return resolve(null); + return resolve({ text: await file.text(), file }); + }; + // @ts-ignore: TODO: changed from 4.3 to 4.4 + fileInput.oncancel = () => resolve(null); + fileInput.onerror = reject; + fileInput.click(); + }); + } + return openFile; + } + async function actionGlobalOpenStateFile(pinia) { + try { + const open = getFileOpener(); + const result = await open(); + if (!result) + return; + const { text, file } = result; + loadStoresState(pinia, JSON.parse(text)); + toastMessage(`Global state imported from "${file.name}".`); + } + catch (error) { + toastMessage(`Failed to import the state from JSON. Check the console for more details.`, 'error'); + console.error(error); + } + } + function loadStoresState(pinia, state) { + for (const key in state) { + const storeState = pinia.state.value[key]; + // store is already instantiated, patch it + if (storeState) { + Object.assign(storeState, state[key]); + } + else { + // store is not instantiated, set the initial state + pinia.state.value[key] = state[key]; + } + } + } + + function formatDisplay(display) { + return { + _custom: { + display, + }, + }; + } + const PINIA_ROOT_LABEL = '🍍 Pinia (root)'; + const PINIA_ROOT_ID = '_root'; + function formatStoreForInspectorTree(store) { + return isPinia(store) + ? { + id: PINIA_ROOT_ID, + label: PINIA_ROOT_LABEL, + } + : { + id: store.$id, + label: store.$id, + }; + } + function formatStoreForInspectorState(store) { + if (isPinia(store)) { + const storeNames = Array.from(store._s.keys()); + const storeMap = store._s; + const state = { + state: storeNames.map((storeId) => ({ + editable: true, + key: storeId, + value: store.state.value[storeId], + })), + getters: storeNames + .filter((id) => storeMap.get(id)._getters) + .map((id) => { + const store = storeMap.get(id); + return { + editable: false, + key: id, + value: store._getters.reduce((getters, key) => { + getters[key] = store[key]; + return getters; + }, {}), + }; + }), + }; + return state; + } + const state = { + state: Object.keys(store.$state).map((key) => ({ + editable: true, + key, + value: store.$state[key], + })), + }; + // avoid adding empty getters + if (store._getters && store._getters.length) { + state.getters = store._getters.map((getterName) => ({ + editable: false, + key: getterName, + value: store[getterName], + })); + } + if (store._customProperties.size) { + state.customProperties = Array.from(store._customProperties).map((key) => ({ + editable: true, + key, + value: store[key], + })); + } + return state; + } + function formatEventData(events) { + if (!events) + return {}; + if (Array.isArray(events)) { + // TODO: handle add and delete for arrays and objects + return events.reduce((data, event) => { + data.keys.push(event.key); + data.operations.push(event.type); + data.oldValue[event.key] = event.oldValue; + data.newValue[event.key] = event.newValue; + return data; + }, { + oldValue: {}, + keys: [], + operations: [], + newValue: {}, + }); + } + else { + return { + operation: formatDisplay(events.type), + key: formatDisplay(events.key), + oldValue: events.oldValue, + newValue: events.newValue, + }; + } + } + function formatMutationType(type) { + switch (type) { + case exports.MutationType.direct: + return 'mutation'; + case exports.MutationType.patchFunction: + return '$patch'; + case exports.MutationType.patchObject: + return '$patch'; + default: + return 'unknown'; + } + } + + // timeline can be paused when directly changing the state + let isTimelineActive = true; + const componentStateTypes = []; + const MUTATIONS_LAYER_ID = 'pinia:mutations'; + const INSPECTOR_ID = 'pinia'; + const { assign: assign$1 } = Object; + /** + * Gets the displayed name of a store in devtools + * + * @param id - id of the store + * @returns a formatted string + */ + const getStoreType = (id) => '🍍 ' + id; + /** + * Add the pinia plugin without any store. Allows displaying a Pinia plugin tab + * as soon as it is added to the application. + * + * @param app - Vue application + * @param pinia - pinia instance + */ + function registerPiniaDevtools(app, pinia) { + setupDevtoolsPlugin({ + id: 'dev.esm.pinia', + label: 'Pinia 🍍', + logo: 'https://pinia.vuejs.org/logo.svg', + packageName: 'pinia', + homepage: 'https://pinia.vuejs.org', + componentStateTypes, + app, + }, (api) => { + if (typeof api.now !== 'function') { + toastMessage('You seem to be using an outdated version of Vue Devtools. Are you still using the Beta release instead of the stable one? You can find the links at https://devtools.vuejs.org/guide/installation.html.'); + } + api.addTimelineLayer({ + id: MUTATIONS_LAYER_ID, + label: `Pinia 🍍`, + color: 0xe5df88, + }); + api.addInspector({ + id: INSPECTOR_ID, + label: 'Pinia 🍍', + icon: 'storage', + treeFilterPlaceholder: 'Search stores', + actions: [ + { + icon: 'content_copy', + action: () => { + actionGlobalCopyState(pinia); + }, + tooltip: 'Serialize and copy the state', + }, + { + icon: 'content_paste', + action: async () => { + await actionGlobalPasteState(pinia); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + }, + tooltip: 'Replace the state with the content of your clipboard', + }, + { + icon: 'save', + action: () => { + actionGlobalSaveState(pinia); + }, + tooltip: 'Save the state as a JSON file', + }, + { + icon: 'folder_open', + action: async () => { + await actionGlobalOpenStateFile(pinia); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + }, + tooltip: 'Import the state from a JSON file', + }, + ], + nodeActions: [ + { + icon: 'restore', + tooltip: 'Reset the state (with "$reset")', + action: (nodeId) => { + const store = pinia._s.get(nodeId); + if (!store) { + toastMessage(`Cannot reset "${nodeId}" store because it wasn't found.`, 'warn'); + } + else if (typeof store.$reset !== 'function') { + toastMessage(`Cannot reset "${nodeId}" store because it doesn't have a "$reset" method implemented.`, 'warn'); + } + else { + store.$reset(); + toastMessage(`Store "${nodeId}" reset.`); + } + }, + }, + ], + }); + api.on.inspectComponent((payload, ctx) => { + const proxy = (payload.componentInstance && + payload.componentInstance.proxy); + if (proxy && proxy._pStores) { + const piniaStores = payload.componentInstance.proxy._pStores; + Object.values(piniaStores).forEach((store) => { + payload.instanceData.state.push({ + type: getStoreType(store.$id), + key: 'state', + editable: true, + value: store._isOptionsAPI + ? { + _custom: { + value: vueDemi.toRaw(store.$state), + actions: [ + { + icon: 'restore', + tooltip: 'Reset the state of this store', + action: () => store.$reset(), + }, + ], + }, + } + : // NOTE: workaround to unwrap transferred refs + Object.keys(store.$state).reduce((state, key) => { + state[key] = store.$state[key]; + return state; + }, {}), + }); + if (store._getters && store._getters.length) { + payload.instanceData.state.push({ + type: getStoreType(store.$id), + key: 'getters', + editable: false, + value: store._getters.reduce((getters, key) => { + try { + getters[key] = store[key]; + } + catch (error) { + // @ts-expect-error: we just want to show it in devtools + getters[key] = error; + } + return getters; + }, {}), + }); + } + }); + } + }); + api.on.getInspectorTree((payload) => { + if (payload.app === app && payload.inspectorId === INSPECTOR_ID) { + let stores = [pinia]; + stores = stores.concat(Array.from(pinia._s.values())); + payload.rootNodes = (payload.filter + ? stores.filter((store) => '$id' in store + ? store.$id + .toLowerCase() + .includes(payload.filter.toLowerCase()) + : PINIA_ROOT_LABEL.toLowerCase().includes(payload.filter.toLowerCase())) + : stores).map(formatStoreForInspectorTree); + } + }); + // Expose pinia instance as $pinia to window + globalThis.$pinia = pinia; + api.on.getInspectorState((payload) => { + if (payload.app === app && payload.inspectorId === INSPECTOR_ID) { + const inspectedStore = payload.nodeId === PINIA_ROOT_ID + ? pinia + : pinia._s.get(payload.nodeId); + if (!inspectedStore) { + // this could be the selected store restored for a different project + // so it's better not to say anything here + return; + } + if (inspectedStore) { + // Expose selected store as $store to window + if (payload.nodeId !== PINIA_ROOT_ID) + globalThis.$store = vueDemi.toRaw(inspectedStore); + payload.state = formatStoreForInspectorState(inspectedStore); + } + } + }); + api.on.editInspectorState((payload, ctx) => { + if (payload.app === app && payload.inspectorId === INSPECTOR_ID) { + const inspectedStore = payload.nodeId === PINIA_ROOT_ID + ? pinia + : pinia._s.get(payload.nodeId); + if (!inspectedStore) { + return toastMessage(`store "${payload.nodeId}" not found`, 'error'); + } + const { path } = payload; + if (!isPinia(inspectedStore)) { + // access only the state + if (path.length !== 1 || + !inspectedStore._customProperties.has(path[0]) || + path[0] in inspectedStore.$state) { + path.unshift('$state'); + } + } + else { + // Root access, we can omit the `.value` because the devtools API does it for us + path.unshift('state'); + } + isTimelineActive = false; + payload.set(inspectedStore, path, payload.state.value); + isTimelineActive = true; + } + }); + api.on.editComponentState((payload) => { + if (payload.type.startsWith('🍍')) { + const storeId = payload.type.replace(/^🍍\s*/, ''); + const store = pinia._s.get(storeId); + if (!store) { + return toastMessage(`store "${storeId}" not found`, 'error'); + } + const { path } = payload; + if (path[0] !== 'state') { + return toastMessage(`Invalid path for store "${storeId}":\n${path}\nOnly state can be modified.`); + } + // rewrite the first entry to be able to directly set the state as + // well as any other path + path[0] = '$state'; + isTimelineActive = false; + payload.set(store, path, payload.state.value); + isTimelineActive = true; + } + }); + }); + } + function addStoreToDevtools(app, store) { + if (!componentStateTypes.includes(getStoreType(store.$id))) { + componentStateTypes.push(getStoreType(store.$id)); + } + setupDevtoolsPlugin({ + id: 'dev.esm.pinia', + label: 'Pinia 🍍', + logo: 'https://pinia.vuejs.org/logo.svg', + packageName: 'pinia', + homepage: 'https://pinia.vuejs.org', + componentStateTypes, + app, + settings: { + logStoreChanges: { + label: 'Notify about new/deleted stores', + type: 'boolean', + defaultValue: true, + }, + // useEmojis: { + // label: 'Use emojis in messages ⚡️', + // type: 'boolean', + // defaultValue: true, + // }, + }, + }, (api) => { + // gracefully handle errors + const now = typeof api.now === 'function' ? api.now.bind(api) : Date.now; + store.$onAction(({ after, onError, name, args }) => { + const groupId = runningActionId++; + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: '🛫 ' + name, + subtitle: 'start', + data: { + store: formatDisplay(store.$id), + action: formatDisplay(name), + args, + }, + groupId, + }, + }); + after((result) => { + activeAction = undefined; + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: '🛬 ' + name, + subtitle: 'end', + data: { + store: formatDisplay(store.$id), + action: formatDisplay(name), + args, + result, + }, + groupId, + }, + }); + }); + onError((error) => { + activeAction = undefined; + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + logType: 'error', + title: '💥 ' + name, + subtitle: 'end', + data: { + store: formatDisplay(store.$id), + action: formatDisplay(name), + args, + error, + }, + groupId, + }, + }); + }); + }, true); + store._customProperties.forEach((name) => { + vueDemi.watch(() => vueDemi.unref(store[name]), (newValue, oldValue) => { + api.notifyComponentUpdate(); + api.sendInspectorState(INSPECTOR_ID); + if (isTimelineActive) { + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: 'Change', + subtitle: name, + data: { + newValue, + oldValue, + }, + groupId: activeAction, + }, + }); + } + }, { deep: true }); + }); + store.$subscribe(({ events, type }, state) => { + api.notifyComponentUpdate(); + api.sendInspectorState(INSPECTOR_ID); + if (!isTimelineActive) + return; + // rootStore.state[store.id] = state + const eventData = { + time: now(), + title: formatMutationType(type), + data: assign$1({ store: formatDisplay(store.$id) }, formatEventData(events)), + groupId: activeAction, + }; + if (type === exports.MutationType.patchFunction) { + eventData.subtitle = '⤵️'; + } + else if (type === exports.MutationType.patchObject) { + eventData.subtitle = '🧩'; + } + else if (events && !Array.isArray(events)) { + eventData.subtitle = events.type; + } + if (events) { + eventData.data['rawEvent(s)'] = { + _custom: { + display: 'DebuggerEvent', + type: 'object', + tooltip: 'raw DebuggerEvent[]', + value: events, + }, + }; + } + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: eventData, + }); + }, { detached: true, flush: 'sync' }); + const hotUpdate = store._hotUpdate; + store._hotUpdate = vueDemi.markRaw((newStore) => { + hotUpdate(newStore); + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: '🔥 ' + store.$id, + subtitle: 'HMR update', + data: { + store: formatDisplay(store.$id), + info: formatDisplay(`HMR update`), + }, + }, + }); + // update the devtools too + api.notifyComponentUpdate(); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + }); + const { $dispose } = store; + store.$dispose = () => { + $dispose(); + api.notifyComponentUpdate(); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + api.getSettings().logStoreChanges && + toastMessage(`Disposed "${store.$id}" store 🗑`); + }; + // trigger an update so it can display new registered stores + api.notifyComponentUpdate(); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + api.getSettings().logStoreChanges && + toastMessage(`"${store.$id}" store installed 🆕`); + }); + } + let runningActionId = 0; + let activeAction; + /** + * Patches a store to enable action grouping in devtools by wrapping the store with a Proxy that is passed as the + * context of all actions, allowing us to set `runningAction` on each access and effectively associating any state + * mutation to the action. + * + * @param store - store to patch + * @param actionNames - list of actionst to patch + */ + function patchActionForGrouping(store, actionNames, wrapWithProxy) { + // original actions of the store as they are given by pinia. We are going to override them + const actions = actionNames.reduce((storeActions, actionName) => { + // use toRaw to avoid tracking #541 + storeActions[actionName] = vueDemi.toRaw(store)[actionName]; + return storeActions; + }, {}); + for (const actionName in actions) { + store[actionName] = function () { + // the running action id is incremented in a before action hook + const _actionId = runningActionId; + const trackedStore = wrapWithProxy + ? new Proxy(store, { + get(...args) { + activeAction = _actionId; + return Reflect.get(...args); + }, + set(...args) { + activeAction = _actionId; + return Reflect.set(...args); + }, + }) + : store; + // For Setup Stores we need https://github.com/tc39/proposal-async-context + activeAction = _actionId; + const retValue = actions[actionName].apply(trackedStore, arguments); + // this is safer as async actions in Setup Stores would associate mutations done outside of the action + activeAction = undefined; + return retValue; + }; + } + } + /** + * pinia.use(devtoolsPlugin) + */ + function devtoolsPlugin({ app, store, options }) { + // HMR module + if (store.$id.startsWith('__hot:')) { + return; + } + // detect option api vs setup api + store._isOptionsAPI = !!options.state; + // Do not overwrite actions mocked by @pinia/testing (#2298) + if (!store._p._testing) { + patchActionForGrouping(store, Object.keys(options.actions), store._isOptionsAPI); + // Upgrade the HMR to also update the new actions + const originalHotUpdate = store._hotUpdate; + vueDemi.toRaw(store)._hotUpdate = function (newStore) { + originalHotUpdate.apply(this, arguments); + patchActionForGrouping(store, Object.keys(newStore._hmrPayload.actions), !!store._isOptionsAPI); + }; + } + addStoreToDevtools(app, + // FIXME: is there a way to allow the assignment from Store to StoreGeneric? + store); + } + + /** + * Creates a Pinia instance to be used by the application + */ + function createPinia() { + const scope = vueDemi.effectScope(true); + // NOTE: here we could check the window object for a state and directly set it + // if there is anything like it with Vue 3 SSR + const state = scope.run(() => vueDemi.ref({})); + let _p = []; + // plugins added before calling app.use(pinia) + let toBeInstalled = []; + const pinia = vueDemi.markRaw({ + install(app) { + // this allows calling useStore() outside of a component setup after + // installing pinia's plugin + setActivePinia(pinia); + if (!vueDemi.isVue2) { + pinia._a = app; + app.provide(piniaSymbol, pinia); + app.config.globalProperties.$pinia = pinia; + /* istanbul ignore else */ + if (IS_CLIENT) { + registerPiniaDevtools(app, pinia); + } + toBeInstalled.forEach((plugin) => _p.push(plugin)); + toBeInstalled = []; + } + }, + use(plugin) { + if (!this._a && !vueDemi.isVue2) { + toBeInstalled.push(plugin); + } + else { + _p.push(plugin); + } + return this; + }, + _p, + // it's actually undefined here + // @ts-expect-error + _a: null, + _e: scope, + _s: new Map(), + state, + }); + // pinia devtools rely on dev only features so they cannot be forced unless + // the dev build of Vue is used. Avoid old browsers like IE11. + if (typeof Proxy !== 'undefined') { + pinia.use(devtoolsPlugin); + } + return pinia; + } + /** + * Dispose a Pinia instance by stopping its effectScope and removing the state, plugins and stores. This is mostly + * useful in tests, with both a testing pinia or a regular pinia and in applications that use multiple pinia instances. + * Once disposed, the pinia instance cannot be used anymore. + * + * @param pinia - pinia instance + */ + function disposePinia(pinia) { + pinia._e.stop(); + pinia._s.clear(); + pinia._p.splice(0); + pinia.state.value = {}; + // @ts-expect-error: non valid + pinia._a = null; + } + + /** + * Checks if a function is a `StoreDefinition`. + * + * @param fn - object to test + * @returns true if `fn` is a StoreDefinition + */ + const isUseStore = (fn) => { + return typeof fn === 'function' && typeof fn.$id === 'string'; + }; + /** + * Mutates in place `newState` with `oldState` to _hot update_ it. It will + * remove any key not existing in `newState` and recursively merge plain + * objects. + * + * @param newState - new state object to be patched + * @param oldState - old state that should be used to patch newState + * @returns - newState + */ + function patchObject(newState, oldState) { + // no need to go through symbols because they cannot be serialized anyway + for (const key in oldState) { + const subPatch = oldState[key]; + // skip the whole sub tree + if (!(key in newState)) { + continue; + } + const targetValue = newState[key]; + if (isPlainObject(targetValue) && + isPlainObject(subPatch) && + !vueDemi.isRef(subPatch) && + !vueDemi.isReactive(subPatch)) { + newState[key] = patchObject(targetValue, subPatch); + } + else { + // objects are either a bit more complex (e.g. refs) or primitives, so we + // just set the whole thing + if (vueDemi.isVue2) { + vueDemi.set(newState, key, subPatch); + } + else { + newState[key] = subPatch; + } + } + } + return newState; + } + /** + * Creates an _accept_ function to pass to `import.meta.hot` in Vite applications. + * + * @example + * ```js + * const useUser = defineStore(...) + * if (import.meta.hot) { + * import.meta.hot.accept(acceptHMRUpdate(useUser, import.meta.hot)) + * } + * ``` + * + * @param initialUseStore - return of the defineStore to hot update + * @param hot - `import.meta.hot` + */ + function acceptHMRUpdate(initialUseStore, hot) { + return (newModule) => { + const pinia = hot.data.pinia || initialUseStore._pinia; + if (!pinia) { + // this store is still not used + return; + } + // preserve the pinia instance across loads + hot.data.pinia = pinia; + // console.log('got data', newStore) + for (const exportName in newModule) { + const useStore = newModule[exportName]; + // console.log('checking for', exportName) + if (isUseStore(useStore) && pinia._s.has(useStore.$id)) { + // console.log('Accepting update for', useStore.$id) + const id = useStore.$id; + if (id !== initialUseStore.$id) { + console.warn(`The id of the store changed from "${initialUseStore.$id}" to "${id}". Reloading.`); + // return import.meta.hot.invalidate() + return hot.invalidate(); + } + const existingStore = pinia._s.get(id); + if (!existingStore) { + console.log(`[Pinia]: skipping hmr because store doesn't exist yet`); + return; + } + useStore(pinia, existingStore); + } + } + }; + } + + const noop = () => { }; + function addSubscription(subscriptions, callback, detached, onCleanup = noop) { + subscriptions.push(callback); + const removeSubscription = () => { + const idx = subscriptions.indexOf(callback); + if (idx > -1) { + subscriptions.splice(idx, 1); + onCleanup(); + } + }; + if (!detached && vueDemi.getCurrentScope()) { + vueDemi.onScopeDispose(removeSubscription); + } + return removeSubscription; + } + function triggerSubscriptions(subscriptions, ...args) { + subscriptions.slice().forEach((callback) => { + callback(...args); + }); + } + + const fallbackRunWithContext = (fn) => fn(); + /** + * Marks a function as an action for `$onAction` + * @internal + */ + const ACTION_MARKER = Symbol(); + /** + * Action name symbol. Allows to add a name to an action after defining it + * @internal + */ + const ACTION_NAME = Symbol(); + function mergeReactiveObjects(target, patchToApply) { + // Handle Map instances + if (target instanceof Map && patchToApply instanceof Map) { + patchToApply.forEach((value, key) => target.set(key, value)); + } + else if (target instanceof Set && patchToApply instanceof Set) { + // Handle Set instances + patchToApply.forEach(target.add, target); + } + // no need to go through symbols because they cannot be serialized anyway + for (const key in patchToApply) { + if (!patchToApply.hasOwnProperty(key)) + continue; + const subPatch = patchToApply[key]; + const targetValue = target[key]; + if (isPlainObject(targetValue) && + isPlainObject(subPatch) && + target.hasOwnProperty(key) && + !vueDemi.isRef(subPatch) && + !vueDemi.isReactive(subPatch)) { + // NOTE: here I wanted to warn about inconsistent types but it's not possible because in setup stores one might + // start the value of a property as a certain type e.g. a Map, and then for some reason, during SSR, change that + // to `undefined`. When trying to hydrate, we want to override the Map with `undefined`. + target[key] = mergeReactiveObjects(targetValue, subPatch); + } + else { + // @ts-expect-error: subPatch is a valid value + target[key] = subPatch; + } + } + return target; + } + const skipHydrateSymbol = Symbol('pinia:skipHydration') + ; + const skipHydrateMap = /*#__PURE__*/ new WeakMap(); + /** + * Tells Pinia to skip the hydration process of a given object. This is useful in setup stores (only) when you return a + * stateful object in the store but it isn't really state. e.g. returning a router instance in a setup store. + * + * @param obj - target object + * @returns obj + */ + function skipHydrate(obj) { + return vueDemi.isVue2 + ? // in @vue/composition-api, the refs are sealed so defineProperty doesn't work... + /* istanbul ignore next */ skipHydrateMap.set(obj, 1) && obj + : Object.defineProperty(obj, skipHydrateSymbol, {}); + } + /** + * Returns whether a value should be hydrated + * + * @param obj - target variable + * @returns true if `obj` should be hydrated + */ + function shouldHydrate(obj) { + return vueDemi.isVue2 + ? /* istanbul ignore next */ !skipHydrateMap.has(obj) + : !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol); + } + const { assign } = Object; + function isComputed(o) { + return !!(vueDemi.isRef(o) && o.effect); + } + function createOptionsStore(id, options, pinia, hot) { + const { state, actions, getters } = options; + const initialState = pinia.state.value[id]; + let store; + function setup() { + if (!initialState && (!hot)) { + /* istanbul ignore if */ + if (vueDemi.isVue2) { + vueDemi.set(pinia.state.value, id, state ? state() : {}); + } + else { + pinia.state.value[id] = state ? state() : {}; + } + } + // avoid creating a state in pinia.state.value + const localState = hot + ? // use ref() to unwrap refs inside state TODO: check if this is still necessary + vueDemi.toRefs(vueDemi.ref(state ? state() : {}).value) + : vueDemi.toRefs(pinia.state.value[id]); + return assign(localState, actions, Object.keys(getters || {}).reduce((computedGetters, name) => { + if (name in localState) { + console.warn(`[🍍]: A getter cannot have the same name as another state property. Rename one of them. Found with "${name}" in store "${id}".`); + } + computedGetters[name] = vueDemi.markRaw(vueDemi.computed(() => { + setActivePinia(pinia); + // it was created just before + const store = pinia._s.get(id); + // allow cross using stores + /* istanbul ignore if */ + if (vueDemi.isVue2 && !store._r) + return; + // @ts-expect-error + // return getters![name].call(context, context) + // TODO: avoid reading the getter while assigning with a global variable + return getters[name].call(store, store); + })); + return computedGetters; + }, {})); + } + store = createSetupStore(id, setup, options, pinia, hot, true); + return store; + } + function createSetupStore($id, setup, options = {}, pinia, hot, isOptionsStore) { + let scope; + const optionsForPlugin = assign({ actions: {} }, options); + /* istanbul ignore if */ + if (!pinia._e.active) { + throw new Error('Pinia destroyed'); + } + // watcher options for $subscribe + const $subscribeOptions = { deep: true }; + /* istanbul ignore else */ + if (!vueDemi.isVue2) { + $subscribeOptions.onTrigger = (event) => { + /* istanbul ignore else */ + if (isListening) { + debuggerEvents = event; + // avoid triggering this while the store is being built and the state is being set in pinia + } + else if (isListening == false && !store._hotUpdating) { + // let patch send all the events together later + /* istanbul ignore else */ + if (Array.isArray(debuggerEvents)) { + debuggerEvents.push(event); + } + else { + console.error('🍍 debuggerEvents should be an array. This is most likely an internal Pinia bug.'); + } + } + }; + } + // internal state + let isListening; // set to true at the end + let isSyncListening; // set to true at the end + let subscriptions = []; + let actionSubscriptions = []; + let debuggerEvents; + const initialState = pinia.state.value[$id]; + // avoid setting the state for option stores if it is set + // by the setup + if (!isOptionsStore && !initialState && (!hot)) { + /* istanbul ignore if */ + if (vueDemi.isVue2) { + vueDemi.set(pinia.state.value, $id, {}); + } + else { + pinia.state.value[$id] = {}; + } + } + const hotState = vueDemi.ref({}); + // avoid triggering too many listeners + // https://github.com/vuejs/pinia/issues/1129 + let activeListener; + function $patch(partialStateOrMutator) { + let subscriptionMutation; + isListening = isSyncListening = false; + // reset the debugger events since patches are sync + /* istanbul ignore else */ + { + debuggerEvents = []; + } + if (typeof partialStateOrMutator === 'function') { + partialStateOrMutator(pinia.state.value[$id]); + subscriptionMutation = { + type: exports.MutationType.patchFunction, + storeId: $id, + events: debuggerEvents, + }; + } + else { + mergeReactiveObjects(pinia.state.value[$id], partialStateOrMutator); + subscriptionMutation = { + type: exports.MutationType.patchObject, + payload: partialStateOrMutator, + storeId: $id, + events: debuggerEvents, + }; + } + const myListenerId = (activeListener = Symbol()); + vueDemi.nextTick().then(() => { + if (activeListener === myListenerId) { + isListening = true; + } + }); + isSyncListening = true; + // because we paused the watcher, we need to manually call the subscriptions + triggerSubscriptions(subscriptions, subscriptionMutation, pinia.state.value[$id]); + } + const $reset = isOptionsStore + ? function $reset() { + const { state } = options; + const newState = state ? state() : {}; + // we use a patch to group all changes into one single subscription + this.$patch(($state) => { + // @ts-expect-error: FIXME: shouldn't error? + assign($state, newState); + }); + } + : /* istanbul ignore next */ + () => { + throw new Error(`🍍: Store "${$id}" is built using the setup syntax and does not implement $reset().`); + } + ; + function $dispose() { + scope.stop(); + subscriptions = []; + actionSubscriptions = []; + pinia._s.delete($id); + } + /** + * Helper that wraps function so it can be tracked with $onAction + * @param fn - action to wrap + * @param name - name of the action + */ + const action = (fn, name = '') => { + if (ACTION_MARKER in fn) { + fn[ACTION_NAME] = name; + return fn; + } + const wrappedAction = function () { + setActivePinia(pinia); + const args = Array.from(arguments); + const afterCallbackList = []; + const onErrorCallbackList = []; + function after(callback) { + afterCallbackList.push(callback); + } + function onError(callback) { + onErrorCallbackList.push(callback); + } + // @ts-expect-error + triggerSubscriptions(actionSubscriptions, { + args, + name: wrappedAction[ACTION_NAME], + store, + after, + onError, + }); + let ret; + try { + ret = fn.apply(this && this.$id === $id ? this : store, args); + // handle sync errors + } + catch (error) { + triggerSubscriptions(onErrorCallbackList, error); + throw error; + } + if (ret instanceof Promise) { + return ret + .then((value) => { + triggerSubscriptions(afterCallbackList, value); + return value; + }) + .catch((error) => { + triggerSubscriptions(onErrorCallbackList, error); + return Promise.reject(error); + }); + } + // trigger after callbacks + triggerSubscriptions(afterCallbackList, ret); + return ret; + }; + wrappedAction[ACTION_MARKER] = true; + wrappedAction[ACTION_NAME] = name; // will be set later + // @ts-expect-error: we are intentionally limiting the returned type to just Fn + // because all the added properties are internals that are exposed through `$onAction()` only + return wrappedAction; + }; + const _hmrPayload = /*#__PURE__*/ vueDemi.markRaw({ + actions: {}, + getters: {}, + state: [], + hotState, + }); + const partialStore = { + _p: pinia, + // _s: scope, + $id, + $onAction: addSubscription.bind(null, actionSubscriptions), + $patch, + $reset, + $subscribe(callback, options = {}) { + const removeSubscription = addSubscription(subscriptions, callback, options.detached, () => stopWatcher()); + const stopWatcher = scope.run(() => vueDemi.watch(() => pinia.state.value[$id], (state) => { + if (options.flush === 'sync' ? isSyncListening : isListening) { + callback({ + storeId: $id, + type: exports.MutationType.direct, + events: debuggerEvents, + }, state); + } + }, assign({}, $subscribeOptions, options))); + return removeSubscription; + }, + $dispose, + }; + /* istanbul ignore if */ + if (vueDemi.isVue2) { + // start as non ready + partialStore._r = false; + } + const store = vueDemi.reactive(assign({ + _hmrPayload, + _customProperties: vueDemi.markRaw(new Set()), // devtools custom properties + }, partialStore + // must be added later + // setupStore + ) + ); + // store the partial store now so the setup of stores can instantiate each other before they are finished without + // creating infinite loops. + pinia._s.set($id, store); + const runWithContext = (pinia._a && pinia._a.runWithContext) || fallbackRunWithContext; + // TODO: idea create skipSerialize that marks properties as non serializable and they are skipped + const setupStore = runWithContext(() => pinia._e.run(() => (scope = vueDemi.effectScope()).run(() => setup({ action })))); + // overwrite existing actions to support $onAction + for (const key in setupStore) { + const prop = setupStore[key]; + if ((vueDemi.isRef(prop) && !isComputed(prop)) || vueDemi.isReactive(prop)) { + // mark it as a piece of state to be serialized + if (hot) { + vueDemi.set(hotState.value, key, vueDemi.toRef(setupStore, key)); + // createOptionStore directly sets the state in pinia.state.value so we + // can just skip that + } + else if (!isOptionsStore) { + // in setup stores we must hydrate the state and sync pinia state tree with the refs the user just created + if (initialState && shouldHydrate(prop)) { + if (vueDemi.isRef(prop)) { + prop.value = initialState[key]; + } + else { + // probably a reactive object, lets recursively assign + // @ts-expect-error: prop is unknown + mergeReactiveObjects(prop, initialState[key]); + } + } + // transfer the ref to the pinia state to keep everything in sync + /* istanbul ignore if */ + if (vueDemi.isVue2) { + vueDemi.set(pinia.state.value[$id], key, prop); + } + else { + pinia.state.value[$id][key] = prop; + } + } + /* istanbul ignore else */ + { + _hmrPayload.state.push(key); + } + // action + } + else if (typeof prop === 'function') { + const actionValue = hot ? prop : action(prop, key); + // this a hot module replacement store because the hotUpdate method needs + // to do it with the right context + /* istanbul ignore if */ + if (vueDemi.isVue2) { + vueDemi.set(setupStore, key, actionValue); + } + else { + // @ts-expect-error + setupStore[key] = actionValue; + } + /* istanbul ignore else */ + { + _hmrPayload.actions[key] = prop; + } + // list actions so they can be used in plugins + // @ts-expect-error + optionsForPlugin.actions[key] = prop; + } + else { + // add getters for devtools + if (isComputed(prop)) { + _hmrPayload.getters[key] = isOptionsStore + ? // @ts-expect-error + options.getters[key] + : prop; + if (IS_CLIENT) { + const getters = setupStore._getters || + // @ts-expect-error: same + (setupStore._getters = vueDemi.markRaw([])); + getters.push(key); + } + } + } + } + // add the state, getters, and action properties + /* istanbul ignore if */ + if (vueDemi.isVue2) { + Object.keys(setupStore).forEach((key) => { + vueDemi.set(store, key, setupStore[key]); + }); + } + else { + assign(store, setupStore); + // allows retrieving reactive objects with `storeToRefs()`. Must be called after assigning to the reactive object. + // Make `storeToRefs()` work with `reactive()` #799 + assign(vueDemi.toRaw(store), setupStore); + } + // use this instead of a computed with setter to be able to create it anywhere + // without linking the computed lifespan to wherever the store is first + // created. + Object.defineProperty(store, '$state', { + get: () => (hot ? hotState.value : pinia.state.value[$id]), + set: (state) => { + /* istanbul ignore if */ + if (hot) { + throw new Error('cannot set hotState'); + } + $patch(($state) => { + // @ts-expect-error: FIXME: shouldn't error? + assign($state, state); + }); + }, + }); + // add the hotUpdate before plugins to allow them to override it + /* istanbul ignore else */ + { + store._hotUpdate = vueDemi.markRaw((newStore) => { + store._hotUpdating = true; + newStore._hmrPayload.state.forEach((stateKey) => { + if (stateKey in store.$state) { + const newStateTarget = newStore.$state[stateKey]; + const oldStateSource = store.$state[stateKey]; + if (typeof newStateTarget === 'object' && + isPlainObject(newStateTarget) && + isPlainObject(oldStateSource)) { + patchObject(newStateTarget, oldStateSource); + } + else { + // transfer the ref + newStore.$state[stateKey] = oldStateSource; + } + } + // patch direct access properties to allow store.stateProperty to work as + // store.$state.stateProperty + vueDemi.set(store, stateKey, vueDemi.toRef(newStore.$state, stateKey)); + }); + // remove deleted state properties + Object.keys(store.$state).forEach((stateKey) => { + if (!(stateKey in newStore.$state)) { + vueDemi.del(store, stateKey); + } + }); + // avoid devtools logging this as a mutation + isListening = false; + isSyncListening = false; + pinia.state.value[$id] = vueDemi.toRef(newStore._hmrPayload, 'hotState'); + isSyncListening = true; + vueDemi.nextTick().then(() => { + isListening = true; + }); + for (const actionName in newStore._hmrPayload.actions) { + const actionFn = newStore[actionName]; + vueDemi.set(store, actionName, action(actionFn, actionName)); + } + // TODO: does this work in both setup and option store? + for (const getterName in newStore._hmrPayload.getters) { + const getter = newStore._hmrPayload.getters[getterName]; + const getterValue = isOptionsStore + ? // special handling of options api + vueDemi.computed(() => { + setActivePinia(pinia); + return getter.call(store, store); + }) + : getter; + vueDemi.set(store, getterName, getterValue); + } + // remove deleted getters + Object.keys(store._hmrPayload.getters).forEach((key) => { + if (!(key in newStore._hmrPayload.getters)) { + vueDemi.del(store, key); + } + }); + // remove old actions + Object.keys(store._hmrPayload.actions).forEach((key) => { + if (!(key in newStore._hmrPayload.actions)) { + vueDemi.del(store, key); + } + }); + // update the values used in devtools and to allow deleting new properties later on + store._hmrPayload = newStore._hmrPayload; + store._getters = newStore._getters; + store._hotUpdating = false; + }); + } + if (IS_CLIENT) { + const nonEnumerable = { + writable: true, + configurable: true, + // avoid warning on devtools trying to display this property + enumerable: false, + }; + ['_p', '_hmrPayload', '_getters', '_customProperties'].forEach((p) => { + Object.defineProperty(store, p, assign({ value: store[p] }, nonEnumerable)); + }); + } + /* istanbul ignore if */ + if (vueDemi.isVue2) { + // mark the store as ready before plugins + store._r = true; + } + // apply all plugins + pinia._p.forEach((extender) => { + /* istanbul ignore else */ + if (IS_CLIENT) { + const extensions = scope.run(() => extender({ + store: store, + app: pinia._a, + pinia, + options: optionsForPlugin, + })); + Object.keys(extensions || {}).forEach((key) => store._customProperties.add(key)); + assign(store, extensions); + } + else { + assign(store, scope.run(() => extender({ + store: store, + app: pinia._a, + pinia, + options: optionsForPlugin, + }))); + } + }); + if (store.$state && + typeof store.$state === 'object' && + typeof store.$state.constructor === 'function' && + !store.$state.constructor.toString().includes('[native code]')) { + console.warn(`[🍍]: The "state" must be a plain object. It cannot be\n` + + `\tstate: () => new MyClass()\n` + + `Found in store "${store.$id}".`); + } + // only apply hydrate to option stores with an initial state in pinia + if (initialState && + isOptionsStore && + options.hydrate) { + options.hydrate(store.$state, initialState); + } + isListening = true; + isSyncListening = true; + return store; + } + // allows unused stores to be tree shaken + /*! #__NO_SIDE_EFFECTS__ */ + function defineStore( + // TODO: add proper types from above + idOrOptions, setup, setupOptions) { + let id; + let options; + const isSetupStore = typeof setup === 'function'; + if (typeof idOrOptions === 'string') { + id = idOrOptions; + // the option store setup will contain the actual options in this case + options = isSetupStore ? setupOptions : setup; + } + else { + options = idOrOptions; + id = idOrOptions.id; + if (typeof id !== 'string') { + throw new Error(`[🍍]: "defineStore()" must be passed a store id as its first argument.`); + } + } + function useStore(pinia, hot) { + const hasContext = vueDemi.hasInjectionContext(); + pinia = + // in test mode, ignore the argument provided as we can always retrieve a + // pinia instance with getActivePinia() + (pinia) || + (hasContext ? vueDemi.inject(piniaSymbol, null) : null); + if (pinia) + setActivePinia(pinia); + if (!activePinia) { + throw new Error(`[🍍]: "getActivePinia()" was called but there was no active Pinia. Are you trying to use a store before calling "app.use(pinia)"?\n` + + `See https://pinia.vuejs.org/core-concepts/outside-component-usage.html for help.\n` + + `This will fail in production.`); + } + pinia = activePinia; + if (!pinia._s.has(id)) { + // creating the store registers it in `pinia._s` + if (isSetupStore) { + createSetupStore(id, setup, options, pinia); + } + else { + createOptionsStore(id, options, pinia); + } + /* istanbul ignore else */ + { + // @ts-expect-error: not the right inferred type + useStore._pinia = pinia; + } + } + const store = pinia._s.get(id); + if (hot) { + const hotId = '__hot:' + id; + const newStore = isSetupStore + ? createSetupStore(hotId, setup, options, pinia, true) + : createOptionsStore(hotId, assign({}, options), pinia, true); + hot._hotUpdate(newStore); + // cleanup the state properties and the store from the cache + delete pinia.state.value[hotId]; + pinia._s.delete(hotId); + } + if (IS_CLIENT) { + const currentInstance = vueDemi.getCurrentInstance(); + // save stores in instances to access them devtools + if (currentInstance && + currentInstance.proxy && + // avoid adding stores that are just built for hot module replacement + !hot) { + const vm = currentInstance.proxy; + const cache = '_pStores' in vm ? vm._pStores : (vm._pStores = {}); + cache[id] = store; + } + } + // StoreGeneric cannot be casted towards Store + return store; + } + useStore.$id = id; + return useStore; + } + + let mapStoreSuffix = 'Store'; + /** + * Changes the suffix added by `mapStores()`. Can be set to an empty string. + * Defaults to `"Store"`. Make sure to extend the MapStoresCustomization + * interface if you are using TypeScript. + * + * @param suffix - new suffix + */ + function setMapStoreSuffix(suffix // could be 'Store' but that would be annoying for JS + ) { + mapStoreSuffix = suffix; + } + /** + * Allows using stores without the composition API (`setup()`) by generating an + * object to be spread in the `computed` field of a component. It accepts a list + * of store definitions. + * + * @example + * ```js + * export default { + * computed: { + * // other computed properties + * ...mapStores(useUserStore, useCartStore) + * }, + * + * created() { + * this.userStore // store with id "user" + * this.cartStore // store with id "cart" + * } + * } + * ``` + * + * @param stores - list of stores to map to an object + */ + function mapStores(...stores) { + if (Array.isArray(stores[0])) { + console.warn(`[🍍]: Directly pass all stores to "mapStores()" without putting them in an array:\n` + + `Replace\n` + + `\tmapStores([useAuthStore, useCartStore])\n` + + `with\n` + + `\tmapStores(useAuthStore, useCartStore)\n` + + `This will fail in production if not fixed.`); + stores = stores[0]; + } + return stores.reduce((reduced, useStore) => { + // @ts-expect-error: $id is added by defineStore + reduced[useStore.$id + mapStoreSuffix] = function () { + return useStore(this.$pinia); + }; + return reduced; + }, {}); + } + /** + * Allows using state and getters from one store without using the composition + * API (`setup()`) by generating an object to be spread in the `computed` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ + function mapState(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + reduced[key] = function () { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key]; + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function () { + const store = useStore(this.$pinia); + const storeKey = keysOrMapper[key]; + // for some reason TS is unable to infer the type of storeKey to be a + // function + return typeof storeKey === 'function' + ? storeKey.call(this, store) + : // @ts-expect-error: FIXME: should work? + store[storeKey]; + }; + return reduced; + }, {}); + } + /** + * Alias for `mapState()`. You should use `mapState()` instead. + * @deprecated use `mapState()` instead. + */ + const mapGetters = mapState; + /** + * Allows directly using actions from your store without using the composition + * API (`setup()`) by generating an object to be spread in the `methods` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ + function mapActions(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function (...args) { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key](...args); + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function (...args) { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[keysOrMapper[key]](...args); + }; + return reduced; + }, {}); + } + /** + * Allows using state and getters from one store without using the composition + * API (`setup()`) by generating an object to be spread in the `computed` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ + function mapWritableState(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + // @ts-ignore + reduced[key] = { + get() { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key]; + }, + set(value) { + // @ts-expect-error: FIXME: should work? + return (useStore(this.$pinia)[key] = value); + }, + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-ignore + reduced[key] = { + get() { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[keysOrMapper[key]]; + }, + set(value) { + // @ts-expect-error: FIXME: should work? + return (useStore(this.$pinia)[keysOrMapper[key]] = value); + }, + }; + return reduced; + }, {}); + } + + /** + * Creates an object of references with all the state, getters, and plugin-added + * state properties of the store. Similar to `toRefs()` but specifically + * designed for Pinia stores so methods and non reactive properties are + * completely ignored. + * + * @param store - store to extract the refs from + */ + function storeToRefs(store) { + // See https://github.com/vuejs/pinia/issues/852 + // It's easier to just use toRefs() even if it includes more stuff + if (vueDemi.isVue2) { + // @ts-expect-error: toRefs include methods and others + return vueDemi.toRefs(store); + } + else { + const rawStore = vueDemi.toRaw(store); + const refs = {}; + for (const key in rawStore) { + const value = rawStore[key]; + if (vueDemi.isRef(value) || vueDemi.isReactive(value)) { + // @ts-expect-error: the key is state or getter + refs[key] = + // --- + vueDemi.toRef(store, key); + } + } + return refs; + } + } + + /** + * Vue 2 Plugin that must be installed for pinia to work. Note **you don't need + * this plugin if you are using Nuxt.js**. Use the `buildModule` instead: + * https://pinia.vuejs.org/ssr/nuxt.html. + * + * @example + * ```js + * import Vue from 'vue' + * import { PiniaVuePlugin, createPinia } from 'pinia' + * + * Vue.use(PiniaVuePlugin) + * const pinia = createPinia() + * + * new Vue({ + * el: '#app', + * // ... + * pinia, + * }) + * ``` + * + * @param _Vue - `Vue` imported from 'vue'. + */ + const PiniaVuePlugin = function (_Vue) { + // Equivalent of + // app.config.globalProperties.$pinia = pinia + _Vue.mixin({ + beforeCreate() { + const options = this.$options; + if (options.pinia) { + const pinia = options.pinia; + // HACK: taken from provide(): https://github.com/vuejs/composition-api/blob/main/src/apis/inject.ts#L31 + /* istanbul ignore else */ + if (!this._provided) { + const provideCache = {}; + Object.defineProperty(this, '_provided', { + get: () => provideCache, + set: (v) => Object.assign(provideCache, v), + }); + } + this._provided[piniaSymbol] = pinia; + // propagate the pinia instance in an SSR friendly way + // avoid adding it to nuxt twice + /* istanbul ignore else */ + if (!this.$pinia) { + this.$pinia = pinia; + } + pinia._a = this; + if (IS_CLIENT) { + // this allows calling useStore() outside of a component setup after + // installing pinia's plugin + setActivePinia(pinia); + } + if (IS_CLIENT) { + registerPiniaDevtools(pinia._a, pinia); + } + } + else if (!this.$pinia && options.parent && options.parent.$pinia) { + this.$pinia = options.parent.$pinia; + } + }, + destroyed() { + delete this._pStores; + }, + }); + }; + + exports.PiniaVuePlugin = PiniaVuePlugin; + exports.acceptHMRUpdate = acceptHMRUpdate; + exports.createPinia = createPinia; + exports.defineStore = defineStore; + exports.disposePinia = disposePinia; + exports.getActivePinia = getActivePinia; + exports.mapActions = mapActions; + exports.mapGetters = mapGetters; + exports.mapState = mapState; + exports.mapStores = mapStores; + exports.mapWritableState = mapWritableState; + exports.setActivePinia = setActivePinia; + exports.setMapStoreSuffix = setMapStoreSuffix; + exports.shouldHydrate = shouldHydrate; + exports.skipHydrate = skipHydrate; + exports.storeToRefs = storeToRefs; + + return exports; + +})({}, VueDemi); diff --git a/node_modules/pinia/dist/pinia.iife.prod.js b/node_modules/pinia/dist/pinia.iife.prod.js new file mode 100644 index 0000000..99ef186 --- /dev/null +++ b/node_modules/pinia/dist/pinia.iife.prod.js @@ -0,0 +1,7 @@ +/*! + * pinia v2.2.5 + * (c) 2024 Eduardo San Martin Morote + * @license MIT + */ +var Pinia=function(t,e){"use strict";let n;const i=t=>n=t,s=Symbol();function o(t){return t&&"object"==typeof t&&"[object Object]"===Object.prototype.toString.call(t)&&"function"!=typeof t.toJSON}var r;t.MutationType=void 0,(r=t.MutationType||(t.MutationType={})).direct="direct",r.patchObject="patch object",r.patchFunction="patch function";const c="undefined"!=typeof window;const a=()=>{};function u(t,n,i,s=a){t.push(n);const o=()=>{const e=t.indexOf(n);e>-1&&(t.splice(e,1),s())};return!i&&e.getCurrentScope()&&e.onScopeDispose(o),o}function p(t,...e){t.slice().forEach((t=>{t(...e)}))}const f=t=>t(),h=Symbol(),l=Symbol();function d(t,n){t instanceof Map&&n instanceof Map?n.forEach(((e,n)=>t.set(n,e))):t instanceof Set&&n instanceof Set&&n.forEach(t.add,t);for(const i in n){if(!n.hasOwnProperty(i))continue;const s=n[i],r=t[i];t[i]=o(r)&&o(s)&&t.hasOwnProperty(i)&&!e.isRef(s)&&!e.isReactive(s)?d(r,s):s}return t}const y=Symbol(),v=new WeakMap;function $(t){return e.isVue2?!v.has(t):!o(t)||!t.hasOwnProperty(y)}const{assign:_}=Object;function b(n,s,o={},r,c,y){let v;const b=_({actions:{}},o),j={deep:!0};let S,m,O,g=[],R=[];const P=r.state.value[n];let V;function w(i){let s;S=m=!1,"function"==typeof i?(i(r.state.value[n]),s={type:t.MutationType.patchFunction,storeId:n,events:O}):(d(r.state.value[n],i),s={type:t.MutationType.patchObject,payload:i,storeId:n,events:O});const o=V=Symbol();e.nextTick().then((()=>{V===o&&(S=!0)})),m=!0,p(g,s,r.state.value[n])}y||P||(e.isVue2?e.set(r.state.value,n,{}):r.state.value[n]={}),e.ref({});const M=y?function(){const{state:t}=o,e=t?t():{};this.$patch((t=>{_(t,e)}))}:a;const A=(t,e="")=>{if(h in t)return t[l]=e,t;const s=function(){i(r);const e=Array.from(arguments),o=[],c=[];let a;p(R,{args:e,name:s[l],store:T,after:function(t){o.push(t)},onError:function(t){c.push(t)}});try{a=t.apply(this&&this.$id===n?this:T,e)}catch(t){throw p(c,t),t}return a instanceof Promise?a.then((t=>(p(o,t),t))).catch((t=>(p(c,t),Promise.reject(t)))):(p(o,a),a)};return s[h]=!0,s[l]=e,s},k={_p:r,$id:n,$onAction:u.bind(null,R),$patch:w,$reset:M,$subscribe(i,s={}){const o=u(g,i,s.detached,(()=>c())),c=v.run((()=>e.watch((()=>r.state.value[n]),(e=>{("sync"===s.flush?m:S)&&i({storeId:n,type:t.MutationType.direct,events:O},e)}),_({},j,s))));return o},$dispose:function(){v.stop(),g=[],R=[],r._s.delete(n)}};e.isVue2&&(k._r=!1);const T=e.reactive(k);r._s.set(n,T);const x=(r._a&&r._a.runWithContext||f)((()=>r._e.run((()=>(v=e.effectScope()).run((()=>s({action:A})))))));for(const t in x){const i=x[t];if(e.isRef(i)&&(!e.isRef(E=i)||!E.effect)||e.isReactive(i))y||(P&&$(i)&&(e.isRef(i)?i.value=P[t]:d(i,P[t])),e.isVue2?e.set(r.state.value[n],t,i):r.state.value[n][t]=i);else if("function"==typeof i){const n=A(i,t);e.isVue2?e.set(x,t,n):x[t]=n,b.actions[t]=i}}var E;return e.isVue2?Object.keys(x).forEach((t=>{e.set(T,t,x[t])})):(_(T,x),_(e.toRaw(T),x)),Object.defineProperty(T,"$state",{get:()=>r.state.value[n],set:t=>{w((e=>{_(e,t)}))}}),e.isVue2&&(T._r=!0),r._p.forEach((t=>{_(T,v.run((()=>t({store:T,app:r._a,pinia:r,options:b}))))})),P&&y&&o.hydrate&&o.hydrate(T.$state,P),S=!0,m=!0,T} +/*! #__NO_SIDE_EFFECTS__ */let j="Store";function S(t,e){return Array.isArray(e)?e.reduce(((e,n)=>(e[n]=function(){return t(this.$pinia)[n]},e)),{}):Object.keys(e).reduce(((n,i)=>(n[i]=function(){const n=t(this.$pinia),s=e[i];return"function"==typeof s?s.call(this,n):n[s]},n)),{})}const m=S;return t.PiniaVuePlugin=function(t){t.mixin({beforeCreate(){const t=this.$options;if(t.pinia){const e=t.pinia;if(!this._provided){const t={};Object.defineProperty(this,"_provided",{get:()=>t,set:e=>Object.assign(t,e)})}this._provided[s]=e,this.$pinia||(this.$pinia=e),e._a=this,c&&i(e)}else!this.$pinia&&t.parent&&t.parent.$pinia&&(this.$pinia=t.parent.$pinia)},destroyed(){delete this._pStores}})},t.acceptHMRUpdate=function(t,e){return()=>{}},t.createPinia=function(){const t=e.effectScope(!0),n=t.run((()=>e.ref({})));let o=[],r=[];const c=e.markRaw({install(t){i(c),e.isVue2||(c._a=t,t.provide(s,c),t.config.globalProperties.$pinia=c,r.forEach((t=>o.push(t))),r=[])},use(t){return this._a||e.isVue2?o.push(t):r.push(t),this},_p:o,_a:null,_e:t,_s:new Map,state:n});return c},t.defineStore=function(t,o,r){let c,a;const u="function"==typeof o;function p(t,r){const p=e.hasInjectionContext();(t=t||(p?e.inject(s,null):null))&&i(t),(t=n)._s.has(c)||(u?b(c,o,a,t):function(t,n,s){const{state:o,actions:r,getters:c}=n,a=s.state.value[t];let u;u=b(t,(function(){a||(e.isVue2?e.set(s.state.value,t,o?o():{}):s.state.value[t]=o?o():{});const n=e.toRefs(s.state.value[t]);return _(n,r,Object.keys(c||{}).reduce(((n,o)=>(n[o]=e.markRaw(e.computed((()=>{i(s);const n=s._s.get(t);if(!e.isVue2||n._r)return c[o].call(n,n)}))),n)),{}))}),n,s,0,!0)}(c,a,t));return t._s.get(c)}return"string"==typeof t?(c=t,a=u?r:o):(a=t,c=t.id),p.$id=c,p},t.disposePinia=function(t){t._e.stop(),t._s.clear(),t._p.splice(0),t.state.value={},t._a=null},t.getActivePinia=()=>e.hasInjectionContext()&&e.inject(s)||n,t.mapActions=function(t,e){return Array.isArray(e)?e.reduce(((e,n)=>(e[n]=function(...e){return t(this.$pinia)[n](...e)},e)),{}):Object.keys(e).reduce(((n,i)=>(n[i]=function(...n){return t(this.$pinia)[e[i]](...n)},n)),{})},t.mapGetters=m,t.mapState=S,t.mapStores=function(...t){return t.reduce(((t,e)=>(t[e.$id+j]=function(){return e(this.$pinia)},t)),{})},t.mapWritableState=function(t,e){return Array.isArray(e)?e.reduce(((e,n)=>(e[n]={get(){return t(this.$pinia)[n]},set(e){return t(this.$pinia)[n]=e}},e)),{}):Object.keys(e).reduce(((n,i)=>(n[i]={get(){return t(this.$pinia)[e[i]]},set(n){return t(this.$pinia)[e[i]]=n}},n)),{})},t.setActivePinia=i,t.setMapStoreSuffix=function(t){j=t},t.shouldHydrate=$,t.skipHydrate=function(t){return e.isVue2?v.set(t,1)&&t:Object.defineProperty(t,y,{})},t.storeToRefs=function(t){if(e.isVue2)return e.toRefs(t);{const n=e.toRaw(t),i={};for(const s in n){const o=n[s];(e.isRef(o)||e.isReactive(o))&&(i[s]=e.toRef(t,s))}return i}},t}({},VueDemi); diff --git a/node_modules/pinia/dist/pinia.mjs b/node_modules/pinia/dist/pinia.mjs new file mode 100644 index 0000000..611a112 --- /dev/null +++ b/node_modules/pinia/dist/pinia.mjs @@ -0,0 +1,2043 @@ +/*! + * pinia v2.2.5 + * (c) 2024 Eduardo San Martin Morote + * @license MIT + */ +import { hasInjectionContext, inject, toRaw, watch, unref, markRaw, effectScope, ref, isVue2, isRef, isReactive, set, getCurrentScope, onScopeDispose, getCurrentInstance, reactive, toRef, del, nextTick, computed, toRefs } from 'vue-demi'; +import { setupDevtoolsPlugin } from '@vue/devtools-api'; + +/** + * setActivePinia must be called to handle SSR at the top of functions like + * `fetch`, `setup`, `serverPrefetch` and others + */ +let activePinia; +/** + * Sets or unsets the active pinia. Used in SSR and internally when calling + * actions and getters + * + * @param pinia - Pinia instance + */ +// @ts-expect-error: cannot constrain the type of the return +const setActivePinia = (pinia) => (activePinia = pinia); +/** + * Get the currently active pinia if there is any. + */ +const getActivePinia = () => (hasInjectionContext() && inject(piniaSymbol)) || activePinia; +const piniaSymbol = ((process.env.NODE_ENV !== 'production') ? Symbol('pinia') : /* istanbul ignore next */ Symbol()); + +function isPlainObject( +// eslint-disable-next-line @typescript-eslint/no-explicit-any +o) { + return (o && + typeof o === 'object' && + Object.prototype.toString.call(o) === '[object Object]' && + typeof o.toJSON !== 'function'); +} +// type DeepReadonly = { readonly [P in keyof T]: DeepReadonly } +// TODO: can we change these to numbers? +/** + * Possible types for SubscriptionCallback + */ +var MutationType; +(function (MutationType) { + /** + * Direct mutation of the state: + * + * - `store.name = 'new name'` + * - `store.$state.name = 'new name'` + * - `store.list.push('new item')` + */ + MutationType["direct"] = "direct"; + /** + * Mutated the state with `$patch` and an object + * + * - `store.$patch({ name: 'newName' })` + */ + MutationType["patchObject"] = "patch object"; + /** + * Mutated the state with `$patch` and a function + * + * - `store.$patch(state => state.name = 'newName')` + */ + MutationType["patchFunction"] = "patch function"; + // maybe reset? for $state = {} and $reset +})(MutationType || (MutationType = {})); + +const IS_CLIENT = typeof window !== 'undefined'; + +/* + * FileSaver.js A saveAs() FileSaver implementation. + * + * Originally by Eli Grey, adapted as an ESM module by Eduardo San Martin + * Morote. + * + * License : MIT + */ +// The one and only way of getting global scope in all environments +// https://stackoverflow.com/q/3277182/1008999 +const _global = /*#__PURE__*/ (() => typeof window === 'object' && window.window === window + ? window + : typeof self === 'object' && self.self === self + ? self + : typeof global === 'object' && global.global === global + ? global + : typeof globalThis === 'object' + ? globalThis + : { HTMLElement: null })(); +function bom(blob, { autoBom = false } = {}) { + // prepend BOM for UTF-8 XML and text/* types (including HTML) + // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF + if (autoBom && + /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) { + return new Blob([String.fromCharCode(0xfeff), blob], { type: blob.type }); + } + return blob; +} +function download(url, name, opts) { + const xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.responseType = 'blob'; + xhr.onload = function () { + saveAs(xhr.response, name, opts); + }; + xhr.onerror = function () { + console.error('could not download file'); + }; + xhr.send(); +} +function corsEnabled(url) { + const xhr = new XMLHttpRequest(); + // use sync to avoid popup blocker + xhr.open('HEAD', url, false); + try { + xhr.send(); + } + catch (e) { } + return xhr.status >= 200 && xhr.status <= 299; +} +// `a.click()` doesn't work for all browsers (#465) +function click(node) { + try { + node.dispatchEvent(new MouseEvent('click')); + } + catch (e) { + const evt = document.createEvent('MouseEvents'); + evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null); + node.dispatchEvent(evt); + } +} +const _navigator = typeof navigator === 'object' ? navigator : { userAgent: '' }; +// Detect WebView inside a native macOS app by ruling out all browsers +// We just need to check for 'Safari' because all other browsers (besides Firefox) include that too +// https://www.whatismybrowser.com/guides/the-latest-user-agent/macos +const isMacOSWebView = /*#__PURE__*/ (() => /Macintosh/.test(_navigator.userAgent) && + /AppleWebKit/.test(_navigator.userAgent) && + !/Safari/.test(_navigator.userAgent))(); +const saveAs = !IS_CLIENT + ? () => { } // noop + : // Use download attribute first if possible (#193 Lumia mobile) unless this is a macOS WebView or mini program + typeof HTMLAnchorElement !== 'undefined' && + 'download' in HTMLAnchorElement.prototype && + !isMacOSWebView + ? downloadSaveAs + : // Use msSaveOrOpenBlob as a second approach + 'msSaveOrOpenBlob' in _navigator + ? msSaveAs + : // Fallback to using FileReader and a popup + fileSaverSaveAs; +function downloadSaveAs(blob, name = 'download', opts) { + const a = document.createElement('a'); + a.download = name; + a.rel = 'noopener'; // tabnabbing + // TODO: detect chrome extensions & packaged apps + // a.target = '_blank' + if (typeof blob === 'string') { + // Support regular links + a.href = blob; + if (a.origin !== location.origin) { + if (corsEnabled(a.href)) { + download(blob, name, opts); + } + else { + a.target = '_blank'; + click(a); + } + } + else { + click(a); + } + } + else { + // Support blobs + a.href = URL.createObjectURL(blob); + setTimeout(function () { + URL.revokeObjectURL(a.href); + }, 4e4); // 40s + setTimeout(function () { + click(a); + }, 0); + } +} +function msSaveAs(blob, name = 'download', opts) { + if (typeof blob === 'string') { + if (corsEnabled(blob)) { + download(blob, name, opts); + } + else { + const a = document.createElement('a'); + a.href = blob; + a.target = '_blank'; + setTimeout(function () { + click(a); + }); + } + } + else { + // @ts-ignore: works on windows + navigator.msSaveOrOpenBlob(bom(blob, opts), name); + } +} +function fileSaverSaveAs(blob, name, opts, popup) { + // Open a popup immediately do go around popup blocker + // Mostly only available on user interaction and the fileReader is async so... + popup = popup || open('', '_blank'); + if (popup) { + popup.document.title = popup.document.body.innerText = 'downloading...'; + } + if (typeof blob === 'string') + return download(blob, name, opts); + const force = blob.type === 'application/octet-stream'; + const isSafari = /constructor/i.test(String(_global.HTMLElement)) || 'safari' in _global; + const isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent); + if ((isChromeIOS || (force && isSafari) || isMacOSWebView) && + typeof FileReader !== 'undefined') { + // Safari doesn't allow downloading of blob URLs + const reader = new FileReader(); + reader.onloadend = function () { + let url = reader.result; + if (typeof url !== 'string') { + popup = null; + throw new Error('Wrong reader.result type'); + } + url = isChromeIOS + ? url + : url.replace(/^data:[^;]*;/, 'data:attachment/file;'); + if (popup) { + popup.location.href = url; + } + else { + location.assign(url); + } + popup = null; // reverse-tabnabbing #460 + }; + reader.readAsDataURL(blob); + } + else { + const url = URL.createObjectURL(blob); + if (popup) + popup.location.assign(url); + else + location.href = url; + popup = null; // reverse-tabnabbing #460 + setTimeout(function () { + URL.revokeObjectURL(url); + }, 4e4); // 40s + } +} + +/** + * Shows a toast or console.log + * + * @param message - message to log + * @param type - different color of the tooltip + */ +function toastMessage(message, type) { + const piniaMessage = '🍍 ' + message; + if (typeof __VUE_DEVTOOLS_TOAST__ === 'function') { + // No longer available :( + __VUE_DEVTOOLS_TOAST__(piniaMessage, type); + } + else if (type === 'error') { + console.error(piniaMessage); + } + else if (type === 'warn') { + console.warn(piniaMessage); + } + else { + console.log(piniaMessage); + } +} +function isPinia(o) { + return '_a' in o && 'install' in o; +} + +/** + * This file contain devtools actions, they are not Pinia actions. + */ +// --- +function checkClipboardAccess() { + if (!('clipboard' in navigator)) { + toastMessage(`Your browser doesn't support the Clipboard API`, 'error'); + return true; + } +} +function checkNotFocusedError(error) { + if (error instanceof Error && + error.message.toLowerCase().includes('document is not focused')) { + toastMessage('You need to activate the "Emulate a focused page" setting in the "Rendering" panel of devtools.', 'warn'); + return true; + } + return false; +} +async function actionGlobalCopyState(pinia) { + if (checkClipboardAccess()) + return; + try { + await navigator.clipboard.writeText(JSON.stringify(pinia.state.value)); + toastMessage('Global state copied to clipboard.'); + } + catch (error) { + if (checkNotFocusedError(error)) + return; + toastMessage(`Failed to serialize the state. Check the console for more details.`, 'error'); + console.error(error); + } +} +async function actionGlobalPasteState(pinia) { + if (checkClipboardAccess()) + return; + try { + loadStoresState(pinia, JSON.parse(await navigator.clipboard.readText())); + toastMessage('Global state pasted from clipboard.'); + } + catch (error) { + if (checkNotFocusedError(error)) + return; + toastMessage(`Failed to deserialize the state from clipboard. Check the console for more details.`, 'error'); + console.error(error); + } +} +async function actionGlobalSaveState(pinia) { + try { + saveAs(new Blob([JSON.stringify(pinia.state.value)], { + type: 'text/plain;charset=utf-8', + }), 'pinia-state.json'); + } + catch (error) { + toastMessage(`Failed to export the state as JSON. Check the console for more details.`, 'error'); + console.error(error); + } +} +let fileInput; +function getFileOpener() { + if (!fileInput) { + fileInput = document.createElement('input'); + fileInput.type = 'file'; + fileInput.accept = '.json'; + } + function openFile() { + return new Promise((resolve, reject) => { + fileInput.onchange = async () => { + const files = fileInput.files; + if (!files) + return resolve(null); + const file = files.item(0); + if (!file) + return resolve(null); + return resolve({ text: await file.text(), file }); + }; + // @ts-ignore: TODO: changed from 4.3 to 4.4 + fileInput.oncancel = () => resolve(null); + fileInput.onerror = reject; + fileInput.click(); + }); + } + return openFile; +} +async function actionGlobalOpenStateFile(pinia) { + try { + const open = getFileOpener(); + const result = await open(); + if (!result) + return; + const { text, file } = result; + loadStoresState(pinia, JSON.parse(text)); + toastMessage(`Global state imported from "${file.name}".`); + } + catch (error) { + toastMessage(`Failed to import the state from JSON. Check the console for more details.`, 'error'); + console.error(error); + } +} +function loadStoresState(pinia, state) { + for (const key in state) { + const storeState = pinia.state.value[key]; + // store is already instantiated, patch it + if (storeState) { + Object.assign(storeState, state[key]); + } + else { + // store is not instantiated, set the initial state + pinia.state.value[key] = state[key]; + } + } +} + +function formatDisplay(display) { + return { + _custom: { + display, + }, + }; +} +const PINIA_ROOT_LABEL = '🍍 Pinia (root)'; +const PINIA_ROOT_ID = '_root'; +function formatStoreForInspectorTree(store) { + return isPinia(store) + ? { + id: PINIA_ROOT_ID, + label: PINIA_ROOT_LABEL, + } + : { + id: store.$id, + label: store.$id, + }; +} +function formatStoreForInspectorState(store) { + if (isPinia(store)) { + const storeNames = Array.from(store._s.keys()); + const storeMap = store._s; + const state = { + state: storeNames.map((storeId) => ({ + editable: true, + key: storeId, + value: store.state.value[storeId], + })), + getters: storeNames + .filter((id) => storeMap.get(id)._getters) + .map((id) => { + const store = storeMap.get(id); + return { + editable: false, + key: id, + value: store._getters.reduce((getters, key) => { + getters[key] = store[key]; + return getters; + }, {}), + }; + }), + }; + return state; + } + const state = { + state: Object.keys(store.$state).map((key) => ({ + editable: true, + key, + value: store.$state[key], + })), + }; + // avoid adding empty getters + if (store._getters && store._getters.length) { + state.getters = store._getters.map((getterName) => ({ + editable: false, + key: getterName, + value: store[getterName], + })); + } + if (store._customProperties.size) { + state.customProperties = Array.from(store._customProperties).map((key) => ({ + editable: true, + key, + value: store[key], + })); + } + return state; +} +function formatEventData(events) { + if (!events) + return {}; + if (Array.isArray(events)) { + // TODO: handle add and delete for arrays and objects + return events.reduce((data, event) => { + data.keys.push(event.key); + data.operations.push(event.type); + data.oldValue[event.key] = event.oldValue; + data.newValue[event.key] = event.newValue; + return data; + }, { + oldValue: {}, + keys: [], + operations: [], + newValue: {}, + }); + } + else { + return { + operation: formatDisplay(events.type), + key: formatDisplay(events.key), + oldValue: events.oldValue, + newValue: events.newValue, + }; + } +} +function formatMutationType(type) { + switch (type) { + case MutationType.direct: + return 'mutation'; + case MutationType.patchFunction: + return '$patch'; + case MutationType.patchObject: + return '$patch'; + default: + return 'unknown'; + } +} + +// timeline can be paused when directly changing the state +let isTimelineActive = true; +const componentStateTypes = []; +const MUTATIONS_LAYER_ID = 'pinia:mutations'; +const INSPECTOR_ID = 'pinia'; +const { assign: assign$1 } = Object; +/** + * Gets the displayed name of a store in devtools + * + * @param id - id of the store + * @returns a formatted string + */ +const getStoreType = (id) => '🍍 ' + id; +/** + * Add the pinia plugin without any store. Allows displaying a Pinia plugin tab + * as soon as it is added to the application. + * + * @param app - Vue application + * @param pinia - pinia instance + */ +function registerPiniaDevtools(app, pinia) { + setupDevtoolsPlugin({ + id: 'dev.esm.pinia', + label: 'Pinia 🍍', + logo: 'https://pinia.vuejs.org/logo.svg', + packageName: 'pinia', + homepage: 'https://pinia.vuejs.org', + componentStateTypes, + app, + }, (api) => { + if (typeof api.now !== 'function') { + toastMessage('You seem to be using an outdated version of Vue Devtools. Are you still using the Beta release instead of the stable one? You can find the links at https://devtools.vuejs.org/guide/installation.html.'); + } + api.addTimelineLayer({ + id: MUTATIONS_LAYER_ID, + label: `Pinia 🍍`, + color: 0xe5df88, + }); + api.addInspector({ + id: INSPECTOR_ID, + label: 'Pinia 🍍', + icon: 'storage', + treeFilterPlaceholder: 'Search stores', + actions: [ + { + icon: 'content_copy', + action: () => { + actionGlobalCopyState(pinia); + }, + tooltip: 'Serialize and copy the state', + }, + { + icon: 'content_paste', + action: async () => { + await actionGlobalPasteState(pinia); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + }, + tooltip: 'Replace the state with the content of your clipboard', + }, + { + icon: 'save', + action: () => { + actionGlobalSaveState(pinia); + }, + tooltip: 'Save the state as a JSON file', + }, + { + icon: 'folder_open', + action: async () => { + await actionGlobalOpenStateFile(pinia); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + }, + tooltip: 'Import the state from a JSON file', + }, + ], + nodeActions: [ + { + icon: 'restore', + tooltip: 'Reset the state (with "$reset")', + action: (nodeId) => { + const store = pinia._s.get(nodeId); + if (!store) { + toastMessage(`Cannot reset "${nodeId}" store because it wasn't found.`, 'warn'); + } + else if (typeof store.$reset !== 'function') { + toastMessage(`Cannot reset "${nodeId}" store because it doesn't have a "$reset" method implemented.`, 'warn'); + } + else { + store.$reset(); + toastMessage(`Store "${nodeId}" reset.`); + } + }, + }, + ], + }); + api.on.inspectComponent((payload, ctx) => { + const proxy = (payload.componentInstance && + payload.componentInstance.proxy); + if (proxy && proxy._pStores) { + const piniaStores = payload.componentInstance.proxy._pStores; + Object.values(piniaStores).forEach((store) => { + payload.instanceData.state.push({ + type: getStoreType(store.$id), + key: 'state', + editable: true, + value: store._isOptionsAPI + ? { + _custom: { + value: toRaw(store.$state), + actions: [ + { + icon: 'restore', + tooltip: 'Reset the state of this store', + action: () => store.$reset(), + }, + ], + }, + } + : // NOTE: workaround to unwrap transferred refs + Object.keys(store.$state).reduce((state, key) => { + state[key] = store.$state[key]; + return state; + }, {}), + }); + if (store._getters && store._getters.length) { + payload.instanceData.state.push({ + type: getStoreType(store.$id), + key: 'getters', + editable: false, + value: store._getters.reduce((getters, key) => { + try { + getters[key] = store[key]; + } + catch (error) { + // @ts-expect-error: we just want to show it in devtools + getters[key] = error; + } + return getters; + }, {}), + }); + } + }); + } + }); + api.on.getInspectorTree((payload) => { + if (payload.app === app && payload.inspectorId === INSPECTOR_ID) { + let stores = [pinia]; + stores = stores.concat(Array.from(pinia._s.values())); + payload.rootNodes = (payload.filter + ? stores.filter((store) => '$id' in store + ? store.$id + .toLowerCase() + .includes(payload.filter.toLowerCase()) + : PINIA_ROOT_LABEL.toLowerCase().includes(payload.filter.toLowerCase())) + : stores).map(formatStoreForInspectorTree); + } + }); + // Expose pinia instance as $pinia to window + globalThis.$pinia = pinia; + api.on.getInspectorState((payload) => { + if (payload.app === app && payload.inspectorId === INSPECTOR_ID) { + const inspectedStore = payload.nodeId === PINIA_ROOT_ID + ? pinia + : pinia._s.get(payload.nodeId); + if (!inspectedStore) { + // this could be the selected store restored for a different project + // so it's better not to say anything here + return; + } + if (inspectedStore) { + // Expose selected store as $store to window + if (payload.nodeId !== PINIA_ROOT_ID) + globalThis.$store = toRaw(inspectedStore); + payload.state = formatStoreForInspectorState(inspectedStore); + } + } + }); + api.on.editInspectorState((payload, ctx) => { + if (payload.app === app && payload.inspectorId === INSPECTOR_ID) { + const inspectedStore = payload.nodeId === PINIA_ROOT_ID + ? pinia + : pinia._s.get(payload.nodeId); + if (!inspectedStore) { + return toastMessage(`store "${payload.nodeId}" not found`, 'error'); + } + const { path } = payload; + if (!isPinia(inspectedStore)) { + // access only the state + if (path.length !== 1 || + !inspectedStore._customProperties.has(path[0]) || + path[0] in inspectedStore.$state) { + path.unshift('$state'); + } + } + else { + // Root access, we can omit the `.value` because the devtools API does it for us + path.unshift('state'); + } + isTimelineActive = false; + payload.set(inspectedStore, path, payload.state.value); + isTimelineActive = true; + } + }); + api.on.editComponentState((payload) => { + if (payload.type.startsWith('🍍')) { + const storeId = payload.type.replace(/^🍍\s*/, ''); + const store = pinia._s.get(storeId); + if (!store) { + return toastMessage(`store "${storeId}" not found`, 'error'); + } + const { path } = payload; + if (path[0] !== 'state') { + return toastMessage(`Invalid path for store "${storeId}":\n${path}\nOnly state can be modified.`); + } + // rewrite the first entry to be able to directly set the state as + // well as any other path + path[0] = '$state'; + isTimelineActive = false; + payload.set(store, path, payload.state.value); + isTimelineActive = true; + } + }); + }); +} +function addStoreToDevtools(app, store) { + if (!componentStateTypes.includes(getStoreType(store.$id))) { + componentStateTypes.push(getStoreType(store.$id)); + } + setupDevtoolsPlugin({ + id: 'dev.esm.pinia', + label: 'Pinia 🍍', + logo: 'https://pinia.vuejs.org/logo.svg', + packageName: 'pinia', + homepage: 'https://pinia.vuejs.org', + componentStateTypes, + app, + settings: { + logStoreChanges: { + label: 'Notify about new/deleted stores', + type: 'boolean', + defaultValue: true, + }, + // useEmojis: { + // label: 'Use emojis in messages ⚡️', + // type: 'boolean', + // defaultValue: true, + // }, + }, + }, (api) => { + // gracefully handle errors + const now = typeof api.now === 'function' ? api.now.bind(api) : Date.now; + store.$onAction(({ after, onError, name, args }) => { + const groupId = runningActionId++; + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: '🛫 ' + name, + subtitle: 'start', + data: { + store: formatDisplay(store.$id), + action: formatDisplay(name), + args, + }, + groupId, + }, + }); + after((result) => { + activeAction = undefined; + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: '🛬 ' + name, + subtitle: 'end', + data: { + store: formatDisplay(store.$id), + action: formatDisplay(name), + args, + result, + }, + groupId, + }, + }); + }); + onError((error) => { + activeAction = undefined; + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + logType: 'error', + title: '💥 ' + name, + subtitle: 'end', + data: { + store: formatDisplay(store.$id), + action: formatDisplay(name), + args, + error, + }, + groupId, + }, + }); + }); + }, true); + store._customProperties.forEach((name) => { + watch(() => unref(store[name]), (newValue, oldValue) => { + api.notifyComponentUpdate(); + api.sendInspectorState(INSPECTOR_ID); + if (isTimelineActive) { + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: 'Change', + subtitle: name, + data: { + newValue, + oldValue, + }, + groupId: activeAction, + }, + }); + } + }, { deep: true }); + }); + store.$subscribe(({ events, type }, state) => { + api.notifyComponentUpdate(); + api.sendInspectorState(INSPECTOR_ID); + if (!isTimelineActive) + return; + // rootStore.state[store.id] = state + const eventData = { + time: now(), + title: formatMutationType(type), + data: assign$1({ store: formatDisplay(store.$id) }, formatEventData(events)), + groupId: activeAction, + }; + if (type === MutationType.patchFunction) { + eventData.subtitle = '⤵️'; + } + else if (type === MutationType.patchObject) { + eventData.subtitle = '🧩'; + } + else if (events && !Array.isArray(events)) { + eventData.subtitle = events.type; + } + if (events) { + eventData.data['rawEvent(s)'] = { + _custom: { + display: 'DebuggerEvent', + type: 'object', + tooltip: 'raw DebuggerEvent[]', + value: events, + }, + }; + } + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: eventData, + }); + }, { detached: true, flush: 'sync' }); + const hotUpdate = store._hotUpdate; + store._hotUpdate = markRaw((newStore) => { + hotUpdate(newStore); + api.addTimelineEvent({ + layerId: MUTATIONS_LAYER_ID, + event: { + time: now(), + title: '🔥 ' + store.$id, + subtitle: 'HMR update', + data: { + store: formatDisplay(store.$id), + info: formatDisplay(`HMR update`), + }, + }, + }); + // update the devtools too + api.notifyComponentUpdate(); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + }); + const { $dispose } = store; + store.$dispose = () => { + $dispose(); + api.notifyComponentUpdate(); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + api.getSettings().logStoreChanges && + toastMessage(`Disposed "${store.$id}" store 🗑`); + }; + // trigger an update so it can display new registered stores + api.notifyComponentUpdate(); + api.sendInspectorTree(INSPECTOR_ID); + api.sendInspectorState(INSPECTOR_ID); + api.getSettings().logStoreChanges && + toastMessage(`"${store.$id}" store installed 🆕`); + }); +} +let runningActionId = 0; +let activeAction; +/** + * Patches a store to enable action grouping in devtools by wrapping the store with a Proxy that is passed as the + * context of all actions, allowing us to set `runningAction` on each access and effectively associating any state + * mutation to the action. + * + * @param store - store to patch + * @param actionNames - list of actionst to patch + */ +function patchActionForGrouping(store, actionNames, wrapWithProxy) { + // original actions of the store as they are given by pinia. We are going to override them + const actions = actionNames.reduce((storeActions, actionName) => { + // use toRaw to avoid tracking #541 + storeActions[actionName] = toRaw(store)[actionName]; + return storeActions; + }, {}); + for (const actionName in actions) { + store[actionName] = function () { + // the running action id is incremented in a before action hook + const _actionId = runningActionId; + const trackedStore = wrapWithProxy + ? new Proxy(store, { + get(...args) { + activeAction = _actionId; + return Reflect.get(...args); + }, + set(...args) { + activeAction = _actionId; + return Reflect.set(...args); + }, + }) + : store; + // For Setup Stores we need https://github.com/tc39/proposal-async-context + activeAction = _actionId; + const retValue = actions[actionName].apply(trackedStore, arguments); + // this is safer as async actions in Setup Stores would associate mutations done outside of the action + activeAction = undefined; + return retValue; + }; + } +} +/** + * pinia.use(devtoolsPlugin) + */ +function devtoolsPlugin({ app, store, options }) { + // HMR module + if (store.$id.startsWith('__hot:')) { + return; + } + // detect option api vs setup api + store._isOptionsAPI = !!options.state; + // Do not overwrite actions mocked by @pinia/testing (#2298) + if (!store._p._testing) { + patchActionForGrouping(store, Object.keys(options.actions), store._isOptionsAPI); + // Upgrade the HMR to also update the new actions + const originalHotUpdate = store._hotUpdate; + toRaw(store)._hotUpdate = function (newStore) { + originalHotUpdate.apply(this, arguments); + patchActionForGrouping(store, Object.keys(newStore._hmrPayload.actions), !!store._isOptionsAPI); + }; + } + addStoreToDevtools(app, + // FIXME: is there a way to allow the assignment from Store to StoreGeneric? + store); +} + +/** + * Creates a Pinia instance to be used by the application + */ +function createPinia() { + const scope = effectScope(true); + // NOTE: here we could check the window object for a state and directly set it + // if there is anything like it with Vue 3 SSR + const state = scope.run(() => ref({})); + let _p = []; + // plugins added before calling app.use(pinia) + let toBeInstalled = []; + const pinia = markRaw({ + install(app) { + // this allows calling useStore() outside of a component setup after + // installing pinia's plugin + setActivePinia(pinia); + if (!isVue2) { + pinia._a = app; + app.provide(piniaSymbol, pinia); + app.config.globalProperties.$pinia = pinia; + /* istanbul ignore else */ + if ((((process.env.NODE_ENV !== 'production') || (typeof __VUE_PROD_DEVTOOLS__ !== 'undefined' && __VUE_PROD_DEVTOOLS__)) && !(process.env.NODE_ENV === 'test')) && IS_CLIENT) { + registerPiniaDevtools(app, pinia); + } + toBeInstalled.forEach((plugin) => _p.push(plugin)); + toBeInstalled = []; + } + }, + use(plugin) { + if (!this._a && !isVue2) { + toBeInstalled.push(plugin); + } + else { + _p.push(plugin); + } + return this; + }, + _p, + // it's actually undefined here + // @ts-expect-error + _a: null, + _e: scope, + _s: new Map(), + state, + }); + // pinia devtools rely on dev only features so they cannot be forced unless + // the dev build of Vue is used. Avoid old browsers like IE11. + if ((((process.env.NODE_ENV !== 'production') || (typeof __VUE_PROD_DEVTOOLS__ !== 'undefined' && __VUE_PROD_DEVTOOLS__)) && !(process.env.NODE_ENV === 'test')) && typeof Proxy !== 'undefined') { + pinia.use(devtoolsPlugin); + } + return pinia; +} +/** + * Dispose a Pinia instance by stopping its effectScope and removing the state, plugins and stores. This is mostly + * useful in tests, with both a testing pinia or a regular pinia and in applications that use multiple pinia instances. + * Once disposed, the pinia instance cannot be used anymore. + * + * @param pinia - pinia instance + */ +function disposePinia(pinia) { + pinia._e.stop(); + pinia._s.clear(); + pinia._p.splice(0); + pinia.state.value = {}; + // @ts-expect-error: non valid + pinia._a = null; +} + +/** + * Checks if a function is a `StoreDefinition`. + * + * @param fn - object to test + * @returns true if `fn` is a StoreDefinition + */ +const isUseStore = (fn) => { + return typeof fn === 'function' && typeof fn.$id === 'string'; +}; +/** + * Mutates in place `newState` with `oldState` to _hot update_ it. It will + * remove any key not existing in `newState` and recursively merge plain + * objects. + * + * @param newState - new state object to be patched + * @param oldState - old state that should be used to patch newState + * @returns - newState + */ +function patchObject(newState, oldState) { + // no need to go through symbols because they cannot be serialized anyway + for (const key in oldState) { + const subPatch = oldState[key]; + // skip the whole sub tree + if (!(key in newState)) { + continue; + } + const targetValue = newState[key]; + if (isPlainObject(targetValue) && + isPlainObject(subPatch) && + !isRef(subPatch) && + !isReactive(subPatch)) { + newState[key] = patchObject(targetValue, subPatch); + } + else { + // objects are either a bit more complex (e.g. refs) or primitives, so we + // just set the whole thing + if (isVue2) { + set(newState, key, subPatch); + } + else { + newState[key] = subPatch; + } + } + } + return newState; +} +/** + * Creates an _accept_ function to pass to `import.meta.hot` in Vite applications. + * + * @example + * ```js + * const useUser = defineStore(...) + * if (import.meta.hot) { + * import.meta.hot.accept(acceptHMRUpdate(useUser, import.meta.hot)) + * } + * ``` + * + * @param initialUseStore - return of the defineStore to hot update + * @param hot - `import.meta.hot` + */ +function acceptHMRUpdate(initialUseStore, hot) { + // strip as much as possible from iife.prod + if (!(process.env.NODE_ENV !== 'production')) { + return () => { }; + } + return (newModule) => { + const pinia = hot.data.pinia || initialUseStore._pinia; + if (!pinia) { + // this store is still not used + return; + } + // preserve the pinia instance across loads + hot.data.pinia = pinia; + // console.log('got data', newStore) + for (const exportName in newModule) { + const useStore = newModule[exportName]; + // console.log('checking for', exportName) + if (isUseStore(useStore) && pinia._s.has(useStore.$id)) { + // console.log('Accepting update for', useStore.$id) + const id = useStore.$id; + if (id !== initialUseStore.$id) { + console.warn(`The id of the store changed from "${initialUseStore.$id}" to "${id}". Reloading.`); + // return import.meta.hot.invalidate() + return hot.invalidate(); + } + const existingStore = pinia._s.get(id); + if (!existingStore) { + console.log(`[Pinia]: skipping hmr because store doesn't exist yet`); + return; + } + useStore(pinia, existingStore); + } + } + }; +} + +const noop = () => { }; +function addSubscription(subscriptions, callback, detached, onCleanup = noop) { + subscriptions.push(callback); + const removeSubscription = () => { + const idx = subscriptions.indexOf(callback); + if (idx > -1) { + subscriptions.splice(idx, 1); + onCleanup(); + } + }; + if (!detached && getCurrentScope()) { + onScopeDispose(removeSubscription); + } + return removeSubscription; +} +function triggerSubscriptions(subscriptions, ...args) { + subscriptions.slice().forEach((callback) => { + callback(...args); + }); +} + +const fallbackRunWithContext = (fn) => fn(); +/** + * Marks a function as an action for `$onAction` + * @internal + */ +const ACTION_MARKER = Symbol(); +/** + * Action name symbol. Allows to add a name to an action after defining it + * @internal + */ +const ACTION_NAME = Symbol(); +function mergeReactiveObjects(target, patchToApply) { + // Handle Map instances + if (target instanceof Map && patchToApply instanceof Map) { + patchToApply.forEach((value, key) => target.set(key, value)); + } + else if (target instanceof Set && patchToApply instanceof Set) { + // Handle Set instances + patchToApply.forEach(target.add, target); + } + // no need to go through symbols because they cannot be serialized anyway + for (const key in patchToApply) { + if (!patchToApply.hasOwnProperty(key)) + continue; + const subPatch = patchToApply[key]; + const targetValue = target[key]; + if (isPlainObject(targetValue) && + isPlainObject(subPatch) && + target.hasOwnProperty(key) && + !isRef(subPatch) && + !isReactive(subPatch)) { + // NOTE: here I wanted to warn about inconsistent types but it's not possible because in setup stores one might + // start the value of a property as a certain type e.g. a Map, and then for some reason, during SSR, change that + // to `undefined`. When trying to hydrate, we want to override the Map with `undefined`. + target[key] = mergeReactiveObjects(targetValue, subPatch); + } + else { + // @ts-expect-error: subPatch is a valid value + target[key] = subPatch; + } + } + return target; +} +const skipHydrateSymbol = (process.env.NODE_ENV !== 'production') + ? Symbol('pinia:skipHydration') + : /* istanbul ignore next */ Symbol(); +const skipHydrateMap = /*#__PURE__*/ new WeakMap(); +/** + * Tells Pinia to skip the hydration process of a given object. This is useful in setup stores (only) when you return a + * stateful object in the store but it isn't really state. e.g. returning a router instance in a setup store. + * + * @param obj - target object + * @returns obj + */ +function skipHydrate(obj) { + return isVue2 + ? // in @vue/composition-api, the refs are sealed so defineProperty doesn't work... + /* istanbul ignore next */ skipHydrateMap.set(obj, 1) && obj + : Object.defineProperty(obj, skipHydrateSymbol, {}); +} +/** + * Returns whether a value should be hydrated + * + * @param obj - target variable + * @returns true if `obj` should be hydrated + */ +function shouldHydrate(obj) { + return isVue2 + ? /* istanbul ignore next */ !skipHydrateMap.has(obj) + : !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol); +} +const { assign } = Object; +function isComputed(o) { + return !!(isRef(o) && o.effect); +} +function createOptionsStore(id, options, pinia, hot) { + const { state, actions, getters } = options; + const initialState = pinia.state.value[id]; + let store; + function setup() { + if (!initialState && (!(process.env.NODE_ENV !== 'production') || !hot)) { + /* istanbul ignore if */ + if (isVue2) { + set(pinia.state.value, id, state ? state() : {}); + } + else { + pinia.state.value[id] = state ? state() : {}; + } + } + // avoid creating a state in pinia.state.value + const localState = (process.env.NODE_ENV !== 'production') && hot + ? // use ref() to unwrap refs inside state TODO: check if this is still necessary + toRefs(ref(state ? state() : {}).value) + : toRefs(pinia.state.value[id]); + return assign(localState, actions, Object.keys(getters || {}).reduce((computedGetters, name) => { + if ((process.env.NODE_ENV !== 'production') && name in localState) { + console.warn(`[🍍]: A getter cannot have the same name as another state property. Rename one of them. Found with "${name}" in store "${id}".`); + } + computedGetters[name] = markRaw(computed(() => { + setActivePinia(pinia); + // it was created just before + const store = pinia._s.get(id); + // allow cross using stores + /* istanbul ignore if */ + if (isVue2 && !store._r) + return; + // @ts-expect-error + // return getters![name].call(context, context) + // TODO: avoid reading the getter while assigning with a global variable + return getters[name].call(store, store); + })); + return computedGetters; + }, {})); + } + store = createSetupStore(id, setup, options, pinia, hot, true); + return store; +} +function createSetupStore($id, setup, options = {}, pinia, hot, isOptionsStore) { + let scope; + const optionsForPlugin = assign({ actions: {} }, options); + /* istanbul ignore if */ + if ((process.env.NODE_ENV !== 'production') && !pinia._e.active) { + throw new Error('Pinia destroyed'); + } + // watcher options for $subscribe + const $subscribeOptions = { deep: true }; + /* istanbul ignore else */ + if ((process.env.NODE_ENV !== 'production') && !isVue2) { + $subscribeOptions.onTrigger = (event) => { + /* istanbul ignore else */ + if (isListening) { + debuggerEvents = event; + // avoid triggering this while the store is being built and the state is being set in pinia + } + else if (isListening == false && !store._hotUpdating) { + // let patch send all the events together later + /* istanbul ignore else */ + if (Array.isArray(debuggerEvents)) { + debuggerEvents.push(event); + } + else { + console.error('🍍 debuggerEvents should be an array. This is most likely an internal Pinia bug.'); + } + } + }; + } + // internal state + let isListening; // set to true at the end + let isSyncListening; // set to true at the end + let subscriptions = []; + let actionSubscriptions = []; + let debuggerEvents; + const initialState = pinia.state.value[$id]; + // avoid setting the state for option stores if it is set + // by the setup + if (!isOptionsStore && !initialState && (!(process.env.NODE_ENV !== 'production') || !hot)) { + /* istanbul ignore if */ + if (isVue2) { + set(pinia.state.value, $id, {}); + } + else { + pinia.state.value[$id] = {}; + } + } + const hotState = ref({}); + // avoid triggering too many listeners + // https://github.com/vuejs/pinia/issues/1129 + let activeListener; + function $patch(partialStateOrMutator) { + let subscriptionMutation; + isListening = isSyncListening = false; + // reset the debugger events since patches are sync + /* istanbul ignore else */ + if ((process.env.NODE_ENV !== 'production')) { + debuggerEvents = []; + } + if (typeof partialStateOrMutator === 'function') { + partialStateOrMutator(pinia.state.value[$id]); + subscriptionMutation = { + type: MutationType.patchFunction, + storeId: $id, + events: debuggerEvents, + }; + } + else { + mergeReactiveObjects(pinia.state.value[$id], partialStateOrMutator); + subscriptionMutation = { + type: MutationType.patchObject, + payload: partialStateOrMutator, + storeId: $id, + events: debuggerEvents, + }; + } + const myListenerId = (activeListener = Symbol()); + nextTick().then(() => { + if (activeListener === myListenerId) { + isListening = true; + } + }); + isSyncListening = true; + // because we paused the watcher, we need to manually call the subscriptions + triggerSubscriptions(subscriptions, subscriptionMutation, pinia.state.value[$id]); + } + const $reset = isOptionsStore + ? function $reset() { + const { state } = options; + const newState = state ? state() : {}; + // we use a patch to group all changes into one single subscription + this.$patch(($state) => { + // @ts-expect-error: FIXME: shouldn't error? + assign($state, newState); + }); + } + : /* istanbul ignore next */ + (process.env.NODE_ENV !== 'production') + ? () => { + throw new Error(`🍍: Store "${$id}" is built using the setup syntax and does not implement $reset().`); + } + : noop; + function $dispose() { + scope.stop(); + subscriptions = []; + actionSubscriptions = []; + pinia._s.delete($id); + } + /** + * Helper that wraps function so it can be tracked with $onAction + * @param fn - action to wrap + * @param name - name of the action + */ + const action = (fn, name = '') => { + if (ACTION_MARKER in fn) { + fn[ACTION_NAME] = name; + return fn; + } + const wrappedAction = function () { + setActivePinia(pinia); + const args = Array.from(arguments); + const afterCallbackList = []; + const onErrorCallbackList = []; + function after(callback) { + afterCallbackList.push(callback); + } + function onError(callback) { + onErrorCallbackList.push(callback); + } + // @ts-expect-error + triggerSubscriptions(actionSubscriptions, { + args, + name: wrappedAction[ACTION_NAME], + store, + after, + onError, + }); + let ret; + try { + ret = fn.apply(this && this.$id === $id ? this : store, args); + // handle sync errors + } + catch (error) { + triggerSubscriptions(onErrorCallbackList, error); + throw error; + } + if (ret instanceof Promise) { + return ret + .then((value) => { + triggerSubscriptions(afterCallbackList, value); + return value; + }) + .catch((error) => { + triggerSubscriptions(onErrorCallbackList, error); + return Promise.reject(error); + }); + } + // trigger after callbacks + triggerSubscriptions(afterCallbackList, ret); + return ret; + }; + wrappedAction[ACTION_MARKER] = true; + wrappedAction[ACTION_NAME] = name; // will be set later + // @ts-expect-error: we are intentionally limiting the returned type to just Fn + // because all the added properties are internals that are exposed through `$onAction()` only + return wrappedAction; + }; + const _hmrPayload = /*#__PURE__*/ markRaw({ + actions: {}, + getters: {}, + state: [], + hotState, + }); + const partialStore = { + _p: pinia, + // _s: scope, + $id, + $onAction: addSubscription.bind(null, actionSubscriptions), + $patch, + $reset, + $subscribe(callback, options = {}) { + const removeSubscription = addSubscription(subscriptions, callback, options.detached, () => stopWatcher()); + const stopWatcher = scope.run(() => watch(() => pinia.state.value[$id], (state) => { + if (options.flush === 'sync' ? isSyncListening : isListening) { + callback({ + storeId: $id, + type: MutationType.direct, + events: debuggerEvents, + }, state); + } + }, assign({}, $subscribeOptions, options))); + return removeSubscription; + }, + $dispose, + }; + /* istanbul ignore if */ + if (isVue2) { + // start as non ready + partialStore._r = false; + } + const store = reactive((process.env.NODE_ENV !== 'production') || ((((process.env.NODE_ENV !== 'production') || (typeof __VUE_PROD_DEVTOOLS__ !== 'undefined' && __VUE_PROD_DEVTOOLS__)) && !(process.env.NODE_ENV === 'test')) && IS_CLIENT) + ? assign({ + _hmrPayload, + _customProperties: markRaw(new Set()), // devtools custom properties + }, partialStore + // must be added later + // setupStore + ) + : partialStore); + // store the partial store now so the setup of stores can instantiate each other before they are finished without + // creating infinite loops. + pinia._s.set($id, store); + const runWithContext = (pinia._a && pinia._a.runWithContext) || fallbackRunWithContext; + // TODO: idea create skipSerialize that marks properties as non serializable and they are skipped + const setupStore = runWithContext(() => pinia._e.run(() => (scope = effectScope()).run(() => setup({ action })))); + // overwrite existing actions to support $onAction + for (const key in setupStore) { + const prop = setupStore[key]; + if ((isRef(prop) && !isComputed(prop)) || isReactive(prop)) { + // mark it as a piece of state to be serialized + if ((process.env.NODE_ENV !== 'production') && hot) { + set(hotState.value, key, toRef(setupStore, key)); + // createOptionStore directly sets the state in pinia.state.value so we + // can just skip that + } + else if (!isOptionsStore) { + // in setup stores we must hydrate the state and sync pinia state tree with the refs the user just created + if (initialState && shouldHydrate(prop)) { + if (isRef(prop)) { + prop.value = initialState[key]; + } + else { + // probably a reactive object, lets recursively assign + // @ts-expect-error: prop is unknown + mergeReactiveObjects(prop, initialState[key]); + } + } + // transfer the ref to the pinia state to keep everything in sync + /* istanbul ignore if */ + if (isVue2) { + set(pinia.state.value[$id], key, prop); + } + else { + pinia.state.value[$id][key] = prop; + } + } + /* istanbul ignore else */ + if ((process.env.NODE_ENV !== 'production')) { + _hmrPayload.state.push(key); + } + // action + } + else if (typeof prop === 'function') { + const actionValue = (process.env.NODE_ENV !== 'production') && hot ? prop : action(prop, key); + // this a hot module replacement store because the hotUpdate method needs + // to do it with the right context + /* istanbul ignore if */ + if (isVue2) { + set(setupStore, key, actionValue); + } + else { + // @ts-expect-error + setupStore[key] = actionValue; + } + /* istanbul ignore else */ + if ((process.env.NODE_ENV !== 'production')) { + _hmrPayload.actions[key] = prop; + } + // list actions so they can be used in plugins + // @ts-expect-error + optionsForPlugin.actions[key] = prop; + } + else if ((process.env.NODE_ENV !== 'production')) { + // add getters for devtools + if (isComputed(prop)) { + _hmrPayload.getters[key] = isOptionsStore + ? // @ts-expect-error + options.getters[key] + : prop; + if (IS_CLIENT) { + const getters = setupStore._getters || + // @ts-expect-error: same + (setupStore._getters = markRaw([])); + getters.push(key); + } + } + } + } + // add the state, getters, and action properties + /* istanbul ignore if */ + if (isVue2) { + Object.keys(setupStore).forEach((key) => { + set(store, key, setupStore[key]); + }); + } + else { + assign(store, setupStore); + // allows retrieving reactive objects with `storeToRefs()`. Must be called after assigning to the reactive object. + // Make `storeToRefs()` work with `reactive()` #799 + assign(toRaw(store), setupStore); + } + // use this instead of a computed with setter to be able to create it anywhere + // without linking the computed lifespan to wherever the store is first + // created. + Object.defineProperty(store, '$state', { + get: () => ((process.env.NODE_ENV !== 'production') && hot ? hotState.value : pinia.state.value[$id]), + set: (state) => { + /* istanbul ignore if */ + if ((process.env.NODE_ENV !== 'production') && hot) { + throw new Error('cannot set hotState'); + } + $patch(($state) => { + // @ts-expect-error: FIXME: shouldn't error? + assign($state, state); + }); + }, + }); + // add the hotUpdate before plugins to allow them to override it + /* istanbul ignore else */ + if ((process.env.NODE_ENV !== 'production')) { + store._hotUpdate = markRaw((newStore) => { + store._hotUpdating = true; + newStore._hmrPayload.state.forEach((stateKey) => { + if (stateKey in store.$state) { + const newStateTarget = newStore.$state[stateKey]; + const oldStateSource = store.$state[stateKey]; + if (typeof newStateTarget === 'object' && + isPlainObject(newStateTarget) && + isPlainObject(oldStateSource)) { + patchObject(newStateTarget, oldStateSource); + } + else { + // transfer the ref + newStore.$state[stateKey] = oldStateSource; + } + } + // patch direct access properties to allow store.stateProperty to work as + // store.$state.stateProperty + set(store, stateKey, toRef(newStore.$state, stateKey)); + }); + // remove deleted state properties + Object.keys(store.$state).forEach((stateKey) => { + if (!(stateKey in newStore.$state)) { + del(store, stateKey); + } + }); + // avoid devtools logging this as a mutation + isListening = false; + isSyncListening = false; + pinia.state.value[$id] = toRef(newStore._hmrPayload, 'hotState'); + isSyncListening = true; + nextTick().then(() => { + isListening = true; + }); + for (const actionName in newStore._hmrPayload.actions) { + const actionFn = newStore[actionName]; + set(store, actionName, action(actionFn, actionName)); + } + // TODO: does this work in both setup and option store? + for (const getterName in newStore._hmrPayload.getters) { + const getter = newStore._hmrPayload.getters[getterName]; + const getterValue = isOptionsStore + ? // special handling of options api + computed(() => { + setActivePinia(pinia); + return getter.call(store, store); + }) + : getter; + set(store, getterName, getterValue); + } + // remove deleted getters + Object.keys(store._hmrPayload.getters).forEach((key) => { + if (!(key in newStore._hmrPayload.getters)) { + del(store, key); + } + }); + // remove old actions + Object.keys(store._hmrPayload.actions).forEach((key) => { + if (!(key in newStore._hmrPayload.actions)) { + del(store, key); + } + }); + // update the values used in devtools and to allow deleting new properties later on + store._hmrPayload = newStore._hmrPayload; + store._getters = newStore._getters; + store._hotUpdating = false; + }); + } + if ((((process.env.NODE_ENV !== 'production') || (typeof __VUE_PROD_DEVTOOLS__ !== 'undefined' && __VUE_PROD_DEVTOOLS__)) && !(process.env.NODE_ENV === 'test')) && IS_CLIENT) { + const nonEnumerable = { + writable: true, + configurable: true, + // avoid warning on devtools trying to display this property + enumerable: false, + }; + ['_p', '_hmrPayload', '_getters', '_customProperties'].forEach((p) => { + Object.defineProperty(store, p, assign({ value: store[p] }, nonEnumerable)); + }); + } + /* istanbul ignore if */ + if (isVue2) { + // mark the store as ready before plugins + store._r = true; + } + // apply all plugins + pinia._p.forEach((extender) => { + /* istanbul ignore else */ + if ((((process.env.NODE_ENV !== 'production') || (typeof __VUE_PROD_DEVTOOLS__ !== 'undefined' && __VUE_PROD_DEVTOOLS__)) && !(process.env.NODE_ENV === 'test')) && IS_CLIENT) { + const extensions = scope.run(() => extender({ + store: store, + app: pinia._a, + pinia, + options: optionsForPlugin, + })); + Object.keys(extensions || {}).forEach((key) => store._customProperties.add(key)); + assign(store, extensions); + } + else { + assign(store, scope.run(() => extender({ + store: store, + app: pinia._a, + pinia, + options: optionsForPlugin, + }))); + } + }); + if ((process.env.NODE_ENV !== 'production') && + store.$state && + typeof store.$state === 'object' && + typeof store.$state.constructor === 'function' && + !store.$state.constructor.toString().includes('[native code]')) { + console.warn(`[🍍]: The "state" must be a plain object. It cannot be\n` + + `\tstate: () => new MyClass()\n` + + `Found in store "${store.$id}".`); + } + // only apply hydrate to option stores with an initial state in pinia + if (initialState && + isOptionsStore && + options.hydrate) { + options.hydrate(store.$state, initialState); + } + isListening = true; + isSyncListening = true; + return store; +} +// allows unused stores to be tree shaken +/*! #__NO_SIDE_EFFECTS__ */ +function defineStore( +// TODO: add proper types from above +idOrOptions, setup, setupOptions) { + let id; + let options; + const isSetupStore = typeof setup === 'function'; + if (typeof idOrOptions === 'string') { + id = idOrOptions; + // the option store setup will contain the actual options in this case + options = isSetupStore ? setupOptions : setup; + } + else { + options = idOrOptions; + id = idOrOptions.id; + if ((process.env.NODE_ENV !== 'production') && typeof id !== 'string') { + throw new Error(`[🍍]: "defineStore()" must be passed a store id as its first argument.`); + } + } + function useStore(pinia, hot) { + const hasContext = hasInjectionContext(); + pinia = + // in test mode, ignore the argument provided as we can always retrieve a + // pinia instance with getActivePinia() + ((process.env.NODE_ENV === 'test') && activePinia && activePinia._testing ? null : pinia) || + (hasContext ? inject(piniaSymbol, null) : null); + if (pinia) + setActivePinia(pinia); + if ((process.env.NODE_ENV !== 'production') && !activePinia) { + throw new Error(`[🍍]: "getActivePinia()" was called but there was no active Pinia. Are you trying to use a store before calling "app.use(pinia)"?\n` + + `See https://pinia.vuejs.org/core-concepts/outside-component-usage.html for help.\n` + + `This will fail in production.`); + } + pinia = activePinia; + if (!pinia._s.has(id)) { + // creating the store registers it in `pinia._s` + if (isSetupStore) { + createSetupStore(id, setup, options, pinia); + } + else { + createOptionsStore(id, options, pinia); + } + /* istanbul ignore else */ + if ((process.env.NODE_ENV !== 'production')) { + // @ts-expect-error: not the right inferred type + useStore._pinia = pinia; + } + } + const store = pinia._s.get(id); + if ((process.env.NODE_ENV !== 'production') && hot) { + const hotId = '__hot:' + id; + const newStore = isSetupStore + ? createSetupStore(hotId, setup, options, pinia, true) + : createOptionsStore(hotId, assign({}, options), pinia, true); + hot._hotUpdate(newStore); + // cleanup the state properties and the store from the cache + delete pinia.state.value[hotId]; + pinia._s.delete(hotId); + } + if ((process.env.NODE_ENV !== 'production') && IS_CLIENT) { + const currentInstance = getCurrentInstance(); + // save stores in instances to access them devtools + if (currentInstance && + currentInstance.proxy && + // avoid adding stores that are just built for hot module replacement + !hot) { + const vm = currentInstance.proxy; + const cache = '_pStores' in vm ? vm._pStores : (vm._pStores = {}); + cache[id] = store; + } + } + // StoreGeneric cannot be casted towards Store + return store; + } + useStore.$id = id; + return useStore; +} + +let mapStoreSuffix = 'Store'; +/** + * Changes the suffix added by `mapStores()`. Can be set to an empty string. + * Defaults to `"Store"`. Make sure to extend the MapStoresCustomization + * interface if you are using TypeScript. + * + * @param suffix - new suffix + */ +function setMapStoreSuffix(suffix // could be 'Store' but that would be annoying for JS +) { + mapStoreSuffix = suffix; +} +/** + * Allows using stores without the composition API (`setup()`) by generating an + * object to be spread in the `computed` field of a component. It accepts a list + * of store definitions. + * + * @example + * ```js + * export default { + * computed: { + * // other computed properties + * ...mapStores(useUserStore, useCartStore) + * }, + * + * created() { + * this.userStore // store with id "user" + * this.cartStore // store with id "cart" + * } + * } + * ``` + * + * @param stores - list of stores to map to an object + */ +function mapStores(...stores) { + if ((process.env.NODE_ENV !== 'production') && Array.isArray(stores[0])) { + console.warn(`[🍍]: Directly pass all stores to "mapStores()" without putting them in an array:\n` + + `Replace\n` + + `\tmapStores([useAuthStore, useCartStore])\n` + + `with\n` + + `\tmapStores(useAuthStore, useCartStore)\n` + + `This will fail in production if not fixed.`); + stores = stores[0]; + } + return stores.reduce((reduced, useStore) => { + // @ts-expect-error: $id is added by defineStore + reduced[useStore.$id + mapStoreSuffix] = function () { + return useStore(this.$pinia); + }; + return reduced; + }, {}); +} +/** + * Allows using state and getters from one store without using the composition + * API (`setup()`) by generating an object to be spread in the `computed` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ +function mapState(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + reduced[key] = function () { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key]; + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function () { + const store = useStore(this.$pinia); + const storeKey = keysOrMapper[key]; + // for some reason TS is unable to infer the type of storeKey to be a + // function + return typeof storeKey === 'function' + ? storeKey.call(this, store) + : // @ts-expect-error: FIXME: should work? + store[storeKey]; + }; + return reduced; + }, {}); +} +/** + * Alias for `mapState()`. You should use `mapState()` instead. + * @deprecated use `mapState()` instead. + */ +const mapGetters = mapState; +/** + * Allows directly using actions from your store without using the composition + * API (`setup()`) by generating an object to be spread in the `methods` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ +function mapActions(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function (...args) { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key](...args); + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function (...args) { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[keysOrMapper[key]](...args); + }; + return reduced; + }, {}); +} +/** + * Allows using state and getters from one store without using the composition + * API (`setup()`) by generating an object to be spread in the `computed` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ +function mapWritableState(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + // @ts-ignore + reduced[key] = { + get() { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key]; + }, + set(value) { + // @ts-expect-error: FIXME: should work? + return (useStore(this.$pinia)[key] = value); + }, + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-ignore + reduced[key] = { + get() { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[keysOrMapper[key]]; + }, + set(value) { + // @ts-expect-error: FIXME: should work? + return (useStore(this.$pinia)[keysOrMapper[key]] = value); + }, + }; + return reduced; + }, {}); +} + +/** + * Creates an object of references with all the state, getters, and plugin-added + * state properties of the store. Similar to `toRefs()` but specifically + * designed for Pinia stores so methods and non reactive properties are + * completely ignored. + * + * @param store - store to extract the refs from + */ +function storeToRefs(store) { + // See https://github.com/vuejs/pinia/issues/852 + // It's easier to just use toRefs() even if it includes more stuff + if (isVue2) { + // @ts-expect-error: toRefs include methods and others + return toRefs(store); + } + else { + const rawStore = toRaw(store); + const refs = {}; + for (const key in rawStore) { + const value = rawStore[key]; + if (isRef(value) || isReactive(value)) { + // @ts-expect-error: the key is state or getter + refs[key] = + // --- + toRef(store, key); + } + } + return refs; + } +} + +/** + * Vue 2 Plugin that must be installed for pinia to work. Note **you don't need + * this plugin if you are using Nuxt.js**. Use the `buildModule` instead: + * https://pinia.vuejs.org/ssr/nuxt.html. + * + * @example + * ```js + * import Vue from 'vue' + * import { PiniaVuePlugin, createPinia } from 'pinia' + * + * Vue.use(PiniaVuePlugin) + * const pinia = createPinia() + * + * new Vue({ + * el: '#app', + * // ... + * pinia, + * }) + * ``` + * + * @param _Vue - `Vue` imported from 'vue'. + */ +const PiniaVuePlugin = function (_Vue) { + // Equivalent of + // app.config.globalProperties.$pinia = pinia + _Vue.mixin({ + beforeCreate() { + const options = this.$options; + if (options.pinia) { + const pinia = options.pinia; + // HACK: taken from provide(): https://github.com/vuejs/composition-api/blob/main/src/apis/inject.ts#L31 + /* istanbul ignore else */ + if (!this._provided) { + const provideCache = {}; + Object.defineProperty(this, '_provided', { + get: () => provideCache, + set: (v) => Object.assign(provideCache, v), + }); + } + this._provided[piniaSymbol] = pinia; + // propagate the pinia instance in an SSR friendly way + // avoid adding it to nuxt twice + /* istanbul ignore else */ + if (!this.$pinia) { + this.$pinia = pinia; + } + pinia._a = this; + if (IS_CLIENT) { + // this allows calling useStore() outside of a component setup after + // installing pinia's plugin + setActivePinia(pinia); + } + if ((((process.env.NODE_ENV !== 'production') || (typeof __VUE_PROD_DEVTOOLS__ !== 'undefined' && __VUE_PROD_DEVTOOLS__)) && !(process.env.NODE_ENV === 'test')) && IS_CLIENT) { + registerPiniaDevtools(pinia._a, pinia); + } + } + else if (!this.$pinia && options.parent && options.parent.$pinia) { + this.$pinia = options.parent.$pinia; + } + }, + destroyed() { + delete this._pStores; + }, + }); +}; + +export { MutationType, PiniaVuePlugin, acceptHMRUpdate, createPinia, defineStore, disposePinia, getActivePinia, mapActions, mapGetters, mapState, mapStores, mapWritableState, setActivePinia, setMapStoreSuffix, shouldHydrate, skipHydrate, storeToRefs }; diff --git a/node_modules/pinia/dist/pinia.prod.cjs b/node_modules/pinia/dist/pinia.prod.cjs new file mode 100644 index 0000000..41412c7 --- /dev/null +++ b/node_modules/pinia/dist/pinia.prod.cjs @@ -0,0 +1,845 @@ +/*! + * pinia v2.2.5 + * (c) 2024 Eduardo San Martin Morote + * @license MIT + */ +'use strict'; + +var vueDemi = require('vue-demi'); + +/** + * setActivePinia must be called to handle SSR at the top of functions like + * `fetch`, `setup`, `serverPrefetch` and others + */ +let activePinia; +/** + * Sets or unsets the active pinia. Used in SSR and internally when calling + * actions and getters + * + * @param pinia - Pinia instance + */ +// @ts-expect-error: cannot constrain the type of the return +const setActivePinia = (pinia) => (activePinia = pinia); +/** + * Get the currently active pinia if there is any. + */ +const getActivePinia = () => (vueDemi.hasInjectionContext() && vueDemi.inject(piniaSymbol)) || activePinia; +const piniaSymbol = (/* istanbul ignore next */ Symbol()); + +function isPlainObject( +// eslint-disable-next-line @typescript-eslint/no-explicit-any +o) { + return (o && + typeof o === 'object' && + Object.prototype.toString.call(o) === '[object Object]' && + typeof o.toJSON !== 'function'); +} +// type DeepReadonly = { readonly [P in keyof T]: DeepReadonly } +// TODO: can we change these to numbers? +/** + * Possible types for SubscriptionCallback + */ +exports.MutationType = void 0; +(function (MutationType) { + /** + * Direct mutation of the state: + * + * - `store.name = 'new name'` + * - `store.$state.name = 'new name'` + * - `store.list.push('new item')` + */ + MutationType["direct"] = "direct"; + /** + * Mutated the state with `$patch` and an object + * + * - `store.$patch({ name: 'newName' })` + */ + MutationType["patchObject"] = "patch object"; + /** + * Mutated the state with `$patch` and a function + * + * - `store.$patch(state => state.name = 'newName')` + */ + MutationType["patchFunction"] = "patch function"; + // maybe reset? for $state = {} and $reset +})(exports.MutationType || (exports.MutationType = {})); + +const IS_CLIENT = typeof window !== 'undefined'; + +/** + * Creates a Pinia instance to be used by the application + */ +function createPinia() { + const scope = vueDemi.effectScope(true); + // NOTE: here we could check the window object for a state and directly set it + // if there is anything like it with Vue 3 SSR + const state = scope.run(() => vueDemi.ref({})); + let _p = []; + // plugins added before calling app.use(pinia) + let toBeInstalled = []; + const pinia = vueDemi.markRaw({ + install(app) { + // this allows calling useStore() outside of a component setup after + // installing pinia's plugin + setActivePinia(pinia); + if (!vueDemi.isVue2) { + pinia._a = app; + app.provide(piniaSymbol, pinia); + app.config.globalProperties.$pinia = pinia; + toBeInstalled.forEach((plugin) => _p.push(plugin)); + toBeInstalled = []; + } + }, + use(plugin) { + if (!this._a && !vueDemi.isVue2) { + toBeInstalled.push(plugin); + } + else { + _p.push(plugin); + } + return this; + }, + _p, + // it's actually undefined here + // @ts-expect-error + _a: null, + _e: scope, + _s: new Map(), + state, + }); + return pinia; +} +/** + * Dispose a Pinia instance by stopping its effectScope and removing the state, plugins and stores. This is mostly + * useful in tests, with both a testing pinia or a regular pinia and in applications that use multiple pinia instances. + * Once disposed, the pinia instance cannot be used anymore. + * + * @param pinia - pinia instance + */ +function disposePinia(pinia) { + pinia._e.stop(); + pinia._s.clear(); + pinia._p.splice(0); + pinia.state.value = {}; + // @ts-expect-error: non valid + pinia._a = null; +} + +/** + * Creates an _accept_ function to pass to `import.meta.hot` in Vite applications. + * + * @example + * ```js + * const useUser = defineStore(...) + * if (import.meta.hot) { + * import.meta.hot.accept(acceptHMRUpdate(useUser, import.meta.hot)) + * } + * ``` + * + * @param initialUseStore - return of the defineStore to hot update + * @param hot - `import.meta.hot` + */ +function acceptHMRUpdate(initialUseStore, hot) { + // strip as much as possible from iife.prod + { + return () => { }; + } +} + +const noop = () => { }; +function addSubscription(subscriptions, callback, detached, onCleanup = noop) { + subscriptions.push(callback); + const removeSubscription = () => { + const idx = subscriptions.indexOf(callback); + if (idx > -1) { + subscriptions.splice(idx, 1); + onCleanup(); + } + }; + if (!detached && vueDemi.getCurrentScope()) { + vueDemi.onScopeDispose(removeSubscription); + } + return removeSubscription; +} +function triggerSubscriptions(subscriptions, ...args) { + subscriptions.slice().forEach((callback) => { + callback(...args); + }); +} + +const fallbackRunWithContext = (fn) => fn(); +/** + * Marks a function as an action for `$onAction` + * @internal + */ +const ACTION_MARKER = Symbol(); +/** + * Action name symbol. Allows to add a name to an action after defining it + * @internal + */ +const ACTION_NAME = Symbol(); +function mergeReactiveObjects(target, patchToApply) { + // Handle Map instances + if (target instanceof Map && patchToApply instanceof Map) { + patchToApply.forEach((value, key) => target.set(key, value)); + } + else if (target instanceof Set && patchToApply instanceof Set) { + // Handle Set instances + patchToApply.forEach(target.add, target); + } + // no need to go through symbols because they cannot be serialized anyway + for (const key in patchToApply) { + if (!patchToApply.hasOwnProperty(key)) + continue; + const subPatch = patchToApply[key]; + const targetValue = target[key]; + if (isPlainObject(targetValue) && + isPlainObject(subPatch) && + target.hasOwnProperty(key) && + !vueDemi.isRef(subPatch) && + !vueDemi.isReactive(subPatch)) { + // NOTE: here I wanted to warn about inconsistent types but it's not possible because in setup stores one might + // start the value of a property as a certain type e.g. a Map, and then for some reason, during SSR, change that + // to `undefined`. When trying to hydrate, we want to override the Map with `undefined`. + target[key] = mergeReactiveObjects(targetValue, subPatch); + } + else { + // @ts-expect-error: subPatch is a valid value + target[key] = subPatch; + } + } + return target; +} +const skipHydrateSymbol = /* istanbul ignore next */ Symbol(); +const skipHydrateMap = /*#__PURE__*/ new WeakMap(); +/** + * Tells Pinia to skip the hydration process of a given object. This is useful in setup stores (only) when you return a + * stateful object in the store but it isn't really state. e.g. returning a router instance in a setup store. + * + * @param obj - target object + * @returns obj + */ +function skipHydrate(obj) { + return vueDemi.isVue2 + ? // in @vue/composition-api, the refs are sealed so defineProperty doesn't work... + /* istanbul ignore next */ skipHydrateMap.set(obj, 1) && obj + : Object.defineProperty(obj, skipHydrateSymbol, {}); +} +/** + * Returns whether a value should be hydrated + * + * @param obj - target variable + * @returns true if `obj` should be hydrated + */ +function shouldHydrate(obj) { + return vueDemi.isVue2 + ? /* istanbul ignore next */ !skipHydrateMap.has(obj) + : !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol); +} +const { assign } = Object; +function isComputed(o) { + return !!(vueDemi.isRef(o) && o.effect); +} +function createOptionsStore(id, options, pinia, hot) { + const { state, actions, getters } = options; + const initialState = pinia.state.value[id]; + let store; + function setup() { + if (!initialState && (!false)) { + /* istanbul ignore if */ + if (vueDemi.isVue2) { + vueDemi.set(pinia.state.value, id, state ? state() : {}); + } + else { + pinia.state.value[id] = state ? state() : {}; + } + } + // avoid creating a state in pinia.state.value + const localState = vueDemi.toRefs(pinia.state.value[id]); + return assign(localState, actions, Object.keys(getters || {}).reduce((computedGetters, name) => { + computedGetters[name] = vueDemi.markRaw(vueDemi.computed(() => { + setActivePinia(pinia); + // it was created just before + const store = pinia._s.get(id); + // allow cross using stores + /* istanbul ignore if */ + if (vueDemi.isVue2 && !store._r) + return; + // @ts-expect-error + // return getters![name].call(context, context) + // TODO: avoid reading the getter while assigning with a global variable + return getters[name].call(store, store); + })); + return computedGetters; + }, {})); + } + store = createSetupStore(id, setup, options, pinia, hot, true); + return store; +} +function createSetupStore($id, setup, options = {}, pinia, hot, isOptionsStore) { + let scope; + const optionsForPlugin = assign({ actions: {} }, options); + // watcher options for $subscribe + const $subscribeOptions = { deep: true }; + // internal state + let isListening; // set to true at the end + let isSyncListening; // set to true at the end + let subscriptions = []; + let actionSubscriptions = []; + let debuggerEvents; + const initialState = pinia.state.value[$id]; + // avoid setting the state for option stores if it is set + // by the setup + if (!isOptionsStore && !initialState && (!false)) { + /* istanbul ignore if */ + if (vueDemi.isVue2) { + vueDemi.set(pinia.state.value, $id, {}); + } + else { + pinia.state.value[$id] = {}; + } + } + vueDemi.ref({}); + // avoid triggering too many listeners + // https://github.com/vuejs/pinia/issues/1129 + let activeListener; + function $patch(partialStateOrMutator) { + let subscriptionMutation; + isListening = isSyncListening = false; + if (typeof partialStateOrMutator === 'function') { + partialStateOrMutator(pinia.state.value[$id]); + subscriptionMutation = { + type: exports.MutationType.patchFunction, + storeId: $id, + events: debuggerEvents, + }; + } + else { + mergeReactiveObjects(pinia.state.value[$id], partialStateOrMutator); + subscriptionMutation = { + type: exports.MutationType.patchObject, + payload: partialStateOrMutator, + storeId: $id, + events: debuggerEvents, + }; + } + const myListenerId = (activeListener = Symbol()); + vueDemi.nextTick().then(() => { + if (activeListener === myListenerId) { + isListening = true; + } + }); + isSyncListening = true; + // because we paused the watcher, we need to manually call the subscriptions + triggerSubscriptions(subscriptions, subscriptionMutation, pinia.state.value[$id]); + } + const $reset = isOptionsStore + ? function $reset() { + const { state } = options; + const newState = state ? state() : {}; + // we use a patch to group all changes into one single subscription + this.$patch(($state) => { + // @ts-expect-error: FIXME: shouldn't error? + assign($state, newState); + }); + } + : /* istanbul ignore next */ + noop; + function $dispose() { + scope.stop(); + subscriptions = []; + actionSubscriptions = []; + pinia._s.delete($id); + } + /** + * Helper that wraps function so it can be tracked with $onAction + * @param fn - action to wrap + * @param name - name of the action + */ + const action = (fn, name = '') => { + if (ACTION_MARKER in fn) { + fn[ACTION_NAME] = name; + return fn; + } + const wrappedAction = function () { + setActivePinia(pinia); + const args = Array.from(arguments); + const afterCallbackList = []; + const onErrorCallbackList = []; + function after(callback) { + afterCallbackList.push(callback); + } + function onError(callback) { + onErrorCallbackList.push(callback); + } + // @ts-expect-error + triggerSubscriptions(actionSubscriptions, { + args, + name: wrappedAction[ACTION_NAME], + store, + after, + onError, + }); + let ret; + try { + ret = fn.apply(this && this.$id === $id ? this : store, args); + // handle sync errors + } + catch (error) { + triggerSubscriptions(onErrorCallbackList, error); + throw error; + } + if (ret instanceof Promise) { + return ret + .then((value) => { + triggerSubscriptions(afterCallbackList, value); + return value; + }) + .catch((error) => { + triggerSubscriptions(onErrorCallbackList, error); + return Promise.reject(error); + }); + } + // trigger after callbacks + triggerSubscriptions(afterCallbackList, ret); + return ret; + }; + wrappedAction[ACTION_MARKER] = true; + wrappedAction[ACTION_NAME] = name; // will be set later + // @ts-expect-error: we are intentionally limiting the returned type to just Fn + // because all the added properties are internals that are exposed through `$onAction()` only + return wrappedAction; + }; + const partialStore = { + _p: pinia, + // _s: scope, + $id, + $onAction: addSubscription.bind(null, actionSubscriptions), + $patch, + $reset, + $subscribe(callback, options = {}) { + const removeSubscription = addSubscription(subscriptions, callback, options.detached, () => stopWatcher()); + const stopWatcher = scope.run(() => vueDemi.watch(() => pinia.state.value[$id], (state) => { + if (options.flush === 'sync' ? isSyncListening : isListening) { + callback({ + storeId: $id, + type: exports.MutationType.direct, + events: debuggerEvents, + }, state); + } + }, assign({}, $subscribeOptions, options))); + return removeSubscription; + }, + $dispose, + }; + /* istanbul ignore if */ + if (vueDemi.isVue2) { + // start as non ready + partialStore._r = false; + } + const store = vueDemi.reactive(partialStore); + // store the partial store now so the setup of stores can instantiate each other before they are finished without + // creating infinite loops. + pinia._s.set($id, store); + const runWithContext = (pinia._a && pinia._a.runWithContext) || fallbackRunWithContext; + // TODO: idea create skipSerialize that marks properties as non serializable and they are skipped + const setupStore = runWithContext(() => pinia._e.run(() => (scope = vueDemi.effectScope()).run(() => setup({ action })))); + // overwrite existing actions to support $onAction + for (const key in setupStore) { + const prop = setupStore[key]; + if ((vueDemi.isRef(prop) && !isComputed(prop)) || vueDemi.isReactive(prop)) { + // mark it as a piece of state to be serialized + if (!isOptionsStore) { + // in setup stores we must hydrate the state and sync pinia state tree with the refs the user just created + if (initialState && shouldHydrate(prop)) { + if (vueDemi.isRef(prop)) { + prop.value = initialState[key]; + } + else { + // probably a reactive object, lets recursively assign + // @ts-expect-error: prop is unknown + mergeReactiveObjects(prop, initialState[key]); + } + } + // transfer the ref to the pinia state to keep everything in sync + /* istanbul ignore if */ + if (vueDemi.isVue2) { + vueDemi.set(pinia.state.value[$id], key, prop); + } + else { + pinia.state.value[$id][key] = prop; + } + } + // action + } + else if (typeof prop === 'function') { + const actionValue = action(prop, key); + // this a hot module replacement store because the hotUpdate method needs + // to do it with the right context + /* istanbul ignore if */ + if (vueDemi.isVue2) { + vueDemi.set(setupStore, key, actionValue); + } + else { + // @ts-expect-error + setupStore[key] = actionValue; + } + // list actions so they can be used in plugins + // @ts-expect-error + optionsForPlugin.actions[key] = prop; + } + else ; + } + // add the state, getters, and action properties + /* istanbul ignore if */ + if (vueDemi.isVue2) { + Object.keys(setupStore).forEach((key) => { + vueDemi.set(store, key, setupStore[key]); + }); + } + else { + assign(store, setupStore); + // allows retrieving reactive objects with `storeToRefs()`. Must be called after assigning to the reactive object. + // Make `storeToRefs()` work with `reactive()` #799 + assign(vueDemi.toRaw(store), setupStore); + } + // use this instead of a computed with setter to be able to create it anywhere + // without linking the computed lifespan to wherever the store is first + // created. + Object.defineProperty(store, '$state', { + get: () => (pinia.state.value[$id]), + set: (state) => { + $patch(($state) => { + // @ts-expect-error: FIXME: shouldn't error? + assign($state, state); + }); + }, + }); + /* istanbul ignore if */ + if (vueDemi.isVue2) { + // mark the store as ready before plugins + store._r = true; + } + // apply all plugins + pinia._p.forEach((extender) => { + /* istanbul ignore else */ + { + assign(store, scope.run(() => extender({ + store: store, + app: pinia._a, + pinia, + options: optionsForPlugin, + }))); + } + }); + // only apply hydrate to option stores with an initial state in pinia + if (initialState && + isOptionsStore && + options.hydrate) { + options.hydrate(store.$state, initialState); + } + isListening = true; + isSyncListening = true; + return store; +} +// allows unused stores to be tree shaken +/*! #__NO_SIDE_EFFECTS__ */ +function defineStore( +// TODO: add proper types from above +idOrOptions, setup, setupOptions) { + let id; + let options; + const isSetupStore = typeof setup === 'function'; + if (typeof idOrOptions === 'string') { + id = idOrOptions; + // the option store setup will contain the actual options in this case + options = isSetupStore ? setupOptions : setup; + } + else { + options = idOrOptions; + id = idOrOptions.id; + } + function useStore(pinia, hot) { + const hasContext = vueDemi.hasInjectionContext(); + pinia = + // in test mode, ignore the argument provided as we can always retrieve a + // pinia instance with getActivePinia() + ((process.env.NODE_ENV === 'test') && activePinia && activePinia._testing ? null : pinia) || + (hasContext ? vueDemi.inject(piniaSymbol, null) : null); + if (pinia) + setActivePinia(pinia); + pinia = activePinia; + if (!pinia._s.has(id)) { + // creating the store registers it in `pinia._s` + if (isSetupStore) { + createSetupStore(id, setup, options, pinia); + } + else { + createOptionsStore(id, options, pinia); + } + } + const store = pinia._s.get(id); + // StoreGeneric cannot be casted towards Store + return store; + } + useStore.$id = id; + return useStore; +} + +let mapStoreSuffix = 'Store'; +/** + * Changes the suffix added by `mapStores()`. Can be set to an empty string. + * Defaults to `"Store"`. Make sure to extend the MapStoresCustomization + * interface if you are using TypeScript. + * + * @param suffix - new suffix + */ +function setMapStoreSuffix(suffix // could be 'Store' but that would be annoying for JS +) { + mapStoreSuffix = suffix; +} +/** + * Allows using stores without the composition API (`setup()`) by generating an + * object to be spread in the `computed` field of a component. It accepts a list + * of store definitions. + * + * @example + * ```js + * export default { + * computed: { + * // other computed properties + * ...mapStores(useUserStore, useCartStore) + * }, + * + * created() { + * this.userStore // store with id "user" + * this.cartStore // store with id "cart" + * } + * } + * ``` + * + * @param stores - list of stores to map to an object + */ +function mapStores(...stores) { + return stores.reduce((reduced, useStore) => { + // @ts-expect-error: $id is added by defineStore + reduced[useStore.$id + mapStoreSuffix] = function () { + return useStore(this.$pinia); + }; + return reduced; + }, {}); +} +/** + * Allows using state and getters from one store without using the composition + * API (`setup()`) by generating an object to be spread in the `computed` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ +function mapState(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + reduced[key] = function () { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key]; + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function () { + const store = useStore(this.$pinia); + const storeKey = keysOrMapper[key]; + // for some reason TS is unable to infer the type of storeKey to be a + // function + return typeof storeKey === 'function' + ? storeKey.call(this, store) + : // @ts-expect-error: FIXME: should work? + store[storeKey]; + }; + return reduced; + }, {}); +} +/** + * Alias for `mapState()`. You should use `mapState()` instead. + * @deprecated use `mapState()` instead. + */ +const mapGetters = mapState; +/** + * Allows directly using actions from your store without using the composition + * API (`setup()`) by generating an object to be spread in the `methods` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ +function mapActions(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function (...args) { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key](...args); + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-expect-error + reduced[key] = function (...args) { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[keysOrMapper[key]](...args); + }; + return reduced; + }, {}); +} +/** + * Allows using state and getters from one store without using the composition + * API (`setup()`) by generating an object to be spread in the `computed` field + * of a component. + * + * @param useStore - store to map from + * @param keysOrMapper - array or object + */ +function mapWritableState(useStore, keysOrMapper) { + return Array.isArray(keysOrMapper) + ? keysOrMapper.reduce((reduced, key) => { + // @ts-ignore + reduced[key] = { + get() { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[key]; + }, + set(value) { + // @ts-expect-error: FIXME: should work? + return (useStore(this.$pinia)[key] = value); + }, + }; + return reduced; + }, {}) + : Object.keys(keysOrMapper).reduce((reduced, key) => { + // @ts-ignore + reduced[key] = { + get() { + // @ts-expect-error: FIXME: should work? + return useStore(this.$pinia)[keysOrMapper[key]]; + }, + set(value) { + // @ts-expect-error: FIXME: should work? + return (useStore(this.$pinia)[keysOrMapper[key]] = value); + }, + }; + return reduced; + }, {}); +} + +/** + * Creates an object of references with all the state, getters, and plugin-added + * state properties of the store. Similar to `toRefs()` but specifically + * designed for Pinia stores so methods and non reactive properties are + * completely ignored. + * + * @param store - store to extract the refs from + */ +function storeToRefs(store) { + // See https://github.com/vuejs/pinia/issues/852 + // It's easier to just use toRefs() even if it includes more stuff + if (vueDemi.isVue2) { + // @ts-expect-error: toRefs include methods and others + return vueDemi.toRefs(store); + } + else { + const rawStore = vueDemi.toRaw(store); + const refs = {}; + for (const key in rawStore) { + const value = rawStore[key]; + if (vueDemi.isRef(value) || vueDemi.isReactive(value)) { + // @ts-expect-error: the key is state or getter + refs[key] = + // --- + vueDemi.toRef(store, key); + } + } + return refs; + } +} + +/** + * Vue 2 Plugin that must be installed for pinia to work. Note **you don't need + * this plugin if you are using Nuxt.js**. Use the `buildModule` instead: + * https://pinia.vuejs.org/ssr/nuxt.html. + * + * @example + * ```js + * import Vue from 'vue' + * import { PiniaVuePlugin, createPinia } from 'pinia' + * + * Vue.use(PiniaVuePlugin) + * const pinia = createPinia() + * + * new Vue({ + * el: '#app', + * // ... + * pinia, + * }) + * ``` + * + * @param _Vue - `Vue` imported from 'vue'. + */ +const PiniaVuePlugin = function (_Vue) { + // Equivalent of + // app.config.globalProperties.$pinia = pinia + _Vue.mixin({ + beforeCreate() { + const options = this.$options; + if (options.pinia) { + const pinia = options.pinia; + // HACK: taken from provide(): https://github.com/vuejs/composition-api/blob/main/src/apis/inject.ts#L31 + /* istanbul ignore else */ + if (!this._provided) { + const provideCache = {}; + Object.defineProperty(this, '_provided', { + get: () => provideCache, + set: (v) => Object.assign(provideCache, v), + }); + } + this._provided[piniaSymbol] = pinia; + // propagate the pinia instance in an SSR friendly way + // avoid adding it to nuxt twice + /* istanbul ignore else */ + if (!this.$pinia) { + this.$pinia = pinia; + } + pinia._a = this; + if (IS_CLIENT) { + // this allows calling useStore() outside of a component setup after + // installing pinia's plugin + setActivePinia(pinia); + } + } + else if (!this.$pinia && options.parent && options.parent.$pinia) { + this.$pinia = options.parent.$pinia; + } + }, + destroyed() { + delete this._pStores; + }, + }); +}; + +exports.PiniaVuePlugin = PiniaVuePlugin; +exports.acceptHMRUpdate = acceptHMRUpdate; +exports.createPinia = createPinia; +exports.defineStore = defineStore; +exports.disposePinia = disposePinia; +exports.getActivePinia = getActivePinia; +exports.mapActions = mapActions; +exports.mapGetters = mapGetters; +exports.mapState = mapState; +exports.mapStores = mapStores; +exports.mapWritableState = mapWritableState; +exports.setActivePinia = setActivePinia; +exports.setMapStoreSuffix = setMapStoreSuffix; +exports.shouldHydrate = shouldHydrate; +exports.skipHydrate = skipHydrate; +exports.storeToRefs = storeToRefs; diff --git a/node_modules/pinia/index.cjs b/node_modules/pinia/index.cjs new file mode 100644 index 0000000..9fc1f5c --- /dev/null +++ b/node_modules/pinia/index.cjs @@ -0,0 +1,7 @@ +'use strict' + +if (process.env.NODE_ENV === 'production') { + module.exports = require('./dist/pinia.prod.cjs') +} else { + module.exports = require('./dist/pinia.cjs') +} diff --git a/node_modules/pinia/index.js b/node_modules/pinia/index.js new file mode 100644 index 0000000..9fc1f5c --- /dev/null +++ b/node_modules/pinia/index.js @@ -0,0 +1,7 @@ +'use strict' + +if (process.env.NODE_ENV === 'production') { + module.exports = require('./dist/pinia.prod.cjs') +} else { + module.exports = require('./dist/pinia.cjs') +} diff --git a/node_modules/pinia/package.json b/node_modules/pinia/package.json new file mode 100644 index 0000000..177b131 --- /dev/null +++ b/node_modules/pinia/package.json @@ -0,0 +1,126 @@ +{ + "_from": "pinia", + "_id": "pinia@2.2.5", + "_inBundle": false, + "_integrity": "sha512-T4PEQ4uFv2KIRC8A1Y3k1ceQGTDtxtd7nngYGu1IJUUSpuQoYfGq7w7rOc+f5YN1vx3mEs2NjjtN2IFbNS7jqA==", + "_location": "/pinia", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "pinia", + "name": "pinia", + "escapedName": "pinia", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.2.5.tgz", + "_shasum": "3269ff2cd67ae3dcc939334c0cf985f86c48b7a1", + "_spec": "pinia", + "_where": "D:\\FeiYi", + "author": { + "name": "Eduardo San Martin Morote", + "email": "posva13@gmail.com" + }, + "bugs": { + "url": "https://github.com/vuejs/pinia/issues" + }, + "bundleDependencies": false, + "dependencies": { + "@vue/devtools-api": "^6.6.3", + "vue-demi": "^0.14.10" + }, + "deprecated": false, + "description": "Intuitive, type safe and flexible Store for Vue", + "devDependencies": { + "@microsoft/api-extractor": "7.47.9", + "@vue/test-utils": "^2.4.6" + }, + "exports": { + ".": { + "types": "./dist/pinia.d.ts", + "node": { + "import": { + "production": "./dist/pinia.prod.cjs", + "development": "./dist/pinia.mjs", + "default": "./dist/pinia.mjs" + }, + "require": { + "production": "./dist/pinia.prod.cjs", + "development": "./dist/pinia.cjs", + "default": "./index.js" + } + }, + "import": "./dist/pinia.mjs", + "require": "./index.js" + }, + "./package.json": "./package.json", + "./dist/*": "./dist/*" + }, + "files": [ + "dist/*.js", + "dist/*.mjs", + "dist/*.cjs", + "dist/pinia.d.ts", + "index.js", + "index.cjs", + "LICENSE", + "README.md" + ], + "funding": "https://github.com/sponsors/posva", + "homepage": "https://github.com/vuejs/pinia#readme", + "jsdelivr": "dist/pinia.iife.js", + "keywords": [ + "vue", + "vuex", + "store", + "pinia", + "piña", + "pigna", + "composition", + "api", + "setup", + "typed", + "typescript", + "ts", + "type", + "safe" + ], + "license": "MIT", + "main": "index.js", + "module": "dist/pinia.mjs", + "name": "pinia", + "peerDependencies": { + "@vue/composition-api": "^1.4.0", + "typescript": ">=4.4.4", + "vue": "^2.6.14 || ^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "@vue/composition-api": { + "optional": true + } + }, + "repository": { + "type": "git", + "url": "git+https://github.com/vuejs/pinia.git" + }, + "scripts": { + "build": "rimraf dist && rollup -c ../../rollup.config.mjs --environment TARGET:pinia", + "build:dts": "api-extractor run --local --verbose && tail -n +3 ./src/globalExtensions.ts >> dist/pinia.d.ts", + "changelog": "conventional-changelog -p angular -i CHANGELOG.md -s --commit-path . -l pinia -r 1", + "test": "pnpm run build && pnpm run build:dts && pnpm test:dts", + "test:dts": "tsc -p ./test-dts/tsconfig.json" + }, + "sideEffects": false, + "types": "dist/pinia.d.ts", + "unpkg": "dist/pinia.iife.js", + "version": "2.2.5" +} diff --git a/node_modules/vue-demi/LICENSE b/node_modules/vue-demi/LICENSE new file mode 100644 index 0000000..894ffaf --- /dev/null +++ b/node_modules/vue-demi/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020-present, Anthony Fu + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/vue-demi/README.md b/node_modules/vue-demi/README.md new file mode 100644 index 0000000..f941590 --- /dev/null +++ b/node_modules/vue-demi/README.md @@ -0,0 +1,229 @@ + + +

+Vue Demi (half in French) is a developing utility
allows you to write Universal Vue Libraries for Vue 2 & 3
+See more details in this blog post +

+ +
+ +
+ +## Strategies + +- `<=2.6`: exports from `vue` + `@vue/composition-api` with plugin auto installing. +- `2.7`: exports from `vue` (Composition API is built-in in Vue 2.7). +- `>=3.0`: exports from `vue`, with polyfill of Vue 2's `set` and `del` API. + +## Usage + +Install this as your plugin's dependency: + +```bash +npm i vue-demi +# or +yarn add vue-demi +# or +pnpm i vue-demi +``` + +Add `vue` and `@vue/composition-api` to your plugin's peer dependencies to specify what versions you support. + +```jsonc +{ + "dependencies": { + "vue-demi": "latest" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^2.0.0 || >=3.0.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + }, + "devDependencies": { + "vue": "^3.0.0" // or "^2.6.0" base on your preferred working environment + }, +} +``` + +Import everything related to Vue from it, it will redirect to `vue@2` + `@vue/composition-api` or `vue@3` based on users' environments. + +```ts +import { ref, reactive, defineComponent } from 'vue-demi' +``` + +Publish your plugin and all is done! + +> When using with [Vite](https://vitejs.dev), you will need to opt-out the pre-bundling to get `vue-demi` work properly by +> ```js +> // vite.config.js +> export default defineConfig({ +> optimizeDeps: { +> exclude: ['vue-demi'] +> } +> }) +> ``` + +### Extra APIs + +`Vue Demi` provides extra APIs to help distinguish users' environments and to do some version-specific logic. + +### `isVue2` `isVue3` + +```ts +import { isVue2, isVue3 } from 'vue-demi' + +if (isVue2) { + // Vue 2 only +} else { + // Vue 3 only +} +``` + +### `Vue2` + +To avoid bringing in all the tree-shakable modules, we provide a `Vue2` export to support access to Vue 2's global API. (See [#41](https://github.com/vueuse/vue-demi/issues/41).) + +```ts +import { Vue2 } from 'vue-demi' + +if (Vue2) { + Vue2.config.ignoredElements.push('x-foo') +} +``` + +### `install()` + +Composition API in Vue 2 is provided as a plugin and needs to be installed on the Vue instance before using. Normally, `vue-demi` will try to install it automatically. For some usages where you might need to ensure the plugin gets installed correctly, the `install()` API is exposed to as a safe version of `Vue.use(CompositionAPI)`. `install()` in the Vue 3 environment will be an empty function (no-op). + +```ts +import { install } from 'vue-demi' + +install() +``` + +## CLI + +### Manually Switch Versions + +To explicitly switch the redirecting version, you can use these commands in your project's root. + +```bash +npx vue-demi-switch 2 +# or +npx vue-demi-switch 3 +``` + +### Package Aliasing + +If you would like to import `vue` under an alias, you can use the following command + +```bash +npx vue-demi-switch 2 vue2 +# or +npx vue-demi-switch 3 vue3 +``` + +Then `vue-demi` will redirect APIs from the alias name you specified, for example: + +```ts +import * as Vue from 'vue3' + +var isVue2 = false +var isVue3 = true +var Vue2 = undefined + +export * from 'vue3' +export { + Vue, + Vue2, + isVue2, + isVue3, +} +``` + +### Auto Fix + +If the `postinstall` hook doesn't get triggered or you have updated the Vue version, try to run the following command to resolve the redirecting. + +```bash +npx vue-demi-fix +``` + +### Isomorphic Testings + +You can support testing for both versions by adding npm alias in your dev dependencies. For example: + +```json +{ + "scripts": { + "test:2": "vue-demi-switch 2 vue2 && jest", + "test:3": "vue-demi-switch 3 && jest", + }, + "devDependencies": { + "vue": "^3.0.0", + "vue2": "npm:vue@2" + }, +} +``` + +or + +```json +{ + "scripts": { + "test:2": "vue-demi-switch 2 && jest", + "test:3": "vue-demi-switch 3 vue3 && jest", + }, + "devDependencies": { + "vue": "^2.6.0", + "vue3": "npm:vue@3" + }, +} +``` + +## Examples + +See [examples](./examples). + +## Who is using this? + +- [VueUse](https://github.com/vueuse/vueuse) - Collection of Composition API utils +- [@vue/apollo-composable](https://github.com/vuejs/vue-apollo/tree/v4/packages/vue-apollo-composable) - Apollo GraphQL functions for Vue Composition API +- [vuelidate](https://github.com/vuelidate/vuelidate) - Simple, lightweight model-based validation +- [vue-composition-test-utils](https://github.com/ariesjia/vue-composition-test-utils) - Simple vue composition api unit test utilities +- [vue-use-stripe](https://github.com/frandiox/vue-use-stripe) - Stripe Elements wrapper for Vue.js +- [@opd/g2plot-vue](https://github.com/open-data-plan/g2plot-vue) - G2plot for vue +- [vue-echarts](https://github.com/ecomfe/vue-echarts) - Vue.js component for Apache ECharts. +- [fluent-vue](https://github.com/Demivan/fluent-vue) - Vue.js integration for [Fluent.js](https://github.com/projectfluent/fluent.js) - JavaScript implementation of [Project Fluent](https://projectfluent.org) +- [vue-datatable-url-sync](https://github.com/socotecio/vue-datatable-url-sync) - Synchronize datatable options and filters with the url to keep user preference even after refresh or navigation +- [vue-insta-stories](https://github.com/UnevenSoftware/vue-insta-stories) - Instagram stories in your vue projects. +- [vue-tiny-validate](https://github.com/FrontLabsOfficial/vue-tiny-validate) - Tiny Vue Validate Composition +- [v-perfect-signature](https://github.com/wobsoriano/v-perfect-signature) - Pressure-sensitive signature drawing for Vue 2 and 3 +- [vue-winbox](https://github.com/wobsoriano/vue-winbox) - A wrapper component for WinBox.js that adds the ability to mount Vue components. +- [vue-word-highlighter](https://github.com/kawamataryo/vue-word-highlighter) - The word highlighter library for Vue 2 and Vue 3 +- [vue-chart-3](https://github.com/victorgarciaesgi/vue-chart-3) - Vue.js component for Chart.js +- [json-editor-vue](https://github.com/cloydlau/json-editor-vue) - JSON editor & viewer for Vue 2 and 3. +- [kidar-echarts](https://github.com/kidarjs/kidar-echarts) - A simpler echarts component for Vue 2 and 3. +- [vue3-sketch-ruler](https://github.com/kakajun/vue3-sketch-ruler) - The zoom operation used for page presentation for Vue 2 and 3( Replace render function with template ) +- [vue-rough-notation](https://github.com/Leecason/vue-rough-notation) - RoughNotation wrapper component for Vue 2 and 3. +- [vue-request](https://github.com/AttoJS/vue-request) - Vue composition API for data fetching, supports SWR, polling, error retry, cache request, pagination, etc. +- [vue3-lazyload](https://github.com/murongg/vue3-lazyload) - A vue3.x image lazyload plugin. +- [vue-codemirror6](https://github.com/logue/vue-codemirror6) - CodeMirror6 component for Vue2 and 3. +- [@tanstack/vue-query](https://github.com/TanStack/query) - TanStack Query for Vue. +> open a PR to add your library ;) + +## Underhood + +See [the blog post](https://antfu.me/posts/make-libraries-working-with-vue-2-and-3/#-introducing-vue-demi). + +## License + +MIT License © 2020 [Anthony Fu](https://github.com/antfu) diff --git a/node_modules/vue-demi/bin/vue-demi-fix.js b/node_modules/vue-demi/bin/vue-demi-fix.js new file mode 100644 index 0000000..684a621 --- /dev/null +++ b/node_modules/vue-demi/bin/vue-demi-fix.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node +'use strict' +require('../scripts/postinstall') diff --git a/node_modules/vue-demi/bin/vue-demi-switch.js b/node_modules/vue-demi/bin/vue-demi-switch.js new file mode 100644 index 0000000..360eada --- /dev/null +++ b/node_modules/vue-demi/bin/vue-demi-switch.js @@ -0,0 +1,3 @@ +#!/usr/bin/env node +'use strict' +require('../scripts/switch-cli') diff --git a/node_modules/vue-demi/lib/index.cjs b/node_modules/vue-demi/lib/index.cjs new file mode 100644 index 0000000..8197f90 --- /dev/null +++ b/node_modules/vue-demi/lib/index.cjs @@ -0,0 +1,29 @@ +var Vue = require('vue') + +Object.keys(Vue).forEach(function(key) { + exports[key] = Vue[key] +}) + +exports.set = function(target, key, val) { + if (Array.isArray(target)) { + target.length = Math.max(target.length, key) + target.splice(key, 1, val) + return val + } + target[key] = val + return val +} + +exports.del = function(target, key) { + if (Array.isArray(target)) { + target.splice(key, 1) + return + } + delete target[key] +} + +exports.Vue = Vue +exports.Vue2 = undefined +exports.isVue2 = false +exports.isVue3 = true +exports.install = function(){} diff --git a/node_modules/vue-demi/lib/index.d.ts b/node_modules/vue-demi/lib/index.d.ts new file mode 100644 index 0000000..897b4c5 --- /dev/null +++ b/node_modules/vue-demi/lib/index.d.ts @@ -0,0 +1,22 @@ +import * as Vue from 'vue' +declare const isVue2: boolean +declare const isVue3: boolean +declare const Vue2: any +declare const install: (vue?: any) => void +/** + * @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead. + * Refer to https://github.com/vueuse/vue-demi/issues/41 + */ +declare const V: typeof Vue + +export function set(target: any, key: any, val: T): T +export function del(target: any, key: any): void + +export * from 'vue' +export { + V as Vue, + Vue2, + isVue2, + isVue3, + install, +} diff --git a/node_modules/vue-demi/lib/index.iife.js b/node_modules/vue-demi/lib/index.iife.js new file mode 100644 index 0000000..fd017b7 --- /dev/null +++ b/node_modules/vue-demi/lib/index.iife.js @@ -0,0 +1,126 @@ +var _VueDemiGlobal = typeof globalThis !== 'undefined' + ? globalThis + : typeof global !== 'undefined' + ? global + : typeof self !== 'undefined' + ? self + : this +var VueDemi = (function (VueDemi, Vue, VueCompositionAPI) { + if (VueDemi.install) { + return VueDemi + } + if (!Vue) { + console.error('[vue-demi] no Vue instance found, please be sure to import `vue` before `vue-demi`.') + return VueDemi + } + + // Vue 2.7 + if (Vue.version.slice(0, 4) === '2.7.') { + for (var key in Vue) { + VueDemi[key] = Vue[key] + } + VueDemi.isVue2 = true + VueDemi.isVue3 = false + VueDemi.install = function () {} + VueDemi.Vue = Vue + VueDemi.Vue2 = Vue + VueDemi.version = Vue.version + VueDemi.warn = Vue.util.warn + VueDemi.hasInjectionContext = function() { + return !!VueDemi.getCurrentInstance() + } + function createApp(rootComponent, rootProps) { + var vm + var provide = {} + var app = { + config: Vue.config, + use: Vue.use.bind(Vue), + mixin: Vue.mixin.bind(Vue), + component: Vue.component.bind(Vue), + provide: function (key, value) { + provide[key] = value + return this + }, + directive: function (name, dir) { + if (dir) { + Vue.directive(name, dir) + return app + } else { + return Vue.directive(name) + } + }, + mount: function (el, hydrating) { + if (!vm) { + vm = new Vue(Object.assign({ propsData: rootProps }, rootComponent, { provide: Object.assign(provide, rootComponent.provide) })) + vm.$mount(el, hydrating) + return vm + } else { + return vm + } + }, + unmount: function () { + if (vm) { + vm.$destroy() + vm = undefined + } + }, + } + return app + } + VueDemi.createApp = createApp + } + // Vue 2.6.x + else if (Vue.version.slice(0, 2) === '2.') { + if (VueCompositionAPI) { + for (var key in VueCompositionAPI) { + VueDemi[key] = VueCompositionAPI[key] + } + VueDemi.isVue2 = true + VueDemi.isVue3 = false + VueDemi.install = function () {} + VueDemi.Vue = Vue + VueDemi.Vue2 = Vue + VueDemi.version = Vue.version + VueDemi.hasInjectionContext = function() { + return !!VueDemi.getCurrentInstance() + } + } else { + console.error('[vue-demi] no VueCompositionAPI instance found, please be sure to import `@vue/composition-api` before `vue-demi`.') + } + } + // Vue 3 + else if (Vue.version.slice(0, 2) === '3.') { + for (var key in Vue) { + VueDemi[key] = Vue[key] + } + VueDemi.isVue2 = false + VueDemi.isVue3 = true + VueDemi.install = function () {} + VueDemi.Vue = Vue + VueDemi.Vue2 = undefined + VueDemi.version = Vue.version + VueDemi.set = function (target, key, val) { + if (Array.isArray(target)) { + target.length = Math.max(target.length, key) + target.splice(key, 1, val) + return val + } + target[key] = val + return val + } + VueDemi.del = function (target, key) { + if (Array.isArray(target)) { + target.splice(key, 1) + return + } + delete target[key] + } + } else { + console.error('[vue-demi] Vue version ' + Vue.version + ' is unsupported.') + } + return VueDemi +})( + (_VueDemiGlobal.VueDemi = _VueDemiGlobal.VueDemi || (typeof VueDemi !== 'undefined' ? VueDemi : {})), + _VueDemiGlobal.Vue || (typeof Vue !== 'undefined' ? Vue : undefined), + _VueDemiGlobal.VueCompositionAPI || (typeof VueCompositionAPI !== 'undefined' ? VueCompositionAPI : undefined) +); diff --git a/node_modules/vue-demi/lib/index.mjs b/node_modules/vue-demi/lib/index.mjs new file mode 100644 index 0000000..be3a96d --- /dev/null +++ b/node_modules/vue-demi/lib/index.mjs @@ -0,0 +1,34 @@ +import * as Vue from 'vue' + +var isVue2 = false +var isVue3 = true +var Vue2 = undefined + +function install() {} + +export function set(target, key, val) { + if (Array.isArray(target)) { + target.length = Math.max(target.length, key) + target.splice(key, 1, val) + return val + } + target[key] = val + return val +} + +export function del(target, key) { + if (Array.isArray(target)) { + target.splice(key, 1) + return + } + delete target[key] +} + +export * from 'vue' +export { + Vue, + Vue2, + isVue2, + isVue3, + install, +} diff --git a/node_modules/vue-demi/lib/v2.7/index.cjs b/node_modules/vue-demi/lib/v2.7/index.cjs new file mode 100644 index 0000000..8fa3b68 --- /dev/null +++ b/node_modules/vue-demi/lib/v2.7/index.cjs @@ -0,0 +1,60 @@ +var VueModule = require('vue') + +// get the real Vue https://github.com/vueuse/vue-demi/issues/192 +var Vue = VueModule.default || VueModule + +exports.Vue = Vue +exports.Vue2 = Vue +exports.isVue2 = true +exports.isVue3 = false +exports.install = function () {} +exports.warn = Vue.util.warn + +// createApp polyfill +exports.createApp = function (rootComponent, rootProps) { + var vm + var provide = {} + var app = { + config: Vue.config, + use: Vue.use.bind(Vue), + mixin: Vue.mixin.bind(Vue), + component: Vue.component.bind(Vue), + provide: function (key, value) { + provide[key] = value + return this + }, + directive: function (name, dir) { + if (dir) { + Vue.directive(name, dir) + return app + } else { + return Vue.directive(name) + } + }, + mount: function (el, hydrating) { + if (!vm) { + vm = new Vue(Object.assign({ propsData: rootProps }, rootComponent, { provide: Object.assign(provide, rootComponent.provide) })) + vm.$mount(el, hydrating) + return vm + } else { + return vm + } + }, + unmount: function () { + if (vm) { + vm.$destroy() + vm = undefined + } + }, + } + return app +} + +Object.keys(VueModule).forEach(function (key) { + exports[key] = VueModule[key] +}) + +// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance() +exports.hasInjectionContext = function() { + return !!VueModule.getCurrentInstance() +} \ No newline at end of file diff --git a/node_modules/vue-demi/lib/v2.7/index.d.ts b/node_modules/vue-demi/lib/v2.7/index.d.ts new file mode 100644 index 0000000..827c7b2 --- /dev/null +++ b/node_modules/vue-demi/lib/v2.7/index.d.ts @@ -0,0 +1,38 @@ +import Vue from 'vue' +import type { PluginFunction, PluginObject, VueConstructor, Directive, InjectionKey, Component } from 'vue' + +declare const isVue2: boolean +declare const isVue3: boolean +declare const Vue2: typeof Vue | undefined +declare const version: string +declare const install: (vue?: typeof Vue) => void +export declare function warn(msg: string, vm?: Component | null): void +/** + * @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead. + * Refer to https://github.com/vueuse/vue-demi/issues/41 + */ +declare const V: typeof Vue + +// accept no generic because Vue 3 doesn't accept any +// https://github.com/vuejs/vue-next/pull/2758/ +export declare type Plugin = PluginObject | PluginFunction +export type { VNode } from 'vue' +export * from 'vue' +export { V as Vue, Vue2, isVue2, isVue3, version, install } + +// #region createApp polyfill +export interface App { + config: VueConstructor['config'] + use: VueConstructor['use'] + mixin: VueConstructor['mixin'] + component: VueConstructor['component'] + directive(name: string): Directive | undefined + directive(name: string, directive: Directive): this + provide(key: InjectionKey | string, value: T): this + mount: Vue['$mount'] + unmount: Vue['$destroy'] +} +export declare function createApp(rootComponent: any, rootProps?: any): App +// #endregion + +export declare function hasInjectionContext(): boolean diff --git a/node_modules/vue-demi/lib/v2.7/index.mjs b/node_modules/vue-demi/lib/v2.7/index.mjs new file mode 100644 index 0000000..e575059 --- /dev/null +++ b/node_modules/vue-demi/lib/v2.7/index.mjs @@ -0,0 +1,80 @@ +import Vue from 'vue' +import { getCurrentInstance } from 'vue' + +var isVue2 = true +var isVue3 = false +var Vue2 = Vue +var warn = Vue.util.warn + +function install() {} + +// createApp polyfill +export function createApp(rootComponent, rootProps) { + var vm + var provide = {} + var app = { + config: Vue.config, + use: Vue.use.bind(Vue), + mixin: Vue.mixin.bind(Vue), + component: Vue.component.bind(Vue), + provide: function (key, value) { + provide[key] = value + return this + }, + directive: function (name, dir) { + if (dir) { + Vue.directive(name, dir) + return app + } else { + return Vue.directive(name) + } + }, + mount: function (el, hydrating) { + if (!vm) { + vm = new Vue(Object.assign({ propsData: rootProps }, rootComponent, { provide: Object.assign(provide, rootComponent.provide) })) + vm.$mount(el, hydrating) + return vm + } else { + return vm + } + }, + unmount: function () { + if (vm) { + vm.$destroy() + vm = undefined + } + }, + } + return app +} + +export { + Vue, + Vue2, + isVue2, + isVue3, + install, + warn +} + +// Vue 3 components mock +function createMockComponent(name) { + return { + setup() { + throw new Error('[vue-demi] ' + name + ' is not supported in Vue 2. It\'s provided to avoid compiler errors.') + } + } +} +export var Fragment = /*#__PURE__*/ createMockComponent('Fragment') +export var Transition = /*#__PURE__*/ createMockComponent('Transition') +export var TransitionGroup = /*#__PURE__*/ createMockComponent('TransitionGroup') +export var Teleport = /*#__PURE__*/ createMockComponent('Teleport') +export var Suspense = /*#__PURE__*/ createMockComponent('Suspense') +export var KeepAlive = /*#__PURE__*/ createMockComponent('KeepAlive') + +export * from 'vue' + +// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance() +export function hasInjectionContext() { + return !!getCurrentInstance() +} diff --git a/node_modules/vue-demi/lib/v2/index.cjs b/node_modules/vue-demi/lib/v2/index.cjs new file mode 100644 index 0000000..c3d298e --- /dev/null +++ b/node_modules/vue-demi/lib/v2/index.cjs @@ -0,0 +1,34 @@ +var Vue = require('vue') +var VueCompositionAPI = require('@vue/composition-api') + +function install(_vue) { + var vueLib = _vue || Vue + if (vueLib && 'default' in vueLib) { + vueLib = vueLib.default + } + + if (vueLib && !vueLib['__composition_api_installed__']) { + if (VueCompositionAPI && 'default' in VueCompositionAPI) + vueLib.use(VueCompositionAPI.default) + else if (VueCompositionAPI) + vueLib.use(VueCompositionAPI) + } +} + +install(Vue) + +Object.keys(VueCompositionAPI).forEach(function(key) { + exports[key] = VueCompositionAPI[key] +}) + +exports.Vue = Vue +exports.Vue2 = Vue +exports.isVue2 = true +exports.isVue3 = false +exports.install = install +exports.version = Vue.version + +// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance() +exports.hasInjectionContext = function () { + return !!VueCompositionAPI.getCurrentInstance() +} diff --git a/node_modules/vue-demi/lib/v2/index.d.ts b/node_modules/vue-demi/lib/v2/index.d.ts new file mode 100644 index 0000000..bbdcbc5 --- /dev/null +++ b/node_modules/vue-demi/lib/v2/index.d.ts @@ -0,0 +1,33 @@ +import Vue from 'vue' +import type { PluginFunction, PluginObject } from 'vue' +declare const isVue2: boolean +declare const isVue3: boolean +declare const Vue2: typeof Vue | undefined +declare const version: string +declare const install: (vue?: typeof Vue) => void +/** + * @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead. + * Refer to https://github.com/vueuse/vue-demi/issues/41 + */ +declare const V: typeof Vue + +/** + * DebuggerEvent is a Vue 3 development only feature. This type cannot exist in Vue 2. + */ +export declare type DebuggerEvent = never + +// accept no generic because Vue 3 doesn't accept any +// https://github.com/vuejs/vue-next/pull/2758/ +export declare type Plugin = PluginObject | PluginFunction +export type { VNode } from 'vue' +export * from '@vue/composition-api' +export { + V as Vue, + Vue2, + isVue2, + isVue3, + version, + install, +} + +export declare function hasInjectionContext(): boolean diff --git a/node_modules/vue-demi/lib/v2/index.mjs b/node_modules/vue-demi/lib/v2/index.mjs new file mode 100644 index 0000000..2c18122 --- /dev/null +++ b/node_modules/vue-demi/lib/v2/index.mjs @@ -0,0 +1,49 @@ +import Vue from 'vue' +import VueCompositionAPI, { getCurrentInstance } from '@vue/composition-api/dist/vue-composition-api.mjs' + +function install(_vue) { + _vue = _vue || Vue + if (_vue && !_vue['__composition_api_installed__']) + _vue.use(VueCompositionAPI) +} + +install(Vue) + +var isVue2 = true +var isVue3 = false +var Vue2 = Vue +var version = Vue.version + +/**VCA-EXPORTS**/ +export * from '@vue/composition-api/dist/vue-composition-api.mjs' +/**VCA-EXPORTS**/ + +export { + Vue, + Vue2, + isVue2, + isVue3, + version, + install, +} + + +// Vue 3 components mock +function createMockComponent(name) { + return { + setup() { + throw new Error('[vue-demi] ' + name + ' is not supported in Vue 2. It\'s provided to avoid compiler errors.') + } + } +} +export var Fragment = /*#__PURE__*/ createMockComponent('Fragment') +export var Transition = /*#__PURE__*/ createMockComponent('Transition') +export var TransitionGroup = /*#__PURE__*/ createMockComponent('TransitionGroup') +export var Teleport = /*#__PURE__*/ createMockComponent('Teleport') +export var Suspense = /*#__PURE__*/ createMockComponent('Suspense') +export var KeepAlive = /*#__PURE__*/ createMockComponent('KeepAlive') + +// Not implemented https://github.com/vuejs/core/pull/8111, falls back to getCurrentInstance() +export function hasInjectionContext() { + return !!getCurrentInstance() +} diff --git a/node_modules/vue-demi/lib/v3/index.cjs b/node_modules/vue-demi/lib/v3/index.cjs new file mode 100644 index 0000000..8197f90 --- /dev/null +++ b/node_modules/vue-demi/lib/v3/index.cjs @@ -0,0 +1,29 @@ +var Vue = require('vue') + +Object.keys(Vue).forEach(function(key) { + exports[key] = Vue[key] +}) + +exports.set = function(target, key, val) { + if (Array.isArray(target)) { + target.length = Math.max(target.length, key) + target.splice(key, 1, val) + return val + } + target[key] = val + return val +} + +exports.del = function(target, key) { + if (Array.isArray(target)) { + target.splice(key, 1) + return + } + delete target[key] +} + +exports.Vue = Vue +exports.Vue2 = undefined +exports.isVue2 = false +exports.isVue3 = true +exports.install = function(){} diff --git a/node_modules/vue-demi/lib/v3/index.d.ts b/node_modules/vue-demi/lib/v3/index.d.ts new file mode 100644 index 0000000..897b4c5 --- /dev/null +++ b/node_modules/vue-demi/lib/v3/index.d.ts @@ -0,0 +1,22 @@ +import * as Vue from 'vue' +declare const isVue2: boolean +declare const isVue3: boolean +declare const Vue2: any +declare const install: (vue?: any) => void +/** + * @deprecated To avoid bringing in all the tree-shakable modules, this API has been deprecated. Use `Vue2` or named exports instead. + * Refer to https://github.com/vueuse/vue-demi/issues/41 + */ +declare const V: typeof Vue + +export function set(target: any, key: any, val: T): T +export function del(target: any, key: any): void + +export * from 'vue' +export { + V as Vue, + Vue2, + isVue2, + isVue3, + install, +} diff --git a/node_modules/vue-demi/lib/v3/index.mjs b/node_modules/vue-demi/lib/v3/index.mjs new file mode 100644 index 0000000..be3a96d --- /dev/null +++ b/node_modules/vue-demi/lib/v3/index.mjs @@ -0,0 +1,34 @@ +import * as Vue from 'vue' + +var isVue2 = false +var isVue3 = true +var Vue2 = undefined + +function install() {} + +export function set(target, key, val) { + if (Array.isArray(target)) { + target.length = Math.max(target.length, key) + target.splice(key, 1, val) + return val + } + target[key] = val + return val +} + +export function del(target, key) { + if (Array.isArray(target)) { + target.splice(key, 1) + return + } + delete target[key] +} + +export * from 'vue' +export { + Vue, + Vue2, + isVue2, + isVue3, + install, +} diff --git a/node_modules/vue-demi/package.json b/node_modules/vue-demi/package.json new file mode 100644 index 0000000..bb1166f --- /dev/null +++ b/node_modules/vue-demi/package.json @@ -0,0 +1,83 @@ +{ + "_from": "vue-demi@^0.14.10", + "_id": "vue-demi@0.14.10", + "_inBundle": false, + "_integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "_location": "/vue-demi", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "vue-demi@^0.14.10", + "name": "vue-demi", + "escapedName": "vue-demi", + "rawSpec": "^0.14.10", + "saveSpec": null, + "fetchSpec": "^0.14.10" + }, + "_requiredBy": [ + "/pinia" + ], + "_resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz", + "_shasum": "afc78de3d6f9e11bf78c55e8510ee12814522f04", + "_spec": "vue-demi@^0.14.10", + "_where": "D:\\FeiYi\\node_modules\\pinia", + "author": { + "name": "Anthony Fu", + "email": "anthonyfu117@hotmail.com" + }, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "bugs": { + "url": "https://github.com/antfu/vue-demi/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "


npm

", + "engines": { + "node": ">=12" + }, + "exports": { + ".": { + "types": "./lib/index.d.ts", + "require": "./lib/index.cjs", + "import": "./lib/index.mjs", + "browser": "./lib/index.mjs" + }, + "./*": "./*" + }, + "files": [ + "lib", + "bin", + "scripts" + ], + "funding": "https://github.com/sponsors/antfu", + "homepage": "https://github.com/antfu/vue-demi#readme", + "jsdelivr": "lib/index.iife.js", + "license": "MIT", + "main": "lib/index.cjs", + "module": "lib/index.mjs", + "name": "vue-demi", + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + }, + "repository": { + "type": "git", + "url": "git+https://github.com/antfu/vue-demi.git" + }, + "scripts": { + "postinstall": "node -e \"try{require('./scripts/postinstall.js')}catch(e){}\"", + "release": "npx bumpp --tag --commit --push && npm publish" + }, + "types": "lib/index.d.ts", + "unpkg": "lib/index.iife.js", + "version": "0.14.10" +} diff --git a/node_modules/vue-demi/scripts/postinstall.js b/node_modules/vue-demi/scripts/postinstall.js new file mode 100644 index 0000000..7baf14e --- /dev/null +++ b/node_modules/vue-demi/scripts/postinstall.js @@ -0,0 +1,19 @@ +const { switchVersion, loadModule } = require('./utils') + +const Vue = loadModule('vue') + +if (!Vue || typeof Vue.version !== 'string') { + console.warn('[vue-demi] Vue is not found. Please run "npm install vue" to install.') +} +else if (Vue.version.startsWith('2.7.')) { + switchVersion(2.7) +} +else if (Vue.version.startsWith('2.')) { + switchVersion(2) +} +else if (Vue.version.startsWith('3.')) { + switchVersion(3) +} +else { + console.warn(`[vue-demi] Vue version v${Vue.version} is not supported.`) +} diff --git a/node_modules/vue-demi/scripts/switch-cli.js b/node_modules/vue-demi/scripts/switch-cli.js new file mode 100644 index 0000000..3c104ca --- /dev/null +++ b/node_modules/vue-demi/scripts/switch-cli.js @@ -0,0 +1,18 @@ +const { switchVersion } = require('./utils') + +const version = process.argv[2] +const vueEntry = process.argv[3] || 'vue' + +if (version === '2.7') { + switchVersion(2.7, vueEntry) + console.log(`[vue-demi] Switched for Vue 2.7 (entry: "${vueEntry}")`) +} else if (version === '2') { + switchVersion(2, vueEntry) + console.log(`[vue-demi] Switched for Vue 2 (entry: "${vueEntry}")`) +} else if (version === '3') { + switchVersion(3, vueEntry) + console.log(`[vue-demi] Switched for Vue 3 (entry: "${vueEntry}")`) +} else { + console.warn(`[vue-demi] expecting version "2" or "2.7" or "3" but got "${version}"`) + process.exit(1) +} diff --git a/node_modules/vue-demi/scripts/utils.js b/node_modules/vue-demi/scripts/utils.js new file mode 100644 index 0000000..eff99f0 --- /dev/null +++ b/node_modules/vue-demi/scripts/utils.js @@ -0,0 +1,62 @@ +const fs = require('fs') +const path = require('path') + +const dir = path.resolve(__dirname, '..', 'lib') + +function loadModule(name) { + try { + return require(name) + } catch (e) { + return undefined + } +} + +function copy(name, version, vue) { + vue = vue || 'vue' + const src = path.join(dir, `v${version}`, name) + const dest = path.join(dir, name) + let content = fs.readFileSync(src, 'utf-8') + content = content.replace(/'vue'/g, `'${vue}'`) + // unlink for pnpm, #92 + try { + fs.unlinkSync(dest) + } catch (error) { } + fs.writeFileSync(dest, content, 'utf-8') +} + +function updateVue2API() { + const ignoreList = ['version', 'default'] + const VCA = loadModule('@vue/composition-api') + if (!VCA) { + console.warn('[vue-demi] Composition API plugin is not found. Please run "npm install @vue/composition-api" to install.') + return + } + + const exports = Object.keys(VCA).filter(i => !ignoreList.includes(i)) + + const esmPath = path.join(dir, 'index.mjs') + let content = fs.readFileSync(esmPath, 'utf-8') + + content = content.replace( + /\/\*\*VCA-EXPORTS\*\*\/[\s\S]+\/\*\*VCA-EXPORTS\*\*\//m, +`/**VCA-EXPORTS**/ +export { ${exports.join(', ')} } from '@vue/composition-api/dist/vue-composition-api.mjs' +/**VCA-EXPORTS**/` + ) + + fs.writeFileSync(esmPath, content, 'utf-8') + +} + +function switchVersion(version, vue) { + copy('index.cjs', version, vue) + copy('index.mjs', version, vue) + copy('index.d.ts', version, vue) + + if (version === 2) + updateVue2API() +} + + +module.exports.loadModule = loadModule +module.exports.switchVersion = switchVersion diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..f317812 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,30 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==" + }, + "mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" + }, + "pinia": { + "version": "2.2.5", + "resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.2.5.tgz", + "integrity": "sha512-T4PEQ4uFv2KIRC8A1Y3k1ceQGTDtxtd7nngYGu1IJUUSpuQoYfGq7w7rOc+f5YN1vx3mEs2NjjtN2IFbNS7jqA==", + "requires": { + "@vue/devtools-api": "^6.6.3", + "vue-demi": "^0.14.10" + } + }, + "vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==" + } + } +} diff --git a/pages.json b/pages.json index 6883ac7..c01a108 100644 --- a/pages.json +++ b/pages.json @@ -157,6 +157,13 @@ { "navigationBarTitleText" : "" } + }, + { + "path" : "pages/order/productOrderDetail/productOrderDetail", + "style" : + { + "navigationBarTitleText" : "" + } } ], "globalStyle": { diff --git a/pages/mine/main/main.vue b/pages/mine/main/main.vue index 4a5bc03..431f8c7 100644 --- a/pages/mine/main/main.vue +++ b/pages/mine/main/main.vue @@ -1,6 +1,6 @@ \ No newline at end of file diff --git a/pages/utils/emitter.ts b/pages/utils/emitter.ts new file mode 100644 index 0000000..1e79349 --- /dev/null +++ b/pages/utils/emitter.ts @@ -0,0 +1,5 @@ +import mitt from 'mitt' + +const emitter = mitt() + +export default emitter \ No newline at end of file diff --git a/store/index.js b/store/index.js new file mode 100644 index 0000000..c26da0e --- /dev/null +++ b/store/index.js @@ -0,0 +1,5 @@ +import { createPinia } from 'pinia' + +const pinia = createPinia() + +export default pinia //导出名为store diff --git a/store/userStore.ts b/store/userStore.ts new file mode 100644 index 0000000..ef6668a --- /dev/null +++ b/store/userStore.ts @@ -0,0 +1,25 @@ +import {defineStore} from "pinia"; +import { baseUrl, testUrl , suiUrl} from '@/api/request'; +export const userStore = defineStore('userInfo', { + state: () => { + return { + userInfo: { + id: 2, + userAvatar: '', + userName: '匠承非遗', + points: 800 + } + } + }, + actions: { + // updateUserInfo: async () => { + // const res = await uni.request({ + // url: testUrl + '/user/updateUser' + // }) + // console.log(res) + // }, + // getLoginUser(res) { + + // } + } +}) diff --git a/unpackage/dist/dev/mp-weixin/api/request.js b/unpackage/dist/dev/mp-weixin/api/request.js new file mode 100644 index 0000000..719d514 --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/api/request.js @@ -0,0 +1,3 @@ +"use strict"; +const testUrl = "http://123.249.108.160:8888/api"; +exports.testUrl = testUrl; diff --git a/unpackage/dist/dev/mp-weixin/app.js b/unpackage/dist/dev/mp-weixin/app.js index a8bf5b9..ce10613 100644 --- a/unpackage/dist/dev/mp-weixin/app.js +++ b/unpackage/dist/dev/mp-weixin/app.js @@ -1,6 +1,7 @@ "use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const common_vendor = require("./common/vendor.js"); +const store_index = require("./store/index.js"); if (!Math) { "./pages/home/home.js"; "./pages/store-home/main/main.js"; @@ -24,6 +25,7 @@ if (!Math) { "./pages/order/paysuccess/paysuccess.js"; "./pages/booking/Simple/Simple.js"; "./pages/booking/bookingpay/bookingpay.js"; + "./pages/order/productOrderDetail/productOrderDetail.js"; } const _sfc_main = {}; function _sfc_render(_ctx, _cache) { @@ -32,6 +34,7 @@ function _sfc_render(_ctx, _cache) { const App = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]); function createApp() { const app = common_vendor.createSSRApp(App); + app.use(store_index.pinia); return { app }; diff --git a/unpackage/dist/dev/mp-weixin/app.json b/unpackage/dist/dev/mp-weixin/app.json index 6b811a5..539b107 100644 --- a/unpackage/dist/dev/mp-weixin/app.json +++ b/unpackage/dist/dev/mp-weixin/app.json @@ -21,7 +21,8 @@ "pages/order/product-waitpay/product-waitpay", "pages/order/paysuccess/paysuccess", "pages/booking/Simple/Simple", - "pages/booking/bookingpay/bookingpay" + "pages/booking/bookingpay/bookingpay", + "pages/order/productOrderDetail/productOrderDetail" ], "window": { "navigationBarTextStyle": "black", diff --git a/unpackage/dist/dev/mp-weixin/assets/zhuye.8d1ff27e.png b/unpackage/dist/dev/mp-weixin/assets/zhuye.8d1ff27e.png deleted file mode 100644 index 343c6d1..0000000 Binary files a/unpackage/dist/dev/mp-weixin/assets/zhuye.8d1ff27e.png and /dev/null differ diff --git a/unpackage/dist/dev/mp-weixin/common/assets.js b/unpackage/dist/dev/mp-weixin/common/assets.js index 880ffdd..c090f07 100644 --- a/unpackage/dist/dev/mp-weixin/common/assets.js +++ b/unpackage/dist/dev/mp-weixin/common/assets.js @@ -4,12 +4,6 @@ const rili = "/assets/rili.7746043b.png"; const xuanchuan = "/assets/xuanchuan.f0fc207c.png"; const shizi = "/assets/shizi.dd0347ec.png"; const you$1 = "/assets/you.60391a00.png"; -const img1 = "/assets/cailiaobao.52f9097b.png"; -const img2 = "/assets/shouchiwu.37cdee46.png"; -const img3 = "/assets/toushi.6558cc23.png"; -const img4 = "/assets/dingzhi.d6614f9f.png"; -const img5 = "/assets/jifenduihuan.a1c23524.png"; -const product_img$1 = "/assets/shangpingtupian.ec8c0440.png"; const add_img = "/assets/tianjia.187834c9.png"; const sousuokuang = "/assets/sousuokuang.6160c4c7.png"; const address = "/assets/address.e91cc3a1.png"; @@ -34,7 +28,6 @@ const show1 = "/assets/show1.6119e6ca.png"; const show2 = "/assets/show2.6ef01c5d.png"; const show3 = "/assets/show3.4b906849.png"; const show4 = "/assets/show4.00c949b6.png"; -const zhuye = "/assets/zhuye.8d1ff27e.png"; const dingwei$1 = "/assets/dingwei.69908177.png"; const selected = "/assets/selected.c24e4f58.png"; const detele = "/assets/delete.377ec392.png"; @@ -68,18 +61,12 @@ exports.detele = detele; exports.dingdan = dingdan; exports.dingwei = dingwei$1; exports.dingwei$1 = dingwei; -exports.img1 = img1; -exports.img2 = img2; -exports.img3 = img3; -exports.img4 = img4; -exports.img5 = img5; exports.kefu = kefu; exports.lianxiren_s = lianxiren_s; exports.product = product$2; exports.product$1 = product$1; exports.product$2 = product; -exports.product_img = product_img$1; -exports.product_img$1 = product_img; +exports.product_img = product_img; exports.pull = pull; exports.qianbao = qianbao; exports.rili = rili; @@ -110,4 +97,3 @@ exports.you = you$1; exports.you$1 = you; exports.you_cheng = you_cheng; exports.you_hei = you_hei; -exports.zhuye = zhuye; diff --git a/unpackage/dist/dev/mp-weixin/common/vendor.js b/unpackage/dist/dev/mp-weixin/common/vendor.js index 255636f..002aa28 100644 --- a/unpackage/dist/dev/mp-weixin/common/vendor.js +++ b/unpackage/dist/dev/mp-weixin/common/vendor.js @@ -47,7 +47,7 @@ const toTypeString = (value) => objectToString.call(value); const toRawType = (value) => { return toTypeString(value).slice(8, -1); }; -const isPlainObject = (val) => toTypeString(val) === "[object Object]"; +const isPlainObject$1 = (val) => toTypeString(val) === "[object Object]"; const isIntegerKey = (key) => isString(key) && key !== "NaN" && key[0] !== "-" && "" + parseInt(key, 10) === key; const isReservedProp = /* @__PURE__ */ makeMap( // the leading comma is intentional so empty string "" is also included @@ -75,8 +75,8 @@ const capitalize = cacheStringFunction((str) => { return str.charAt(0).toUpperCase() + str.slice(1); }); const toHandlerKey = cacheStringFunction((str) => { - const s = str ? `on${capitalize(str)}` : ``; - return s; + const s2 = str ? `on${capitalize(str)}` : ``; + return s2; }); const hasChanged = (value, oldValue) => !Object.is(value, oldValue); const invokeArrayFns$1 = (fns, arg) => { @@ -92,13 +92,63 @@ const def = (obj, key, value) => { }); }; const looseToNumber = (val) => { - const n = parseFloat(val); - return isNaN(n) ? val : n; + const n2 = parseFloat(val); + return isNaN(n2) ? val : n2; }; let _globalThis; const getGlobalThis = () => { return _globalThis || (_globalThis = typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : {}); }; +function normalizeStyle(value) { + if (isArray(value)) { + const res = {}; + for (let i = 0; i < value.length; i++) { + const item = value[i]; + const normalized = isString(item) ? parseStringStyle(item) : normalizeStyle(item); + if (normalized) { + for (const key in normalized) { + res[key] = normalized[key]; + } + } + } + return res; + } else if (isString(value) || isObject(value)) { + return value; + } +} +const listDelimiterRE = /;(?![^(]*\))/g; +const propertyDelimiterRE = /:([^]+)/; +const styleCommentRE = /\/\*[^]*?\*\//g; +function parseStringStyle(cssText) { + const ret = {}; + cssText.replace(styleCommentRE, "").split(listDelimiterRE).forEach((item) => { + if (item) { + const tmp = item.split(propertyDelimiterRE); + tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim()); + } + }); + return ret; +} +function normalizeClass(value) { + let res = ""; + if (isString(value)) { + res = value; + } else if (isArray(value)) { + for (let i = 0; i < value.length; i++) { + const normalized = normalizeClass(value[i]); + if (normalized) { + res += normalized + " "; + } + } + } else if (isObject(value)) { + for (const name in value) { + if (value[name]) { + res += name + " "; + } + } + } + return res.trim(); +} const toDisplayString = (val) => { return isString(val) ? val : val == null ? "" : isArray(val) || isObject(val) && (val.toString === objectToString || !isFunction(val.toString)) ? JSON.stringify(val, replacer, 2) : String(val); }; @@ -121,7 +171,7 @@ const replacer = (_key, val) => { }; } else if (isSymbol(val)) { return stringifySymbol(val); - } else if (isObject(val) && !isArray(val) && !isPlainObject(val)) { + } else if (isObject(val) && !isArray(val) && !isPlainObject$1(val)) { return String(val); } return val; @@ -202,7 +252,7 @@ function getValueByDataPath(obj, path) { } function sortObject(obj) { let sortObj = {}; - if (isPlainObject(obj)) { + if (isPlainObject$1(obj)) { Object.keys(obj).sort().forEach((key) => { const _key = key; sortObj[_key] = obj[_key]; @@ -216,7 +266,7 @@ function stringifyQuery(obj, encodeStr = encode) { let val = obj[key]; if (typeof val === void 0 || val === null) { val = ""; - } else if (isPlainObject(val)) { + } else if (isPlainObject$1(val)) { val = JSON.stringify(val); } return encodeStr(key) + "=" + encodeStr(val); @@ -315,8 +365,8 @@ const E = function() { }; E.prototype = { on: function(name, callback, ctx) { - var e = this.e || (this.e = {}); - (e[name] || (e[name] = [])).push({ + var e2 = this.e || (this.e = {}); + (e2[name] || (e2[name] = [])).push({ fn: callback, ctx }); @@ -342,8 +392,8 @@ E.prototype = { return this; }, off: function(name, callback) { - var e = this.e || (this.e = {}); - var evts = e[name]; + var e2 = this.e || (this.e = {}); + var evts = e2[name]; var liveEvents = []; if (evts && callback) { for (var i = evts.length - 1; i >= 0; i--) { @@ -354,7 +404,7 @@ E.prototype = { } liveEvents = evts; } - liveEvents.length ? e[name] = liveEvents : delete e[name]; + liveEvents.length ? e2[name] = liveEvents : delete e2[name]; return this; } }; @@ -439,7 +489,7 @@ function validateProtocols(name, args, protocol, onFail) { } } function validateProp$1(name, value, prop, isAbsent) { - if (!isPlainObject(prop)) { + if (!isPlainObject$1(prop)) { prop = { type: prop }; } const { type, required, validator } = prop; @@ -529,8 +579,8 @@ function tryCatch(fn) { return function() { try { return fn.apply(fn, arguments); - } catch (e) { - console.error(e); + } catch (e2) { + console.error(e2); } }; } @@ -577,7 +627,7 @@ function normalizeErrMsg(errMsg, name) { return name + errMsg.substring(errMsg.indexOf(":fail")); } function createAsyncApiCallback(name, args = {}, { beforeAll, beforeSuccess } = {}) { - if (!isPlainObject(args)) { + if (!isPlainObject$1(args)) { args = {}; } const { success, fail, complete } = getApiCallbacks(args); @@ -699,7 +749,7 @@ function invokeApi(method, api, options, params) { return api(options, ...params); } function hasCallback(args) { - if (isPlainObject(args) && [API_SUCCESS, API_FAIL, API_COMPLETE].find((cb) => isFunction(args[cb]))) { + if (isPlainObject$1(args) && [API_SUCCESS, API_FAIL, API_COMPLETE].find((cb) => isFunction(args[cb]))) { return true; } return false; @@ -712,14 +762,14 @@ function promisify$1(name, fn) { if (hasCallback(args)) { return wrapperReturnValue(name, invokeApi(name, fn, args, rest)); } - return wrapperReturnValue(name, handlePromise(new Promise((resolve, reject) => { - invokeApi(name, fn, extend(args, { success: resolve, fail: reject }), rest); + return wrapperReturnValue(name, handlePromise(new Promise((resolve2, reject) => { + invokeApi(name, fn, extend(args, { success: resolve2, fail: reject }), rest); }))); }; } function formatApiArgs(args, options) { const params = args[0]; - if (!options || !options.formatArgs || !isPlainObject(options.formatArgs) && isPlainObject(params)) { + if (!options || !options.formatArgs || !isPlainObject$1(options.formatArgs) && isPlainObject$1(params)) { return; } const formatArgs = options.formatArgs; @@ -892,20 +942,20 @@ function dedupeHooks(hooks) { return res; } const addInterceptor = defineSyncApi(API_ADD_INTERCEPTOR, (method, interceptor) => { - if (isString(method) && isPlainObject(interceptor)) { + if (isString(method) && isPlainObject$1(interceptor)) { mergeInterceptorHook(scopedInterceptors[method] || (scopedInterceptors[method] = {}), interceptor); - } else if (isPlainObject(method)) { + } else if (isPlainObject$1(method)) { mergeInterceptorHook(globalInterceptors, method); } }, AddInterceptorProtocol); const removeInterceptor = defineSyncApi(API_REMOVE_INTERCEPTOR, (method, interceptor) => { if (isString(method)) { - if (isPlainObject(interceptor)) { + if (isPlainObject$1(interceptor)) { removeInterceptorHook(scopedInterceptors[method], interceptor); } else { delete scopedInterceptors[method]; } - } else if (isPlainObject(method)) { + } else if (isPlainObject$1(method)) { removeInterceptorHook(globalInterceptors, method); } }, RemoveInterceptorProtocol); @@ -960,7 +1010,7 @@ const $off = defineSyncApi(API_OFF, (name, callback) => { } if (!isArray(name)) name = [name]; - name.forEach((n) => emitter.off(n, callback)); + name.forEach((n2) => emitter.off(n2, callback)); }, OffProtocol); const $emit = defineSyncApi(API_EMIT, (name, ...args) => { emitter.emit(name, ...args); @@ -971,7 +1021,7 @@ let enabled; function normalizePushMessage(message) { try { return JSON.parse(message); - } catch (e) { + } catch (e2) { } return message; } @@ -1011,7 +1061,7 @@ function invokeGetPushCidCallbacks(cid2, errMsg) { getPushCidCallbacks.length = 0; } const API_GET_PUSH_CLIENT_ID = "getPushClientId"; -const getPushClientId = defineAsyncApi(API_GET_PUSH_CLIENT_ID, (_, { resolve, reject }) => { +const getPushClientId = defineAsyncApi(API_GET_PUSH_CLIENT_ID, (_, { resolve: resolve2, reject }) => { Promise.resolve().then(() => { if (typeof enabled === "undefined") { enabled = false; @@ -1020,7 +1070,7 @@ const getPushClientId = defineAsyncApi(API_GET_PUSH_CLIENT_ID, (_, { resolve, re } getPushCidCallbacks.push((cid2, errMsg) => { if (cid2) { - resolve({ cid: cid2 }); + resolve2({ cid: cid2 }); } else { reject(errMsg); } @@ -1085,9 +1135,9 @@ function promisify(name, api) { if (isFunction(options.success) || isFunction(options.fail) || isFunction(options.complete)) { return wrapperReturnValue(name, invokeApi(name, api, options, rest)); } - return wrapperReturnValue(name, handlePromise(new Promise((resolve, reject) => { + return wrapperReturnValue(name, handlePromise(new Promise((resolve2, reject) => { invokeApi(name, api, extend({}, options, { - success: resolve, + success: resolve2, fail: reject }), rest); }))); @@ -1101,7 +1151,7 @@ function initWrapper(protocols2) { }; } function processArgs(methodName, fromArgs, argsOption = {}, returnValue = {}, keepFromArgs = false) { - if (isPlainObject(fromArgs)) { + if (isPlainObject$1(fromArgs)) { const toArgs = keepFromArgs === true ? fromArgs : {}; if (isFunction(argsOption)) { argsOption = argsOption(fromArgs, toArgs) || {}; @@ -1116,7 +1166,7 @@ function initWrapper(protocols2) { console.warn(`微信小程序 ${methodName} 暂不支持 ${key}`); } else if (isString(keyOption)) { toArgs[keyOption] = fromArgs[key]; - } else if (isPlainObject(keyOption)) { + } else if (isPlainObject$1(keyOption)) { toArgs[keyOption.name ? keyOption.name : key] = keyOption.value; } } else if (CALLBACKS.indexOf(key) !== -1) { @@ -2137,6 +2187,9 @@ class EffectScope { } } } +function effectScope(detached) { + return new EffectScope(detached); +} function recordEffectScope(effect2, scope = activeEffectScope) { if (scope && scope.active) { scope.effects.push(effect2); @@ -2145,6 +2198,15 @@ function recordEffectScope(effect2, scope = activeEffectScope) { function getCurrentScope() { return activeEffectScope; } +function onScopeDispose(fn) { + if (activeEffectScope) { + activeEffectScope.cleanups.push(fn); + } else { + warn$2( + `onScopeDispose() is called when there is no active effect scope to be associated with.` + ); + } +} let activeEffect; class ReactiveEffect2 { constructor(fn, trigger2, scheduler, scope) { @@ -2394,6 +2456,10 @@ function trigger(target, type, key, newValue, oldValue, oldTarget) { } resetScheduling(); } +function getDepFromReactive(object, key) { + var _a; + return (_a = targetMap.get(object)) == null ? void 0 : _a.get(key); +} const isNonTrackableKeys = /* @__PURE__ */ makeMap(`__proto__,__v_isRef,__isVue`); const builtInSymbols = new Set( /* @__PURE__ */ Object.getOwnPropertyNames(Symbol).filter((key) => key !== "arguments" && key !== "caller").map((key) => Symbol[key]).filter(isSymbol) @@ -2943,6 +3009,9 @@ function isReadonly(value) { function isShallow(value) { return !!(value && value["__v_isShallow"]); } +function isProxy(value) { + return isReactive(value) || isReadonly(value); +} function toRaw(observed) { const raw = observed && observed["__v_raw"]; return raw ? toRaw(raw) : observed; @@ -3108,6 +3177,59 @@ const shallowUnwrapHandlers = { function proxyRefs(objectWithRefs) { return isReactive(objectWithRefs) ? objectWithRefs : new Proxy(objectWithRefs, shallowUnwrapHandlers); } +function toRefs(object) { + if (!isProxy(object)) { + warn$2(`toRefs() expects a reactive object but received a plain one.`); + } + const ret = isArray(object) ? new Array(object.length) : {}; + for (const key in object) { + ret[key] = propertyToRef(object, key); + } + return ret; +} +class ObjectRefImpl { + constructor(_object, _key, _defaultValue) { + this._object = _object; + this._key = _key; + this._defaultValue = _defaultValue; + this.__v_isRef = true; + } + get value() { + const val = this._object[this._key]; + return val === void 0 ? this._defaultValue : val; + } + set value(newVal) { + this._object[this._key] = newVal; + } + get dep() { + return getDepFromReactive(toRaw(this._object), this._key); + } +} +class GetterRefImpl { + constructor(_getter) { + this._getter = _getter; + this.__v_isRef = true; + this.__v_isReadonly = true; + } + get value() { + return this._getter(); + } +} +function toRef(source, key, defaultValue) { + if (isRef(source)) { + return source; + } else if (isFunction(source)) { + return new GetterRefImpl(source); + } else if (isObject(source) && arguments.length > 1) { + return propertyToRef(source, key, defaultValue); + } else { + return ref(source); + } +} +function propertyToRef(source, key, defaultValue) { + const val = source[key]; + return isRef(val) ? val : new ObjectRefImpl(source, key, defaultValue); +} const stack = []; function pushWarningContext(vnode) { stack.push(vnode); @@ -3737,6 +3859,47 @@ function setCurrentRenderingInstance(instance) { instance && instance.type.__scopeId || null; return prev; } +const COMPONENTS = "components"; +function resolveComponent(name, maybeSelfReference) { + return resolveAsset(COMPONENTS, name, true, maybeSelfReference) || name; +} +function resolveAsset(type, name, warnMissing = true, maybeSelfReference = false) { + const instance = currentRenderingInstance || currentInstance; + if (instance) { + const Component2 = instance.type; + if (type === COMPONENTS) { + const selfName = getComponentName( + Component2, + false + ); + if (selfName && (selfName === name || selfName === camelize(name) || selfName === capitalize(camelize(name)))) { + return Component2; + } + } + const res = ( + // local registration + // check instance[type] first which is resolved for options API + resolve(instance[type] || Component2[type], name) || // global registration + resolve(instance.appContext[type], name) + ); + if (!res && maybeSelfReference) { + return Component2; + } + if (warnMissing && !res) { + const extra = type === COMPONENTS ? ` +If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.` : ``; + warn$1(`Failed to resolve ${type.slice(0, -1)}: ${name}${extra}`); + } + return res; + } else { + warn$1( + `resolve${capitalize(type.slice(0, -1))} can only be used in render() or setup().` + ); + } +} +function resolve(registry, name) { + return registry && (registry[name] || registry[camelize(name)] || registry[capitalize(camelize(name))]); +} const INITIAL_WATCHER_VALUE = {}; function watch(source, cb, options) { if (!isFunction(cb)) { @@ -3962,7 +4125,7 @@ function traverse(value, depth, currentDepth = 0, seen) { value.forEach((v) => { traverse(v, depth, currentDepth, seen); }); - } else if (isPlainObject(value)) { + } else if (isPlainObject$1(value)) { for (const key in value) { traverse(value[key], depth, currentDepth, seen); } @@ -4140,6 +4303,9 @@ function inject(key, defaultValue, treatDefaultAsFactory = false) { warn$1(`inject() can only be used inside setup() or functional components.`); } } +function hasInjectionContext() { + return !!(currentInstance || currentRenderingInstance || currentApp); +} /*! #__NO_SIDE_EFFECTS__ */ // @__NO_SIDE_EFFECTS__ function defineComponent(options, extraOptions) { @@ -4222,21 +4388,21 @@ function injectHook(type, hook, target = currentInstance, prepend = false) { ); } } -const createHook = (lifecycle) => (hook, target = currentInstance) => ( +const createHook$1 = (lifecycle) => (hook, target = currentInstance) => ( // post-create lifecycle registrations are noops during SSR (except for serverPrefetch) (!isInSSRComponentSetup || lifecycle === "sp") && injectHook(lifecycle, (...args) => hook(...args), target) ); -const onBeforeMount = createHook("bm"); -const onMounted = createHook("m"); -const onBeforeUpdate = createHook("bu"); -const onUpdated = createHook("u"); -const onBeforeUnmount = createHook("bum"); -const onUnmounted = createHook("um"); -const onServerPrefetch = createHook("sp"); -const onRenderTriggered = createHook( +const onBeforeMount = createHook$1("bm"); +const onMounted = createHook$1("m"); +const onBeforeUpdate = createHook$1("bu"); +const onUpdated = createHook$1("u"); +const onBeforeUnmount = createHook$1("bum"); +const onUnmounted = createHook$1("um"); +const onServerPrefetch = createHook$1("sp"); +const onRenderTriggered = createHook$1( "rtg" ); -const onRenderTracked = createHook( +const onRenderTracked = createHook$1( "rtc" ); function onErrorCaptured(hook, target = currentInstance) { @@ -5353,6 +5519,12 @@ const Static = Symbol.for("v-stc"); function isVNode(value) { return value ? value.__v_isVNode === true : false; } +const InternalObjectKey = `__vInternal`; +function guardReactiveProps(props) { + if (!props) + return null; + return isProxy(props) || InternalObjectKey in props ? extend({}, props) : props; +} const emptyAppContext = createAppContext(); let uid = 0; function createComponentInstance(vnode, parent, suspense) { @@ -6421,7 +6593,7 @@ function initHooks$1(options, instance, publicThis) { function applyOptions$2(options, instance, publicThis) { initHooks$1(options, instance, publicThis); } -function set(target, key, val) { +function set$2(target, key, val) { return target[key] = val; } function $callMethod(method, ...args) { @@ -6528,7 +6700,7 @@ function initApp(app) { uniIdMixin(globalProperties); } { - globalProperties.$set = set; + globalProperties.$set = set$2; globalProperties.$applyOptions = applyOptions$2; globalProperties.$callMethod = $callMethod; } @@ -6537,6 +6709,11 @@ function initApp(app) { } } const propsCaches = /* @__PURE__ */ Object.create(null); +function renderProps(props) { + const { uid: uid2, __counter } = getCurrentInstance(); + const propsId = (propsCaches[uid2] || (propsCaches[uid2] = [])).push(guardReactiveProps(props)) - 1; + return uid2 + "," + propsId + "," + __counter; +} function pruneComponentPropsCache(uid2) { delete propsCaches[uid2]; } @@ -6646,10 +6823,10 @@ function patchMPEvent(event) { event.detail = typeof event.detail === "object" ? event.detail : {}; event.detail.markerId = event.markerId; } - if (isPlainObject(event.detail) && hasOwn(event.detail, "checked") && !hasOwn(event.detail, "value")) { + if (isPlainObject$1(event.detail) && hasOwn(event.detail, "checked") && !hasOwn(event.detail, "value")) { event.detail.value = event.detail.checked; } - if (isPlainObject(event.detail)) { + if (isPlainObject$1(event.detail)) { event.target = extend({}, event.target, event.detail); } } @@ -6698,9 +6875,34 @@ function vFor(source, renderItem) { } return ret; } +function stringifyStyle(value) { + if (isString(value)) { + return value; + } + return stringify(normalizeStyle(value)); +} +function stringify(styles) { + let ret = ""; + if (!styles || isString(styles)) { + return ret; + } + for (const key in styles) { + ret += `${key.startsWith(`--`) ? key : hyphenate(key)}:${styles[key]};`; + } + return ret; +} +function setRef(ref2, id, opts = {}) { + const { $templateRefs } = getCurrentInstance(); + $templateRefs.push({ i: id, r: ref2, k: opts.k, f: opts.f }); +} const o = (value, key) => vOn(value, key); const f = (source, renderItem) => vFor(source, renderItem); +const s = (value) => stringifyStyle(value); +const e = (target, ...sources) => extend(target, ...sources); +const n = (value) => normalizeClass(value); const t = (val) => toDisplayString(val); +const p = (props) => renderProps(props); +const sr = (ref2, id, opts) => setRef(ref2, id, opts); function createApp$1(rootComponent, rootProps = null) { rootComponent && (rootComponent.mpType = "app"); return createVueApp(rootComponent, rootProps).use(plugin); @@ -7159,10 +7361,10 @@ function initPageProps({ properties }, rawProps) { value: "" }; }); - } else if (isPlainObject(rawProps)) { + } else if (isPlainObject$1(rawProps)) { Object.keys(rawProps).forEach((key) => { const opts = rawProps[key]; - if (isPlainObject(opts)) { + if (isPlainObject$1(opts)) { let value = opts.default; if (isFunction(value)) { value = value(); @@ -7186,7 +7388,7 @@ function findPropsData(properties, isPage2) { } function findPagePropsData(properties) { const propsData = {}; - if (isPlainObject(properties)) { + if (isPlainObject$1(properties)) { Object.keys(properties).forEach((name) => { if (builtInProps.indexOf(name) === -1) { propsData[name] = properties[name]; @@ -7532,12 +7734,637 @@ const createSubpackageApp = initCreateSubpackageApp(); wx.createPluginApp = global.createPluginApp = createPluginApp; wx.createSubpackageApp = global.createSubpackageApp = createSubpackageApp; } +var isVue2 = false; +function set(target, key, val) { + if (Array.isArray(target)) { + target.length = Math.max(target.length, key); + target.splice(key, 1, val); + return val; + } + target[key] = val; + return val; +} +function del(target, key) { + if (Array.isArray(target)) { + target.splice(key, 1); + return; + } + delete target[key]; +} +/*! + * pinia v2.1.7 + * (c) 2023 Eduardo San Martin Morote + * @license MIT + */ +let activePinia; +const setActivePinia = (pinia) => activePinia = pinia; +const piniaSymbol = Symbol("pinia"); +function isPlainObject(o2) { + return o2 && typeof o2 === "object" && Object.prototype.toString.call(o2) === "[object Object]" && typeof o2.toJSON !== "function"; +} +var MutationType; +(function(MutationType2) { + MutationType2["direct"] = "direct"; + MutationType2["patchObject"] = "patch object"; + MutationType2["patchFunction"] = "patch function"; +})(MutationType || (MutationType = {})); +const IS_CLIENT = typeof window !== "undefined"; +const USE_DEVTOOLS = IS_CLIENT; +const componentStateTypes = []; +const getStoreType = (id) => "🍍 " + id; +function addStoreToDevtools(app, store) { + if (!componentStateTypes.includes(getStoreType(store.$id))) { + componentStateTypes.push(getStoreType(store.$id)); + } +} +function patchActionForGrouping(store, actionNames, wrapWithProxy) { + const actions = actionNames.reduce((storeActions, actionName) => { + storeActions[actionName] = toRaw(store)[actionName]; + return storeActions; + }, {}); + for (const actionName in actions) { + store[actionName] = function() { + const trackedStore = wrapWithProxy ? new Proxy(store, { + get(...args) { + return Reflect.get(...args); + }, + set(...args) { + return Reflect.set(...args); + } + }) : store; + const retValue = actions[actionName].apply(trackedStore, arguments); + return retValue; + }; + } +} +function devtoolsPlugin({ app, store, options }) { + if (store.$id.startsWith("__hot:")) { + return; + } + store._isOptionsAPI = !!options.state; + patchActionForGrouping(store, Object.keys(options.actions), store._isOptionsAPI); + const originalHotUpdate = store._hotUpdate; + toRaw(store)._hotUpdate = function(newStore) { + originalHotUpdate.apply(this, arguments); + patchActionForGrouping(store, Object.keys(newStore._hmrPayload.actions), !!store._isOptionsAPI); + }; + addStoreToDevtools( + app, + // FIXME: is there a way to allow the assignment from Store to StoreGeneric? + store + ); +} +function createPinia() { + const scope = effectScope(true); + const state = scope.run(() => ref({})); + let _p = []; + let toBeInstalled = []; + const pinia = markRaw({ + install(app) { + setActivePinia(pinia); + { + pinia._a = app; + app.provide(piniaSymbol, pinia); + app.config.globalProperties.$pinia = pinia; + toBeInstalled.forEach((plugin2) => _p.push(plugin2)); + toBeInstalled = []; + } + }, + use(plugin2) { + if (!this._a && !isVue2) { + toBeInstalled.push(plugin2); + } else { + _p.push(plugin2); + } + return this; + }, + _p, + // it's actually undefined here + // @ts-expect-error + _a: null, + _e: scope, + _s: /* @__PURE__ */ new Map(), + state + }); + if (USE_DEVTOOLS && typeof Proxy !== "undefined") { + pinia.use(devtoolsPlugin); + } + return pinia; +} +function patchObject(newState, oldState) { + for (const key in oldState) { + const subPatch = oldState[key]; + if (!(key in newState)) { + continue; + } + const targetValue = newState[key]; + if (isPlainObject(targetValue) && isPlainObject(subPatch) && !isRef(subPatch) && !isReactive(subPatch)) { + newState[key] = patchObject(targetValue, subPatch); + } else { + { + newState[key] = subPatch; + } + } + } + return newState; +} +const noop = () => { +}; +function addSubscription(subscriptions, callback, detached, onCleanup = noop) { + subscriptions.push(callback); + const removeSubscription = () => { + const idx = subscriptions.indexOf(callback); + if (idx > -1) { + subscriptions.splice(idx, 1); + onCleanup(); + } + }; + if (!detached && getCurrentScope()) { + onScopeDispose(removeSubscription); + } + return removeSubscription; +} +function triggerSubscriptions(subscriptions, ...args) { + subscriptions.slice().forEach((callback) => { + callback(...args); + }); +} +const fallbackRunWithContext = (fn) => fn(); +function mergeReactiveObjects(target, patchToApply) { + if (target instanceof Map && patchToApply instanceof Map) { + patchToApply.forEach((value, key) => target.set(key, value)); + } + if (target instanceof Set && patchToApply instanceof Set) { + patchToApply.forEach(target.add, target); + } + for (const key in patchToApply) { + if (!patchToApply.hasOwnProperty(key)) + continue; + const subPatch = patchToApply[key]; + const targetValue = target[key]; + if (isPlainObject(targetValue) && isPlainObject(subPatch) && target.hasOwnProperty(key) && !isRef(subPatch) && !isReactive(subPatch)) { + target[key] = mergeReactiveObjects(targetValue, subPatch); + } else { + target[key] = subPatch; + } + } + return target; +} +const skipHydrateSymbol = Symbol("pinia:skipHydration"); +function shouldHydrate(obj) { + return !isPlainObject(obj) || !obj.hasOwnProperty(skipHydrateSymbol); +} +const { assign } = Object; +function isComputed(o2) { + return !!(isRef(o2) && o2.effect); +} +function createOptionsStore(id, options, pinia, hot) { + const { state, actions, getters } = options; + const initialState = pinia.state.value[id]; + let store; + function setup() { + if (!initialState && !hot) { + { + pinia.state.value[id] = state ? state() : {}; + } + } + const localState = hot ? ( + // use ref() to unwrap refs inside state TODO: check if this is still necessary + toRefs(ref(state ? state() : {}).value) + ) : toRefs(pinia.state.value[id]); + return assign(localState, actions, Object.keys(getters || {}).reduce((computedGetters, name) => { + if (name in localState) { + console.warn(`[🍍]: A getter cannot have the same name as another state property. Rename one of them. Found with "${name}" in store "${id}".`); + } + computedGetters[name] = markRaw(computed(() => { + setActivePinia(pinia); + const store2 = pinia._s.get(id); + return getters[name].call(store2, store2); + })); + return computedGetters; + }, {})); + } + store = createSetupStore(id, setup, options, pinia, hot, true); + return store; +} +function createSetupStore($id, setup, options = {}, pinia, hot, isOptionsStore) { + let scope; + const optionsForPlugin = assign({ actions: {} }, options); + if (!pinia._e.active) { + throw new Error("Pinia destroyed"); + } + const $subscribeOptions = { + deep: true + // flush: 'post', + }; + { + $subscribeOptions.onTrigger = (event) => { + if (isListening) { + debuggerEvents = event; + } else if (isListening == false && !store._hotUpdating) { + if (Array.isArray(debuggerEvents)) { + debuggerEvents.push(event); + } else { + console.error("🍍 debuggerEvents should be an array. This is most likely an internal Pinia bug."); + } + } + }; + } + let isListening; + let isSyncListening; + let subscriptions = []; + let actionSubscriptions = []; + let debuggerEvents; + const initialState = pinia.state.value[$id]; + if (!isOptionsStore && !initialState && !hot) { + { + pinia.state.value[$id] = {}; + } + } + const hotState = ref({}); + let activeListener; + function $patch(partialStateOrMutator) { + let subscriptionMutation; + isListening = isSyncListening = false; + { + debuggerEvents = []; + } + if (typeof partialStateOrMutator === "function") { + partialStateOrMutator(pinia.state.value[$id]); + subscriptionMutation = { + type: MutationType.patchFunction, + storeId: $id, + events: debuggerEvents + }; + } else { + mergeReactiveObjects(pinia.state.value[$id], partialStateOrMutator); + subscriptionMutation = { + type: MutationType.patchObject, + payload: partialStateOrMutator, + storeId: $id, + events: debuggerEvents + }; + } + const myListenerId = activeListener = Symbol(); + nextTick$1().then(() => { + if (activeListener === myListenerId) { + isListening = true; + } + }); + isSyncListening = true; + triggerSubscriptions(subscriptions, subscriptionMutation, pinia.state.value[$id]); + } + const $reset = isOptionsStore ? function $reset2() { + const { state } = options; + const newState = state ? state() : {}; + this.$patch(($state) => { + assign($state, newState); + }); + } : ( + /* istanbul ignore next */ + () => { + throw new Error(`🍍: Store "${$id}" is built using the setup syntax and does not implement $reset().`); + } + ); + function $dispose() { + scope.stop(); + subscriptions = []; + actionSubscriptions = []; + pinia._s.delete($id); + } + function wrapAction(name, action) { + return function() { + setActivePinia(pinia); + const args = Array.from(arguments); + const afterCallbackList = []; + const onErrorCallbackList = []; + function after(callback) { + afterCallbackList.push(callback); + } + function onError(callback) { + onErrorCallbackList.push(callback); + } + triggerSubscriptions(actionSubscriptions, { + args, + name, + store, + after, + onError + }); + let ret; + try { + ret = action.apply(this && this.$id === $id ? this : store, args); + } catch (error) { + triggerSubscriptions(onErrorCallbackList, error); + throw error; + } + if (ret instanceof Promise) { + return ret.then((value) => { + triggerSubscriptions(afterCallbackList, value); + return value; + }).catch((error) => { + triggerSubscriptions(onErrorCallbackList, error); + return Promise.reject(error); + }); + } + triggerSubscriptions(afterCallbackList, ret); + return ret; + }; + } + const _hmrPayload = /* @__PURE__ */ markRaw({ + actions: {}, + getters: {}, + state: [], + hotState + }); + const partialStore = { + _p: pinia, + // _s: scope, + $id, + $onAction: addSubscription.bind(null, actionSubscriptions), + $patch, + $reset, + $subscribe(callback, options2 = {}) { + const removeSubscription = addSubscription(subscriptions, callback, options2.detached, () => stopWatcher()); + const stopWatcher = scope.run(() => watch(() => pinia.state.value[$id], (state) => { + if (options2.flush === "sync" ? isSyncListening : isListening) { + callback({ + storeId: $id, + type: MutationType.direct, + events: debuggerEvents + }, state); + } + }, assign({}, $subscribeOptions, options2))); + return removeSubscription; + }, + $dispose + }; + const store = reactive(assign( + { + _hmrPayload, + _customProperties: markRaw(/* @__PURE__ */ new Set()) + // devtools custom properties + }, + partialStore + // must be added later + // setupStore + )); + pinia._s.set($id, store); + const runWithContext = pinia._a && pinia._a.runWithContext || fallbackRunWithContext; + const setupStore = runWithContext(() => pinia._e.run(() => (scope = effectScope()).run(setup))); + for (const key in setupStore) { + const prop = setupStore[key]; + if (isRef(prop) && !isComputed(prop) || isReactive(prop)) { + if (hot) { + set(hotState.value, key, toRef(setupStore, key)); + } else if (!isOptionsStore) { + if (initialState && shouldHydrate(prop)) { + if (isRef(prop)) { + prop.value = initialState[key]; + } else { + mergeReactiveObjects(prop, initialState[key]); + } + } + { + pinia.state.value[$id][key] = prop; + } + } + { + _hmrPayload.state.push(key); + } + } else if (typeof prop === "function") { + const actionValue = hot ? prop : wrapAction(key, prop); + { + setupStore[key] = actionValue; + } + { + _hmrPayload.actions[key] = prop; + } + optionsForPlugin.actions[key] = prop; + } else { + if (isComputed(prop)) { + _hmrPayload.getters[key] = isOptionsStore ? ( + // @ts-expect-error + options.getters[key] + ) : prop; + if (IS_CLIENT) { + const getters = setupStore._getters || // @ts-expect-error: same + (setupStore._getters = markRaw([])); + getters.push(key); + } + } + } + } + { + assign(store, setupStore); + assign(toRaw(store), setupStore); + } + Object.defineProperty(store, "$state", { + get: () => hot ? hotState.value : pinia.state.value[$id], + set: (state) => { + if (hot) { + throw new Error("cannot set hotState"); + } + $patch(($state) => { + assign($state, state); + }); + } + }); + { + store._hotUpdate = markRaw((newStore) => { + store._hotUpdating = true; + newStore._hmrPayload.state.forEach((stateKey) => { + if (stateKey in store.$state) { + const newStateTarget = newStore.$state[stateKey]; + const oldStateSource = store.$state[stateKey]; + if (typeof newStateTarget === "object" && isPlainObject(newStateTarget) && isPlainObject(oldStateSource)) { + patchObject(newStateTarget, oldStateSource); + } else { + newStore.$state[stateKey] = oldStateSource; + } + } + set(store, stateKey, toRef(newStore.$state, stateKey)); + }); + Object.keys(store.$state).forEach((stateKey) => { + if (!(stateKey in newStore.$state)) { + del(store, stateKey); + } + }); + isListening = false; + isSyncListening = false; + pinia.state.value[$id] = toRef(newStore._hmrPayload, "hotState"); + isSyncListening = true; + nextTick$1().then(() => { + isListening = true; + }); + for (const actionName in newStore._hmrPayload.actions) { + const action = newStore[actionName]; + set(store, actionName, wrapAction(actionName, action)); + } + for (const getterName in newStore._hmrPayload.getters) { + const getter = newStore._hmrPayload.getters[getterName]; + const getterValue = isOptionsStore ? ( + // special handling of options api + computed(() => { + setActivePinia(pinia); + return getter.call(store, store); + }) + ) : getter; + set(store, getterName, getterValue); + } + Object.keys(store._hmrPayload.getters).forEach((key) => { + if (!(key in newStore._hmrPayload.getters)) { + del(store, key); + } + }); + Object.keys(store._hmrPayload.actions).forEach((key) => { + if (!(key in newStore._hmrPayload.actions)) { + del(store, key); + } + }); + store._hmrPayload = newStore._hmrPayload; + store._getters = newStore._getters; + store._hotUpdating = false; + }); + } + if (USE_DEVTOOLS) { + const nonEnumerable = { + writable: true, + configurable: true, + // avoid warning on devtools trying to display this property + enumerable: false + }; + ["_p", "_hmrPayload", "_getters", "_customProperties"].forEach((p2) => { + Object.defineProperty(store, p2, assign({ value: store[p2] }, nonEnumerable)); + }); + } + pinia._p.forEach((extender) => { + if (USE_DEVTOOLS) { + const extensions = scope.run(() => extender({ + store, + app: pinia._a, + pinia, + options: optionsForPlugin + })); + Object.keys(extensions || {}).forEach((key) => store._customProperties.add(key)); + assign(store, extensions); + } else { + assign(store, scope.run(() => extender({ + store, + app: pinia._a, + pinia, + options: optionsForPlugin + }))); + } + }); + if (store.$state && typeof store.$state === "object" && typeof store.$state.constructor === "function" && !store.$state.constructor.toString().includes("[native code]")) { + console.warn(`[🍍]: The "state" must be a plain object. It cannot be + state: () => new MyClass() +Found in store "${store.$id}".`); + } + if (initialState && isOptionsStore && options.hydrate) { + options.hydrate(store.$state, initialState); + } + isListening = true; + isSyncListening = true; + return store; +} +function defineStore(idOrOptions, setup, setupOptions) { + let id; + let options; + const isSetupStore = typeof setup === "function"; + if (typeof idOrOptions === "string") { + id = idOrOptions; + options = isSetupStore ? setupOptions : setup; + } else { + options = idOrOptions; + id = idOrOptions.id; + if (typeof id !== "string") { + throw new Error(`[🍍]: "defineStore()" must be passed a store id as its first argument.`); + } + } + function useStore(pinia, hot) { + const hasContext = hasInjectionContext(); + pinia = // in test mode, ignore the argument provided as we can always retrieve a + // pinia instance with getActivePinia() + pinia || (hasContext ? inject(piniaSymbol, null) : null); + if (pinia) + setActivePinia(pinia); + if (!activePinia) { + throw new Error(`[🍍]: "getActivePinia()" was called but there was no active Pinia. Are you trying to use a store before calling "app.use(pinia)"? +See https://pinia.vuejs.org/core-concepts/outside-component-usage.html for help. +This will fail in production.`); + } + pinia = activePinia; + if (!pinia._s.has(id)) { + if (isSetupStore) { + createSetupStore(id, setup, options, pinia); + } else { + createOptionsStore(id, options, pinia); + } + { + useStore._pinia = pinia; + } + } + const store = pinia._s.get(id); + if (hot) { + const hotId = "__hot:" + id; + const newStore = isSetupStore ? createSetupStore(hotId, setup, options, pinia, true) : createOptionsStore(hotId, assign({}, options), pinia, true); + hot._hotUpdate(newStore); + delete pinia.state.value[hotId]; + pinia._s.delete(hotId); + } + if (IS_CLIENT) { + const currentInstance2 = getCurrentInstance(); + if (currentInstance2 && currentInstance2.proxy && // avoid adding stores that are just built for hot module replacement + !hot) { + const vm = currentInstance2.proxy; + const cache = "_pStores" in vm ? vm._pStores : vm._pStores = {}; + cache[id] = store; + } + } + return store; + } + useStore.$id = id; + return useStore; +} +const createHook = (lifecycle) => (hook, target = getCurrentInstance()) => { + !isInSSRComponentSetup && injectHook(lifecycle, hook, target); +}; +const onLoad = /* @__PURE__ */ createHook(ON_LOAD); +function mitt(n2) { + return { all: n2 = n2 || /* @__PURE__ */ new Map(), on: function(t2, e2) { + var i = n2.get(t2); + i ? i.push(e2) : n2.set(t2, [e2]); + }, off: function(t2, e2) { + var i = n2.get(t2); + i && (e2 ? i.splice(i.indexOf(e2) >>> 0, 1) : n2.set(t2, [])); + }, emit: function(t2, e2) { + var i = n2.get(t2); + i && i.slice().map(function(n3) { + n3(e2); + }), (i = n2.get("*")) && i.slice().map(function(n3) { + n3(t2, e2); + }); + } }; +} exports._export_sfc = _export_sfc; +exports.createPinia = createPinia; exports.createSSRApp = createSSRApp; exports.defineComponent = defineComponent; +exports.defineStore = defineStore; +exports.e = e; exports.f = f; exports.index = index; +exports.mitt = mitt; +exports.n = n; exports.o = o; +exports.onLoad = onLoad; +exports.onMounted = onMounted; +exports.p = p; exports.ref = ref; +exports.resolveComponent = resolveComponent; +exports.s = s; +exports.sr = sr; exports.t = t; exports.unref = unref; diff --git a/unpackage/dist/dev/mp-weixin/pages/Shopping-cart/productmain/productmain.js b/unpackage/dist/dev/mp-weixin/pages/Shopping-cart/productmain/productmain.js index 5c5bd4a..2b3d8d4 100644 --- a/unpackage/dist/dev/mp-weixin/pages/Shopping-cart/productmain/productmain.js +++ b/unpackage/dist/dev/mp-weixin/pages/Shopping-cart/productmain/productmain.js @@ -12,7 +12,7 @@ const _sfc_main = { "selected_style": "紫色", "product_num": 1, "product_price": 138, - "product_img": common_assets.product_img$1, + "product_img": common_assets.product_img, "pull_img": common_assets.pull, "select_img": common_assets.choose, "rmb_img": common_assets.rmb, @@ -25,7 +25,7 @@ const _sfc_main = { "selected_style": "紫色", "product_num": 1, "product_price": 138, - "product_img": common_assets.product_img$1, + "product_img": common_assets.product_img, "pull_img": common_assets.pull, "select_img": common_assets.choose, "rmb_img": common_assets.rmb, @@ -38,7 +38,7 @@ const _sfc_main = { "selected_style": "紫色", "product_num": 1, "product_price": 138, - "product_img": common_assets.product_img$1, + "product_img": common_assets.product_img, "pull_img": common_assets.pull, "select_img": common_assets.choose, "rmb_img": common_assets.rmb, @@ -51,7 +51,7 @@ const _sfc_main = { "selected_style": "紫色", "product_num": 1, "product_price": 138, - "product_img": common_assets.product_img$1, + "product_img": common_assets.product_img, "pull_img": common_assets.pull, "select_img": common_assets.choose, "rmb_img": common_assets.rmb, @@ -64,7 +64,7 @@ const _sfc_main = { "selected_style": "紫色", "product_num": 1, "product_price": 138, - "product_img": common_assets.product_img$1, + "product_img": common_assets.product_img, "pull_img": common_assets.pull, "select_img": common_assets.choose, "rmb_img": common_assets.rmb, @@ -77,7 +77,7 @@ const _sfc_main = { "selected_style": "紫色", "product_num": 1, "product_price": 138, - "product_img": common_assets.product_img$1, + "product_img": common_assets.product_img, "pull_img": common_assets.pull, "select_img": common_assets.choose, "rmb_img": common_assets.rmb, diff --git a/unpackage/dist/dev/mp-weixin/pages/mine/main/main.js b/unpackage/dist/dev/mp-weixin/pages/mine/main/main.js index 55a4122..b3bc411 100644 --- a/unpackage/dist/dev/mp-weixin/pages/mine/main/main.js +++ b/unpackage/dist/dev/mp-weixin/pages/mine/main/main.js @@ -1,9 +1,11 @@ "use strict"; const common_vendor = require("../../../common/vendor.js"); +const store_userStore = require("../../../store/userStore.js"); const common_assets = require("../../../common/assets.js"); const _sfc_main = { __name: "main", setup(__props) { + store_userStore.userStore(); return (_ctx, _cache) => { return { a: common_vendor.unref(common_assets.avator), diff --git a/unpackage/dist/dev/mp-weixin/pages/order/component/addressComponent.js b/unpackage/dist/dev/mp-weixin/pages/order/component/addressComponent.js new file mode 100644 index 0000000..84a7d08 --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/pages/order/component/addressComponent.js @@ -0,0 +1,53 @@ +"use strict"; +const common_vendor = require("../../../common/vendor.js"); +const pages_utils_emitter = require("../../utils/emitter.js"); +const api_request = require("../../../api/request.js"); +const store_userStore = require("../../../store/userStore.js"); +const _sfc_main = { + __name: "addressComponent", + setup(__props) { + common_vendor.ref([null, null]); + const addressList = common_vendor.ref([]); + const store = store_userStore.userStore(); + common_vendor.onMounted(() => { + getAddressList(); + }); + const getAddressList = async () => { + const res = await common_vendor.index.request({ + url: api_request.testUrl + "/address/list", + method: "POST", + data: { + id: store.userInfo.id + } + }); + addressList.value = res.data.data; + }; + const close = () => { + pages_utils_emitter.emitter.emit("close"); + }; + const radioChange = (event) => { + const index = event.detail.value; + const temp = addressList.value[index]; + pages_utils_emitter.emitter.emit("addressInfo", temp); + pages_utils_emitter.emitter.emit("close"); + }; + return (_ctx, _cache) => { + return { + a: common_vendor.o(close), + b: common_vendor.f(addressList.value, (item, index, i0) => { + return { + a: index, + b: index === _ctx.current, + c: common_vendor.t(item.name), + d: common_vendor.t(item.phone), + e: common_vendor.t(item.detailAddress), + f: index + }; + }), + c: common_vendor.o(radioChange) + }; + }; + } +}; +const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-c20b9e4d"]]); +wx.createComponent(Component); diff --git a/unpackage/dist/dev/mp-weixin/pages/order/component/addressComponent.json b/unpackage/dist/dev/mp-weixin/pages/order/component/addressComponent.json new file mode 100644 index 0000000..e8cfaaf --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/pages/order/component/addressComponent.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} +} \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/pages/order/component/addressComponent.wxml b/unpackage/dist/dev/mp-weixin/pages/order/component/addressComponent.wxml new file mode 100644 index 0000000..2d20294 --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/pages/order/component/addressComponent.wxml @@ -0,0 +1 @@ +收货地址{{item.c}}{{item.d}}{{item.e}}添加新地址 \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/pages/order/component/addressComponent.wxss b/unpackage/dist/dev/mp-weixin/pages/order/component/addressComponent.wxss new file mode 100644 index 0000000..e89c0a8 --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/pages/order/component/addressComponent.wxss @@ -0,0 +1,491 @@ +/* 水平间距 */ +/* 水平间距 */ +/************************************************************ +** 请将全局样式拷贝到项目的全局 CSS 文件或者当前页面的顶部 ** +** 否则页面将无法正常显示 ** +************************************************************/ +html.data-v-c20b9e4d { + font-size: 16px; +} +body.data-v-c20b9e4d { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', + 'Droid Sans', 'Helvetica Neue', 'Microsoft Yahei', sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +view.data-v-c20b9e4d, +image.data-v-c20b9e4d, +text.data-v-c20b9e4d { + box-sizing: border-box; + flex-shrink: 0; +} +#app.data-v-c20b9e4d { + width: 100vw; + height: 100vh; +} +.flex-row.data-v-c20b9e4d { + display: flex; + flex-direction: row; +} +.flex-col.data-v-c20b9e4d { + display: flex; + flex-direction: column; +} +.justify-start.data-v-c20b9e4d { + justify-content: flex-start; +} +.justify-end.data-v-c20b9e4d { + justify-content: flex-end; +} +.justify-center.data-v-c20b9e4d { + justify-content: center; +} +.justify-between.data-v-c20b9e4d { + justify-content: space-between; +} +.justify-around.data-v-c20b9e4d { + justify-content: space-around; +} +.justify-evenly.data-v-c20b9e4d { + justify-content: space-evenly; +} +.items-start.data-v-c20b9e4d { + align-items: flex-start; +} +.items-end.data-v-c20b9e4d { + align-items: flex-end; +} +.items-center.data-v-c20b9e4d { + align-items: center; +} +.items-baseline.data-v-c20b9e4d { + align-items: baseline; +} +.items-stretch.data-v-c20b9e4d { + align-items: stretch; +} +.self-start.data-v-c20b9e4d { + align-self: flex-start; +} +.self-end.data-v-c20b9e4d { + align-self: flex-end; +} +.self-center.data-v-c20b9e4d { + align-self: center; +} +.self-baseline.data-v-c20b9e4d { + align-self: baseline; +} +.self-stretch.data-v-c20b9e4d { + align-self: stretch; +} +.flex-1.data-v-c20b9e4d { + flex: 1 1 0%; +} +.flex-auto.data-v-c20b9e4d { + flex: 1 1 auto; +} +.grow.data-v-c20b9e4d { + flex-grow: 1; +} +.grow-0.data-v-c20b9e4d { + flex-grow: 0; +} +.shrink.data-v-c20b9e4d { + flex-shrink: 1; +} +.shrink-0.data-v-c20b9e4d { + flex-shrink: 0; +} +.relative.data-v-c20b9e4d { + position: relative; +} +.ml-2.data-v-c20b9e4d { + margin-left: 3.75rpx; +} +.mt-2.data-v-c20b9e4d { + margin-top: 3.75rpx; +} +.ml-4.data-v-c20b9e4d { + margin-left: 7.5rpx; +} +.mt-4.data-v-c20b9e4d { + margin-top: 7.5rpx; +} +.ml-6.data-v-c20b9e4d { + margin-left: 11.25rpx; +} +.mt-6.data-v-c20b9e4d { + margin-top: 11.25rpx; +} +.ml-8.data-v-c20b9e4d { + margin-left: 15rpx; +} +.mt-8.data-v-c20b9e4d { + margin-top: 15rpx; +} +.ml-10.data-v-c20b9e4d { + margin-left: 18.75rpx; +} +.mt-10.data-v-c20b9e4d { + margin-top: 18.75rpx; +} +.ml-12.data-v-c20b9e4d { + margin-left: 22.5rpx; +} +.mt-12.data-v-c20b9e4d { + margin-top: 22.5rpx; +} +.ml-14.data-v-c20b9e4d { + margin-left: 26.25rpx; +} +.mt-14.data-v-c20b9e4d { + margin-top: 26.25rpx; +} +.ml-16.data-v-c20b9e4d { + margin-left: 30rpx; +} +.mt-16.data-v-c20b9e4d { + margin-top: 30rpx; +} +.ml-18.data-v-c20b9e4d { + margin-left: 33.75rpx; +} +.mt-18.data-v-c20b9e4d { + margin-top: 33.75rpx; +} +.ml-20.data-v-c20b9e4d { + margin-left: 37.5rpx; +} +.mt-20.data-v-c20b9e4d { + margin-top: 37.5rpx; +} +.ml-22.data-v-c20b9e4d { + margin-left: 41.25rpx; +} +.mt-22.data-v-c20b9e4d { + margin-top: 41.25rpx; +} +.ml-24.data-v-c20b9e4d { + margin-left: 45rpx; +} +.mt-24.data-v-c20b9e4d { + margin-top: 45rpx; +} +.ml-26.data-v-c20b9e4d { + margin-left: 48.75rpx; +} +.mt-26.data-v-c20b9e4d { + margin-top: 48.75rpx; +} +.ml-28.data-v-c20b9e4d { + margin-left: 52.5rpx; +} +.mt-28.data-v-c20b9e4d { + margin-top: 52.5rpx; +} +.ml-30.data-v-c20b9e4d { + margin-left: 56.25rpx; +} +.mt-30.data-v-c20b9e4d { + margin-top: 56.25rpx; +} +.ml-32.data-v-c20b9e4d { + margin-left: 60rpx; +} +.mt-32.data-v-c20b9e4d { + margin-top: 60rpx; +} +.ml-34.data-v-c20b9e4d { + margin-left: 63.75rpx; +} +.mt-34.data-v-c20b9e4d { + margin-top: 63.75rpx; +} +.ml-36.data-v-c20b9e4d { + margin-left: 67.5rpx; +} +.mt-36.data-v-c20b9e4d { + margin-top: 67.5rpx; +} +.ml-38.data-v-c20b9e4d { + margin-left: 71.25rpx; +} +.mt-38.data-v-c20b9e4d { + margin-top: 71.25rpx; +} +.ml-40.data-v-c20b9e4d { + margin-left: 75rpx; +} +.mt-40.data-v-c20b9e4d { + margin-top: 75rpx; +} +.ml-42.data-v-c20b9e4d { + margin-left: 78.75rpx; +} +.mt-42.data-v-c20b9e4d { + margin-top: 78.75rpx; +} +.ml-44.data-v-c20b9e4d { + margin-left: 82.5rpx; +} +.mt-44.data-v-c20b9e4d { + margin-top: 82.5rpx; +} +.ml-46.data-v-c20b9e4d { + margin-left: 86.25rpx; +} +.mt-46.data-v-c20b9e4d { + margin-top: 86.25rpx; +} +.ml-48.data-v-c20b9e4d { + margin-left: 90rpx; +} +.mt-48.data-v-c20b9e4d { + margin-top: 90rpx; +} +.ml-50.data-v-c20b9e4d { + margin-left: 93.75rpx; +} +.mt-50.data-v-c20b9e4d { + margin-top: 93.75rpx; +} +.ml-52.data-v-c20b9e4d { + margin-left: 97.5rpx; +} +.mt-52.data-v-c20b9e4d { + margin-top: 97.5rpx; +} +.ml-54.data-v-c20b9e4d { + margin-left: 101.25rpx; +} +.mt-54.data-v-c20b9e4d { + margin-top: 101.25rpx; +} +.ml-56.data-v-c20b9e4d { + margin-left: 105rpx; +} +.mt-56.data-v-c20b9e4d { + margin-top: 105rpx; +} +.ml-58.data-v-c20b9e4d { + margin-left: 108.75rpx; +} +.mt-58.data-v-c20b9e4d { + margin-top: 108.75rpx; +} +.ml-60.data-v-c20b9e4d { + margin-left: 112.5rpx; +} +.mt-60.data-v-c20b9e4d { + margin-top: 112.5rpx; +} +.ml-62.data-v-c20b9e4d { + margin-left: 116.25rpx; +} +.mt-62.data-v-c20b9e4d { + margin-top: 116.25rpx; +} +.ml-64.data-v-c20b9e4d { + margin-left: 120rpx; +} +.mt-64.data-v-c20b9e4d { + margin-top: 120rpx; +} +.ml-66.data-v-c20b9e4d { + margin-left: 123.75rpx; +} +.mt-66.data-v-c20b9e4d { + margin-top: 123.75rpx; +} +.ml-68.data-v-c20b9e4d { + margin-left: 127.5rpx; +} +.mt-68.data-v-c20b9e4d { + margin-top: 127.5rpx; +} +.ml-70.data-v-c20b9e4d { + margin-left: 131.25rpx; +} +.mt-70.data-v-c20b9e4d { + margin-top: 131.25rpx; +} +.ml-72.data-v-c20b9e4d { + margin-left: 135rpx; +} +.mt-72.data-v-c20b9e4d { + margin-top: 135rpx; +} +.ml-74.data-v-c20b9e4d { + margin-left: 138.75rpx; +} +.mt-74.data-v-c20b9e4d { + margin-top: 138.75rpx; +} +.ml-76.data-v-c20b9e4d { + margin-left: 142.5rpx; +} +.mt-76.data-v-c20b9e4d { + margin-top: 142.5rpx; +} +.ml-78.data-v-c20b9e4d { + margin-left: 146.25rpx; +} +.mt-78.data-v-c20b9e4d { + margin-top: 146.25rpx; +} +.ml-80.data-v-c20b9e4d { + margin-left: 150rpx; +} +.mt-80.data-v-c20b9e4d { + margin-top: 150rpx; +} +.ml-82.data-v-c20b9e4d { + margin-left: 153.75rpx; +} +.mt-82.data-v-c20b9e4d { + margin-top: 153.75rpx; +} +.ml-84.data-v-c20b9e4d { + margin-left: 157.5rpx; +} +.mt-84.data-v-c20b9e4d { + margin-top: 157.5rpx; +} +.ml-86.data-v-c20b9e4d { + margin-left: 161.25rpx; +} +.mt-86.data-v-c20b9e4d { + margin-top: 161.25rpx; +} +.ml-88.data-v-c20b9e4d { + margin-left: 165rpx; +} +.mt-88.data-v-c20b9e4d { + margin-top: 165rpx; +} +.ml-90.data-v-c20b9e4d { + margin-left: 168.75rpx; +} +.mt-90.data-v-c20b9e4d { + margin-top: 168.75rpx; +} +.ml-92.data-v-c20b9e4d { + margin-left: 172.5rpx; +} +.mt-92.data-v-c20b9e4d { + margin-top: 172.5rpx; +} +.ml-94.data-v-c20b9e4d { + margin-left: 176.25rpx; +} +.mt-94.data-v-c20b9e4d { + margin-top: 176.25rpx; +} +.ml-96.data-v-c20b9e4d { + margin-left: 180rpx; +} +.mt-96.data-v-c20b9e4d { + margin-top: 180rpx; +} +.ml-98.data-v-c20b9e4d { + margin-left: 183.75rpx; +} +.mt-98.data-v-c20b9e4d { + margin-top: 183.75rpx; +} +.ml-100.data-v-c20b9e4d { + margin-left: 187.5rpx; +} +.mt-100.data-v-c20b9e4d { + margin-top: 187.5rpx; +} +.ml-9.data-v-c20b9e4d { + margin-left: 16.88rpx; +} +.page.data-v-c20b9e4d { + padding-top: 18.75rpx; + background-color: #f5f5dc; + border-radius: 28.13rpx 28.13rpx 0rpx 0rpx; + width: 100%; + overflow-y: auto; + overflow-x: hidden; + height: 100%; +} +.group.data-v-c20b9e4d { + padding: 11.47rpx 24.38rpx 6.26rpx; +} +.text.data-v-c20b9e4d { + color: #323232; + font-size: 37.5rpx; + font-family: Open Sans; + line-height: 34.76rpx; +} +.image.data-v-c20b9e4d { + width: 52.5rpx; + height: 52.5rpx; +} +.pos.data-v-c20b9e4d { + position: absolute; + right: 24.38rpx; + top: 50%; + transform: translateY(-50%); +} +.list.data-v-c20b9e4d { + margin-top: 30rpx; +} +.list-item_1.data-v-c20b9e4d { + padding: 26.27rpx 16.8rpx 24.98rpx; + background-color: #fffef8; + border-bottom: solid 1.88rpx #c8c8c8; +} +.image_2.data-v-c20b9e4d { + width: 33.75rpx; + height: 33.75rpx; +} +.font.data-v-c20b9e4d { + font-size: 30rpx; + font-family: Open Sans; + line-height: 27.19rpx; + color: #323232; +} +.font_2.data-v-c20b9e4d { + font-size: 30rpx; + font-family: Open Sans; + line-height: 22.05rpx; + color: #323232; +} +.group_3.data-v-c20b9e4d { + margin-right: 10.97rpx; +} +.image_3.data-v-c20b9e4d { + width: 39.38rpx; + height: 39.38rpx; +} +.font_3.data-v-c20b9e4d { + font-size: 26.25rpx; + font-family: Open Sans; + line-height: 31.88rpx; + color: #818181; +} +.text_2.data-v-c20b9e4d { + width: 601.88rpx; +} +.section.data-v-c20b9e4d { + margin-top: 202.5rpx; + padding: 18.75rpx 0; + background-color: #fffef8; +} +.text-wrapper.data-v-c20b9e4d { + padding: 27.9rpx 0 29.01rpx; + background-color: #fbb612; + border-radius: 75rpx; + width: 639.38rpx; +} +.text_3.data-v-c20b9e4d { + color: #ffffff; + font-size: 33.75rpx; + font-family: Open Sans; + line-height: 31.22rpx; +} \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/pages/order/paysuccess/paysuccess.js b/unpackage/dist/dev/mp-weixin/pages/order/paysuccess/paysuccess.js index 7a7b88d..26a8a7f 100644 --- a/unpackage/dist/dev/mp-weixin/pages/order/paysuccess/paysuccess.js +++ b/unpackage/dist/dev/mp-weixin/pages/order/paysuccess/paysuccess.js @@ -30,12 +30,18 @@ const _sfc_main = { product_value: 99 } ]); + const toOrderDetail = () => { + common_vendor.index.navigateTo({ + url: "../productOrderDetail/productOrderDetail" + }); + }; return (_ctx, _cache) => { return { a: common_vendor.unref(common_assets.success), - b: common_vendor.unref(common_assets.xian), - c: common_vendor.unref(common_assets.xian2), - d: common_vendor.f(products.value, (item, index, i0) => { + b: common_vendor.o(toOrderDetail), + c: common_vendor.unref(common_assets.xian), + d: common_vendor.unref(common_assets.xian2), + e: common_vendor.f(products.value, (item, index, i0) => { return { a: item.product_img, b: common_vendor.t(item.product_type), @@ -44,7 +50,7 @@ const _sfc_main = { e: index }; }), - e: common_vendor.unref(common_assets.rmb$1) + f: common_vendor.unref(common_assets.rmb$1) }; }; } diff --git a/unpackage/dist/dev/mp-weixin/pages/order/paysuccess/paysuccess.wxml b/unpackage/dist/dev/mp-weixin/pages/order/paysuccess/paysuccess.wxml index 5914295..c244c31 100644 --- a/unpackage/dist/dev/mp-weixin/pages/order/paysuccess/paysuccess.wxml +++ b/unpackage/dist/dev/mp-weixin/pages/order/paysuccess/paysuccess.wxml @@ -1 +1 @@ -支付成功返回首页查看订单更多精选商品【{{item.b}}】{{item.c}}{{item.d}}.00 \ No newline at end of file +支付成功返回首页查看订单更多精选商品【{{item.b}}】{{item.c}}{{item.d}}.00 \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.js b/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.js index 0cb4d3e..25cdee4 100644 --- a/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.js +++ b/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.js @@ -1,24 +1,51 @@ "use strict"; const common_vendor = require("../../../common/vendor.js"); +const pages_utils_emitter = require("../../utils/emitter.js"); const common_assets = require("../../../common/assets.js"); +if (!Array) { + const _easycom_uni_popup2 = common_vendor.resolveComponent("uni-popup"); + _easycom_uni_popup2(); +} +const _easycom_uni_popup = () => "../../../uni_modules/uni-popup/components/uni-popup/uni-popup.js"; +if (!Math) { + (addressComponentVue + _easycom_uni_popup)(); +} +const addressComponentVue = () => "../component/addressComponent.js"; const _sfc_main = { __name: "product-waitpay", setup(__props) { + const popup = common_vendor.ref(null); + const addressRealInfo = common_vendor.ref({}); + const productObject = common_vendor.ref({}); + const labelList = common_vendor.ref([]); + common_vendor.onMounted(() => { + pages_utils_emitter.emitter.on("close", () => { + close(); + }); + pages_utils_emitter.emitter.on("addressInfo", (val) => { + addressRealInfo.value = val; + }); + }); + common_vendor.onLoad((options) => { + productObject.value = JSON.parse(options.product); + labelList.value = productObject.value.label.split(";"); + labelList.value = labelList.value.filter((s) => { + return s; + }); + }); + const close = () => { + popup.value.close(); + }; + const loadPop = () => { + popup.value.open("bottom"); + }; const jump_pay = () => { console.log(123); common_vendor.index.navigateTo({ url: "../../../pages/order/paysuccess/paysuccess" }); }; - const address = common_vendor.ref( - { - address: "黑龙江省哈尔滨市呼兰区", - detail: "学院路街道288号哈尔滨华德学院", - name: "张三", - phone: "15888610253" - } - ); - const product_object = common_vendor.ref([ + common_vendor.ref([ { product_name: "非遗绒花", product_type: "材料包", @@ -40,42 +67,48 @@ const _sfc_main = { const sumprice = common_vendor.ref(88); return (_ctx, _cache) => { return { - a: common_vendor.t(address.value.address), + a: common_vendor.t(addressRealInfo.value.region), b: common_vendor.unref(common_assets.dingwei$1), - c: common_vendor.t(address.value.detail), + c: common_vendor.t(addressRealInfo.value.detailAddress), d: common_vendor.unref(common_assets.you_cheng), - e: common_vendor.t(address.value.name), - f: common_vendor.t(address.value.phone), - g: common_vendor.f(product_object.value, (item, index, i0) => { + e: common_vendor.o(($event) => loadPop()), + f: common_vendor.t(addressRealInfo.value.name), + g: common_vendor.t(addressRealInfo.value.phone), + h: productObject.value.goodImg, + i: common_vendor.t(productObject.value.name), + j: common_vendor.t(productObject.value.type), + k: common_vendor.f(labelList.value, (item, index, i0) => { return { - a: item.product_img, - b: common_vendor.t(item.product_name), - c: common_vendor.t(item.product_type), - d: common_vendor.t(item.selected_style), - e: common_vendor.t(item.tag[0]), - f: common_vendor.t(item.tag[1]), - g: common_vendor.t(item.tag[2]), - h: common_vendor.t(item.product_price), - i: item.rmb_img, - j: item.min_img, - k: item.add_img, - l: index + a: common_vendor.t(labelList.value[index]), + b: index }; }), - h: common_vendor.unref(common_assets.yiwen), - i: common_vendor.t(num.value), - j: common_vendor.unref(common_assets.rmb_36px), - k: common_vendor.unref(common_assets.you_hei), - l: common_vendor.t(youhuijuan_num.value), - m: common_vendor.t(manjian.value), - n: common_vendor.t(manjian1.value), - o: common_vendor.unref(common_assets.rmb_cheng), - p: common_vendor.t(manjian1.value), - q: common_vendor.unref(common_assets.rmb_36px), - r: common_vendor.t(sumprice.value), - s: common_vendor.unref(common_assets.rmb_huang), - t: common_vendor.t(sumprice.value), - v: common_vendor.o(jump_pay) + l: common_vendor.t(productObject.value.price), + m: common_vendor.unref(common_assets.rmb_32), + n: common_vendor.unref(common_assets.short$1), + o: common_vendor.unref(common_assets.add$1), + p: common_vendor.unref(common_assets.yiwen), + q: common_vendor.t(num.value), + r: common_vendor.unref(common_assets.rmb_36px), + s: common_vendor.t(productObject.value.price), + t: common_vendor.unref(common_assets.you_hei), + v: common_vendor.t(youhuijuan_num.value), + w: common_vendor.t(manjian.value), + x: common_vendor.t(manjian1.value), + y: common_vendor.unref(common_assets.rmb_cheng), + z: common_vendor.t(manjian1.value), + A: common_vendor.unref(common_assets.rmb_36px), + B: common_vendor.t(productObject.value.price - 50), + C: common_vendor.unref(common_assets.rmb_huang), + D: common_vendor.t(sumprice.value), + E: common_vendor.o(jump_pay), + F: common_vendor.sr(popup, "eda1e8f0-0", { + "k": "popup" + }), + G: common_vendor.o(_ctx.change), + H: common_vendor.p({ + ["background-color"]: "#fff" + }) }; }; } diff --git a/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.json b/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.json index a0812ee..48960a5 100644 --- a/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.json +++ b/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.json @@ -1,4 +1,7 @@ { "navigationBarTitleText": "", - "usingComponents": {} + "usingComponents": { + "uni-popup": "../../../uni_modules/uni-popup/components/uni-popup/uni-popup", + "address-component-vue": "../component/addressComponent" + } } \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.wxml b/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.wxml index 964b8a7..904eac4 100644 --- a/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.wxml +++ b/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.wxml @@ -1 +1 @@ -{{a}}{{c}}更换地址{{e}}{{f}}{{item.b}}【{{item.c}}】已选种类:{{item.d}}#{{item.e}}#{{item.f}}#{{item.g}}{{item.h}}.001注:购买商品均视为同意用户须知商品总价共{{i}}件商品138.00优惠券{{l}}张优惠券可用满{{m}}减{{n}}优惠{{p}}.00 合计{{r}}.00订单备注应付:{{t}}.00微信支付 \ No newline at end of file +{{a}}{{c}}更换地址{{f}}{{g}}{{i}}【{{j}}】#{{item.a}}{{l}}.001注:购买商品均视为同意用户须知商品总价共 {{q}} 件商品{{s}}优惠券{{v}}张优惠券可用满{{w}}减{{x}}优惠{{z}}.00 合计{{B}}.00订单备注应付:{{D}}.00微信支付 \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.wxss b/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.wxss index f782bb0..12df48b 100644 --- a/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.wxss +++ b/unpackage/dist/dev/mp-weixin/pages/order/product-waitpay/product-waitpay.wxss @@ -401,6 +401,12 @@ text.data-v-eda1e8f0 { .mt-100.data-v-eda1e8f0 { margin-top: 187.5rpx; } +.popup-content.data-v-eda1e8f0 { + height: 392px; + align-items: center; + justify-content: center; + background-color: #fff; +} .ml-17.data-v-eda1e8f0 { margin-left: 31.88rpx; } diff --git a/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail.js b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail.js new file mode 100644 index 0000000..4e8dfa8 --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail.js @@ -0,0 +1,18 @@ +"use strict"; +const common_vendor = require("../../../common/vendor.js"); +const _sfc_main = { + __name: "productOrderDetail", + setup(__props) { + return (_ctx, _cache) => { + return { + a: common_vendor.f(_ctx.items, (item, index, i0) => { + return { + a: index + }; + }) + }; + }; + } +}; +const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-f0df60ad"]]); +wx.createPage(MiniProgramPage); diff --git a/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail.json b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail.json new file mode 100644 index 0000000..a0812ee --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail.json @@ -0,0 +1,4 @@ +{ + "navigationBarTitleText": "", + "usingComponents": {} +} \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail.wxml b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail.wxml new file mode 100644 index 0000000..8862eee --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail.wxml @@ -0,0 +1 @@ +等待商家发货张三 15888610253黑龙江省哈尔滨市呼兰区学院路街道288号哈尔滨华德学院非遗绒花【材料包】已选种类:紫色138.00×1商品总价138.00优惠券50.00应付款:88.00买家留言 希望所使用的材料是可持续来源的,并且制作工艺要精细,以确保每一朵花瓣都能生动地展现出绒花的质感和美感。 订单编号:E20241005095840091406189复制创建时间:2024-10-05 09:58:41在线客服更多精选商品【非遗手工艺体验】玉雕-古法制玉体验99.00 \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail.wxss b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail.wxss new file mode 100644 index 0000000..9839a73 --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail.wxss @@ -0,0 +1,738 @@ +/* 水平间距 */ +/* 水平间距 */ +/************************************************************ +** 请将全局样式拷贝到项目的全局 CSS 文件或者当前页面的顶部 ** +** 否则页面将无法正常显示 ** +************************************************************/ +html.data-v-f0df60ad { + font-size: 16px; +} +body.data-v-f0df60ad { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', + 'Droid Sans', 'Helvetica Neue', 'Microsoft Yahei', sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +view.data-v-f0df60ad, +image.data-v-f0df60ad, +text.data-v-f0df60ad { + box-sizing: border-box; + flex-shrink: 0; +} +#app.data-v-f0df60ad { + width: 100vw; + height: 100vh; +} +.flex-row.data-v-f0df60ad { + display: flex; + flex-direction: row; +} +.flex-col.data-v-f0df60ad { + display: flex; + flex-direction: column; +} +.justify-start.data-v-f0df60ad { + justify-content: flex-start; +} +.justify-end.data-v-f0df60ad { + justify-content: flex-end; +} +.justify-center.data-v-f0df60ad { + justify-content: center; +} +.justify-between.data-v-f0df60ad { + justify-content: space-between; +} +.justify-around.data-v-f0df60ad { + justify-content: space-around; +} +.justify-evenly.data-v-f0df60ad { + justify-content: space-evenly; +} +.items-start.data-v-f0df60ad { + align-items: flex-start; +} +.items-end.data-v-f0df60ad { + align-items: flex-end; +} +.items-center.data-v-f0df60ad { + align-items: center; +} +.items-baseline.data-v-f0df60ad { + align-items: baseline; +} +.items-stretch.data-v-f0df60ad { + align-items: stretch; +} +.self-start.data-v-f0df60ad { + align-self: flex-start; +} +.self-end.data-v-f0df60ad { + align-self: flex-end; +} +.self-center.data-v-f0df60ad { + align-self: center; +} +.self-baseline.data-v-f0df60ad { + align-self: baseline; +} +.self-stretch.data-v-f0df60ad { + align-self: stretch; +} +.flex-1.data-v-f0df60ad { + flex: 1 1 0%; +} +.flex-auto.data-v-f0df60ad { + flex: 1 1 auto; +} +.grow.data-v-f0df60ad { + flex-grow: 1; +} +.grow-0.data-v-f0df60ad { + flex-grow: 0; +} +.shrink.data-v-f0df60ad { + flex-shrink: 1; +} +.shrink-0.data-v-f0df60ad { + flex-shrink: 0; +} +.relative.data-v-f0df60ad { + position: relative; +} +.ml-2.data-v-f0df60ad { + margin-left: 3.75rpx; +} +.mt-2.data-v-f0df60ad { + margin-top: 3.75rpx; +} +.ml-4.data-v-f0df60ad { + margin-left: 7.5rpx; +} +.mt-4.data-v-f0df60ad { + margin-top: 7.5rpx; +} +.ml-6.data-v-f0df60ad { + margin-left: 11.25rpx; +} +.mt-6.data-v-f0df60ad { + margin-top: 11.25rpx; +} +.ml-8.data-v-f0df60ad { + margin-left: 15rpx; +} +.mt-8.data-v-f0df60ad { + margin-top: 15rpx; +} +.ml-10.data-v-f0df60ad { + margin-left: 18.75rpx; +} +.mt-10.data-v-f0df60ad { + margin-top: 18.75rpx; +} +.ml-12.data-v-f0df60ad { + margin-left: 22.5rpx; +} +.mt-12.data-v-f0df60ad { + margin-top: 22.5rpx; +} +.ml-14.data-v-f0df60ad { + margin-left: 26.25rpx; +} +.mt-14.data-v-f0df60ad { + margin-top: 26.25rpx; +} +.ml-16.data-v-f0df60ad { + margin-left: 30rpx; +} +.mt-16.data-v-f0df60ad { + margin-top: 30rpx; +} +.ml-18.data-v-f0df60ad { + margin-left: 33.75rpx; +} +.mt-18.data-v-f0df60ad { + margin-top: 33.75rpx; +} +.ml-20.data-v-f0df60ad { + margin-left: 37.5rpx; +} +.mt-20.data-v-f0df60ad { + margin-top: 37.5rpx; +} +.ml-22.data-v-f0df60ad { + margin-left: 41.25rpx; +} +.mt-22.data-v-f0df60ad { + margin-top: 41.25rpx; +} +.ml-24.data-v-f0df60ad { + margin-left: 45rpx; +} +.mt-24.data-v-f0df60ad { + margin-top: 45rpx; +} +.ml-26.data-v-f0df60ad { + margin-left: 48.75rpx; +} +.mt-26.data-v-f0df60ad { + margin-top: 48.75rpx; +} +.ml-28.data-v-f0df60ad { + margin-left: 52.5rpx; +} +.mt-28.data-v-f0df60ad { + margin-top: 52.5rpx; +} +.ml-30.data-v-f0df60ad { + margin-left: 56.25rpx; +} +.mt-30.data-v-f0df60ad { + margin-top: 56.25rpx; +} +.ml-32.data-v-f0df60ad { + margin-left: 60rpx; +} +.mt-32.data-v-f0df60ad { + margin-top: 60rpx; +} +.ml-34.data-v-f0df60ad { + margin-left: 63.75rpx; +} +.mt-34.data-v-f0df60ad { + margin-top: 63.75rpx; +} +.ml-36.data-v-f0df60ad { + margin-left: 67.5rpx; +} +.mt-36.data-v-f0df60ad { + margin-top: 67.5rpx; +} +.ml-38.data-v-f0df60ad { + margin-left: 71.25rpx; +} +.mt-38.data-v-f0df60ad { + margin-top: 71.25rpx; +} +.ml-40.data-v-f0df60ad { + margin-left: 75rpx; +} +.mt-40.data-v-f0df60ad { + margin-top: 75rpx; +} +.ml-42.data-v-f0df60ad { + margin-left: 78.75rpx; +} +.mt-42.data-v-f0df60ad { + margin-top: 78.75rpx; +} +.ml-44.data-v-f0df60ad { + margin-left: 82.5rpx; +} +.mt-44.data-v-f0df60ad { + margin-top: 82.5rpx; +} +.ml-46.data-v-f0df60ad { + margin-left: 86.25rpx; +} +.mt-46.data-v-f0df60ad { + margin-top: 86.25rpx; +} +.ml-48.data-v-f0df60ad { + margin-left: 90rpx; +} +.mt-48.data-v-f0df60ad { + margin-top: 90rpx; +} +.ml-50.data-v-f0df60ad { + margin-left: 93.75rpx; +} +.mt-50.data-v-f0df60ad { + margin-top: 93.75rpx; +} +.ml-52.data-v-f0df60ad { + margin-left: 97.5rpx; +} +.mt-52.data-v-f0df60ad { + margin-top: 97.5rpx; +} +.ml-54.data-v-f0df60ad { + margin-left: 101.25rpx; +} +.mt-54.data-v-f0df60ad { + margin-top: 101.25rpx; +} +.ml-56.data-v-f0df60ad { + margin-left: 105rpx; +} +.mt-56.data-v-f0df60ad { + margin-top: 105rpx; +} +.ml-58.data-v-f0df60ad { + margin-left: 108.75rpx; +} +.mt-58.data-v-f0df60ad { + margin-top: 108.75rpx; +} +.ml-60.data-v-f0df60ad { + margin-left: 112.5rpx; +} +.mt-60.data-v-f0df60ad { + margin-top: 112.5rpx; +} +.ml-62.data-v-f0df60ad { + margin-left: 116.25rpx; +} +.mt-62.data-v-f0df60ad { + margin-top: 116.25rpx; +} +.ml-64.data-v-f0df60ad { + margin-left: 120rpx; +} +.mt-64.data-v-f0df60ad { + margin-top: 120rpx; +} +.ml-66.data-v-f0df60ad { + margin-left: 123.75rpx; +} +.mt-66.data-v-f0df60ad { + margin-top: 123.75rpx; +} +.ml-68.data-v-f0df60ad { + margin-left: 127.5rpx; +} +.mt-68.data-v-f0df60ad { + margin-top: 127.5rpx; +} +.ml-70.data-v-f0df60ad { + margin-left: 131.25rpx; +} +.mt-70.data-v-f0df60ad { + margin-top: 131.25rpx; +} +.ml-72.data-v-f0df60ad { + margin-left: 135rpx; +} +.mt-72.data-v-f0df60ad { + margin-top: 135rpx; +} +.ml-74.data-v-f0df60ad { + margin-left: 138.75rpx; +} +.mt-74.data-v-f0df60ad { + margin-top: 138.75rpx; +} +.ml-76.data-v-f0df60ad { + margin-left: 142.5rpx; +} +.mt-76.data-v-f0df60ad { + margin-top: 142.5rpx; +} +.ml-78.data-v-f0df60ad { + margin-left: 146.25rpx; +} +.mt-78.data-v-f0df60ad { + margin-top: 146.25rpx; +} +.ml-80.data-v-f0df60ad { + margin-left: 150rpx; +} +.mt-80.data-v-f0df60ad { + margin-top: 150rpx; +} +.ml-82.data-v-f0df60ad { + margin-left: 153.75rpx; +} +.mt-82.data-v-f0df60ad { + margin-top: 153.75rpx; +} +.ml-84.data-v-f0df60ad { + margin-left: 157.5rpx; +} +.mt-84.data-v-f0df60ad { + margin-top: 157.5rpx; +} +.ml-86.data-v-f0df60ad { + margin-left: 161.25rpx; +} +.mt-86.data-v-f0df60ad { + margin-top: 161.25rpx; +} +.ml-88.data-v-f0df60ad { + margin-left: 165rpx; +} +.mt-88.data-v-f0df60ad { + margin-top: 165rpx; +} +.ml-90.data-v-f0df60ad { + margin-left: 168.75rpx; +} +.mt-90.data-v-f0df60ad { + margin-top: 168.75rpx; +} +.ml-92.data-v-f0df60ad { + margin-left: 172.5rpx; +} +.mt-92.data-v-f0df60ad { + margin-top: 172.5rpx; +} +.ml-94.data-v-f0df60ad { + margin-left: 176.25rpx; +} +.mt-94.data-v-f0df60ad { + margin-top: 176.25rpx; +} +.ml-96.data-v-f0df60ad { + margin-left: 180rpx; +} +.mt-96.data-v-f0df60ad { + margin-top: 180rpx; +} +.ml-98.data-v-f0df60ad { + margin-left: 183.75rpx; +} +.mt-98.data-v-f0df60ad { + margin-top: 183.75rpx; +} +.ml-100.data-v-f0df60ad { + margin-left: 187.5rpx; +} +.mt-100.data-v-f0df60ad { + margin-top: 187.5rpx; +} +.ml-7.data-v-f0df60ad { + margin-left: 13.13rpx; +} +.mt-9.data-v-f0df60ad { + margin-top: 16.88rpx; +} +.ml-17.data-v-f0df60ad { + margin-left: 31.88rpx; +} +.mt-11.data-v-f0df60ad { + margin-top: 20.63rpx; +} +.mt-39.data-v-f0df60ad { + margin-top: 73.13rpx; +} +.ml-11.data-v-f0df60ad { + margin-left: 20.63rpx; +} +.mt-19.data-v-f0df60ad { + margin-top: 35.63rpx; +} +.page.data-v-f0df60ad { + background-color: #fffaf0; + width: 100%; + overflow-y: auto; + overflow-x: hidden; + height: 100%; +} +.image-wrapper.data-v-f0df60ad { + padding: 15rpx 0; + background-color: #a0522d; +} +.image.data-v-f0df60ad { + margin-left: 16.88rpx; + width: 37.5rpx; + height: 37.5rpx; +} +.group.data-v-f0df60ad { + padding-left: 16.41rpx; + padding-right: 13.59rpx; +} +.group_2.data-v-f0df60ad { + padding: 15rpx 0; +} +.section.data-v-f0df60ad { + padding: 20.49rpx 26.12rpx 22.63rpx; + background-color: #ffffff; + border-radius: 18.75rpx; + border: solid 1.88rpx #818181; +} +.image_2.data-v-f0df60ad { + width: 61.88rpx; + height: 61.88rpx; +} +.font.data-v-f0df60ad { + font-size: 26.25rpx; + font-family: Open Sans; + line-height: 24.43rpx; + color: #323232; +} +.text.data-v-f0df60ad { + color: #323233; + font-size: 28.13rpx; + line-height: 26.08rpx; +} +.section_2.data-v-f0df60ad { + padding: 32.72rpx 14.94rpx 31.99rpx 18.68rpx; + background-color: #ffffff; + border-radius: 18.75rpx; + border: solid 1.88rpx #818181; +} +.image_3.data-v-f0df60ad { + width: 43.13rpx; + height: 43.13rpx; +} +.text_2.data-v-f0df60ad { + line-height: 23.77rpx; +} +.font_2.data-v-f0df60ad { + font-size: 22.5rpx; + font-family: Open Sans; + line-height: 20.68rpx; + color: #818181; +} +.text_3.data-v-f0df60ad { + line-height: 20.91rpx; +} +.section_3.data-v-f0df60ad { + padding: 0 14.89rpx 18.88rpx 18.62rpx; + background-color: #ffffff; + border-radius: 18.75rpx; + border: solid 1.88rpx #818181; +} +.group_3.data-v-f0df60ad { + padding: 20.49rpx 3.75rpx 18.75rpx; + border-bottom: solid 1.88rpx #dfdfdf; +} +.image_4.data-v-f0df60ad { + margin-bottom: 5.63rpx; + border-radius: 9.38rpx; + width: 146.25rpx; + height: 165rpx; +} +.group_4.data-v-f0df60ad { + margin-top: 4.07rpx; +} +.text_4.data-v-f0df60ad { + margin-left: 2.1rpx; + line-height: 20.79rpx; +} +.group_5.data-v-f0df60ad { + width: 90.66rpx; +} +.text_5.data-v-f0df60ad { + margin-left: 25.03rpx; + color: #323232; + font-size: 33.75rpx; + font-family: Open Sans; + font-weight: 600; + line-height: 24.88rpx; +} +.image_5.data-v-f0df60ad { + width: 30rpx; + height: 30rpx; +} +.image_6.data-v-f0df60ad { + margin-left: -90.66rpx; +} +.font_3.data-v-f0df60ad { + font-size: 26.25rpx; + font-family: Open Sans; + line-height: 20.68rpx; + color: #323232; +} +.text_6.data-v-f0df60ad { + font-weight: 600; + line-height: 19.29rpx; +} +.text_7.data-v-f0df60ad { + margin-right: 9.83rpx; + margin-bottom: 7.5rpx; + line-height: 18.73rpx; +} +.view.data-v-f0df60ad { + margin-top: 26.25rpx; + padding: 0 5.53rpx; +} +.font_4.data-v-f0df60ad { + font-size: 26.25rpx; + font-family: Open Sans; + line-height: 24.43rpx; + color: #818181; +} +.text_8.data-v-f0df60ad { + line-height: 24.36rpx; +} +.text_9.data-v-f0df60ad { + line-height: 19.39rpx; +} +.view_2.data-v-f0df60ad { + margin-top: 13.13rpx; + padding: 0 4.69rpx; +} +.text_10.data-v-f0df60ad { + line-height: 24.26rpx; +} +.group_1.data-v-f0df60ad { + margin-right: 2.72rpx; +} +.image_7.data-v-f0df60ad { + width: 41.25rpx; + height: 30rpx; +} +.text_11.data-v-f0df60ad { + line-height: 19.39rpx; +} +.group_7.data-v-f0df60ad { + margin-top: 16.88rpx; + padding: 0 5.91rpx; +} +.group_8.data-v-f0df60ad { + width: 128.44rpx; +} +.image_8.data-v-f0df60ad { + margin-left: 98.44rpx; +} +.text_12.data-v-f0df60ad { + margin-left: -128.44rpx; + line-height: 24.54rpx; +} +.text_13.data-v-f0df60ad { + color: #fb8b05; + line-height: 19.39rpx; +} +.divider.data-v-f0df60ad { + background-color: #dfdfdf; + height: 1.88rpx; +} +.view_3.data-v-f0df60ad { + margin: 16.88rpx 9.62rpx 0 3.75rpx; +} +.text_14.data-v-f0df60ad { + margin-left: 5.16rpx; + margin-top: 24.86rpx; + line-height: 24.21rpx; +} +.text-wrapper.data-v-f0df60ad { + margin-right: 13.37rpx; + margin-top: 16.56rpx; + padding: 14.64rpx 0 9.77rpx; + background-color: #ffffff; + border-radius: 9.38rpx; + border: solid 1.88rpx #f1f1b5; +} +.text_15.data-v-f0df60ad { + margin-left: 15.37rpx; + margin-right: 20.27rpx; + line-height: 26.25rpx; +} +.view_4.data-v-f0df60ad { + margin: 18.75rpx 9.62rpx 0 3.75rpx; +} +.view_5.data-v-f0df60ad { + margin-top: 24.09rpx; + padding: 0 4.88rpx; +} +.text_16.data-v-f0df60ad { + line-height: 20.85rpx; +} +.group_9.data-v-f0df60ad { + margin-right: 4.74rpx; +} +.font_5.data-v-f0df60ad { + font-size: 22.5rpx; + font-family: Open Sans; + color: #323232; +} +.text_17.data-v-f0df60ad { + line-height: 16.54rpx; +} +.text-wrapper_2.data-v-f0df60ad { + padding-bottom: 2.29rpx; + background-color: #fffef8; + width: 50.63rpx; + height: 22.5rpx; + border: solid 0.94rpx #d1d1d1; +} +.text_18.data-v-f0df60ad { + color: #323232; + font-size: 18.75rpx; + font-family: Open Sans; + line-height: 17.38rpx; +} +.view_6.data-v-f0df60ad { + margin-top: 11.16rpx; + padding: 0 4.35rpx; +} +.text_19.data-v-f0df60ad { + line-height: 20.7rpx; +} +.text_20.data-v-f0df60ad { + margin-right: 157.91rpx; + line-height: 16.63rpx; +} +.group_10.data-v-f0df60ad { + margin-top: 27.81rpx; +} +.image_9.data-v-f0df60ad { + width: 45rpx; + height: 45rpx; +} +.font_6.data-v-f0df60ad { + font-size: 30rpx; + font-family: Open Sans; + color: #323232; +} +.text_21.data-v-f0df60ad { + line-height: 27.69rpx; +} +.image_10.data-v-f0df60ad { + width: 251.25rpx; + height: 1.88rpx; +} +.text_22.data-v-f0df60ad { + line-height: 27.71rpx; +} +.grid.data-v-f0df60ad { + margin-left: 11.72rpx; + margin-right: 14.53rpx; + height: 965.63rpx; + display: grid; + grid-template-rows: repeat(2, minmax(0, 1fr)); + grid-template-columns: repeat(2, minmax(0, 1fr)); + row-gap: 30.13rpx; + column-gap: 28.26rpx; +} +.grid-item.data-v-f0df60ad { + padding-bottom: 28.26rpx; + background-color: #ffffff; + border-radius: 18.75rpx; + border: solid 1.88rpx #818181; +} +.image_11.data-v-f0df60ad { + border-radius: 18.75rpx 18.75rpx 0rpx 0rpx; + width: 333.75rpx; + height: 322.5rpx; +} +.font_7.data-v-f0df60ad { + font-size: 26.25rpx; + font-family: Open Sans; + line-height: 30rpx; + color: #000000; +} +.text_23.data-v-f0df60ad { + margin: 8.42rpx 6.69rpx 0 12.06rpx; + font-size: 24.38rpx; +} +.group_11.data-v-f0df60ad { + margin-top: 17.83rpx; + padding: 0 22.37rpx; +} +.image_12.data-v-f0df60ad { + width: 26.25rpx; + height: 26.25rpx; +} +.font_8.data-v-f0df60ad { + font-size: 30rpx; + font-family: Times New Roman; + line-height: 20.68rpx; + color: #fbb612; +} +.section_4.data-v-f0df60ad { + background-color: #ffffff; + height: 103.13rpx; +} \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail/productOrderDetail.js b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail/productOrderDetail.js new file mode 100644 index 0000000..95b7aae --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail/productOrderDetail.js @@ -0,0 +1,18 @@ +"use strict"; +const common_vendor = require("../../../../common/vendor.js"); +const _sfc_main = { + __name: "productOrderDetail", + setup(__props) { + return (_ctx, _cache) => { + return { + a: common_vendor.f(_ctx.items, (item, index, i0) => { + return { + a: index + }; + }) + }; + }; + } +}; +const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-a18a39cb"]]); +wx.createPage(MiniProgramPage); diff --git a/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail/productOrderDetail.json b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail/productOrderDetail.json new file mode 100644 index 0000000..a0812ee --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail/productOrderDetail.json @@ -0,0 +1,4 @@ +{ + "navigationBarTitleText": "", + "usingComponents": {} +} \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail/productOrderDetail.wxml b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail/productOrderDetail.wxml new file mode 100644 index 0000000..eaeacde --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail/productOrderDetail.wxml @@ -0,0 +1 @@ +等待商家发货张三 15888610253黑龙江省哈尔滨市呼兰区学院路街道288号哈尔滨华德学院非遗绒花【材料包】已选种类:紫色138.00×1商品总价138.00优惠券50.00应付款:88.00买家留言 希望所使用的材料是可持续来源的,并且制作工艺要精细,以确保每一朵花瓣都能生动地展现出绒花的质感和美感。 订单编号:E20241005095840091406189复制创建时间:2024-10-05 09:58:41在线客服更多精选商品【非遗手工艺体验】玉雕-古法制玉体验99.00 \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail/productOrderDetail.wxss b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail/productOrderDetail.wxss new file mode 100644 index 0000000..1aed011 --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/pages/order/productOrderDetail/productOrderDetail/productOrderDetail.wxss @@ -0,0 +1,337 @@ +/* 水平间距 */ +/* 水平间距 */ +.ml-7.data-v-a18a39cb { + margin-left: 13.13rpx; +} +.mt-9.data-v-a18a39cb { + margin-top: 16.88rpx; +} +.ml-17.data-v-a18a39cb { + margin-left: 31.88rpx; +} +.mt-11.data-v-a18a39cb { + margin-top: 20.63rpx; +} +.mt-39.data-v-a18a39cb { + margin-top: 73.13rpx; +} +.ml-11.data-v-a18a39cb { + margin-left: 20.63rpx; +} +.mt-19.data-v-a18a39cb { + margin-top: 35.63rpx; +} +.page.data-v-a18a39cb { + background-color: #fffaf0; + width: 100%; + overflow-y: auto; + overflow-x: hidden; + height: 100%; +} +.image-wrapper.data-v-a18a39cb { + padding: 15rpx 0; + background-color: #a0522d; +} +.image.data-v-a18a39cb { + margin-left: 16.88rpx; + width: 37.5rpx; + height: 37.5rpx; +} +.group.data-v-a18a39cb { + padding-left: 16.41rpx; + padding-right: 13.59rpx; +} +.group_2.data-v-a18a39cb { + padding: 15rpx 0; +} +.section.data-v-a18a39cb { + padding: 20.49rpx 26.12rpx 22.63rpx; + background-color: #ffffff; + border-radius: 18.75rpx; + border: solid 1.88rpx #818181; +} +.image_2.data-v-a18a39cb { + width: 61.88rpx; + height: 61.88rpx; +} +.font.data-v-a18a39cb { + font-size: 26.25rpx; + font-family: Open Sans; + line-height: 24.43rpx; + color: #323232; +} +.text.data-v-a18a39cb { + color: #323233; + font-size: 28.13rpx; + line-height: 26.08rpx; +} +.section_2.data-v-a18a39cb { + padding: 32.72rpx 14.94rpx 31.99rpx 18.68rpx; + background-color: #ffffff; + border-radius: 18.75rpx; + border: solid 1.88rpx #818181; +} +.image_3.data-v-a18a39cb { + width: 43.13rpx; + height: 43.13rpx; +} +.text_2.data-v-a18a39cb { + line-height: 23.77rpx; +} +.font_2.data-v-a18a39cb { + font-size: 22.5rpx; + font-family: Open Sans; + line-height: 20.68rpx; + color: #818181; +} +.text_3.data-v-a18a39cb { + line-height: 20.91rpx; +} +.section_3.data-v-a18a39cb { + padding: 0 14.89rpx 18.88rpx 18.62rpx; + background-color: #ffffff; + border-radius: 18.75rpx; + border: solid 1.88rpx #818181; +} +.group_3.data-v-a18a39cb { + padding: 20.49rpx 3.75rpx 18.75rpx; + border-bottom: solid 1.88rpx #dfdfdf; +} +.image_4.data-v-a18a39cb { + margin-bottom: 5.63rpx; + border-radius: 9.38rpx; + width: 146.25rpx; + height: 165rpx; +} +.group_4.data-v-a18a39cb { + margin-top: 4.07rpx; +} +.text_4.data-v-a18a39cb { + margin-left: 2.1rpx; + line-height: 20.79rpx; +} +.group_5.data-v-a18a39cb { + width: 90.66rpx; +} +.text_5.data-v-a18a39cb { + margin-left: 25.03rpx; + color: #323232; + font-size: 33.75rpx; + font-family: Open Sans; + font-weight: 600; + line-height: 24.88rpx; +} +.image_5.data-v-a18a39cb { + width: 30rpx; + height: 30rpx; +} +.image_6.data-v-a18a39cb { + margin-left: -90.66rpx; +} +.font_3.data-v-a18a39cb { + font-size: 26.25rpx; + font-family: Open Sans; + line-height: 20.68rpx; + color: #323232; +} +.text_6.data-v-a18a39cb { + font-weight: 600; + line-height: 19.29rpx; +} +.text_7.data-v-a18a39cb { + margin-right: 9.83rpx; + margin-bottom: 7.5rpx; + line-height: 18.73rpx; +} +.view.data-v-a18a39cb { + margin-top: 26.25rpx; + padding: 0 5.53rpx; +} +.font_4.data-v-a18a39cb { + font-size: 26.25rpx; + font-family: Open Sans; + line-height: 24.43rpx; + color: #818181; +} +.text_8.data-v-a18a39cb { + line-height: 24.36rpx; +} +.text_9.data-v-a18a39cb { + line-height: 19.39rpx; +} +.view_2.data-v-a18a39cb { + margin-top: 13.13rpx; + padding: 0 4.69rpx; +} +.text_10.data-v-a18a39cb { + line-height: 24.26rpx; +} +.group_1.data-v-a18a39cb { + margin-right: 2.72rpx; +} +.image_7.data-v-a18a39cb { + width: 41.25rpx; + height: 30rpx; +} +.text_11.data-v-a18a39cb { + line-height: 19.39rpx; +} +.group_7.data-v-a18a39cb { + margin-top: 16.88rpx; + padding: 0 5.91rpx; +} +.group_8.data-v-a18a39cb { + width: 128.44rpx; +} +.image_8.data-v-a18a39cb { + margin-left: 98.44rpx; +} +.text_12.data-v-a18a39cb { + margin-left: -128.44rpx; + line-height: 24.54rpx; +} +.text_13.data-v-a18a39cb { + color: #fb8b05; + line-height: 19.39rpx; +} +.divider.data-v-a18a39cb { + background-color: #dfdfdf; + height: 1.88rpx; +} +.view_3.data-v-a18a39cb { + margin: 16.88rpx 9.62rpx 0 3.75rpx; +} +.text_14.data-v-a18a39cb { + margin-left: 5.16rpx; + margin-top: 24.86rpx; + line-height: 24.21rpx; +} +.text-wrapper.data-v-a18a39cb { + margin-right: 13.37rpx; + margin-top: 16.56rpx; + padding: 14.64rpx 0 9.77rpx; + background-color: #ffffff; + border-radius: 9.38rpx; + border: solid 1.88rpx #f1f1b5; +} +.text_15.data-v-a18a39cb { + margin-left: 15.37rpx; + margin-right: 20.27rpx; + line-height: 26.25rpx; +} +.view_4.data-v-a18a39cb { + margin: 18.75rpx 9.62rpx 0 3.75rpx; +} +.view_5.data-v-a18a39cb { + margin-top: 24.09rpx; + padding: 0 4.88rpx; +} +.text_16.data-v-a18a39cb { + line-height: 20.85rpx; +} +.group_9.data-v-a18a39cb { + margin-right: 4.74rpx; +} +.font_5.data-v-a18a39cb { + font-size: 22.5rpx; + font-family: Open Sans; + color: #323232; +} +.text_17.data-v-a18a39cb { + line-height: 16.54rpx; +} +.text-wrapper_2.data-v-a18a39cb { + padding-bottom: 2.29rpx; + background-color: #fffef8; + width: 50.63rpx; + height: 22.5rpx; + border: solid 0.94rpx #d1d1d1; +} +.text_18.data-v-a18a39cb { + color: #323232; + font-size: 18.75rpx; + font-family: Open Sans; + line-height: 17.38rpx; +} +.view_6.data-v-a18a39cb { + margin-top: 11.16rpx; + padding: 0 4.35rpx; +} +.text_19.data-v-a18a39cb { + line-height: 20.7rpx; +} +.text_20.data-v-a18a39cb { + margin-right: 157.91rpx; + line-height: 16.63rpx; +} +.group_10.data-v-a18a39cb { + margin-top: 27.81rpx; +} +.image_9.data-v-a18a39cb { + width: 45rpx; + height: 45rpx; +} +.font_6.data-v-a18a39cb { + font-size: 30rpx; + font-family: Open Sans; + color: #323232; +} +.text_21.data-v-a18a39cb { + line-height: 27.69rpx; +} +.image_10.data-v-a18a39cb { + width: 251.25rpx; + height: 1.88rpx; +} +.text_22.data-v-a18a39cb { + line-height: 27.71rpx; +} +.grid.data-v-a18a39cb { + margin-left: 11.72rpx; + margin-right: 14.53rpx; + height: 965.63rpx; + display: grid; + grid-template-rows: repeat(2, minmax(0, 1fr)); + grid-template-columns: repeat(2, minmax(0, 1fr)); + row-gap: 30.13rpx; + column-gap: 28.26rpx; +} +.grid-item.data-v-a18a39cb { + padding-bottom: 28.26rpx; + background-color: #ffffff; + border-radius: 18.75rpx; + border: solid 1.88rpx #818181; +} +.image_11.data-v-a18a39cb { + border-radius: 18.75rpx 18.75rpx 0rpx 0rpx; + width: 333.75rpx; + height: 322.5rpx; +} +.font_7.data-v-a18a39cb { + font-size: 26.25rpx; + font-family: Open Sans; + line-height: 30rpx; + color: #000000; +} +.text_23.data-v-a18a39cb { + margin: 8.42rpx 6.69rpx 0 12.06rpx; + font-size: 24.38rpx; +} +.group_11.data-v-a18a39cb { + margin-top: 17.83rpx; + padding: 0 22.37rpx; +} +.image_12.data-v-a18a39cb { + width: 26.25rpx; + height: 26.25rpx; +} +.font_8.data-v-a18a39cb { + font-size: 30rpx; + font-family: Times New Roman; + line-height: 20.68rpx; + color: #fbb612; +} +.section_4.data-v-a18a39cb { + background-color: #ffffff; + height: 103.13rpx; +} \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/pages/store-home/ProductDetails/ProductDetails.js b/unpackage/dist/dev/mp-weixin/pages/store-home/ProductDetails/ProductDetails.js index aef9dea..c5cd4fe 100644 --- a/unpackage/dist/dev/mp-weixin/pages/store-home/ProductDetails/ProductDetails.js +++ b/unpackage/dist/dev/mp-weixin/pages/store-home/ProductDetails/ProductDetails.js @@ -1,34 +1,44 @@ "use strict"; const common_vendor = require("../../../common/vendor.js"); const common_assets = require("../../../common/assets.js"); +require("../../utils/emitter.js"); const _sfc_main = { __name: "ProductDetails", setup(__props) { - common_vendor.ref(750); - common_vendor.ref("琉璃发簪新手体验包"); - const detail = common_vendor.ref("琉璃发簪便是汉代美人常常佩戴的发饰之一。琉璃发簪不仅美观大方,还有 着深厚的文化底蕴。购买体验包,即可体验古代文化。"); - const arr_tag = common_vendor.ref(["发簪", "送亲友", "体验包", "友情"]); + const productObject = common_vendor.ref({}); + const labelList = common_vendor.ref([]); + common_vendor.onLoad((options) => { + productObject.value = JSON.parse(options.info); + labelList.value = productObject.value.label.split(";"); + labelList.value = labelList.value.filter((s) => { + return s; + }); + }); const jump_buy = () => { common_vendor.index.navigateTo({ - url: "../../../pages/order/product-waitpay/product-waitpay" + url: "../../../pages/order/product-waitpay/product-waitpay?product=" + JSON.stringify(productObject.value) }); }; return (_ctx, _cache) => { return { - a: common_vendor.unref(common_assets.zhuye), + a: productObject.value.goodImg, b: common_vendor.unref(common_assets.show1), c: common_vendor.unref(common_assets.show2), d: common_vendor.unref(common_assets.show3), e: common_vendor.unref(common_assets.show4), f: common_vendor.unref(common_assets.show3), - g: common_vendor.unref(common_assets.denglong), - h: common_vendor.t(detail.value), - i: common_vendor.t(arr_tag.value[0]), - j: common_vendor.t(arr_tag.value[1]), - k: common_vendor.t(arr_tag.value[2]), - l: common_vendor.t(arr_tag.value[3]), - m: common_vendor.unref(common_assets.kefu), - n: common_vendor.o(jump_buy) + g: common_vendor.t(productObject.value.price), + h: common_vendor.t(productObject.value.name), + i: common_vendor.unref(common_assets.denglong), + j: common_vendor.t(productObject.value.introDetail), + k: common_vendor.f(labelList.value, (item, index, i0) => { + return { + a: common_vendor.t(labelList.value[index]), + b: index + }; + }), + l: common_vendor.unref(common_assets.kefu), + m: common_vendor.o(jump_buy) }; }; } diff --git a/unpackage/dist/dev/mp-weixin/pages/store-home/ProductDetails/ProductDetails.wxml b/unpackage/dist/dev/mp-weixin/pages/store-home/ProductDetails/ProductDetails.wxml index ebc048a..dd0c48b 100644 --- a/unpackage/dist/dev/mp-weixin/pages/store-home/ProductDetails/ProductDetails.wxml +++ b/unpackage/dist/dev/mp-weixin/pages/store-home/ProductDetails/ProductDetails.wxml @@ -1 +1 @@ -商品详情推荐图片展示750琉璃发簪新手体验包中秋节限定 商品简介:{{h}} 商品标签:#{{i}}#{{j}}#{{k}}#{{l}}用户须知1.发货后不接受退货、不接受7天无理由退货2.商品购买后无法自主退款,需联系客服进行退款处理 3.定制款商品购买后不接受退货退款,包售后需要录制开箱视频,并且开箱视频需要从拆包装开始 4.商品售罄后的款式也可以重新预定,需等待并联系客服5.定制商品的具体发货日期根据制作团队制作情况而定6.只售后邮寄破损商品详情客服加入购物车立即购买 \ No newline at end of file +商品详情推荐图片展示{{g}}{{h}}中秋节限定 商品简介:{{j}} 商品标签:#{{item.a}}用户须知1.发货后不接受退货、不接受7天无理由退货2.商品购买后无法自主退款,需联系客服进行退款处理 3.定制款商品购买后不接受退货退款,包售后需要录制开箱视频,并且开箱视频需要从拆包装开始 4.商品售罄后的款式也可以重新预定,需等待并联系客服5.定制商品的具体发货日期根据制作团队制作情况而定6.只售后邮寄破损商品详情客服加入购物车立即购买 \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/pages/store-home/main/main.js b/unpackage/dist/dev/mp-weixin/pages/store-home/main/main.js index 6a16dc0..3a1e464 100644 --- a/unpackage/dist/dev/mp-weixin/pages/store-home/main/main.js +++ b/unpackage/dist/dev/mp-weixin/pages/store-home/main/main.js @@ -1,84 +1,72 @@ "use strict"; const common_vendor = require("../../../common/vendor.js"); +const api_request = require("../../../api/request.js"); const common_assets = require("../../../common/assets.js"); const _sfc_main = { __name: "main", setup(__props) { - const sort = common_vendor.ref([ - { - name: "材料包", - imgurl: common_assets.img1 - }, - { - name: "手持物", - imgurl: common_assets.img2 - }, - { - name: "头饰", - imgurl: common_assets.img3 - }, - { - name: "定制", - imgurl: common_assets.img4 - }, - { - name: "积分商城", - imgurl: common_assets.img5 + const currentColor = common_vendor.ref(0); + const sort = common_vendor.ref([{}]); + const headerList = common_vendor.ref([{}]); + const productList = common_vendor.ref([{}]); + common_vendor.onMounted(async () => { + await Getsort(); + await changeTypes(sort.value[0], 0); + }); + const Getsort = async () => { + const res = await common_vendor.index.request({ + url: api_request.testUrl + "/category/list", + method: "POST" + }); + if (res.data.code === 1) { + for (let key in res.data.data) { + sort.value[key] = { + //类别列表 + name: res.data.data[key].typeName, + imgurl: res.data.data[key].typeUrl, + id: res.data.data[key].id + }; + headerList.value[key] = { + name: res.data.data[key].typeName, + typeIntro: res.data.data[key].typeIntro + }; + } + } else { + common_vendor.index.showToast({ + //提示请求错误 + title: "请求商品分类错误", + icon: "none", + duration: 2e3 + }); } - ]); - const product_list = common_vendor.ref([ - { - product_name: "琉璃发簪体验包", - detail: "非遗材料包,匠心独运", - value: "750", - imgurl: common_assets.product_img - }, - { - product_name: "琉璃发簪体验包", - detail: "非遗材料包,匠心独运", - value: "750", - imgurl: common_assets.product_img - }, - { - product_name: "琉璃发簪体验包", - detail: "非遗材料包,匠心独运", - value: "750", - imgurl: common_assets.product_img - }, - { - product_name: "琉璃发簪体验包", - detail: "非遗材料包,匠心独运", - value: "750", - imgurl: common_assets.product_img - }, - { - product_name: "琉璃发簪体验包", - detail: "非遗材料包,匠心独运", - value: "750", - imgurl: common_assets.product_img - }, - { - product_name: "琉璃发簪体验包", - detail: "非遗材料包,匠心独运", - value: "750", - imgurl: common_assets.product_img - }, - { - product_name: "琉璃发簪体验包", - detail: "非遗材料包,匠心独运", - value: "750", - imgurl: common_assets.product_img - }, - { - product_name: "琉璃发簪体验包", - detail: "非遗材料包,匠心独运", - value: "750", - imgurl: common_assets.product_img + }; + const changeTypes = async (item, index) => { + currentColor.value = index; + const res = await common_vendor.index.request({ + url: api_request.testUrl + "/category/list/type", + method: "POST", + data: { + id: item.id + } + }); + if (res.data.code === 1) { + productList.value = res.data.data[item.id]; + } else { + common_vendor.index.showToast({ + //商品请求错误 + title: "更改类别错误", + icon: "none", + duration: 2e3 + }); } - ]); - const tap = () => { + }; + const getBoxStyle = (index) => ({ + backgroundColor: currentColor.value === index ? "brown" : "#fffef8" + }); + const goToProduct = (item) => { + console.log(item, 123); common_vendor.index.navigateTo({ - url: "../../../pages/store-home/ProductDetails/ProductDetails" + url: "../../../pages/store-home/ProductDetails/ProductDetails?info=" + JSON.stringify(item) }); }; return (_ctx, _cache) => { @@ -88,17 +76,19 @@ const _sfc_main = { return { a: item.imgurl, b: common_vendor.t(item.name), - c: index + c: index, + d: common_vendor.s(getBoxStyle(index)), + e: common_vendor.o(($event) => changeTypes(item, index), index) }; }), - c: common_vendor.f(product_list.value, (item, index, i0) => { + c: common_vendor.f(productList.value, (item, index, i0) => { return { - a: item.imgurl, - b: common_vendor.t(item.product_name), - c: common_vendor.t(item.detail), - d: common_vendor.t(item.value), + a: item.goodImg, + b: common_vendor.t(item.name), + c: common_vendor.t(item.intro), + d: common_vendor.t(item.price), e: index, - f: common_vendor.o(tap, index) + f: common_vendor.o(($event) => goToProduct(item), index) }; }), d: common_vendor.unref(common_assets.add_img) diff --git a/unpackage/dist/dev/mp-weixin/pages/store-home/main/main.wxml b/unpackage/dist/dev/mp-weixin/pages/store-home/main/main.wxml index bc7f41f..9f46b54 100644 --- a/unpackage/dist/dev/mp-weixin/pages/store-home/main/main.wxml +++ b/unpackage/dist/dev/mp-weixin/pages/store-home/main/main.wxml @@ -1 +1 @@ -商品{{item.b}}材料包提供材料自行DIY{{item.b}}{{item.c}}¥{{item.d}} \ No newline at end of file +商品{{item.b}}材料包提供材料自行DIY{{item.b}}{{item.c}}¥{{item.d}} \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/pages/store-home/main/main.wxss b/unpackage/dist/dev/mp-weixin/pages/store-home/main/main.wxss index 8dd0573..5caa731 100644 --- a/unpackage/dist/dev/mp-weixin/pages/store-home/main/main.wxss +++ b/unpackage/dist/dev/mp-weixin/pages/store-home/main/main.wxss @@ -413,9 +413,10 @@ text.data-v-7e3c386d { } .mt-3.data-v-7e3c386d { margin-top: 5.63rpx; + text-align: center; } .mt-13.data-v-7e3c386d { - margin-top: 24.38rpx; + margin-top: 17.38rpx; } .mt-5.data-v-7e3c386d { margin-top: 9.38rpx; @@ -504,11 +505,11 @@ text.data-v-7e3c386d { } .image_3.data-v-7e3c386d { border-radius: 0rpx 9.38rpx 9.38rpx 0rpx; - width: 48.75rpx; - height: 48.75rpx; + width: 60rpx; + height: 60rpx; } .font_4.data-v-7e3c386d { - font-size: 30rpx; + font-size: 25rpx; font-family: STFangsong; line-height: 28.26rpx; color: #c1651a; diff --git a/unpackage/dist/dev/mp-weixin/pages/utils/emitter.js b/unpackage/dist/dev/mp-weixin/pages/utils/emitter.js new file mode 100644 index 0000000..bbcdff8 --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/pages/utils/emitter.js @@ -0,0 +1,4 @@ +"use strict"; +const common_vendor = require("../../common/vendor.js"); +const emitter = common_vendor.mitt(); +exports.emitter = emitter; diff --git a/unpackage/dist/dev/mp-weixin/project.config.json b/unpackage/dist/dev/mp-weixin/project.config.json index f1e88b6..bc80aed 100644 --- a/unpackage/dist/dev/mp-weixin/project.config.json +++ b/unpackage/dist/dev/mp-weixin/project.config.json @@ -19,9 +19,26 @@ }, "compileType": "miniprogram", "libVersion": "3.6.0", - "appid": "wxbcb1cf9951fa17c8", + "appid": "wx3f968a09e31d6bed", "projectname": "FeiYi", - "condition": {}, + "condition": { + "search": { + "current": -1, + "list": [] + }, + "conversation": { + "current": -1, + "list": [] + }, + "game": { + "current": -1, + "list": [] + }, + "miniprogram": { + "current": -1, + "list": [] + } + }, "editorSetting": { "tabIndent": "insertSpaces", "tabSize": 2 diff --git a/unpackage/dist/dev/mp-weixin/project.private.config.json b/unpackage/dist/dev/mp-weixin/project.private.config.json index 4250156..44a4b7f 100644 --- a/unpackage/dist/dev/mp-weixin/project.private.config.json +++ b/unpackage/dist/dev/mp-weixin/project.private.config.json @@ -3,5 +3,22 @@ "projectname": "FeiYi", "setting": { "compileHotReLoad": true + }, + "condition": { + "miniprogram": { + "list": [ + { + "name": "pages/store-home/main/main", + "pathName": "pages/store-home/main/main", + "query": "", + "launchMode": "default", + "scene": null, + "partialCompile": { + "enabled": true, + "pages": [] + } + } + ] + } } } \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/store/index.js b/unpackage/dist/dev/mp-weixin/store/index.js new file mode 100644 index 0000000..f43c15e --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/store/index.js @@ -0,0 +1,4 @@ +"use strict"; +const common_vendor = require("../common/vendor.js"); +const pinia = common_vendor.createPinia(); +exports.pinia = pinia; diff --git a/unpackage/dist/dev/mp-weixin/store/userStore.js b/unpackage/dist/dev/mp-weixin/store/userStore.js new file mode 100644 index 0000000..5630f9e --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/store/userStore.js @@ -0,0 +1,25 @@ +"use strict"; +const common_vendor = require("../common/vendor.js"); +const userStore = common_vendor.defineStore("userInfo", { + state: () => { + return { + userInfo: { + id: 2, + userAvatar: "", + userName: "匠承非遗", + points: 800 + } + }; + }, + actions: { + // updateUserInfo: async () => { + // const res = await uni.request({ + // url: testUrl + '/user/updateUser' + // }) + // console.log(res) + // }, + // getLoginUser(res) { + // } + } +}); +exports.userStore = userStore; diff --git a/unpackage/dist/dev/mp-weixin/uni_modules/uni-popup/components/uni-popup/uni-popup.js b/unpackage/dist/dev/mp-weixin/uni_modules/uni-popup/components/uni-popup/uni-popup.js new file mode 100644 index 0000000..291ab4e --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/uni_modules/uni-popup/components/uni-popup/uni-popup.js @@ -0,0 +1,393 @@ +"use strict"; +const common_vendor = require("../../../../common/vendor.js"); +const _sfc_main = { + name: "uniPopup", + components: {}, + emits: ["change", "maskClick"], + props: { + // 开启动画 + animation: { + type: Boolean, + default: true + }, + // 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层 + // message: 消息提示 ; dialog : 对话框 + type: { + type: String, + default: "center" + }, + // maskClick + isMaskClick: { + type: Boolean, + default: null + }, + // TODO 2 个版本后废弃属性 ,使用 isMaskClick + maskClick: { + type: Boolean, + default: null + }, + backgroundColor: { + type: String, + default: "none" + }, + safeArea: { + type: Boolean, + default: true + }, + maskBackgroundColor: { + type: String, + default: "rgba(0, 0, 0, 0.4)" + }, + borderRadius: { + type: String + } + }, + watch: { + /** + * 监听type类型 + */ + type: { + handler: function(type) { + if (!this.config[type]) + return; + this[this.config[type]](true); + }, + immediate: true + }, + isDesktop: { + handler: function(newVal) { + if (!this.config[newVal]) + return; + this[this.config[this.type]](true); + }, + immediate: true + }, + /** + * 监听遮罩是否可点击 + * @param {Object} val + */ + maskClick: { + handler: function(val) { + this.mkclick = val; + }, + immediate: true + }, + isMaskClick: { + handler: function(val) { + this.mkclick = val; + }, + immediate: true + }, + // H5 下禁止底部滚动 + showPopup(show) { + } + }, + data() { + return { + duration: 300, + ani: [], + showPopup: false, + showTrans: false, + popupWidth: 0, + popupHeight: 0, + config: { + top: "top", + bottom: "bottom", + center: "center", + left: "left", + right: "right", + message: "top", + dialog: "center", + share: "bottom" + }, + maskClass: { + position: "fixed", + bottom: 0, + top: 0, + left: 0, + right: 0, + backgroundColor: "rgba(0, 0, 0, 0.4)" + }, + transClass: { + backgroundColor: "transparent", + borderRadius: this.borderRadius || "0", + position: "fixed", + left: 0, + right: 0 + }, + maskShow: true, + mkclick: true, + popupstyle: "top" + }; + }, + computed: { + getStyles() { + let res = { backgroundColor: this.bg }; + if (this.borderRadius || "0") { + res = Object.assign(res, { borderRadius: this.borderRadius }); + } + return res; + }, + isDesktop() { + return this.popupWidth >= 500 && this.popupHeight >= 500; + }, + bg() { + if (this.backgroundColor === "" || this.backgroundColor === "none") { + return "transparent"; + } + return this.backgroundColor; + } + }, + mounted() { + const fixSize = () => { + const { + windowWidth, + windowHeight, + windowTop, + safeArea, + screenHeight, + safeAreaInsets + } = common_vendor.index.getSystemInfoSync(); + this.popupWidth = windowWidth; + this.popupHeight = windowHeight + (windowTop || 0); + if (safeArea && this.safeArea) { + this.safeAreaInsets = screenHeight - safeArea.bottom; + } else { + this.safeAreaInsets = 0; + } + }; + fixSize(); + }, + // TODO vue3 + unmounted() { + this.setH5Visible(); + }, + activated() { + this.setH5Visible(!this.showPopup); + }, + deactivated() { + this.setH5Visible(true); + }, + created() { + if (this.isMaskClick === null && this.maskClick === null) { + this.mkclick = true; + } else { + this.mkclick = this.isMaskClick !== null ? this.isMaskClick : this.maskClick; + } + if (this.animation) { + this.duration = 300; + } else { + this.duration = 0; + } + this.messageChild = null; + this.clearPropagation = false; + this.maskClass.backgroundColor = this.maskBackgroundColor; + }, + methods: { + setH5Visible(visible = true) { + }, + /** + * 公用方法,不显示遮罩层 + */ + closeMask() { + this.maskShow = false; + }, + /** + * 公用方法,遮罩层禁止点击 + */ + disableMask() { + this.mkclick = false; + }, + // TODO nvue 取消冒泡 + clear(e) { + e.stopPropagation(); + this.clearPropagation = true; + }, + open(direction) { + if (this.showPopup) { + return; + } + let innerType = ["top", "center", "bottom", "left", "right", "message", "dialog", "share"]; + if (!(direction && innerType.indexOf(direction) !== -1)) { + direction = this.type; + } + if (!this.config[direction]) { + console.error("缺少类型:", direction); + return; + } + this[this.config[direction]](); + this.$emit("change", { + show: true, + type: direction + }); + }, + close(type) { + this.showTrans = false; + this.$emit("change", { + show: false, + type: this.type + }); + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.showPopup = false; + }, 300); + }, + // TODO 处理冒泡事件,头条的冒泡事件有问题 ,先这样兼容 + touchstart() { + this.clearPropagation = false; + }, + onTap() { + if (this.clearPropagation) { + this.clearPropagation = false; + return; + } + this.$emit("maskClick"); + if (!this.mkclick) + return; + this.close(); + }, + /** + * 顶部弹出样式处理 + */ + top(type) { + this.popupstyle = this.isDesktop ? "fixforpc-top" : "top"; + this.ani = ["slide-top"]; + this.transClass = { + position: "fixed", + left: 0, + right: 0, + backgroundColor: this.bg, + borderRadius: this.borderRadius || "0" + }; + if (type) + return; + this.showPopup = true; + this.showTrans = true; + this.$nextTick(() => { + if (this.messageChild && this.type === "message") { + this.messageChild.timerClose(); + } + }); + }, + /** + * 底部弹出样式处理 + */ + bottom(type) { + this.popupstyle = "bottom"; + this.ani = ["slide-bottom"]; + this.transClass = { + position: "fixed", + left: 0, + right: 0, + bottom: 0, + paddingBottom: this.safeAreaInsets + "px", + backgroundColor: this.bg, + borderRadius: this.borderRadius || "0" + }; + if (type) + return; + this.showPopup = true; + this.showTrans = true; + }, + /** + * 中间弹出样式处理 + */ + center(type) { + this.popupstyle = "center"; + this.ani = ["fade"]; + this.transClass = { + position: "fixed", + display: "flex", + flexDirection: "column", + bottom: 0, + left: 0, + right: 0, + top: 0, + justifyContent: "center", + alignItems: "center", + borderRadius: this.borderRadius || "0" + }; + if (type) + return; + this.showPopup = true; + this.showTrans = true; + }, + left(type) { + this.popupstyle = "left"; + this.ani = ["slide-left"]; + this.transClass = { + position: "fixed", + left: 0, + bottom: 0, + top: 0, + backgroundColor: this.bg, + borderRadius: this.borderRadius || "0", + display: "flex", + flexDirection: "column" + }; + if (type) + return; + this.showPopup = true; + this.showTrans = true; + }, + right(type) { + this.popupstyle = "right"; + this.ani = ["slide-right"]; + this.transClass = { + position: "fixed", + bottom: 0, + right: 0, + top: 0, + backgroundColor: this.bg, + borderRadius: this.borderRadius || "0", + display: "flex", + flexDirection: "column" + }; + if (type) + return; + this.showPopup = true; + this.showTrans = true; + } + } +}; +if (!Array) { + const _easycom_uni_transition2 = common_vendor.resolveComponent("uni-transition"); + _easycom_uni_transition2(); +} +const _easycom_uni_transition = () => "../../../uni-transition/components/uni-transition/uni-transition.js"; +if (!Math) { + _easycom_uni_transition(); +} +function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { + return common_vendor.e({ + a: $data.showPopup + }, $data.showPopup ? common_vendor.e({ + b: $data.maskShow + }, $data.maskShow ? { + c: common_vendor.o($options.onTap), + d: common_vendor.p({ + name: "mask", + ["mode-class"]: "fade", + styles: $data.maskClass, + duration: $data.duration, + show: $data.showTrans + }) + } : {}, { + e: common_vendor.s($options.getStyles), + f: common_vendor.n($data.popupstyle), + g: common_vendor.o((...args) => $options.clear && $options.clear(...args)), + h: common_vendor.o($options.onTap), + i: common_vendor.p({ + ["mode-class"]: $data.ani, + name: "content", + styles: $data.transClass, + duration: $data.duration, + show: $data.showTrans + }), + j: common_vendor.o((...args) => $options.touchstart && $options.touchstart(...args)), + k: common_vendor.n($data.popupstyle), + l: common_vendor.n($options.isDesktop ? "fixforpc-z-index" : "") + }) : {}); +} +const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]); +wx.createComponent(Component); diff --git a/unpackage/dist/dev/mp-weixin/uni_modules/uni-popup/components/uni-popup/uni-popup.json b/unpackage/dist/dev/mp-weixin/uni_modules/uni-popup/components/uni-popup/uni-popup.json new file mode 100644 index 0000000..3a0615f --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/uni_modules/uni-popup/components/uni-popup/uni-popup.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "uni-transition": "../../../uni-transition/components/uni-transition/uni-transition" + } +} \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/uni_modules/uni-popup/components/uni-popup/uni-popup.wxml b/unpackage/dist/dev/mp-weixin/uni_modules/uni-popup/components/uni-popup/uni-popup.wxml new file mode 100644 index 0000000..4e06aa2 --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/uni_modules/uni-popup/components/uni-popup/uni-popup.wxml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/uni_modules/uni-popup/components/uni-popup/uni-popup.wxss b/unpackage/dist/dev/mp-weixin/uni_modules/uni-popup/components/uni-popup/uni-popup.wxss new file mode 100644 index 0000000..4107e39 --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/uni_modules/uni-popup/components/uni-popup/uni-popup.wxss @@ -0,0 +1,24 @@ +/* 水平间距 */ +/* 水平间距 */ +.uni-popup { + position: fixed; + z-index: 99; +} +.uni-popup.top, .uni-popup.left, .uni-popup.right { + top: 0; +} +.uni-popup .uni-popup__wrapper { + display: block; + position: relative; + /* iphonex 等安全区设置,底部安全区适配 */ +} +.uni-popup .uni-popup__wrapper.left, .uni-popup .uni-popup__wrapper.right { + padding-top: 0; + flex: 1; +} +.fixforpc-z-index { + z-index: 999; +} +.fixforpc-top { + top: 0; +} \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/uni_modules/uni-transition/components/uni-transition/createAnimation.js b/unpackage/dist/dev/mp-weixin/uni_modules/uni-transition/components/uni-transition/createAnimation.js new file mode 100644 index 0000000..819683a --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/uni_modules/uni-transition/components/uni-transition/createAnimation.js @@ -0,0 +1,115 @@ +"use strict"; +const common_vendor = require("../../../../common/vendor.js"); +class MPAnimation { + constructor(options, _this) { + this.options = options; + this.animation = common_vendor.index.createAnimation({ + ...options + }); + this.currentStepAnimates = {}; + this.next = 0; + this.$ = _this; + } + _nvuePushAnimates(type, args) { + let aniObj = this.currentStepAnimates[this.next]; + let styles = {}; + if (!aniObj) { + styles = { + styles: {}, + config: {} + }; + } else { + styles = aniObj; + } + if (animateTypes1.includes(type)) { + if (!styles.styles.transform) { + styles.styles.transform = ""; + } + let unit = ""; + if (type === "rotate") { + unit = "deg"; + } + styles.styles.transform += `${type}(${args + unit}) `; + } else { + styles.styles[type] = `${args}`; + } + this.currentStepAnimates[this.next] = styles; + } + _animateRun(styles = {}, config = {}) { + let ref = this.$.$refs["ani"].ref; + if (!ref) + return; + return new Promise((resolve, reject) => { + nvueAnimation.transition(ref, { + styles, + ...config + }, (res) => { + resolve(); + }); + }); + } + _nvueNextAnimate(animates, step = 0, fn) { + let obj = animates[step]; + if (obj) { + let { + styles, + config + } = obj; + this._animateRun(styles, config).then(() => { + step += 1; + this._nvueNextAnimate(animates, step, fn); + }); + } else { + this.currentStepAnimates = {}; + typeof fn === "function" && fn(); + this.isEnd = true; + } + } + step(config = {}) { + this.animation.step(config); + return this; + } + run(fn) { + this.$.animationData = this.animation.export(); + this.$.timer = setTimeout(() => { + typeof fn === "function" && fn(); + }, this.$.durationTime); + } +} +const animateTypes1 = [ + "matrix", + "matrix3d", + "rotate", + "rotate3d", + "rotateX", + "rotateY", + "rotateZ", + "scale", + "scale3d", + "scaleX", + "scaleY", + "scaleZ", + "skew", + "skewX", + "skewY", + "translate", + "translate3d", + "translateX", + "translateY", + "translateZ" +]; +const animateTypes2 = ["opacity", "backgroundColor"]; +const animateTypes3 = ["width", "height", "left", "right", "top", "bottom"]; +animateTypes1.concat(animateTypes2, animateTypes3).forEach((type) => { + MPAnimation.prototype[type] = function(...args) { + this.animation[type](...args); + return this; + }; +}); +function createAnimation(option, _this) { + if (!_this) + return; + clearTimeout(_this.timer); + return new MPAnimation(option, _this); +} +exports.createAnimation = createAnimation; diff --git a/unpackage/dist/dev/mp-weixin/uni_modules/uni-transition/components/uni-transition/uni-transition.js b/unpackage/dist/dev/mp-weixin/uni_modules/uni-transition/components/uni-transition/uni-transition.js new file mode 100644 index 0000000..cc27c04 --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/uni_modules/uni-transition/components/uni-transition/uni-transition.js @@ -0,0 +1,265 @@ +"use strict"; +const uni_modules_uniTransition_components_uniTransition_createAnimation = require("./createAnimation.js"); +const common_vendor = require("../../../../common/vendor.js"); +const _sfc_main = { + name: "uniTransition", + emits: ["click", "change"], + props: { + show: { + type: Boolean, + default: false + }, + modeClass: { + type: [Array, String], + default() { + return "fade"; + } + }, + duration: { + type: Number, + default: 300 + }, + styles: { + type: Object, + default() { + return {}; + } + }, + customClass: { + type: String, + default: "" + }, + onceRender: { + type: Boolean, + default: false + } + }, + data() { + return { + isShow: false, + transform: "", + opacity: 1, + animationData: {}, + durationTime: 300, + config: {} + }; + }, + watch: { + show: { + handler(newVal) { + if (newVal) { + this.open(); + } else { + if (this.isShow) { + this.close(); + } + } + }, + immediate: true + } + }, + computed: { + // 生成样式数据 + stylesObject() { + let styles = { + ...this.styles, + "transition-duration": this.duration / 1e3 + "s" + }; + let transform = ""; + for (let i in styles) { + let line = this.toLine(i); + transform += line + ":" + styles[i] + ";"; + } + return transform; + }, + // 初始化动画条件 + transformStyles() { + return "transform:" + this.transform + ";opacity:" + this.opacity + ";" + this.stylesObject; + } + }, + created() { + this.config = { + duration: this.duration, + timingFunction: "ease", + transformOrigin: "50% 50%", + delay: 0 + }; + this.durationTime = this.duration; + }, + methods: { + /** + * ref 触发 初始化动画 + */ + init(obj = {}) { + if (obj.duration) { + this.durationTime = obj.duration; + } + this.animation = uni_modules_uniTransition_components_uniTransition_createAnimation.createAnimation(Object.assign(this.config, obj), this); + }, + /** + * 点击组件触发回调 + */ + onClick() { + this.$emit("click", { + detail: this.isShow + }); + }, + /** + * ref 触发 动画分组 + * @param {Object} obj + */ + step(obj, config = {}) { + if (!this.animation) + return; + for (let i in obj) { + try { + if (typeof obj[i] === "object") { + this.animation[i](...obj[i]); + } else { + this.animation[i](obj[i]); + } + } catch (e) { + console.error(`方法 ${i} 不存在`); + } + } + this.animation.step(config); + return this; + }, + /** + * ref 触发 执行动画 + */ + run(fn) { + if (!this.animation) + return; + this.animation.run(fn); + }, + // 开始过度动画 + open() { + clearTimeout(this.timer); + this.transform = ""; + this.isShow = true; + let { opacity, transform } = this.styleInit(false); + if (typeof opacity !== "undefined") { + this.opacity = opacity; + } + this.transform = transform; + this.$nextTick(() => { + this.timer = setTimeout(() => { + this.animation = uni_modules_uniTransition_components_uniTransition_createAnimation.createAnimation(this.config, this); + this.tranfromInit(false).step(); + this.animation.run(); + this.$emit("change", { + detail: this.isShow + }); + }, 20); + }); + }, + // 关闭过度动画 + close(type) { + if (!this.animation) + return; + this.tranfromInit(true).step().run(() => { + this.isShow = false; + this.animationData = null; + this.animation = null; + let { opacity, transform } = this.styleInit(false); + this.opacity = opacity || 1; + this.transform = transform; + this.$emit("change", { + detail: this.isShow + }); + }); + }, + // 处理动画开始前的默认样式 + styleInit(type) { + let styles = { + transform: "" + }; + let buildStyle = (type2, mode) => { + if (mode === "fade") { + styles.opacity = this.animationType(type2)[mode]; + } else { + styles.transform += this.animationType(type2)[mode] + " "; + } + }; + if (typeof this.modeClass === "string") { + buildStyle(type, this.modeClass); + } else { + this.modeClass.forEach((mode) => { + buildStyle(type, mode); + }); + } + return styles; + }, + // 处理内置组合动画 + tranfromInit(type) { + let buildTranfrom = (type2, mode) => { + let aniNum = null; + if (mode === "fade") { + aniNum = type2 ? 0 : 1; + } else { + aniNum = type2 ? "-100%" : "0"; + if (mode === "zoom-in") { + aniNum = type2 ? 0.8 : 1; + } + if (mode === "zoom-out") { + aniNum = type2 ? 1.2 : 1; + } + if (mode === "slide-right") { + aniNum = type2 ? "100%" : "0"; + } + if (mode === "slide-bottom") { + aniNum = type2 ? "100%" : "0"; + } + } + this.animation[this.animationMode()[mode]](aniNum); + }; + if (typeof this.modeClass === "string") { + buildTranfrom(type, this.modeClass); + } else { + this.modeClass.forEach((mode) => { + buildTranfrom(type, mode); + }); + } + return this.animation; + }, + animationType(type) { + return { + fade: type ? 0 : 1, + "slide-top": `translateY(${type ? "0" : "-100%"})`, + "slide-right": `translateX(${type ? "0" : "100%"})`, + "slide-bottom": `translateY(${type ? "0" : "100%"})`, + "slide-left": `translateX(${type ? "0" : "-100%"})`, + "zoom-in": `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`, + "zoom-out": `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})` + }; + }, + // 内置动画类型与实际动画对应字典 + animationMode() { + return { + fade: "opacity", + "slide-top": "translateY", + "slide-right": "translateX", + "slide-bottom": "translateY", + "slide-left": "translateX", + "zoom-in": "scale", + "zoom-out": "scale" + }; + }, + // 驼峰转中横线 + toLine(name) { + return name.replace(/([A-Z])/g, "-$1").toLowerCase(); + } + } +}; +function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { + return { + a: $data.isShow, + b: $data.animationData, + c: common_vendor.n($props.customClass), + d: common_vendor.s($options.transformStyles), + e: common_vendor.o((...args) => $options.onClick && $options.onClick(...args)) + }; +} +const Component = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]); +wx.createComponent(Component); diff --git a/unpackage/dist/dev/mp-weixin/uni_modules/uni-transition/components/uni-transition/uni-transition.json b/unpackage/dist/dev/mp-weixin/uni_modules/uni-transition/components/uni-transition/uni-transition.json new file mode 100644 index 0000000..e8cfaaf --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/uni_modules/uni-transition/components/uni-transition/uni-transition.json @@ -0,0 +1,4 @@ +{ + "component": true, + "usingComponents": {} +} \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/uni_modules/uni-transition/components/uni-transition/uni-transition.wxml b/unpackage/dist/dev/mp-weixin/uni_modules/uni-transition/components/uni-transition/uni-transition.wxml new file mode 100644 index 0000000..8fa2f75 --- /dev/null +++ b/unpackage/dist/dev/mp-weixin/uni_modules/uni-transition/components/uni-transition/uni-transition.wxml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/unpackage/dist/dev/mp-weixin/uni_modules/uni-transition/components/uni-transition/uni-transition.wxss b/unpackage/dist/dev/mp-weixin/uni_modules/uni-transition/components/uni-transition/uni-transition.wxss new file mode 100644 index 0000000..e69de29

+ +
+
npm +