@astralweb/nova-recently-viewed 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/README.md +311 -0
- package/dist/api/extendMiddleware.d.ts +16 -0
- package/dist/api/extendMiddleware.d.ts.map +1 -0
- package/dist/api/index.d.ts +4 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/queryFields.d.ts +3 -0
- package/dist/api/queryFields.d.ts.map +1 -0
- package/dist/api/web.d.ts +27 -0
- package/dist/api/web.d.ts.map +1 -0
- package/dist/api.cjs +46 -0
- package/dist/api.js +2201 -0
- package/dist/chunks/useRecentlyViewed-BMqCM4G9.js +1 -0
- package/dist/chunks/useRecentlyViewed-DmIwibiG.js +96 -0
- package/dist/chunks/web-DMlcd6E0.js +1 -0
- package/dist/chunks/web-WoqqfD6L.js +26 -0
- package/dist/composables/index.d.ts +2 -0
- package/dist/composables/index.d.ts.map +1 -0
- package/dist/composables/useRecentlyViewed.d.ts +7 -0
- package/dist/composables/useRecentlyViewed.d.ts.map +1 -0
- package/dist/composables.cjs +1 -0
- package/dist/composables.js +4 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/types/api.d.ts +9 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/composables.d.ts +19 -0
- package/dist/types/composables.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types.cjs +1 -0
- package/dist/types.js +1 -0
- package/package.json +95 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const E=require("vue"),u=require("./web-DMlcd6E0.js"),l={GUEST:"recently_viewed_products_guest",CUSTOMER:"recently_viewed_products_customer"},v={MAX_ITEMS:20},w={JS_TO_SERVER_DIVISOR:1e3,SERVER_TO_JS_MULTIPLIER:1e3},R={maxItems:v.MAX_ITEMS,guestStorageKey:l.GUEST,customerStorageKey:l.CUSTOMER,enableServerSync:!0};function I(g={},n){const s={...R,...g},a=E.computed(()=>n.value?s.customerStorageKey:s.guestStorageKey),c=()=>typeof window<"u"&&typeof localStorage<"u",S=e=>Math.floor(e/w.JS_TO_SERVER_DIVISOR),_=e=>e*w.SERVER_TO_JS_MULTIPLIER,i=e=>{if(!c())return[];try{const r=localStorage.getItem(e),t=JSON.parse(r??"[]");return Array.isArray(t)?t:[]}catch{return[]}},d=(e,r)=>{c()&&localStorage.setItem(e,JSON.stringify(r))},m=e=>{const r=new Set;return e.filter(t=>!t?.sku||typeof t.sku!="string"||r.has(t.sku)?!1:(r.add(t.sku),!0)).sort((t,o)=>o.viewedAt-t.viewedAt).slice(0,s.maxItems)},y=e=>{const t=i(a.value).filter(o=>o.sku!==e);t.push({sku:e,viewedAt:Date.now()}),d(a.value,m(t))},f=e=>{const r=i(a.value);return m(r).map(o=>o.sku).filter(o=>o&&o!==e)};return{addRecentlyViewed:async e=>{if(!(!e||typeof e!="string"))if(n.value&&s.enableServerSync)try{await u.addRecentlyViewedWeb([{product_sku:e,viewed_at:S(Date.now())}])}catch(r){throw y(e),new Error(`Failed to sync to server: ${r instanceof Error?r.message:String(r)}`)}else y(e)},getRecentlyViewedSkus:async e=>{if(n.value&&s.enableServerSync)try{const r=await u.fetchRecentlyViewedWeb();if(r&&r.length>0){const t=r.map(o=>({sku:o.product_sku,viewedAt:_(o.viewed_at)}));return d(a.value,t),r.map(o=>o.product_sku).filter(o=>o&&o!==e).slice(0,s.maxItems)}}catch{return f(e)}return f(e)},clearAllRecentlyViewed:()=>{c()&&(localStorage.removeItem(l.GUEST),localStorage.removeItem(l.CUSTOMER))},mergeGuestToCustomer:async()=>{if(!n.value||!s.enableServerSync)return;const e=i(s.guestStorageKey);if(e.length===0)return;const r=e.filter(t=>t?.sku).slice(0,s.maxItems).map(t=>({product_sku:t.sku,viewed_at:S(t.viewedAt)}));if(c()&&localStorage.removeItem(s.guestStorageKey),r.length>0)try{await u.addRecentlyViewedWeb(r)}catch(t){throw new Error(`Failed to backfill guest data: ${t instanceof Error?t.message:String(t)}`)}},isLoggedIn:n}}exports.useRecentlyViewed=I;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { computed as E } from "vue";
|
|
2
|
+
import { a as y, f as v } from "./web-WoqqfD6L.js";
|
|
3
|
+
const l = {
|
|
4
|
+
GUEST: "recently_viewed_products_guest",
|
|
5
|
+
CUSTOMER: "recently_viewed_products_customer"
|
|
6
|
+
}, R = {
|
|
7
|
+
MAX_ITEMS: 20
|
|
8
|
+
}, w = {
|
|
9
|
+
JS_TO_SERVER_DIVISOR: 1e3,
|
|
10
|
+
// JavaScript timestamp 轉 Unix timestamp
|
|
11
|
+
SERVER_TO_JS_MULTIPLIER: 1e3
|
|
12
|
+
// Unix timestamp 轉 JavaScript timestamp
|
|
13
|
+
}, p = {
|
|
14
|
+
maxItems: R.MAX_ITEMS,
|
|
15
|
+
guestStorageKey: l.GUEST,
|
|
16
|
+
customerStorageKey: l.CUSTOMER,
|
|
17
|
+
enableServerSync: !0
|
|
18
|
+
};
|
|
19
|
+
function M(g = {}, a) {
|
|
20
|
+
const s = { ...p, ...g }, n = E(() => a.value ? s.customerStorageKey : s.guestStorageKey), c = () => typeof window < "u" && typeof localStorage < "u", u = (e) => Math.floor(e / w.JS_TO_SERVER_DIVISOR), _ = (e) => e * w.SERVER_TO_JS_MULTIPLIER, i = (e) => {
|
|
21
|
+
if (!c()) return [];
|
|
22
|
+
try {
|
|
23
|
+
const r = localStorage.getItem(e), t = JSON.parse(r ?? "[]");
|
|
24
|
+
return Array.isArray(t) ? t : [];
|
|
25
|
+
} catch {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
}, S = (e, r) => {
|
|
29
|
+
c() && localStorage.setItem(e, JSON.stringify(r));
|
|
30
|
+
}, d = (e) => {
|
|
31
|
+
const r = /* @__PURE__ */ new Set();
|
|
32
|
+
return e.filter((t) => !t?.sku || typeof t.sku != "string" || r.has(t.sku) ? !1 : (r.add(t.sku), !0)).sort((t, o) => o.viewedAt - t.viewedAt).slice(0, s.maxItems);
|
|
33
|
+
}, m = (e) => {
|
|
34
|
+
const t = i(n.value).filter((o) => o.sku !== e);
|
|
35
|
+
t.push({ sku: e, viewedAt: Date.now() }), S(n.value, d(t));
|
|
36
|
+
}, f = (e) => {
|
|
37
|
+
const r = i(n.value);
|
|
38
|
+
return d(r).map((o) => o.sku).filter((o) => o && o !== e);
|
|
39
|
+
};
|
|
40
|
+
return {
|
|
41
|
+
addRecentlyViewed: async (e) => {
|
|
42
|
+
if (!(!e || typeof e != "string"))
|
|
43
|
+
if (a.value && s.enableServerSync)
|
|
44
|
+
try {
|
|
45
|
+
await y([
|
|
46
|
+
{
|
|
47
|
+
product_sku: e,
|
|
48
|
+
viewed_at: u(Date.now())
|
|
49
|
+
}
|
|
50
|
+
]);
|
|
51
|
+
} catch (r) {
|
|
52
|
+
throw m(e), new Error(`Failed to sync to server: ${r instanceof Error ? r.message : String(r)}`);
|
|
53
|
+
}
|
|
54
|
+
else
|
|
55
|
+
m(e);
|
|
56
|
+
},
|
|
57
|
+
getRecentlyViewedSkus: async (e) => {
|
|
58
|
+
if (a.value && s.enableServerSync)
|
|
59
|
+
try {
|
|
60
|
+
const r = await v();
|
|
61
|
+
if (r && r.length > 0) {
|
|
62
|
+
const t = r.map((o) => ({
|
|
63
|
+
sku: o.product_sku,
|
|
64
|
+
viewedAt: _(o.viewed_at)
|
|
65
|
+
}));
|
|
66
|
+
return S(n.value, t), r.map((o) => o.product_sku).filter((o) => o && o !== e).slice(0, s.maxItems);
|
|
67
|
+
}
|
|
68
|
+
} catch {
|
|
69
|
+
return f(e);
|
|
70
|
+
}
|
|
71
|
+
return f(e);
|
|
72
|
+
},
|
|
73
|
+
clearAllRecentlyViewed: () => {
|
|
74
|
+
c() && (localStorage.removeItem(l.GUEST), localStorage.removeItem(l.CUSTOMER));
|
|
75
|
+
},
|
|
76
|
+
mergeGuestToCustomer: async () => {
|
|
77
|
+
if (!a.value || !s.enableServerSync) return;
|
|
78
|
+
const e = i(s.guestStorageKey);
|
|
79
|
+
if (e.length === 0) return;
|
|
80
|
+
const r = e.filter((t) => t?.sku).slice(0, s.maxItems).map((t) => ({
|
|
81
|
+
product_sku: t.sku,
|
|
82
|
+
viewed_at: u(t.viewedAt)
|
|
83
|
+
}));
|
|
84
|
+
if (c() && localStorage.removeItem(s.guestStorageKey), r.length > 0)
|
|
85
|
+
try {
|
|
86
|
+
await y(r);
|
|
87
|
+
} catch (t) {
|
|
88
|
+
throw new Error(`Failed to backfill guest data: ${t instanceof Error ? t.message : String(t)}`);
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
isLoggedIn: a
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export {
|
|
95
|
+
M as u
|
|
96
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";let r=null;function c(e){r=e}function d(){if(!r)throw new Error("SDK not found. Please use setSdk() to set the SDK instance.");return r}const o=async()=>{const{data:e,errors:t}=await d().magento.recentlyViewedProducts({});if(t&&t.length>0)throw new Error(t.map(n=>n.message).join(", "));return e?.recentlyViewedProducts??[]},a=async e=>{const{data:t,errors:n}=await d().magento.addRecentlyViewedProducts({input:e});if(n&&n.length>0)throw new Error(n.map(s=>s.message).join(", "));return t?.addRecentlyViewedProducts??{success:!0}};exports.addRecentlyViewedWeb=a;exports.fetchRecentlyViewedWeb=o;exports.getSdk=d;exports.setSdk=c;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
let r = null;
|
|
2
|
+
function o(e) {
|
|
3
|
+
r = e;
|
|
4
|
+
}
|
|
5
|
+
function s() {
|
|
6
|
+
if (!r)
|
|
7
|
+
throw new Error("SDK not found. Please use setSdk() to set the SDK instance.");
|
|
8
|
+
return r;
|
|
9
|
+
}
|
|
10
|
+
const c = async () => {
|
|
11
|
+
const { data: e, errors: t } = await s().magento.recentlyViewedProducts({});
|
|
12
|
+
if (t && t.length > 0)
|
|
13
|
+
throw new Error(t.map((n) => n.message).join(", "));
|
|
14
|
+
return e?.recentlyViewedProducts ?? [];
|
|
15
|
+
}, d = async (e) => {
|
|
16
|
+
const { data: t, errors: n } = await s().magento.addRecentlyViewedProducts({ input: e });
|
|
17
|
+
if (n && n.length > 0)
|
|
18
|
+
throw new Error(n.map((a) => a.message).join(", "));
|
|
19
|
+
return t?.addRecentlyViewedProducts ?? { success: !0 };
|
|
20
|
+
};
|
|
21
|
+
export {
|
|
22
|
+
d as a,
|
|
23
|
+
c as f,
|
|
24
|
+
s as g,
|
|
25
|
+
o as s
|
|
26
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/composables/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ComputedRef } from 'vue';
|
|
2
|
+
import { RecentlyViewedConfig, UseRecentlyViewedReturn } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* 管理最近瀏覽商品的本地儲存和後端同步
|
|
5
|
+
*/
|
|
6
|
+
export declare function useRecentlyViewed(config: RecentlyViewedConfig | undefined, isLoggedIn: ComputedRef<boolean>): UseRecentlyViewedReturn;
|
|
7
|
+
//# sourceMappingURL=useRecentlyViewed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRecentlyViewed.d.ts","sourceRoot":"","sources":["../../src/composables/useRecentlyViewed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,KAAK,CAAC;AAEjD,OAAO,KAAK,EAEV,oBAAoB,EACpB,uBAAuB,EAExB,MAAM,UAAU,CAAC;AA2BlB;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,oBAAoB,YAAK,EACjC,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,GAC/B,uBAAuB,CAgMzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./chunks/useRecentlyViewed-BMqCM4G9.js");exports.useRecentlyViewed=e.useRecentlyViewed;
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./chunks/useRecentlyViewed-BMqCM4G9.js"),e=require("./api.cjs"),d=require("./chunks/web-DMlcd6E0.js");exports.useRecentlyViewed=t.useRecentlyViewed;exports.addRecentlyViewedProducts=e.addRecentlyViewedProducts;exports.addRecentlyViewedProductsFields=e.addRecentlyViewedProductsFields;exports.recentlyViewedProducts=e.recentlyViewedProducts;exports.recentlyViewedProductsFields=e.recentlyViewedProductsFields;exports.addRecentlyViewedWeb=d.addRecentlyViewedWeb;exports.fetchRecentlyViewedWeb=d.fetchRecentlyViewedWeb;exports.getSdk=d.getSdk;exports.setSdk=d.setSdk;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,OAAO,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { u as t } from "./chunks/useRecentlyViewed-DmIwibiG.js";
|
|
2
|
+
import { addRecentlyViewedProducts as c, addRecentlyViewedProductsFields as r, recentlyViewedProducts as o, recentlyViewedProductsFields as a } from "./api.js";
|
|
3
|
+
import { a as l, f as n, g as w, s as y } from "./chunks/web-WoqqfD6L.js";
|
|
4
|
+
export {
|
|
5
|
+
c as addRecentlyViewedProducts,
|
|
6
|
+
r as addRecentlyViewedProductsFields,
|
|
7
|
+
l as addRecentlyViewedWeb,
|
|
8
|
+
n as fetchRecentlyViewedWeb,
|
|
9
|
+
w as getSdk,
|
|
10
|
+
o as recentlyViewedProducts,
|
|
11
|
+
a as recentlyViewedProductsFields,
|
|
12
|
+
y as setSdk,
|
|
13
|
+
t as useRecentlyViewed
|
|
14
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/types/api.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ComputedRef } from 'vue';
|
|
2
|
+
export interface RecentlyViewedItem {
|
|
3
|
+
sku: string;
|
|
4
|
+
viewedAt: number;
|
|
5
|
+
}
|
|
6
|
+
export interface RecentlyViewedConfig {
|
|
7
|
+
maxItems?: number;
|
|
8
|
+
guestStorageKey?: string;
|
|
9
|
+
customerStorageKey?: string;
|
|
10
|
+
enableServerSync?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface UseRecentlyViewedReturn {
|
|
13
|
+
addRecentlyViewed: (sku: string) => Promise<void>;
|
|
14
|
+
getRecentlyViewedSkus: (excludeSku?: string) => Promise<string[]>;
|
|
15
|
+
clearAllRecentlyViewed: () => void;
|
|
16
|
+
mergeGuestToCustomer: () => Promise<void>;
|
|
17
|
+
isLoggedIn: ComputedRef<boolean>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=composables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composables.d.ts","sourceRoot":"","sources":["../../src/types/composables.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,KAAK,CAAC;AAEvC,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,uBAAuB;IACtC,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,qBAAqB,EAAE,CAAC,UAAU,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAClE,sBAAsB,EAAE,MAAM,IAAI,CAAC;IACnC,oBAAoB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;CAClC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,OAAO,CAAC"}
|
package/dist/types.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@astralweb/nova-recently-viewed",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Recently Viewed module for Nova e-commerce platform - (Internal Use Only)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.cjs",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./api": {
|
|
16
|
+
"types": "./dist/api/index.d.ts",
|
|
17
|
+
"import": "./dist/api.js",
|
|
18
|
+
"require": "./dist/api.cjs"
|
|
19
|
+
},
|
|
20
|
+
"./types": {
|
|
21
|
+
"types": "./dist/types/index.d.ts",
|
|
22
|
+
"import": "./dist/types.js",
|
|
23
|
+
"require": "./dist/types.cjs"
|
|
24
|
+
},
|
|
25
|
+
"./composables": {
|
|
26
|
+
"types": "./dist/composables/index.d.ts",
|
|
27
|
+
"import": "./dist/composables.js",
|
|
28
|
+
"require": "./dist/composables.cjs"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist"
|
|
33
|
+
],
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"vue": "^3.5.18",
|
|
36
|
+
"nuxt": "^3.12.4",
|
|
37
|
+
"tailwindcss": "^3.4.17"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@astralweb/eslint-config": "^1.0.0",
|
|
41
|
+
"@astralweb/nova-magento-types": "^1.3.1",
|
|
42
|
+
"@types/node": "^22.13.10",
|
|
43
|
+
"@vitejs/plugin-vue": "^6.0.1",
|
|
44
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
45
|
+
"@vue/test-utils": "^2.4.6",
|
|
46
|
+
"eslint": "^9.22.0",
|
|
47
|
+
"happy-dom": "^20.0.2",
|
|
48
|
+
"sass-embedded": "^1.90.0",
|
|
49
|
+
"stylelint": "^16.23.1",
|
|
50
|
+
"terser": "^5.43.1",
|
|
51
|
+
"tsup": "^8.0.0",
|
|
52
|
+
"typescript": "^5.8.2",
|
|
53
|
+
"vite": "^7.1.1",
|
|
54
|
+
"vite-plugin-css-injected-by-js": "^3.5.2",
|
|
55
|
+
"vite-plugin-dts": "^4.3.0",
|
|
56
|
+
"vitest": "^3.0.9",
|
|
57
|
+
"vue-tsc": "^2.2.12"
|
|
58
|
+
},
|
|
59
|
+
"publishConfig": {
|
|
60
|
+
"access": "public"
|
|
61
|
+
},
|
|
62
|
+
"repository": {
|
|
63
|
+
"type": "git",
|
|
64
|
+
"url": "https://github.com/AstralWebTW/nova-packages",
|
|
65
|
+
"directory": "packages/recently-viewed"
|
|
66
|
+
},
|
|
67
|
+
"keywords": [
|
|
68
|
+
"recently-viewed",
|
|
69
|
+
"nova",
|
|
70
|
+
"vue",
|
|
71
|
+
"nuxt"
|
|
72
|
+
],
|
|
73
|
+
"author": "Astral Web",
|
|
74
|
+
"license": "Proprietary",
|
|
75
|
+
"homepage": "https://github.com/AstralWebTW/nova-packages/tree/main/packages/recently-viewed",
|
|
76
|
+
"engines": {
|
|
77
|
+
"node": ">=20.0.0",
|
|
78
|
+
"pnpm": ">=10.0.0"
|
|
79
|
+
},
|
|
80
|
+
"scripts": {
|
|
81
|
+
"build": "vite build",
|
|
82
|
+
"dev": "vite build --watch",
|
|
83
|
+
"typecheck": "tsc --noEmit",
|
|
84
|
+
"typecheck:watch": "tsc --noEmit --watch",
|
|
85
|
+
"lint": "eslint src/",
|
|
86
|
+
"lint:fix": "eslint src/ --fix",
|
|
87
|
+
"lint:types": "tsc --noEmit && eslint .",
|
|
88
|
+
"test": "vitest run",
|
|
89
|
+
"test:watch": "vitest",
|
|
90
|
+
"test:ui": "vitest --ui",
|
|
91
|
+
"test:coverage": "vitest run --coverage",
|
|
92
|
+
"test:typecheck": "vitest typecheck",
|
|
93
|
+
"ci": "pnpm typecheck && pnpm lint && pnpm test && pnpm build"
|
|
94
|
+
}
|
|
95
|
+
}
|