@aistrike-dev/ui-shell-dev 1.0.1 → 1.0.2

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.
@@ -0,0 +1 @@
1
+ var e=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),t=function(e,t){return new URL(e,t).href},n={},r=function(e){return e.pathname.endsWith(`.css`)},i=function(i,a,o){let s=Promise.resolve();if(a&&a.length>0){let i,c=document.querySelector(`meta[property=csp-nonce]`),l=c?.nonce||c?.getAttribute(`nonce`);function u(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function d(e){return import.meta.resolve?new URL(import.meta.resolve(e)):new URL(e,import.meta.url)}s=u(a.map(a=>{a=t(a,o);let s=d(a);if(s.href in n)return;n[s.href]=!0;let c=r(s);if(i===void 0){i={all:new Set,styles:new Set};let e=document.getElementsByTagName(`link`);for(let t=e.length-1;t>=0;t--){let n=e[t];i.all.add(n.href),n.rel===`stylesheet`&&i.styles.add(n.href)}}if((c?i.styles:i.all).has(s.href))return;let u=document.createElement(`link`);if(u.rel=c?`stylesheet`:e,c||(u.as=`script`),u.crossOrigin=``,u.href=s.href,l&&u.setAttribute(`nonce`,l),document.head.appendChild(u),c)return new Promise((e,t)=>{u.addEventListener(`load`,e),u.addEventListener(`error`,()=>t(Error(`Unable to preload CSS for ${s}`)))})}).filter(e=>e!==void 0))}function c(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return s.then(e=>{for(let t of e||[])t.status===`rejected`&&c(t.reason);return i().catch(c)})},a=()=>{let e,t=0;return{async mount(n){t+=1;let r=t;e?.(),e=void 0;let{mountUi:a}=await i(async()=>{let{mountUi:e}=await import(`./chunks/ui-DCccj5l0.js`);return{mountUi:e}},[],import.meta.url);r===t&&(e=a(n))},unmount(){t+=1,e?.(),e=void 0}}};export{a as activate};
@@ -0,0 +1,6 @@
1
+ {
2
+ "contract": "1",
3
+ "id": "home",
4
+ "version": "0.1.0",
5
+ "entry": "./entry.js"
6
+ }
@@ -0,0 +1,14 @@
1
+ [
2
+ {
3
+ "id": "assistant",
4
+ "devPort": 5104
5
+ },
6
+ {
7
+ "id": "settings",
8
+ "devPort": 5101
9
+ },
10
+ {
11
+ "id": "home",
12
+ "devPort": 5102
13
+ }
14
+ ]
@@ -0,0 +1,149 @@
1
+ //#region src/mock/brandHandler.ts
2
+ var HEX = /^#[0-9a-f]{6}$/i;
3
+ var PATH = /^\/api\/brand\/(organisation|tenant)\/([^/]+)$/;
4
+ function isRecord(body) {
5
+ if (typeof body !== "object" || body === null) return false;
6
+ const { colors, allowPersonal } = body;
7
+ if (typeof allowPersonal !== "boolean" || typeof colors !== "object" || colors === null) return false;
8
+ const { accent, fields, line } = colors;
9
+ const isHex = (v) => typeof v === "string" && HEX.test(v);
10
+ return isHex(accent) && isHex(line) && Array.isArray(fields) && fields.length === 5 && fields.every(isHex);
11
+ }
12
+ async function readBody$1(req) {
13
+ const chunks = [];
14
+ for await (const chunk of req) chunks.push(chunk);
15
+ try {
16
+ return JSON.parse(Buffer.concat(chunks).toString("utf8"));
17
+ } catch {
18
+ return;
19
+ }
20
+ }
21
+ /**
22
+ * In-memory `/api/brand/<organisation|tenant>/<id>` for local development. Returns false when the request is not for it.
23
+ *
24
+ * This mock accepts any bearer token. The real brand API must enforce `settings:brand` on PUT and DELETE, and
25
+ * membership of the organisation or tenant on GET.
26
+ */
27
+ function createBrandHandler(initial = {}) {
28
+ const records = new Map(Object.entries(initial));
29
+ const send = (res, status, body) => {
30
+ res.statusCode = status;
31
+ if (body !== void 0) res.setHeader("Content-Type", "application/json");
32
+ res.end(body === void 0 ? void 0 : JSON.stringify(body));
33
+ };
34
+ const handlePut = (req, res, key) => {
35
+ if (!/^application\/json\b/.test(req.headers["content-type"] ?? "")) {
36
+ send(res, 415, { error: "send JSON" });
37
+ return;
38
+ }
39
+ readBody$1(req).then((body) => {
40
+ if (!isRecord(body)) {
41
+ send(res, 400, { error: "a brand record is seven #RRGGBB colours and an allowPersonal boolean" });
42
+ return;
43
+ }
44
+ const record = {
45
+ colors: body.colors,
46
+ allowPersonal: body.allowPersonal
47
+ };
48
+ records.set(key, record);
49
+ send(res, 200, record);
50
+ }).catch(() => {
51
+ send(res, 500, { error: "internal error" });
52
+ });
53
+ };
54
+ const handle = (req, res, key) => {
55
+ if (req.method === "GET") {
56
+ const record = records.get(key);
57
+ if (record === void 0) send(res, 404, { error: "no brand" });
58
+ else send(res, 200, record);
59
+ } else if (req.method === "DELETE") {
60
+ records.delete(key);
61
+ send(res, 204);
62
+ } else if (req.method === "PUT") handlePut(req, res, key);
63
+ else send(res, 405, { error: "method not allowed" });
64
+ };
65
+ return (req, res) => {
66
+ const match = PATH.exec((req.url ?? "").split("?")[0]);
67
+ if (match === null) return false;
68
+ const key = `${match[1]}/${decodeURIComponent(match[2])}`;
69
+ if (!/^Bearer\s+\S+/.test(req.headers.authorization ?? "")) {
70
+ send(res, 401, { error: "unauthorized" });
71
+ return true;
72
+ }
73
+ handle(req, res, key);
74
+ return true;
75
+ };
76
+ }
77
+ //#endregion
78
+ //#region src/mock/profileHandler.ts
79
+ var MAX_LENGTH = 80;
80
+ function isValid(body) {
81
+ if (typeof body !== "object" || body === null) return false;
82
+ const { displayName, jobTitle } = body;
83
+ return [displayName, jobTitle].every((v) => typeof v === "string" && v.length <= MAX_LENGTH);
84
+ }
85
+ async function readBody(req) {
86
+ const chunks = [];
87
+ for await (const chunk of req) chunks.push(chunk);
88
+ try {
89
+ return JSON.parse(Buffer.concat(chunks).toString("utf8"));
90
+ } catch {
91
+ return;
92
+ }
93
+ }
94
+ /**
95
+ * In-memory `/api/profile` for local development. Returns false when the request is not for it.
96
+ *
97
+ * This mock accepts any bearer token; the real profile API must enforce `settings:write` server-side for PUT.
98
+ */
99
+ function createProfileHandler(initial = {
100
+ displayName: "",
101
+ jobTitle: ""
102
+ }) {
103
+ let profile = { ...initial };
104
+ const send = (res, status, body) => {
105
+ res.statusCode = status;
106
+ if (body !== void 0) res.setHeader("Content-Type", "application/json");
107
+ res.end(body === void 0 ? void 0 : JSON.stringify(body));
108
+ };
109
+ return (req, res) => {
110
+ if ((req.url ?? "").split("?")[0] !== "/api/profile") return false;
111
+ if (!/^Bearer\s+\S+/.test(req.headers.authorization ?? "")) {
112
+ send(res, 401, { error: "unauthorized" });
113
+ return true;
114
+ }
115
+ if (req.method === "GET") {
116
+ send(res, 200, profile);
117
+ return true;
118
+ }
119
+ if (req.method === "PUT") {
120
+ readBody(req).then((body) => {
121
+ if (!isValid(body)) {
122
+ send(res, 400, { error: `displayName and jobTitle must be strings of at most ${String(MAX_LENGTH)} characters` });
123
+ return;
124
+ }
125
+ profile = {
126
+ displayName: body.displayName,
127
+ jobTitle: body.jobTitle
128
+ };
129
+ send(res, 200, profile);
130
+ }).catch(() => {
131
+ send(res, 500, { error: "internal error" });
132
+ });
133
+ return true;
134
+ }
135
+ send(res, 405, { error: "method not allowed" });
136
+ return true;
137
+ };
138
+ }
139
+ //#endregion
140
+ //#region src/mock/index.ts
141
+ /**
142
+ * The in-memory profile and brand APIs, fresh state per call. The MFE's own dev server and the dev host's bundled copy
143
+ * (`@aistrike-dev/ui-shell-dev`, which loads the build of this file) both run them. Never part of the MFE's build.
144
+ */
145
+ function createMockHandlers() {
146
+ return [createProfileHandler(), createBrandHandler()];
147
+ }
148
+ //#endregion
149
+ export { createMockHandlers };
@@ -0,0 +1 @@
1
+ var e=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),t=function(e,t){return new URL(e,t).href},n={},r=function(e){return e.pathname.endsWith(`.css`)},i=function(i,a,o){let s=Promise.resolve();if(a&&a.length>0){let i,c=document.querySelector(`meta[property=csp-nonce]`),l=c?.nonce||c?.getAttribute(`nonce`);function u(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function d(e){return import.meta.resolve?new URL(import.meta.resolve(e)):new URL(e,import.meta.url)}s=u(a.map(a=>{a=t(a,o);let s=d(a);if(s.href in n)return;n[s.href]=!0;let c=r(s);if(i===void 0){i={all:new Set,styles:new Set};let e=document.getElementsByTagName(`link`);for(let t=e.length-1;t>=0;t--){let n=e[t];i.all.add(n.href),n.rel===`stylesheet`&&i.styles.add(n.href)}}if((c?i.styles:i.all).has(s.href))return;let u=document.createElement(`link`);if(u.rel=c?`stylesheet`:e,c||(u.as=`script`),u.crossOrigin=``,u.href=s.href,l&&u.setAttribute(`nonce`,l),document.head.appendChild(u),c)return new Promise((e,t)=>{u.addEventListener(`load`,e),u.addEventListener(`error`,()=>t(Error(`Unable to preload CSS for ${s}`)))})}).filter(e=>e!==void 0))}function c(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return s.then(e=>{for(let t of e||[])t.status===`rejected`&&c(t.reason);return i().catch(c)})};export{i as t};