@velora-cms/server 0.11.0 → 0.12.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/dist/admin/sync-admin-bundle.d.ts +9 -0
- package/dist/admin/sync-admin-bundle.js +120 -0
- package/dist/admin-bundle/.velora-version +1 -0
- package/dist/admin-bundle/assets/{_virtual_mf-localSharedImportMap___mfe_internal__velora_admin__mf_owner__1-DOKdWYyj.js → _virtual_mf-localSharedImportMap___mfe_internal__velora_admin__mf_owner__1-DlIgIuFP.js} +1 -1
- package/dist/admin-bundle/assets/{_virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare___mf_0_velora_mf_2_cms_mf_1_plugin_mf_2_sdk__loadShare__.js-C1-ZAxwO.js → _virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare___mf_0_velora_mf_2_cms_mf_1_plugin_mf_2_sdk__loadShare__.js-Bm9EahCG.js} +2 -2
- package/dist/admin-bundle/assets/{content-trash.schema-DfXHkC-w.js → content-trash.schema-tvJ4Lbos.js} +5 -5
- package/dist/admin-bundle/assets/{hostInit--C4xK6nj.js → hostInit-B-6-34XY.js} +1 -1
- package/dist/admin-bundle/assets/{index-DhMY-0sC.js → index-CHCGuSbb.js} +1 -1
- package/dist/admin-bundle/assets/{index-BIAF0ShP.js → index-DYO7-IK8.js} +33 -33
- package/dist/admin-bundle/assets/{mf-entry-bootstrap-0-aef015cd.js → mf-entry-bootstrap-0-7b0ce2fe.js} +2 -2
- package/dist/admin-bundle/assets/{remoteEntry-CNyN68bc.js → remoteEntry-J2yJXsGB.js} +2 -2
- package/dist/admin-bundle/index.html +4 -4
- package/dist/app.d.ts +16 -1
- package/dist/app.js +63 -4
- package/dist/auth/api-keys.d.ts +1 -0
- package/dist/auth/api-keys.js +5 -1
- package/dist/auth/route-rate-limits.d.ts +4 -0
- package/dist/auth/route-rate-limits.js +13 -0
- package/dist/bin-sync-admin.d.ts +2 -0
- package/dist/bin-sync-admin.js +39 -0
- package/dist/bundled-templates/com.velora.blog/package.tar.gz +0 -0
- package/dist/config/public-url.d.ts +3 -0
- package/dist/config/public-url.js +45 -0
- package/dist/db/core-migrations/steps.js +95 -16
- package/dist/docs-bundle/pagefind/fragment/en_42f5356.pf_fragment +0 -0
- package/dist/docs-bundle/pagefind/fragment/en_67dccf8.pf_fragment +0 -0
- package/dist/docs-bundle/pagefind/fragment/en_80941b8.pf_fragment +0 -0
- package/dist/docs-bundle/pagefind/fragment/en_a64440b.pf_fragment +0 -0
- package/dist/docs-bundle/pagefind/fragment/en_eb168aa.pf_fragment +0 -0
- package/dist/docs-bundle/pagefind/index/en_8450ec7.pf_index +0 -0
- package/dist/docs-bundle/pagefind/index/en_c285f7b.pf_index +0 -0
- package/dist/docs-bundle/pagefind/index/en_e8cada7.pf_index +0 -0
- package/dist/docs-bundle/pagefind/pagefind-entry.json +1 -1
- package/dist/docs-bundle/pagefind/pagefind.en_57d2f8922f.pf_meta +0 -0
- package/dist/docs-bundle/v1/using-velora/getting-started/index.html +5 -3
- package/dist/docs-bundle/v1/using-velora/headless-api/index.html +10 -4
- package/dist/docs-bundle/v1/using-velora/index.html +6 -4
- package/dist/docs-bundle/v1/using-velora/installation/index.html +73 -15
- package/dist/docs-bundle/v1/using-velora/media/index.html +118 -34
- package/dist/graphql/schema.d.ts +1 -0
- package/dist/graphql/schema.js +5 -2
- package/dist/lib.d.ts +1 -0
- package/dist/lib.js +45 -11
- package/dist/media/media-service.d.ts +14 -15
- package/dist/media/media-service.js +121 -59
- package/dist/media/media-tokens.d.ts +6 -0
- package/dist/media/media-tokens.js +88 -0
- package/dist/media/storage/local.d.ts +16 -0
- package/dist/media/storage/local.js +99 -0
- package/dist/media/storage/s3.d.ts +25 -0
- package/dist/media/storage/s3.js +134 -0
- package/dist/media/storage/types.d.ts +21 -0
- package/dist/media/storage/types.js +44 -0
- package/dist/routes/admin-static.d.ts +2 -0
- package/dist/routes/admin-static.js +42 -4
- package/dist/routes/media-public.d.ts +6 -0
- package/dist/routes/media-public.js +265 -0
- package/dist/routes/media.d.ts +2 -1
- package/dist/routes/media.js +95 -5
- package/dist/routes/plugin-storage.js +5 -1
- package/dist/routes/public-api.js +5 -3
- package/dist/routes/published-item.d.ts +2 -1
- package/dist/routes/published-item.js +28 -5
- package/dist/scripts/copy-admin-bundle.js +9 -1
- package/package.json +7 -6
- package/prisma/schema.prisma +16 -3
- package/dist/docs-bundle/pagefind/fragment/en_1d9eb24.pf_fragment +0 -0
- package/dist/docs-bundle/pagefind/fragment/en_3099406.pf_fragment +0 -0
- package/dist/docs-bundle/pagefind/fragment/en_9aa652e.pf_fragment +0 -0
- package/dist/docs-bundle/pagefind/fragment/en_d855550.pf_fragment +0 -0
- package/dist/docs-bundle/pagefind/fragment/en_e6d88d8.pf_fragment +0 -0
- package/dist/docs-bundle/pagefind/index/en_5feeed7.pf_index +0 -0
- package/dist/docs-bundle/pagefind/index/en_c6981f9.pf_index +0 -0
- package/dist/docs-bundle/pagefind/index/en_ce4f6bf.pf_index +0 -0
- package/dist/docs-bundle/pagefind/pagefind.en_1e94abd852.pf_meta +0 -0
|
@@ -27,7 +27,7 @@ const __mfImport = (src) =>
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
(async () => {
|
|
30
|
-
const __mfHostInit = await __mfImport("./hostInit
|
|
30
|
+
const __mfHostInit = await __mfImport("./hostInit-B-6-34XY.js");
|
|
31
31
|
await __mfHostInit.__tla;
|
|
32
32
|
const { initHost } = __mfHostInit;
|
|
33
33
|
await initHost();
|
|
@@ -38,4 +38,4 @@ const __mfImport = (src) =>
|
|
|
38
38
|
if (__mfReactServerModuleCache?.pendingShareLoads) {
|
|
39
39
|
await Promise.all(__mfReactServerModuleCache.pendingShareLoads);
|
|
40
40
|
}
|
|
41
|
-
})().then(() => __mfImport("./index-
|
|
41
|
+
})().then(() => __mfImport("./index-DYO7-IK8.js"));
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-Do71v6NZ.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{_ as xe}from"./vite-preload-helper-Cgledu0r.js";import{h as ct,i as lt}from"./index-Do71v6NZ.js";const dt=ct.share;typeof __VUE_HMR_RUNTIME__>"u"&&(globalThis.__VUE_HMR_RUNTIME__={createRecord(){},rerender(){},reload(){}});const Ne="__mf_init__virtual:mf:__mfe_internal__velora_admin__mf_owner__1__mf_v__runtimeInit__mf_v__.js__";let de=globalThis[Ne];if(!de){let s,f;const u=new Promise((h,C)=>{s=h,f=C});de=globalThis[Ne]={initPromise:u,initResolve:s,initReject:f}}const ut=de.initResolve,re="__mf_module_cache__";globalThis[re]||={share:{},remote:{}};globalThis[re].share||={};globalThis[re].remote||={};const d=globalThis[re];for(const s of Object.keys(d.share))if(s.startsWith("default:")){const f=s.slice(8);d.share[f]===void 0&&(d.share[f]=d.share[s])}else if(!s.includes(":")){const f="default:"+s;d.share[f]===void 0&&(d.share[f]=d.share[s])}const Te={},mt=Array.isArray("default")?"default":["default"],Fe="default",A="velora_admin",ce=[["react"],["react/jsx-runtime","react-dom","@velora-cms/plugin-sdk"],["react-dom/client"]];let ee,te,ue;async function _e(s){for(let f=0;;f++)try{return await s()}catch(u){throw u}}const Le=Symbol("mf.originalSharedProvider"),_t={emit:s=>s},ht=(s,f)=>{if(f!=="version-first")return s;const u={};for(const[h,C]of Object.entries(s))u[h]=Object.assign({},C,{[Le]:C});return u},le=(s,f)=>{if(!f)return;const u=Object.entries(s||{}),h=u.find(([,p])=>p===f);if(h)return{version:h[0],provider:f,registered:!0};if(typeof f.version=="string"&&f.version)return{version:f.version,provider:f,registered:!1};const C=u.filter(([,p])=>p===f||!!(f.from&&(p==null?void 0:p.from)===f.from));if(C.length===1)return{version:C[0][0],provider:f,registered:!1}},me=(s,f,u,h)=>{var E;if(!s||!u)return;const C=Array.isArray(u.scope)?u.scope:[u.scope||"default"],p=ht(s,h),x={};for(const D of C)x[D||"default"]={[f]:p};const P=(E=dt.getRegisteredShare(x,f,{...u,scope:C,strategy:h},_t))==null?void 0:E.shared;return(P==null?void 0:P[Le])||P},U=(s,f,u,h)=>{var P;const C=E=>k(E,u),p=Object.fromEntries(Object.entries(s||{}).filter(([,E])=>!C(E)));u!=null&&u.version&&((P=u.shareConfig)==null?void 0:P.import)!==!1&&(p[u.version]||(p[u.version]=u));const x=me(p,f,u,h);return C(x)?void 0:x},k=(s,f)=>s===f||!!(f!=null&&f.from&&(s==null?void 0:s.from)===f.from),gt=(s,f,u,h,C,p,x,P,E)=>{var B,J,W;if(!P)return;const D=(J=(B=f==null?void 0:f.options)==null?void 0:B.shared)==null?void 0:J[C],K=Array.isArray(D)?D.find(N=>(N==null?void 0:N.version)===p):void 0,V=((P==null?void 0:P.from)===((W=f==null?void 0:f.options)==null?void 0:W.name)?P:void 0)||(k(K,P)?K:f?void 0:P);return V&&s.some(N=>{var q,M;return N!==f&&((q=N==null?void 0:N.options)==null?void 0:q.name)===(x==null?void 0:x.from)&&((M=N==null?void 0:N.shareScopeMap)==null?void 0:M[h])===u})?V:void 0},vt=(s,f,u,h,C,p,x,P,E)=>{const D=p.registered?gt(s,f,u,h,C,p.version,p.provider,P):void 0,K=D||x;if(K&&!(p.registered&&!k(K,P)))return{provider:K,scopeRootProvider:D}};async function bt(){return ee||(ee=_e(()=>xe(()=>import("./_virtual_mf-localSharedImportMap___mfe_internal__velora_admin__mf_owner__1-DOKdWYyj.js"),__vite__mapDeps([0]))).catch(s=>{throw ee=void 0,s})),ee}async function yt(){return te||(te=_e(()=>xe(()=>import("./virtualExposes-BDCSo5OS.js"),[])).then(s=>s.default??s).catch(s=>{throw te=void 0,s})),te}async function Pt(s={},f=[]){var we,je,Re,Ce,Ee;const u=(t,e,r,n)=>{const o=(Array.isArray(n)?n[0]:n)||"default",c=e||!r?t:t+"@"+r,a={canonical:o+":"+c};return o==="default"&&(a.aliases=[c]),a},h=(t,e)=>{const r=t[e.canonical];if(r!==void 0)return r;const n=e.aliases||[];for(const i of n){if(!Object.prototype.hasOwnProperty.call(t,i))continue;const o=t[i];if(o!==void 0)return t[e.canonical]=o,o}},C=Symbol.for("module-federation.shared-cache-listeners"),p=Symbol.for("module-federation.shared-cache-owners"),x=t=>{let e=t[p];return e===void 0&&(e=Object.create(null),Object.defineProperty(t,p,{value:e,enumerable:!1,configurable:!1,writable:!1})),e},P=(t,e)=>{var r;return(r=t[p])==null?void 0:r[e.canonical]},E=(t,e,r,n)=>{var a;t[e.canonical]=r;const i=e.aliases||[];for(const l of i)Object.defineProperty(t,l,{value:r,enumerable:!0,configurable:!0,writable:!0});const o=t[p];n===void 0?o&&delete o[e.canonical]:x(t)[e.canonical]=n;const c=(a=t[C])==null?void 0:a[e.canonical];if(c)for(const l of c)l(r);return r},D=Symbol.for("module-federation.tree-shaking-shared-cache"),K=t=>{let e=t[D];return e===void 0&&(e=Object.create(null),Object.defineProperty(t,D,{value:e,enumerable:!1,configurable:!1,writable:!1})),e},he=(t,e,r,n)=>{if(!Array.isArray(r))return n;const i=[...new Set(r)].sort(),o=K(t),c=o[e.canonical]||=[],a=c.find(l=>l.providedExports.length===i.length&&l.providedExports.every((b,m)=>b===i[m]));return a?a.value=n:c.push({providedExports:i,value:n}),n},V=Symbol.for("module-federation.tree-shaking-shared-selection-cache"),ge=t=>{let e=t[V];return e===void 0&&(e=Object.create(null),Object.defineProperty(t,V,{value:e,enumerable:!1,configurable:!1,writable:!1})),e},B=(t,e,r)=>{var i,o;const n=h(t,e);return n!==void 0?n:(o=(i=t[V])==null?void 0:i[e.canonical])==null?void 0:o[r]},J=(t,e,r,n)=>{const i=ge(t),o=i[e.canonical]||=Object.create(null);return o[r]=n,n},W=((we=globalThis.__FEDERATION__)==null?void 0:we.__INSTANCES__)||[],N=(je=f.find(t=>t==null?void 0:t.from))==null?void 0:je.from,q=W.find(t=>{var e,r;return((e=t==null?void 0:t.options)==null?void 0:e.name)===N&&((r=t==null?void 0:t.shareScopeMap)==null?void 0:r.default)===s})||W.find(t=>{var e,r;return((e=t==null?void 0:t.options)==null?void 0:e.name)!==A&&((r=t==null?void 0:t.shareScopeMap)==null?void 0:r.default)===s}),M=Object.create(null),Ae=t=>{const e=Object.create(null);for(const[r,n]of Object.entries(t||{}))e[r]=Object.assign(Object.create(null),n);return e},ke=(t,e)=>{const r=!q&&Object.values(e||{}).some(i=>Object.values(i||{}).some(Q)),n=r?Ae(e):e;return M[t]={host:e,runtime:n,isWebpackScope:r},n},De=()=>{const t=Object.values(M).filter(({isWebpackScope:e})=>e);if(t.length!==0)for(const{host:e,runtime:r}of t)for(const[n,i]of Object.entries(e||{})){const o=r[n]||=Object.create(null);for(const[c,a]of Object.entries(i||{}))o[c]=a}},z=Object.create(null);for(const[t,e]of Object.entries(s)){const r=z[t]=Object.create(null);for(const[n,i]of Object.entries(e))r[n]=Object.assign({},i)}const{usedShared:I,usedRemotes:ze}=await bt();function Q(t){if(typeof(t==null?void 0:t.get)!="function")return!1;const e=Function.prototype.toString.call(t.get);return e.includes("__webpack_require__")||/\.\s*e\s*\([^)]*\)\s*\.then\s*\(/.test(e)}const Ke=Object.values(z).some(t=>Object.values(t||{}).some(Q)),Be=t=>{const e=t.split("/");return t.startsWith("@")?e.slice(0,2).join("/"):e[0]},ne=(t,e,r)=>{if(typeof U!="function")return;const n=Be(t),i=n===t?[[t,e]]:[[t,e],[n,I[n]]];for(const[o,c]of i){if(!c)continue;const a=r?o===t?r:z[o]:s[o],l=U(a,o,c,"version-first");if(l&&Q(l)&&!l.lib&&!l.loaded)return l}};var X=Te[Fe];if(X||(X=Te[Fe]={from:A}),f.indexOf(X)>=0)return;f.push(X);const ve=t=>{let e=t;for(let r=0;r<5;r++){const n=e==null?void 0:e.default;if(!n||typeof n!="object"||Object.keys(n).length===0)break;const i=Object.keys(e).filter(o=>o!=="default").map(o=>e[o]);if(i.length>0&&i.some(o=>o!==void 0))break;e=n}return e},Ge=[],Ve=typeof globalThis.window>"u"?await Promise.all([]):[],oe="__mf_vite_runtime_share_load_id__";let We=0;const ie=new Map,se=new Map,H=lt({name:A,remotes:ze,shared:I,plugins:[He(),Ue(),...Ge,...Ve],shareStrategy:"version-first"});H.initShareScopeMap("default",ke("default",s));function He(){return{name:"vite-share-pin-lifecycle-plugin",resolveShare(t){var i;const e=(i=t.shareInfo)==null?void 0:i[oe],r=e===void 0?void 0:se.get(e);if(!r)return t;const n=t.resolver;return t.resolver=(...o)=>(r.pinned.reapply(),n(...o)),r.pinned.reveal(),t}}}function Ue(){return{name:"vite-real-name-snapshot-plugin",afterLoadSnapshot(t){const e=t&&t.remoteSnapshot,r=e&&e.globalName,n=e&&e.version;if(!r||!n||!e.remoteEntry)return t;const i=globalThis.__FEDERATION__&&globalThis.__FEDERATION__.moduleInfo,o=r+":"+n;return i&&!i[o]&&(i[o]=e),t}}}const qe=H.sharedHandler.hooks.lifecycle.resolveShare,Y=new WeakMap;qe.on(t=>{var i;const e=(i=t.shareInfo)==null?void 0:i[oe],r=t.resolver;if(typeof r!="function")return t;const n=(...o)=>{const c=r(...o),a=c==null?void 0:c.shared;return a&&(typeof a=="object"||typeof a=="function")&&!Y.has(a)&&Y.set(a,{from:a.from}),e!==void 0&&a&&ie.set(e,a),c};return t.resolver=n,t});const Me=(t,e,r,n)=>{if(!t||t[e]!==r)return;const i=Object.assign({},n,{version:n.version??e,scope:n.scope??(r==null?void 0:r.scope)??["default"],strategy:"loaded-first"}),o=n.from;t[e]=i;const c=()=>r===void 0?t[e]===void 0:t[e]===r;return{provider:i,reveal(){return t[e]!==i?!1:(r===void 0?delete t[e]:t[e]=r,!0)},reapply(){return c()?(t[e]=i,!0):!1},release(a,l=!0){return n.from=o,t[e]!==i?!l&&c():l?a?(i.from=o,a&&i.lib&&(i.loaded=!0),n.strategy===void 0?delete i.strategy:i.strategy=n.strategy,!0):(r===void 0?delete t[e]:t[e]=r,!1):(r===void 0?delete t[e]:t[e]=r,!0)}}},Je=t=>Object.entries(t||{}).map(([e,r])=>({provider:r,version:e,from:r.from,registered:!0})),Qe=(t,e)=>{if(e===void 0)return;let r;for(const n of t){const i=n.provider,o=i.treeShaking||i;if(!(n.loadedFactory!==e&&i.lib!==e&&o.lib!==e)){if(r)return;r=n}}return r},Xe=async(t,e,r)=>{const n=++We;se.set(n,{pinned:r});try{const i=await H.loadShare(t,{customShareInfo:{shareConfig:e,[oe]:n}});return{factory:i===!1?void 0:i,selectedProvider:ie.get(n)}}finally{ie.delete(n),se.delete(n)}},be=async(t,e,r,n,i,o,c=!0)=>{const a=o.from,l=Me(r,n,i,o);if(!l)return;let b;try{b=await Xe(t,e,l)}catch(j){throw l.release(!1),j}const m=b==null?void 0:b.factory;if(m===void 0){l.release(!1);return}const _=Je(r),g=l.provider.treeShaking||l.provider,R=l.provider.lib===m||g.lib===m;if(!c&&R){const j=_.findIndex(S=>S.provider===l.provider);j!==-1&&_.splice(j,1)}!c&&!_.some(j=>j.provider===o)&&_.push({provider:o,version:n,from:a,registered:!1,loadedFactory:R?m:void 0});const O=!c&&b.selectedProvider===l.provider&&R?o:b.selectedProvider;if(O&&!_.some(j=>j.provider===O)){const j=Y.get(O),S=typeof O.version=="string"&&O.version?O.version:n;_.push({provider:O,version:S,from:j?j.from:O.from,registered:(r==null?void 0:r[S])===O,loadedFactory:m})}const v=_.find(j=>j.provider===O)??Qe(_,m);if(!l.release(!0,(v==null?void 0:v.provider)===l.provider)||!v)return;const y=Y.get(v.provider);v.from=v.provider===o?a:y?y.from:v.provider.from,y&&(v.provider.from=y.from);const L=typeof m=="function"?m():m,w=await Promise.resolve(L);if(!(v.registered&&(r==null?void 0:r[v.version])!==v.provider))return{provider:v.provider,selection:v,resolved:w}},fe=new Set,ae=new Map,Ye=async(t,e,r)=>{var i;const n=!!((i=e.shareConfig)!=null&&i.singleton);if(!n&&e.canLiveRebind!==!1)try{const o=U(r,t,e,"version-first"),c=le(r,o);if(!c)return;const{version:a}=c;if(!n&&a!==e.version||!o.lib&&!o.loading&&!(o.loaded&&typeof o.get=="function"))return;const l=u(t,n,e.version,e.scope);if(h(d.share,l)!==void 0)return;const b=s[t],m=b==null?void 0:b[a];if(c.registered&&!k(m,o))return;let _,g=o.lib;if(!g&&Q(o)||(!g&&o.loading&&(g=await o.loading),!g&&o.loaded&&typeof o.get=="function"&&(g=await o.get()),!g))return;const R=typeof g=="function"?g():g,O=await Promise.resolve(R),v=c.registered?m:o;_={provider:v,selection:{provider:v,version:a,from:o.from,registered:c.registered},resolved:O};const T=_==null?void 0:_.provider,y=_==null?void 0:_.selection;if(!y)return;const L=_==null?void 0:_.resolved;if(L===void 0||h(d.share,l)!==void 0||y.registered&&(b==null?void 0:b[y.version])!==T)return;E(d.share,l,ve(L),y.from),fe.add(T)}catch(o){console.error('[Module Federation] Failed to bridge materialized shared module "'+t+'"',o)}},ye=async(t,e,r,n,i)=>{var o,c;try{const a=u(t,(o=e.shareConfig)==null?void 0:o.singleton,e.version,e.scope),l=h(d.share,a),b=P(d.share,a),m=U(r,t,e,"version-first"),_=m||me(r,t,e,"version-first")||e,g=le(r,_);if(!g)return;const R=k(_,e),{version:O}=g;if(!((c=e.shareConfig)!=null&&c.singleton)&&O!==e.version)return;const v=n==null?void 0:n[O],T=vt(W,q,s,"default",t,g,m,v,"version-first");if(!T&&!R)return;const{provider:y,scopeRootProvider:L}=T||{provider:_,scopeRootProvider:void 0};if(e.canLiveRebind===!1||l!==void 0&&b!==A)return;const w=s[t],j=w==null?void 0:w[O];if(g.registered&&!L&&!k(j,y))return;const S=await be(t,e.shareConfig,w,O,j,y,g.registered&&!R),G=S==null?void 0:S.provider,F=S==null?void 0:S.selection;if(!F||k(G,e)||i&&(i.version!==F.version||!k({from:F.from},i.provider))||fe.has(G))return;const Ie=S==null?void 0:S.resolved;if(Ie===void 0)return;const st=h(d.share,a),ft=P(d.share,a);if(st!==void 0&&ft!==A||F.registered&&(w==null?void 0:w[F.version])!==G)return;i||ae.set(t,{version:F.version,provider:{from:F.from}}),fe.add(G);const at=ve(Ie);E(d.share,a,at,F.from)}catch(a){console.error('[Module Federation] Failed to bridge external shared module "'+t+'"',a)}};for(const t of ce)await Promise.all(t.map(async e=>{const r=I[e];!r||r.materialize===!1||r.treeShaking||await Ye(e,r,z[e])}));for(const[t,e]of Object.entries(I)){if(e.treeShaking)continue;const r=u(t,(Re=e.shareConfig)==null?void 0:Re.singleton,e.version,e.scope);if(h(d.share,r)!==void 0)continue;const n=u(t,!0,e.version,e.scope),i=h(d.share,n);i!==void 0&&E(d.share,r,i,P(d.share,n))}const Ze=["react","react/jsx-runtime","react-dom","@velora-cms/plugin-sdk","react-dom/client"],$e=[["react"],["react/jsx-runtime","react-dom","@velora-cms/plugin-sdk"],["react-dom/client"]],Z=Ze.filter(t=>{var e;return I[t]&&(I[t].materialize!==!1||((e=I[t].shareConfig)==null?void 0:e.import)===!1)});d.providerInit||=new Map;const et=(t,e)=>{const r=d.providerInit.get(t);if(r)return r;const n=Promise.resolve().then(e);return d.providerInit.set(t,n),n.catch(()=>d.providerInit.delete(t)),n};var Se=async t=>{const e=new Set(t);for(const r of $e)await Promise.all(r.filter(n=>e.has(n)).map(async n=>{var O,v;const i=I[n],o=u(n,(O=i.shareConfig)==null?void 0:O.singleton,i.version,i.scope);if(((v=i.shareConfig)==null?void 0:v.import)===!1||i.treeShaking||h(d.share,o)!==void 0)return;const c=u(n,!0,i.version,i.scope),a=h(d.share,c);if(a!==void 0){E(d.share,o,a,P(d.share,c));return}const l=typeof ne=="function"?ne(n,i):void 0;if(l&&!l.lib&&!l.loaded)return;const b=o.canonical,m=await et(b,async()=>{const T=await i.get(),y=typeof T=="function"?T():T;return Promise.resolve(y)}),g=(T=>{let y=T;for(let L=0;L<5;L++){const w=y==null?void 0:y.default;if(!w||typeof w!="object"||Object.keys(w).length===0)break;const j=Object.keys(y).filter(S=>S!=="default").map(S=>y[S]);if(j.length>0&&j.some(S=>S!==void 0))break;y=w}return y})(m),R=g===m?{...m}:g;R.__esModule!==!0&&Object.defineProperty(R,"__esModule",{value:!0,enumerable:!1}),E(d.share,o,R,A)}))};const pe=t=>{var n,i;const e=I[t];if(!e.treeShaking&&((n=e.shareConfig)==null?void 0:n.import)!==!1)return!1;const r=u(t,(i=e.shareConfig)==null?void 0:i.singleton,e.version,e.scope);return e.treeShaking?B(d.share,r,A)===void 0&&h(d.share,r)===void 0:h(d.share,r)===void 0},tt=t=>{var i,o;const e=I[t],r=u(t,(i=e.shareConfig)==null?void 0:i.singleton,e.version,e.scope);return(e.treeShaking?B(d.share,r,A)??h(d.share,r):h(d.share,r))!==void 0?!1:e.treeShaking||((o=e.shareConfig)==null?void 0:o.import)===!1?!0:typeof U!="function"?!1:!!U(z[t],t,e,"version-first")},$=Z.findIndex(tt),rt=$===-1?Z:Z.slice(0,$);var nt=$===-1?[]:Z.slice($);await Se(rt);try{await _e(async()=>{await Promise.all(await H.initializeSharing("default",{strategy:"version-first",from:"build",initScope:f}))})}catch(t){console.error("[Module Federation]",t)}De();const Pe=async()=>{for(const t of ce)await Promise.all(t.map(async e=>{const r=I[e];!r||r.materialize===!1||r.treeShaking||await ye(e,r,s[e],z[e],void 0)}))};await Pe(),Ke&&(ue=Pe);try{const t=(Ce=globalThis.__FEDERATION__)==null?void 0:Ce.__SHARE__,e=Object.create(null);if(t)for(const[,r]of Object.entries(t))for(const n of mt){const i=r==null?void 0:r[n];if(i)for(const[o,c]of Object.entries(i)){const a=I==null?void 0:I[o],l=z[o],b=ae.get(o);if(!a||!l||!b||a.treeShaking)continue;const m=e[o]||(e[o]=Object.create(null));for(const[_,g]of Object.entries(c)){if(!g.lib||b.version!==_||!k(g,b.provider))continue;const R=l[_];(g===R||R!=null&&R.from&&g.from===R.from)&&(g===a||a.from&&g.from===a.from||m[_]===void 0&&(m[_]=g))}}}for(const r of ce)await Promise.all(r.map(async n=>{const i=e[n];i&&await ye(n,I[n],i,z[n],ae.get(n))}))}catch(t){console.error("[Module Federation] Failed to bridge external shared modules",t)}const ot=async()=>{},it=async(t,e)=>{var T,y;const r=u(t,(T=e.shareConfig)==null?void 0:T.singleton,e.version,e.scope),n=e.treeShaking?B(d.share,r,A):h(d.share,r);if(((y=e.shareConfig)==null?void 0:y.import)!==!1||n!==void 0||ne(t,e,z[t]))return;const i=L=>{let w=L;for(let j=0;j<5;j++){const S=w==null?void 0:w.default;if(!S||typeof S!="object"||Object.keys(S).length===0)break;const G=Object.keys(w).filter(F=>F!=="default").map(F=>w[F]);if(G.length>0&&G.some(F=>F!==void 0))break;w=S}return w},o=s==null?void 0:s[t],c=me(o,t,e,"version-first")||e,a=le(o,c);if(!a)return;const{version:l}=a,b=o==null?void 0:o[l],m=await be(t,e.shareConfig,o,l,b,c,a.registered&&!k(c,e)),_=m==null?void 0:m.selection,g=m==null?void 0:m.provider,R=m==null?void 0:m.resolved;if(!_||k(g,e)||R===void 0||(e.treeShaking?B(d.share,r,A):h(d.share,r))!==void 0||_.registered&&(o==null?void 0:o[_.version])!==g)return;const v=i(R);if(e.treeShaking){const L=e.treeShaking.providedExports??e.treeShaking.usedExports??[];he(d.share,r,L,v),J(d.share,r,A,v)}else E(d.share,r,v,_.from)},Oe=[];for(const t of nt){const e=I[t];if(pe(t))try{e.treeShaking?await ot(t,e):((Ee=e.shareConfig)==null?void 0:Ee.import)===!1&&await it(t,e)}catch(r){console.error(`[Module Federation] Failed to resolve runtime-only shared module "${t}"`,r);break}if(pe(t))break;Oe.push(t)}return await Se(Oe),ut(H),H}async function Ot(s){const f=await yt();if(!(s in f))throw new Error(`[Module Federation] Module ${s} does not exist in container.`);return ue&&await ue(),d.pendingShareLoads&&await Promise.all(d.pendingShareLoads),f[s]().then(u=>()=>u)}export{Ot as get,Pt as init};
|
|
2
|
+
import{_ as xe}from"./vite-preload-helper-Cgledu0r.js";import{h as ct,i as lt}from"./index-Do71v6NZ.js";const dt=ct.share;typeof __VUE_HMR_RUNTIME__>"u"&&(globalThis.__VUE_HMR_RUNTIME__={createRecord(){},rerender(){},reload(){}});const Ne="__mf_init__virtual:mf:__mfe_internal__velora_admin__mf_owner__1__mf_v__runtimeInit__mf_v__.js__";let de=globalThis[Ne];if(!de){let s,f;const u=new Promise((h,C)=>{s=h,f=C});de=globalThis[Ne]={initPromise:u,initResolve:s,initReject:f}}const ut=de.initResolve,re="__mf_module_cache__";globalThis[re]||={share:{},remote:{}};globalThis[re].share||={};globalThis[re].remote||={};const d=globalThis[re];for(const s of Object.keys(d.share))if(s.startsWith("default:")){const f=s.slice(8);d.share[f]===void 0&&(d.share[f]=d.share[s])}else if(!s.includes(":")){const f="default:"+s;d.share[f]===void 0&&(d.share[f]=d.share[s])}const Te={},mt=Array.isArray("default")?"default":["default"],Fe="default",A="velora_admin",ce=[["react"],["react/jsx-runtime","react-dom","@velora-cms/plugin-sdk"],["react-dom/client"]];let ee,te,ue;async function _e(s){for(let f=0;;f++)try{return await s()}catch(u){throw u}}const Le=Symbol("mf.originalSharedProvider"),_t={emit:s=>s},ht=(s,f)=>{if(f!=="version-first")return s;const u={};for(const[h,C]of Object.entries(s))u[h]=Object.assign({},C,{[Le]:C});return u},le=(s,f)=>{if(!f)return;const u=Object.entries(s||{}),h=u.find(([,p])=>p===f);if(h)return{version:h[0],provider:f,registered:!0};if(typeof f.version=="string"&&f.version)return{version:f.version,provider:f,registered:!1};const C=u.filter(([,p])=>p===f||!!(f.from&&(p==null?void 0:p.from)===f.from));if(C.length===1)return{version:C[0][0],provider:f,registered:!1}},me=(s,f,u,h)=>{var E;if(!s||!u)return;const C=Array.isArray(u.scope)?u.scope:[u.scope||"default"],p=ht(s,h),x={};for(const D of C)x[D||"default"]={[f]:p};const P=(E=dt.getRegisteredShare(x,f,{...u,scope:C,strategy:h},_t))==null?void 0:E.shared;return(P==null?void 0:P[Le])||P},U=(s,f,u,h)=>{var P;const C=E=>k(E,u),p=Object.fromEntries(Object.entries(s||{}).filter(([,E])=>!C(E)));u!=null&&u.version&&((P=u.shareConfig)==null?void 0:P.import)!==!1&&(p[u.version]||(p[u.version]=u));const x=me(p,f,u,h);return C(x)?void 0:x},k=(s,f)=>s===f||!!(f!=null&&f.from&&(s==null?void 0:s.from)===f.from),gt=(s,f,u,h,C,p,x,P,E)=>{var B,J,W;if(!P)return;const D=(J=(B=f==null?void 0:f.options)==null?void 0:B.shared)==null?void 0:J[C],K=Array.isArray(D)?D.find(N=>(N==null?void 0:N.version)===p):void 0,V=((P==null?void 0:P.from)===((W=f==null?void 0:f.options)==null?void 0:W.name)?P:void 0)||(k(K,P)?K:f?void 0:P);return V&&s.some(N=>{var q,M;return N!==f&&((q=N==null?void 0:N.options)==null?void 0:q.name)===(x==null?void 0:x.from)&&((M=N==null?void 0:N.shareScopeMap)==null?void 0:M[h])===u})?V:void 0},vt=(s,f,u,h,C,p,x,P,E)=>{const D=p.registered?gt(s,f,u,h,C,p.version,p.provider,P):void 0,K=D||x;if(K&&!(p.registered&&!k(K,P)))return{provider:K,scopeRootProvider:D}};async function bt(){return ee||(ee=_e(()=>xe(()=>import("./_virtual_mf-localSharedImportMap___mfe_internal__velora_admin__mf_owner__1-DlIgIuFP.js"),__vite__mapDeps([0]))).catch(s=>{throw ee=void 0,s})),ee}async function yt(){return te||(te=_e(()=>xe(()=>import("./virtualExposes-BDCSo5OS.js"),[])).then(s=>s.default??s).catch(s=>{throw te=void 0,s})),te}async function Pt(s={},f=[]){var we,je,Re,Ce,Ee;const u=(t,e,r,n)=>{const o=(Array.isArray(n)?n[0]:n)||"default",c=e||!r?t:t+"@"+r,a={canonical:o+":"+c};return o==="default"&&(a.aliases=[c]),a},h=(t,e)=>{const r=t[e.canonical];if(r!==void 0)return r;const n=e.aliases||[];for(const i of n){if(!Object.prototype.hasOwnProperty.call(t,i))continue;const o=t[i];if(o!==void 0)return t[e.canonical]=o,o}},C=Symbol.for("module-federation.shared-cache-listeners"),p=Symbol.for("module-federation.shared-cache-owners"),x=t=>{let e=t[p];return e===void 0&&(e=Object.create(null),Object.defineProperty(t,p,{value:e,enumerable:!1,configurable:!1,writable:!1})),e},P=(t,e)=>{var r;return(r=t[p])==null?void 0:r[e.canonical]},E=(t,e,r,n)=>{var a;t[e.canonical]=r;const i=e.aliases||[];for(const l of i)Object.defineProperty(t,l,{value:r,enumerable:!0,configurable:!0,writable:!0});const o=t[p];n===void 0?o&&delete o[e.canonical]:x(t)[e.canonical]=n;const c=(a=t[C])==null?void 0:a[e.canonical];if(c)for(const l of c)l(r);return r},D=Symbol.for("module-federation.tree-shaking-shared-cache"),K=t=>{let e=t[D];return e===void 0&&(e=Object.create(null),Object.defineProperty(t,D,{value:e,enumerable:!1,configurable:!1,writable:!1})),e},he=(t,e,r,n)=>{if(!Array.isArray(r))return n;const i=[...new Set(r)].sort(),o=K(t),c=o[e.canonical]||=[],a=c.find(l=>l.providedExports.length===i.length&&l.providedExports.every((b,m)=>b===i[m]));return a?a.value=n:c.push({providedExports:i,value:n}),n},V=Symbol.for("module-federation.tree-shaking-shared-selection-cache"),ge=t=>{let e=t[V];return e===void 0&&(e=Object.create(null),Object.defineProperty(t,V,{value:e,enumerable:!1,configurable:!1,writable:!1})),e},B=(t,e,r)=>{var i,o;const n=h(t,e);return n!==void 0?n:(o=(i=t[V])==null?void 0:i[e.canonical])==null?void 0:o[r]},J=(t,e,r,n)=>{const i=ge(t),o=i[e.canonical]||=Object.create(null);return o[r]=n,n},W=((we=globalThis.__FEDERATION__)==null?void 0:we.__INSTANCES__)||[],N=(je=f.find(t=>t==null?void 0:t.from))==null?void 0:je.from,q=W.find(t=>{var e,r;return((e=t==null?void 0:t.options)==null?void 0:e.name)===N&&((r=t==null?void 0:t.shareScopeMap)==null?void 0:r.default)===s})||W.find(t=>{var e,r;return((e=t==null?void 0:t.options)==null?void 0:e.name)!==A&&((r=t==null?void 0:t.shareScopeMap)==null?void 0:r.default)===s}),M=Object.create(null),Ae=t=>{const e=Object.create(null);for(const[r,n]of Object.entries(t||{}))e[r]=Object.assign(Object.create(null),n);return e},ke=(t,e)=>{const r=!q&&Object.values(e||{}).some(i=>Object.values(i||{}).some(Q)),n=r?Ae(e):e;return M[t]={host:e,runtime:n,isWebpackScope:r},n},De=()=>{const t=Object.values(M).filter(({isWebpackScope:e})=>e);if(t.length!==0)for(const{host:e,runtime:r}of t)for(const[n,i]of Object.entries(e||{})){const o=r[n]||=Object.create(null);for(const[c,a]of Object.entries(i||{}))o[c]=a}},z=Object.create(null);for(const[t,e]of Object.entries(s)){const r=z[t]=Object.create(null);for(const[n,i]of Object.entries(e))r[n]=Object.assign({},i)}const{usedShared:I,usedRemotes:ze}=await bt();function Q(t){if(typeof(t==null?void 0:t.get)!="function")return!1;const e=Function.prototype.toString.call(t.get);return e.includes("__webpack_require__")||/\.\s*e\s*\([^)]*\)\s*\.then\s*\(/.test(e)}const Ke=Object.values(z).some(t=>Object.values(t||{}).some(Q)),Be=t=>{const e=t.split("/");return t.startsWith("@")?e.slice(0,2).join("/"):e[0]},ne=(t,e,r)=>{if(typeof U!="function")return;const n=Be(t),i=n===t?[[t,e]]:[[t,e],[n,I[n]]];for(const[o,c]of i){if(!c)continue;const a=r?o===t?r:z[o]:s[o],l=U(a,o,c,"version-first");if(l&&Q(l)&&!l.lib&&!l.loaded)return l}};var X=Te[Fe];if(X||(X=Te[Fe]={from:A}),f.indexOf(X)>=0)return;f.push(X);const ve=t=>{let e=t;for(let r=0;r<5;r++){const n=e==null?void 0:e.default;if(!n||typeof n!="object"||Object.keys(n).length===0)break;const i=Object.keys(e).filter(o=>o!=="default").map(o=>e[o]);if(i.length>0&&i.some(o=>o!==void 0))break;e=n}return e},Ge=[],Ve=typeof globalThis.window>"u"?await Promise.all([]):[],oe="__mf_vite_runtime_share_load_id__";let We=0;const ie=new Map,se=new Map,H=lt({name:A,remotes:ze,shared:I,plugins:[He(),Ue(),...Ge,...Ve],shareStrategy:"version-first"});H.initShareScopeMap("default",ke("default",s));function He(){return{name:"vite-share-pin-lifecycle-plugin",resolveShare(t){var i;const e=(i=t.shareInfo)==null?void 0:i[oe],r=e===void 0?void 0:se.get(e);if(!r)return t;const n=t.resolver;return t.resolver=(...o)=>(r.pinned.reapply(),n(...o)),r.pinned.reveal(),t}}}function Ue(){return{name:"vite-real-name-snapshot-plugin",afterLoadSnapshot(t){const e=t&&t.remoteSnapshot,r=e&&e.globalName,n=e&&e.version;if(!r||!n||!e.remoteEntry)return t;const i=globalThis.__FEDERATION__&&globalThis.__FEDERATION__.moduleInfo,o=r+":"+n;return i&&!i[o]&&(i[o]=e),t}}}const qe=H.sharedHandler.hooks.lifecycle.resolveShare,Y=new WeakMap;qe.on(t=>{var i;const e=(i=t.shareInfo)==null?void 0:i[oe],r=t.resolver;if(typeof r!="function")return t;const n=(...o)=>{const c=r(...o),a=c==null?void 0:c.shared;return a&&(typeof a=="object"||typeof a=="function")&&!Y.has(a)&&Y.set(a,{from:a.from}),e!==void 0&&a&&ie.set(e,a),c};return t.resolver=n,t});const Me=(t,e,r,n)=>{if(!t||t[e]!==r)return;const i=Object.assign({},n,{version:n.version??e,scope:n.scope??(r==null?void 0:r.scope)??["default"],strategy:"loaded-first"}),o=n.from;t[e]=i;const c=()=>r===void 0?t[e]===void 0:t[e]===r;return{provider:i,reveal(){return t[e]!==i?!1:(r===void 0?delete t[e]:t[e]=r,!0)},reapply(){return c()?(t[e]=i,!0):!1},release(a,l=!0){return n.from=o,t[e]!==i?!l&&c():l?a?(i.from=o,a&&i.lib&&(i.loaded=!0),n.strategy===void 0?delete i.strategy:i.strategy=n.strategy,!0):(r===void 0?delete t[e]:t[e]=r,!1):(r===void 0?delete t[e]:t[e]=r,!0)}}},Je=t=>Object.entries(t||{}).map(([e,r])=>({provider:r,version:e,from:r.from,registered:!0})),Qe=(t,e)=>{if(e===void 0)return;let r;for(const n of t){const i=n.provider,o=i.treeShaking||i;if(!(n.loadedFactory!==e&&i.lib!==e&&o.lib!==e)){if(r)return;r=n}}return r},Xe=async(t,e,r)=>{const n=++We;se.set(n,{pinned:r});try{const i=await H.loadShare(t,{customShareInfo:{shareConfig:e,[oe]:n}});return{factory:i===!1?void 0:i,selectedProvider:ie.get(n)}}finally{ie.delete(n),se.delete(n)}},be=async(t,e,r,n,i,o,c=!0)=>{const a=o.from,l=Me(r,n,i,o);if(!l)return;let b;try{b=await Xe(t,e,l)}catch(j){throw l.release(!1),j}const m=b==null?void 0:b.factory;if(m===void 0){l.release(!1);return}const _=Je(r),g=l.provider.treeShaking||l.provider,R=l.provider.lib===m||g.lib===m;if(!c&&R){const j=_.findIndex(S=>S.provider===l.provider);j!==-1&&_.splice(j,1)}!c&&!_.some(j=>j.provider===o)&&_.push({provider:o,version:n,from:a,registered:!1,loadedFactory:R?m:void 0});const O=!c&&b.selectedProvider===l.provider&&R?o:b.selectedProvider;if(O&&!_.some(j=>j.provider===O)){const j=Y.get(O),S=typeof O.version=="string"&&O.version?O.version:n;_.push({provider:O,version:S,from:j?j.from:O.from,registered:(r==null?void 0:r[S])===O,loadedFactory:m})}const v=_.find(j=>j.provider===O)??Qe(_,m);if(!l.release(!0,(v==null?void 0:v.provider)===l.provider)||!v)return;const y=Y.get(v.provider);v.from=v.provider===o?a:y?y.from:v.provider.from,y&&(v.provider.from=y.from);const L=typeof m=="function"?m():m,w=await Promise.resolve(L);if(!(v.registered&&(r==null?void 0:r[v.version])!==v.provider))return{provider:v.provider,selection:v,resolved:w}},fe=new Set,ae=new Map,Ye=async(t,e,r)=>{var i;const n=!!((i=e.shareConfig)!=null&&i.singleton);if(!n&&e.canLiveRebind!==!1)try{const o=U(r,t,e,"version-first"),c=le(r,o);if(!c)return;const{version:a}=c;if(!n&&a!==e.version||!o.lib&&!o.loading&&!(o.loaded&&typeof o.get=="function"))return;const l=u(t,n,e.version,e.scope);if(h(d.share,l)!==void 0)return;const b=s[t],m=b==null?void 0:b[a];if(c.registered&&!k(m,o))return;let _,g=o.lib;if(!g&&Q(o)||(!g&&o.loading&&(g=await o.loading),!g&&o.loaded&&typeof o.get=="function"&&(g=await o.get()),!g))return;const R=typeof g=="function"?g():g,O=await Promise.resolve(R),v=c.registered?m:o;_={provider:v,selection:{provider:v,version:a,from:o.from,registered:c.registered},resolved:O};const T=_==null?void 0:_.provider,y=_==null?void 0:_.selection;if(!y)return;const L=_==null?void 0:_.resolved;if(L===void 0||h(d.share,l)!==void 0||y.registered&&(b==null?void 0:b[y.version])!==T)return;E(d.share,l,ve(L),y.from),fe.add(T)}catch(o){console.error('[Module Federation] Failed to bridge materialized shared module "'+t+'"',o)}},ye=async(t,e,r,n,i)=>{var o,c;try{const a=u(t,(o=e.shareConfig)==null?void 0:o.singleton,e.version,e.scope),l=h(d.share,a),b=P(d.share,a),m=U(r,t,e,"version-first"),_=m||me(r,t,e,"version-first")||e,g=le(r,_);if(!g)return;const R=k(_,e),{version:O}=g;if(!((c=e.shareConfig)!=null&&c.singleton)&&O!==e.version)return;const v=n==null?void 0:n[O],T=vt(W,q,s,"default",t,g,m,v,"version-first");if(!T&&!R)return;const{provider:y,scopeRootProvider:L}=T||{provider:_,scopeRootProvider:void 0};if(e.canLiveRebind===!1||l!==void 0&&b!==A)return;const w=s[t],j=w==null?void 0:w[O];if(g.registered&&!L&&!k(j,y))return;const S=await be(t,e.shareConfig,w,O,j,y,g.registered&&!R),G=S==null?void 0:S.provider,F=S==null?void 0:S.selection;if(!F||k(G,e)||i&&(i.version!==F.version||!k({from:F.from},i.provider))||fe.has(G))return;const Ie=S==null?void 0:S.resolved;if(Ie===void 0)return;const st=h(d.share,a),ft=P(d.share,a);if(st!==void 0&&ft!==A||F.registered&&(w==null?void 0:w[F.version])!==G)return;i||ae.set(t,{version:F.version,provider:{from:F.from}}),fe.add(G);const at=ve(Ie);E(d.share,a,at,F.from)}catch(a){console.error('[Module Federation] Failed to bridge external shared module "'+t+'"',a)}};for(const t of ce)await Promise.all(t.map(async e=>{const r=I[e];!r||r.materialize===!1||r.treeShaking||await Ye(e,r,z[e])}));for(const[t,e]of Object.entries(I)){if(e.treeShaking)continue;const r=u(t,(Re=e.shareConfig)==null?void 0:Re.singleton,e.version,e.scope);if(h(d.share,r)!==void 0)continue;const n=u(t,!0,e.version,e.scope),i=h(d.share,n);i!==void 0&&E(d.share,r,i,P(d.share,n))}const Ze=["react","react/jsx-runtime","react-dom","@velora-cms/plugin-sdk","react-dom/client"],$e=[["react"],["react/jsx-runtime","react-dom","@velora-cms/plugin-sdk"],["react-dom/client"]],Z=Ze.filter(t=>{var e;return I[t]&&(I[t].materialize!==!1||((e=I[t].shareConfig)==null?void 0:e.import)===!1)});d.providerInit||=new Map;const et=(t,e)=>{const r=d.providerInit.get(t);if(r)return r;const n=Promise.resolve().then(e);return d.providerInit.set(t,n),n.catch(()=>d.providerInit.delete(t)),n};var Se=async t=>{const e=new Set(t);for(const r of $e)await Promise.all(r.filter(n=>e.has(n)).map(async n=>{var O,v;const i=I[n],o=u(n,(O=i.shareConfig)==null?void 0:O.singleton,i.version,i.scope);if(((v=i.shareConfig)==null?void 0:v.import)===!1||i.treeShaking||h(d.share,o)!==void 0)return;const c=u(n,!0,i.version,i.scope),a=h(d.share,c);if(a!==void 0){E(d.share,o,a,P(d.share,c));return}const l=typeof ne=="function"?ne(n,i):void 0;if(l&&!l.lib&&!l.loaded)return;const b=o.canonical,m=await et(b,async()=>{const T=await i.get(),y=typeof T=="function"?T():T;return Promise.resolve(y)}),g=(T=>{let y=T;for(let L=0;L<5;L++){const w=y==null?void 0:y.default;if(!w||typeof w!="object"||Object.keys(w).length===0)break;const j=Object.keys(y).filter(S=>S!=="default").map(S=>y[S]);if(j.length>0&&j.some(S=>S!==void 0))break;y=w}return y})(m),R=g===m?{...m}:g;R.__esModule!==!0&&Object.defineProperty(R,"__esModule",{value:!0,enumerable:!1}),E(d.share,o,R,A)}))};const pe=t=>{var n,i;const e=I[t];if(!e.treeShaking&&((n=e.shareConfig)==null?void 0:n.import)!==!1)return!1;const r=u(t,(i=e.shareConfig)==null?void 0:i.singleton,e.version,e.scope);return e.treeShaking?B(d.share,r,A)===void 0&&h(d.share,r)===void 0:h(d.share,r)===void 0},tt=t=>{var i,o;const e=I[t],r=u(t,(i=e.shareConfig)==null?void 0:i.singleton,e.version,e.scope);return(e.treeShaking?B(d.share,r,A)??h(d.share,r):h(d.share,r))!==void 0?!1:e.treeShaking||((o=e.shareConfig)==null?void 0:o.import)===!1?!0:typeof U!="function"?!1:!!U(z[t],t,e,"version-first")},$=Z.findIndex(tt),rt=$===-1?Z:Z.slice(0,$);var nt=$===-1?[]:Z.slice($);await Se(rt);try{await _e(async()=>{await Promise.all(await H.initializeSharing("default",{strategy:"version-first",from:"build",initScope:f}))})}catch(t){console.error("[Module Federation]",t)}De();const Pe=async()=>{for(const t of ce)await Promise.all(t.map(async e=>{const r=I[e];!r||r.materialize===!1||r.treeShaking||await ye(e,r,s[e],z[e],void 0)}))};await Pe(),Ke&&(ue=Pe);try{const t=(Ce=globalThis.__FEDERATION__)==null?void 0:Ce.__SHARE__,e=Object.create(null);if(t)for(const[,r]of Object.entries(t))for(const n of mt){const i=r==null?void 0:r[n];if(i)for(const[o,c]of Object.entries(i)){const a=I==null?void 0:I[o],l=z[o],b=ae.get(o);if(!a||!l||!b||a.treeShaking)continue;const m=e[o]||(e[o]=Object.create(null));for(const[_,g]of Object.entries(c)){if(!g.lib||b.version!==_||!k(g,b.provider))continue;const R=l[_];(g===R||R!=null&&R.from&&g.from===R.from)&&(g===a||a.from&&g.from===a.from||m[_]===void 0&&(m[_]=g))}}}for(const r of ce)await Promise.all(r.map(async n=>{const i=e[n];i&&await ye(n,I[n],i,z[n],ae.get(n))}))}catch(t){console.error("[Module Federation] Failed to bridge external shared modules",t)}const ot=async()=>{},it=async(t,e)=>{var T,y;const r=u(t,(T=e.shareConfig)==null?void 0:T.singleton,e.version,e.scope),n=e.treeShaking?B(d.share,r,A):h(d.share,r);if(((y=e.shareConfig)==null?void 0:y.import)!==!1||n!==void 0||ne(t,e,z[t]))return;const i=L=>{let w=L;for(let j=0;j<5;j++){const S=w==null?void 0:w.default;if(!S||typeof S!="object"||Object.keys(S).length===0)break;const G=Object.keys(w).filter(F=>F!=="default").map(F=>w[F]);if(G.length>0&&G.some(F=>F!==void 0))break;w=S}return w},o=s==null?void 0:s[t],c=me(o,t,e,"version-first")||e,a=le(o,c);if(!a)return;const{version:l}=a,b=o==null?void 0:o[l],m=await be(t,e.shareConfig,o,l,b,c,a.registered&&!k(c,e)),_=m==null?void 0:m.selection,g=m==null?void 0:m.provider,R=m==null?void 0:m.resolved;if(!_||k(g,e)||R===void 0||(e.treeShaking?B(d.share,r,A):h(d.share,r))!==void 0||_.registered&&(o==null?void 0:o[_.version])!==g)return;const v=i(R);if(e.treeShaking){const L=e.treeShaking.providedExports??e.treeShaking.usedExports??[];he(d.share,r,L,v),J(d.share,r,A,v)}else E(d.share,r,v,_.from)},Oe=[];for(const t of nt){const e=I[t];if(pe(t))try{e.treeShaking?await ot(t,e):((Ee=e.shareConfig)==null?void 0:Ee.import)===!1&&await it(t,e)}catch(r){console.error(`[Module Federation] Failed to resolve runtime-only shared module "${t}"`,r);break}if(pe(t))break;Oe.push(t)}return await Se(Oe),ut(H),H}async function Ot(s){const f=await yt();if(!(s in f))throw new Error(`[Module Federation] Module ${s} does not exist in container.`);return ue&&await ue(),d.pendingShareLoads&&await Promise.all(d.pendingShareLoads),f[s]().then(u=>()=>u)}export{Ot as get,Pt as init};
|
|
3
3
|
|
|
4
4
|
if (typeof document !== 'undefined' && document.head) {
|
|
5
5
|
try {
|
|
6
|
-
for (const __mfWarmupPath of ["./virtualExposes-BDCSo5OS.js","./_virtual_mf-localSharedImportMap___mfe_internal__velora_admin__mf_owner__1-
|
|
6
|
+
for (const __mfWarmupPath of ["./virtualExposes-BDCSo5OS.js","./_virtual_mf-localSharedImportMap___mfe_internal__velora_admin__mf_owner__1-DlIgIuFP.js","./vite-preload-helper-Cgledu0r.js","./index-Do71v6NZ.js"]) {
|
|
7
7
|
const __mfWarmupLink = document.createElement('link');
|
|
8
8
|
__mfWarmupLink.rel = 'modulepreload';
|
|
9
9
|
__mfWarmupLink.crossOrigin = '';
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Velora Admin</title>
|
|
7
|
-
<script type="module" crossorigin src="/velora/assets/mf-entry-bootstrap-0-
|
|
7
|
+
<script type="module" crossorigin src="/velora/assets/mf-entry-bootstrap-0-7b0ce2fe.js"></script>
|
|
8
8
|
<link rel="modulepreload" crossorigin href="/velora/assets/index-Do71v6NZ.js">
|
|
9
|
-
<link rel="modulepreload" crossorigin href="/velora/assets/remoteEntry-
|
|
10
|
-
<link rel="modulepreload" crossorigin href="/velora/assets/content-trash.schema-
|
|
9
|
+
<link rel="modulepreload" crossorigin href="/velora/assets/remoteEntry-J2yJXsGB.js">
|
|
10
|
+
<link rel="modulepreload" crossorigin href="/velora/assets/content-trash.schema-tvJ4Lbos.js">
|
|
11
11
|
<link rel="stylesheet" crossorigin href="/velora/assets/index-DnZV_gsg.css">
|
|
12
|
-
<link rel="modulepreload" crossorigin href="/velora/assets/_virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DMaku-HC.js"><link rel="modulepreload" crossorigin href="/velora/assets/_virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare__react__loadShare__.js-BuUBskgj.js"><link rel="modulepreload" crossorigin href="/velora/assets/__virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare__react__loadShare__.js_commonjs-proxy-Ng0fOpdU.js"><link rel="modulepreload" crossorigin href="/velora/assets/__virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare__react_mf_2_dom__loadShare__.js_commonjs-proxy-oc1i_iBU.js"><link rel="modulepreload" crossorigin href="/velora/assets/_virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-BPoj3DC9.js"><link rel="modulepreload" crossorigin href="/velora/assets/_virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare___mf_0_velora_mf_2_cms_mf_1_plugin_mf_2_sdk__loadShare__.js-
|
|
12
|
+
<link rel="modulepreload" crossorigin href="/velora/assets/_virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-DMaku-HC.js"><link rel="modulepreload" crossorigin href="/velora/assets/_virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare__react__loadShare__.js-BuUBskgj.js"><link rel="modulepreload" crossorigin href="/velora/assets/__virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare__react__loadShare__.js_commonjs-proxy-Ng0fOpdU.js"><link rel="modulepreload" crossorigin href="/velora/assets/__virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare__react_mf_2_dom__loadShare__.js_commonjs-proxy-oc1i_iBU.js"><link rel="modulepreload" crossorigin href="/velora/assets/_virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-BPoj3DC9.js"><link rel="modulepreload" crossorigin href="/velora/assets/_virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare___mf_0_velora_mf_2_cms_mf_1_plugin_mf_2_sdk__loadShare__.js-Bm9EahCG.js"><link rel="modulepreload" crossorigin href="/velora/assets/_virtual_mf___mfe_internal__velora_admin__mf_owner__1__loadShare__react_mf_2_dom__loadShare__.js-DYfqn12F.js"><link rel="modulepreload" crossorigin href="/velora/assets/hostInit-B-6-34XY.js"><link rel="modulepreload" crossorigin href="/velora/assets/index-DYO7-IK8.js"><link rel="modulepreload" crossorigin href="/velora/assets/virtualExposes-BDCSo5OS.js"><link rel="modulepreload" crossorigin href="/velora/assets/_virtual_mf-localSharedImportMap___mfe_internal__velora_admin__mf_owner__1-DlIgIuFP.js"><link rel="modulepreload" crossorigin href="/velora/assets/index-CHCGuSbb.js"><link rel="modulepreload" crossorigin href="/velora/assets/vite-preload-helper-Cgledu0r.js"></head>
|
|
13
13
|
<body>
|
|
14
14
|
<div id="root"></div>
|
|
15
15
|
</body>
|
package/dist/app.d.ts
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
|
-
import { type FastifyInstance } from "fastify";
|
|
1
|
+
import { type FastifyInstance, type FastifyRequest } from "fastify";
|
|
2
2
|
import { PluginRegistryService } from "./plugins/plugin-registry-service.js";
|
|
3
3
|
declare module "fastify" {
|
|
4
4
|
interface FastifyInstance {
|
|
5
5
|
pluginRegistry: PluginRegistryService;
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
|
+
export declare function redactSensitiveQueryParams(url: string): string;
|
|
9
|
+
declare function redactingReqSerializer(request: FastifyRequest): {
|
|
10
|
+
method: string;
|
|
11
|
+
url: string;
|
|
12
|
+
version: string | undefined;
|
|
13
|
+
host: string;
|
|
14
|
+
remoteAddress: string;
|
|
15
|
+
remotePort: number | undefined;
|
|
16
|
+
};
|
|
17
|
+
export declare const requestLoggerOptions: {
|
|
18
|
+
serializers: {
|
|
19
|
+
req: typeof redactingReqSerializer;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
8
22
|
export declare function buildApp(): Promise<FastifyInstance>;
|
|
23
|
+
export {};
|
package/dist/app.js
CHANGED
|
@@ -15,7 +15,7 @@ import { prisma, resolvePrismaDialect } from "./db/prisma.js";
|
|
|
15
15
|
import { resolveClientDir } from "./db/resolve-client-dir.js";
|
|
16
16
|
import { filterPublicApiSpec } from "./docs/filter-public-api-spec.js";
|
|
17
17
|
import { startLicenseRevalidation } from "./marketplace/license-revalidation-job.js";
|
|
18
|
-
import { MediaService,
|
|
18
|
+
import { MediaService, resolveMediaStorage } from "./media/media-service.js";
|
|
19
19
|
import { bootInstalledPlugins } from "./plugins/boot-plugin-loader.js";
|
|
20
20
|
import { createHookDispatcher } from "./plugins/hook-dispatcher.js";
|
|
21
21
|
import { PluginRegistryService } from "./plugins/plugin-registry-service.js";
|
|
@@ -33,6 +33,7 @@ import { createFrameworkErrorHandler, registerHeadlessBridge } from "./routes/he
|
|
|
33
33
|
import { healthRoutes } from "./routes/health.js";
|
|
34
34
|
import { marketplaceProxyRoutes } from "./routes/marketplace-proxy.js";
|
|
35
35
|
import { mediaRoutes } from "./routes/media.js";
|
|
36
|
+
import { mediaPublicRoutes } from "./routes/media-public.js";
|
|
36
37
|
import { dataTypeRoutes } from "./routes/data-types.js";
|
|
37
38
|
import { pluginRoutes } from "./routes/plugins.js";
|
|
38
39
|
import { themeRoutes } from "./routes/themes.js";
|
|
@@ -45,6 +46,54 @@ import { snapshotRoutes } from "./routes/snapshots.js";
|
|
|
45
46
|
import { setupRoutes } from "./routes/setup.js";
|
|
46
47
|
import { usersRoutes } from "./routes/users.js";
|
|
47
48
|
import { templateRoutes } from "./routes/templates.js";
|
|
49
|
+
// S186c Task 3 fix wave, M2: signed media/preview links (media-tokens.ts's
|
|
50
|
+
// `?token=`, preview-tokens.ts's `?previewToken=`) ride in the URL, and
|
|
51
|
+
// Fastify's request logging (logger: true below) logs `req.url` verbatim
|
|
52
|
+
// on every single request — meaning both land in cleartext in the access
|
|
53
|
+
// log, a persistent, usually-shipped-off-box artifact, even though each
|
|
54
|
+
// token is itself short-lived and scoped. Only the VALUE is masked; the
|
|
55
|
+
// param NAME stays visible (worth keeping for triage — "was a token even
|
|
56
|
+
// presented" is still answerable from the log line).
|
|
57
|
+
const REDACTED_QUERY_PARAMS = new Set(["token", "previewToken"]);
|
|
58
|
+
export function redactSensitiveQueryParams(url) {
|
|
59
|
+
const [path, query] = url.split("?", 2);
|
|
60
|
+
if (!query)
|
|
61
|
+
return url;
|
|
62
|
+
const redactedQuery = query
|
|
63
|
+
.split("&")
|
|
64
|
+
.map((pair) => {
|
|
65
|
+
const eqIndex = pair.indexOf("=");
|
|
66
|
+
const key = eqIndex === -1 ? pair : pair.slice(0, eqIndex);
|
|
67
|
+
return REDACTED_QUERY_PARAMS.has(key) ? `${key}=[redacted]` : pair;
|
|
68
|
+
})
|
|
69
|
+
.join("&");
|
|
70
|
+
return `${path}?${redactedQuery}`;
|
|
71
|
+
}
|
|
72
|
+
// Field-for-field the same shape as Fastify's own default req serializer
|
|
73
|
+
// (fastify/lib/logger-pino.js's `serializers.req`) — method, url, version,
|
|
74
|
+
// host, remoteAddress, remotePort — with `url` swapped for the redacted
|
|
75
|
+
// version above. Fastify calls this with the real (decorated) request
|
|
76
|
+
// object, not the raw Node one, hence `.host`/`.ip`/`.socket` rather than
|
|
77
|
+
// header-parsing by hand here.
|
|
78
|
+
function redactingReqSerializer(request) {
|
|
79
|
+
// accept-version, like any header, can legally repeat (string[]) — the
|
|
80
|
+
// default serializer this mirrors (fastify/lib/logger-pino.js) doesn't
|
|
81
|
+
// account for that either, so this narrows to Fastify's own declared
|
|
82
|
+
// `string | undefined` serializer shape rather than widening it.
|
|
83
|
+
const acceptVersion = request.headers?.["accept-version"];
|
|
84
|
+
return {
|
|
85
|
+
method: request.method,
|
|
86
|
+
url: redactSensitiveQueryParams(request.url),
|
|
87
|
+
version: typeof acceptVersion === "string" ? acceptVersion : undefined,
|
|
88
|
+
host: request.host,
|
|
89
|
+
remoteAddress: request.ip,
|
|
90
|
+
remotePort: request.socket ? request.socket.remotePort : undefined,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
// Exported so a test can wire this exact serializer into its own minimal
|
|
94
|
+
// Fastify instance (with a capturable `stream`) rather than duplicating
|
|
95
|
+
// the redaction logic or standing up the full buildApp() + database.
|
|
96
|
+
export const requestLoggerOptions = { serializers: { req: redactingReqSerializer } };
|
|
48
97
|
export async function buildApp() {
|
|
49
98
|
// frameworkErrors (S156): the only hook into find-my-way's own
|
|
50
99
|
// pre-routing FST_ERR_BAD_URL/FST_ERR_ASYNC_CONSTRAINT responses — it's
|
|
@@ -63,7 +112,13 @@ export async function buildApp() {
|
|
|
63
112
|
// byte-for-byte for every deployment that hasn't opted in.
|
|
64
113
|
const trustProxy = trustProxyFromEnv();
|
|
65
114
|
const app = Fastify({
|
|
66
|
-
logger: true
|
|
115
|
+
// M2 (S186c Task 3 fix wave): logger: true previously used Fastify's
|
|
116
|
+
// default req serializer verbatim, which logs req.url unredacted —
|
|
117
|
+
// requestLoggerOptions above swaps in the one field that needs
|
|
118
|
+
// masking and otherwise matches the default exactly, so this is
|
|
119
|
+
// still "logger: true" in every other respect (level, timestamps,
|
|
120
|
+
// etc. all default).
|
|
121
|
+
logger: requestLoggerOptions,
|
|
67
122
|
frameworkErrors: createFrameworkErrorHandler(),
|
|
68
123
|
...(trustProxy !== undefined ? { trustProxy } : {}),
|
|
69
124
|
}).withTypeProvider();
|
|
@@ -133,7 +188,7 @@ export async function buildApp() {
|
|
|
133
188
|
app.addHook("onClose", async () => {
|
|
134
189
|
await contentDb.adapter.disconnect();
|
|
135
190
|
});
|
|
136
|
-
const mediaService = new MediaService(prisma,
|
|
191
|
+
const mediaService = new MediaService(prisma, resolveMediaStorage(),
|
|
137
192
|
// Routed through resolveClientDir() rather than reading
|
|
138
193
|
// VELORA_PRISMA_CLIENT_DIR directly, so there's one channel deciding
|
|
139
194
|
// "which generated client dir" instead of two (db/prisma.ts's own
|
|
@@ -143,7 +198,7 @@ export async function buildApp() {
|
|
|
143
198
|
// branch untouched, so resolvePrismaDialect still falls through to the
|
|
144
199
|
// DATABASE_URL-scheme branch for it exactly as before.
|
|
145
200
|
resolvePrismaDialect(resolveClientDir(), process.env.DATABASE_URL));
|
|
146
|
-
await mediaService.
|
|
201
|
+
await mediaService.ensureReady();
|
|
147
202
|
// The registry's dialect gate follows the content database's resolved
|
|
148
203
|
// dialect — contentDb.dialect is the resolved postgresql|mysql|sqlite
|
|
149
204
|
// union (Session 122), so 'mock' is excluded by construction and no
|
|
@@ -195,6 +250,10 @@ export async function buildApp() {
|
|
|
195
250
|
// 404-with-cause there, not a bare unmatched-route 404), while leaving
|
|
196
251
|
// GET / on its pre-S184 headless-bridge behaviour.
|
|
197
252
|
await app.register(adminStaticRoutes);
|
|
253
|
+
// The stable media route (S186c §3) — full app only, same as
|
|
254
|
+
// adminStaticRoutes above; buildSetupOnlyApp() (setup-app.ts) has no
|
|
255
|
+
// MediaService/Prisma to serve from and never registers this.
|
|
256
|
+
await app.register(mediaPublicRoutes, { mediaService });
|
|
198
257
|
await app.register(pluginAssetsRoutes);
|
|
199
258
|
await app.register(authRoutes);
|
|
200
259
|
await app.register(usersRoutes);
|
package/dist/auth/api-keys.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { FastifyReply, FastifyRequest } from "fastify";
|
|
2
2
|
import type { ApiKeyScope } from "@velora-cms/api-schemas";
|
|
3
|
+
export declare const KEY_PREFIX = "vk_";
|
|
3
4
|
export declare function generateApiKey(): string;
|
|
4
5
|
export declare function hashApiKey(key: string): string;
|
|
5
6
|
export declare function isApiKeyHashValid(hash: string): Promise<boolean>;
|
package/dist/auth/api-keys.js
CHANGED
|
@@ -3,7 +3,11 @@ import { prisma } from "../db/prisma.js";
|
|
|
3
3
|
// Public Content API keys (Month 9, Session 101). A deliberately separate
|
|
4
4
|
// code path from the admin JWT/cookie session (api-design.md: never
|
|
5
5
|
// conflate headless consumers with logged-in admin sessions).
|
|
6
|
-
|
|
6
|
+
// Exported so any other caller that must recognize a "this even looks like
|
|
7
|
+
// one of ours" key (e.g. media-public.ts's hasReadApiKey, L2 fix wave)
|
|
8
|
+
// checks against the exact same literal rather than a second, potentially
|
|
9
|
+
// drifting copy of it.
|
|
10
|
+
export const KEY_PREFIX = "vk_";
|
|
7
11
|
// High-entropy random secret, so sha256 (fast) is the right hash — same
|
|
8
12
|
// reasoning as hashRefreshToken in tokens.ts, NOT bcrypt like passwords.
|
|
9
13
|
export function generateApiKey() {
|
|
@@ -16,6 +16,10 @@ export declare const ADMIN_RATE_LIMIT: {
|
|
|
16
16
|
max: () => number;
|
|
17
17
|
timeWindow: () => string;
|
|
18
18
|
};
|
|
19
|
+
export declare const MEDIA_RATE_LIMIT: {
|
|
20
|
+
max: () => number;
|
|
21
|
+
timeWindow: () => string;
|
|
22
|
+
};
|
|
19
23
|
export declare function ipOnlyKeyGenerator(request: FastifyRequest): Promise<string>;
|
|
20
24
|
export declare function ipOnlyRateLimitConfig(): {
|
|
21
25
|
max: number;
|
|
@@ -65,6 +65,19 @@ export const ADMIN_RATE_LIMIT = {
|
|
|
65
65
|
max: () => parsePositiveInt(process.env.VELORA_RATE_LIMIT_ADMIN, 120),
|
|
66
66
|
timeWindow: () => parseWindow(process.env.VELORA_RATE_LIMIT_ADMIN_WINDOW, "1 minute"),
|
|
67
67
|
};
|
|
68
|
+
// The stable media route (S186c §3), GET /media/:id/:filename —
|
|
69
|
+
// registered in media-public.ts, plugin-level, IP-only (same shape as
|
|
70
|
+
// ADMIN_RATE_LIMIT/DOCS_RATE_LIMIT above): a public bandwidth endpoint
|
|
71
|
+
// that both anonymous public-image requests and headless consumers hit
|
|
72
|
+
// directly (not behind an API key or JWT for public items), so it cannot
|
|
73
|
+
// bucket on the three-lane rateLimitConfig's jwt:/apiKey: lanes — IP is
|
|
74
|
+
// the only key every caller has. Generous ceiling: this serves actual
|
|
75
|
+
// bytes (images, downloads) embedded in ordinary pages, so a real page
|
|
76
|
+
// load can fire many requests against it in a burst.
|
|
77
|
+
export const MEDIA_RATE_LIMIT = {
|
|
78
|
+
max: () => parsePositiveInt(process.env.VELORA_RATE_LIMIT_MEDIA, 300),
|
|
79
|
+
timeWindow: () => parseWindow(process.env.VELORA_RATE_LIMIT_MEDIA_WINDOW, "1 minute"),
|
|
80
|
+
};
|
|
68
81
|
// The shared rateLimitKey puts a VERIFIED JWT into the jwt: lane, which is
|
|
69
82
|
// Number.MAX_SAFE_INTEGER — effectively unlimited. Login must never inherit
|
|
70
83
|
// that, or anyone holding one valid session could brute-force passwords
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The `velora-sync-admin` command (S186b): re-copies the installed admin
|
|
3
|
+
// bundle into the scaffold's public/velora-admin (or VELORA_ADMIN_DIR),
|
|
4
|
+
// rewriting its version stamp — the drift-control half of the visible
|
|
5
|
+
// scaffold, run after `npm update @velora-cms/server`. Runs with cwd set to
|
|
6
|
+
// the USER's project, never this package, which is exactly what
|
|
7
|
+
// syncAdminBundle resolves targetDir against.
|
|
8
|
+
import { resolve } from "node:path";
|
|
9
|
+
import { syncAdminBundle } from "./admin/sync-admin-bundle.js";
|
|
10
|
+
import { loadEnvFile } from "./config/load-env.js";
|
|
11
|
+
// Review finding I2: spec §3 puts VELORA_ADMIN_DIR in the scaffold's
|
|
12
|
+
// `.env`, but this bin used to read process.env directly and never loaded
|
|
13
|
+
// it — so the override only ever worked if it happened to already be in
|
|
14
|
+
// the shell's real environment. Same loader index.ts/lib.ts use, called
|
|
15
|
+
// with defaults (process.env, process.cwd()) since this bin, like them,
|
|
16
|
+
// runs with cwd set to the scaffold, not this package.
|
|
17
|
+
loadEnvFile();
|
|
18
|
+
// Review finding C1: --force bypasses syncAdminBundle's dangerous-target
|
|
19
|
+
// guard, for the rare case where a caller genuinely wants to replace a
|
|
20
|
+
// directory that doesn't look like a prior admin bundle.
|
|
21
|
+
const force = process.argv.slice(2).includes("--force");
|
|
22
|
+
const targetDir = process.env.VELORA_ADMIN_DIR || "public/velora-admin";
|
|
23
|
+
// Resolved up front so every line this bin prints — success or failure —
|
|
24
|
+
// names the actual absolute path being acted on, not the raw (possibly
|
|
25
|
+
// relative) override string.
|
|
26
|
+
const resolvedTarget = resolve(targetDir);
|
|
27
|
+
try {
|
|
28
|
+
const { version, copied } = await syncAdminBundle(targetDir, { force });
|
|
29
|
+
console.log(`Synced admin UI ${version} into ${resolvedTarget} (${copied} files).`);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
// Review finding M1: every failure — including syncAdminBundle's own
|
|
33
|
+
// missing-source and dangerous-target messages — is wrapped with a
|
|
34
|
+
// consistent "what were we trying to do" prefix naming the resolved
|
|
35
|
+
// target, rather than printing the bare underlying message.
|
|
36
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
37
|
+
console.error(`Could not sync the admin UI into ${resolvedTarget}: ${message}`);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// S186c Task 3 fix wave, L1: extracted out of published-item.ts's
|
|
2
|
+
// resolvePublicBaseUrl (which still re-exports it for its existing call
|
|
3
|
+
// sites) so this base-resolution logic lives in `config/` beside every
|
|
4
|
+
// other env-derived base URL, and mirrors config/preview.ts's
|
|
5
|
+
// previewBaseUrl idiom exactly: read fresh at call time (not frozen at
|
|
6
|
+
// module-import time, so a test's env override always takes effect),
|
|
7
|
+
// empty/whitespace-only treated as unset, trailing slashes stripped.
|
|
8
|
+
// Configured public base URL override — production behind a reverse
|
|
9
|
+
// proxy/CDN, where the request's own Host/proto may not be the
|
|
10
|
+
// public-facing one. Unset (or blank) means "derive from the request"
|
|
11
|
+
// (see resolvePublicBaseUrl below).
|
|
12
|
+
export function configuredPublicUrl() {
|
|
13
|
+
const raw = process.env.VELORA_PUBLIC_URL;
|
|
14
|
+
if (!raw) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
const trimmed = raw.trim();
|
|
18
|
+
if (!trimmed) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return trimmed.replace(/\/+$/, "");
|
|
22
|
+
}
|
|
23
|
+
// S186c Task 3, mandate 1: the PUBLIC surface (REST /api/v1/media* and
|
|
24
|
+
// GraphQL) is consumed cross-origin by design — a headless frontend's own
|
|
25
|
+
// server fetches `downloadUrl` directly, so a path-relative URL there
|
|
26
|
+
// resolves against the wrong origin.
|
|
27
|
+
//
|
|
28
|
+
// Base resolution: VELORA_PUBLIC_URL when the operator has set one;
|
|
29
|
+
// otherwise derived from THIS request's protocol + `request.host` — NOT
|
|
30
|
+
// `request.hostname`, which strips the port in Fastify 5 (H2 fix: a
|
|
31
|
+
// non-default-port deployment, e.g. the blog starter's default
|
|
32
|
+
// http://localhost:3000, was getting handed back
|
|
33
|
+
// http://localhost/media/... with the port silently dropped).
|
|
34
|
+
// `request.host`/`request.protocol` both honor trustProxyFromEnv() the
|
|
35
|
+
// same way every other host-derived value in this app does (they read
|
|
36
|
+
// X-Forwarded-Host/-Proto once trustProxy is configured). Never cached —
|
|
37
|
+
// re-derived per request, since two requests can legitimately arrive with
|
|
38
|
+
// different hosts (multiple domains pointed at one instance).
|
|
39
|
+
export function resolvePublicBaseUrl(request) {
|
|
40
|
+
const configured = configuredPublicUrl();
|
|
41
|
+
if (configured) {
|
|
42
|
+
return configured;
|
|
43
|
+
}
|
|
44
|
+
return `${request.protocol}://${request.host}`;
|
|
45
|
+
}
|
|
@@ -1,3 +1,43 @@
|
|
|
1
|
+
// Shared probe for every additive step below. NEVER probe by running a
|
|
2
|
+
// statement that's expected to fail on a pre-column database and catching
|
|
3
|
+
// the error — `applyMigrations` (packages/db-adapter) wraps each step's
|
|
4
|
+
// up() in a single BEGIN/COMMIT. On postgresql, one failed statement
|
|
5
|
+
// (`SELECT <missing column>`) leaves that transaction in error state
|
|
6
|
+
// 25P02 ("current transaction is aborted, commands ignored until end of
|
|
7
|
+
// transaction block"); every statement issued afterwards on the SAME
|
|
8
|
+
// transaction — including the ALTER meant to fix things — fails too, and
|
|
9
|
+
// the whole step throws. A pre-column postgres database can then never
|
|
10
|
+
// get the column added: the boot gate refuses the site forever. MySQL and
|
|
11
|
+
// SQLite don't poison the transaction this way, but postgres is Tier 1
|
|
12
|
+
// and this idiom is banned everywhere for consistency — no step body may
|
|
13
|
+
// contain a try/catch around a statement expected to fail.
|
|
14
|
+
//
|
|
15
|
+
// Instead, ask the schema catalog directly — a query that ALWAYS
|
|
16
|
+
// succeeds, column present or not:
|
|
17
|
+
// - mysql: information_schema.columns, scoped to the current database.
|
|
18
|
+
// - sqlite: the pragma_table_info() table-valued function.
|
|
19
|
+
// - postgresql: not used by this helper — see the comment on each
|
|
20
|
+
// postgres branch below, `ADD COLUMN IF NOT EXISTS` makes the probe
|
|
21
|
+
// unnecessary there and this helper is never called with "postgresql".
|
|
22
|
+
async function columnExists(tx, dialect, table, column) {
|
|
23
|
+
if (dialect === "postgresql") {
|
|
24
|
+
// ADD COLUMN IF NOT EXISTS makes probing unnecessary on postgres —
|
|
25
|
+
// no step should ever call this helper with "postgresql".
|
|
26
|
+
throw new Error("columnExists: postgresql steps use ADD COLUMN IF NOT EXISTS instead of probing");
|
|
27
|
+
}
|
|
28
|
+
if (dialect === "sqlite") {
|
|
29
|
+
const row = await tx.queryOne({
|
|
30
|
+
sql: "SELECT COUNT(*) AS n FROM pragma_table_info(?) WHERE name = ?",
|
|
31
|
+
params: [table, column],
|
|
32
|
+
});
|
|
33
|
+
return Number(row?.n ?? 0) > 0;
|
|
34
|
+
}
|
|
35
|
+
const row = await tx.queryOne({
|
|
36
|
+
sql: "SELECT COUNT(*) AS n FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = ? AND column_name = ?",
|
|
37
|
+
params: [table, column],
|
|
38
|
+
});
|
|
39
|
+
return Number(row?.n ?? 0) > 0;
|
|
40
|
+
}
|
|
1
41
|
// The Prisma-owned schema's upgrade ledger. 0001 is a pure baseline: it
|
|
2
42
|
// marks "the 0.10.0-release db-push shape" and carries no SQL. Every schema
|
|
3
43
|
// change that ships AFTER that release becomes its own numbered step here —
|
|
@@ -26,27 +66,66 @@ const coreBaseline = {
|
|
|
26
66
|
// demo box after S182 shipped) already has the column, and this step must
|
|
27
67
|
// run harmlessly against it too. Rather than branch on "has 0001 already
|
|
28
68
|
// run without this column" (which the ledger can't tell apart from "db
|
|
29
|
-
// push already included it"),
|
|
30
|
-
// and only ALTER if
|
|
31
|
-
//
|
|
32
|
-
//
|
|
69
|
+
// push already included it"), check the schema catalog first via the
|
|
70
|
+
// shared columnExists() helper and only ALTER if it's missing — see that
|
|
71
|
+
// helper's comment for why this can never be a try/catch-of-a-failing-
|
|
72
|
+
// probe (it poisons the whole step's transaction on postgres). Postgres
|
|
73
|
+
// skips the check entirely: `ADD COLUMN IF NOT EXISTS` is natively
|
|
74
|
+
// idempotent and transaction-safe, so there's nothing to probe for.
|
|
33
75
|
function apiKeyScopeStep(dialect) {
|
|
34
76
|
return {
|
|
35
77
|
id: "0002_api_key_scope",
|
|
36
78
|
name: "api_keys.scope column (S182)",
|
|
37
79
|
up: async (tx) => {
|
|
38
|
-
|
|
39
|
-
await tx.
|
|
80
|
+
if (dialect === "postgresql") {
|
|
81
|
+
await tx.execute({
|
|
82
|
+
sql: "ALTER TABLE api_keys ADD COLUMN IF NOT EXISTS scope TEXT NOT NULL DEFAULT 'read'",
|
|
83
|
+
});
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (await columnExists(tx, dialect, "api_keys", "scope")) {
|
|
40
87
|
return; // column already present — nothing to do
|
|
41
88
|
}
|
|
42
|
-
|
|
43
|
-
|
|
89
|
+
const alter = dialect === "mysql"
|
|
90
|
+
? "ALTER TABLE api_keys ADD COLUMN scope VARCHAR(191) NOT NULL DEFAULT 'read'"
|
|
91
|
+
: "ALTER TABLE api_keys ADD COLUMN scope TEXT NOT NULL DEFAULT 'read'";
|
|
92
|
+
await tx.execute({ sql: alter });
|
|
93
|
+
},
|
|
94
|
+
// No-op, same as the baseline: additive steps never need to undo
|
|
95
|
+
// anything (house pattern — this ledger only ever moves forward).
|
|
96
|
+
down: async () => { },
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// media_files.visibility (S186c §2): `TEXT NOT NULL DEFAULT 'public'` on
|
|
100
|
+
// postgresql/sqlite, `VARCHAR(191) NOT NULL DEFAULT 'public'` on mysql —
|
|
101
|
+
// matching schema.prisma's `visibility String @default("public")`, which
|
|
102
|
+
// Prisma maps to VARCHAR(191) on mysql by its own default (same reasoning
|
|
103
|
+
// as 0002_api_key_scope above: no `@db.VarChar` override in either
|
|
104
|
+
// schema.prisma or .prisma-variant-mysql.schema.prisma).
|
|
105
|
+
//
|
|
106
|
+
// Same columnExists()-then-ALTER idiom as 0002 above (see its comment,
|
|
107
|
+
// and columnExists' own comment, for why a try/catch-of-a-failing-probe
|
|
108
|
+
// is banned): a post-S186c database (fresh db-push, or any deployment
|
|
109
|
+
// that boots after this ships) already has the column, and up() must run
|
|
110
|
+
// harmlessly against it too. Postgres again skips the check — ADD COLUMN
|
|
111
|
+
// IF NOT EXISTS is already idempotent and transaction-safe.
|
|
112
|
+
function mediaVisibilityStep(dialect) {
|
|
113
|
+
return {
|
|
114
|
+
id: "0003_media_visibility",
|
|
115
|
+
name: "media_files.visibility column (S186c)",
|
|
116
|
+
up: async (tx) => {
|
|
117
|
+
if (dialect === "postgresql") {
|
|
118
|
+
await tx.execute({
|
|
119
|
+
sql: "ALTER TABLE media_files ADD COLUMN IF NOT EXISTS visibility TEXT NOT NULL DEFAULT 'public'",
|
|
120
|
+
});
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
if (await columnExists(tx, dialect, "media_files", "visibility")) {
|
|
124
|
+
return; // column already present — nothing to do
|
|
44
125
|
}
|
|
45
|
-
const alter = dialect === "
|
|
46
|
-
? "ALTER TABLE
|
|
47
|
-
:
|
|
48
|
-
? "ALTER TABLE api_keys ADD COLUMN scope VARCHAR(191) NOT NULL DEFAULT 'read'"
|
|
49
|
-
: "ALTER TABLE api_keys ADD COLUMN scope TEXT NOT NULL DEFAULT 'read'";
|
|
126
|
+
const alter = dialect === "mysql"
|
|
127
|
+
? "ALTER TABLE media_files ADD COLUMN visibility VARCHAR(191) NOT NULL DEFAULT 'public'"
|
|
128
|
+
: "ALTER TABLE media_files ADD COLUMN visibility TEXT NOT NULL DEFAULT 'public'";
|
|
50
129
|
await tx.execute({ sql: alter });
|
|
51
130
|
},
|
|
52
131
|
// No-op, same as the baseline: additive steps never need to undo
|
|
@@ -54,13 +133,13 @@ function apiKeyScopeStep(dialect) {
|
|
|
54
133
|
down: async () => { },
|
|
55
134
|
};
|
|
56
135
|
}
|
|
57
|
-
// A factory, not a plain array: 0002's up()
|
|
58
|
-
//
|
|
136
|
+
// A factory, not a plain array: 0002/0003's up() need to know which dialect
|
|
137
|
+
// they're running against (TransactionContext carries no dialect field, only
|
|
59
138
|
// DatabaseAdapter does), so the registry is built per-dialect at the call
|
|
60
139
|
// site instead of threading dialect through the shared Migration type.
|
|
61
140
|
// CORE_MIGRATION_IDS below stays dialect-independent — ids never vary by
|
|
62
141
|
// dialect — so it's fine to read off of any one dialect's build.
|
|
63
142
|
export function buildCoreMigrations(dialect) {
|
|
64
|
-
return [coreBaseline, apiKeyScopeStep(dialect)];
|
|
143
|
+
return [coreBaseline, apiKeyScopeStep(dialect), mediaVisibilityStep(dialect)];
|
|
65
144
|
}
|
|
66
145
|
export const CORE_MIGRATION_IDS = buildCoreMigrations("sqlite").map((m) => m.id);
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.5.2","languages":{"en":{"hash":"
|
|
1
|
+
{"version":"1.5.2","languages":{"en":{"hash":"en_57d2f8922f","wasm":"en","page_count":11}},"include_characters":["_","‿","⁀","⁔","︳","︴","﹍","﹎","﹏","_"]}
|
|
Binary file
|