@blinkk/root-cms 1.0.0-alpha.27 → 1.0.0-alpha.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/app.js ADDED
@@ -0,0 +1,111 @@
1
+ // core/app.tsx
2
+ import { render as renderToString } from "preact-render-to-string";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { initializeApp } from "firebase-admin/app";
6
+ import { getAuth } from "firebase-admin/auth";
7
+ import { jsx, jsxs } from "preact/jsx-runtime";
8
+ var __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ var uiCssPath = path.join(__dirname, "ui.css");
10
+ var uiJsPath = path.join(__dirname, "ui.js");
11
+ function App(props) {
12
+ return /* @__PURE__ */ jsxs("html", {
13
+ children: [
14
+ /* @__PURE__ */ jsxs("head", {
15
+ children: [
16
+ /* @__PURE__ */ jsx("title", {
17
+ children: props.title
18
+ }),
19
+ /* @__PURE__ */ jsx("link", {
20
+ rel: "preconnect",
21
+ href: "https://fonts.googleapis.com"
22
+ }),
23
+ /* @__PURE__ */ jsx("link", {
24
+ rel: "preconnect",
25
+ href: "https://fonts.gstatic.com",
26
+ crossOrigin: "anonymous"
27
+ }),
28
+ /* @__PURE__ */ jsx("link", {
29
+ rel: "stylesheet",
30
+ href: "https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;900&display=swap"
31
+ }),
32
+ /* @__PURE__ */ jsx("link", {
33
+ rel: "stylesheet",
34
+ href: `/@fs${uiCssPath}`
35
+ })
36
+ ]
37
+ }),
38
+ /* @__PURE__ */ jsxs("body", {
39
+ children: [
40
+ /* @__PURE__ */ jsx("div", {
41
+ id: "root",
42
+ children: /* @__PURE__ */ jsxs("div", {
43
+ className: "bootstrap",
44
+ children: [
45
+ /* @__PURE__ */ jsx("h1", {
46
+ className: "bootstrap__loading",
47
+ children: "Loading..."
48
+ }),
49
+ /* @__PURE__ */ jsx("div", {
50
+ className: "bootstrap-error",
51
+ children: "If the CMS fails to load, try a force refresh by holding the shift key while refreshing the page."
52
+ })
53
+ ]
54
+ })
55
+ }),
56
+ /* @__PURE__ */ jsx("script", {
57
+ dangerouslySetInnerHTML: {
58
+ __html: `window.__ROOT_CTX = ${JSON.stringify(props.ctx)}`
59
+ }
60
+ }),
61
+ /* @__PURE__ */ jsx("script", {
62
+ type: "module",
63
+ src: `/@fs${uiJsPath}`
64
+ })
65
+ ]
66
+ })
67
+ ]
68
+ });
69
+ }
70
+ async function render(req, res) {
71
+ if (!req.user || !req.user.jwt) {
72
+ throw new Error("not logged in");
73
+ }
74
+ const email = req.user.jwt.email;
75
+ const uid = req.user.jwt.uid;
76
+ const app = initializeApp();
77
+ const auth = getAuth();
78
+ const customToken = await auth.createCustomToken(uid);
79
+ const { uid: firebaseUid } = await auth.verifyIdToken(customToken);
80
+ const token = await auth.createCustomToken(firebaseUid);
81
+ console.log("custom firebase auth token:");
82
+ console.log(token);
83
+ const collectionModules = import.meta.glob("/collections/*.schema.ts", {
84
+ eager: true
85
+ });
86
+ const collections = Object.values(collectionModules).map(
87
+ (module) => module.default
88
+ );
89
+ const ctx = {
90
+ user: {
91
+ email,
92
+ jwt: token
93
+ },
94
+ collections
95
+ };
96
+ const mainHtml = renderToString(/* @__PURE__ */ jsx(App, {
97
+ title: "Root.js CMS",
98
+ ctx
99
+ }));
100
+ const html = await req.viteServer.transformIndexHtml(
101
+ req.originalUrl,
102
+ `<!doctype html>
103
+ ${mainHtml}`
104
+ );
105
+ res.setHeader("Content-Type", "text/html");
106
+ res.send(html);
107
+ }
108
+ export {
109
+ render
110
+ };
111
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vY29yZS9hcHAudHN4Il0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQge1Jlc3BvbnNlfSBmcm9tICdAYmxpbmtrL3Jvb3QnO1xuaW1wb3J0IHtDb2xsZWN0aW9ufSBmcm9tICcuL3NjaGVtYS5qcyc7XG5pbXBvcnQge1VzZXJSZXF1ZXN0fSBmcm9tICcuL3VzZXJzLmpzJztcbmltcG9ydCB7cmVuZGVyIGFzIHJlbmRlclRvU3RyaW5nfSBmcm9tICdwcmVhY3QtcmVuZGVyLXRvLXN0cmluZyc7XG5pbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHtmaWxlVVJMVG9QYXRofSBmcm9tICdub2RlOnVybCc7XG5pbXBvcnQge2luaXRpYWxpemVBcHB9IGZyb20gJ2ZpcmViYXNlLWFkbWluL2FwcCc7XG5pbXBvcnQge2dldEF1dGh9IGZyb20gJ2ZpcmViYXNlLWFkbWluL2F1dGgnO1xuXG5jb25zdCBfX2Rpcm5hbWUgPSBwYXRoLmRpcm5hbWUoZmlsZVVSTFRvUGF0aChpbXBvcnQubWV0YS51cmwpKTtcbmNvbnN0IHVpQ3NzUGF0aCA9IHBhdGguam9pbihfX2Rpcm5hbWUsICd1aS5jc3MnKTtcbmNvbnN0IHVpSnNQYXRoID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJ3VpLmpzJyk7XG5cbmludGVyZmFjZSBBcHBQcm9wcyB7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIGN0eDogYW55O1xufVxuXG5mdW5jdGlvbiBBcHAocHJvcHM6IEFwcFByb3BzKSB7XG4gIHJldHVybiAoXG4gICAgPGh0bWw+XG4gICAgICA8aGVhZD5cbiAgICAgICAgPHRpdGxlPntwcm9wcy50aXRsZX08L3RpdGxlPlxuICAgICAgICA8bGluayByZWw9XCJwcmVjb25uZWN0XCIgaHJlZj1cImh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb21cIiAvPlxuICAgICAgICA8bGlua1xuICAgICAgICAgIHJlbD1cInByZWNvbm5lY3RcIlxuICAgICAgICAgIGhyZWY9XCJodHRwczovL2ZvbnRzLmdzdGF0aWMuY29tXCJcbiAgICAgICAgICBjcm9zc09yaWdpbj1cImFub255bW91c1wiXG4gICAgICAgIC8+XG4gICAgICAgIDxsaW5rXG4gICAgICAgICAgcmVsPVwic3R5bGVzaGVldFwiXG4gICAgICAgICAgaHJlZj1cImh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzMj9mYW1pbHk9SW50ZXI6d2dodEAzMDA7NDAwOzUwMDs2MDA7NzAwOzkwMCZkaXNwbGF5PXN3YXBcIlxuICAgICAgICAvPlxuICAgICAgICA8bGluayByZWw9XCJzdHlsZXNoZWV0XCIgaHJlZj17YC9AZnMke3VpQ3NzUGF0aH1gfSAvPlxuICAgICAgPC9oZWFkPlxuICAgICAgPGJvZHk+XG4gICAgICAgIDxkaXYgaWQ9XCJyb290XCI+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJib290c3RyYXBcIj5cbiAgICAgICAgICAgIDxoMSBjbGFzc05hbWU9XCJib290c3RyYXBfX2xvYWRpbmdcIj5Mb2FkaW5nLi4uPC9oMT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYm9vdHN0cmFwLWVycm9yXCI+XG4gICAgICAgICAgICAgIElmIHRoZSBDTVMgZmFpbHMgdG8gbG9hZCwgdHJ5IGEgZm9yY2UgcmVmcmVzaCBieSBob2xkaW5nIHRoZSBzaGlmdFxuICAgICAgICAgICAgICBrZXkgd2hpbGUgcmVmcmVzaGluZyB0aGUgcGFnZS5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPHNjcmlwdFxuICAgICAgICAgIGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MPXt7XG4gICAgICAgICAgICBfX2h0bWw6IGB3aW5kb3cuX19ST09UX0NUWCA9ICR7SlNPTi5zdHJpbmdpZnkocHJvcHMuY3R4KX1gLFxuICAgICAgICAgIH19XG4gICAgICAgIC8+XG4gICAgICAgIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiIHNyYz17YC9AZnMke3VpSnNQYXRofWB9Pjwvc2NyaXB0PlxuICAgICAgPC9ib2R5PlxuICAgIDwvaHRtbD5cbiAgKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlbmRlcihyZXE6IFVzZXJSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSB7XG4gIGlmICghcmVxLnVzZXIgfHwgIXJlcS51c2VyLmp3dCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbm90IGxvZ2dlZCBpbicpO1xuICB9XG5cbiAgY29uc3QgZW1haWwgPSByZXEudXNlci5qd3QuZW1haWw7XG4gIGNvbnN0IHVpZCA9IHJlcS51c2VyLmp3dC51aWQ7XG5cbiAgY29uc3QgYXBwID0gaW5pdGlhbGl6ZUFwcCgpO1xuICBjb25zdCBhdXRoID0gZ2V0QXV0aCgpO1xuICAvLyBDcmVhdGUgYSBGaXJlYmFzZSBjdXN0b20gdG9rZW4gZm9yIHRoZSB1c2VyXG4gIGNvbnN0IGN1c3RvbVRva2VuID0gYXdhaXQgYXV0aC5jcmVhdGVDdXN0b21Ub2tlbih1aWQpO1xuICAvLyBFeGNoYW5nZSB0aGUgRmlyZWJhc2UgY3VzdG9tIHRva2VuIGZvciBhIEZpcmViYXNlIEF1dGggSldUXG4gIGNvbnN0IHt1aWQ6IGZpcmViYXNlVWlkfSA9IGF3YWl0IGF1dGgudmVyaWZ5SWRUb2tlbihjdXN0b21Ub2tlbik7XG4gIGNvbnN0IHRva2VuID0gYXdhaXQgYXV0aC5jcmVhdGVDdXN0b21Ub2tlbihmaXJlYmFzZVVpZCk7XG4gIGNvbnNvbGUubG9nKCdjdXN0b20gZmlyZWJhc2UgYXV0aCB0b2tlbjonKTtcbiAgY29uc29sZS5sb2codG9rZW4pO1xuXG4gIGNvbnN0IGNvbGxlY3Rpb25Nb2R1bGVzID0gaW1wb3J0Lm1ldGEuZ2xvYignL2NvbGxlY3Rpb25zLyouc2NoZW1hLnRzJywge1xuICAgIGVhZ2VyOiB0cnVlLFxuICB9KSBhcyBhbnk7XG4gIGNvbnN0IGNvbGxlY3Rpb25zID0gT2JqZWN0LnZhbHVlcyhjb2xsZWN0aW9uTW9kdWxlcykubWFwKFxuICAgIChtb2R1bGU6IGFueSkgPT4gbW9kdWxlLmRlZmF1bHQgYXMgQ29sbGVjdGlvblxuICApO1xuICBjb25zdCBjdHggPSB7XG4gICAgdXNlcjoge1xuICAgICAgZW1haWw6IGVtYWlsLFxuICAgICAgand0OiB0b2tlbixcbiAgICB9LFxuICAgIGNvbGxlY3Rpb25zOiBjb2xsZWN0aW9ucyxcbiAgfTtcbiAgY29uc3QgbWFpbkh0bWwgPSByZW5kZXJUb1N0cmluZyg8QXBwIHRpdGxlPVwiUm9vdC5qcyBDTVNcIiBjdHg9e2N0eH0gLz4pO1xuICBjb25zdCBodG1sID0gYXdhaXQgcmVxLnZpdGVTZXJ2ZXIhLnRyYW5zZm9ybUluZGV4SHRtbChcbiAgICByZXEub3JpZ2luYWxVcmwsXG4gICAgYDwhZG9jdHlwZSBodG1sPlxcbiR7bWFpbkh0bWx9YFxuICApO1xuICByZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAndGV4dC9odG1sJyk7XG4gIHJlcy5zZW5kKGh0bWwpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUdBLFNBQVEsVUFBVSxzQkFBcUI7QUFDdkMsT0FBTyxVQUFVO0FBQ2pCLFNBQVEscUJBQW9CO0FBQzVCLFNBQVEscUJBQW9CO0FBQzVCLFNBQVEsZUFBYztBQWNoQixTQUNFLEtBREY7QUFaTixJQUFNLFlBQVksS0FBSyxRQUFRLGNBQWMsWUFBWSxHQUFHLENBQUM7QUFDN0QsSUFBTSxZQUFZLEtBQUssS0FBSyxXQUFXLFFBQVE7QUFDL0MsSUFBTSxXQUFXLEtBQUssS0FBSyxXQUFXLE9BQU87QUFPN0MsU0FBUyxJQUFJLE9BQWlCO0FBQzVCLFNBQ0UscUJBQUM7QUFBQSxJQUNDO0FBQUEsMkJBQUM7QUFBQSxRQUNDO0FBQUEsOEJBQUM7QUFBQSxZQUFPLGdCQUFNO0FBQUEsV0FBTTtBQUFBLFVBQ3BCLG9CQUFDO0FBQUEsWUFBSyxLQUFJO0FBQUEsWUFBYSxNQUFLO0FBQUEsV0FBK0I7QUFBQSxVQUMzRCxvQkFBQztBQUFBLFlBQ0MsS0FBSTtBQUFBLFlBQ0osTUFBSztBQUFBLFlBQ0wsYUFBWTtBQUFBLFdBQ2Q7QUFBQSxVQUNBLG9CQUFDO0FBQUEsWUFDQyxLQUFJO0FBQUEsWUFDSixNQUFLO0FBQUEsV0FDUDtBQUFBLFVBQ0Esb0JBQUM7QUFBQSxZQUFLLEtBQUk7QUFBQSxZQUFhLE1BQU0sT0FBTztBQUFBLFdBQWE7QUFBQTtBQUFBLE9BQ25EO0FBQUEsTUFDQSxxQkFBQztBQUFBLFFBQ0M7QUFBQSw4QkFBQztBQUFBLFlBQUksSUFBRztBQUFBLFlBQ04sK0JBQUM7QUFBQSxjQUFJLFdBQVU7QUFBQSxjQUNiO0FBQUEsb0NBQUM7QUFBQSxrQkFBRyxXQUFVO0FBQUEsa0JBQXFCO0FBQUEsaUJBQVU7QUFBQSxnQkFDN0Msb0JBQUM7QUFBQSxrQkFBSSxXQUFVO0FBQUEsa0JBQWtCO0FBQUEsaUJBR2pDO0FBQUE7QUFBQSxhQUNGO0FBQUEsV0FDRjtBQUFBLFVBQ0Esb0JBQUM7QUFBQSxZQUNDLHlCQUF5QjtBQUFBLGNBQ3ZCLFFBQVEsdUJBQXVCLEtBQUssVUFBVSxNQUFNLEdBQUc7QUFBQSxZQUN6RDtBQUFBLFdBQ0Y7QUFBQSxVQUNBLG9CQUFDO0FBQUEsWUFBTyxNQUFLO0FBQUEsWUFBUyxLQUFLLE9BQU87QUFBQSxXQUFZO0FBQUE7QUFBQSxPQUNoRDtBQUFBO0FBQUEsR0FDRjtBQUVKO0FBRUEsZUFBc0IsT0FBTyxLQUFrQixLQUFlO0FBQzVELE1BQUksQ0FBQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLEtBQUssS0FBSztBQUM5QixVQUFNLElBQUksTUFBTSxlQUFlO0FBQUEsRUFDakM7QUFFQSxRQUFNLFFBQVEsSUFBSSxLQUFLLElBQUk7QUFDM0IsUUFBTSxNQUFNLElBQUksS0FBSyxJQUFJO0FBRXpCLFFBQU0sTUFBTSxjQUFjO0FBQzFCLFFBQU0sT0FBTyxRQUFRO0FBRXJCLFFBQU0sY0FBYyxNQUFNLEtBQUssa0JBQWtCLEdBQUc7QUFFcEQsUUFBTSxFQUFDLEtBQUssWUFBVyxJQUFJLE1BQU0sS0FBSyxjQUFjLFdBQVc7QUFDL0QsUUFBTSxRQUFRLE1BQU0sS0FBSyxrQkFBa0IsV0FBVztBQUN0RCxVQUFRLElBQUksNkJBQTZCO0FBQ3pDLFVBQVEsSUFBSSxLQUFLO0FBRWpCLFFBQU0sb0JBQW9CLFlBQVksS0FBSyw0QkFBNEI7QUFBQSxJQUNyRSxPQUFPO0FBQUEsRUFDVCxDQUFDO0FBQ0QsUUFBTSxjQUFjLE9BQU8sT0FBTyxpQkFBaUIsRUFBRTtBQUFBLElBQ25ELENBQUMsV0FBZ0IsT0FBTztBQUFBLEVBQzFCO0FBQ0EsUUFBTSxNQUFNO0FBQUEsSUFDVixNQUFNO0FBQUEsTUFDSjtBQUFBLE1BQ0EsS0FBSztBQUFBLElBQ1A7QUFBQSxJQUNBO0FBQUEsRUFDRjtBQUNBLFFBQU0sV0FBVyxlQUFlLG9CQUFDO0FBQUEsSUFBSSxPQUFNO0FBQUEsSUFBYztBQUFBLEdBQVUsQ0FBRTtBQUNyRSxRQUFNLE9BQU8sTUFBTSxJQUFJLFdBQVk7QUFBQSxJQUNqQyxJQUFJO0FBQUEsSUFDSjtBQUFBLEVBQW9CO0FBQUEsRUFDdEI7QUFDQSxNQUFJLFVBQVUsZ0JBQWdCLFdBQVc7QUFDekMsTUFBSSxLQUFLLElBQUk7QUFDZjsiLAogICJuYW1lcyI6IFtdCn0K
package/dist/core.js ADDED
@@ -0,0 +1,70 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // core/schema.ts
8
+ var schema_exports = {};
9
+ __export(schema_exports, {
10
+ array: () => array,
11
+ boolean: () => boolean,
12
+ collection: () => collection,
13
+ date: () => date,
14
+ datetime: () => datetime,
15
+ define: () => define,
16
+ defineCollection: () => defineCollection,
17
+ defineSchema: () => defineSchema,
18
+ image: () => image,
19
+ multiselect: () => multiselect,
20
+ number: () => number,
21
+ object: () => object,
22
+ oneOf: () => oneOf,
23
+ select: () => select,
24
+ string: () => string
25
+ });
26
+ function string(field) {
27
+ return { ...field, type: "string" };
28
+ }
29
+ function number(field) {
30
+ return { ...field, type: "number" };
31
+ }
32
+ function date(field) {
33
+ return { ...field, type: "date" };
34
+ }
35
+ function datetime(field) {
36
+ return { ...field, type: "datetime" };
37
+ }
38
+ function boolean(field) {
39
+ return { ...field, type: "boolean" };
40
+ }
41
+ function select(field) {
42
+ return { ...field, type: "select" };
43
+ }
44
+ function multiselect(field) {
45
+ return { ...field, type: "multiselect" };
46
+ }
47
+ function image(field) {
48
+ return { ...field, type: "image" };
49
+ }
50
+ function object(field) {
51
+ return { ...field, type: "object" };
52
+ }
53
+ function array(field) {
54
+ return { ...field, type: "array" };
55
+ }
56
+ function oneOf(field) {
57
+ return { ...field, type: "oneof" };
58
+ }
59
+ function defineSchema(schema) {
60
+ return schema;
61
+ }
62
+ var define = defineSchema;
63
+ function defineCollection(collection2) {
64
+ return collection2;
65
+ }
66
+ var collection = defineCollection;
67
+ export {
68
+ schema_exports as schema
69
+ };
70
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vY29yZS9zY2hlbWEudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImltcG9ydCB7RnVuY3Rpb25hbENvbXBvbmVudH0gZnJvbSAncHJlYWN0JztcblxuZXhwb3J0IGludGVyZmFjZSBDb21tb25GaWVsZFByb3BzIHtcbiAgaWQ/OiBzdHJpbmc7XG4gIGxhYmVsPzogc3RyaW5nO1xuICBoZWxwPzogc3RyaW5nO1xuICB0eXBlOiBzdHJpbmc7XG4gIGRlZmF1bHQ/OiBhbnk7XG4gIGhpZGRlbj86IGJvb2xlYW47XG4gIGRlcHJlY2F0ZWQ/OiBib29sZWFuO1xufVxuXG5leHBvcnQgdHlwZSBTdHJpbmdGaWVsZCA9IENvbW1vbkZpZWxkUHJvcHMgJiB7XG4gIHR5cGU6ICdzdHJpbmcnO1xuICBkZWZhdWx0Pzogc3RyaW5nO1xuICB0cmFuc2xhdGU/OiBib29sZWFuO1xuICB2YXJpYW50PzogJ2lucHV0JyB8ICd0ZXh0YXJlYSc7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gc3RyaW5nKGZpZWxkOiBPbWl0PFN0cmluZ0ZpZWxkLCAndHlwZSc+KTogU3RyaW5nRmllbGQge1xuICByZXR1cm4gey4uLmZpZWxkLCB0eXBlOiAnc3RyaW5nJ307XG59XG5cbmV4cG9ydCB0eXBlIE51bWJlckZpZWxkID0gQ29tbW9uRmllbGRQcm9wcyAmIHtcbiAgdHlwZTogJ251bWJlcic7XG4gIGRlZmF1bHQ/OiBudW1iZXI7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gbnVtYmVyKGZpZWxkOiBPbWl0PE51bWJlckZpZWxkLCAndHlwZSc+KTogTnVtYmVyRmllbGQge1xuICByZXR1cm4gey4uLmZpZWxkLCB0eXBlOiAnbnVtYmVyJ307XG59XG5cbmV4cG9ydCB0eXBlIERhdGVGaWVsZCA9IENvbW1vbkZpZWxkUHJvcHMgJiB7XG4gIHR5cGU6ICdkYXRlJztcbiAgZGVmYXVsdD86IHN0cmluZztcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBkYXRlKGZpZWxkOiBPbWl0PERhdGVGaWVsZCwgJ3R5cGUnPik6IERhdGVGaWVsZCB7XG4gIHJldHVybiB7Li4uZmllbGQsIHR5cGU6ICdkYXRlJ307XG59XG5cbmV4cG9ydCB0eXBlIERhdGVUaW1lRmllbGQgPSBDb21tb25GaWVsZFByb3BzICYge1xuICB0eXBlOiAnZGF0ZXRpbWUnO1xuICBkZWZhdWx0Pzogc3RyaW5nO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGRhdGV0aW1lKGZpZWxkOiBPbWl0PERhdGVUaW1lRmllbGQsICd0eXBlJz4pOiBEYXRlVGltZUZpZWxkIHtcbiAgcmV0dXJuIHsuLi5maWVsZCwgdHlwZTogJ2RhdGV0aW1lJ307XG59XG5cbmV4cG9ydCB0eXBlIEJvb2xlYW5GaWVsZCA9IENvbW1vbkZpZWxkUHJvcHMgJiB7XG4gIHR5cGU6ICdib29sZWFuJztcbiAgZGVmYXVsdD86IGJvb2xlYW47XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gYm9vbGVhbihmaWVsZDogT21pdDxCb29sZWFuRmllbGQsICd0eXBlJz4pOiBCb29sZWFuRmllbGQge1xuICByZXR1cm4gey4uLmZpZWxkLCB0eXBlOiAnYm9vbGVhbid9O1xufVxuXG5leHBvcnQgdHlwZSBTZWxlY3RGaWVsZCA9IENvbW1vbkZpZWxkUHJvcHMgJiB7XG4gIHR5cGU6ICdzZWxlY3QnO1xuICBkZWZhdWx0Pzogc3RyaW5nO1xuICBvcHRpb25zPzoge1xuICAgIHZhbHVlcz86IEFycmF5PHt2YWx1ZTogc3RyaW5nOyBsYWJlbD86IHN0cmluZ30+O1xuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHNlbGVjdChmaWVsZDogT21pdDxTZWxlY3RGaWVsZCwgJ3R5cGUnPik6IFNlbGVjdEZpZWxkIHtcbiAgcmV0dXJuIHsuLi5maWVsZCwgdHlwZTogJ3NlbGVjdCd9O1xufVxuXG5leHBvcnQgdHlwZSBNdWx0aVNlbGVjdEZpZWxkID0gT21pdDxTZWxlY3RGaWVsZCwgJ3R5cGUnPiAmIHtcbiAgdHlwZTogJ211bHRpc2VsZWN0JztcbiAgZGVmYXVsdD86IHN0cmluZ1tdO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG11bHRpc2VsZWN0KFxuICBmaWVsZDogT21pdDxNdWx0aVNlbGVjdEZpZWxkLCAndHlwZSc+XG4pOiBNdWx0aVNlbGVjdEZpZWxkIHtcbiAgcmV0dXJuIHsuLi5maWVsZCwgdHlwZTogJ211bHRpc2VsZWN0J307XG59XG5cbmV4cG9ydCB0eXBlIEltYWdlRmllbGQgPSBDb21tb25GaWVsZFByb3BzICYge1xuICB0eXBlOiAnaW1hZ2UnO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGltYWdlKGZpZWxkOiBPbWl0PEltYWdlRmllbGQsICd0eXBlJz4pOiBJbWFnZUZpZWxkIHtcbiAgcmV0dXJuIHsuLi5maWVsZCwgdHlwZTogJ2ltYWdlJ307XG59XG5cbmV4cG9ydCB0eXBlIE9iamVjdEZpZWxkID0gQ29tbW9uRmllbGRQcm9wcyAmIHtcbiAgdHlwZTogJ29iamVjdCc7XG4gIGZpZWxkczogRmllbGRXaXRoSWRbXTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBvYmplY3QoZmllbGQ6IE9taXQ8T2JqZWN0RmllbGQsICd0eXBlJz4pOiBPYmplY3RGaWVsZCB7XG4gIHJldHVybiB7Li4uZmllbGQsIHR5cGU6ICdvYmplY3QnfTtcbn1cblxuZXhwb3J0IHR5cGUgQXJyYXlGaWVsZCA9IENvbW1vbkZpZWxkUHJvcHMgJiB7XG4gIHR5cGU6ICdhcnJheSc7XG4gIGRlZmF1bHQ/OiBBcnJheTxhbnk+O1xuICBwcmV2aWV3PzogKHZhbHVlOiBhbnkpID0+IHN0cmluZztcbiAgLy8gTk9URShzdGV2ZW5sZSk6IHRoZSBhcnJheSBmaWVsZCBzaG91bGQgb25seSBhY2NlcHQgb2JqZWN0IHZhbHVlcyB0byBrZWVwXG4gIC8vIHRoZSBzY2hlbWFzIGZ1dHVyZS1mcmllbmRseS4gRm9yIGV4YW1wbGUsIGlmIHdlIHdlcmUgdG8gYWNjZXB0IHByaW1hdGl2ZXNcbiAgLy8gKGUuZy4gQXJyYXk8c3RyaW5nPikgYW5kIHRoZSBkZXZlbG9wZXIgZGVjaWRlcyBpbiB0aGUgZnV0dXJlIHRoYXQgdGhleVxuICAvLyBuZWVkIHRvIGFkZCBleHRyYSBmaWVsZHMgdG8gdGhhdCBhcnJheSB0eXBlLCB0aGV5IHdvdWxkIGhhdmUgdG8gY3JlYXRlIGFcbiAgLy8gbmV3IGZpZWxkLCBjcmVhdGUgYSBuZXcgc2NoZW1hIGZpZWxkLCBhbmQgdGhlbiBwZXJmb3JtIGEgZGIgbWlncmF0aW9uIHRvXG4gIC8vIHVwZGF0ZSBmcm9tIHRoZSBvbGQgZmllbGQgdHlwZSB0byB0aGUgbmV3IGZpZWxkIHR5cGUuIEJ1dCBpZiB3ZSBlbmZvcmNlXG4gIC8vIG9iamVjdHMgaGVyZSwgYSBkZXZlbG9wZXIgc2hvdWxkIHRlY2huaWNhbGx5IGJlIGFibGUgdG8gYWRkIGZpZWxkcyB0byB0aGVcbiAgLy8gbmVzdGVkIGZpZWxkIGRlZmluaXRpb24gd2l0aG91dCBicmVha2luZyBhbnkgZXhpc3RpbmcgZGIgZW50cmllcy5cbiAgb2Y6IEltYWdlRmllbGQgfCBPYmplY3RGaWVsZCB8IE9uZU9mRmllbGQ7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gYXJyYXkoZmllbGQ6IE9taXQ8QXJyYXlGaWVsZCwgJ3R5cGUnPik6IEFycmF5RmllbGQge1xuICByZXR1cm4gey4uLmZpZWxkLCB0eXBlOiAnYXJyYXknfTtcbn1cblxuZXhwb3J0IHR5cGUgT25lT2ZGaWVsZCA9IENvbW1vbkZpZWxkUHJvcHMgJiB7XG4gIHR5cGU6ICdvbmVvZic7XG4gIHR5cGVzOiBBcnJheTxTY2hlbWE+O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG9uZU9mKGZpZWxkOiBPbWl0PE9uZU9mRmllbGQsICd0eXBlJz4pOiBPbmVPZkZpZWxkIHtcbiAgcmV0dXJuIHsuLi5maWVsZCwgdHlwZTogJ29uZW9mJ307XG59XG5cbmV4cG9ydCB0eXBlIEZpZWxkID1cbiAgfCBTdHJpbmdGaWVsZFxuICB8IE51bWJlckZpZWxkXG4gIHwgRGF0ZUZpZWxkXG4gIHwgRGF0ZVRpbWVGaWVsZFxuICB8IEJvb2xlYW5GaWVsZFxuICB8IFNlbGVjdEZpZWxkXG4gIHwgTXVsdGlTZWxlY3RGaWVsZFxuICB8IEltYWdlRmllbGRcbiAgfCBPYmplY3RGaWVsZFxuICB8IEFycmF5RmllbGRcbiAgfCBPbmVPZkZpZWxkO1xuXG5leHBvcnQgdHlwZSBGaWVsZFdpdGhJZCA9IEZpZWxkO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNjaGVtYSB7XG4gIG5hbWU6IHN0cmluZztcbiAgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gIGZpZWxkczogQXJyYXk8RmllbGRXaXRoSWQ+O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVmaW5lU2NoZW1hKHNjaGVtYTogU2NoZW1hKTogU2NoZW1hIHtcbiAgcmV0dXJuIHNjaGVtYTtcbn1cblxuZXhwb3J0IGNvbnN0IGRlZmluZSA9IGRlZmluZVNjaGVtYTtcblxuZXhwb3J0IHR5cGUgQ29sbGVjdGlvbiA9IFNjaGVtYSAmIHtcbiAgLy8gVVJMIHdoZXJlIHRoZSBjb2xsZWN0aW9uIHNlcnZlcyBmcm9tLlxuICB1cmw/OiBzdHJpbmc7XG4gIC8vIFBhZ2UgY29tcG9uZW50IHRvIHJlbmRlciBmb3IgdGhlIGNvbGxlY3Rpb24uXG4gIENvbXBvbmVudDogRnVuY3Rpb25hbENvbXBvbmVudDtcbiAgLy8gRGVmaW5lcyB0aGUgZmllbGRzIHRvIHVzZSBmb3IgZG9jdW1lbnQgcHJldmlldy5cbiAgcHJldmlldz86IHtcbiAgICB0aXRsZT86IHN0cmluZztcbiAgICBpbWFnZT86IHN0cmluZztcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZpbmVDb2xsZWN0aW9uKGNvbGxlY3Rpb246IENvbGxlY3Rpb24pOiBDb2xsZWN0aW9uIHtcbiAgcmV0dXJuIGNvbGxlY3Rpb247XG59XG5cbmV4cG9ydCBjb25zdCBjb2xsZWN0aW9uID0gZGVmaW5lQ29sbGVjdGlvbjtcbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFtQk8sU0FBUyxPQUFPLE9BQStDO0FBQ3BFLFNBQU8sRUFBQyxHQUFHLE9BQU8sTUFBTSxTQUFRO0FBQ2xDO0FBT08sU0FBUyxPQUFPLE9BQStDO0FBQ3BFLFNBQU8sRUFBQyxHQUFHLE9BQU8sTUFBTSxTQUFRO0FBQ2xDO0FBT08sU0FBUyxLQUFLLE9BQTJDO0FBQzlELFNBQU8sRUFBQyxHQUFHLE9BQU8sTUFBTSxPQUFNO0FBQ2hDO0FBT08sU0FBUyxTQUFTLE9BQW1EO0FBQzFFLFNBQU8sRUFBQyxHQUFHLE9BQU8sTUFBTSxXQUFVO0FBQ3BDO0FBT08sU0FBUyxRQUFRLE9BQWlEO0FBQ3ZFLFNBQU8sRUFBQyxHQUFHLE9BQU8sTUFBTSxVQUFTO0FBQ25DO0FBVU8sU0FBUyxPQUFPLE9BQStDO0FBQ3BFLFNBQU8sRUFBQyxHQUFHLE9BQU8sTUFBTSxTQUFRO0FBQ2xDO0FBT08sU0FBUyxZQUNkLE9BQ2tCO0FBQ2xCLFNBQU8sRUFBQyxHQUFHLE9BQU8sTUFBTSxjQUFhO0FBQ3ZDO0FBTU8sU0FBUyxNQUFNLE9BQTZDO0FBQ2pFLFNBQU8sRUFBQyxHQUFHLE9BQU8sTUFBTSxRQUFPO0FBQ2pDO0FBT08sU0FBUyxPQUFPLE9BQStDO0FBQ3BFLFNBQU8sRUFBQyxHQUFHLE9BQU8sTUFBTSxTQUFRO0FBQ2xDO0FBaUJPLFNBQVMsTUFBTSxPQUE2QztBQUNqRSxTQUFPLEVBQUMsR0FBRyxPQUFPLE1BQU0sUUFBTztBQUNqQztBQU9PLFNBQVMsTUFBTSxPQUE2QztBQUNqRSxTQUFPLEVBQUMsR0FBRyxPQUFPLE1BQU0sUUFBTztBQUNqQztBQXVCTyxTQUFTLGFBQWEsUUFBd0I7QUFDbkQsU0FBTztBQUNUO0FBRU8sSUFBTSxTQUFTO0FBY2YsU0FBUyxpQkFBaUJBLGFBQW9DO0FBQ25FLFNBQU9BO0FBQ1Q7QUFFTyxJQUFNLGFBQWE7IiwKICAibmFtZXMiOiBbImNvbGxlY3Rpb24iXQp9Cg==
package/dist/index.d.ts CHANGED
@@ -1,3 +1,163 @@
1
- declare const test: {};
1
+ import { FunctionalComponent } from 'preact';
2
2
 
3
- export { test };
3
+ interface CommonFieldProps {
4
+ id?: string;
5
+ label?: string;
6
+ help?: string;
7
+ type: string;
8
+ default?: any;
9
+ hidden?: boolean;
10
+ deprecated?: boolean;
11
+ }
12
+ type StringField = CommonFieldProps & {
13
+ type: 'string';
14
+ default?: string;
15
+ translate?: boolean;
16
+ variant?: 'input' | 'textarea';
17
+ };
18
+ declare function string(field: Omit<StringField, 'type'>): StringField;
19
+ type NumberField = CommonFieldProps & {
20
+ type: 'number';
21
+ default?: number;
22
+ };
23
+ declare function number(field: Omit<NumberField, 'type'>): NumberField;
24
+ type DateField = CommonFieldProps & {
25
+ type: 'date';
26
+ default?: string;
27
+ };
28
+ declare function date(field: Omit<DateField, 'type'>): DateField;
29
+ type DateTimeField = CommonFieldProps & {
30
+ type: 'datetime';
31
+ default?: string;
32
+ };
33
+ declare function datetime(field: Omit<DateTimeField, 'type'>): DateTimeField;
34
+ type BooleanField = CommonFieldProps & {
35
+ type: 'boolean';
36
+ default?: boolean;
37
+ };
38
+ declare function boolean(field: Omit<BooleanField, 'type'>): BooleanField;
39
+ type SelectField = CommonFieldProps & {
40
+ type: 'select';
41
+ default?: string;
42
+ options?: {
43
+ values?: Array<{
44
+ value: string;
45
+ label?: string;
46
+ }>;
47
+ };
48
+ };
49
+ declare function select(field: Omit<SelectField, 'type'>): SelectField;
50
+ type MultiSelectField = Omit<SelectField, 'type'> & {
51
+ type: 'multiselect';
52
+ default?: string[];
53
+ };
54
+ declare function multiselect(field: Omit<MultiSelectField, 'type'>): MultiSelectField;
55
+ type ImageField = CommonFieldProps & {
56
+ type: 'image';
57
+ };
58
+ declare function image(field: Omit<ImageField, 'type'>): ImageField;
59
+ type ObjectField = CommonFieldProps & {
60
+ type: 'object';
61
+ fields: FieldWithId[];
62
+ };
63
+ declare function object(field: Omit<ObjectField, 'type'>): ObjectField;
64
+ type ArrayField = CommonFieldProps & {
65
+ type: 'array';
66
+ default?: Array<any>;
67
+ preview?: (value: any) => string;
68
+ of: ImageField | ObjectField | OneOfField;
69
+ };
70
+ declare function array(field: Omit<ArrayField, 'type'>): ArrayField;
71
+ type OneOfField = CommonFieldProps & {
72
+ type: 'oneof';
73
+ types: Array<Schema>;
74
+ };
75
+ declare function oneOf(field: Omit<OneOfField, 'type'>): OneOfField;
76
+ type Field = StringField | NumberField | DateField | DateTimeField | BooleanField | SelectField | MultiSelectField | ImageField | ObjectField | ArrayField | OneOfField;
77
+ type FieldWithId = Field;
78
+ interface Schema {
79
+ name: string;
80
+ description?: string;
81
+ fields: Array<FieldWithId>;
82
+ }
83
+ declare function defineSchema(schema: Schema): Schema;
84
+ declare const define: typeof defineSchema;
85
+ type Collection = Schema & {
86
+ url?: string;
87
+ Component: FunctionalComponent;
88
+ preview?: {
89
+ title?: string;
90
+ image?: string;
91
+ };
92
+ };
93
+ declare function defineCollection(collection: Collection): Collection;
94
+ declare const collection: typeof defineCollection;
95
+
96
+ type schema_CommonFieldProps = CommonFieldProps;
97
+ type schema_StringField = StringField;
98
+ declare const schema_string: typeof string;
99
+ type schema_NumberField = NumberField;
100
+ declare const schema_number: typeof number;
101
+ type schema_DateField = DateField;
102
+ declare const schema_date: typeof date;
103
+ type schema_DateTimeField = DateTimeField;
104
+ declare const schema_datetime: typeof datetime;
105
+ type schema_BooleanField = BooleanField;
106
+ declare const schema_boolean: typeof boolean;
107
+ type schema_SelectField = SelectField;
108
+ declare const schema_select: typeof select;
109
+ type schema_MultiSelectField = MultiSelectField;
110
+ declare const schema_multiselect: typeof multiselect;
111
+ type schema_ImageField = ImageField;
112
+ declare const schema_image: typeof image;
113
+ type schema_ObjectField = ObjectField;
114
+ declare const schema_object: typeof object;
115
+ type schema_ArrayField = ArrayField;
116
+ declare const schema_array: typeof array;
117
+ type schema_OneOfField = OneOfField;
118
+ declare const schema_oneOf: typeof oneOf;
119
+ type schema_Field = Field;
120
+ type schema_FieldWithId = FieldWithId;
121
+ type schema_Schema = Schema;
122
+ declare const schema_defineSchema: typeof defineSchema;
123
+ declare const schema_define: typeof define;
124
+ type schema_Collection = Collection;
125
+ declare const schema_defineCollection: typeof defineCollection;
126
+ declare const schema_collection: typeof collection;
127
+ declare namespace schema {
128
+ export {
129
+ schema_CommonFieldProps as CommonFieldProps,
130
+ schema_StringField as StringField,
131
+ schema_string as string,
132
+ schema_NumberField as NumberField,
133
+ schema_number as number,
134
+ schema_DateField as DateField,
135
+ schema_date as date,
136
+ schema_DateTimeField as DateTimeField,
137
+ schema_datetime as datetime,
138
+ schema_BooleanField as BooleanField,
139
+ schema_boolean as boolean,
140
+ schema_SelectField as SelectField,
141
+ schema_select as select,
142
+ schema_MultiSelectField as MultiSelectField,
143
+ schema_multiselect as multiselect,
144
+ schema_ImageField as ImageField,
145
+ schema_image as image,
146
+ schema_ObjectField as ObjectField,
147
+ schema_object as object,
148
+ schema_ArrayField as ArrayField,
149
+ schema_array as array,
150
+ schema_OneOfField as OneOfField,
151
+ schema_oneOf as oneOf,
152
+ schema_Field as Field,
153
+ schema_FieldWithId as FieldWithId,
154
+ schema_Schema as Schema,
155
+ schema_defineSchema as defineSchema,
156
+ schema_define as define,
157
+ schema_Collection as Collection,
158
+ schema_defineCollection as defineCollection,
159
+ schema_collection as collection,
160
+ };
161
+ }
162
+
163
+ export { schema };
package/dist/plugin.d.ts CHANGED
@@ -1,6 +1,14 @@
1
- import { Plugin } from '@blinkk/root';
1
+ import { Request, Plugin } from '@blinkk/root';
2
2
 
3
- declare type CMSPluginOptions = {};
3
+ interface User {
4
+ email: string;
5
+ jwt: any;
6
+ }
7
+
8
+ type CMSPluginOptions = {
9
+ cookieSecret?: string | string[];
10
+ isUserAuthorized?: (req: Request, user: User) => boolean | Promise<boolean>;
11
+ };
4
12
  declare function cmsPlugin(options?: CMSPluginOptions): Plugin;
5
13
 
6
- export { cmsPlugin };
14
+ export { CMSPluginOptions, cmsPlugin };
package/dist/plugin.js CHANGED
@@ -1,17 +1,196 @@
1
- // src/plugin.ts
1
+ // core/users.ts
2
+ import jsonwebtoken from "jsonwebtoken";
3
+ var AUTH_COOKIE = "ROOTJS_AUTH";
4
+ function usersMiddleware(options) {
5
+ const clientId = process.env.GOOGLE_CLIENT_ID;
6
+ const clientSecret = process.env.GOOGLE_CLIENT_SECRET;
7
+ const loginUrl = options.loginUrl || "/cms/login";
8
+ if (!clientId || !clientSecret) {
9
+ throw new Error(
10
+ "Missing one or more required .env vars: GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET"
11
+ );
12
+ }
13
+ function isLoginRequired(req) {
14
+ if (!options.isLoginRequired) {
15
+ return false;
16
+ }
17
+ return options.isLoginRequired(req);
18
+ }
19
+ function isUserAuthorized(req, user) {
20
+ if (!options.isUserAuthorized) {
21
+ return true;
22
+ }
23
+ return options.isUserAuthorized(req, user);
24
+ }
25
+ function getLoginUrl(req) {
26
+ const params = new URLSearchParams();
27
+ params.set("scope", "email");
28
+ params.set("access_type", "online");
29
+ params.set("client_id", clientId);
30
+ params.set("redirect_uri", getRedirectUrl(req));
31
+ params.set("state", req.originalUrl);
32
+ params.set("response_type", "code");
33
+ return `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;
34
+ }
35
+ function getRedirectUrl(req) {
36
+ const host = getHost(req);
37
+ const protocol = req.protocol;
38
+ return `${protocol}://${host}${loginUrl}`;
39
+ }
40
+ function getHost(req) {
41
+ return req.headers["x-forwarded-host"] || req.headers.host;
42
+ }
43
+ function loginRedirect(req, res) {
44
+ const loginUrl2 = getLoginUrl(req);
45
+ res.redirect(loginUrl2);
46
+ return;
47
+ }
48
+ async function getOAuthToken(req, code) {
49
+ const params = new URLSearchParams();
50
+ params.set("client_id", clientId);
51
+ params.set("client_secret", clientSecret);
52
+ params.set("redirect_uri", getRedirectUrl(req));
53
+ params.set("grant_type", "authorization_code");
54
+ params.set("code", code);
55
+ const res = await fetch("https://oauth2.googleapis.com/token", {
56
+ method: "POST",
57
+ headers: {
58
+ "Content-Type": "application/x-www-form-urlencoded"
59
+ },
60
+ body: params.toString()
61
+ });
62
+ if (res.status !== 200) {
63
+ console.error(res.status);
64
+ throw new Error("failed to retrieve jwt token");
65
+ }
66
+ return res.json();
67
+ }
68
+ async function getUser(req) {
69
+ const cookieValue = req.signedCookies[AUTH_COOKIE];
70
+ console.log(cookieValue);
71
+ if (cookieValue) {
72
+ try {
73
+ const jwt = decodeJWT(cookieValue);
74
+ if (jwt && jwt.email) {
75
+ return {
76
+ email: jwt.email,
77
+ jwt
78
+ };
79
+ }
80
+ } catch (e) {
81
+ console.error(`failed to parse jwt: ${cookieValue}`);
82
+ console.error(e);
83
+ }
84
+ }
85
+ return null;
86
+ }
87
+ async function handleLogin(req, res) {
88
+ const code = req.query.code;
89
+ if (!code) {
90
+ res.status(403).send("Missing required param: code");
91
+ return;
92
+ }
93
+ const token = await getOAuthToken(req, code);
94
+ const jwt = decodeJWT(token.id_token);
95
+ if (!jwt || !jwt.email || !jwt.email_verified) {
96
+ res.status(500).send("500: Login failed");
97
+ return;
98
+ }
99
+ const exp = jwt.exp || Math.floor(new Date().getTime() / 1e3 + 3600);
100
+ res.cookie(AUTH_COOKIE, token.id_token, {
101
+ secure: req.hostname !== "localhost",
102
+ httpOnly: true,
103
+ sameSite: true,
104
+ expires: new Date(exp * 1e3),
105
+ signed: true
106
+ });
107
+ const state = String(req.params.state);
108
+ if (state && state.startsWith("/cms")) {
109
+ res.redirect(state);
110
+ } else {
111
+ res.redirect("/cms");
112
+ }
113
+ }
114
+ function decodeJWT(token) {
115
+ try {
116
+ const decoded = jsonwebtoken.decode(token, { complete: true });
117
+ return decoded == null ? void 0 : decoded.payload;
118
+ } catch (err) {
119
+ return null;
120
+ }
121
+ }
122
+ return async (req, res, next) => {
123
+ try {
124
+ if (req.originalUrl.startsWith(loginUrl)) {
125
+ await handleLogin(req, res);
126
+ return;
127
+ }
128
+ const user = await getUser(req);
129
+ if (isLoginRequired(req)) {
130
+ if (!user) {
131
+ loginRedirect(req, res);
132
+ return;
133
+ }
134
+ if (!isUserAuthorized(req, user)) {
135
+ res.status(403).send("403: Login failed");
136
+ return;
137
+ }
138
+ }
139
+ const r = req;
140
+ r.user = user;
141
+ next();
142
+ } catch (err) {
143
+ next(err);
144
+ }
145
+ };
146
+ }
147
+
148
+ // core/plugin.ts
149
+ import cookieParser from "cookie-parser";
150
+ import * as dotenv from "dotenv";
151
+ import path from "node:path";
152
+ import { fileURLToPath } from "node:url";
153
+ var __dirname = path.dirname(fileURLToPath(import.meta.url));
154
+ dotenv.config();
155
+ function generateSecret() {
156
+ const result = [];
157
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
158
+ for (let i = 0; i < 36; i++) {
159
+ const rand = Math.floor(Math.random() * chars.length);
160
+ result.push(chars.charAt(rand));
161
+ }
162
+ return result.join("");
163
+ }
2
164
  function cmsPlugin(options) {
165
+ const cookieSecret = (options == null ? void 0 : options.cookieSecret) || generateSecret();
3
166
  return {
4
167
  name: "root-cms",
5
168
  configureServer: (server) => {
6
- server.use("/cms", (req, res) => {
7
- console.log("root config context var:");
8
- console.log(req.rootConfig);
9
- res.end("cms");
10
- });
169
+ server.use("/cms", cookieParser(cookieSecret));
170
+ server.use(
171
+ "/cms",
172
+ usersMiddleware({
173
+ isLoginRequired: () => true,
174
+ isUserAuthorized: options == null ? void 0 : options.isUserAuthorized
175
+ })
176
+ );
177
+ server.use(
178
+ "/cms",
179
+ async (req, res, next) => {
180
+ try {
181
+ const appPath = path.resolve(__dirname, "./app.js");
182
+ const app = await req.viteServer.ssrLoadModule(appPath);
183
+ app.render(req, res);
184
+ } catch (err) {
185
+ console.error(err);
186
+ next(err);
187
+ }
188
+ }
189
+ );
11
190
  }
12
191
  };
13
192
  }
14
193
  export {
15
194
  cmsPlugin
16
195
  };
17
- //# sourceMappingURL=plugin.js.map
196
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vY29yZS91c2Vycy50cyIsICIuLi9jb3JlL3BsdWdpbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHtOZXh0RnVuY3Rpb24sIFJlcXVlc3QsIFJlc3BvbnNlfSBmcm9tICdAYmxpbmtrL3Jvb3QnO1xuaW1wb3J0IGpzb253ZWJ0b2tlbiBmcm9tICdqc29ud2VidG9rZW4nO1xuXG5leHBvcnQgaW50ZXJmYWNlIFVzZXIge1xuICBlbWFpbDogc3RyaW5nO1xuICBqd3Q6IGFueTtcbn1cblxuZXhwb3J0IHR5cGUgVXNlclJlcXVlc3QgPSBSZXF1ZXN0ICYge1xuICB1c2VyPzogVXNlciB8IG51bGw7XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIE1pZGRsZXdhcmVPcHRpb25zIHtcbiAgaXNMb2dpblJlcXVpcmVkPzogKHJlcTogUmVxdWVzdCkgPT4gYm9vbGVhbjtcbiAgaXNVc2VyQXV0aG9yaXplZD86IChyZXE6IFJlcXVlc3QsIHVzZXI6IFVzZXIpID0+IGJvb2xlYW4gfCBQcm9taXNlPGJvb2xlYW4+O1xuICBsb2dpblVybD86IHN0cmluZztcbn1cblxuY29uc3QgQVVUSF9DT09LSUUgPSAnUk9PVEpTX0FVVEgnO1xuXG5leHBvcnQgZnVuY3Rpb24gdXNlcnNNaWRkbGV3YXJlKG9wdGlvbnM6IE1pZGRsZXdhcmVPcHRpb25zKSB7XG4gIGNvbnN0IGNsaWVudElkID0gcHJvY2Vzcy5lbnYuR09PR0xFX0NMSUVOVF9JRCE7XG4gIGNvbnN0IGNsaWVudFNlY3JldCA9IHByb2Nlc3MuZW52LkdPT0dMRV9DTElFTlRfU0VDUkVUITtcbiAgY29uc3QgbG9naW5VcmwgPSBvcHRpb25zLmxvZ2luVXJsIHx8ICcvY21zL2xvZ2luJztcblxuICBpZiAoIWNsaWVudElkIHx8ICFjbGllbnRTZWNyZXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnTWlzc2luZyBvbmUgb3IgbW9yZSByZXF1aXJlZCAuZW52IHZhcnM6IEdPT0dMRV9DTElFTlRfSUQsIEdPT0dMRV9DTElFTlRfU0VDUkVUJ1xuICAgICk7XG4gIH1cblxuICBmdW5jdGlvbiBpc0xvZ2luUmVxdWlyZWQocmVxOiBSZXF1ZXN0KSB7XG4gICAgaWYgKCFvcHRpb25zLmlzTG9naW5SZXF1aXJlZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gb3B0aW9ucy5pc0xvZ2luUmVxdWlyZWQocmVxKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzVXNlckF1dGhvcml6ZWQocmVxOiBSZXF1ZXN0LCB1c2VyOiBVc2VyKSB7XG4gICAgaWYgKCFvcHRpb25zLmlzVXNlckF1dGhvcml6ZWQpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gb3B0aW9ucy5pc1VzZXJBdXRob3JpemVkKHJlcSwgdXNlcik7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRMb2dpblVybChyZXE6IFJlcXVlc3QpIHtcbiAgICBjb25zdCBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKCk7XG4gICAgcGFyYW1zLnNldCgnc2NvcGUnLCAnZW1haWwnKTtcbiAgICBwYXJhbXMuc2V0KCdhY2Nlc3NfdHlwZScsICdvbmxpbmUnKTtcbiAgICBwYXJhbXMuc2V0KCdjbGllbnRfaWQnLCBjbGllbnRJZCk7XG4gICAgcGFyYW1zLnNldCgncmVkaXJlY3RfdXJpJywgZ2V0UmVkaXJlY3RVcmwocmVxKSk7XG4gICAgcGFyYW1zLnNldCgnc3RhdGUnLCByZXEub3JpZ2luYWxVcmwpO1xuICAgIHBhcmFtcy5zZXQoJ3Jlc3BvbnNlX3R5cGUnLCAnY29kZScpO1xuICAgIHJldHVybiBgaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tL28vb2F1dGgyL3YyL2F1dGg/JHtwYXJhbXMudG9TdHJpbmcoKX1gO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0UmVkaXJlY3RVcmwocmVxOiBSZXF1ZXN0KSB7XG4gICAgY29uc3QgaG9zdCA9IGdldEhvc3QocmVxKTtcbiAgICBjb25zdCBwcm90b2NvbCA9IHJlcS5wcm90b2NvbDtcbiAgICByZXR1cm4gYCR7cHJvdG9jb2x9Oi8vJHtob3N0fSR7bG9naW5Vcmx9YDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldEhvc3QocmVxOiBSZXF1ZXN0KSB7XG4gICAgcmV0dXJuIHJlcS5oZWFkZXJzWyd4LWZvcndhcmRlZC1ob3N0J10gfHwgcmVxLmhlYWRlcnMuaG9zdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGxvZ2luUmVkaXJlY3QocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSB7XG4gICAgY29uc3QgbG9naW5VcmwgPSBnZXRMb2dpblVybChyZXEpO1xuICAgIHJlcy5yZWRpcmVjdChsb2dpblVybCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gZ2V0T0F1dGhUb2tlbihyZXE6IFJlcXVlc3QsIGNvZGU6IHN0cmluZykge1xuICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoKTtcbiAgICBwYXJhbXMuc2V0KCdjbGllbnRfaWQnLCBjbGllbnRJZCk7XG4gICAgcGFyYW1zLnNldCgnY2xpZW50X3NlY3JldCcsIGNsaWVudFNlY3JldCk7XG4gICAgcGFyYW1zLnNldCgncmVkaXJlY3RfdXJpJywgZ2V0UmVkaXJlY3RVcmwocmVxKSk7XG4gICAgcGFyYW1zLnNldCgnZ3JhbnRfdHlwZScsICdhdXRob3JpemF0aW9uX2NvZGUnKTtcbiAgICBwYXJhbXMuc2V0KCdjb2RlJywgY29kZSk7XG5cbiAgICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaCgnaHR0cHM6Ly9vYXV0aDIuZ29vZ2xlYXBpcy5jb20vdG9rZW4nLCB7XG4gICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAgICAgfSxcbiAgICAgIGJvZHk6IHBhcmFtcy50b1N0cmluZygpLFxuICAgIH0pO1xuICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDApIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IocmVzLnN0YXR1cyk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ZhaWxlZCB0byByZXRyaWV2ZSBqd3QgdG9rZW4nKTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcy5qc29uKCk7XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBnZXRVc2VyKHJlcTogUmVxdWVzdCk6IFByb21pc2U8VXNlciB8IG51bGw+IHtcbiAgICBjb25zdCBjb29raWVWYWx1ZSA9IHJlcS5zaWduZWRDb29raWVzW0FVVEhfQ09PS0lFXTtcbiAgICBjb25zb2xlLmxvZyhjb29raWVWYWx1ZSk7XG4gICAgaWYgKGNvb2tpZVZhbHVlKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBqd3QgPSBkZWNvZGVKV1QoY29va2llVmFsdWUpO1xuICAgICAgICBpZiAoand0ICYmIGp3dC5lbWFpbCkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBlbWFpbDogand0LmVtYWlsLFxuICAgICAgICAgICAgand0OiBqd3QsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBmYWlsZWQgdG8gcGFyc2Ugand0OiAke2Nvb2tpZVZhbHVlfWApO1xuICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGhhbmRsZUxvZ2luKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkge1xuICAgIGNvbnN0IGNvZGUgPSByZXEucXVlcnkuY29kZSBhcyBzdHJpbmc7XG4gICAgaWYgKCFjb2RlKSB7XG4gICAgICByZXMuc3RhdHVzKDQwMykuc2VuZCgnTWlzc2luZyByZXF1aXJlZCBwYXJhbTogY29kZScpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGdldE9BdXRoVG9rZW4ocmVxLCBjb2RlKTtcbiAgICBjb25zdCBqd3QgPSBkZWNvZGVKV1QodG9rZW4uaWRfdG9rZW4pO1xuICAgIGlmICghand0IHx8ICFqd3QuZW1haWwgfHwgIWp3dC5lbWFpbF92ZXJpZmllZCkge1xuICAgICAgcmVzLnN0YXR1cyg1MDApLnNlbmQoJzUwMDogTG9naW4gZmFpbGVkJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGV4cCA9IGp3dC5leHAgfHwgTWF0aC5mbG9vcihuZXcgRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDAgKyAzNjAwKTtcbiAgICByZXMuY29va2llKEFVVEhfQ09PS0lFLCB0b2tlbi5pZF90b2tlbiwge1xuICAgICAgc2VjdXJlOiByZXEuaG9zdG5hbWUgIT09ICdsb2NhbGhvc3QnLFxuICAgICAgaHR0cE9ubHk6IHRydWUsXG4gICAgICBzYW1lU2l0ZTogdHJ1ZSxcbiAgICAgIGV4cGlyZXM6IG5ldyBEYXRlKGV4cCAqIDEwMDApLFxuICAgICAgc2lnbmVkOiB0cnVlLFxuICAgIH0pO1xuICAgIGNvbnN0IHN0YXRlID0gU3RyaW5nKHJlcS5wYXJhbXMuc3RhdGUpO1xuICAgIGlmIChzdGF0ZSAmJiBzdGF0ZS5zdGFydHNXaXRoKCcvY21zJykpIHtcbiAgICAgIHJlcy5yZWRpcmVjdChzdGF0ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlcy5yZWRpcmVjdCgnL2NtcycpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGRlY29kZUpXVCh0b2tlbjogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGRlY29kZWQgPSBqc29ud2VidG9rZW4uZGVjb2RlKHRva2VuLCB7Y29tcGxldGU6IHRydWV9KTtcbiAgICAgIHJldHVybiBkZWNvZGVkPy5wYXlsb2FkIGFzIGpzb253ZWJ0b2tlbi5Kd3RQYXlsb2FkO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGFzeW5jIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbikgPT4ge1xuICAgIHRyeSB7XG4gICAgICBpZiAocmVxLm9yaWdpbmFsVXJsLnN0YXJ0c1dpdGgobG9naW5VcmwpKSB7XG4gICAgICAgIGF3YWl0IGhhbmRsZUxvZ2luKHJlcSwgcmVzKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgdXNlciA9IGF3YWl0IGdldFVzZXIocmVxKTtcbiAgICAgIGlmIChpc0xvZ2luUmVxdWlyZWQocmVxKSkge1xuICAgICAgICBpZiAoIXVzZXIpIHtcbiAgICAgICAgICBsb2dpblJlZGlyZWN0KHJlcSwgcmVzKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc1VzZXJBdXRob3JpemVkKHJlcSwgdXNlcikpIHtcbiAgICAgICAgICByZXMuc3RhdHVzKDQwMykuc2VuZCgnNDAzOiBMb2dpbiBmYWlsZWQnKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IHIgPSByZXEgYXMgVXNlclJlcXVlc3Q7XG4gICAgICByLnVzZXIgPSB1c2VyO1xuICAgICAgbmV4dCgpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgbmV4dChlcnIpO1xuICAgIH1cbiAgfTtcbn1cbiIsICJpbXBvcnQge05leHRGdW5jdGlvbiwgUGx1Z2luLCBSZXF1ZXN0LCBSZXNwb25zZX0gZnJvbSAnQGJsaW5ray9yb290JztcbmltcG9ydCB7VXNlciwgdXNlcnNNaWRkbGV3YXJlfSBmcm9tICcuL3VzZXJzLmpzJztcbmltcG9ydCBjb29raWVQYXJzZXIgZnJvbSAnY29va2llLXBhcnNlcic7XG5pbXBvcnQgKiBhcyBkb3RlbnYgZnJvbSAnZG90ZW52JztcbmltcG9ydCBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XG5pbXBvcnQge2ZpbGVVUkxUb1BhdGh9IGZyb20gJ25vZGU6dXJsJztcblxuY29uc3QgX19kaXJuYW1lID0gcGF0aC5kaXJuYW1lKGZpbGVVUkxUb1BhdGgoaW1wb3J0Lm1ldGEudXJsKSk7XG5cbmRvdGVudi5jb25maWcoKTtcblxuZXhwb3J0IHR5cGUgQ01TUGx1Z2luT3B0aW9ucyA9IHtcbiAgLy8gU2VjcmV0IHZhbHVlKHMpIHVzZWQgZm9yIHNpZ25pbmcgdGhlIHVzZXIgYXV0aGVudGljYXRpb24gY29va2llLlxuICBjb29raWVTZWNyZXQ/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgLy8gRnVuY3Rpb24gY2FsbGVkIHRvIGNoZWNrIGlmIGEgdXNlciBzaG91bGQgaGF2ZSBhY2Nlc3MgdG8gdGhlIENNUy5cbiAgaXNVc2VyQXV0aG9yaXplZD86IChyZXE6IFJlcXVlc3QsIHVzZXI6IFVzZXIpID0+IGJvb2xlYW4gfCBQcm9taXNlPGJvb2xlYW4+O1xufTtcblxuZnVuY3Rpb24gZ2VuZXJhdGVTZWNyZXQoKTogc3RyaW5nIHtcbiAgY29uc3QgcmVzdWx0ID0gW107XG4gIGNvbnN0IGNoYXJzID1cbiAgICAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODknO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IDM2OyBpKyspIHtcbiAgICBjb25zdCByYW5kID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogY2hhcnMubGVuZ3RoKTtcbiAgICByZXN1bHQucHVzaChjaGFycy5jaGFyQXQocmFuZCkpO1xuICB9XG4gIHJldHVybiByZXN1bHQuam9pbignJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjbXNQbHVnaW4ob3B0aW9ucz86IENNU1BsdWdpbk9wdGlvbnMpOiBQbHVnaW4ge1xuICBjb25zdCBjb29raWVTZWNyZXQgPSBvcHRpb25zPy5jb29raWVTZWNyZXQgfHwgZ2VuZXJhdGVTZWNyZXQoKTtcbiAgcmV0dXJuIHtcbiAgICBuYW1lOiAncm9vdC1jbXMnLFxuICAgIGNvbmZpZ3VyZVNlcnZlcjogKHNlcnZlcikgPT4ge1xuICAgICAgc2VydmVyLnVzZSgnL2NtcycsIGNvb2tpZVBhcnNlcihjb29raWVTZWNyZXQpKTtcbiAgICAgIHNlcnZlci51c2UoXG4gICAgICAgICcvY21zJyxcbiAgICAgICAgdXNlcnNNaWRkbGV3YXJlKHtcbiAgICAgICAgICBpc0xvZ2luUmVxdWlyZWQ6ICgpID0+IHRydWUsXG4gICAgICAgICAgaXNVc2VyQXV0aG9yaXplZDogb3B0aW9ucz8uaXNVc2VyQXV0aG9yaXplZCxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgICAvLyBzZXJ2ZXIudXNlKCcvY21zL21haW4uanMnLCBhc3luYyAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlKSA9PiB7XG4gICAgICAvLyAgIGNvbnN0IHZpdGVTZXJ2ZXIgPSByZXEudml0ZVNlcnZlciE7XG4gICAgICAvLyAgIGNvbnN0IGFwcFBhdGggPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi9hcHAuanMnKTtcbiAgICAgIC8vICAgY29uc3QgZmlsZVVybCA9IHBhdGguam9pbignL0BmcycsIGFwcFBhdGguc2xpY2UoMSkpO1xuICAgICAgLy8gICBjb25zb2xlLmxvZyhmaWxlVXJsKTtcbiAgICAgIC8vICAgY29uc3QgdmFsID0gYXdhaXQgdml0ZVNlcnZlci50cmFuc2Zvcm1SZXF1ZXN0KFxuICAgICAgLy8gICAgIHBhdGguam9pbignL0BmcycsIGFwcFBhdGguc2xpY2UoMSkpXG4gICAgICAvLyAgICk7XG4gICAgICAvLyAgIGlmICh2YWw/LmNvZGUpIHtcbiAgICAgIC8vICAgICByZXMuc2V0SGVhZGVyKCdjb250ZW50LXR5cGUnLCAndGV4dC9wbGFpbicpO1xuICAgICAgLy8gICAgIHJlcy5zZW5kKHZhbC5jb2RlKTtcbiAgICAgIC8vICAgfSBlbHNlIHtcbiAgICAgIC8vICAgICByZXMuc2VuZCgnbm90IGZvdW5kJyk7XG4gICAgICAvLyAgIH1cbiAgICAgIC8vIH0pO1xuICAgICAgc2VydmVyLnVzZShcbiAgICAgICAgJy9jbXMnLFxuICAgICAgICBhc3luYyAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgYXBwUGF0aCA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL2FwcC5qcycpO1xuICAgICAgICAgICAgY29uc3QgYXBwID0gYXdhaXQgcmVxLnZpdGVTZXJ2ZXIhLnNzckxvYWRNb2R1bGUoYXBwUGF0aCk7XG4gICAgICAgICAgICBhcHAucmVuZGVyKHJlcSwgcmVzKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAgICAgICAgICAgIG5leHQoZXJyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICk7XG4gICAgfSxcbiAgfTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7QUFDQSxPQUFPLGtCQUFrQjtBQWlCekIsSUFBTSxjQUFjO0FBRWIsU0FBUyxnQkFBZ0IsU0FBNEI7QUFDMUQsUUFBTSxXQUFXLFFBQVEsSUFBSTtBQUM3QixRQUFNLGVBQWUsUUFBUSxJQUFJO0FBQ2pDLFFBQU0sV0FBVyxRQUFRLFlBQVk7QUFFckMsTUFBSSxDQUFDLFlBQVksQ0FBQyxjQUFjO0FBQzlCLFVBQU0sSUFBSTtBQUFBLE1BQ1I7QUFBQSxJQUNGO0FBQUEsRUFDRjtBQUVBLFdBQVMsZ0JBQWdCLEtBQWM7QUFDckMsUUFBSSxDQUFDLFFBQVEsaUJBQWlCO0FBQzVCLGFBQU87QUFBQSxJQUNUO0FBQ0EsV0FBTyxRQUFRLGdCQUFnQixHQUFHO0FBQUEsRUFDcEM7QUFFQSxXQUFTLGlCQUFpQixLQUFjLE1BQVk7QUFDbEQsUUFBSSxDQUFDLFFBQVEsa0JBQWtCO0FBQzdCLGFBQU87QUFBQSxJQUNUO0FBQ0EsV0FBTyxRQUFRLGlCQUFpQixLQUFLLElBQUk7QUFBQSxFQUMzQztBQUVBLFdBQVMsWUFBWSxLQUFjO0FBQ2pDLFVBQU0sU0FBUyxJQUFJLGdCQUFnQjtBQUNu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