@miroart/sdk 0.1.0
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 +40 -0
- package/README.md +17 -0
- package/dist/asset.d.ts +29 -0
- package/dist/bag.d.ts +6 -0
- package/dist/composables.d.ts +16 -0
- package/dist/context.d.ts +11 -0
- package/dist/decode.d.ts +4 -0
- package/dist/http.d.ts +7 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +1 -0
- package/dist/install.d.ts +9 -0
- package/dist/menu.d.ts +24 -0
- package/dist/page.d.ts +43 -0
- package/dist/paths.d.ts +14 -0
- package/dist/plugin.d.ts +16 -0
- package/dist/runtime.d.ts +19 -0
- package/dist/site.d.ts +27 -0
- package/dist/types.d.ts +77 -0
- package/dist/values.d.ts +65 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
MiroCMS frontend client license
|
|
2
|
+
Copyright (c) 2026 Agencja Reklamowa MiroArt. All rights reserved.
|
|
3
|
+
|
|
4
|
+
This license covers the source in `src/`, the compiled output in `dist/`,
|
|
5
|
+
and the npm package `@miroart/sdk` (the “Software”).
|
|
6
|
+
|
|
7
|
+
Wersja polska i angielska mają to samo znaczenie. W razie rozbieżności
|
|
8
|
+
rozstrzyga tekst angielski.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## English (binding)
|
|
13
|
+
|
|
14
|
+
Permission is granted, free of charge, to any person who has a legitimate
|
|
15
|
+
MiroCMS project accepted by Agencja Reklamowa MiroArt to install and run the
|
|
16
|
+
Software solely to work with that project.
|
|
17
|
+
|
|
18
|
+
You may not, without prior written permission from Agencja Reklamowa MiroArt:
|
|
19
|
+
|
|
20
|
+
- copy, fork, or republish the Software except as npm installs the published
|
|
21
|
+
package for your own use;
|
|
22
|
+
- sublicense, sell, or redistribute the Software or a substantial part of
|
|
23
|
+
its source;
|
|
24
|
+
- use the Software to build, operate, or offer a competing product;
|
|
25
|
+
- remove or alter copyright notices.
|
|
26
|
+
|
|
27
|
+
The Software is provided “AS IS”, without warranty of any kind.
|
|
28
|
+
|
|
29
|
+
All rights not expressly granted are reserved.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Polski
|
|
34
|
+
|
|
35
|
+
Udziela się bezpłatnej zgody osobie, która ma legalny projekt MiroCMS, na
|
|
36
|
+
instalację i uruchamianie Oprogramowania wyłącznie do pracy z tym projektem.
|
|
37
|
+
|
|
38
|
+
Bez uprzedniej pisemnej zgody Agencja Reklamowa MiroArt nie wolno kopiować,
|
|
39
|
+
forować, sublicencjonować ani używać Oprogramowania do konkurencyjnego
|
|
40
|
+
produktu. Oprogramowanie jest dostarczane „TAK JAK JEST”.
|
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# @miroart/sdk
|
|
2
|
+
|
|
3
|
+
Vue 3 plugin. Reads a preloaded payload and optional remote JSON.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @miroart/sdk
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
import { createApp } from "vue";
|
|
11
|
+
import Miro from "@miroart/sdk";
|
|
12
|
+
|
|
13
|
+
createApp(App).use(Miro).mount("#app");
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Set `window.MiroConfig.apiBase` before boot when a remote origin is required.
|
|
17
|
+
Project-specific usage lives in your application docs, not in this package.
|
package/dist/asset.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AssetName, UrlValue } from "./values";
|
|
2
|
+
import type { AssetRecord } from "./types";
|
|
3
|
+
import type { Kernel } from "./context";
|
|
4
|
+
export declare class Asset {
|
|
5
|
+
private readonly record;
|
|
6
|
+
private readonly runtime;
|
|
7
|
+
constructor(record: AssetRecord, runtime: Kernel);
|
|
8
|
+
getUuid(): string;
|
|
9
|
+
getName(): AssetName;
|
|
10
|
+
getMime(): string;
|
|
11
|
+
isImage(): boolean;
|
|
12
|
+
url(): UrlValue;
|
|
13
|
+
srcset(): string;
|
|
14
|
+
raw(): AssetRecord;
|
|
15
|
+
private urlString;
|
|
16
|
+
}
|
|
17
|
+
export declare class Gallery {
|
|
18
|
+
private readonly items;
|
|
19
|
+
constructor(items: Asset[]);
|
|
20
|
+
all(): Asset[];
|
|
21
|
+
first(): Asset | null;
|
|
22
|
+
extra(): Asset[];
|
|
23
|
+
hero(): Asset | null;
|
|
24
|
+
urls(): UrlValue[];
|
|
25
|
+
isEmpty(): boolean;
|
|
26
|
+
count(): number;
|
|
27
|
+
[Symbol.iterator](): Iterator<Asset>;
|
|
28
|
+
}
|
|
29
|
+
export declare function assetsFromUnknown(value: unknown, runtime: Kernel): Asset[];
|
package/dist/bag.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PageRecord, SiteRecord, Snapshot } from "./types";
|
|
2
|
+
export declare function emptySnapshot(): Snapshot;
|
|
3
|
+
export declare function snapshotFromPayload(payload: unknown): Snapshot;
|
|
4
|
+
export declare function mergeSnapshots(base: Snapshot, patch: Partial<Snapshot>): Snapshot;
|
|
5
|
+
export declare function pageKey(record: PageRecord | null | undefined): string;
|
|
6
|
+
export declare function siteKey(record: SiteRecord | null | undefined): string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Gallery } from "./asset";
|
|
2
|
+
import { Menu } from "./menu";
|
|
3
|
+
import { Page } from "./page";
|
|
4
|
+
import { type PluginHandle } from "./plugin";
|
|
5
|
+
import { Site } from "./site";
|
|
6
|
+
export declare function useMiroPage(): Page;
|
|
7
|
+
export declare function useMiroSite(): Site;
|
|
8
|
+
export declare function useMiroMenu(position?: string): Menu;
|
|
9
|
+
export declare function useMiroAssets(): Gallery;
|
|
10
|
+
export declare function usePlugin(name: string): PluginHandle;
|
|
11
|
+
export declare function useMiroConfig(): {
|
|
12
|
+
apiBase: import("vue").ComputedRef<string>;
|
|
13
|
+
siteBase: import("vue").ComputedRef<string>;
|
|
14
|
+
siteRef: import("vue").ComputedRef<string>;
|
|
15
|
+
};
|
|
16
|
+
export { Gallery };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { MenuRecord, PageRecord, SiteRecord, Snapshot } from "./types";
|
|
2
|
+
export type Kernel = {
|
|
3
|
+
apiBase(): string;
|
|
4
|
+
siteBase(): string;
|
|
5
|
+
siteRef(): string;
|
|
6
|
+
request<T = unknown>(path: string, init?: RequestInit): Promise<T>;
|
|
7
|
+
snapshot(): Snapshot;
|
|
8
|
+
rememberPage(record: PageRecord): void;
|
|
9
|
+
rememberSite(record: SiteRecord): void;
|
|
10
|
+
rememberMenu(record: MenuRecord): void;
|
|
11
|
+
};
|
package/dist/decode.d.ts
ADDED
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Dict } from "./types";
|
|
2
|
+
export declare function resolveApiBase(override?: string): string;
|
|
3
|
+
export declare function resolveSiteBase(override?: string): string;
|
|
4
|
+
export declare function requestJson<T = Dict>(base: string, path: string, init?: RequestInit & {
|
|
5
|
+
fetchImpl?: typeof fetch;
|
|
6
|
+
}): Promise<T>;
|
|
7
|
+
export declare function unwrapData<T = Dict>(payload: unknown): T;
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.create,Object.defineProperty,Object.getOwnPropertyDescriptor,Object.getOwnPropertyNames,Object.getPrototypeOf,Object.prototype.hasOwnProperty,Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("vue");function e(t,e){return{page:void 0!==e.page?e.page:t.page,site:void 0!==e.site?e.site:t.site,menus:e.menus?{...t.menus,...e.menus}:{...t.menus},locales:e.locales??t.locales,seo:void 0!==e.seo?e.seo:t.seo,options:e.options?{...t.options,...e.options}:{...t.options}}}function r(t){return Boolean(t)&&"object"==typeof t&&!Array.isArray(t)}function n(t){return r(t)?t:null}function s(t){return t?String(t.uuid||t.ulid||t.id||t.slug||t.full_url||""):""}function i(t){return t?String(t.uuid||t.domain||t.id||""):""}function o(t){return String.fromCharCode(...t.map(t=>23^t))}function u(t,e){const r=String(t||"").replace(/\/+$/,""),n=e.startsWith("/")?e:`/${e}`;return r?`${r}${n}`:n}function c(){const t=o([56,118,103,126]),e=o([97,38]),r=o([100,126,99,114,100]),n=o([103,118,112,114,100]),s=o([100,114,118,101,116,127]),i=o([122,114,121,98,100]),c=o([122,114,115,126,118]),a=o([103,123,98,112,126,121,100]);return{sites:()=>u("",`${t}/${e}/${r}`),site:n=>u("",`${t}/${e}/${r}/${encodeURIComponent(n)}`),pages:s=>u("",`${t}/${e}/${r}/${encodeURIComponent(s)}/${n}`),page:(s,i)=>u("",`${t}/${e}/${r}/${encodeURIComponent(s)}/${n}/${i.split("/").map(t=>encodeURIComponent(t)).join("/")}`),search:i=>u("",`${t}/${e}/${r}/${encodeURIComponent(i)}/${n}/${s}`),menus:n=>u("",`${t}/${e}/${r}/${encodeURIComponent(n)}/${i}`),menu:(n,s)=>u("",`${t}/${e}/${r}/${encodeURIComponent(n)}/${i}/${encodeURIComponent(s)}`),media:e=>u("",`${t}/${c}/${encodeURIComponent(e)}`),plugins:(e,r,n="")=>{const s=`${t}/${a}/${encodeURIComponent(e)}/${encodeURIComponent(r)}`;return n&&"/"!==n?`${s}${n.startsWith("/")?n:`/${n}`}`:s}}}function a(){if("undefined"==typeof globalThis)return{};const t=globalThis.MiroConfig;return t&&"object"==typeof t?t:{}}function l(t){return t&&"object"==typeof t&&"data"in t?t.data:t}function p(t){return null==t?"":"string"==typeof t?t:"number"==typeof t||"boolean"==typeof t?String(t):""}function h(t){const e=p(t);if(!e)return"";if("undefined"!=typeof document){const t=document.createElement("textarea");return t.innerHTML=e,t.value}return e.replace(/&#(\d+);/g,(t,e)=>String.fromCharCode(Number(e))).replace(/&#x([0-9a-f]+);/gi,(t,e)=>String.fromCharCode(parseInt(e,16))).replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function d(t){return h(t).replace(/<script[\s\S]*?>[\s\S]*?<\/script>/gi," ").replace(/<style[\s\S]*?>[\s\S]*?<\/style>/gi," ").replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim()}class g extends String{kind;extra;constructor(t,e,r={}){super(h(e)),this.kind=t,this.extra=r,Object.setPrototypeOf(this,new.target.prototype)}toString(){return String.prototype.toString.call(this)}valueOf(){return String.prototype.valueOf.call(this)}raw(){return this.toString()}decode(){return h(this.toString())}cleanContent(){return d(this.toString())}stripHtml(){return this.cleanContent()}excerpt(t=160){const e=this.cleanContent();return e.length<=t?e:`${e.slice(0,Math.max(0,t-1)).trimEnd()}…`}firstParagraph(){return function(t){const e=h(t),r=e.match(/<p\b[^>]*>([\s\S]*?)<\/p>/i);return d(r?r[1]:e)}(this.toString())}isEmpty(){return""===this.cleanContent()}json(){const t=this.toString().trim();if(!t)return null;try{return JSON.parse(t)}catch{return null}}bool(){const t=this.toString().trim().toLowerCase();return"1"===t||"true"===t||"yes"===t||"on"===t}number(){const t=Number(this.toString().trim());return Number.isFinite(t)?t:null}}class f extends g{constructor(t){super("PageTitle",t)}}class m extends g{constructor(t){super("PageSubtitle",t)}}class y extends g{constructor(t){super("PageSmallTitle",t)}}class S extends g{constructor(t){super("PageSummary",t)}}class w extends g{constructor(t){super("PageContent",t)}html(){return this.toString()}}class $ extends g{constructor(t){super("SiteTitle",t)}}class b extends g{constructor(t){super("SiteName",t)}}class x extends g{key;constructor(t,e){super("OptionValue",A(e),{key:t}),this.key=t}present(){return!this.isEmpty()}}class k extends g{constructor(t){super("UrlValue",t)}path(){const t=this.toString().trim();if(!t)return"/";try{if(/^https?:\/\//i.test(t))return new URL(t).pathname.replace(/\/+$/,"")||"/"}catch{}return(t.startsWith("/")?t:`/${t}`).replace(/\/+$/,"")||"/"}href(t=""){const e=this.path();return!t||/^https?:\/\//i.test(e)?e:`${String(t).replace(/\/+$/,"")}${e}`}}class j extends g{constructor(t){super("MenuTitle",t)}}class R extends g{constructor(t){super("AssetName",t)}}class C extends g{constructor(t){super("SeoTitle",t)}}class P extends g{constructor(t){super("SeoDescription",t)}}function A(t){if(null==t)return"";if("boolean"==typeof t||"number"==typeof t)return String(t);if("string"==typeof t){const e=t.trim();if(""===e||"[]"===e||"{}"===e)return"";if(e.startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]")||e.startsWith('"')&&e.endsWith('"'))try{return A(JSON.parse(e))}catch{return h(t)}return h(t)}return Array.isArray(t)?t.length?A(t[0]):"":"object"==typeof t&&null!==t&&"value"in t?A(t.value):p(t)}function _(t,e){if(!t)return"";if(Array.isArray(t)){const r=t.find(t=>t&&"object"==typeof t&&t.key===e);return r&&"object"==typeof r?r.value:""}return"object"==typeof t?t[e]:""}class O{constructor(t){this.record=t}record;getTitle(){return new j(this.record.title)}getUrl(){return new k(this.record.url)}getChildren(){return v(this.record.children)}raw(){return{...this.record}}}class U{constructor(t,e){this.source=t,this.runtime=e}source;runtime;get record(){return"function"==typeof this.source?this.source():this.source}static async find(t,e){const r=function(){if(!M)throw new Error("Client is not installed.");return M}(),n=null!=e&&""!==String(e)?String(e):r.siteRef(),s=r.snapshot().menus,i=s[t]||Object.values(s).find(e=>!!e&&(String(e.uuid)===t||String(e.id)===t||String(e.name)===t||String(e.position)===t));if(i)return new U(i,r);const o=l(await r.request(c().menu(n,t)));return r.rememberMenu(o),new U(o,r)}getName(){return new j(this.record.name)}getPosition(){return String(this.record.position||"")}getItems(){return v(this.record.items)}raw(){return{...this.record}}}function v(t){return Array.isArray(t)?t.filter(t=>Boolean(t)&&"object"==typeof t).map(t=>new O(t)):[]}let M=null;const T=[{mark:"1_8",width:256},{mark:"1_4",width:512},{mark:"1_2",width:1024},{mark:"2_3",width:1400}];class I{constructor(t,e){this.record=t,this.runtime=e}record;runtime;getUuid(){return String(this.record.uuid||this.record.id||"")}getName(){return new R(this.record.name)}getMime(){return String(this.record.mime_type||"")}isImage(){return!!this.getMime().startsWith("image/")||/\.(jpe?g|png|gif|webp|svg)(\?|$)/i.test(this.urlString())}url(){return new k(this.urlString())}srcset(){const t=this.urlString();if(!t||/\.svg([?#]|$)/i.test(t)||/^https?:\/\//i.test(t)||t.startsWith("//"))return"";if(!/\.webp([?#]|$)/i.test(t)||/\.(?:1_16|1_8|1_4|1_2|2_3)\.webp([?#]|$)/i.test(t))return"";const e=T.map(({mark:e,width:r})=>`${t.replace(/\.webp([?#].*)?$/i,`.${e}.webp$1`)} ${r}w`);return e.push(`${t} 2048w`),e.join(", ")}raw(){return{...this.record}}urlString(){const t=String(this.record.url||this.record.path||"");if(t)return t;const e=this.getUuid();if(!e)return"";const r=c().media(e),n=this.runtime.apiBase();return n?u(n,r):r}}class B{constructor(t){this.items=t}items;all(){return this.items.slice()}first(){return this.items[0]??null}extra(){return this.items.slice(1)}hero(){return this.first()}urls(){return this.items.map(t=>t.url())}isEmpty(){return 0===this.items.length}count(){return this.items.length}[Symbol.iterator](){return this.items[Symbol.iterator]()}}class q{constructor(t,e){this.source=t,this.kernel=e}source;kernel;get record(){return"function"==typeof this.source?this.source():this.source}static async find(t){const e=function(){if(!N)throw new Error("Client is not installed.");return N}(),r=null!=t&&""!==String(t)?String(t):e.siteRef(),n=e.snapshot().site;if(n&&(!t||String(n.uuid)===String(t)||String(n.id)===String(t)||String(n.domain)===String(t)||i(n)===String(t)))return new q(n,e);const s=l(await e.request(c().site(r)));return e.rememberSite(s),new q(s,e)}static async findPage(t,e){return E.find(t,e)}static async findMenu(t,e){return U.find(t,e)}getName(){return new b(this.record.name)}getTitle(){const t=_(this.record.options,"seo_title")||_(this.record.options,"title");return new $(t||this.record.name)}getDomain(){return String(this.record.domain||"")}getLang(){return String(this.record.lang||"")}getUuid(){return String(this.record.uuid||"")}getOption(t){return new x(t,_(this.record.options,t))}async findPage(t){return E.find(t,this.ref())}async findMenu(t){return U.find(t,this.ref())}async menus(){const t=this.kernel.snapshot().menus,e=Object.values(t).filter(Boolean);return e.length?e.map(t=>new U(t,this.kernel)):((await this.kernel.request(c().menus(this.ref()))).data??[]).map(t=>(this.kernel.rememberMenu(t),new U(t,this.kernel)))}async pages(t={}){const e=new URLSearchParams;for(const[n,s]of Object.entries(t))e.set(n,String(s));const r=e.toString()?`?${e.toString()}`:"";return((await this.kernel.request(`${c().pages(this.ref())}${r}`)).data??[]).map(t=>(this.kernel.rememberPage(t),new E(t,this.kernel)))}raw(){return{...this.record}}ref(){return String(this.record.uuid||this.record.domain||this.record.id||this.kernel.siteRef())}}let N=null;class E{constructor(t,e){this.source=t,this.kernel=e}source;kernel;get record(){return"function"==typeof this.source?this.source():this.source}setRecord(t){"function"!=typeof this.source?this.source=t:this.kernel.rememberPage(t)}static async findByUlid(t,e){return V(t,e)}static async find(t,e){return V(t,e)}static async search(t,e){const r=D(),n=L(r,e),s=`${c().search(n)}?q=${encodeURIComponent(t)}`,i=await r.request(s);return(Array.isArray(i?.data)?i.data:Array.isArray(i)?i:[]).map(t=>(r.rememberPage(t),new E(t,r)))}getTitle(){return new f(this.record.title)}getSubtitle(){return new m(this.record.subtitle)}getSmallTitle(){return new y(this.record.smalltitle)}getSummary(){return new S(this.record.summary)}getContent(){return new w(this.record.content)}getSlug(){return String(this.record.slug||"")}getUrl(){return new k(this.record.full_url||(this.record.slug?`/${this.record.slug}`:"/"))}getUuid(){return String(this.record.uuid||this.record.ulid||"")}getId(){return String(this.record.id||this.getUuid())}getLayout(){return String(this.record.layout||"")}getDisplay(){return String(this.record.display||"")}getOption(t){const e=_(this.record.options,t);if(null!=e&&""!==e)return new x(t,e);const r=this.kernel.snapshot().options[t];return new x(t,r)}getSeo(){const t=(this.record.seo&&"object"==typeof this.record.seo?this.record.seo:this.kernel.snapshot().seo)??{};return{title:new C(t.title??this.record.title),description:new P(t.description??this.record.summary),raw:{...t}}}getAssets(){return new B((t=this.record.assets,e=this.kernel,Array.isArray(t)?t.filter(t=>Boolean(t)&&"object"==typeof t).map(t=>new I(t,e)):[]));var t,e}async getChildren(){return await this.ensure(["children"]),(Array.isArray(this.record.children)?this.record.children:[]).filter(t=>Boolean(t)&&"object"==typeof t).map(t=>new E(t,this.kernel))}async getSiblings(){if(Array.isArray(this.record.siblings))return this.record.siblings.filter(t=>Boolean(t)&&"object"==typeof t).map(t=>new E(t,this.kernel));const t=this.record.parent_id,e=this.siteRef();if(null==t||""===t){const t=await this.kernel.request(`${c().pages(e)}?parent=root`);return this.excludeSelf(t.data??[])}const r=await this.kernel.request(`${c().pages(e)}?parent=${encodeURIComponent(String(t))}`);return this.excludeSelf(r.data??[])}async getParent(){if(this.record.parent&&"object"==typeof this.record.parent)return new E(this.record.parent,this.kernel);const t=this.record.parent_id;return null==t||""===t?null:V(String(t),this.siteRef())}async getSite(){if(this.record.site&&"object"==typeof this.record.site)return new q(this.record.site,this.kernel);const t=this.kernel.snapshot().site;if(t&&(String(t.id)===String(this.record.site_id)||!this.record.site_id))return new q(t,this.kernel);const e=this.record.site_id?String(this.record.site_id):this.kernel.siteRef(),r=l(await this.kernel.request(c().site(e)));return this.kernel.rememberSite(r),new q(r,this.kernel)}async load(){return await this.ensure(["content","options","assets","children"]),this}raw(){return{...this.record}}siteRef(){return this.record.site&&"object"==typeof this.record.site?i(this.record.site)||this.kernel.siteRef():this.record.site_id?String(this.record.site_id):this.kernel.siteRef()}excludeSelf(t){const e=s(this.record);return t.filter(t=>s(t)!==e).map(t=>new E(t,this.kernel))}async ensure(t){if(!t.some(t=>void 0===this.record[t]))return;const e=this.getUuid()||this.getSlug()||String(this.record.id||"");if(!e)return;const r=l(await this.kernel.request(c().page(this.siteRef(),e)));this.setRecord({...this.record,...r})}}let W=null;function D(){if(!W)throw new Error("Client is not installed.");return W}function L(t,e){return null!=e&&""!==String(e)?String(e):t.siteRef()}async function V(t,e){const r=D(),n=L(r,e),s=l(await r.request(c().page(n,t)));return r.rememberPage(s),new E(s,r)}class H{snap={page:null,site:null,menus:{},locales:[],seo:null,options:{}};options;constructor(t={}){this.options=t,t.page&&this.hydrate(t.page),W=this,N=this,M=this}hydrate(t){return this.snap=e(this.snap,function(t){const e={page:null,site:null,menus:{},locales:[],seo:null,options:{}};if(!t||"object"!=typeof t)return e;const s=t,i=r(s.props)?s.props:s;e.page=n(i.page),e.site=n(i.site),e.seo=r(i.seo)?i.seo:null,e.options=r(i.options)?i.options:{},e.locales=Array.isArray(i.locales)?i.locales:[];const o=i.menus;if(r(o))for(const[r,u]of Object.entries(o))e.menus[r]=n(u);return e}(t)),this.snap}snapshot(){return this.snap}apiBase(){return function(t){if(t)return String(t).replace(/\/+$/,"");const e=a();if(e.apiBase)return String(e.apiBase).replace(/\/+$/,"");if("undefined"==typeof location)return"";const r=location.hostname.replace(/^www\./i,"");return r&&"localhost"!==r&&"127.0.0.1"!==r?`${location.protocol}//api.${r}`:""}(this.options.apiBase)}siteBase(){return function(t){if(t)return String(t).replace(/\/+$/,"");const e=a();return e.siteBase?String(e.siteBase).replace(/\/+$/,""):"undefined"!=typeof location?location.origin:""}(this.options.siteBase)}siteRef(){return null!=this.options.site&&""!==String(this.options.site)?String(this.options.site):i(this.snap.site)}async request(t,e={}){const r=this.apiBase();if(!r)throw new Error("Remote origin is not configured.");return async function(t,e,r={}){const{fetchImpl:n,...s}=r,i=e.startsWith("http")?e:u(t,e),o=n??fetch,c=new Headers(s.headers);c.has("Accept")||c.set("Accept","application/json");const a=await o(i,{...s,headers:c}),l=await a.text();let p=null;if(l)try{p=JSON.parse(l)}catch{p={message:l}}if(!a.ok){const t=new Error(`Request failed (${a.status})`);throw t.status=a.status,t.body=p,t}return p}(r,t,{...e,fetchImpl:this.options.fetch})}rememberPage(t){const r=this.snap.page;r&&String(r.id)===String(t.id)&&(this.snap=e(this.snap,{page:{...r,...t}}))}rememberSite(t){this.snap=e(this.snap,{site:{...this.snap.site??{},...t}})}rememberMenu(t){const r=String(t.position||t.uuid||t.id||t.name||"menu");this.snap=e(this.snap,{menus:{[r]:t}})}}let J=null;function K(t={}){return J=new H(t),J}function z(){return J||(J=new H),J}const Z=Symbol.for("miro.client");function G(){return t.inject(Z,null)??z()}function F(t={}){return{install(e,r={}){const n=K({...t,...r});e.provide(Z,n),function(t){import("@inertiajs/vue3").then(e=>{const r=e.router;r?.on?.("success",e=>{const r=e?.detail?.page;r&&t.hydrate(r)}),r?.on?.("navigate",e=>{const r=e?.detail?.page;r&&t.hydrate(r)})}).catch(()=>{})}(n)}}}const Y=F();function Q(t){return`mc_${(String(t??"").trim().split("/").pop()??"").replace(/^@/,"").replace(/[^A-Za-z0-9]+/g,"_").replace(/^_+|_+$/g,"").toUpperCase()}`}function X(t){return t.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^A-Za-z0-9]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()}function tt(t){if("undefined"==typeof window)return{};const e=window[t];return e&&"object"==typeof e?e:{}}function et(){const t=G(),e=function(){try{const t=globalThis.__INERTIA_PAGE__;if(t?.props)return t.props}catch{}return null}();return e&&t.hydrate(e),t}function rt(){const t=et();return nt(t),new E(()=>t.snapshot().page??{},t)}function nt(e){try{const r=function(){try{return st??null}catch{return null}}();if(!r)return;const n=r.usePage();e.hydrate(t.unref(n))}catch{}}let st=null;import("@inertiajs/vue3").then(t=>{st=t}).catch(()=>{st=null});const it=Y;exports.Asset=I,exports.AssetName=R,exports.Gallery=B,exports.Menu=U,exports.MenuItem=O,exports.MenuTitle=j,exports.Miro=Y,exports.OptionValue=x,exports.Page=E,exports.PageContent=w,exports.PageSmallTitle=y,exports.PageSubtitle=m,exports.PageSummary=S,exports.PageTitle=f,exports.SDK_KEY=Z,exports.SeoDescription=P,exports.SeoTitle=C,exports.Site=q,exports.SiteName=b,exports.SiteTitle=$,exports.TextValue=g,exports.UrlValue=k,exports.createMiro=F,exports.createRuntime=K,exports.default=it,exports.getRuntime=z,exports.pluginWindowKey=Q,exports.useKernel=G,exports.useMiroAssets=function(){return rt().getAssets()},exports.useMiroConfig=function(){const e=G();return{apiBase:t.computed(()=>e.apiBase()),siteBase:t.computed(()=>e.siteBase()),siteRef:t.computed(()=>e.siteRef())}},exports.useMiroMenu=function(t="topbar"){const e=et();return nt(e),new U(()=>e.snapshot().menus[t]??{position:t,items:[]},e)},exports.useMiroPage=rt,exports.useMiroSite=function(){const t=et();return nt(t),new q(()=>t.snapshot().site??{},t)},exports.usePlugin=function(t){return function(t,e){const r=Q(t),n=function(t){const e=String(t??"").trim();if(e.includes("/")){const[t,...r]=e.split("/");return{vendor:t||"miroart",slug:X(r.join("/")||e)}}return{vendor:"miroart",slug:X(e)}}(t);return new Proxy({name:t,key:r,ready:async()=>async function(t){const e=Date.now();for(;Date.now()-e<4e3;){const e=tt(t);if(Object.keys(e).length)return e;await new Promise(t=>setTimeout(t,50))}return tt(t)}(r),api:()=>tt(r),call:(t,...e)=>{const n=tt(r),s=n[t];if("function"!=typeof s)throw new Error(`Missing plugin method: ${t}`);return s.apply(n,e)},request:async(t="/",r={})=>{const s=c().plugins(n.vendor,n.slug,t||"/"),i=new Headers(r.headers);let o=r.body;return void 0!==r.json&&(o=JSON.stringify(r.json)),l(await e.request(s,{...r,headers:i,body:o}))}},{get(t,e,n){if(e in t)return Reflect.get(t,e,n);if("then"===e||e===Symbol.toStringTag)return;const s=tt(r),i=s[String(e)];return"function"==typeof i?i.bind(s):i},has:(t,e)=>e in t||e in tt(r)})}(t,G())};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Plugin } from "vue";
|
|
2
|
+
import { createMiro, Miro, SDK_KEY, useKernel } from "./install";
|
|
3
|
+
import { Page } from "./page";
|
|
4
|
+
import { Site } from "./site";
|
|
5
|
+
import { Menu, MenuItem } from "./menu";
|
|
6
|
+
import { Asset, Gallery } from "./asset";
|
|
7
|
+
import { createRuntime, getRuntime } from "./runtime";
|
|
8
|
+
import { useMiroAssets, useMiroConfig, useMiroMenu, useMiroPage, useMiroSite, usePlugin } from "./composables";
|
|
9
|
+
import { AssetName, MenuTitle, OptionValue, PageContent, PageSmallTitle, PageSubtitle, PageSummary, PageTitle, SeoDescription, SeoTitle, SiteName, SiteTitle, TextValue, UrlValue } from "./values";
|
|
10
|
+
import { pluginWindowKey } from "./plugin";
|
|
11
|
+
import type { ClientOptions } from "./types";
|
|
12
|
+
export { Asset, AssetName, createMiro, createRuntime, Gallery, getRuntime, Menu, MenuItem, MenuTitle, Miro, OptionValue, Page, PageContent, PageSmallTitle, PageSubtitle, PageSummary, PageTitle, pluginWindowKey, SDK_KEY, SeoDescription, SeoTitle, Site, SiteName, SiteTitle, TextValue, UrlValue, useKernel, useMiroAssets, useMiroConfig, useMiroMenu, useMiroPage, useMiroSite, usePlugin, };
|
|
13
|
+
export type { ClientOptions };
|
|
14
|
+
declare const plugin: Plugin;
|
|
15
|
+
export default plugin;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{inject as t,computed as e,unref as r}from"vue";function n(t,e){return{page:void 0!==e.page?e.page:t.page,site:void 0!==e.site?e.site:t.site,menus:e.menus?{...t.menus,...e.menus}:{...t.menus},locales:e.locales??t.locales,seo:void 0!==e.seo?e.seo:t.seo,options:e.options?{...t.options,...e.options}:{...t.options}}}function s(t){return Boolean(t)&&"object"==typeof t&&!Array.isArray(t)}function i(t){return s(t)?t:null}function o(t){return t?String(t.uuid||t.ulid||t.id||t.slug||t.full_url||""):""}function c(t){return t?String(t.uuid||t.domain||t.id||""):""}function u(t){return String.fromCharCode(...t.map(t=>23^t))}function a(t,e){const r=String(t||"").replace(/\/+$/,""),n=e.startsWith("/")?e:`/${e}`;return r?`${r}${n}`:n}function l(){const t=u([56,118,103,126]),e=u([97,38]),r=u([100,126,99,114,100]),n=u([103,118,112,114,100]),s=u([100,114,118,101,116,127]),i=u([122,114,121,98,100]),o=u([122,114,115,126,118]),c=u([103,123,98,112,126,121,100]);return{sites:()=>a("",`${t}/${e}/${r}`),site:n=>a("",`${t}/${e}/${r}/${encodeURIComponent(n)}`),pages:s=>a("",`${t}/${e}/${r}/${encodeURIComponent(s)}/${n}`),page:(s,i)=>a("",`${t}/${e}/${r}/${encodeURIComponent(s)}/${n}/${i.split("/").map(t=>encodeURIComponent(t)).join("/")}`),search:i=>a("",`${t}/${e}/${r}/${encodeURIComponent(i)}/${n}/${s}`),menus:n=>a("",`${t}/${e}/${r}/${encodeURIComponent(n)}/${i}`),menu:(n,s)=>a("",`${t}/${e}/${r}/${encodeURIComponent(n)}/${i}/${encodeURIComponent(s)}`),media:e=>a("",`${t}/${o}/${encodeURIComponent(e)}`),plugins:(e,r,n="")=>{const s=`${t}/${c}/${encodeURIComponent(e)}/${encodeURIComponent(r)}`;return n&&"/"!==n?`${s}${n.startsWith("/")?n:`/${n}`}`:s}}}function h(){if("undefined"==typeof globalThis)return{};const t=globalThis.MiroConfig;return t&&"object"==typeof t?t:{}}function p(t){return t&&"object"==typeof t&&"data"in t?t.data:t}function d(t){return null==t?"":"string"==typeof t?t:"number"==typeof t||"boolean"==typeof t?String(t):""}function g(t){const e=d(t);if(!e)return"";if("undefined"!=typeof document){const t=document.createElement("textarea");return t.innerHTML=e,t.value}return e.replace(/&#(\d+);/g,(t,e)=>String.fromCharCode(Number(e))).replace(/&#x([0-9a-f]+);/gi,(t,e)=>String.fromCharCode(parseInt(e,16))).replace(/"/g,'"').replace(/'/g,"'").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}function f(t){return g(t).replace(/<script[\s\S]*?>[\s\S]*?<\/script>/gi," ").replace(/<style[\s\S]*?>[\s\S]*?<\/style>/gi," ").replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim()}class m extends String{kind;extra;constructor(t,e,r={}){super(g(e)),this.kind=t,this.extra=r,Object.setPrototypeOf(this,new.target.prototype)}toString(){return String.prototype.toString.call(this)}valueOf(){return String.prototype.valueOf.call(this)}raw(){return this.toString()}decode(){return g(this.toString())}cleanContent(){return f(this.toString())}stripHtml(){return this.cleanContent()}excerpt(t=160){const e=this.cleanContent();return e.length<=t?e:`${e.slice(0,Math.max(0,t-1)).trimEnd()}…`}firstParagraph(){return function(t){const e=g(t),r=e.match(/<p\b[^>]*>([\s\S]*?)<\/p>/i);return f(r?r[1]:e)}(this.toString())}isEmpty(){return""===this.cleanContent()}json(){const t=this.toString().trim();if(!t)return null;try{return JSON.parse(t)}catch{return null}}bool(){const t=this.toString().trim().toLowerCase();return"1"===t||"true"===t||"yes"===t||"on"===t}number(){const t=Number(this.toString().trim());return Number.isFinite(t)?t:null}}class y extends m{constructor(t){super("PageTitle",t)}}class S extends m{constructor(t){super("PageSubtitle",t)}}class w extends m{constructor(t){super("PageSmallTitle",t)}}class $ extends m{constructor(t){super("PageSummary",t)}}class b extends m{constructor(t){super("PageContent",t)}html(){return this.toString()}}class k extends m{constructor(t){super("SiteTitle",t)}}class R extends m{constructor(t){super("SiteName",t)}}class C extends m{key;constructor(t,e){super("OptionValue",v(e),{key:t}),this.key=t}present(){return!this.isEmpty()}}class j extends m{constructor(t){super("UrlValue",t)}path(){const t=this.toString().trim();if(!t)return"/";try{if(/^https?:\/\//i.test(t))return new URL(t).pathname.replace(/\/+$/,"")||"/"}catch{}return(t.startsWith("/")?t:`/${t}`).replace(/\/+$/,"")||"/"}href(t=""){const e=this.path();return!t||/^https?:\/\//i.test(e)?e:`${String(t).replace(/\/+$/,"")}${e}`}}class A extends m{constructor(t){super("MenuTitle",t)}}class _ extends m{constructor(t){super("AssetName",t)}}class x extends m{constructor(t){super("SeoTitle",t)}}class U extends m{constructor(t){super("SeoDescription",t)}}function v(t){if(null==t)return"";if("boolean"==typeof t||"number"==typeof t)return String(t);if("string"==typeof t){const e=t.trim();if(""===e||"[]"===e||"{}"===e)return"";if(e.startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]")||e.startsWith('"')&&e.endsWith('"'))try{return v(JSON.parse(e))}catch{return g(t)}return g(t)}return Array.isArray(t)?t.length?v(t[0]):"":"object"==typeof t&&null!==t&&"value"in t?v(t.value):d(t)}function B(t,e){if(!t)return"";if(Array.isArray(t)){const r=t.find(t=>t&&"object"==typeof t&&t.key===e);return r&&"object"==typeof r?r.value:""}return"object"==typeof t?t[e]:""}class I{constructor(t){this.record=t}record;getTitle(){return new A(this.record.title)}getUrl(){return new j(this.record.url)}getChildren(){return q(this.record.children)}raw(){return{...this.record}}}class P{constructor(t,e){this.source=t,this.runtime=e}source;runtime;get record(){return"function"==typeof this.source?this.source():this.source}static async find(t,e){const r=function(){if(!O)throw new Error("Client is not installed.");return O}(),n=null!=e&&""!==String(e)?String(e):r.siteRef(),s=r.snapshot().menus,i=s[t]||Object.values(s).find(e=>!!e&&(String(e.uuid)===t||String(e.id)===t||String(e.name)===t||String(e.position)===t));if(i)return new P(i,r);const o=p(await r.request(l().menu(n,t)));return r.rememberMenu(o),new P(o,r)}getName(){return new A(this.record.name)}getPosition(){return String(this.record.position||"")}getItems(){return q(this.record.items)}raw(){return{...this.record}}}function q(t){return Array.isArray(t)?t.filter(t=>Boolean(t)&&"object"==typeof t).map(t=>new I(t)):[]}let O=null;const T=[{mark:"1_8",width:256},{mark:"1_4",width:512},{mark:"1_2",width:1024},{mark:"2_3",width:1400}];class E{constructor(t,e){this.record=t,this.runtime=e}record;runtime;getUuid(){return String(this.record.uuid||this.record.id||"")}getName(){return new _(this.record.name)}getMime(){return String(this.record.mime_type||"")}isImage(){return!!this.getMime().startsWith("image/")||/\.(jpe?g|png|gif|webp|svg)(\?|$)/i.test(this.urlString())}url(){return new j(this.urlString())}srcset(){const t=this.urlString();if(!t||/\.svg([?#]|$)/i.test(t)||/^https?:\/\//i.test(t)||t.startsWith("//"))return"";if(!/\.webp([?#]|$)/i.test(t)||/\.(?:1_16|1_8|1_4|1_2|2_3)\.webp([?#]|$)/i.test(t))return"";const e=T.map(({mark:e,width:r})=>`${t.replace(/\.webp([?#].*)?$/i,`.${e}.webp$1`)} ${r}w`);return e.push(`${t} 2048w`),e.join(", ")}raw(){return{...this.record}}urlString(){const t=String(this.record.url||this.record.path||"");if(t)return t;const e=this.getUuid();if(!e)return"";const r=l().media(e),n=this.runtime.apiBase();return n?a(n,r):r}}class N{constructor(t){this.items=t}items;all(){return this.items.slice()}first(){return this.items[0]??null}extra(){return this.items.slice(1)}hero(){return this.first()}urls(){return this.items.map(t=>t.url())}isEmpty(){return 0===this.items.length}count(){return this.items.length}[Symbol.iterator](){return this.items[Symbol.iterator]()}}class M{constructor(t,e){this.source=t,this.kernel=e}source;kernel;get record(){return"function"==typeof this.source?this.source():this.source}static async find(t){const e=function(){if(!W)throw new Error("Client is not installed.");return W}(),r=null!=t&&""!==String(t)?String(t):e.siteRef(),n=e.snapshot().site;if(n&&(!t||String(n.uuid)===String(t)||String(n.id)===String(t)||String(n.domain)===String(t)||c(n)===String(t)))return new M(n,e);const s=p(await e.request(l().site(r)));return e.rememberSite(s),new M(s,e)}static async findPage(t,e){return L.find(t,e)}static async findMenu(t,e){return P.find(t,e)}getName(){return new R(this.record.name)}getTitle(){const t=B(this.record.options,"seo_title")||B(this.record.options,"title");return new k(t||this.record.name)}getDomain(){return String(this.record.domain||"")}getLang(){return String(this.record.lang||"")}getUuid(){return String(this.record.uuid||"")}getOption(t){return new C(t,B(this.record.options,t))}async findPage(t){return L.find(t,this.ref())}async findMenu(t){return P.find(t,this.ref())}async menus(){const t=this.kernel.snapshot().menus,e=Object.values(t).filter(Boolean);return e.length?e.map(t=>new P(t,this.kernel)):((await this.kernel.request(l().menus(this.ref()))).data??[]).map(t=>(this.kernel.rememberMenu(t),new P(t,this.kernel)))}async pages(t={}){const e=new URLSearchParams;for(const[n,s]of Object.entries(t))e.set(n,String(s));const r=e.toString()?`?${e.toString()}`:"";return((await this.kernel.request(`${l().pages(this.ref())}${r}`)).data??[]).map(t=>(this.kernel.rememberPage(t),new L(t,this.kernel)))}raw(){return{...this.record}}ref(){return String(this.record.uuid||this.record.domain||this.record.id||this.kernel.siteRef())}}let W=null;class L{constructor(t,e){this.source=t,this.kernel=e}source;kernel;get record(){return"function"==typeof this.source?this.source():this.source}setRecord(t){"function"!=typeof this.source?this.source=t:this.kernel.rememberPage(t)}static async findByUlid(t,e){return z(t,e)}static async find(t,e){return z(t,e)}static async search(t,e){const r=H(),n=J(r,e),s=`${l().search(n)}?q=${encodeURIComponent(t)}`,i=await r.request(s);return(Array.isArray(i?.data)?i.data:Array.isArray(i)?i:[]).map(t=>(r.rememberPage(t),new L(t,r)))}getTitle(){return new y(this.record.title)}getSubtitle(){return new S(this.record.subtitle)}getSmallTitle(){return new w(this.record.smalltitle)}getSummary(){return new $(this.record.summary)}getContent(){return new b(this.record.content)}getSlug(){return String(this.record.slug||"")}getUrl(){return new j(this.record.full_url||(this.record.slug?`/${this.record.slug}`:"/"))}getUuid(){return String(this.record.uuid||this.record.ulid||"")}getId(){return String(this.record.id||this.getUuid())}getLayout(){return String(this.record.layout||"")}getDisplay(){return String(this.record.display||"")}getOption(t){const e=B(this.record.options,t);if(null!=e&&""!==e)return new C(t,e);const r=this.kernel.snapshot().options[t];return new C(t,r)}getSeo(){const t=(this.record.seo&&"object"==typeof this.record.seo?this.record.seo:this.kernel.snapshot().seo)??{};return{title:new x(t.title??this.record.title),description:new U(t.description??this.record.summary),raw:{...t}}}getAssets(){return new N((t=this.record.assets,e=this.kernel,Array.isArray(t)?t.filter(t=>Boolean(t)&&"object"==typeof t).map(t=>new E(t,e)):[]));var t,e}async getChildren(){return await this.ensure(["children"]),(Array.isArray(this.record.children)?this.record.children:[]).filter(t=>Boolean(t)&&"object"==typeof t).map(t=>new L(t,this.kernel))}async getSiblings(){if(Array.isArray(this.record.siblings))return this.record.siblings.filter(t=>Boolean(t)&&"object"==typeof t).map(t=>new L(t,this.kernel));const t=this.record.parent_id,e=this.siteRef();if(null==t||""===t){const t=await this.kernel.request(`${l().pages(e)}?parent=root`);return this.excludeSelf(t.data??[])}const r=await this.kernel.request(`${l().pages(e)}?parent=${encodeURIComponent(String(t))}`);return this.excludeSelf(r.data??[])}async getParent(){if(this.record.parent&&"object"==typeof this.record.parent)return new L(this.record.parent,this.kernel);const t=this.record.parent_id;return null==t||""===t?null:z(String(t),this.siteRef())}async getSite(){if(this.record.site&&"object"==typeof this.record.site)return new M(this.record.site,this.kernel);const t=this.kernel.snapshot().site;if(t&&(String(t.id)===String(this.record.site_id)||!this.record.site_id))return new M(t,this.kernel);const e=this.record.site_id?String(this.record.site_id):this.kernel.siteRef(),r=p(await this.kernel.request(l().site(e)));return this.kernel.rememberSite(r),new M(r,this.kernel)}async load(){return await this.ensure(["content","options","assets","children"]),this}raw(){return{...this.record}}siteRef(){return this.record.site&&"object"==typeof this.record.site?c(this.record.site)||this.kernel.siteRef():this.record.site_id?String(this.record.site_id):this.kernel.siteRef()}excludeSelf(t){const e=o(this.record);return t.filter(t=>o(t)!==e).map(t=>new L(t,this.kernel))}async ensure(t){if(!t.some(t=>void 0===this.record[t]))return;const e=this.getUuid()||this.getSlug()||String(this.record.id||"");if(!e)return;const r=p(await this.kernel.request(l().page(this.siteRef(),e)));this.setRecord({...this.record,...r})}}let D=null;function H(){if(!D)throw new Error("Client is not installed.");return D}function J(t,e){return null!=e&&""!==String(e)?String(e):t.siteRef()}async function z(t,e){const r=H(),n=J(r,e),s=p(await r.request(l().page(n,t)));return r.rememberPage(s),new L(s,r)}class Z{snap={page:null,site:null,menus:{},locales:[],seo:null,options:{}};options;constructor(t={}){this.options=t,t.page&&this.hydrate(t.page),D=this,W=this,O=this}hydrate(t){return this.snap=n(this.snap,function(t){const e={page:null,site:null,menus:{},locales:[],seo:null,options:{}};if(!t||"object"!=typeof t)return e;const r=t,n=s(r.props)?r.props:r;e.page=i(n.page),e.site=i(n.site),e.seo=s(n.seo)?n.seo:null,e.options=s(n.options)?n.options:{},e.locales=Array.isArray(n.locales)?n.locales:[];const o=n.menus;if(s(o))for(const[s,c]of Object.entries(o))e.menus[s]=i(c);return e}(t)),this.snap}snapshot(){return this.snap}apiBase(){return function(t){if(t)return String(t).replace(/\/+$/,"");const e=h();if(e.apiBase)return String(e.apiBase).replace(/\/+$/,"");if("undefined"==typeof location)return"";const r=location.hostname.replace(/^www\./i,"");return r&&"localhost"!==r&&"127.0.0.1"!==r?`${location.protocol}//api.${r}`:""}(this.options.apiBase)}siteBase(){return function(t){if(t)return String(t).replace(/\/+$/,"");const e=h();return e.siteBase?String(e.siteBase).replace(/\/+$/,""):"undefined"!=typeof location?location.origin:""}(this.options.siteBase)}siteRef(){return null!=this.options.site&&""!==String(this.options.site)?String(this.options.site):c(this.snap.site)}async request(t,e={}){const r=this.apiBase();if(!r)throw new Error("Remote origin is not configured.");return async function(t,e,r={}){const{fetchImpl:n,...s}=r,i=e.startsWith("http")?e:a(t,e),o=n??fetch,c=new Headers(s.headers);c.has("Accept")||c.set("Accept","application/json");const u=await o(i,{...s,headers:c}),l=await u.text();let h=null;if(l)try{h=JSON.parse(l)}catch{h={message:l}}if(!u.ok){const t=new Error(`Request failed (${u.status})`);throw t.status=u.status,t.body=h,t}return h}(r,t,{...e,fetchImpl:this.options.fetch})}rememberPage(t){const e=this.snap.page;e&&String(e.id)===String(t.id)&&(this.snap=n(this.snap,{page:{...e,...t}}))}rememberSite(t){this.snap=n(this.snap,{site:{...this.snap.site??{},...t}})}rememberMenu(t){const e=String(t.position||t.uuid||t.id||t.name||"menu");this.snap=n(this.snap,{menus:{[e]:t}})}}let V=null;function F(t={}){return V=new Z(t),V}function G(){return V||(V=new Z),V}const K=/* @__PURE__ */Symbol.for("miro.client");function Q(){return t(K,null)??G()}function X(t={}){return{install(e,r={}){const n=F({...t,...r});e.provide(K,n),function(t){import("@inertiajs/vue3").then(e=>{const r=e.router;r?.on?.("success",e=>{const r=e?.detail?.page;r&&t.hydrate(r)}),r?.on?.("navigate",e=>{const r=e?.detail?.page;r&&t.hydrate(r)})}).catch(()=>{})}(n)}}}const Y=X();function tt(t){return`mc_${(String(t??"").trim().split("/").pop()??"").replace(/^@/,"").replace(/[^A-Za-z0-9]+/g,"_").replace(/^_+|_+$/g,"").toUpperCase()}`}function et(t){return t.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^A-Za-z0-9]+/g,"-").replace(/^-+|-+$/g,"").toLowerCase()}function rt(t){if("undefined"==typeof window)return{};const e=window[t];return e&&"object"==typeof e?e:{}}function nt(){const t=Q(),e=function(){try{const t=globalThis.__INERTIA_PAGE__;if(t?.props)return t.props}catch{}return null}();return e&&t.hydrate(e),t}function st(){const t=nt();return lt(t),new L(()=>t.snapshot().page??{},t)}function it(){const t=nt();return lt(t),new M(()=>t.snapshot().site??{},t)}function ot(t="topbar"){const e=nt();return lt(e),new P(()=>e.snapshot().menus[t]??{position:t,items:[]},e)}function ct(){return st().getAssets()}function ut(t){return function(t,e){const r=tt(t),n=function(t){const e=String(t??"").trim();if(e.includes("/")){const[t,...r]=e.split("/");return{vendor:t||"miroart",slug:et(r.join("/")||e)}}return{vendor:"miroart",slug:et(e)}}(t);return new Proxy({name:t,key:r,ready:async()=>async function(t){const e=Date.now();for(;Date.now()-e<4e3;){const e=rt(t);if(Object.keys(e).length)return e;await new Promise(t=>setTimeout(t,50))}return rt(t)}(r),api:()=>rt(r),call:(t,...e)=>{const n=rt(r),s=n[t];if("function"!=typeof s)throw new Error(`Missing plugin method: ${t}`);return s.apply(n,e)},request:async(t="/",r={})=>{const s=l().plugins(n.vendor,n.slug,t||"/"),i=new Headers(r.headers);let o=r.body;return void 0!==r.json&&(o=JSON.stringify(r.json)),p(await e.request(s,{...r,headers:i,body:o}))}},{get(t,e,n){if(e in t)return Reflect.get(t,e,n);if("then"===e||e===Symbol.toStringTag)return;const s=rt(r),i=s[String(e)];return"function"==typeof i?i.bind(s):i},has:(t,e)=>e in t||e in rt(r)})}(t,Q())}function at(){const t=Q();return{apiBase:e(()=>t.apiBase()),siteBase:e(()=>t.siteBase()),siteRef:e(()=>t.siteRef())}}function lt(t){try{const e=function(){try{return ht??null}catch{return null}}();if(!e)return;const n=e.usePage();t.hydrate(r(n))}catch{}}let ht=null;import("@inertiajs/vue3").then(t=>{ht=t}).catch(()=>{ht=null});const pt=Y;export{E as Asset,_ as AssetName,N as Gallery,P as Menu,I as MenuItem,A as MenuTitle,Y as Miro,C as OptionValue,L as Page,b as PageContent,w as PageSmallTitle,S as PageSubtitle,$ as PageSummary,y as PageTitle,K as SDK_KEY,U as SeoDescription,x as SeoTitle,M as Site,R as SiteName,k as SiteTitle,m as TextValue,j as UrlValue,X as createMiro,F as createRuntime,pt as default,G as getRuntime,tt as pluginWindowKey,Q as useKernel,ct as useMiroAssets,at as useMiroConfig,ot as useMiroMenu,st as useMiroPage,it as useMiroSite,ut as usePlugin};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { InjectionKey, Plugin } from "vue";
|
|
2
|
+
import type { Kernel } from "./context";
|
|
3
|
+
import { Runtime } from "./runtime";
|
|
4
|
+
import type { ClientOptions } from "./types";
|
|
5
|
+
export declare const SDK_KEY: InjectionKey<Runtime>;
|
|
6
|
+
export declare function useKernel(): Runtime;
|
|
7
|
+
export declare function createMiro(options?: ClientOptions): Plugin;
|
|
8
|
+
export declare const Miro: Plugin;
|
|
9
|
+
export type { Kernel };
|
package/dist/menu.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { MenuTitle, UrlValue } from "./values";
|
|
2
|
+
import type { MenuItemRecord, MenuRecord } from "./types";
|
|
3
|
+
import type { Kernel } from "./context";
|
|
4
|
+
export declare class MenuItem {
|
|
5
|
+
private readonly record;
|
|
6
|
+
constructor(record: MenuItemRecord);
|
|
7
|
+
getTitle(): MenuTitle;
|
|
8
|
+
getUrl(): UrlValue;
|
|
9
|
+
getChildren(): MenuItem[];
|
|
10
|
+
raw(): MenuItemRecord;
|
|
11
|
+
}
|
|
12
|
+
export declare class Menu {
|
|
13
|
+
private readonly source;
|
|
14
|
+
private readonly runtime;
|
|
15
|
+
constructor(source: MenuRecord | (() => MenuRecord), runtime: Kernel);
|
|
16
|
+
private get record();
|
|
17
|
+
static find(key: string, site?: string | number): Promise<Menu>;
|
|
18
|
+
getName(): MenuTitle;
|
|
19
|
+
getPosition(): string;
|
|
20
|
+
getItems(): MenuItem[];
|
|
21
|
+
raw(): MenuRecord;
|
|
22
|
+
}
|
|
23
|
+
export declare function itemsFromUnknown(value: unknown): MenuItem[];
|
|
24
|
+
export declare function bindMenuRuntime(runtime: Kernel): void;
|
package/dist/page.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Gallery } from "./asset";
|
|
2
|
+
import type { Kernel } from "./context";
|
|
3
|
+
import { OptionValue, PageContent, PageSmallTitle, PageSubtitle, PageSummary, PageTitle, SeoDescription, SeoTitle, UrlValue } from "./values";
|
|
4
|
+
import type { Dict, PageRecord } from "./types";
|
|
5
|
+
import { Site } from "./site";
|
|
6
|
+
export declare class Page {
|
|
7
|
+
private source;
|
|
8
|
+
private readonly kernel;
|
|
9
|
+
constructor(source: PageRecord | (() => PageRecord), kernel: Kernel);
|
|
10
|
+
private get record();
|
|
11
|
+
private setRecord;
|
|
12
|
+
static findByUlid(id: string, site?: string | number): Promise<Page>;
|
|
13
|
+
static find(id: string, site?: string | number): Promise<Page>;
|
|
14
|
+
static search(query: string, site?: string | number): Promise<Page[]>;
|
|
15
|
+
getTitle(): PageTitle;
|
|
16
|
+
getSubtitle(): PageSubtitle;
|
|
17
|
+
getSmallTitle(): PageSmallTitle;
|
|
18
|
+
getSummary(): PageSummary;
|
|
19
|
+
getContent(): PageContent;
|
|
20
|
+
getSlug(): string;
|
|
21
|
+
getUrl(): UrlValue;
|
|
22
|
+
getUuid(): string;
|
|
23
|
+
getId(): string;
|
|
24
|
+
getLayout(): string;
|
|
25
|
+
getDisplay(): string;
|
|
26
|
+
getOption(key: string): OptionValue;
|
|
27
|
+
getSeo(): {
|
|
28
|
+
title: SeoTitle;
|
|
29
|
+
description: SeoDescription;
|
|
30
|
+
raw: Dict;
|
|
31
|
+
};
|
|
32
|
+
getAssets(): Gallery;
|
|
33
|
+
getChildren(): Promise<Page[]>;
|
|
34
|
+
getSiblings(): Promise<Page[]>;
|
|
35
|
+
getParent(): Promise<Page | null>;
|
|
36
|
+
getSite(): Promise<Site>;
|
|
37
|
+
load(): Promise<this>;
|
|
38
|
+
raw(): PageRecord;
|
|
39
|
+
private siteRef;
|
|
40
|
+
private excludeSelf;
|
|
41
|
+
private ensure;
|
|
42
|
+
}
|
|
43
|
+
export declare function bindPageRuntime(kernel: Kernel): void;
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function pack(bytes: number[]): string;
|
|
2
|
+
export declare function joinUrl(base: string, path: string): string;
|
|
3
|
+
/** Packed public catalog paths — reconstructed at runtime. */
|
|
4
|
+
export declare function catalog(): {
|
|
5
|
+
sites: () => string;
|
|
6
|
+
site: (site: string) => string;
|
|
7
|
+
pages: (site: string) => string;
|
|
8
|
+
page: (site: string, page: string) => string;
|
|
9
|
+
search: (site: string) => string;
|
|
10
|
+
menus: (site: string) => string;
|
|
11
|
+
menu: (site: string, menu: string) => string;
|
|
12
|
+
media: (uuid: string) => string;
|
|
13
|
+
plugins: (vendor: string, slug: string, rest?: string) => string;
|
|
14
|
+
};
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Kernel } from "./context";
|
|
2
|
+
import type { PluginRequestInit } from "./types";
|
|
3
|
+
export type PluginHandle = {
|
|
4
|
+
name: string;
|
|
5
|
+
key: string;
|
|
6
|
+
ready: () => Promise<Record<string, unknown>>;
|
|
7
|
+
api: () => Record<string, unknown>;
|
|
8
|
+
call: (method: string, ...args: unknown[]) => unknown;
|
|
9
|
+
request: <T = unknown>(path?: string, init?: PluginRequestInit) => Promise<T>;
|
|
10
|
+
} & Record<string, unknown>;
|
|
11
|
+
export declare function pluginWindowKey(name: string): string;
|
|
12
|
+
export declare function pluginSlugParts(name: string): {
|
|
13
|
+
vendor: string;
|
|
14
|
+
slug: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function createPluginHandle(name: string, kernel: Kernel): PluginHandle;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Kernel } from "./context";
|
|
2
|
+
import type { ClientOptions, MenuRecord, PageRecord, SiteRecord, Snapshot } from "./types";
|
|
3
|
+
export declare class Runtime implements Kernel {
|
|
4
|
+
private snap;
|
|
5
|
+
private readonly options;
|
|
6
|
+
constructor(options?: ClientOptions);
|
|
7
|
+
hydrate(payload: unknown): Snapshot;
|
|
8
|
+
snapshot(): Snapshot;
|
|
9
|
+
apiBase(): string;
|
|
10
|
+
siteBase(): string;
|
|
11
|
+
siteRef(): string;
|
|
12
|
+
request<T = unknown>(path: string, init?: RequestInit): Promise<T>;
|
|
13
|
+
rememberPage(record: PageRecord): void;
|
|
14
|
+
rememberSite(record: SiteRecord): void;
|
|
15
|
+
rememberMenu(record: MenuRecord): void;
|
|
16
|
+
}
|
|
17
|
+
export declare function createRuntime(options?: ClientOptions): Runtime;
|
|
18
|
+
export declare function getRuntime(): Runtime;
|
|
19
|
+
export declare function hydrateFromUnknown(payload: unknown): Snapshot;
|
package/dist/site.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Kernel } from "./context";
|
|
2
|
+
import { Menu } from "./menu";
|
|
3
|
+
import { Page } from "./page";
|
|
4
|
+
import { OptionValue, SiteName, SiteTitle } from "./values";
|
|
5
|
+
import type { SiteRecord } from "./types";
|
|
6
|
+
export declare class Site {
|
|
7
|
+
private readonly source;
|
|
8
|
+
private readonly kernel;
|
|
9
|
+
constructor(source: SiteRecord | (() => SiteRecord), kernel: Kernel);
|
|
10
|
+
private get record();
|
|
11
|
+
static find(id?: string | number): Promise<Site>;
|
|
12
|
+
static findPage(id: string, site?: string | number): Promise<Page>;
|
|
13
|
+
static findMenu(key: string, site?: string | number): Promise<Menu>;
|
|
14
|
+
getName(): SiteName;
|
|
15
|
+
getTitle(): SiteTitle;
|
|
16
|
+
getDomain(): string;
|
|
17
|
+
getLang(): string;
|
|
18
|
+
getUuid(): string;
|
|
19
|
+
getOption(key: string): OptionValue;
|
|
20
|
+
findPage(id: string): Promise<Page>;
|
|
21
|
+
findMenu(key: string): Promise<Menu>;
|
|
22
|
+
menus(): Promise<Menu[]>;
|
|
23
|
+
pages(query?: Record<string, string | number | boolean>): Promise<Page[]>;
|
|
24
|
+
raw(): SiteRecord;
|
|
25
|
+
private ref;
|
|
26
|
+
}
|
|
27
|
+
export declare function bindSiteRuntime(kernel: Kernel): void;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export type Json = null | boolean | number | string | Json[] | {
|
|
2
|
+
[key: string]: Json;
|
|
3
|
+
};
|
|
4
|
+
export type Dict = Record<string, unknown>;
|
|
5
|
+
export type PageRecord = Dict & {
|
|
6
|
+
id?: number | string;
|
|
7
|
+
uuid?: string;
|
|
8
|
+
ulid?: string;
|
|
9
|
+
parent_id?: number | string | null;
|
|
10
|
+
site_id?: number | string;
|
|
11
|
+
slug?: string;
|
|
12
|
+
full_url?: string;
|
|
13
|
+
title?: string;
|
|
14
|
+
subtitle?: string;
|
|
15
|
+
smalltitle?: string;
|
|
16
|
+
summary?: string;
|
|
17
|
+
content?: string;
|
|
18
|
+
layout?: string;
|
|
19
|
+
display?: string;
|
|
20
|
+
options?: unknown;
|
|
21
|
+
assets?: unknown;
|
|
22
|
+
children?: unknown;
|
|
23
|
+
siblings?: unknown;
|
|
24
|
+
parent?: unknown;
|
|
25
|
+
site?: unknown;
|
|
26
|
+
seo?: unknown;
|
|
27
|
+
};
|
|
28
|
+
export type SiteRecord = Dict & {
|
|
29
|
+
id?: number | string;
|
|
30
|
+
uuid?: string;
|
|
31
|
+
name?: string;
|
|
32
|
+
domain?: string;
|
|
33
|
+
lang?: string;
|
|
34
|
+
options?: unknown;
|
|
35
|
+
};
|
|
36
|
+
export type MenuRecord = Dict & {
|
|
37
|
+
id?: number | string;
|
|
38
|
+
uuid?: string;
|
|
39
|
+
name?: string;
|
|
40
|
+
position?: string | null;
|
|
41
|
+
items?: unknown;
|
|
42
|
+
};
|
|
43
|
+
export type AssetRecord = Dict & {
|
|
44
|
+
id?: number | string;
|
|
45
|
+
uuid?: string;
|
|
46
|
+
name?: string;
|
|
47
|
+
url?: string;
|
|
48
|
+
path?: string;
|
|
49
|
+
mime_type?: string;
|
|
50
|
+
sort_order?: number;
|
|
51
|
+
};
|
|
52
|
+
export type MenuItemRecord = Dict & {
|
|
53
|
+
id?: number | string;
|
|
54
|
+
title?: string;
|
|
55
|
+
url?: string;
|
|
56
|
+
children?: unknown;
|
|
57
|
+
};
|
|
58
|
+
export type Snapshot = {
|
|
59
|
+
page: PageRecord | null;
|
|
60
|
+
site: SiteRecord | null;
|
|
61
|
+
menus: Record<string, MenuRecord | null>;
|
|
62
|
+
locales: unknown[];
|
|
63
|
+
seo: Dict | null;
|
|
64
|
+
options: Dict;
|
|
65
|
+
};
|
|
66
|
+
export type ClientOptions = {
|
|
67
|
+
apiBase?: string;
|
|
68
|
+
siteBase?: string;
|
|
69
|
+
site?: string | number;
|
|
70
|
+
page?: {
|
|
71
|
+
props?: Dict;
|
|
72
|
+
} | Dict;
|
|
73
|
+
fetch?: typeof fetch;
|
|
74
|
+
};
|
|
75
|
+
export type PluginRequestInit = RequestInit & {
|
|
76
|
+
json?: unknown;
|
|
77
|
+
};
|
package/dist/values.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export type TextKind = "PageTitle" | "PageSubtitle" | "PageSmallTitle" | "PageSummary" | "PageContent" | "SiteTitle" | "SiteName" | "OptionValue" | "UrlValue" | "MenuTitle" | "AssetName" | "SeoTitle" | "SeoDescription" | "PlainText";
|
|
2
|
+
type Extra = Record<string, unknown>;
|
|
3
|
+
export declare class TextValue extends String {
|
|
4
|
+
readonly kind: TextKind;
|
|
5
|
+
readonly extra: Extra;
|
|
6
|
+
constructor(kind: TextKind, value: unknown, extra?: Extra);
|
|
7
|
+
toString(): string;
|
|
8
|
+
valueOf(): string;
|
|
9
|
+
raw(): string;
|
|
10
|
+
decode(): string;
|
|
11
|
+
cleanContent(): string;
|
|
12
|
+
stripHtml(): string;
|
|
13
|
+
excerpt(length?: number): string;
|
|
14
|
+
firstParagraph(): string;
|
|
15
|
+
isEmpty(): boolean;
|
|
16
|
+
json<T = unknown>(): T | null;
|
|
17
|
+
bool(): boolean;
|
|
18
|
+
number(): number | null;
|
|
19
|
+
}
|
|
20
|
+
export declare class PageTitle extends TextValue {
|
|
21
|
+
constructor(value: unknown);
|
|
22
|
+
}
|
|
23
|
+
export declare class PageSubtitle extends TextValue {
|
|
24
|
+
constructor(value: unknown);
|
|
25
|
+
}
|
|
26
|
+
export declare class PageSmallTitle extends TextValue {
|
|
27
|
+
constructor(value: unknown);
|
|
28
|
+
}
|
|
29
|
+
export declare class PageSummary extends TextValue {
|
|
30
|
+
constructor(value: unknown);
|
|
31
|
+
}
|
|
32
|
+
export declare class PageContent extends TextValue {
|
|
33
|
+
constructor(value: unknown);
|
|
34
|
+
html(): string;
|
|
35
|
+
}
|
|
36
|
+
export declare class SiteTitle extends TextValue {
|
|
37
|
+
constructor(value: unknown);
|
|
38
|
+
}
|
|
39
|
+
export declare class SiteName extends TextValue {
|
|
40
|
+
constructor(value: unknown);
|
|
41
|
+
}
|
|
42
|
+
export declare class OptionValue extends TextValue {
|
|
43
|
+
readonly key: string;
|
|
44
|
+
constructor(key: string, value: unknown);
|
|
45
|
+
present(): boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare class UrlValue extends TextValue {
|
|
48
|
+
constructor(value: unknown);
|
|
49
|
+
path(): string;
|
|
50
|
+
href(base?: string): string;
|
|
51
|
+
}
|
|
52
|
+
export declare class MenuTitle extends TextValue {
|
|
53
|
+
constructor(value: unknown);
|
|
54
|
+
}
|
|
55
|
+
export declare class AssetName extends TextValue {
|
|
56
|
+
constructor(value: unknown);
|
|
57
|
+
}
|
|
58
|
+
export declare class SeoTitle extends TextValue {
|
|
59
|
+
constructor(value: unknown);
|
|
60
|
+
}
|
|
61
|
+
export declare class SeoDescription extends TextValue {
|
|
62
|
+
constructor(value: unknown);
|
|
63
|
+
}
|
|
64
|
+
export declare function optionFromBag(bag: unknown, key: string): unknown;
|
|
65
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@miroart/sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Vue 3 client for preloaded page data and a remote JSON origin.",
|
|
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
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"sideEffects": false,
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=20"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "vite build && vue-tsc -p tsconfig.build.json --emitDeclarationOnly",
|
|
27
|
+
"dev": "vite build --watch",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"prepublishOnly": "npm run build"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"vue": "^3.4.0"
|
|
33
|
+
},
|
|
34
|
+
"peerDependenciesMeta": {
|
|
35
|
+
"@inertiajs/vue3": {
|
|
36
|
+
"optional": true
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@inertiajs/vue3": "^2.0.0",
|
|
41
|
+
"terser": "^5.43.0",
|
|
42
|
+
"typescript": "^5.9.2",
|
|
43
|
+
"vite": "^7.0.7",
|
|
44
|
+
"vite-plugin-dts": "^4.5.4",
|
|
45
|
+
"vitest": "^3.2.4",
|
|
46
|
+
"vue": "^3.5.13",
|
|
47
|
+
"vue-tsc": "^2.2.12"
|
|
48
|
+
},
|
|
49
|
+
"keywords": [
|
|
50
|
+
"vue",
|
|
51
|
+
"client"
|
|
52
|
+
],
|
|
53
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"access": "public"
|
|
56
|
+
}
|
|
57
|
+
}
|