From 740731ff99cdc7c683883fc19773f4f8a70122d1 Mon Sep 17 00:00:00 2001 From: MZ-Dlovely <591562538@qq.com> Date: Tue, 15 Aug 2023 14:15:34 +0800 Subject: [PATCH] =?UTF-8?q?feat=E2=9C=A8:=20allow=20to=20change=20and=20pe?= =?UTF-8?q?rsist=20cookie=20before=20nuxt=20init?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 3 +++ packages/nuxt/playground/app.vue | 5 +++++ .../nuxt/playground/composables/presetCookie.ts | 17 +++++++++++++++++ .../middleware/change-cookie.global.ts | 11 +++++++++++ packages/nuxt/src/constant.ts | 7 +++++++ packages/nuxt/src/module.ts | 8 +++++++- packages/nuxt/src/runtime/persist-cookie.ts | 12 ++++++++++++ packages/nuxt/src/server/plugin.ts | 11 +++++++++++ packages/nuxt/src/server/tsconfig.json | 4 ++++ packages/nuxt/tsconfig.json | 3 ++- packages/plugin/src/index.ts | 2 ++ packages/plugin/src/pick.ts | 7 ++----- 12 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 packages/nuxt/playground/composables/presetCookie.ts create mode 100644 packages/nuxt/playground/middleware/change-cookie.global.ts create mode 100644 packages/nuxt/src/constant.ts create mode 100644 packages/nuxt/src/runtime/persist-cookie.ts create mode 100644 packages/nuxt/src/server/plugin.ts create mode 100644 packages/nuxt/src/server/tsconfig.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..44aeb40 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "typescript.tsdk": "node_modules\\typescript\\lib" +} diff --git a/packages/nuxt/playground/app.vue b/packages/nuxt/playground/app.vue index f4f0f79..1d8ddb0 100644 --- a/packages/nuxt/playground/app.vue +++ b/packages/nuxt/playground/app.vue @@ -1,6 +1,7 @@ diff --git a/packages/nuxt/playground/composables/presetCookie.ts b/packages/nuxt/playground/composables/presetCookie.ts new file mode 100644 index 0000000..5ec572f --- /dev/null +++ b/packages/nuxt/playground/composables/presetCookie.ts @@ -0,0 +1,17 @@ +import { defineStore } from 'pinia' + +export const usePresetCookie = defineStore('preset-cookie', { + state: () => ({ + access_token: 0, + refresh_token: 0, + }), + actions: { + setToken(token?: number) { + this.access_token = token ?? this.access_token + 1 + this.refresh_token = token ?? this.refresh_token + 1 + }, + }, + persist: { + storage: persistedState.cookies, + }, +}) diff --git a/packages/nuxt/playground/middleware/change-cookie.global.ts b/packages/nuxt/playground/middleware/change-cookie.global.ts new file mode 100644 index 0000000..61ce199 --- /dev/null +++ b/packages/nuxt/playground/middleware/change-cookie.global.ts @@ -0,0 +1,11 @@ +/* eslint-disable no-console */ +/* eslint-disable n/prefer-global/process */ +export default defineNuxtRouteMiddleware(() => { + if (process.client) + return + const preset_cookie = usePresetCookie() + console.log(toRaw(preset_cookie.$state)) + preset_cookie.setToken() + console.log(toRaw(preset_cookie.$state)) + persistCookie(preset_cookie, ['access_token']) +}) diff --git a/packages/nuxt/src/constant.ts b/packages/nuxt/src/constant.ts new file mode 100644 index 0000000..512e145 --- /dev/null +++ b/packages/nuxt/src/constant.ts @@ -0,0 +1,7 @@ +export const persisted_state = '__persisted-state' + +declare module 'h3' { + interface H3EventContext { + [persisted_state]?: Record + } +} diff --git a/packages/nuxt/src/module.ts b/packages/nuxt/src/module.ts index c1fd6f5..a5923c3 100644 --- a/packages/nuxt/src/module.ts +++ b/packages/nuxt/src/module.ts @@ -1,4 +1,4 @@ -import { addImports, addPlugin, createResolver, defineNuxtModule } from '@nuxt/kit' +import { addImports, addPlugin, addServerPlugin, createResolver, defineNuxtModule } from '@nuxt/kit' import { type CookieOptions } from 'nuxt/app' import { type NuxtModule } from 'nuxt/schema' import { defu } from 'defu' @@ -36,9 +36,15 @@ export default defineNuxtModule({ from: resolve('./runtime/storages'), }) + addImports({ + name: 'persistCookie', + from: resolve('./runtime/persist-cookie'), + }) + // provides plugin nuxt.hook('modules:done', () => { addPlugin(resolve('./runtime/plugin'), { append: true }) + addServerPlugin(resolve('./server/plugin')) }) }, }) satisfies NuxtModule diff --git a/packages/nuxt/src/runtime/persist-cookie.ts b/packages/nuxt/src/runtime/persist-cookie.ts new file mode 100644 index 0000000..0363588 --- /dev/null +++ b/packages/nuxt/src/runtime/persist-cookie.ts @@ -0,0 +1,12 @@ +import type { Store } from 'pinia' +import { pick } from 'pinia-plugin-persistedstate' +import { persisted_state } from '../constant' +import { useRequestEvent } from '#imports' + +export function persistCookie(store: Store, path?: string[]) { + const event = useRequestEvent() + if (event) { + const cookies = event.context[persisted_state] ??= {} + cookies[store.$id] = path ? pick(store.$state, path) : store.$state + } +} diff --git a/packages/nuxt/src/server/plugin.ts b/packages/nuxt/src/server/plugin.ts new file mode 100644 index 0000000..9d586c7 --- /dev/null +++ b/packages/nuxt/src/server/plugin.ts @@ -0,0 +1,11 @@ +import { persisted_state } from '../constant' +import { defineNitroPlugin } from '#imports' + +export default defineNitroPlugin((nitroApp) => { + nitroApp.hooks.hook('render:response', (_, { event }) => { + const cookies = event.context[persisted_state] ?? {} + const id_list = Object.keys(cookies) + for (const id of id_list) + setCookie(event, id, JSON.stringify(cookies[id])) + }) +}) diff --git a/packages/nuxt/src/server/tsconfig.json b/packages/nuxt/src/server/tsconfig.json new file mode 100644 index 0000000..ed758a4 --- /dev/null +++ b/packages/nuxt/src/server/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../playground/.nuxt/tsconfig.server.json", + "include": ["./", "../runtime/persist-cookie.ts"] +} diff --git a/packages/nuxt/tsconfig.json b/packages/nuxt/tsconfig.json index d86c5f9..edd6045 100644 --- a/packages/nuxt/tsconfig.json +++ b/packages/nuxt/tsconfig.json @@ -1,4 +1,5 @@ { "extends": "./playground/.nuxt/tsconfig.json", - "include": ["./src"] + "include": ["./src"], + "exclude": ["./src/server"] } diff --git a/packages/plugin/src/index.ts b/packages/plugin/src/index.ts index 3a05638..58d8e24 100644 --- a/packages/plugin/src/index.ts +++ b/packages/plugin/src/index.ts @@ -1,5 +1,7 @@ import { createPersistedState } from './plugin' +export { pick } from './pick' + export { type PersistedStateOptions, type PersistedStateFactoryOptions, diff --git a/packages/plugin/src/pick.ts b/packages/plugin/src/pick.ts index d513204..b10ba59 100644 --- a/packages/plugin/src/pick.ts +++ b/packages/plugin/src/pick.ts @@ -6,13 +6,10 @@ function get(state: StateTree, path: Array): unknown { }, state) } +const ProtoRE = /^(__proto__)$/ function set(state: StateTree, path: Array, val: unknown): StateTree { return ( - (path.slice(0, -1).reduce((obj, p) => { - if (/^(__proto__)$/.test(p)) - return {} - else return (obj[p] = obj[p] || {}) - }, state)[path[path.length - 1]] = val), + (path.slice(0, -1).reduce((obj, p) => ProtoRE.test(p) ? {} : (obj[p] ||= {}), state)[path.at(-1)!] = val), state ) }