@kosdev-code/kos-ui-plugin 2.1.31 → 2.1.33

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.
@@ -1 +1 @@
1
- {"version":3,"file":"with-plugin-dev-server.d.ts","sourceRoot":"","sources":["../../../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-plugin-dev-server.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AACH,eAAO,MAAM,mBAAmB,aAAa,sBAAsB,cAQjD,GAAG,WAAW,GAAG,QAuJlC,CAAC"}
1
+ {"version":3,"file":"with-plugin-dev-server.d.ts","sourceRoot":"","sources":["../../../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-plugin-dev-server.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqFG;AACH,eAAO,MAAM,mBAAmB,aAAa,sBAAsB,cAQjD,GAAG,WAAW,GAAG,QAiKlC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kosdev-code/kos-ui-plugin",
3
- "version": "2.1.31",
3
+ "version": "2.1.33",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "kos": {
23
23
  "build": {
24
- "gitHash": "292ed660445b69d5a70bd9b40e6f910b97b19867"
24
+ "gitHash": "e05cb0b38c81d9ea95d719504f4afe4a6c8737bf"
25
25
  }
26
26
  },
27
27
  "publishConfig": {
package/webpack.cjs CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const B=require("fs"),M=require("path"),re=require("os"),oe=require("crypto"),F=require("uuid");function G(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const s in e)if(s!=="default"){const a=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(t,s,a.get?a:{enumerable:!0,get:()=>e[s]})}}return t.default=e,Object.freeze(t)}const Q=G(B),H=G(M);var N={exports:{}};const ne="16.6.1",se={version:ne},J=B,Y=M,ae=re,ie=oe,ce=se,U=ce.version,le=/(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;function ue(e){const t={};let s=e.toString();s=s.replace(/\r\n?/mg,`
2
- `);let a;for(;(a=le.exec(s))!=null;){const u=a[1];let r=a[2]||"";r=r.trim();const n=r[0];r=r.replace(/^(['"`])([\s\S]*)\1$/mg,"$2"),n==='"'&&(r=r.replace(/\\n/g,`
3
- `),r=r.replace(/\\r/g,"\r")),t[u]=r}return t}function ge(e){e=e||{};const t=ee(e);e.path=t;const s=p.configDotenv(e);if(!s.parsed){const n=new Error(`MISSING_DATA: Cannot parse ${t} for an unknown reason`);throw n.code="MISSING_DATA",n}const a=Z(e).split(","),u=a.length;let r;for(let n=0;n<u;n++)try{const o=a[n].trim(),c=pe(s,o);r=p.decrypt(c.ciphertext,c.key);break}catch(o){if(n+1>=u)throw o}return p.parse(r)}function de(e){console.log(`[dotenv@${U}][WARN] ${e}`)}function R(e){console.log(`[dotenv@${U}][DEBUG] ${e}`)}function X(e){console.log(`[dotenv@${U}] ${e}`)}function Z(e){return e&&e.DOTENV_KEY&&e.DOTENV_KEY.length>0?e.DOTENV_KEY:process.env.DOTENV_KEY&&process.env.DOTENV_KEY.length>0?process.env.DOTENV_KEY:""}function pe(e,t){let s;try{s=new URL(t)}catch(o){if(o.code==="ERR_INVALID_URL"){const c=new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");throw c.code="INVALID_DOTENV_KEY",c}throw o}const a=s.password;if(!a){const o=new Error("INVALID_DOTENV_KEY: Missing key part");throw o.code="INVALID_DOTENV_KEY",o}const u=s.searchParams.get("environment");if(!u){const o=new Error("INVALID_DOTENV_KEY: Missing environment part");throw o.code="INVALID_DOTENV_KEY",o}const r=`DOTENV_VAULT_${u.toUpperCase()}`,n=e.parsed[r];if(!n){const o=new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${r} in your .env.vault file.`);throw o.code="NOT_FOUND_DOTENV_ENVIRONMENT",o}return{ciphertext:n,key:a}}function ee(e){let t=null;if(e&&e.path&&e.path.length>0)if(Array.isArray(e.path))for(const s of e.path)J.existsSync(s)&&(t=s.endsWith(".vault")?s:`${s}.vault`);else t=e.path.endsWith(".vault")?e.path:`${e.path}.vault`;else t=Y.resolve(process.cwd(),".env.vault");return J.existsSync(t)?t:null}function z(e){return e[0]==="~"?Y.join(ae.homedir(),e.slice(1)):e}function fe(e){const t=!!(e&&e.debug),s=e&&"quiet"in e?e.quiet:!0;(t||!s)&&X("Loading env from encrypted .env.vault");const a=p._parseVault(e);let u=process.env;return e&&e.processEnv!=null&&(u=e.processEnv),p.populate(u,a,e),{parsed:a}}function ve(e){const t=Y.resolve(process.cwd(),".env");let s="utf8";const a=!!(e&&e.debug),u=e&&"quiet"in e?e.quiet:!0;e&&e.encoding?s=e.encoding:a&&R("No encoding is specified. UTF-8 is used by default");let r=[t];if(e&&e.path)if(!Array.isArray(e.path))r=[z(e.path)];else{r=[];for(const d of e.path)r.push(z(d))}let n;const o={};for(const d of r)try{const g=p.parse(J.readFileSync(d,{encoding:s}));p.populate(o,g,e)}catch(g){a&&R(`Failed to load ${d} ${g.message}`),n=g}let c=process.env;if(e&&e.processEnv!=null&&(c=e.processEnv),p.populate(c,o,e),a||!u){const d=Object.keys(o).length,g=[];for(const m of r)try{const v=Y.relative(process.cwd(),m);g.push(v)}catch(v){a&&R(`Failed to load ${m} ${v.message}`),n=v}X(`injecting env (${d}) from ${g.join(",")}`)}return n?{parsed:o,error:n}:{parsed:o}}function he(e){if(Z(e).length===0)return p.configDotenv(e);const t=ee(e);return t?p._configVault(e):(de(`You set DOTENV_KEY but you are missing a .env.vault file at ${t}. Did you forget to build it?`),p.configDotenv(e))}function De(e,t){const s=Buffer.from(t.slice(-64),"hex");let a=Buffer.from(e,"base64");const u=a.subarray(0,12),r=a.subarray(-16);a=a.subarray(12,-16);try{const n=ie.createDecipheriv("aes-256-gcm",s,u);return n.setAuthTag(r),`${n.update(a)}${n.final()}`}catch(n){const o=n instanceof RangeError,c=n.message==="Invalid key length",d=n.message==="Unsupported state or unable to authenticate data";if(o||c){const g=new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");throw g.code="INVALID_DOTENV_KEY",g}else if(d){const g=new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");throw g.code="DECRYPTION_FAILED",g}else throw n}}function Ee(e,t,s={}){const a=!!(s&&s.debug),u=!!(s&&s.override);if(typeof t!="object"){const r=new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");throw r.code="OBJECT_REQUIRED",r}for(const r of Object.keys(t))Object.prototype.hasOwnProperty.call(e,r)?(u===!0&&(e[r]=t[r]),a&&R(u===!0?`"${r}" is already defined and WAS overwritten`:`"${r}" is already defined and was NOT overwritten`)):e[r]=t[r]}const p={configDotenv:ve,_configVault:fe,_parseVault:ge,config:he,decrypt:De,parse:ue,populate:Ee};N.exports.configDotenv=p.configDotenv;N.exports._configVault=p._configVault;N.exports._parseVault=p._parseVault;var ke=N.exports.config=p.config;N.exports.decrypt=p.decrypt;N.exports.parse=p.parse;N.exports.populate=p.populate;N.exports=p;function we(){return Object.keys(process.env).filter(t=>t.startsWith("KOS_"))}ke({path:".env"});const ye=e=>t=>{var s;return t&&(t.resolve=t.resolve||{},t.resolve.fallback={...t.resolve.fallback,path:!1}),t.mode=process.env.NODE_ENV||t.mode,(s=t==null?void 0:t.plugins)==null||s.push(new e.EnvironmentPlugin(["NODE_ENV",...we()])),t},me=(e={})=>{const{kosJsonPath:t=".kos.json",projectRoot:s,defaultContext:a="kosdev.ddk",verbose:u=!1}=e;return(r,n)=>{var g,m;if(!r.devServer)return u&&console.log("[withPluginDevServer] No devServer config found, skipping middleware"),r;let o=s||process.cwd();s||(r!=null&&r.context&&typeof r.context=="string"?o=r.context:(g=n==null?void 0:n.options)!=null&&g.root&&((m=n==null?void 0:n.options)!=null&&m.projectRoot)&&(o=H.join(n.options.root,n.options.projectRoot)));const c=H.resolve(o,t);u&&console.log("[withPluginDevServer] Configuration:",{kosJsonPath:c,projectRoot:o,defaultContext:a});const d=r.devServer.setupMiddlewares;return r.devServer.setupMiddlewares=(v,O)=>(d&&(v=d(v,O)),O.app.get("/api/kos/ui/plugins/contexts",(L,_)=>{var S,q,E,V;try{if(!Q.existsSync(c)){const b=`.kos.json not found at ${c}`;return console.error(`[withPluginDevServer] ${b}`),_.status(404).json({status:404,error:b,hint:"Ensure .kos.json exists in your plugin project root"})}const k=Q.readFileSync(c,"utf-8"),T=JSON.parse(k),P=(q=(S=T.kos)==null?void 0:S.ui)==null?void 0:q.plugin;if(!P){const b="kos.ui.plugin section not found in .kos.json";return console.error(`[withPluginDevServer] ${b}`),_.status(400).json({status:400,error:b,hint:"Ensure .kos.json has kos.ui.plugin section defined"})}const j=(E=T.test)==null?void 0:E.plugin,I=(j==null?void 0:j.context)||a,K=F.v4(),$={status:200,version:{major:1,minor:0},data:[{name:I,plugins:[{descriptor:P,id:K,path:"/"}]}]};u&&console.log("[withPluginDevServer] Serving plugin metadata:",{pluginId:P.id,context:I,extensionsCount:((V=P.extensions)==null?void 0:V.length)||0}),_.json($)}catch(k){console.error("[withPluginDevServer] Error serving plugin metadata:",k),_.status(500).json({status:500,error:"Failed to serve plugin metadata",details:k instanceof Error?k.message:String(k)})}}),u&&console.log("[withPluginDevServer] Plugin metadata endpoint registered at /api/kos/ui/plugins/contexts"),v),r}},_e=e=>{const{pluginServers:t,includeHostPlugins:s=!0,kosJsonPath:a=".kos.json",mergeWithBackend:u=!1,fallbackToBackend:r=!0,backendUrl:n="http://localhost:8081",verbose:o=!1}=e;return(c,d)=>{var O,L;let g=process.cwd();c!=null&&c.context&&typeof c.context=="string"?g=c.context:(O=d==null?void 0:d.options)!=null&&O.root&&((L=d==null?void 0:d.options)!=null&&L.projectRoot)&&(g=M.join(d.options.root,d.options.projectRoot));const m=M.join(g,a);if(!c.devServer)return o&&console.log("[withPluginDevAggregator] No devServer config found, skipping middleware"),c;o&&console.log("[withPluginDevAggregator] Configuration:",{pluginServers:t,fallbackToBackend:r,backendUrl:n,projectRoot:g,kosJsonPath:m});const v=c.devServer.setupMiddlewares;return c.devServer.setupMiddlewares=(_,S)=>(v&&(_=v(_,S)),S.app.get("/api/kos/ui/plugins/contexts",async(q,E)=>{var V,k,T,P,j,I,K;try{if(t.length===0)if(r){o&&console.log("[withPluginDevAggregator] No plugin servers, proxying to backend:",n);const l=await(await fetch(`${n}/api/kos/ui/plugins/contexts`)).json();return E.json(l)}else return E.status(404).json({status:404,error:"No plugin servers configured",hint:"Add plugin server URLs to withPluginDevAggregator options or enable fallbackToBackend"});const b=(await Promise.all(t.map(async i=>{try{const l=await fetch(`${i}/api/kos/ui/plugins/contexts`);if(!l.ok)return o&&console.warn(`[withPluginDevAggregator] Failed to fetch from ${i}: ${l.status}`),null;const f=await l.json();return{serverUrl:i,data:f}}catch(l){return o&&console.warn(`[withPluginDevAggregator] Error fetching from ${i}:`,l),null}}))).filter(i=>i&&i.data&&i.data.status===200);if(b.length===0&&r){o&&console.log("[withPluginDevAggregator] No plugin servers responded, falling back to backend");try{const l=await(await fetch(`${n}/api/kos/ui/plugins/contexts`)).json();return E.json(l)}catch(i){return E.status(503).json({status:503,error:"No plugin servers available and backend unreachable",details:i instanceof Error?i.message:String(i)})}}const D={},C={};if(u)try{o&&console.log("[withPluginDevAggregator] Fetching backend plugins from:",n);const i=await fetch(`${n}/api/kos/ui/plugins/contexts`);if(i.ok){const l=await i.json();l.status===200&&l.data&&(l.data.forEach(f=>{const w=f.name;D[w]||(D[w]=[]),f.plugins.forEach(y=>{var h;D[w].push(y),o&&console.log(`[withPluginDevAggregator] Added backend plugin: ${(h=y.descriptor)==null?void 0:h.id} (no override)`)})}),o&&console.log("[withPluginDevAggregator] Successfully merged backend plugins"))}else o&&console.warn(`[withPluginDevAggregator] Backend fetch failed: ${i.status}`)}catch(i){o&&console.warn("[withPluginDevAggregator] Error fetching backend plugins:",i)}if(s)try{const i=B.readFileSync(m,"utf-8"),l=JSON.parse(i),f=(k=(V=l.kos)==null?void 0:V.ui)==null?void 0:k.plugin,w=(j=(P=(T=l.kosdev)==null?void 0:T.ddk)==null?void 0:P.ncui)==null?void 0:j.plugin,y=[];f&&y.push({name:((K=(I=l.test)==null?void 0:I.plugin)==null?void 0:K.context)||"kos.ui",plugin:{descriptor:f,id:F.v4(),path:"/"}}),w&&y.push({name:"kosdev.ddk",plugin:{descriptor:w,id:F.v4(),path:"/"}}),y.forEach(({name:h,plugin:A})=>{D[h]||(D[h]=[]),D[h].push(A),o&&console.log(`[withPluginDevAggregator] Added host plugin: ${A.descriptor.id} to context ${h}`)})}catch(i){o&&console.warn("[withPluginDevAggregator] Failed to read host .kos.json:",i)}b.forEach(i=>{var w;if(!i)return;const{serverUrl:l,data:f}=i;(w=f.data)==null||w.forEach(y=>{const h=y.name;D[h]||(D[h]=[]),y.plugins.forEach(A=>{var W;D[h].push(A),C[A.id]=`${l}/`,o&&console.log(`[withPluginDevAggregator] Added local dev plugin: ${(W=A.descriptor)==null?void 0:W.id} with override to ${l}/`)})})});const x=Object.entries(D).map(([i,l])=>({name:i,plugins:l})),te={status:200,version:{major:1,minor:0},data:x,overrides:C};o&&console.log("[withPluginDevAggregator] Aggregated plugins:",{contexts:x.length,totalPlugins:x.reduce((i,l)=>i+l.plugins.length,0),pluginIds:x.flatMap(i=>i.plugins.map(l=>{var f;return(f=l.descriptor)==null?void 0:f.id})),overrides:C}),E.json(te)}catch($){console.error("[withPluginDevAggregator] Error aggregating plugins:",$),E.status(500).json({status:500,error:"Failed to aggregate plugin metadata",details:$ instanceof Error?$.message:String($)})}}),o&&console.log("[withPluginDevAggregator] Plugin aggregation endpoint registered at /api/kos/ui/plugins/contexts"),_),c}};exports.withKosConfig=ye;exports.withPluginDevAggregator=_e;exports.withPluginDevServer=me;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const B=require("fs"),M=require("path"),re=require("os"),oe=require("crypto"),F=require("uuid");function G(e){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const s in e)if(s!=="default"){const a=Object.getOwnPropertyDescriptor(e,s);Object.defineProperty(r,s,a.get?a:{enumerable:!0,get:()=>e[s]})}}return r.default=e,Object.freeze(r)}const H=G(B),Q=G(M);var b={exports:{}};const ne="16.6.1",se={version:ne},J=B,C=M,ae=re,ie=oe,le=se,U=le.version,ce=/(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;function ue(e){const r={};let s=e.toString();s=s.replace(/\r\n?/mg,`
2
+ `);let a;for(;(a=ce.exec(s))!=null;){const u=a[1];let t=a[2]||"";t=t.trim();const n=t[0];t=t.replace(/^(['"`])([\s\S]*)\1$/mg,"$2"),n==='"'&&(t=t.replace(/\\n/g,`
3
+ `),t=t.replace(/\\r/g,"\r")),r[u]=t}return r}function ge(e){e=e||{};const r=ee(e);e.path=r;const s=p.configDotenv(e);if(!s.parsed){const n=new Error(`MISSING_DATA: Cannot parse ${r} for an unknown reason`);throw n.code="MISSING_DATA",n}const a=Z(e).split(","),u=a.length;let t;for(let n=0;n<u;n++)try{const o=a[n].trim(),l=pe(s,o);t=p.decrypt(l.ciphertext,l.key);break}catch(o){if(n+1>=u)throw o}return p.parse(t)}function de(e){console.log(`[dotenv@${U}][WARN] ${e}`)}function R(e){console.log(`[dotenv@${U}][DEBUG] ${e}`)}function X(e){console.log(`[dotenv@${U}] ${e}`)}function Z(e){return e&&e.DOTENV_KEY&&e.DOTENV_KEY.length>0?e.DOTENV_KEY:process.env.DOTENV_KEY&&process.env.DOTENV_KEY.length>0?process.env.DOTENV_KEY:""}function pe(e,r){let s;try{s=new URL(r)}catch(o){if(o.code==="ERR_INVALID_URL"){const l=new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");throw l.code="INVALID_DOTENV_KEY",l}throw o}const a=s.password;if(!a){const o=new Error("INVALID_DOTENV_KEY: Missing key part");throw o.code="INVALID_DOTENV_KEY",o}const u=s.searchParams.get("environment");if(!u){const o=new Error("INVALID_DOTENV_KEY: Missing environment part");throw o.code="INVALID_DOTENV_KEY",o}const t=`DOTENV_VAULT_${u.toUpperCase()}`,n=e.parsed[t];if(!n){const o=new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${t} in your .env.vault file.`);throw o.code="NOT_FOUND_DOTENV_ENVIRONMENT",o}return{ciphertext:n,key:a}}function ee(e){let r=null;if(e&&e.path&&e.path.length>0)if(Array.isArray(e.path))for(const s of e.path)J.existsSync(s)&&(r=s.endsWith(".vault")?s:`${s}.vault`);else r=e.path.endsWith(".vault")?e.path:`${e.path}.vault`;else r=C.resolve(process.cwd(),".env.vault");return J.existsSync(r)?r:null}function z(e){return e[0]==="~"?C.join(ae.homedir(),e.slice(1)):e}function fe(e){const r=!!(e&&e.debug),s=e&&"quiet"in e?e.quiet:!0;(r||!s)&&X("Loading env from encrypted .env.vault");const a=p._parseVault(e);let u=process.env;return e&&e.processEnv!=null&&(u=e.processEnv),p.populate(u,a,e),{parsed:a}}function ve(e){const r=C.resolve(process.cwd(),".env");let s="utf8";const a=!!(e&&e.debug),u=e&&"quiet"in e?e.quiet:!0;e&&e.encoding?s=e.encoding:a&&R("No encoding is specified. UTF-8 is used by default");let t=[r];if(e&&e.path)if(!Array.isArray(e.path))t=[z(e.path)];else{t=[];for(const d of e.path)t.push(z(d))}let n;const o={};for(const d of t)try{const g=p.parse(J.readFileSync(d,{encoding:s}));p.populate(o,g,e)}catch(g){a&&R(`Failed to load ${d} ${g.message}`),n=g}let l=process.env;if(e&&e.processEnv!=null&&(l=e.processEnv),p.populate(l,o,e),a||!u){const d=Object.keys(o).length,g=[];for(const m of t)try{const v=C.relative(process.cwd(),m);g.push(v)}catch(v){a&&R(`Failed to load ${m} ${v.message}`),n=v}X(`injecting env (${d}) from ${g.join(",")}`)}return n?{parsed:o,error:n}:{parsed:o}}function he(e){if(Z(e).length===0)return p.configDotenv(e);const r=ee(e);return r?p._configVault(e):(de(`You set DOTENV_KEY but you are missing a .env.vault file at ${r}. Did you forget to build it?`),p.configDotenv(e))}function Ee(e,r){const s=Buffer.from(r.slice(-64),"hex");let a=Buffer.from(e,"base64");const u=a.subarray(0,12),t=a.subarray(-16);a=a.subarray(12,-16);try{const n=ie.createDecipheriv("aes-256-gcm",s,u);return n.setAuthTag(t),`${n.update(a)}${n.final()}`}catch(n){const o=n instanceof RangeError,l=n.message==="Invalid key length",d=n.message==="Unsupported state or unable to authenticate data";if(o||l){const g=new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");throw g.code="INVALID_DOTENV_KEY",g}else if(d){const g=new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");throw g.code="DECRYPTION_FAILED",g}else throw n}}function De(e,r,s={}){const a=!!(s&&s.debug),u=!!(s&&s.override);if(typeof r!="object"){const t=new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");throw t.code="OBJECT_REQUIRED",t}for(const t of Object.keys(r))Object.prototype.hasOwnProperty.call(e,t)?(u===!0&&(e[t]=r[t]),a&&R(u===!0?`"${t}" is already defined and WAS overwritten`:`"${t}" is already defined and was NOT overwritten`)):e[t]=r[t]}const p={configDotenv:ve,_configVault:fe,_parseVault:ge,config:he,decrypt:Ee,parse:ue,populate:De};b.exports.configDotenv=p.configDotenv;b.exports._configVault=p._configVault;b.exports._parseVault=p._parseVault;var we=b.exports.config=p.config;b.exports.decrypt=p.decrypt;b.exports.parse=p.parse;b.exports.populate=p.populate;b.exports=p;function ke(){return Object.keys(process.env).filter(r=>r.startsWith("KOS_"))}we({path:".env"});const ye=e=>r=>{var s;return r&&(r.resolve=r.resolve||{},r.resolve.fallback={...r.resolve.fallback,path:!1}),r.mode=process.env.NODE_ENV||r.mode,(s=r==null?void 0:r.plugins)==null||s.push(new e.EnvironmentPlugin(["NODE_ENV",...ke()])),r},me=(e={})=>{const{kosJsonPath:r=".kos.json",projectRoot:s,defaultContext:a="kosdev.ddk",verbose:u=!1}=e;return(t,n)=>{var g,m;if(!t.devServer)return u&&console.log("[withPluginDevServer] No devServer config found, skipping middleware"),t;t.devServer.headers={...t.devServer.headers,"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, PUT, DELETE, PATCH, OPTIONS","Access-Control-Allow-Headers":"X-Requested-With, content-type, Authorization"};let o=s||process.cwd();s||(t!=null&&t.context&&typeof t.context=="string"?o=t.context:(g=n==null?void 0:n.options)!=null&&g.root&&((m=n==null?void 0:n.options)!=null&&m.projectRoot)&&(o=Q.join(n.options.root,n.options.projectRoot)));const l=Q.resolve(o,r);u&&console.log("[withPluginDevServer] Configuration:",{kosJsonPath:l,projectRoot:o,defaultContext:a});const d=t.devServer.setupMiddlewares;return t.devServer.setupMiddlewares=(v,O)=>(d&&(v=d(v,O)),O.app.get("/api/kos/ui/plugins/contexts",(L,_)=>{var S,Y,D,T;try{if(!H.existsSync(l)){const P=`.kos.json not found at ${l}`;return console.error(`[withPluginDevServer] ${P}`),_.status(404).json({status:404,error:P,hint:"Ensure .kos.json exists in your plugin project root"})}const w=H.readFileSync(l,"utf-8"),V=JSON.parse(w),N=(Y=(S=V.kos)==null?void 0:S.ui)==null?void 0:Y.plugin;if(!N){const P="kos.ui.plugin section not found in .kos.json";return console.error(`[withPluginDevServer] ${P}`),_.status(400).json({status:400,error:P,hint:"Ensure .kos.json has kos.ui.plugin section defined"})}const $=(D=V.test)==null?void 0:D.plugin,I=($==null?void 0:$.context)||a,K=F.v4(),A={status:200,version:{major:1,minor:0},data:[{name:I,plugins:[{descriptor:N,id:K,path:"/"}]}]};u&&console.log("[withPluginDevServer] Serving plugin metadata:",{pluginId:N.id,context:I,extensionsCount:((T=N.extensions)==null?void 0:T.length)||0}),_.json(A)}catch(w){console.error("[withPluginDevServer] Error serving plugin metadata:",w),_.status(500).json({status:500,error:"Failed to serve plugin metadata",details:w instanceof Error?w.message:String(w)})}}),u&&console.log("[withPluginDevServer] Plugin metadata endpoint registered at /api/kos/ui/plugins/contexts"),v),t}},_e=e=>{const{pluginServers:r,includeHostPlugins:s=!0,kosJsonPath:a=".kos.json",mergeWithBackend:u=!1,fallbackToBackend:t=!0,backendUrl:n="http://localhost:8081",verbose:o=!1}=e;return(l,d)=>{var O,L;let g=process.cwd();l!=null&&l.context&&typeof l.context=="string"?g=l.context:(O=d==null?void 0:d.options)!=null&&O.root&&((L=d==null?void 0:d.options)!=null&&L.projectRoot)&&(g=M.join(d.options.root,d.options.projectRoot));const m=M.join(g,a);if(!l.devServer)return o&&console.log("[withPluginDevAggregator] No devServer config found, skipping middleware"),l;o&&console.log("[withPluginDevAggregator] Configuration:",{pluginServers:r,fallbackToBackend:t,backendUrl:n,projectRoot:g,kosJsonPath:m});const v=l.devServer.setupMiddlewares;return l.devServer.setupMiddlewares=(_,S)=>(v&&(_=v(_,S)),S.app.get("/api/kos/ui/plugins/contexts",async(Y,D)=>{var T,w,V,N,$,I,K;try{if(r.length===0)if(t){o&&console.log("[withPluginDevAggregator] No plugin servers, proxying to backend:",n);const c=await(await fetch(`${n}/api/kos/ui/plugins/contexts`)).json();return D.json(c)}else return D.status(404).json({status:404,error:"No plugin servers configured",hint:"Add plugin server URLs to withPluginDevAggregator options or enable fallbackToBackend"});const P=(await Promise.all(r.map(async i=>{try{const c=await fetch(`${i}/api/kos/ui/plugins/contexts`);if(!c.ok)return o&&console.warn(`[withPluginDevAggregator] Failed to fetch from ${i}: ${c.status}`),null;const f=await c.json();return{serverUrl:i,data:f}}catch(c){return o&&console.warn(`[withPluginDevAggregator] Error fetching from ${i}:`,c),null}}))).filter(i=>i&&i.data&&i.data.status===200);if(P.length===0&&t){o&&console.log("[withPluginDevAggregator] No plugin servers responded, falling back to backend");try{const c=await(await fetch(`${n}/api/kos/ui/plugins/contexts`)).json();return D.json(c)}catch(i){return D.status(503).json({status:503,error:"No plugin servers available and backend unreachable",details:i instanceof Error?i.message:String(i)})}}const E={},q={};if(u)try{o&&console.log("[withPluginDevAggregator] Fetching backend plugins from:",n);const i=await fetch(`${n}/api/kos/ui/plugins/contexts`);if(i.ok){const c=await i.json();c.status===200&&c.data&&(c.data.forEach(f=>{const k=f.name;E[k]||(E[k]=[]),f.plugins.forEach(y=>{var h;E[k].push(y),o&&console.log(`[withPluginDevAggregator] Added backend plugin: ${(h=y.descriptor)==null?void 0:h.id} (no override)`)})}),o&&console.log("[withPluginDevAggregator] Successfully merged backend plugins"))}else o&&console.warn(`[withPluginDevAggregator] Backend fetch failed: ${i.status}`)}catch(i){o&&console.warn("[withPluginDevAggregator] Error fetching backend plugins:",i)}if(s)try{const i=B.readFileSync(m,"utf-8"),c=JSON.parse(i),f=(w=(T=c.kos)==null?void 0:T.ui)==null?void 0:w.plugin,k=($=(N=(V=c.kosdev)==null?void 0:V.ddk)==null?void 0:N.ncui)==null?void 0:$.plugin,y=[];f&&y.push({name:((K=(I=c.test)==null?void 0:I.plugin)==null?void 0:K.context)||"kos.ui",plugin:{descriptor:f,id:F.v4(),path:"/"}}),k&&y.push({name:"kosdev.ddk",plugin:{descriptor:k,id:F.v4(),path:"/"}}),y.forEach(({name:h,plugin:j})=>{E[h]||(E[h]=[]),E[h].push(j),o&&console.log(`[withPluginDevAggregator] Added host plugin: ${j.descriptor.id} to context ${h}`)})}catch(i){o&&console.warn("[withPluginDevAggregator] Failed to read host .kos.json:",i)}P.forEach(i=>{var k;if(!i)return;const{serverUrl:c,data:f}=i;(k=f.data)==null||k.forEach(y=>{const h=y.name;E[h]||(E[h]=[]),y.plugins.forEach(j=>{var W;E[h].push(j),q[j.id]=`${c}/`,o&&console.log(`[withPluginDevAggregator] Added local dev plugin: ${(W=j.descriptor)==null?void 0:W.id} with override to ${c}/`)})})});const x=Object.entries(E).map(([i,c])=>({name:i,plugins:c})),te={status:200,version:{major:1,minor:0},data:x,overrides:q};o&&console.log("[withPluginDevAggregator] Aggregated plugins:",{contexts:x.length,totalPlugins:x.reduce((i,c)=>i+c.plugins.length,0),pluginIds:x.flatMap(i=>i.plugins.map(c=>{var f;return(f=c.descriptor)==null?void 0:f.id})),overrides:q}),D.json(te)}catch(A){console.error("[withPluginDevAggregator] Error aggregating plugins:",A),D.status(500).json({status:500,error:"Failed to aggregate plugin metadata",details:A instanceof Error?A.message:String(A)})}}),o&&console.log("[withPluginDevAggregator] Plugin aggregation endpoint registered at /api/kos/ui/plugins/contexts"),_),l}};exports.withKosConfig=ye;exports.withPluginDevAggregator=_e;exports.withPluginDevServer=me;
4
4
  //# sourceMappingURL=webpack.cjs.map
package/webpack.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"webpack.cjs","sources":["../../../../node_modules/dotenv/lib/main.js","../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-kos-config.ts","../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-plugin-dev-server.ts","../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-plugin-dev-aggregator.ts"],"sourcesContent":["const fs = require('fs')\nconst path = require('path')\nconst os = require('os')\nconst crypto = require('crypto')\nconst packageJson = require('../package.json')\n\nconst version = packageJson.version\n\nconst LINE = /(?:^|^)\\s*(?:export\\s+)?([\\w.-]+)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?\\s*(?:#.*)?(?:$|$)/mg\n\n// Parse src into an Object\nfunction parse (src) {\n const obj = {}\n\n // Convert buffer to string\n let lines = src.toString()\n\n // Convert line breaks to same format\n lines = lines.replace(/\\r\\n?/mg, '\\n')\n\n let match\n while ((match = LINE.exec(lines)) != null) {\n const key = match[1]\n\n // Default undefined or null to empty string\n let value = (match[2] || '')\n\n // Remove whitespace\n value = value.trim()\n\n // Check if double quoted\n const maybeQuote = value[0]\n\n // Remove surrounding quotes\n value = value.replace(/^(['\"`])([\\s\\S]*)\\1$/mg, '$2')\n\n // Expand newlines if double quoted\n if (maybeQuote === '\"') {\n value = value.replace(/\\\\n/g, '\\n')\n value = value.replace(/\\\\r/g, '\\r')\n }\n\n // Add to object\n obj[key] = value\n }\n\n return obj\n}\n\nfunction _parseVault (options) {\n options = options || {}\n\n const vaultPath = _vaultPath(options)\n options.path = vaultPath // parse .env.vault\n const result = DotenvModule.configDotenv(options)\n if (!result.parsed) {\n const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`)\n err.code = 'MISSING_DATA'\n throw err\n }\n\n // handle scenario for comma separated keys - for use with key rotation\n // example: DOTENV_KEY=\"dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod\"\n const keys = _dotenvKey(options).split(',')\n const length = keys.length\n\n let decrypted\n for (let i = 0; i < length; i++) {\n try {\n // Get full key\n const key = keys[i].trim()\n\n // Get instructions for decrypt\n const attrs = _instructions(result, key)\n\n // Decrypt\n decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key)\n\n break\n } catch (error) {\n // last key\n if (i + 1 >= length) {\n throw error\n }\n // try next key\n }\n }\n\n // Parse decrypted .env string\n return DotenvModule.parse(decrypted)\n}\n\nfunction _warn (message) {\n console.log(`[dotenv@${version}][WARN] ${message}`)\n}\n\nfunction _debug (message) {\n console.log(`[dotenv@${version}][DEBUG] ${message}`)\n}\n\nfunction _log (message) {\n console.log(`[dotenv@${version}] ${message}`)\n}\n\nfunction _dotenvKey (options) {\n // prioritize developer directly setting options.DOTENV_KEY\n if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {\n return options.DOTENV_KEY\n }\n\n // secondary infra already contains a DOTENV_KEY environment variable\n if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {\n return process.env.DOTENV_KEY\n }\n\n // fallback to empty string\n return ''\n}\n\nfunction _instructions (result, dotenvKey) {\n // Parse DOTENV_KEY. Format is a URI\n let uri\n try {\n uri = new URL(dotenvKey)\n } catch (error) {\n if (error.code === 'ERR_INVALID_URL') {\n const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n throw error\n }\n\n // Get decrypt key\n const key = uri.password\n if (!key) {\n const err = new Error('INVALID_DOTENV_KEY: Missing key part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get environment\n const environment = uri.searchParams.get('environment')\n if (!environment) {\n const err = new Error('INVALID_DOTENV_KEY: Missing environment part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get ciphertext payload\n const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`\n const ciphertext = result.parsed[environmentKey] // DOTENV_VAULT_PRODUCTION\n if (!ciphertext) {\n const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`)\n err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'\n throw err\n }\n\n return { ciphertext, key }\n}\n\nfunction _vaultPath (options) {\n let possibleVaultPath = null\n\n if (options && options.path && options.path.length > 0) {\n if (Array.isArray(options.path)) {\n for (const filepath of options.path) {\n if (fs.existsSync(filepath)) {\n possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`\n }\n }\n } else {\n possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`\n }\n } else {\n possibleVaultPath = path.resolve(process.cwd(), '.env.vault')\n }\n\n if (fs.existsSync(possibleVaultPath)) {\n return possibleVaultPath\n }\n\n return null\n}\n\nfunction _resolveHome (envPath) {\n return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath\n}\n\nfunction _configVault (options) {\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (debug || !quiet) {\n _log('Loading env from encrypted .env.vault')\n }\n\n const parsed = DotenvModule._parseVault(options)\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsed, options)\n\n return { parsed }\n}\n\nfunction configDotenv (options) {\n const dotenvPath = path.resolve(process.cwd(), '.env')\n let encoding = 'utf8'\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (options && options.encoding) {\n encoding = options.encoding\n } else {\n if (debug) {\n _debug('No encoding is specified. UTF-8 is used by default')\n }\n }\n\n let optionPaths = [dotenvPath] // default, look for .env\n if (options && options.path) {\n if (!Array.isArray(options.path)) {\n optionPaths = [_resolveHome(options.path)]\n } else {\n optionPaths = [] // reset default\n for (const filepath of options.path) {\n optionPaths.push(_resolveHome(filepath))\n }\n }\n }\n\n // Build the parsed data in a temporary object (because we need to return it). Once we have the final\n // parsed data, we will combine it with process.env (or options.processEnv if provided).\n let lastError\n const parsedAll = {}\n for (const path of optionPaths) {\n try {\n // Specifying an encoding returns a string instead of a buffer\n const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }))\n\n DotenvModule.populate(parsedAll, parsed, options)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${path} ${e.message}`)\n }\n lastError = e\n }\n }\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsedAll, options)\n\n if (debug || !quiet) {\n const keysCount = Object.keys(parsedAll).length\n const shortPaths = []\n for (const filePath of optionPaths) {\n try {\n const relative = path.relative(process.cwd(), filePath)\n shortPaths.push(relative)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${filePath} ${e.message}`)\n }\n lastError = e\n }\n }\n\n _log(`injecting env (${keysCount}) from ${shortPaths.join(',')}`)\n }\n\n if (lastError) {\n return { parsed: parsedAll, error: lastError }\n } else {\n return { parsed: parsedAll }\n }\n}\n\n// Populates process.env from .env file\nfunction config (options) {\n // fallback to original dotenv if DOTENV_KEY is not set\n if (_dotenvKey(options).length === 0) {\n return DotenvModule.configDotenv(options)\n }\n\n const vaultPath = _vaultPath(options)\n\n // dotenvKey exists but .env.vault file does not exist\n if (!vaultPath) {\n _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`)\n\n return DotenvModule.configDotenv(options)\n }\n\n return DotenvModule._configVault(options)\n}\n\nfunction decrypt (encrypted, keyStr) {\n const key = Buffer.from(keyStr.slice(-64), 'hex')\n let ciphertext = Buffer.from(encrypted, 'base64')\n\n const nonce = ciphertext.subarray(0, 12)\n const authTag = ciphertext.subarray(-16)\n ciphertext = ciphertext.subarray(12, -16)\n\n try {\n const aesgcm = crypto.createDecipheriv('aes-256-gcm', key, nonce)\n aesgcm.setAuthTag(authTag)\n return `${aesgcm.update(ciphertext)}${aesgcm.final()}`\n } catch (error) {\n const isRange = error instanceof RangeError\n const invalidKeyLength = error.message === 'Invalid key length'\n const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'\n\n if (isRange || invalidKeyLength) {\n const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n } else if (decryptionFailed) {\n const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY')\n err.code = 'DECRYPTION_FAILED'\n throw err\n } else {\n throw error\n }\n }\n}\n\n// Populate process.env with parsed values\nfunction populate (processEnv, parsed, options = {}) {\n const debug = Boolean(options && options.debug)\n const override = Boolean(options && options.override)\n\n if (typeof parsed !== 'object') {\n const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate')\n err.code = 'OBJECT_REQUIRED'\n throw err\n }\n\n // Set process.env\n for (const key of Object.keys(parsed)) {\n if (Object.prototype.hasOwnProperty.call(processEnv, key)) {\n if (override === true) {\n processEnv[key] = parsed[key]\n }\n\n if (debug) {\n if (override === true) {\n _debug(`\"${key}\" is already defined and WAS overwritten`)\n } else {\n _debug(`\"${key}\" is already defined and was NOT overwritten`)\n }\n }\n } else {\n processEnv[key] = parsed[key]\n }\n }\n}\n\nconst DotenvModule = {\n configDotenv,\n _configVault,\n _parseVault,\n config,\n decrypt,\n parse,\n populate\n}\n\nmodule.exports.configDotenv = DotenvModule.configDotenv\nmodule.exports._configVault = DotenvModule._configVault\nmodule.exports._parseVault = DotenvModule._parseVault\nmodule.exports.config = DotenvModule.config\nmodule.exports.decrypt = DotenvModule.decrypt\nmodule.exports.parse = DotenvModule.parse\nmodule.exports.populate = DotenvModule.populate\n\nmodule.exports = DotenvModule\n","import * as dotenv from \"dotenv\";\nfunction getKosEnv() {\n const kosKeys = Object.keys(process.env).filter((key) =>\n key.startsWith(\"KOS_\")\n );\n return kosKeys;\n}\ndotenv.config({\n path: \".env\",\n});\nexport const withKosConfig = (webpack) => (config) => {\n if (config) {\n config.resolve = config.resolve || {};\n config.resolve.fallback = {\n ...config.resolve.fallback,\n path: false,\n };\n }\n config.mode = (process.env.NODE_ENV || config.mode) as any;\n // customize webpack config here\n config?.plugins?.push(\n new webpack.EnvironmentPlugin([\"NODE_ENV\", ...getKosEnv()])\n );\n return config;\n};\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport { v4 as uuidv4 } from \"uuid\";\n\n/**\n * Configuration options for plugin development server middleware\n */\nexport interface PluginDevServerOptions {\n /**\n * Path to .kos.json file, relative to project root.\n * Default: '.kos.json'\n */\n kosJsonPath?: string;\n\n /**\n * Project root directory. Used to resolve kosJsonPath.\n * Default: process.cwd()\n */\n projectRoot?: string;\n\n /**\n * Default plugin context if not specified in .kos.json test section.\n * Default: 'kosdev.ddk'\n */\n defaultContext?: string;\n\n /**\n * Enable verbose logging for debugging.\n * Default: false\n */\n verbose?: boolean;\n}\n\n/**\n * Webpack plugin composable that adds plugin development server middleware.\n *\n * This middleware serves the `/api/kos/ui/plugins/contexts` endpoint, mimicking\n * the backend KOS plugin API response format. It enables local plugin development\n * without requiring backend deployment.\n *\n * @example\n * ```typescript\n * // webpack.config.ts\n * import { withKosConfig, withPluginDevServer } from '@kosdev-code/kos-ui-plugin/webpack';\n * import { composePlugins, withNx } from '@nx/webpack';\n *\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withKosConfig(webpack),\n * withPluginDevServer() // ← Add plugin dev server\n * );\n * ```\n *\n * @example With options\n * ```typescript\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withKosConfig(webpack),\n * withPluginDevServer({\n * kosJsonPath: '.kos.json',\n * defaultContext: 'kosdev.ddk',\n * verbose: true\n * })\n * );\n * ```\n *\n * ## .kos.json Structure\n *\n * The middleware reads two sections from .kos.json:\n *\n * ```json\n * {\n * \"kos\": {\n * \"ui\": {\n * \"plugin\": {\n * \"id\": \"MyPlugin\",\n * \"extensions\": [...],\n * \"contributes\": {...}\n * }\n * }\n * },\n * \"test\": {\n * \"plugin\": {\n * \"context\": \"kosdev.ddk\"\n * }\n * }\n * }\n * ```\n *\n * - `kos.ui.plugin`: Production plugin descriptor (becomes API `descriptor`)\n * - `test.plugin.context`: Development plugin context/group name\n *\n * ## Response Format\n *\n * The middleware returns the same format as the backend `/api/kos/ui/plugins/contexts`:\n *\n * ```json\n * {\n * \"status\": 200,\n * \"version\": {\"major\": 1, \"minor\": 0},\n * \"data\": [\n * {\n * \"name\": \"kosdev.ddk\",\n * \"plugins\": [\n * {\n * \"descriptor\": { ... },\n * \"id\": \"uuid-v4\",\n * \"path\": \"/\"\n * }\n * ]\n * }\n * ]\n * }\n * ```\n *\n * @param options - Configuration options\n */\nexport const withPluginDevServer = (options: PluginDevServerOptions = {}) => {\n const {\n kosJsonPath = \".kos.json\",\n projectRoot,\n defaultContext = \"kosdev.ddk\",\n verbose = false,\n } = options;\n\n return (config: any, context: any) => {\n // Only add middleware if devServer is configured\n if (!config.devServer) {\n if (verbose) {\n console.log(\n \"[withPluginDevServer] No devServer config found, skipping middleware\"\n );\n }\n return config;\n }\n\n // Resolve project root from context if not provided\n // In Nx webpack configs, the context is passed as the second argument\n // We need to check several possible locations for the project path:\n // - config.context (webpack context, usually the project root) - PREFERRED\n // - context.options.root + context.options.projectRoot (Nx-specific fallback)\n let effectiveProjectRoot: string = projectRoot || process.cwd();\n\n if (!projectRoot) {\n // Try config.context first (webpack's context is usually the project directory)\n if (config?.context && typeof config.context === \"string\") {\n effectiveProjectRoot = config.context;\n }\n // If that's not available, try combining workspace root with project root\n else if (context?.options?.root && context?.options?.projectRoot) {\n effectiveProjectRoot = path.join(\n context.options.root,\n context.options.projectRoot\n );\n }\n }\n\n const resolvedKosJsonPath = path.resolve(effectiveProjectRoot, kosJsonPath);\n\n if (verbose) {\n console.log(\"[withPluginDevServer] Configuration:\", {\n kosJsonPath: resolvedKosJsonPath,\n projectRoot: effectiveProjectRoot,\n defaultContext,\n });\n }\n\n // Initialize or extend setupMiddlewares\n const originalSetupMiddlewares = config.devServer.setupMiddlewares;\n\n config.devServer.setupMiddlewares = (\n middlewares: any[],\n devServer: any\n ) => {\n // Call original setupMiddlewares if it exists\n if (originalSetupMiddlewares) {\n middlewares = originalSetupMiddlewares(middlewares, devServer);\n }\n\n // Add plugin metadata endpoint\n devServer.app.get(\n \"/api/kos/ui/plugins/contexts\",\n (_req: any, res: any) => {\n try {\n // Check if .kos.json exists\n if (!fs.existsSync(resolvedKosJsonPath)) {\n const errorMsg = `.kos.json not found at ${resolvedKosJsonPath}`;\n console.error(`[withPluginDevServer] ${errorMsg}`);\n return res.status(404).json({\n status: 404,\n error: errorMsg,\n hint: \"Ensure .kos.json exists in your plugin project root\",\n });\n }\n\n // Read and parse .kos.json\n const kosJsonContent = fs.readFileSync(\n resolvedKosJsonPath,\n \"utf-8\"\n );\n const kosJson = JSON.parse(kosJsonContent);\n\n // Extract production plugin descriptor\n const pluginDescriptor = kosJson.kos?.ui?.plugin;\n if (!pluginDescriptor) {\n const errorMsg = \"kos.ui.plugin section not found in .kos.json\";\n console.error(`[withPluginDevServer] ${errorMsg}`);\n return res.status(400).json({\n status: 400,\n error: errorMsg,\n hint: \"Ensure .kos.json has kos.ui.plugin section defined\",\n });\n }\n\n // Extract test configuration\n const testConfig = kosJson.test?.plugin;\n const pluginContext = testConfig?.context || defaultContext;\n\n // Generate deterministic UUID based on plugin ID\n // Using v4 for now, but could use v5 with plugin ID as namespace in future\n const pluginId = uuidv4();\n\n // Build backend-compatible response\n // Note: The 'path' field is just an identifier in dev mode.\n // The actual dev server URL should be provided via 'overrides' in KosPluginProvider\n const metadata = {\n status: 200,\n version: { major: 1, minor: 0 },\n data: [\n {\n name: pluginContext,\n plugins: [\n {\n descriptor: pluginDescriptor,\n id: pluginId,\n path: \"/\", // Simple identifier - actual URL comes from overrides\n },\n ],\n },\n ],\n };\n\n if (verbose) {\n console.log(\"[withPluginDevServer] Serving plugin metadata:\", {\n pluginId: pluginDescriptor.id,\n context: pluginContext,\n extensionsCount: pluginDescriptor.extensions?.length || 0,\n });\n }\n\n res.json(metadata);\n } catch (error) {\n console.error(\n \"[withPluginDevServer] Error serving plugin metadata:\",\n error\n );\n res.status(500).json({\n status: 500,\n error: \"Failed to serve plugin metadata\",\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n );\n\n if (verbose) {\n console.log(\n \"[withPluginDevServer] Plugin metadata endpoint registered at /api/kos/ui/plugins/contexts\"\n );\n }\n\n return middlewares;\n };\n\n return config;\n };\n};\n","/**\n * Multi-Plugin Development Mode Aggregation Middleware\n *\n * This webpack composable aggregates metadata from multiple plugin dev servers\n * running on different ports, combining them into a single response at the\n * `/api/kos/ui/plugins/contexts` endpoint.\n *\n * This allows a host app to load multiple plugins simultaneously during development.\n */\n\nimport { readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport interface PluginDevAggregatorOptions {\n /**\n * List of plugin dev server URLs to aggregate.\n * Example: ['http://localhost:4201', 'http://localhost:4202']\n */\n pluginServers: string[];\n\n /**\n * Include the host app's own .kos.json plugin definitions.\n * Default: true\n */\n includeHostPlugins?: boolean;\n\n /**\n * Path to the host app's .kos.json file.\n * Default: './.kos.json'\n */\n kosJsonPath?: string;\n\n /**\n * Merge backend plugins with local dev plugins.\n * When true, fetches plugins from backend and overlays local dev plugins on top.\n * Local dev plugins get overrides pointing to dev servers.\n * Backend plugins use their original URLs (no overrides).\n *\n * This is useful for third-party developers who want to:\n * - Run against a production DDK backend\n * - Load DDK base plugins from the backend\n * - Develop their own custom plugins locally\n *\n * Default: false (local-only mode)\n */\n mergeWithBackend?: boolean;\n\n /**\n * Fallback to backend if no local plugin servers are available.\n * Default: true\n */\n fallbackToBackend?: boolean;\n\n /**\n * Backend URL to fallback to when no plugin servers available.\n * Default: 'http://localhost:8081'\n */\n backendUrl?: string;\n\n /**\n * Enable verbose logging for debugging.\n * Default: false\n */\n verbose?: boolean;\n}\n\n/**\n * Webpack plugin composable that aggregates multiple plugin dev servers.\n *\n * @example\n * ```typescript\n * // Host app webpack.config.ts\n * import { withPluginDevAggregator } from '@kosdev-code/kos-ui-plugin/webpack';\n *\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withPluginDevAggregator({\n * pluginServers: [\n * 'http://localhost:4201', // beverage-pour\n * 'http://localhost:4202' // kos-ddk-standard-plugin\n * ]\n * })\n * );\n * ```\n *\n * @example With environment variables\n * ```typescript\n * const pluginServers = [\n * process.env.PLUGIN_A_DEV === 'true' && 'http://localhost:4201',\n * process.env.PLUGIN_B_DEV === 'true' && 'http://localhost:4202',\n * ].filter(Boolean);\n *\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withPluginDevAggregator({\n * pluginServers,\n * fallbackToBackend: pluginServers.length === 0\n * })\n * );\n * ```\n */\nexport const withPluginDevAggregator = (\n options: PluginDevAggregatorOptions\n) => {\n const {\n pluginServers,\n includeHostPlugins = true,\n kosJsonPath = \".kos.json\",\n mergeWithBackend = false,\n fallbackToBackend = true,\n backendUrl = \"http://localhost:8081\",\n verbose = false,\n } = options;\n\n return (config: any, context: any) => {\n // Resolve project root from Nx context (similar to withPluginDevServer)\n let effectiveProjectRoot: string = process.cwd();\n\n if (config?.context && typeof config.context === \"string\") {\n effectiveProjectRoot = config.context;\n } else if (context?.options?.root && context?.options?.projectRoot) {\n effectiveProjectRoot = join(\n context.options.root,\n context.options.projectRoot\n );\n }\n\n const resolvedKosJsonPath = join(effectiveProjectRoot, kosJsonPath);\n\n // Only add middleware if devServer is configured\n if (!config.devServer) {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] No devServer config found, skipping middleware\"\n );\n }\n return config;\n }\n\n if (verbose) {\n console.log(\"[withPluginDevAggregator] Configuration:\", {\n pluginServers,\n fallbackToBackend,\n backendUrl,\n projectRoot: effectiveProjectRoot,\n kosJsonPath: resolvedKosJsonPath,\n });\n }\n\n // Initialize or extend setupMiddlewares\n const originalSetupMiddlewares = config.devServer.setupMiddlewares;\n\n config.devServer.setupMiddlewares = (\n middlewares: any[],\n devServer: any\n ) => {\n // Call original setupMiddlewares if it exists\n if (originalSetupMiddlewares) {\n middlewares = originalSetupMiddlewares(middlewares, devServer);\n }\n\n // Add aggregation endpoint\n devServer.app.get(\n \"/api/kos/ui/plugins/contexts\",\n async (_req: any, res: any) => {\n try {\n // If no plugin servers configured, fallback to backend\n if (pluginServers.length === 0) {\n if (fallbackToBackend) {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] No plugin servers, proxying to backend:\",\n backendUrl\n );\n }\n\n // Proxy to backend\n const backendResponse = await fetch(\n `${backendUrl}/api/kos/ui/plugins/contexts`\n );\n const backendData = await backendResponse.json();\n return res.json(backendData);\n } else {\n return res.status(404).json({\n status: 404,\n error: \"No plugin servers configured\",\n hint: \"Add plugin server URLs to withPluginDevAggregator options or enable fallbackToBackend\",\n });\n }\n }\n\n // Fetch from all plugin dev servers\n const responses = await Promise.all(\n pluginServers.map(async (serverUrl) => {\n try {\n const response = await fetch(\n `${serverUrl}/api/kos/ui/plugins/contexts`\n );\n if (!response.ok) {\n if (verbose) {\n console.warn(\n `[withPluginDevAggregator] Failed to fetch from ${serverUrl}: ${response.status}`\n );\n }\n return null;\n }\n const data = await response.json();\n return { serverUrl, data };\n } catch (error) {\n if (verbose) {\n console.warn(\n `[withPluginDevAggregator] Error fetching from ${serverUrl}:`,\n error\n );\n }\n return null;\n }\n })\n );\n\n // Filter out failed requests\n const validResponses = responses.filter(\n (r) => r && r.data && r.data.status === 200\n );\n\n // If no valid responses and fallback enabled, try backend\n if (validResponses.length === 0 && fallbackToBackend) {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] No plugin servers responded, falling back to backend\"\n );\n }\n\n try {\n const backendResponse = await fetch(\n `${backendUrl}/api/kos/ui/plugins/contexts`\n );\n const backendData = await backendResponse.json();\n return res.json(backendData);\n } catch (error) {\n return res.status(503).json({\n status: 503,\n error: \"No plugin servers available and backend unreachable\",\n details:\n error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Merge all plugin data from valid responses\n // Group by context name and merge plugins\n // Also build overrides map for dev server URLs\n const mergedData: Record<string, any[]> = {};\n const overridesMap: Record<string, string> = {};\n\n // Step 1: Fetch and include backend plugins if mergeWithBackend is enabled\n // Backend plugins are added WITHOUT overrides (use their production URLs)\n if (mergeWithBackend) {\n try {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] Fetching backend plugins from:\",\n backendUrl\n );\n }\n\n const backendResponse = await fetch(\n `${backendUrl}/api/kos/ui/plugins/contexts`\n );\n if (backendResponse.ok) {\n const backendData = await backendResponse.json();\n\n if (backendData.status === 200 && backendData.data) {\n backendData.data.forEach((contextGroup: any) => {\n const contextName = contextGroup.name;\n if (!mergedData[contextName]) {\n mergedData[contextName] = [];\n }\n\n // Add backend plugins WITHOUT overrides\n // They will use their production URLs from the backend\n contextGroup.plugins.forEach((plugin: any) => {\n mergedData[contextName].push(plugin);\n\n if (verbose) {\n console.log(\n `[withPluginDevAggregator] Added backend plugin: ${plugin.descriptor?.id} (no override)`\n );\n }\n });\n });\n\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] Successfully merged backend plugins\"\n );\n }\n }\n } else {\n if (verbose) {\n console.warn(\n `[withPluginDevAggregator] Backend fetch failed: ${backendResponse.status}`\n );\n }\n }\n } catch (error) {\n if (verbose) {\n console.warn(\n \"[withPluginDevAggregator] Error fetching backend plugins:\",\n error\n );\n }\n }\n }\n\n // Step 2: Include host app's own plugin definitions if enabled\n if (includeHostPlugins) {\n try {\n const kosJsonContent = readFileSync(\n resolvedKosJsonPath,\n \"utf-8\"\n );\n const kosJson = JSON.parse(kosJsonContent);\n\n // Check for plugin definitions in kos.ui.plugin or kosdev.ddk.ncui.plugin\n const pluginDescriptor = kosJson.kos?.ui?.plugin;\n const ncuiPluginDescriptor = kosJson.kosdev?.ddk?.ncui?.plugin;\n\n // Determine context based on plugin type\n const contexts: Array<{\n name: string;\n plugin: { descriptor: any; id: string; path: string };\n }> = [];\n\n if (pluginDescriptor) {\n contexts.push({\n name: kosJson.test?.plugin?.context || \"kos.ui\",\n plugin: {\n descriptor: pluginDescriptor,\n id: uuidv4(),\n path: \"/\", // Host app plugins are served locally\n },\n });\n }\n\n if (ncuiPluginDescriptor) {\n contexts.push({\n name: \"kosdev.ddk\",\n plugin: {\n descriptor: ncuiPluginDescriptor,\n id: uuidv4(),\n path: \"/\", // Host app plugins are served locally\n },\n });\n }\n\n // Add host plugins to merged data\n contexts.forEach(({ name, plugin }) => {\n if (!mergedData[name]) {\n mergedData[name] = [];\n }\n mergedData[name].push(plugin);\n\n if (verbose) {\n console.log(\n `[withPluginDevAggregator] Added host plugin: ${plugin.descriptor.id} to context ${name}`\n );\n }\n });\n } catch (error) {\n if (verbose) {\n console.warn(\n \"[withPluginDevAggregator] Failed to read host .kos.json:\",\n error\n );\n }\n }\n }\n\n // Step 3: Add plugins from remote dev servers with overrides\n // Local dev plugins get overrides pointing to their dev server URLs\n validResponses.forEach((responseWrapper) => {\n if (!responseWrapper) return;\n const { serverUrl, data: response } = responseWrapper;\n\n response.data?.forEach((contextGroup: any) => {\n const contextName = contextGroup.name;\n if (!mergedData[contextName]) {\n mergedData[contextName] = [];\n }\n\n // Add plugins and build overrides for each plugin\n contextGroup.plugins.forEach((plugin: any) => {\n mergedData[contextName].push(plugin);\n // Map plugin ID to its dev server URL\n // This allows KosPluginProvider to use overrides to point to the right server\n overridesMap[plugin.id] = `${serverUrl}/`;\n\n if (verbose) {\n console.log(\n `[withPluginDevAggregator] Added local dev plugin: ${plugin.descriptor?.id} with override to ${serverUrl}/`\n );\n }\n });\n });\n });\n\n // Convert back to array format\n const aggregatedData = Object.entries(mergedData).map(\n ([name, plugins]) => ({\n name,\n plugins,\n })\n );\n\n const aggregatedResponse = {\n status: 200,\n version: { major: 1, minor: 0 },\n data: aggregatedData,\n // Include overrides map for dev mode\n // This allows the host app to pass these to KosPluginProvider\n overrides: overridesMap,\n };\n\n if (verbose) {\n console.log(\"[withPluginDevAggregator] Aggregated plugins:\", {\n contexts: aggregatedData.length,\n totalPlugins: aggregatedData.reduce(\n (sum, ctx) => sum + ctx.plugins.length,\n 0\n ),\n pluginIds: aggregatedData.flatMap((ctx) =>\n ctx.plugins.map((p: any) => p.descriptor?.id)\n ),\n overrides: overridesMap,\n });\n }\n\n res.json(aggregatedResponse);\n } catch (error) {\n console.error(\n \"[withPluginDevAggregator] Error aggregating plugins:\",\n error\n );\n res.status(500).json({\n status: 500,\n error: \"Failed to aggregate plugin metadata\",\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n );\n\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] Plugin aggregation endpoint registered at /api/kos/ui/plugins/contexts\"\n );\n }\n\n return middlewares;\n };\n\n return config;\n };\n};\n"],"names":["fs","require$$0","path","require$$1","os","require$$2","crypto","require$$3","packageJson","require$$4","version","LINE","parse","src","obj","lines","match","key","value","maybeQuote","_parseVault","options","vaultPath","_vaultPath","result","DotenvModule","err","keys","_dotenvKey","length","decrypted","i","attrs","_instructions","error","_warn","message","_debug","_log","dotenvKey","uri","environment","environmentKey","ciphertext","possibleVaultPath","filepath","_resolveHome","envPath","_configVault","debug","quiet","parsed","processEnv","configDotenv","dotenvPath","encoding","optionPaths","lastError","parsedAll","e","keysCount","shortPaths","filePath","relative","config","decrypt","encrypted","keyStr","nonce","authTag","aesgcm","isRange","invalidKeyLength","decryptionFailed","populate","override","mainModule","config_1","getKosEnv","dotenv.config","withKosConfig","webpack","_a","withPluginDevServer","kosJsonPath","projectRoot","defaultContext","verbose","context","effectiveProjectRoot","_b","resolvedKosJsonPath","originalSetupMiddlewares","middlewares","devServer","_req","res","errorMsg","kosJsonContent","kosJson","pluginDescriptor","testConfig","_c","pluginContext","pluginId","uuidv4","metadata","_d","withPluginDevAggregator","pluginServers","includeHostPlugins","mergeWithBackend","fallbackToBackend","backendUrl","join","backendData","validResponses","serverUrl","response","data","r","mergedData","overridesMap","backendResponse","contextGroup","contextName","plugin","readFileSync","ncuiPluginDescriptor","_e","contexts","_g","_f","name","responseWrapper","aggregatedData","plugins","aggregatedResponse","sum","ctx","p"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"webpack.cjs","sources":["../../../../node_modules/dotenv/lib/main.js","../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-kos-config.ts","../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-plugin-dev-server.ts","../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-plugin-dev-aggregator.ts"],"sourcesContent":["const fs = require('fs')\nconst path = require('path')\nconst os = require('os')\nconst crypto = require('crypto')\nconst packageJson = require('../package.json')\n\nconst version = packageJson.version\n\nconst LINE = /(?:^|^)\\s*(?:export\\s+)?([\\w.-]+)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?\\s*(?:#.*)?(?:$|$)/mg\n\n// Parse src into an Object\nfunction parse (src) {\n const obj = {}\n\n // Convert buffer to string\n let lines = src.toString()\n\n // Convert line breaks to same format\n lines = lines.replace(/\\r\\n?/mg, '\\n')\n\n let match\n while ((match = LINE.exec(lines)) != null) {\n const key = match[1]\n\n // Default undefined or null to empty string\n let value = (match[2] || '')\n\n // Remove whitespace\n value = value.trim()\n\n // Check if double quoted\n const maybeQuote = value[0]\n\n // Remove surrounding quotes\n value = value.replace(/^(['\"`])([\\s\\S]*)\\1$/mg, '$2')\n\n // Expand newlines if double quoted\n if (maybeQuote === '\"') {\n value = value.replace(/\\\\n/g, '\\n')\n value = value.replace(/\\\\r/g, '\\r')\n }\n\n // Add to object\n obj[key] = value\n }\n\n return obj\n}\n\nfunction _parseVault (options) {\n options = options || {}\n\n const vaultPath = _vaultPath(options)\n options.path = vaultPath // parse .env.vault\n const result = DotenvModule.configDotenv(options)\n if (!result.parsed) {\n const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`)\n err.code = 'MISSING_DATA'\n throw err\n }\n\n // handle scenario for comma separated keys - for use with key rotation\n // example: DOTENV_KEY=\"dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod\"\n const keys = _dotenvKey(options).split(',')\n const length = keys.length\n\n let decrypted\n for (let i = 0; i < length; i++) {\n try {\n // Get full key\n const key = keys[i].trim()\n\n // Get instructions for decrypt\n const attrs = _instructions(result, key)\n\n // Decrypt\n decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key)\n\n break\n } catch (error) {\n // last key\n if (i + 1 >= length) {\n throw error\n }\n // try next key\n }\n }\n\n // Parse decrypted .env string\n return DotenvModule.parse(decrypted)\n}\n\nfunction _warn (message) {\n console.log(`[dotenv@${version}][WARN] ${message}`)\n}\n\nfunction _debug (message) {\n console.log(`[dotenv@${version}][DEBUG] ${message}`)\n}\n\nfunction _log (message) {\n console.log(`[dotenv@${version}] ${message}`)\n}\n\nfunction _dotenvKey (options) {\n // prioritize developer directly setting options.DOTENV_KEY\n if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {\n return options.DOTENV_KEY\n }\n\n // secondary infra already contains a DOTENV_KEY environment variable\n if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {\n return process.env.DOTENV_KEY\n }\n\n // fallback to empty string\n return ''\n}\n\nfunction _instructions (result, dotenvKey) {\n // Parse DOTENV_KEY. Format is a URI\n let uri\n try {\n uri = new URL(dotenvKey)\n } catch (error) {\n if (error.code === 'ERR_INVALID_URL') {\n const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n throw error\n }\n\n // Get decrypt key\n const key = uri.password\n if (!key) {\n const err = new Error('INVALID_DOTENV_KEY: Missing key part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get environment\n const environment = uri.searchParams.get('environment')\n if (!environment) {\n const err = new Error('INVALID_DOTENV_KEY: Missing environment part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get ciphertext payload\n const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`\n const ciphertext = result.parsed[environmentKey] // DOTENV_VAULT_PRODUCTION\n if (!ciphertext) {\n const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`)\n err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'\n throw err\n }\n\n return { ciphertext, key }\n}\n\nfunction _vaultPath (options) {\n let possibleVaultPath = null\n\n if (options && options.path && options.path.length > 0) {\n if (Array.isArray(options.path)) {\n for (const filepath of options.path) {\n if (fs.existsSync(filepath)) {\n possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`\n }\n }\n } else {\n possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`\n }\n } else {\n possibleVaultPath = path.resolve(process.cwd(), '.env.vault')\n }\n\n if (fs.existsSync(possibleVaultPath)) {\n return possibleVaultPath\n }\n\n return null\n}\n\nfunction _resolveHome (envPath) {\n return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath\n}\n\nfunction _configVault (options) {\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (debug || !quiet) {\n _log('Loading env from encrypted .env.vault')\n }\n\n const parsed = DotenvModule._parseVault(options)\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsed, options)\n\n return { parsed }\n}\n\nfunction configDotenv (options) {\n const dotenvPath = path.resolve(process.cwd(), '.env')\n let encoding = 'utf8'\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (options && options.encoding) {\n encoding = options.encoding\n } else {\n if (debug) {\n _debug('No encoding is specified. UTF-8 is used by default')\n }\n }\n\n let optionPaths = [dotenvPath] // default, look for .env\n if (options && options.path) {\n if (!Array.isArray(options.path)) {\n optionPaths = [_resolveHome(options.path)]\n } else {\n optionPaths = [] // reset default\n for (const filepath of options.path) {\n optionPaths.push(_resolveHome(filepath))\n }\n }\n }\n\n // Build the parsed data in a temporary object (because we need to return it). Once we have the final\n // parsed data, we will combine it with process.env (or options.processEnv if provided).\n let lastError\n const parsedAll = {}\n for (const path of optionPaths) {\n try {\n // Specifying an encoding returns a string instead of a buffer\n const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }))\n\n DotenvModule.populate(parsedAll, parsed, options)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${path} ${e.message}`)\n }\n lastError = e\n }\n }\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsedAll, options)\n\n if (debug || !quiet) {\n const keysCount = Object.keys(parsedAll).length\n const shortPaths = []\n for (const filePath of optionPaths) {\n try {\n const relative = path.relative(process.cwd(), filePath)\n shortPaths.push(relative)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${filePath} ${e.message}`)\n }\n lastError = e\n }\n }\n\n _log(`injecting env (${keysCount}) from ${shortPaths.join(',')}`)\n }\n\n if (lastError) {\n return { parsed: parsedAll, error: lastError }\n } else {\n return { parsed: parsedAll }\n }\n}\n\n// Populates process.env from .env file\nfunction config (options) {\n // fallback to original dotenv if DOTENV_KEY is not set\n if (_dotenvKey(options).length === 0) {\n return DotenvModule.configDotenv(options)\n }\n\n const vaultPath = _vaultPath(options)\n\n // dotenvKey exists but .env.vault file does not exist\n if (!vaultPath) {\n _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`)\n\n return DotenvModule.configDotenv(options)\n }\n\n return DotenvModule._configVault(options)\n}\n\nfunction decrypt (encrypted, keyStr) {\n const key = Buffer.from(keyStr.slice(-64), 'hex')\n let ciphertext = Buffer.from(encrypted, 'base64')\n\n const nonce = ciphertext.subarray(0, 12)\n const authTag = ciphertext.subarray(-16)\n ciphertext = ciphertext.subarray(12, -16)\n\n try {\n const aesgcm = crypto.createDecipheriv('aes-256-gcm', key, nonce)\n aesgcm.setAuthTag(authTag)\n return `${aesgcm.update(ciphertext)}${aesgcm.final()}`\n } catch (error) {\n const isRange = error instanceof RangeError\n const invalidKeyLength = error.message === 'Invalid key length'\n const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'\n\n if (isRange || invalidKeyLength) {\n const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n } else if (decryptionFailed) {\n const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY')\n err.code = 'DECRYPTION_FAILED'\n throw err\n } else {\n throw error\n }\n }\n}\n\n// Populate process.env with parsed values\nfunction populate (processEnv, parsed, options = {}) {\n const debug = Boolean(options && options.debug)\n const override = Boolean(options && options.override)\n\n if (typeof parsed !== 'object') {\n const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate')\n err.code = 'OBJECT_REQUIRED'\n throw err\n }\n\n // Set process.env\n for (const key of Object.keys(parsed)) {\n if (Object.prototype.hasOwnProperty.call(processEnv, key)) {\n if (override === true) {\n processEnv[key] = parsed[key]\n }\n\n if (debug) {\n if (override === true) {\n _debug(`\"${key}\" is already defined and WAS overwritten`)\n } else {\n _debug(`\"${key}\" is already defined and was NOT overwritten`)\n }\n }\n } else {\n processEnv[key] = parsed[key]\n }\n }\n}\n\nconst DotenvModule = {\n configDotenv,\n _configVault,\n _parseVault,\n config,\n decrypt,\n parse,\n populate\n}\n\nmodule.exports.configDotenv = DotenvModule.configDotenv\nmodule.exports._configVault = DotenvModule._configVault\nmodule.exports._parseVault = DotenvModule._parseVault\nmodule.exports.config = DotenvModule.config\nmodule.exports.decrypt = DotenvModule.decrypt\nmodule.exports.parse = DotenvModule.parse\nmodule.exports.populate = DotenvModule.populate\n\nmodule.exports = DotenvModule\n","import * as dotenv from \"dotenv\";\nfunction getKosEnv() {\n const kosKeys = Object.keys(process.env).filter((key) =>\n key.startsWith(\"KOS_\")\n );\n return kosKeys;\n}\ndotenv.config({\n path: \".env\",\n});\nexport const withKosConfig = (webpack) => (config) => {\n if (config) {\n config.resolve = config.resolve || {};\n config.resolve.fallback = {\n ...config.resolve.fallback,\n path: false,\n };\n }\n config.mode = (process.env.NODE_ENV || config.mode) as any;\n // customize webpack config here\n config?.plugins?.push(\n new webpack.EnvironmentPlugin([\"NODE_ENV\", ...getKosEnv()])\n );\n return config;\n};\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport { v4 as uuidv4 } from \"uuid\";\n\n/**\n * Configuration options for plugin development server middleware\n */\nexport interface PluginDevServerOptions {\n /**\n * Path to .kos.json file, relative to project root.\n * Default: '.kos.json'\n */\n kosJsonPath?: string;\n\n /**\n * Project root directory. Used to resolve kosJsonPath.\n * Default: process.cwd()\n */\n projectRoot?: string;\n\n /**\n * Default plugin context if not specified in .kos.json test section.\n * Default: 'kosdev.ddk'\n */\n defaultContext?: string;\n\n /**\n * Enable verbose logging for debugging.\n * Default: false\n */\n verbose?: boolean;\n}\n\n/**\n * Webpack plugin composable that adds plugin development server middleware.\n *\n * This middleware serves the `/api/kos/ui/plugins/contexts` endpoint, mimicking\n * the backend KOS plugin API response format. It enables local plugin development\n * without requiring backend deployment.\n *\n * @example\n * ```typescript\n * // webpack.config.ts\n * import { withKosConfig, withPluginDevServer } from '@kosdev-code/kos-ui-plugin/webpack';\n * import { composePlugins, withNx } from '@nx/webpack';\n *\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withKosConfig(webpack),\n * withPluginDevServer() // ← Add plugin dev server\n * );\n * ```\n *\n * @example With options\n * ```typescript\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withKosConfig(webpack),\n * withPluginDevServer({\n * kosJsonPath: '.kos.json',\n * defaultContext: 'kosdev.ddk',\n * verbose: true\n * })\n * );\n * ```\n *\n * ## .kos.json Structure\n *\n * The middleware reads two sections from .kos.json:\n *\n * ```json\n * {\n * \"kos\": {\n * \"ui\": {\n * \"plugin\": {\n * \"id\": \"MyPlugin\",\n * \"extensions\": [...],\n * \"contributes\": {...}\n * }\n * }\n * },\n * \"test\": {\n * \"plugin\": {\n * \"context\": \"kosdev.ddk\"\n * }\n * }\n * }\n * ```\n *\n * - `kos.ui.plugin`: Production plugin descriptor (becomes API `descriptor`)\n * - `test.plugin.context`: Development plugin context/group name\n *\n * ## Response Format\n *\n * The middleware returns the same format as the backend `/api/kos/ui/plugins/contexts`:\n *\n * ```json\n * {\n * \"status\": 200,\n * \"version\": {\"major\": 1, \"minor\": 0},\n * \"data\": [\n * {\n * \"name\": \"kosdev.ddk\",\n * \"plugins\": [\n * {\n * \"descriptor\": { ... },\n * \"id\": \"uuid-v4\",\n * \"path\": \"/\"\n * }\n * ]\n * }\n * ]\n * }\n * ```\n *\n * @param options - Configuration options\n */\nexport const withPluginDevServer = (options: PluginDevServerOptions = {}) => {\n const {\n kosJsonPath = \".kos.json\",\n projectRoot,\n defaultContext = \"kosdev.ddk\",\n verbose = false,\n } = options;\n\n return (config: any, context: any) => {\n // Only add middleware if devServer is configured\n if (!config.devServer) {\n if (verbose) {\n console.log(\n \"[withPluginDevServer] No devServer config found, skipping middleware\"\n );\n }\n return config;\n }\n\n // Enable CORS for third-party development mode\n // This allows deployed devices/hosts to fetch plugin metadata from dev servers\n config.devServer.headers = {\n ...config.devServer.headers,\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET, POST, PUT, DELETE, PATCH, OPTIONS\",\n \"Access-Control-Allow-Headers\":\n \"X-Requested-With, content-type, Authorization\",\n };\n\n // Resolve project root from context if not provided\n // In Nx webpack configs, the context is passed as the second argument\n // We need to check several possible locations for the project path:\n // - config.context (webpack context, usually the project root) - PREFERRED\n // - context.options.root + context.options.projectRoot (Nx-specific fallback)\n let effectiveProjectRoot: string = projectRoot || process.cwd();\n\n if (!projectRoot) {\n // Try config.context first (webpack's context is usually the project directory)\n if (config?.context && typeof config.context === \"string\") {\n effectiveProjectRoot = config.context;\n }\n // If that's not available, try combining workspace root with project root\n else if (context?.options?.root && context?.options?.projectRoot) {\n effectiveProjectRoot = path.join(\n context.options.root,\n context.options.projectRoot\n );\n }\n }\n\n const resolvedKosJsonPath = path.resolve(effectiveProjectRoot, kosJsonPath);\n\n if (verbose) {\n console.log(\"[withPluginDevServer] Configuration:\", {\n kosJsonPath: resolvedKosJsonPath,\n projectRoot: effectiveProjectRoot,\n defaultContext,\n });\n }\n\n // Initialize or extend setupMiddlewares\n const originalSetupMiddlewares = config.devServer.setupMiddlewares;\n\n config.devServer.setupMiddlewares = (\n middlewares: any[],\n devServer: any\n ) => {\n // Call original setupMiddlewares if it exists\n if (originalSetupMiddlewares) {\n middlewares = originalSetupMiddlewares(middlewares, devServer);\n }\n\n // Add plugin metadata endpoint\n devServer.app.get(\n \"/api/kos/ui/plugins/contexts\",\n (_req: any, res: any) => {\n try {\n // Check if .kos.json exists\n if (!fs.existsSync(resolvedKosJsonPath)) {\n const errorMsg = `.kos.json not found at ${resolvedKosJsonPath}`;\n console.error(`[withPluginDevServer] ${errorMsg}`);\n return res.status(404).json({\n status: 404,\n error: errorMsg,\n hint: \"Ensure .kos.json exists in your plugin project root\",\n });\n }\n\n // Read and parse .kos.json\n const kosJsonContent = fs.readFileSync(\n resolvedKosJsonPath,\n \"utf-8\"\n );\n const kosJson = JSON.parse(kosJsonContent);\n\n // Extract production plugin descriptor\n const pluginDescriptor = kosJson.kos?.ui?.plugin;\n if (!pluginDescriptor) {\n const errorMsg = \"kos.ui.plugin section not found in .kos.json\";\n console.error(`[withPluginDevServer] ${errorMsg}`);\n return res.status(400).json({\n status: 400,\n error: errorMsg,\n hint: \"Ensure .kos.json has kos.ui.plugin section defined\",\n });\n }\n\n // Extract test configuration\n const testConfig = kosJson.test?.plugin;\n const pluginContext = testConfig?.context || defaultContext;\n\n // Generate deterministic UUID based on plugin ID\n // Using v4 for now, but could use v5 with plugin ID as namespace in future\n const pluginId = uuidv4();\n\n // Build backend-compatible response\n // Note: The 'path' field is just an identifier in dev mode.\n // The actual dev server URL should be provided via 'overrides' in KosPluginProvider\n const metadata = {\n status: 200,\n version: { major: 1, minor: 0 },\n data: [\n {\n name: pluginContext,\n plugins: [\n {\n descriptor: pluginDescriptor,\n id: pluginId,\n path: \"/\", // Simple identifier - actual URL comes from overrides\n },\n ],\n },\n ],\n };\n\n if (verbose) {\n console.log(\"[withPluginDevServer] Serving plugin metadata:\", {\n pluginId: pluginDescriptor.id,\n context: pluginContext,\n extensionsCount: pluginDescriptor.extensions?.length || 0,\n });\n }\n\n res.json(metadata);\n } catch (error) {\n console.error(\n \"[withPluginDevServer] Error serving plugin metadata:\",\n error\n );\n res.status(500).json({\n status: 500,\n error: \"Failed to serve plugin metadata\",\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n );\n\n if (verbose) {\n console.log(\n \"[withPluginDevServer] Plugin metadata endpoint registered at /api/kos/ui/plugins/contexts\"\n );\n }\n\n return middlewares;\n };\n\n return config;\n };\n};\n","/**\n * Multi-Plugin Development Mode Aggregation Middleware\n *\n * This webpack composable aggregates metadata from multiple plugin dev servers\n * running on different ports, combining them into a single response at the\n * `/api/kos/ui/plugins/contexts` endpoint.\n *\n * This allows a host app to load multiple plugins simultaneously during development.\n */\n\nimport { readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport interface PluginDevAggregatorOptions {\n /**\n * List of plugin dev server URLs to aggregate.\n * Example: ['http://localhost:4201', 'http://localhost:4202']\n */\n pluginServers: string[];\n\n /**\n * Include the host app's own .kos.json plugin definitions.\n * Default: true\n */\n includeHostPlugins?: boolean;\n\n /**\n * Path to the host app's .kos.json file.\n * Default: './.kos.json'\n */\n kosJsonPath?: string;\n\n /**\n * Merge backend plugins with local dev plugins.\n * When true, fetches plugins from backend and overlays local dev plugins on top.\n * Local dev plugins get overrides pointing to dev servers.\n * Backend plugins use their original URLs (no overrides).\n *\n * This is useful for third-party developers who want to:\n * - Run against a production DDK backend\n * - Load DDK base plugins from the backend\n * - Develop their own custom plugins locally\n *\n * Default: false (local-only mode)\n */\n mergeWithBackend?: boolean;\n\n /**\n * Fallback to backend if no local plugin servers are available.\n * Default: true\n */\n fallbackToBackend?: boolean;\n\n /**\n * Backend URL to fallback to when no plugin servers available.\n * Default: 'http://localhost:8081'\n */\n backendUrl?: string;\n\n /**\n * Enable verbose logging for debugging.\n * Default: false\n */\n verbose?: boolean;\n}\n\n/**\n * Webpack plugin composable that aggregates multiple plugin dev servers.\n *\n * @example\n * ```typescript\n * // Host app webpack.config.ts\n * import { withPluginDevAggregator } from '@kosdev-code/kos-ui-plugin/webpack';\n *\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withPluginDevAggregator({\n * pluginServers: [\n * 'http://localhost:4201', // beverage-pour\n * 'http://localhost:4202' // kos-ddk-standard-plugin\n * ]\n * })\n * );\n * ```\n *\n * @example With environment variables\n * ```typescript\n * const pluginServers = [\n * process.env.PLUGIN_A_DEV === 'true' && 'http://localhost:4201',\n * process.env.PLUGIN_B_DEV === 'true' && 'http://localhost:4202',\n * ].filter(Boolean);\n *\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withPluginDevAggregator({\n * pluginServers,\n * fallbackToBackend: pluginServers.length === 0\n * })\n * );\n * ```\n */\nexport const withPluginDevAggregator = (\n options: PluginDevAggregatorOptions\n) => {\n const {\n pluginServers,\n includeHostPlugins = true,\n kosJsonPath = \".kos.json\",\n mergeWithBackend = false,\n fallbackToBackend = true,\n backendUrl = \"http://localhost:8081\",\n verbose = false,\n } = options;\n\n return (config: any, context: any) => {\n // Resolve project root from Nx context (similar to withPluginDevServer)\n let effectiveProjectRoot: string = process.cwd();\n\n if (config?.context && typeof config.context === \"string\") {\n effectiveProjectRoot = config.context;\n } else if (context?.options?.root && context?.options?.projectRoot) {\n effectiveProjectRoot = join(\n context.options.root,\n context.options.projectRoot\n );\n }\n\n const resolvedKosJsonPath = join(effectiveProjectRoot, kosJsonPath);\n\n // Only add middleware if devServer is configured\n if (!config.devServer) {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] No devServer config found, skipping middleware\"\n );\n }\n return config;\n }\n\n if (verbose) {\n console.log(\"[withPluginDevAggregator] Configuration:\", {\n pluginServers,\n fallbackToBackend,\n backendUrl,\n projectRoot: effectiveProjectRoot,\n kosJsonPath: resolvedKosJsonPath,\n });\n }\n\n // Initialize or extend setupMiddlewares\n const originalSetupMiddlewares = config.devServer.setupMiddlewares;\n\n config.devServer.setupMiddlewares = (\n middlewares: any[],\n devServer: any\n ) => {\n // Call original setupMiddlewares if it exists\n if (originalSetupMiddlewares) {\n middlewares = originalSetupMiddlewares(middlewares, devServer);\n }\n\n // Add aggregation endpoint\n devServer.app.get(\n \"/api/kos/ui/plugins/contexts\",\n async (_req: any, res: any) => {\n try {\n // If no plugin servers configured, fallback to backend\n if (pluginServers.length === 0) {\n if (fallbackToBackend) {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] No plugin servers, proxying to backend:\",\n backendUrl\n );\n }\n\n // Proxy to backend\n const backendResponse = await fetch(\n `${backendUrl}/api/kos/ui/plugins/contexts`\n );\n const backendData = await backendResponse.json();\n return res.json(backendData);\n } else {\n return res.status(404).json({\n status: 404,\n error: \"No plugin servers configured\",\n hint: \"Add plugin server URLs to withPluginDevAggregator options or enable fallbackToBackend\",\n });\n }\n }\n\n // Fetch from all plugin dev servers\n const responses = await Promise.all(\n pluginServers.map(async (serverUrl) => {\n try {\n const response = await fetch(\n `${serverUrl}/api/kos/ui/plugins/contexts`\n );\n if (!response.ok) {\n if (verbose) {\n console.warn(\n `[withPluginDevAggregator] Failed to fetch from ${serverUrl}: ${response.status}`\n );\n }\n return null;\n }\n const data = await response.json();\n return { serverUrl, data };\n } catch (error) {\n if (verbose) {\n console.warn(\n `[withPluginDevAggregator] Error fetching from ${serverUrl}:`,\n error\n );\n }\n return null;\n }\n })\n );\n\n // Filter out failed requests\n const validResponses = responses.filter(\n (r) => r && r.data && r.data.status === 200\n );\n\n // If no valid responses and fallback enabled, try backend\n if (validResponses.length === 0 && fallbackToBackend) {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] No plugin servers responded, falling back to backend\"\n );\n }\n\n try {\n const backendResponse = await fetch(\n `${backendUrl}/api/kos/ui/plugins/contexts`\n );\n const backendData = await backendResponse.json();\n return res.json(backendData);\n } catch (error) {\n return res.status(503).json({\n status: 503,\n error: \"No plugin servers available and backend unreachable\",\n details:\n error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Merge all plugin data from valid responses\n // Group by context name and merge plugins\n // Also build overrides map for dev server URLs\n const mergedData: Record<string, any[]> = {};\n const overridesMap: Record<string, string> = {};\n\n // Step 1: Fetch and include backend plugins if mergeWithBackend is enabled\n // Backend plugins are added WITHOUT overrides (use their production URLs)\n if (mergeWithBackend) {\n try {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] Fetching backend plugins from:\",\n backendUrl\n );\n }\n\n const backendResponse = await fetch(\n `${backendUrl}/api/kos/ui/plugins/contexts`\n );\n if (backendResponse.ok) {\n const backendData = await backendResponse.json();\n\n if (backendData.status === 200 && backendData.data) {\n backendData.data.forEach((contextGroup: any) => {\n const contextName = contextGroup.name;\n if (!mergedData[contextName]) {\n mergedData[contextName] = [];\n }\n\n // Add backend plugins WITHOUT overrides\n // They will use their production URLs from the backend\n contextGroup.plugins.forEach((plugin: any) => {\n mergedData[contextName].push(plugin);\n\n if (verbose) {\n console.log(\n `[withPluginDevAggregator] Added backend plugin: ${plugin.descriptor?.id} (no override)`\n );\n }\n });\n });\n\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] Successfully merged backend plugins\"\n );\n }\n }\n } else {\n if (verbose) {\n console.warn(\n `[withPluginDevAggregator] Backend fetch failed: ${backendResponse.status}`\n );\n }\n }\n } catch (error) {\n if (verbose) {\n console.warn(\n \"[withPluginDevAggregator] Error fetching backend plugins:\",\n error\n );\n }\n }\n }\n\n // Step 2: Include host app's own plugin definitions if enabled\n if (includeHostPlugins) {\n try {\n const kosJsonContent = readFileSync(\n resolvedKosJsonPath,\n \"utf-8\"\n );\n const kosJson = JSON.parse(kosJsonContent);\n\n // Check for plugin definitions in kos.ui.plugin or kosdev.ddk.ncui.plugin\n const pluginDescriptor = kosJson.kos?.ui?.plugin;\n const ncuiPluginDescriptor = kosJson.kosdev?.ddk?.ncui?.plugin;\n\n // Determine context based on plugin type\n const contexts: Array<{\n name: string;\n plugin: { descriptor: any; id: string; path: string };\n }> = [];\n\n if (pluginDescriptor) {\n contexts.push({\n name: kosJson.test?.plugin?.context || \"kos.ui\",\n plugin: {\n descriptor: pluginDescriptor,\n id: uuidv4(),\n path: \"/\", // Host app plugins are served locally\n },\n });\n }\n\n if (ncuiPluginDescriptor) {\n contexts.push({\n name: \"kosdev.ddk\",\n plugin: {\n descriptor: ncuiPluginDescriptor,\n id: uuidv4(),\n path: \"/\", // Host app plugins are served locally\n },\n });\n }\n\n // Add host plugins to merged data\n contexts.forEach(({ name, plugin }) => {\n if (!mergedData[name]) {\n mergedData[name] = [];\n }\n mergedData[name].push(plugin);\n\n if (verbose) {\n console.log(\n `[withPluginDevAggregator] Added host plugin: ${plugin.descriptor.id} to context ${name}`\n );\n }\n });\n } catch (error) {\n if (verbose) {\n console.warn(\n \"[withPluginDevAggregator] Failed to read host .kos.json:\",\n error\n );\n }\n }\n }\n\n // Step 3: Add plugins from remote dev servers with overrides\n // Local dev plugins get overrides pointing to their dev server URLs\n validResponses.forEach((responseWrapper) => {\n if (!responseWrapper) return;\n const { serverUrl, data: response } = responseWrapper;\n\n response.data?.forEach((contextGroup: any) => {\n const contextName = contextGroup.name;\n if (!mergedData[contextName]) {\n mergedData[contextName] = [];\n }\n\n // Add plugins and build overrides for each plugin\n contextGroup.plugins.forEach((plugin: any) => {\n mergedData[contextName].push(plugin);\n // Map plugin ID to its dev server URL\n // This allows KosPluginProvider to use overrides to point to the right server\n overridesMap[plugin.id] = `${serverUrl}/`;\n\n if (verbose) {\n console.log(\n `[withPluginDevAggregator] Added local dev plugin: ${plugin.descriptor?.id} with override to ${serverUrl}/`\n );\n }\n });\n });\n });\n\n // Convert back to array format\n const aggregatedData = Object.entries(mergedData).map(\n ([name, plugins]) => ({\n name,\n plugins,\n })\n );\n\n const aggregatedResponse = {\n status: 200,\n version: { major: 1, minor: 0 },\n data: aggregatedData,\n // Include overrides map for dev mode\n // This allows the host app to pass these to KosPluginProvider\n overrides: overridesMap,\n };\n\n if (verbose) {\n console.log(\"[withPluginDevAggregator] Aggregated plugins:\", {\n contexts: aggregatedData.length,\n totalPlugins: aggregatedData.reduce(\n (sum, ctx) => sum + ctx.plugins.length,\n 0\n ),\n pluginIds: aggregatedData.flatMap((ctx) =>\n ctx.plugins.map((p: any) => p.descriptor?.id)\n ),\n overrides: overridesMap,\n });\n }\n\n res.json(aggregatedResponse);\n } catch (error) {\n console.error(\n \"[withPluginDevAggregator] Error aggregating plugins:\",\n error\n );\n res.status(500).json({\n status: 500,\n error: \"Failed to aggregate plugin metadata\",\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n );\n\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] Plugin aggregation endpoint registered at /api/kos/ui/plugins/contexts\"\n );\n }\n\n return middlewares;\n };\n\n return config;\n };\n};\n"],"names":["fs","require$$0","path","require$$1","os","require$$2","crypto","require$$3","packageJson","require$$4","version","LINE","parse","src","obj","lines","match","key","value","maybeQuote","_parseVault","options","vaultPath","_vaultPath","result","DotenvModule","err","keys","_dotenvKey","length","decrypted","i","attrs","_instructions","error","_warn","message","_debug","_log","dotenvKey","uri","environment","environmentKey","ciphertext","possibleVaultPath","filepath","_resolveHome","envPath","_configVault","debug","quiet","parsed","processEnv","configDotenv","dotenvPath","encoding","optionPaths","lastError","parsedAll","e","keysCount","shortPaths","filePath","relative","config","decrypt","encrypted","keyStr","nonce","authTag","aesgcm","isRange","invalidKeyLength","decryptionFailed","populate","override","mainModule","config_1","getKosEnv","dotenv.config","withKosConfig","webpack","_a","withPluginDevServer","kosJsonPath","projectRoot","defaultContext","verbose","context","effectiveProjectRoot","_b","resolvedKosJsonPath","originalSetupMiddlewares","middlewares","devServer","_req","res","errorMsg","kosJsonContent","kosJson","pluginDescriptor","testConfig","_c","pluginContext","pluginId","uuidv4","metadata","_d","withPluginDevAggregator","pluginServers","includeHostPlugins","mergeWithBackend","fallbackToBackend","backendUrl","join","backendData","validResponses","serverUrl","response","data","r","mergedData","overridesMap","backendResponse","contextGroup","contextName","plugin","readFileSync","ncuiPluginDescriptor","_e","contexts","_g","_f","name","responseWrapper","aggregatedData","plugins","aggregatedResponse","sum","ctx","p"],"mappings":"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","x_google_ignoreList":[0]}
package/webpack.js CHANGED
@@ -1,14 +1,14 @@
1
1
  import * as U from "fs";
2
2
  import ee, { readFileSync as te } from "fs";
3
3
  import * as W from "path";
4
- import re, { join as Q } from "path";
4
+ import re, { join as H } from "path";
5
5
  import oe from "os";
6
6
  import ne from "crypto";
7
- import { v4 as C } from "uuid";
8
- var b = { exports: {} };
7
+ import { v4 as F } from "uuid";
8
+ var P = { exports: {} };
9
9
  const se = "16.6.1", ae = {
10
10
  version: se
11
- }, J = ee, Y = re, ie = oe, le = ne, ce = ae, B = ce.version, ue = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
11
+ }, J = ee, C = re, ie = oe, le = ne, ce = ae, B = ce.version, ue = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
12
12
  function ge(e) {
13
13
  const r = {};
14
14
  let s = e.toString();
@@ -96,11 +96,11 @@ function X(e) {
96
96
  else
97
97
  r = e.path.endsWith(".vault") ? e.path : `${e.path}.vault`;
98
98
  else
99
- r = Y.resolve(process.cwd(), ".env.vault");
99
+ r = C.resolve(process.cwd(), ".env.vault");
100
100
  return J.existsSync(r) ? r : null;
101
101
  }
102
- function H(e) {
103
- return e[0] === "~" ? Y.join(ie.homedir(), e.slice(1)) : e;
102
+ function Q(e) {
103
+ return e[0] === "~" ? C.join(ie.homedir(), e.slice(1)) : e;
104
104
  }
105
105
  function he(e) {
106
106
  const r = !!(e && e.debug), s = e && "quiet" in e ? e.quiet : !0;
@@ -110,18 +110,18 @@ function he(e) {
110
110
  return e && e.processEnv != null && (u = e.processEnv), p.populate(u, i, e), { parsed: i };
111
111
  }
112
112
  function ve(e) {
113
- const r = Y.resolve(process.cwd(), ".env");
113
+ const r = C.resolve(process.cwd(), ".env");
114
114
  let s = "utf8";
115
115
  const i = !!(e && e.debug), u = e && "quiet" in e ? e.quiet : !0;
116
116
  e && e.encoding ? s = e.encoding : i && R("No encoding is specified. UTF-8 is used by default");
117
117
  let t = [r];
118
118
  if (e && e.path)
119
119
  if (!Array.isArray(e.path))
120
- t = [H(e.path)];
120
+ t = [Q(e.path)];
121
121
  else {
122
122
  t = [];
123
123
  for (const d of e.path)
124
- t.push(H(d));
124
+ t.push(Q(d));
125
125
  }
126
126
  let n;
127
127
  const o = {};
@@ -137,7 +137,7 @@ function ve(e) {
137
137
  const d = Object.keys(o).length, g = [];
138
138
  for (const y of t)
139
139
  try {
140
- const h = Y.relative(process.cwd(), y);
140
+ const h = C.relative(process.cwd(), y);
141
141
  g.push(h);
142
142
  } catch (h) {
143
143
  i && R(`Failed to load ${y} ${h.message}`), n = h;
@@ -152,7 +152,7 @@ function Ee(e) {
152
152
  const r = X(e);
153
153
  return r ? p._configVault(e) : (pe(`You set DOTENV_KEY but you are missing a .env.vault file at ${r}. Did you forget to build it?`), p.configDotenv(e));
154
154
  }
155
- function ke(e, r) {
155
+ function De(e, r) {
156
156
  const s = Buffer.from(r.slice(-64), "hex");
157
157
  let i = Buffer.from(e, "base64");
158
158
  const u = i.subarray(0, 12), t = i.subarray(-16);
@@ -172,7 +172,7 @@ function ke(e, r) {
172
172
  throw n;
173
173
  }
174
174
  }
175
- function De(e, r, s = {}) {
175
+ function ke(e, r, s = {}) {
176
176
  const i = !!(s && s.debug), u = !!(s && s.override);
177
177
  if (typeof r != "object") {
178
178
  const t = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
@@ -186,18 +186,18 @@ const p = {
186
186
  _configVault: he,
187
187
  _parseVault: de,
188
188
  config: Ee,
189
- decrypt: ke,
189
+ decrypt: De,
190
190
  parse: ge,
191
- populate: De
191
+ populate: ke
192
192
  };
193
- b.exports.configDotenv = p.configDotenv;
194
- b.exports._configVault = p._configVault;
195
- b.exports._parseVault = p._parseVault;
196
- var we = b.exports.config = p.config;
197
- b.exports.decrypt = p.decrypt;
198
- b.exports.parse = p.parse;
199
- b.exports.populate = p.populate;
200
- b.exports = p;
193
+ P.exports.configDotenv = p.configDotenv;
194
+ P.exports._configVault = p._configVault;
195
+ P.exports._parseVault = p._parseVault;
196
+ var we = P.exports.config = p.config;
197
+ P.exports.decrypt = p.decrypt;
198
+ P.exports.parse = p.parse;
199
+ P.exports.populate = p.populate;
200
+ P.exports = p;
201
201
  function me() {
202
202
  return Object.keys(process.env).filter(
203
203
  (r) => r.startsWith("KOS_")
@@ -206,7 +206,7 @@ function me() {
206
206
  we({
207
207
  path: ".env"
208
208
  });
209
- const $e = (e) => (r) => {
209
+ const be = (e) => (r) => {
210
210
  var s;
211
211
  return r && (r.resolve = r.resolve || {}, r.resolve.fallback = {
212
212
  ...r.resolve.fallback,
@@ -214,7 +214,7 @@ const $e = (e) => (r) => {
214
214
  }), r.mode = process.env.NODE_ENV || r.mode, (s = r == null ? void 0 : r.plugins) == null || s.push(
215
215
  new e.EnvironmentPlugin(["NODE_ENV", ...me()])
216
216
  ), r;
217
- }, Ae = (e = {}) => {
217
+ }, $e = (e = {}) => {
218
218
  const {
219
219
  kosJsonPath: r = ".kos.json",
220
220
  projectRoot: s,
@@ -227,6 +227,12 @@ const $e = (e) => (r) => {
227
227
  return u && console.log(
228
228
  "[withPluginDevServer] No devServer config found, skipping middleware"
229
229
  ), t;
230
+ t.devServer.headers = {
231
+ ...t.devServer.headers,
232
+ "Access-Control-Allow-Origin": "*",
233
+ "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
234
+ "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
235
+ };
230
236
  let o = s || process.cwd();
231
237
  s || (t != null && t.context && typeof t.context == "string" ? o = t.context : (g = n == null ? void 0 : n.options) != null && g.root && ((y = n == null ? void 0 : n.options) != null && y.projectRoot) && (o = W.join(
232
238
  n.options.root,
@@ -239,10 +245,10 @@ const $e = (e) => (r) => {
239
245
  defaultContext: i
240
246
  });
241
247
  const d = t.devServer.setupMiddlewares;
242
- return t.devServer.setupMiddlewares = (h, V) => (d && (h = d(h, V)), V.app.get(
248
+ return t.devServer.setupMiddlewares = (h, O) => (d && (h = d(h, O)), O.app.get(
243
249
  "/api/kos/ui/plugins/contexts",
244
250
  (L, _) => {
245
- var O, M, k, S;
251
+ var S, M, D, T;
246
252
  try {
247
253
  if (!U.existsSync(l)) {
248
254
  const N = `.kos.json not found at ${l}`;
@@ -252,11 +258,11 @@ const $e = (e) => (r) => {
252
258
  hint: "Ensure .kos.json exists in your plugin project root"
253
259
  });
254
260
  }
255
- const D = U.readFileSync(
261
+ const k = U.readFileSync(
256
262
  l,
257
263
  "utf-8"
258
- ), I = JSON.parse(D), P = (M = (O = I.kos) == null ? void 0 : O.ui) == null ? void 0 : M.plugin;
259
- if (!P) {
264
+ ), V = JSON.parse(k), A = (M = (S = V.kos) == null ? void 0 : S.ui) == null ? void 0 : M.plugin;
265
+ if (!A) {
260
266
  const N = "kos.ui.plugin section not found in .kos.json";
261
267
  return console.error(`[withPluginDevServer] ${N}`), _.status(400).json({
262
268
  status: 400,
@@ -264,15 +270,15 @@ const $e = (e) => (r) => {
264
270
  hint: "Ensure .kos.json has kos.ui.plugin section defined"
265
271
  });
266
272
  }
267
- const A = (k = I.test) == null ? void 0 : k.plugin, T = (A == null ? void 0 : A.context) || i, K = C(), $ = {
273
+ const $ = (D = V.test) == null ? void 0 : D.plugin, I = ($ == null ? void 0 : $.context) || i, K = F(), b = {
268
274
  status: 200,
269
275
  version: { major: 1, minor: 0 },
270
276
  data: [
271
277
  {
272
- name: T,
278
+ name: I,
273
279
  plugins: [
274
280
  {
275
- descriptor: P,
281
+ descriptor: A,
276
282
  id: K,
277
283
  path: "/"
278
284
  // Simple identifier - actual URL comes from overrides
@@ -282,18 +288,18 @@ const $e = (e) => (r) => {
282
288
  ]
283
289
  };
284
290
  u && console.log("[withPluginDevServer] Serving plugin metadata:", {
285
- pluginId: P.id,
286
- context: T,
287
- extensionsCount: ((S = P.extensions) == null ? void 0 : S.length) || 0
288
- }), _.json($);
289
- } catch (D) {
291
+ pluginId: A.id,
292
+ context: I,
293
+ extensionsCount: ((T = A.extensions) == null ? void 0 : T.length) || 0
294
+ }), _.json(b);
295
+ } catch (k) {
290
296
  console.error(
291
297
  "[withPluginDevServer] Error serving plugin metadata:",
292
- D
298
+ k
293
299
  ), _.status(500).json({
294
300
  status: 500,
295
301
  error: "Failed to serve plugin metadata",
296
- details: D instanceof Error ? D.message : String(D)
302
+ details: k instanceof Error ? k.message : String(k)
297
303
  });
298
304
  }
299
305
  }
@@ -312,13 +318,13 @@ const $e = (e) => (r) => {
312
318
  verbose: o = !1
313
319
  } = e;
314
320
  return (l, d) => {
315
- var V, L;
321
+ var O, L;
316
322
  let g = process.cwd();
317
- l != null && l.context && typeof l.context == "string" ? g = l.context : (V = d == null ? void 0 : d.options) != null && V.root && ((L = d == null ? void 0 : d.options) != null && L.projectRoot) && (g = Q(
323
+ l != null && l.context && typeof l.context == "string" ? g = l.context : (O = d == null ? void 0 : d.options) != null && O.root && ((L = d == null ? void 0 : d.options) != null && L.projectRoot) && (g = H(
318
324
  d.options.root,
319
325
  d.options.projectRoot
320
326
  ));
321
- const y = Q(g, i);
327
+ const y = H(g, i);
322
328
  if (!l.devServer)
323
329
  return o && console.log(
324
330
  "[withPluginDevAggregator] No devServer config found, skipping middleware"
@@ -331,10 +337,10 @@ const $e = (e) => (r) => {
331
337
  kosJsonPath: y
332
338
  });
333
339
  const h = l.devServer.setupMiddlewares;
334
- return l.devServer.setupMiddlewares = (_, O) => (h && (_ = h(_, O)), O.app.get(
340
+ return l.devServer.setupMiddlewares = (_, S) => (h && (_ = h(_, S)), S.app.get(
335
341
  "/api/kos/ui/plugins/contexts",
336
- async (M, k) => {
337
- var S, D, I, P, A, T, K;
342
+ async (M, D) => {
343
+ var T, k, V, A, $, I, K;
338
344
  try {
339
345
  if (r.length === 0)
340
346
  if (t) {
@@ -345,9 +351,9 @@ const $e = (e) => (r) => {
345
351
  const c = await (await fetch(
346
352
  `${n}/api/kos/ui/plugins/contexts`
347
353
  )).json();
348
- return k.json(c);
354
+ return D.json(c);
349
355
  } else
350
- return k.status(404).json({
356
+ return D.status(404).json({
351
357
  status: 404,
352
358
  error: "No plugin servers configured",
353
359
  hint: "Add plugin server URLs to withPluginDevAggregator options or enable fallbackToBackend"
@@ -382,16 +388,16 @@ const $e = (e) => (r) => {
382
388
  const c = await (await fetch(
383
389
  `${n}/api/kos/ui/plugins/contexts`
384
390
  )).json();
385
- return k.json(c);
391
+ return D.json(c);
386
392
  } catch (a) {
387
- return k.status(503).json({
393
+ return D.status(503).json({
388
394
  status: 503,
389
395
  error: "No plugin servers available and backend unreachable",
390
396
  details: a instanceof Error ? a.message : String(a)
391
397
  });
392
398
  }
393
399
  }
394
- const E = {}, F = {};
400
+ const E = {}, Y = {};
395
401
  if (u)
396
402
  try {
397
403
  o && console.log(
@@ -429,12 +435,12 @@ const $e = (e) => (r) => {
429
435
  const a = te(
430
436
  y,
431
437
  "utf-8"
432
- ), c = JSON.parse(a), f = (D = (S = c.kos) == null ? void 0 : S.ui) == null ? void 0 : D.plugin, w = (A = (P = (I = c.kosdev) == null ? void 0 : I.ddk) == null ? void 0 : P.ncui) == null ? void 0 : A.plugin, m = [];
438
+ ), c = JSON.parse(a), f = (k = (T = c.kos) == null ? void 0 : T.ui) == null ? void 0 : k.plugin, w = ($ = (A = (V = c.kosdev) == null ? void 0 : V.ddk) == null ? void 0 : A.ncui) == null ? void 0 : $.plugin, m = [];
433
439
  f && m.push({
434
- name: ((K = (T = c.test) == null ? void 0 : T.plugin) == null ? void 0 : K.context) || "kos.ui",
440
+ name: ((K = (I = c.test) == null ? void 0 : I.plugin) == null ? void 0 : K.context) || "kos.ui",
435
441
  plugin: {
436
442
  descriptor: f,
437
- id: C(),
443
+ id: F(),
438
444
  path: "/"
439
445
  // Host app plugins are served locally
440
446
  }
@@ -442,7 +448,7 @@ const $e = (e) => (r) => {
442
448
  name: "kosdev.ddk",
443
449
  plugin: {
444
450
  descriptor: w,
445
- id: C(),
451
+ id: F(),
446
452
  path: "/"
447
453
  // Host app plugins are served locally
448
454
  }
@@ -466,7 +472,7 @@ const $e = (e) => (r) => {
466
472
  const v = m.name;
467
473
  E[v] || (E[v] = []), m.plugins.forEach((j) => {
468
474
  var q;
469
- E[v].push(j), F[j.id] = `${c}/`, o && console.log(
475
+ E[v].push(j), Y[j.id] = `${c}/`, o && console.log(
470
476
  `[withPluginDevAggregator] Added local dev plugin: ${(q = j.descriptor) == null ? void 0 : q.id} with override to ${c}/`
471
477
  );
472
478
  });
@@ -483,7 +489,7 @@ const $e = (e) => (r) => {
483
489
  data: x,
484
490
  // Include overrides map for dev mode
485
491
  // This allows the host app to pass these to KosPluginProvider
486
- overrides: F
492
+ overrides: Y
487
493
  };
488
494
  o && console.log("[withPluginDevAggregator] Aggregated plugins:", {
489
495
  contexts: x.length,
@@ -497,16 +503,16 @@ const $e = (e) => (r) => {
497
503
  return (f = c.descriptor) == null ? void 0 : f.id;
498
504
  })
499
505
  ),
500
- overrides: F
501
- }), k.json(Z);
502
- } catch ($) {
506
+ overrides: Y
507
+ }), D.json(Z);
508
+ } catch (b) {
503
509
  console.error(
504
510
  "[withPluginDevAggregator] Error aggregating plugins:",
505
- $
506
- ), k.status(500).json({
511
+ b
512
+ ), D.status(500).json({
507
513
  status: 500,
508
514
  error: "Failed to aggregate plugin metadata",
509
- details: $ instanceof Error ? $.message : String($)
515
+ details: b instanceof Error ? b.message : String(b)
510
516
  });
511
517
  }
512
518
  }
@@ -516,8 +522,8 @@ const $e = (e) => (r) => {
516
522
  };
517
523
  };
518
524
  export {
519
- $e as withKosConfig,
525
+ be as withKosConfig,
520
526
  je as withPluginDevAggregator,
521
- Ae as withPluginDevServer
527
+ $e as withPluginDevServer
522
528
  };
523
529
  //# sourceMappingURL=webpack.js.map
package/webpack.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"webpack.js","sources":["../../../../node_modules/dotenv/lib/main.js","../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-kos-config.ts","../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-plugin-dev-server.ts","../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-plugin-dev-aggregator.ts"],"sourcesContent":["const fs = require('fs')\nconst path = require('path')\nconst os = require('os')\nconst crypto = require('crypto')\nconst packageJson = require('../package.json')\n\nconst version = packageJson.version\n\nconst LINE = /(?:^|^)\\s*(?:export\\s+)?([\\w.-]+)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?\\s*(?:#.*)?(?:$|$)/mg\n\n// Parse src into an Object\nfunction parse (src) {\n const obj = {}\n\n // Convert buffer to string\n let lines = src.toString()\n\n // Convert line breaks to same format\n lines = lines.replace(/\\r\\n?/mg, '\\n')\n\n let match\n while ((match = LINE.exec(lines)) != null) {\n const key = match[1]\n\n // Default undefined or null to empty string\n let value = (match[2] || '')\n\n // Remove whitespace\n value = value.trim()\n\n // Check if double quoted\n const maybeQuote = value[0]\n\n // Remove surrounding quotes\n value = value.replace(/^(['\"`])([\\s\\S]*)\\1$/mg, '$2')\n\n // Expand newlines if double quoted\n if (maybeQuote === '\"') {\n value = value.replace(/\\\\n/g, '\\n')\n value = value.replace(/\\\\r/g, '\\r')\n }\n\n // Add to object\n obj[key] = value\n }\n\n return obj\n}\n\nfunction _parseVault (options) {\n options = options || {}\n\n const vaultPath = _vaultPath(options)\n options.path = vaultPath // parse .env.vault\n const result = DotenvModule.configDotenv(options)\n if (!result.parsed) {\n const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`)\n err.code = 'MISSING_DATA'\n throw err\n }\n\n // handle scenario for comma separated keys - for use with key rotation\n // example: DOTENV_KEY=\"dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod\"\n const keys = _dotenvKey(options).split(',')\n const length = keys.length\n\n let decrypted\n for (let i = 0; i < length; i++) {\n try {\n // Get full key\n const key = keys[i].trim()\n\n // Get instructions for decrypt\n const attrs = _instructions(result, key)\n\n // Decrypt\n decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key)\n\n break\n } catch (error) {\n // last key\n if (i + 1 >= length) {\n throw error\n }\n // try next key\n }\n }\n\n // Parse decrypted .env string\n return DotenvModule.parse(decrypted)\n}\n\nfunction _warn (message) {\n console.log(`[dotenv@${version}][WARN] ${message}`)\n}\n\nfunction _debug (message) {\n console.log(`[dotenv@${version}][DEBUG] ${message}`)\n}\n\nfunction _log (message) {\n console.log(`[dotenv@${version}] ${message}`)\n}\n\nfunction _dotenvKey (options) {\n // prioritize developer directly setting options.DOTENV_KEY\n if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {\n return options.DOTENV_KEY\n }\n\n // secondary infra already contains a DOTENV_KEY environment variable\n if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {\n return process.env.DOTENV_KEY\n }\n\n // fallback to empty string\n return ''\n}\n\nfunction _instructions (result, dotenvKey) {\n // Parse DOTENV_KEY. Format is a URI\n let uri\n try {\n uri = new URL(dotenvKey)\n } catch (error) {\n if (error.code === 'ERR_INVALID_URL') {\n const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n throw error\n }\n\n // Get decrypt key\n const key = uri.password\n if (!key) {\n const err = new Error('INVALID_DOTENV_KEY: Missing key part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get environment\n const environment = uri.searchParams.get('environment')\n if (!environment) {\n const err = new Error('INVALID_DOTENV_KEY: Missing environment part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get ciphertext payload\n const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`\n const ciphertext = result.parsed[environmentKey] // DOTENV_VAULT_PRODUCTION\n if (!ciphertext) {\n const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`)\n err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'\n throw err\n }\n\n return { ciphertext, key }\n}\n\nfunction _vaultPath (options) {\n let possibleVaultPath = null\n\n if (options && options.path && options.path.length > 0) {\n if (Array.isArray(options.path)) {\n for (const filepath of options.path) {\n if (fs.existsSync(filepath)) {\n possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`\n }\n }\n } else {\n possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`\n }\n } else {\n possibleVaultPath = path.resolve(process.cwd(), '.env.vault')\n }\n\n if (fs.existsSync(possibleVaultPath)) {\n return possibleVaultPath\n }\n\n return null\n}\n\nfunction _resolveHome (envPath) {\n return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath\n}\n\nfunction _configVault (options) {\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (debug || !quiet) {\n _log('Loading env from encrypted .env.vault')\n }\n\n const parsed = DotenvModule._parseVault(options)\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsed, options)\n\n return { parsed }\n}\n\nfunction configDotenv (options) {\n const dotenvPath = path.resolve(process.cwd(), '.env')\n let encoding = 'utf8'\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (options && options.encoding) {\n encoding = options.encoding\n } else {\n if (debug) {\n _debug('No encoding is specified. UTF-8 is used by default')\n }\n }\n\n let optionPaths = [dotenvPath] // default, look for .env\n if (options && options.path) {\n if (!Array.isArray(options.path)) {\n optionPaths = [_resolveHome(options.path)]\n } else {\n optionPaths = [] // reset default\n for (const filepath of options.path) {\n optionPaths.push(_resolveHome(filepath))\n }\n }\n }\n\n // Build the parsed data in a temporary object (because we need to return it). Once we have the final\n // parsed data, we will combine it with process.env (or options.processEnv if provided).\n let lastError\n const parsedAll = {}\n for (const path of optionPaths) {\n try {\n // Specifying an encoding returns a string instead of a buffer\n const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }))\n\n DotenvModule.populate(parsedAll, parsed, options)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${path} ${e.message}`)\n }\n lastError = e\n }\n }\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsedAll, options)\n\n if (debug || !quiet) {\n const keysCount = Object.keys(parsedAll).length\n const shortPaths = []\n for (const filePath of optionPaths) {\n try {\n const relative = path.relative(process.cwd(), filePath)\n shortPaths.push(relative)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${filePath} ${e.message}`)\n }\n lastError = e\n }\n }\n\n _log(`injecting env (${keysCount}) from ${shortPaths.join(',')}`)\n }\n\n if (lastError) {\n return { parsed: parsedAll, error: lastError }\n } else {\n return { parsed: parsedAll }\n }\n}\n\n// Populates process.env from .env file\nfunction config (options) {\n // fallback to original dotenv if DOTENV_KEY is not set\n if (_dotenvKey(options).length === 0) {\n return DotenvModule.configDotenv(options)\n }\n\n const vaultPath = _vaultPath(options)\n\n // dotenvKey exists but .env.vault file does not exist\n if (!vaultPath) {\n _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`)\n\n return DotenvModule.configDotenv(options)\n }\n\n return DotenvModule._configVault(options)\n}\n\nfunction decrypt (encrypted, keyStr) {\n const key = Buffer.from(keyStr.slice(-64), 'hex')\n let ciphertext = Buffer.from(encrypted, 'base64')\n\n const nonce = ciphertext.subarray(0, 12)\n const authTag = ciphertext.subarray(-16)\n ciphertext = ciphertext.subarray(12, -16)\n\n try {\n const aesgcm = crypto.createDecipheriv('aes-256-gcm', key, nonce)\n aesgcm.setAuthTag(authTag)\n return `${aesgcm.update(ciphertext)}${aesgcm.final()}`\n } catch (error) {\n const isRange = error instanceof RangeError\n const invalidKeyLength = error.message === 'Invalid key length'\n const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'\n\n if (isRange || invalidKeyLength) {\n const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n } else if (decryptionFailed) {\n const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY')\n err.code = 'DECRYPTION_FAILED'\n throw err\n } else {\n throw error\n }\n }\n}\n\n// Populate process.env with parsed values\nfunction populate (processEnv, parsed, options = {}) {\n const debug = Boolean(options && options.debug)\n const override = Boolean(options && options.override)\n\n if (typeof parsed !== 'object') {\n const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate')\n err.code = 'OBJECT_REQUIRED'\n throw err\n }\n\n // Set process.env\n for (const key of Object.keys(parsed)) {\n if (Object.prototype.hasOwnProperty.call(processEnv, key)) {\n if (override === true) {\n processEnv[key] = parsed[key]\n }\n\n if (debug) {\n if (override === true) {\n _debug(`\"${key}\" is already defined and WAS overwritten`)\n } else {\n _debug(`\"${key}\" is already defined and was NOT overwritten`)\n }\n }\n } else {\n processEnv[key] = parsed[key]\n }\n }\n}\n\nconst DotenvModule = {\n configDotenv,\n _configVault,\n _parseVault,\n config,\n decrypt,\n parse,\n populate\n}\n\nmodule.exports.configDotenv = DotenvModule.configDotenv\nmodule.exports._configVault = DotenvModule._configVault\nmodule.exports._parseVault = DotenvModule._parseVault\nmodule.exports.config = DotenvModule.config\nmodule.exports.decrypt = DotenvModule.decrypt\nmodule.exports.parse = DotenvModule.parse\nmodule.exports.populate = DotenvModule.populate\n\nmodule.exports = DotenvModule\n","import * as dotenv from \"dotenv\";\nfunction getKosEnv() {\n const kosKeys = Object.keys(process.env).filter((key) =>\n key.startsWith(\"KOS_\")\n );\n return kosKeys;\n}\ndotenv.config({\n path: \".env\",\n});\nexport const withKosConfig = (webpack) => (config) => {\n if (config) {\n config.resolve = config.resolve || {};\n config.resolve.fallback = {\n ...config.resolve.fallback,\n path: false,\n };\n }\n config.mode = (process.env.NODE_ENV || config.mode) as any;\n // customize webpack config here\n config?.plugins?.push(\n new webpack.EnvironmentPlugin([\"NODE_ENV\", ...getKosEnv()])\n );\n return config;\n};\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport { v4 as uuidv4 } from \"uuid\";\n\n/**\n * Configuration options for plugin development server middleware\n */\nexport interface PluginDevServerOptions {\n /**\n * Path to .kos.json file, relative to project root.\n * Default: '.kos.json'\n */\n kosJsonPath?: string;\n\n /**\n * Project root directory. Used to resolve kosJsonPath.\n * Default: process.cwd()\n */\n projectRoot?: string;\n\n /**\n * Default plugin context if not specified in .kos.json test section.\n * Default: 'kosdev.ddk'\n */\n defaultContext?: string;\n\n /**\n * Enable verbose logging for debugging.\n * Default: false\n */\n verbose?: boolean;\n}\n\n/**\n * Webpack plugin composable that adds plugin development server middleware.\n *\n * This middleware serves the `/api/kos/ui/plugins/contexts` endpoint, mimicking\n * the backend KOS plugin API response format. It enables local plugin development\n * without requiring backend deployment.\n *\n * @example\n * ```typescript\n * // webpack.config.ts\n * import { withKosConfig, withPluginDevServer } from '@kosdev-code/kos-ui-plugin/webpack';\n * import { composePlugins, withNx } from '@nx/webpack';\n *\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withKosConfig(webpack),\n * withPluginDevServer() // ← Add plugin dev server\n * );\n * ```\n *\n * @example With options\n * ```typescript\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withKosConfig(webpack),\n * withPluginDevServer({\n * kosJsonPath: '.kos.json',\n * defaultContext: 'kosdev.ddk',\n * verbose: true\n * })\n * );\n * ```\n *\n * ## .kos.json Structure\n *\n * The middleware reads two sections from .kos.json:\n *\n * ```json\n * {\n * \"kos\": {\n * \"ui\": {\n * \"plugin\": {\n * \"id\": \"MyPlugin\",\n * \"extensions\": [...],\n * \"contributes\": {...}\n * }\n * }\n * },\n * \"test\": {\n * \"plugin\": {\n * \"context\": \"kosdev.ddk\"\n * }\n * }\n * }\n * ```\n *\n * - `kos.ui.plugin`: Production plugin descriptor (becomes API `descriptor`)\n * - `test.plugin.context`: Development plugin context/group name\n *\n * ## Response Format\n *\n * The middleware returns the same format as the backend `/api/kos/ui/plugins/contexts`:\n *\n * ```json\n * {\n * \"status\": 200,\n * \"version\": {\"major\": 1, \"minor\": 0},\n * \"data\": [\n * {\n * \"name\": \"kosdev.ddk\",\n * \"plugins\": [\n * {\n * \"descriptor\": { ... },\n * \"id\": \"uuid-v4\",\n * \"path\": \"/\"\n * }\n * ]\n * }\n * ]\n * }\n * ```\n *\n * @param options - Configuration options\n */\nexport const withPluginDevServer = (options: PluginDevServerOptions = {}) => {\n const {\n kosJsonPath = \".kos.json\",\n projectRoot,\n defaultContext = \"kosdev.ddk\",\n verbose = false,\n } = options;\n\n return (config: any, context: any) => {\n // Only add middleware if devServer is configured\n if (!config.devServer) {\n if (verbose) {\n console.log(\n \"[withPluginDevServer] No devServer config found, skipping middleware\"\n );\n }\n return config;\n }\n\n // Resolve project root from context if not provided\n // In Nx webpack configs, the context is passed as the second argument\n // We need to check several possible locations for the project path:\n // - config.context (webpack context, usually the project root) - PREFERRED\n // - context.options.root + context.options.projectRoot (Nx-specific fallback)\n let effectiveProjectRoot: string = projectRoot || process.cwd();\n\n if (!projectRoot) {\n // Try config.context first (webpack's context is usually the project directory)\n if (config?.context && typeof config.context === \"string\") {\n effectiveProjectRoot = config.context;\n }\n // If that's not available, try combining workspace root with project root\n else if (context?.options?.root && context?.options?.projectRoot) {\n effectiveProjectRoot = path.join(\n context.options.root,\n context.options.projectRoot\n );\n }\n }\n\n const resolvedKosJsonPath = path.resolve(effectiveProjectRoot, kosJsonPath);\n\n if (verbose) {\n console.log(\"[withPluginDevServer] Configuration:\", {\n kosJsonPath: resolvedKosJsonPath,\n projectRoot: effectiveProjectRoot,\n defaultContext,\n });\n }\n\n // Initialize or extend setupMiddlewares\n const originalSetupMiddlewares = config.devServer.setupMiddlewares;\n\n config.devServer.setupMiddlewares = (\n middlewares: any[],\n devServer: any\n ) => {\n // Call original setupMiddlewares if it exists\n if (originalSetupMiddlewares) {\n middlewares = originalSetupMiddlewares(middlewares, devServer);\n }\n\n // Add plugin metadata endpoint\n devServer.app.get(\n \"/api/kos/ui/plugins/contexts\",\n (_req: any, res: any) => {\n try {\n // Check if .kos.json exists\n if (!fs.existsSync(resolvedKosJsonPath)) {\n const errorMsg = `.kos.json not found at ${resolvedKosJsonPath}`;\n console.error(`[withPluginDevServer] ${errorMsg}`);\n return res.status(404).json({\n status: 404,\n error: errorMsg,\n hint: \"Ensure .kos.json exists in your plugin project root\",\n });\n }\n\n // Read and parse .kos.json\n const kosJsonContent = fs.readFileSync(\n resolvedKosJsonPath,\n \"utf-8\"\n );\n const kosJson = JSON.parse(kosJsonContent);\n\n // Extract production plugin descriptor\n const pluginDescriptor = kosJson.kos?.ui?.plugin;\n if (!pluginDescriptor) {\n const errorMsg = \"kos.ui.plugin section not found in .kos.json\";\n console.error(`[withPluginDevServer] ${errorMsg}`);\n return res.status(400).json({\n status: 400,\n error: errorMsg,\n hint: \"Ensure .kos.json has kos.ui.plugin section defined\",\n });\n }\n\n // Extract test configuration\n const testConfig = kosJson.test?.plugin;\n const pluginContext = testConfig?.context || defaultContext;\n\n // Generate deterministic UUID based on plugin ID\n // Using v4 for now, but could use v5 with plugin ID as namespace in future\n const pluginId = uuidv4();\n\n // Build backend-compatible response\n // Note: The 'path' field is just an identifier in dev mode.\n // The actual dev server URL should be provided via 'overrides' in KosPluginProvider\n const metadata = {\n status: 200,\n version: { major: 1, minor: 0 },\n data: [\n {\n name: pluginContext,\n plugins: [\n {\n descriptor: pluginDescriptor,\n id: pluginId,\n path: \"/\", // Simple identifier - actual URL comes from overrides\n },\n ],\n },\n ],\n };\n\n if (verbose) {\n console.log(\"[withPluginDevServer] Serving plugin metadata:\", {\n pluginId: pluginDescriptor.id,\n context: pluginContext,\n extensionsCount: pluginDescriptor.extensions?.length || 0,\n });\n }\n\n res.json(metadata);\n } catch (error) {\n console.error(\n \"[withPluginDevServer] Error serving plugin metadata:\",\n error\n );\n res.status(500).json({\n status: 500,\n error: \"Failed to serve plugin metadata\",\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n );\n\n if (verbose) {\n console.log(\n \"[withPluginDevServer] Plugin metadata endpoint registered at /api/kos/ui/plugins/contexts\"\n );\n }\n\n return middlewares;\n };\n\n return config;\n };\n};\n","/**\n * Multi-Plugin Development Mode Aggregation Middleware\n *\n * This webpack composable aggregates metadata from multiple plugin dev servers\n * running on different ports, combining them into a single response at the\n * `/api/kos/ui/plugins/contexts` endpoint.\n *\n * This allows a host app to load multiple plugins simultaneously during development.\n */\n\nimport { readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport interface PluginDevAggregatorOptions {\n /**\n * List of plugin dev server URLs to aggregate.\n * Example: ['http://localhost:4201', 'http://localhost:4202']\n */\n pluginServers: string[];\n\n /**\n * Include the host app's own .kos.json plugin definitions.\n * Default: true\n */\n includeHostPlugins?: boolean;\n\n /**\n * Path to the host app's .kos.json file.\n * Default: './.kos.json'\n */\n kosJsonPath?: string;\n\n /**\n * Merge backend plugins with local dev plugins.\n * When true, fetches plugins from backend and overlays local dev plugins on top.\n * Local dev plugins get overrides pointing to dev servers.\n * Backend plugins use their original URLs (no overrides).\n *\n * This is useful for third-party developers who want to:\n * - Run against a production DDK backend\n * - Load DDK base plugins from the backend\n * - Develop their own custom plugins locally\n *\n * Default: false (local-only mode)\n */\n mergeWithBackend?: boolean;\n\n /**\n * Fallback to backend if no local plugin servers are available.\n * Default: true\n */\n fallbackToBackend?: boolean;\n\n /**\n * Backend URL to fallback to when no plugin servers available.\n * Default: 'http://localhost:8081'\n */\n backendUrl?: string;\n\n /**\n * Enable verbose logging for debugging.\n * Default: false\n */\n verbose?: boolean;\n}\n\n/**\n * Webpack plugin composable that aggregates multiple plugin dev servers.\n *\n * @example\n * ```typescript\n * // Host app webpack.config.ts\n * import { withPluginDevAggregator } from '@kosdev-code/kos-ui-plugin/webpack';\n *\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withPluginDevAggregator({\n * pluginServers: [\n * 'http://localhost:4201', // beverage-pour\n * 'http://localhost:4202' // kos-ddk-standard-plugin\n * ]\n * })\n * );\n * ```\n *\n * @example With environment variables\n * ```typescript\n * const pluginServers = [\n * process.env.PLUGIN_A_DEV === 'true' && 'http://localhost:4201',\n * process.env.PLUGIN_B_DEV === 'true' && 'http://localhost:4202',\n * ].filter(Boolean);\n *\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withPluginDevAggregator({\n * pluginServers,\n * fallbackToBackend: pluginServers.length === 0\n * })\n * );\n * ```\n */\nexport const withPluginDevAggregator = (\n options: PluginDevAggregatorOptions\n) => {\n const {\n pluginServers,\n includeHostPlugins = true,\n kosJsonPath = \".kos.json\",\n mergeWithBackend = false,\n fallbackToBackend = true,\n backendUrl = \"http://localhost:8081\",\n verbose = false,\n } = options;\n\n return (config: any, context: any) => {\n // Resolve project root from Nx context (similar to withPluginDevServer)\n let effectiveProjectRoot: string = process.cwd();\n\n if (config?.context && typeof config.context === \"string\") {\n effectiveProjectRoot = config.context;\n } else if (context?.options?.root && context?.options?.projectRoot) {\n effectiveProjectRoot = join(\n context.options.root,\n context.options.projectRoot\n );\n }\n\n const resolvedKosJsonPath = join(effectiveProjectRoot, kosJsonPath);\n\n // Only add middleware if devServer is configured\n if (!config.devServer) {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] No devServer config found, skipping middleware\"\n );\n }\n return config;\n }\n\n if (verbose) {\n console.log(\"[withPluginDevAggregator] Configuration:\", {\n pluginServers,\n fallbackToBackend,\n backendUrl,\n projectRoot: effectiveProjectRoot,\n kosJsonPath: resolvedKosJsonPath,\n });\n }\n\n // Initialize or extend setupMiddlewares\n const originalSetupMiddlewares = config.devServer.setupMiddlewares;\n\n config.devServer.setupMiddlewares = (\n middlewares: any[],\n devServer: any\n ) => {\n // Call original setupMiddlewares if it exists\n if (originalSetupMiddlewares) {\n middlewares = originalSetupMiddlewares(middlewares, devServer);\n }\n\n // Add aggregation endpoint\n devServer.app.get(\n \"/api/kos/ui/plugins/contexts\",\n async (_req: any, res: any) => {\n try {\n // If no plugin servers configured, fallback to backend\n if (pluginServers.length === 0) {\n if (fallbackToBackend) {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] No plugin servers, proxying to backend:\",\n backendUrl\n );\n }\n\n // Proxy to backend\n const backendResponse = await fetch(\n `${backendUrl}/api/kos/ui/plugins/contexts`\n );\n const backendData = await backendResponse.json();\n return res.json(backendData);\n } else {\n return res.status(404).json({\n status: 404,\n error: \"No plugin servers configured\",\n hint: \"Add plugin server URLs to withPluginDevAggregator options or enable fallbackToBackend\",\n });\n }\n }\n\n // Fetch from all plugin dev servers\n const responses = await Promise.all(\n pluginServers.map(async (serverUrl) => {\n try {\n const response = await fetch(\n `${serverUrl}/api/kos/ui/plugins/contexts`\n );\n if (!response.ok) {\n if (verbose) {\n console.warn(\n `[withPluginDevAggregator] Failed to fetch from ${serverUrl}: ${response.status}`\n );\n }\n return null;\n }\n const data = await response.json();\n return { serverUrl, data };\n } catch (error) {\n if (verbose) {\n console.warn(\n `[withPluginDevAggregator] Error fetching from ${serverUrl}:`,\n error\n );\n }\n return null;\n }\n })\n );\n\n // Filter out failed requests\n const validResponses = responses.filter(\n (r) => r && r.data && r.data.status === 200\n );\n\n // If no valid responses and fallback enabled, try backend\n if (validResponses.length === 0 && fallbackToBackend) {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] No plugin servers responded, falling back to backend\"\n );\n }\n\n try {\n const backendResponse = await fetch(\n `${backendUrl}/api/kos/ui/plugins/contexts`\n );\n const backendData = await backendResponse.json();\n return res.json(backendData);\n } catch (error) {\n return res.status(503).json({\n status: 503,\n error: \"No plugin servers available and backend unreachable\",\n details:\n error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Merge all plugin data from valid responses\n // Group by context name and merge plugins\n // Also build overrides map for dev server URLs\n const mergedData: Record<string, any[]> = {};\n const overridesMap: Record<string, string> = {};\n\n // Step 1: Fetch and include backend plugins if mergeWithBackend is enabled\n // Backend plugins are added WITHOUT overrides (use their production URLs)\n if (mergeWithBackend) {\n try {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] Fetching backend plugins from:\",\n backendUrl\n );\n }\n\n const backendResponse = await fetch(\n `${backendUrl}/api/kos/ui/plugins/contexts`\n );\n if (backendResponse.ok) {\n const backendData = await backendResponse.json();\n\n if (backendData.status === 200 && backendData.data) {\n backendData.data.forEach((contextGroup: any) => {\n const contextName = contextGroup.name;\n if (!mergedData[contextName]) {\n mergedData[contextName] = [];\n }\n\n // Add backend plugins WITHOUT overrides\n // They will use their production URLs from the backend\n contextGroup.plugins.forEach((plugin: any) => {\n mergedData[contextName].push(plugin);\n\n if (verbose) {\n console.log(\n `[withPluginDevAggregator] Added backend plugin: ${plugin.descriptor?.id} (no override)`\n );\n }\n });\n });\n\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] Successfully merged backend plugins\"\n );\n }\n }\n } else {\n if (verbose) {\n console.warn(\n `[withPluginDevAggregator] Backend fetch failed: ${backendResponse.status}`\n );\n }\n }\n } catch (error) {\n if (verbose) {\n console.warn(\n \"[withPluginDevAggregator] Error fetching backend plugins:\",\n error\n );\n }\n }\n }\n\n // Step 2: Include host app's own plugin definitions if enabled\n if (includeHostPlugins) {\n try {\n const kosJsonContent = readFileSync(\n resolvedKosJsonPath,\n \"utf-8\"\n );\n const kosJson = JSON.parse(kosJsonContent);\n\n // Check for plugin definitions in kos.ui.plugin or kosdev.ddk.ncui.plugin\n const pluginDescriptor = kosJson.kos?.ui?.plugin;\n const ncuiPluginDescriptor = kosJson.kosdev?.ddk?.ncui?.plugin;\n\n // Determine context based on plugin type\n const contexts: Array<{\n name: string;\n plugin: { descriptor: any; id: string; path: string };\n }> = [];\n\n if (pluginDescriptor) {\n contexts.push({\n name: kosJson.test?.plugin?.context || \"kos.ui\",\n plugin: {\n descriptor: pluginDescriptor,\n id: uuidv4(),\n path: \"/\", // Host app plugins are served locally\n },\n });\n }\n\n if (ncuiPluginDescriptor) {\n contexts.push({\n name: \"kosdev.ddk\",\n plugin: {\n descriptor: ncuiPluginDescriptor,\n id: uuidv4(),\n path: \"/\", // Host app plugins are served locally\n },\n });\n }\n\n // Add host plugins to merged data\n contexts.forEach(({ name, plugin }) => {\n if (!mergedData[name]) {\n mergedData[name] = [];\n }\n mergedData[name].push(plugin);\n\n if (verbose) {\n console.log(\n `[withPluginDevAggregator] Added host plugin: ${plugin.descriptor.id} to context ${name}`\n );\n }\n });\n } catch (error) {\n if (verbose) {\n console.warn(\n \"[withPluginDevAggregator] Failed to read host .kos.json:\",\n error\n );\n }\n }\n }\n\n // Step 3: Add plugins from remote dev servers with overrides\n // Local dev plugins get overrides pointing to their dev server URLs\n validResponses.forEach((responseWrapper) => {\n if (!responseWrapper) return;\n const { serverUrl, data: response } = responseWrapper;\n\n response.data?.forEach((contextGroup: any) => {\n const contextName = contextGroup.name;\n if (!mergedData[contextName]) {\n mergedData[contextName] = [];\n }\n\n // Add plugins and build overrides for each plugin\n contextGroup.plugins.forEach((plugin: any) => {\n mergedData[contextName].push(plugin);\n // Map plugin ID to its dev server URL\n // This allows KosPluginProvider to use overrides to point to the right server\n overridesMap[plugin.id] = `${serverUrl}/`;\n\n if (verbose) {\n console.log(\n `[withPluginDevAggregator] Added local dev plugin: ${plugin.descriptor?.id} with override to ${serverUrl}/`\n );\n }\n });\n });\n });\n\n // Convert back to array format\n const aggregatedData = Object.entries(mergedData).map(\n ([name, plugins]) => ({\n name,\n plugins,\n })\n );\n\n const aggregatedResponse = {\n status: 200,\n version: { major: 1, minor: 0 },\n data: aggregatedData,\n // Include overrides map for dev mode\n // This allows the host app to pass these to KosPluginProvider\n overrides: overridesMap,\n };\n\n if (verbose) {\n console.log(\"[withPluginDevAggregator] Aggregated plugins:\", {\n contexts: aggregatedData.length,\n totalPlugins: aggregatedData.reduce(\n (sum, ctx) => sum + ctx.plugins.length,\n 0\n ),\n pluginIds: aggregatedData.flatMap((ctx) =>\n ctx.plugins.map((p: any) => p.descriptor?.id)\n ),\n overrides: overridesMap,\n });\n }\n\n res.json(aggregatedResponse);\n } catch (error) {\n console.error(\n \"[withPluginDevAggregator] Error aggregating plugins:\",\n error\n );\n res.status(500).json({\n status: 500,\n error: \"Failed to aggregate plugin metadata\",\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n );\n\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] Plugin aggregation endpoint registered at /api/kos/ui/plugins/contexts\"\n );\n }\n\n return middlewares;\n };\n\n return config;\n };\n};\n"],"names":["fs","require$$0","path","require$$1","os","require$$2","crypto","require$$3","packageJson","require$$4","version","LINE","parse","src","obj","lines","match","key","value","maybeQuote","_parseVault","options","vaultPath","_vaultPath","result","DotenvModule","err","keys","_dotenvKey","length","decrypted","i","attrs","_instructions","error","_warn","message","_debug","_log","dotenvKey","uri","environment","environmentKey","ciphertext","possibleVaultPath","filepath","_resolveHome","envPath","_configVault","debug","quiet","parsed","processEnv","configDotenv","dotenvPath","encoding","optionPaths","lastError","parsedAll","e","keysCount","shortPaths","filePath","relative","config","decrypt","encrypted","keyStr","nonce","authTag","aesgcm","isRange","invalidKeyLength","decryptionFailed","populate","override","mainModule","config_1","getKosEnv","dotenv.config","withKosConfig","webpack","_a","withPluginDevServer","kosJsonPath","projectRoot","defaultContext","verbose","context","effectiveProjectRoot","_b","resolvedKosJsonPath","originalSetupMiddlewares","middlewares","devServer","_req","res","errorMsg","kosJsonContent","kosJson","pluginDescriptor","testConfig","_c","pluginContext","pluginId","uuidv4","metadata","_d","withPluginDevAggregator","pluginServers","includeHostPlugins","mergeWithBackend","fallbackToBackend","backendUrl","join","backendData","validResponses","serverUrl","response","data","r","mergedData","overridesMap","backendResponse","contextGroup","contextName","plugin","readFileSync","ncuiPluginDescriptor","_e","contexts","_g","_f","name","responseWrapper","aggregatedData","plugins","aggregatedResponse","sum","ctx","p"],"mappings":"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","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"webpack.js","sources":["../../../../node_modules/dotenv/lib/main.js","../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-kos-config.ts","../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-plugin-dev-server.ts","../../../../packages/sdk/kos-ui-plugin/src/lib/webpack/with-plugin-dev-aggregator.ts"],"sourcesContent":["const fs = require('fs')\nconst path = require('path')\nconst os = require('os')\nconst crypto = require('crypto')\nconst packageJson = require('../package.json')\n\nconst version = packageJson.version\n\nconst LINE = /(?:^|^)\\s*(?:export\\s+)?([\\w.-]+)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?\\s*(?:#.*)?(?:$|$)/mg\n\n// Parse src into an Object\nfunction parse (src) {\n const obj = {}\n\n // Convert buffer to string\n let lines = src.toString()\n\n // Convert line breaks to same format\n lines = lines.replace(/\\r\\n?/mg, '\\n')\n\n let match\n while ((match = LINE.exec(lines)) != null) {\n const key = match[1]\n\n // Default undefined or null to empty string\n let value = (match[2] || '')\n\n // Remove whitespace\n value = value.trim()\n\n // Check if double quoted\n const maybeQuote = value[0]\n\n // Remove surrounding quotes\n value = value.replace(/^(['\"`])([\\s\\S]*)\\1$/mg, '$2')\n\n // Expand newlines if double quoted\n if (maybeQuote === '\"') {\n value = value.replace(/\\\\n/g, '\\n')\n value = value.replace(/\\\\r/g, '\\r')\n }\n\n // Add to object\n obj[key] = value\n }\n\n return obj\n}\n\nfunction _parseVault (options) {\n options = options || {}\n\n const vaultPath = _vaultPath(options)\n options.path = vaultPath // parse .env.vault\n const result = DotenvModule.configDotenv(options)\n if (!result.parsed) {\n const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`)\n err.code = 'MISSING_DATA'\n throw err\n }\n\n // handle scenario for comma separated keys - for use with key rotation\n // example: DOTENV_KEY=\"dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod\"\n const keys = _dotenvKey(options).split(',')\n const length = keys.length\n\n let decrypted\n for (let i = 0; i < length; i++) {\n try {\n // Get full key\n const key = keys[i].trim()\n\n // Get instructions for decrypt\n const attrs = _instructions(result, key)\n\n // Decrypt\n decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key)\n\n break\n } catch (error) {\n // last key\n if (i + 1 >= length) {\n throw error\n }\n // try next key\n }\n }\n\n // Parse decrypted .env string\n return DotenvModule.parse(decrypted)\n}\n\nfunction _warn (message) {\n console.log(`[dotenv@${version}][WARN] ${message}`)\n}\n\nfunction _debug (message) {\n console.log(`[dotenv@${version}][DEBUG] ${message}`)\n}\n\nfunction _log (message) {\n console.log(`[dotenv@${version}] ${message}`)\n}\n\nfunction _dotenvKey (options) {\n // prioritize developer directly setting options.DOTENV_KEY\n if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {\n return options.DOTENV_KEY\n }\n\n // secondary infra already contains a DOTENV_KEY environment variable\n if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {\n return process.env.DOTENV_KEY\n }\n\n // fallback to empty string\n return ''\n}\n\nfunction _instructions (result, dotenvKey) {\n // Parse DOTENV_KEY. Format is a URI\n let uri\n try {\n uri = new URL(dotenvKey)\n } catch (error) {\n if (error.code === 'ERR_INVALID_URL') {\n const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n throw error\n }\n\n // Get decrypt key\n const key = uri.password\n if (!key) {\n const err = new Error('INVALID_DOTENV_KEY: Missing key part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get environment\n const environment = uri.searchParams.get('environment')\n if (!environment) {\n const err = new Error('INVALID_DOTENV_KEY: Missing environment part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get ciphertext payload\n const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`\n const ciphertext = result.parsed[environmentKey] // DOTENV_VAULT_PRODUCTION\n if (!ciphertext) {\n const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`)\n err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'\n throw err\n }\n\n return { ciphertext, key }\n}\n\nfunction _vaultPath (options) {\n let possibleVaultPath = null\n\n if (options && options.path && options.path.length > 0) {\n if (Array.isArray(options.path)) {\n for (const filepath of options.path) {\n if (fs.existsSync(filepath)) {\n possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`\n }\n }\n } else {\n possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`\n }\n } else {\n possibleVaultPath = path.resolve(process.cwd(), '.env.vault')\n }\n\n if (fs.existsSync(possibleVaultPath)) {\n return possibleVaultPath\n }\n\n return null\n}\n\nfunction _resolveHome (envPath) {\n return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath\n}\n\nfunction _configVault (options) {\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (debug || !quiet) {\n _log('Loading env from encrypted .env.vault')\n }\n\n const parsed = DotenvModule._parseVault(options)\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsed, options)\n\n return { parsed }\n}\n\nfunction configDotenv (options) {\n const dotenvPath = path.resolve(process.cwd(), '.env')\n let encoding = 'utf8'\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (options && options.encoding) {\n encoding = options.encoding\n } else {\n if (debug) {\n _debug('No encoding is specified. UTF-8 is used by default')\n }\n }\n\n let optionPaths = [dotenvPath] // default, look for .env\n if (options && options.path) {\n if (!Array.isArray(options.path)) {\n optionPaths = [_resolveHome(options.path)]\n } else {\n optionPaths = [] // reset default\n for (const filepath of options.path) {\n optionPaths.push(_resolveHome(filepath))\n }\n }\n }\n\n // Build the parsed data in a temporary object (because we need to return it). Once we have the final\n // parsed data, we will combine it with process.env (or options.processEnv if provided).\n let lastError\n const parsedAll = {}\n for (const path of optionPaths) {\n try {\n // Specifying an encoding returns a string instead of a buffer\n const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }))\n\n DotenvModule.populate(parsedAll, parsed, options)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${path} ${e.message}`)\n }\n lastError = e\n }\n }\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsedAll, options)\n\n if (debug || !quiet) {\n const keysCount = Object.keys(parsedAll).length\n const shortPaths = []\n for (const filePath of optionPaths) {\n try {\n const relative = path.relative(process.cwd(), filePath)\n shortPaths.push(relative)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${filePath} ${e.message}`)\n }\n lastError = e\n }\n }\n\n _log(`injecting env (${keysCount}) from ${shortPaths.join(',')}`)\n }\n\n if (lastError) {\n return { parsed: parsedAll, error: lastError }\n } else {\n return { parsed: parsedAll }\n }\n}\n\n// Populates process.env from .env file\nfunction config (options) {\n // fallback to original dotenv if DOTENV_KEY is not set\n if (_dotenvKey(options).length === 0) {\n return DotenvModule.configDotenv(options)\n }\n\n const vaultPath = _vaultPath(options)\n\n // dotenvKey exists but .env.vault file does not exist\n if (!vaultPath) {\n _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`)\n\n return DotenvModule.configDotenv(options)\n }\n\n return DotenvModule._configVault(options)\n}\n\nfunction decrypt (encrypted, keyStr) {\n const key = Buffer.from(keyStr.slice(-64), 'hex')\n let ciphertext = Buffer.from(encrypted, 'base64')\n\n const nonce = ciphertext.subarray(0, 12)\n const authTag = ciphertext.subarray(-16)\n ciphertext = ciphertext.subarray(12, -16)\n\n try {\n const aesgcm = crypto.createDecipheriv('aes-256-gcm', key, nonce)\n aesgcm.setAuthTag(authTag)\n return `${aesgcm.update(ciphertext)}${aesgcm.final()}`\n } catch (error) {\n const isRange = error instanceof RangeError\n const invalidKeyLength = error.message === 'Invalid key length'\n const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'\n\n if (isRange || invalidKeyLength) {\n const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n } else if (decryptionFailed) {\n const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY')\n err.code = 'DECRYPTION_FAILED'\n throw err\n } else {\n throw error\n }\n }\n}\n\n// Populate process.env with parsed values\nfunction populate (processEnv, parsed, options = {}) {\n const debug = Boolean(options && options.debug)\n const override = Boolean(options && options.override)\n\n if (typeof parsed !== 'object') {\n const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate')\n err.code = 'OBJECT_REQUIRED'\n throw err\n }\n\n // Set process.env\n for (const key of Object.keys(parsed)) {\n if (Object.prototype.hasOwnProperty.call(processEnv, key)) {\n if (override === true) {\n processEnv[key] = parsed[key]\n }\n\n if (debug) {\n if (override === true) {\n _debug(`\"${key}\" is already defined and WAS overwritten`)\n } else {\n _debug(`\"${key}\" is already defined and was NOT overwritten`)\n }\n }\n } else {\n processEnv[key] = parsed[key]\n }\n }\n}\n\nconst DotenvModule = {\n configDotenv,\n _configVault,\n _parseVault,\n config,\n decrypt,\n parse,\n populate\n}\n\nmodule.exports.configDotenv = DotenvModule.configDotenv\nmodule.exports._configVault = DotenvModule._configVault\nmodule.exports._parseVault = DotenvModule._parseVault\nmodule.exports.config = DotenvModule.config\nmodule.exports.decrypt = DotenvModule.decrypt\nmodule.exports.parse = DotenvModule.parse\nmodule.exports.populate = DotenvModule.populate\n\nmodule.exports = DotenvModule\n","import * as dotenv from \"dotenv\";\nfunction getKosEnv() {\n const kosKeys = Object.keys(process.env).filter((key) =>\n key.startsWith(\"KOS_\")\n );\n return kosKeys;\n}\ndotenv.config({\n path: \".env\",\n});\nexport const withKosConfig = (webpack) => (config) => {\n if (config) {\n config.resolve = config.resolve || {};\n config.resolve.fallback = {\n ...config.resolve.fallback,\n path: false,\n };\n }\n config.mode = (process.env.NODE_ENV || config.mode) as any;\n // customize webpack config here\n config?.plugins?.push(\n new webpack.EnvironmentPlugin([\"NODE_ENV\", ...getKosEnv()])\n );\n return config;\n};\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport { v4 as uuidv4 } from \"uuid\";\n\n/**\n * Configuration options for plugin development server middleware\n */\nexport interface PluginDevServerOptions {\n /**\n * Path to .kos.json file, relative to project root.\n * Default: '.kos.json'\n */\n kosJsonPath?: string;\n\n /**\n * Project root directory. Used to resolve kosJsonPath.\n * Default: process.cwd()\n */\n projectRoot?: string;\n\n /**\n * Default plugin context if not specified in .kos.json test section.\n * Default: 'kosdev.ddk'\n */\n defaultContext?: string;\n\n /**\n * Enable verbose logging for debugging.\n * Default: false\n */\n verbose?: boolean;\n}\n\n/**\n * Webpack plugin composable that adds plugin development server middleware.\n *\n * This middleware serves the `/api/kos/ui/plugins/contexts` endpoint, mimicking\n * the backend KOS plugin API response format. It enables local plugin development\n * without requiring backend deployment.\n *\n * @example\n * ```typescript\n * // webpack.config.ts\n * import { withKosConfig, withPluginDevServer } from '@kosdev-code/kos-ui-plugin/webpack';\n * import { composePlugins, withNx } from '@nx/webpack';\n *\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withKosConfig(webpack),\n * withPluginDevServer() // ← Add plugin dev server\n * );\n * ```\n *\n * @example With options\n * ```typescript\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withKosConfig(webpack),\n * withPluginDevServer({\n * kosJsonPath: '.kos.json',\n * defaultContext: 'kosdev.ddk',\n * verbose: true\n * })\n * );\n * ```\n *\n * ## .kos.json Structure\n *\n * The middleware reads two sections from .kos.json:\n *\n * ```json\n * {\n * \"kos\": {\n * \"ui\": {\n * \"plugin\": {\n * \"id\": \"MyPlugin\",\n * \"extensions\": [...],\n * \"contributes\": {...}\n * }\n * }\n * },\n * \"test\": {\n * \"plugin\": {\n * \"context\": \"kosdev.ddk\"\n * }\n * }\n * }\n * ```\n *\n * - `kos.ui.plugin`: Production plugin descriptor (becomes API `descriptor`)\n * - `test.plugin.context`: Development plugin context/group name\n *\n * ## Response Format\n *\n * The middleware returns the same format as the backend `/api/kos/ui/plugins/contexts`:\n *\n * ```json\n * {\n * \"status\": 200,\n * \"version\": {\"major\": 1, \"minor\": 0},\n * \"data\": [\n * {\n * \"name\": \"kosdev.ddk\",\n * \"plugins\": [\n * {\n * \"descriptor\": { ... },\n * \"id\": \"uuid-v4\",\n * \"path\": \"/\"\n * }\n * ]\n * }\n * ]\n * }\n * ```\n *\n * @param options - Configuration options\n */\nexport const withPluginDevServer = (options: PluginDevServerOptions = {}) => {\n const {\n kosJsonPath = \".kos.json\",\n projectRoot,\n defaultContext = \"kosdev.ddk\",\n verbose = false,\n } = options;\n\n return (config: any, context: any) => {\n // Only add middleware if devServer is configured\n if (!config.devServer) {\n if (verbose) {\n console.log(\n \"[withPluginDevServer] No devServer config found, skipping middleware\"\n );\n }\n return config;\n }\n\n // Enable CORS for third-party development mode\n // This allows deployed devices/hosts to fetch plugin metadata from dev servers\n config.devServer.headers = {\n ...config.devServer.headers,\n \"Access-Control-Allow-Origin\": \"*\",\n \"Access-Control-Allow-Methods\": \"GET, POST, PUT, DELETE, PATCH, OPTIONS\",\n \"Access-Control-Allow-Headers\":\n \"X-Requested-With, content-type, Authorization\",\n };\n\n // Resolve project root from context if not provided\n // In Nx webpack configs, the context is passed as the second argument\n // We need to check several possible locations for the project path:\n // - config.context (webpack context, usually the project root) - PREFERRED\n // - context.options.root + context.options.projectRoot (Nx-specific fallback)\n let effectiveProjectRoot: string = projectRoot || process.cwd();\n\n if (!projectRoot) {\n // Try config.context first (webpack's context is usually the project directory)\n if (config?.context && typeof config.context === \"string\") {\n effectiveProjectRoot = config.context;\n }\n // If that's not available, try combining workspace root with project root\n else if (context?.options?.root && context?.options?.projectRoot) {\n effectiveProjectRoot = path.join(\n context.options.root,\n context.options.projectRoot\n );\n }\n }\n\n const resolvedKosJsonPath = path.resolve(effectiveProjectRoot, kosJsonPath);\n\n if (verbose) {\n console.log(\"[withPluginDevServer] Configuration:\", {\n kosJsonPath: resolvedKosJsonPath,\n projectRoot: effectiveProjectRoot,\n defaultContext,\n });\n }\n\n // Initialize or extend setupMiddlewares\n const originalSetupMiddlewares = config.devServer.setupMiddlewares;\n\n config.devServer.setupMiddlewares = (\n middlewares: any[],\n devServer: any\n ) => {\n // Call original setupMiddlewares if it exists\n if (originalSetupMiddlewares) {\n middlewares = originalSetupMiddlewares(middlewares, devServer);\n }\n\n // Add plugin metadata endpoint\n devServer.app.get(\n \"/api/kos/ui/plugins/contexts\",\n (_req: any, res: any) => {\n try {\n // Check if .kos.json exists\n if (!fs.existsSync(resolvedKosJsonPath)) {\n const errorMsg = `.kos.json not found at ${resolvedKosJsonPath}`;\n console.error(`[withPluginDevServer] ${errorMsg}`);\n return res.status(404).json({\n status: 404,\n error: errorMsg,\n hint: \"Ensure .kos.json exists in your plugin project root\",\n });\n }\n\n // Read and parse .kos.json\n const kosJsonContent = fs.readFileSync(\n resolvedKosJsonPath,\n \"utf-8\"\n );\n const kosJson = JSON.parse(kosJsonContent);\n\n // Extract production plugin descriptor\n const pluginDescriptor = kosJson.kos?.ui?.plugin;\n if (!pluginDescriptor) {\n const errorMsg = \"kos.ui.plugin section not found in .kos.json\";\n console.error(`[withPluginDevServer] ${errorMsg}`);\n return res.status(400).json({\n status: 400,\n error: errorMsg,\n hint: \"Ensure .kos.json has kos.ui.plugin section defined\",\n });\n }\n\n // Extract test configuration\n const testConfig = kosJson.test?.plugin;\n const pluginContext = testConfig?.context || defaultContext;\n\n // Generate deterministic UUID based on plugin ID\n // Using v4 for now, but could use v5 with plugin ID as namespace in future\n const pluginId = uuidv4();\n\n // Build backend-compatible response\n // Note: The 'path' field is just an identifier in dev mode.\n // The actual dev server URL should be provided via 'overrides' in KosPluginProvider\n const metadata = {\n status: 200,\n version: { major: 1, minor: 0 },\n data: [\n {\n name: pluginContext,\n plugins: [\n {\n descriptor: pluginDescriptor,\n id: pluginId,\n path: \"/\", // Simple identifier - actual URL comes from overrides\n },\n ],\n },\n ],\n };\n\n if (verbose) {\n console.log(\"[withPluginDevServer] Serving plugin metadata:\", {\n pluginId: pluginDescriptor.id,\n context: pluginContext,\n extensionsCount: pluginDescriptor.extensions?.length || 0,\n });\n }\n\n res.json(metadata);\n } catch (error) {\n console.error(\n \"[withPluginDevServer] Error serving plugin metadata:\",\n error\n );\n res.status(500).json({\n status: 500,\n error: \"Failed to serve plugin metadata\",\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n );\n\n if (verbose) {\n console.log(\n \"[withPluginDevServer] Plugin metadata endpoint registered at /api/kos/ui/plugins/contexts\"\n );\n }\n\n return middlewares;\n };\n\n return config;\n };\n};\n","/**\n * Multi-Plugin Development Mode Aggregation Middleware\n *\n * This webpack composable aggregates metadata from multiple plugin dev servers\n * running on different ports, combining them into a single response at the\n * `/api/kos/ui/plugins/contexts` endpoint.\n *\n * This allows a host app to load multiple plugins simultaneously during development.\n */\n\nimport { readFileSync } from \"fs\";\nimport { join } from \"path\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport interface PluginDevAggregatorOptions {\n /**\n * List of plugin dev server URLs to aggregate.\n * Example: ['http://localhost:4201', 'http://localhost:4202']\n */\n pluginServers: string[];\n\n /**\n * Include the host app's own .kos.json plugin definitions.\n * Default: true\n */\n includeHostPlugins?: boolean;\n\n /**\n * Path to the host app's .kos.json file.\n * Default: './.kos.json'\n */\n kosJsonPath?: string;\n\n /**\n * Merge backend plugins with local dev plugins.\n * When true, fetches plugins from backend and overlays local dev plugins on top.\n * Local dev plugins get overrides pointing to dev servers.\n * Backend plugins use their original URLs (no overrides).\n *\n * This is useful for third-party developers who want to:\n * - Run against a production DDK backend\n * - Load DDK base plugins from the backend\n * - Develop their own custom plugins locally\n *\n * Default: false (local-only mode)\n */\n mergeWithBackend?: boolean;\n\n /**\n * Fallback to backend if no local plugin servers are available.\n * Default: true\n */\n fallbackToBackend?: boolean;\n\n /**\n * Backend URL to fallback to when no plugin servers available.\n * Default: 'http://localhost:8081'\n */\n backendUrl?: string;\n\n /**\n * Enable verbose logging for debugging.\n * Default: false\n */\n verbose?: boolean;\n}\n\n/**\n * Webpack plugin composable that aggregates multiple plugin dev servers.\n *\n * @example\n * ```typescript\n * // Host app webpack.config.ts\n * import { withPluginDevAggregator } from '@kosdev-code/kos-ui-plugin/webpack';\n *\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withPluginDevAggregator({\n * pluginServers: [\n * 'http://localhost:4201', // beverage-pour\n * 'http://localhost:4202' // kos-ddk-standard-plugin\n * ]\n * })\n * );\n * ```\n *\n * @example With environment variables\n * ```typescript\n * const pluginServers = [\n * process.env.PLUGIN_A_DEV === 'true' && 'http://localhost:4201',\n * process.env.PLUGIN_B_DEV === 'true' && 'http://localhost:4202',\n * ].filter(Boolean);\n *\n * export default composePlugins(\n * withNx(),\n * withReact({}),\n * withPluginDevAggregator({\n * pluginServers,\n * fallbackToBackend: pluginServers.length === 0\n * })\n * );\n * ```\n */\nexport const withPluginDevAggregator = (\n options: PluginDevAggregatorOptions\n) => {\n const {\n pluginServers,\n includeHostPlugins = true,\n kosJsonPath = \".kos.json\",\n mergeWithBackend = false,\n fallbackToBackend = true,\n backendUrl = \"http://localhost:8081\",\n verbose = false,\n } = options;\n\n return (config: any, context: any) => {\n // Resolve project root from Nx context (similar to withPluginDevServer)\n let effectiveProjectRoot: string = process.cwd();\n\n if (config?.context && typeof config.context === \"string\") {\n effectiveProjectRoot = config.context;\n } else if (context?.options?.root && context?.options?.projectRoot) {\n effectiveProjectRoot = join(\n context.options.root,\n context.options.projectRoot\n );\n }\n\n const resolvedKosJsonPath = join(effectiveProjectRoot, kosJsonPath);\n\n // Only add middleware if devServer is configured\n if (!config.devServer) {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] No devServer config found, skipping middleware\"\n );\n }\n return config;\n }\n\n if (verbose) {\n console.log(\"[withPluginDevAggregator] Configuration:\", {\n pluginServers,\n fallbackToBackend,\n backendUrl,\n projectRoot: effectiveProjectRoot,\n kosJsonPath: resolvedKosJsonPath,\n });\n }\n\n // Initialize or extend setupMiddlewares\n const originalSetupMiddlewares = config.devServer.setupMiddlewares;\n\n config.devServer.setupMiddlewares = (\n middlewares: any[],\n devServer: any\n ) => {\n // Call original setupMiddlewares if it exists\n if (originalSetupMiddlewares) {\n middlewares = originalSetupMiddlewares(middlewares, devServer);\n }\n\n // Add aggregation endpoint\n devServer.app.get(\n \"/api/kos/ui/plugins/contexts\",\n async (_req: any, res: any) => {\n try {\n // If no plugin servers configured, fallback to backend\n if (pluginServers.length === 0) {\n if (fallbackToBackend) {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] No plugin servers, proxying to backend:\",\n backendUrl\n );\n }\n\n // Proxy to backend\n const backendResponse = await fetch(\n `${backendUrl}/api/kos/ui/plugins/contexts`\n );\n const backendData = await backendResponse.json();\n return res.json(backendData);\n } else {\n return res.status(404).json({\n status: 404,\n error: \"No plugin servers configured\",\n hint: \"Add plugin server URLs to withPluginDevAggregator options or enable fallbackToBackend\",\n });\n }\n }\n\n // Fetch from all plugin dev servers\n const responses = await Promise.all(\n pluginServers.map(async (serverUrl) => {\n try {\n const response = await fetch(\n `${serverUrl}/api/kos/ui/plugins/contexts`\n );\n if (!response.ok) {\n if (verbose) {\n console.warn(\n `[withPluginDevAggregator] Failed to fetch from ${serverUrl}: ${response.status}`\n );\n }\n return null;\n }\n const data = await response.json();\n return { serverUrl, data };\n } catch (error) {\n if (verbose) {\n console.warn(\n `[withPluginDevAggregator] Error fetching from ${serverUrl}:`,\n error\n );\n }\n return null;\n }\n })\n );\n\n // Filter out failed requests\n const validResponses = responses.filter(\n (r) => r && r.data && r.data.status === 200\n );\n\n // If no valid responses and fallback enabled, try backend\n if (validResponses.length === 0 && fallbackToBackend) {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] No plugin servers responded, falling back to backend\"\n );\n }\n\n try {\n const backendResponse = await fetch(\n `${backendUrl}/api/kos/ui/plugins/contexts`\n );\n const backendData = await backendResponse.json();\n return res.json(backendData);\n } catch (error) {\n return res.status(503).json({\n status: 503,\n error: \"No plugin servers available and backend unreachable\",\n details:\n error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Merge all plugin data from valid responses\n // Group by context name and merge plugins\n // Also build overrides map for dev server URLs\n const mergedData: Record<string, any[]> = {};\n const overridesMap: Record<string, string> = {};\n\n // Step 1: Fetch and include backend plugins if mergeWithBackend is enabled\n // Backend plugins are added WITHOUT overrides (use their production URLs)\n if (mergeWithBackend) {\n try {\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] Fetching backend plugins from:\",\n backendUrl\n );\n }\n\n const backendResponse = await fetch(\n `${backendUrl}/api/kos/ui/plugins/contexts`\n );\n if (backendResponse.ok) {\n const backendData = await backendResponse.json();\n\n if (backendData.status === 200 && backendData.data) {\n backendData.data.forEach((contextGroup: any) => {\n const contextName = contextGroup.name;\n if (!mergedData[contextName]) {\n mergedData[contextName] = [];\n }\n\n // Add backend plugins WITHOUT overrides\n // They will use their production URLs from the backend\n contextGroup.plugins.forEach((plugin: any) => {\n mergedData[contextName].push(plugin);\n\n if (verbose) {\n console.log(\n `[withPluginDevAggregator] Added backend plugin: ${plugin.descriptor?.id} (no override)`\n );\n }\n });\n });\n\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] Successfully merged backend plugins\"\n );\n }\n }\n } else {\n if (verbose) {\n console.warn(\n `[withPluginDevAggregator] Backend fetch failed: ${backendResponse.status}`\n );\n }\n }\n } catch (error) {\n if (verbose) {\n console.warn(\n \"[withPluginDevAggregator] Error fetching backend plugins:\",\n error\n );\n }\n }\n }\n\n // Step 2: Include host app's own plugin definitions if enabled\n if (includeHostPlugins) {\n try {\n const kosJsonContent = readFileSync(\n resolvedKosJsonPath,\n \"utf-8\"\n );\n const kosJson = JSON.parse(kosJsonContent);\n\n // Check for plugin definitions in kos.ui.plugin or kosdev.ddk.ncui.plugin\n const pluginDescriptor = kosJson.kos?.ui?.plugin;\n const ncuiPluginDescriptor = kosJson.kosdev?.ddk?.ncui?.plugin;\n\n // Determine context based on plugin type\n const contexts: Array<{\n name: string;\n plugin: { descriptor: any; id: string; path: string };\n }> = [];\n\n if (pluginDescriptor) {\n contexts.push({\n name: kosJson.test?.plugin?.context || \"kos.ui\",\n plugin: {\n descriptor: pluginDescriptor,\n id: uuidv4(),\n path: \"/\", // Host app plugins are served locally\n },\n });\n }\n\n if (ncuiPluginDescriptor) {\n contexts.push({\n name: \"kosdev.ddk\",\n plugin: {\n descriptor: ncuiPluginDescriptor,\n id: uuidv4(),\n path: \"/\", // Host app plugins are served locally\n },\n });\n }\n\n // Add host plugins to merged data\n contexts.forEach(({ name, plugin }) => {\n if (!mergedData[name]) {\n mergedData[name] = [];\n }\n mergedData[name].push(plugin);\n\n if (verbose) {\n console.log(\n `[withPluginDevAggregator] Added host plugin: ${plugin.descriptor.id} to context ${name}`\n );\n }\n });\n } catch (error) {\n if (verbose) {\n console.warn(\n \"[withPluginDevAggregator] Failed to read host .kos.json:\",\n error\n );\n }\n }\n }\n\n // Step 3: Add plugins from remote dev servers with overrides\n // Local dev plugins get overrides pointing to their dev server URLs\n validResponses.forEach((responseWrapper) => {\n if (!responseWrapper) return;\n const { serverUrl, data: response } = responseWrapper;\n\n response.data?.forEach((contextGroup: any) => {\n const contextName = contextGroup.name;\n if (!mergedData[contextName]) {\n mergedData[contextName] = [];\n }\n\n // Add plugins and build overrides for each plugin\n contextGroup.plugins.forEach((plugin: any) => {\n mergedData[contextName].push(plugin);\n // Map plugin ID to its dev server URL\n // This allows KosPluginProvider to use overrides to point to the right server\n overridesMap[plugin.id] = `${serverUrl}/`;\n\n if (verbose) {\n console.log(\n `[withPluginDevAggregator] Added local dev plugin: ${plugin.descriptor?.id} with override to ${serverUrl}/`\n );\n }\n });\n });\n });\n\n // Convert back to array format\n const aggregatedData = Object.entries(mergedData).map(\n ([name, plugins]) => ({\n name,\n plugins,\n })\n );\n\n const aggregatedResponse = {\n status: 200,\n version: { major: 1, minor: 0 },\n data: aggregatedData,\n // Include overrides map for dev mode\n // This allows the host app to pass these to KosPluginProvider\n overrides: overridesMap,\n };\n\n if (verbose) {\n console.log(\"[withPluginDevAggregator] Aggregated plugins:\", {\n contexts: aggregatedData.length,\n totalPlugins: aggregatedData.reduce(\n (sum, ctx) => sum + ctx.plugins.length,\n 0\n ),\n pluginIds: aggregatedData.flatMap((ctx) =>\n ctx.plugins.map((p: any) => p.descriptor?.id)\n ),\n overrides: overridesMap,\n });\n }\n\n res.json(aggregatedResponse);\n } catch (error) {\n console.error(\n \"[withPluginDevAggregator] Error aggregating plugins:\",\n error\n );\n res.status(500).json({\n status: 500,\n error: \"Failed to aggregate plugin metadata\",\n details: error instanceof Error ? error.message : String(error),\n });\n }\n }\n );\n\n if (verbose) {\n console.log(\n \"[withPluginDevAggregator] Plugin aggregation endpoint registered at /api/kos/ui/plugins/contexts\"\n );\n }\n\n return middlewares;\n };\n\n return config;\n };\n};\n"],"names":["fs","require$$0","path","require$$1","os","require$$2","crypto","require$$3","packageJson","require$$4","version","LINE","parse","src","obj","lines","match","key","value","maybeQuote","_parseVault","options","vaultPath","_vaultPath","result","DotenvModule","err","keys","_dotenvKey","length","decrypted","i","attrs","_instructions","error","_warn","message","_debug","_log","dotenvKey","uri","environment","environmentKey","ciphertext","possibleVaultPath","filepath","_resolveHome","envPath","_configVault","debug","quiet","parsed","processEnv","configDotenv","dotenvPath","encoding","optionPaths","lastError","parsedAll","e","keysCount","shortPaths","filePath","relative","config","decrypt","encrypted","keyStr","nonce","authTag","aesgcm","isRange","invalidKeyLength","decryptionFailed","populate","override","mainModule","config_1","getKosEnv","dotenv.config","withKosConfig","webpack","_a","withPluginDevServer","kosJsonPath","projectRoot","defaultContext","verbose","context","effectiveProjectRoot","_b","resolvedKosJsonPath","originalSetupMiddlewares","middlewares","devServer","_req","res","errorMsg","kosJsonContent","kosJson","pluginDescriptor","testConfig","_c","pluginContext","pluginId","uuidv4","metadata","_d","withPluginDevAggregator","pluginServers","includeHostPlugins","mergeWithBackend","fallbackToBackend","backendUrl","join","backendData","validResponses","serverUrl","response","data","r","mergedData","overridesMap","backendResponse","contextGroup","contextName","plugin","readFileSync","ncuiPluginDescriptor","_e","contexts","_g","_f","name","responseWrapper","aggregatedData","plugins","aggregatedResponse","sum","ctx","p"],"mappings":"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","x_google_ignoreList":[0]}