@blinkk/root-cms 1.0.0-alpha.9 → 1.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {createRequire} from 'node:module';
4
+ import path from 'node:path';
5
+ import {fileURLToPath} from 'node:url';
6
+ import {Command} from 'commander';
7
+ import {bgGreen, black} from 'kleur/colors';
8
+ import {createServer as createViteServer} from 'vite';
9
+
10
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
+ const require = createRequire(import.meta.url);
12
+ const packageJson = require(path.join(__dirname, '../package.json'));
13
+
14
+ async function main() {
15
+ console.log(`🌱 ${bgGreen(black(' root.js cms '))} v${packageJson.version}`);
16
+
17
+ // Load cli.js through vite SSR so that things like `import.meta.glob` are
18
+ // handled properly.
19
+ // TODO(stevenle): load the vite config from root.config.ts.
20
+ const viteServer = await createViteServer();
21
+ const cli = await viteServer.ssrLoadModule(
22
+ path.resolve(__dirname, '../dist/cli.js')
23
+ );
24
+ await viteServer.close();
25
+
26
+ const program = new Command('root-cms');
27
+ program.version(packageJson.version);
28
+ program
29
+ .command('init-firebase')
30
+ .description('inits the firebase project with proper security rules')
31
+ .action(cli.initFirebase);
32
+ program
33
+ .command('generate-types')
34
+ .description('generates root-cms.d.ts from *.schema.ts in the project')
35
+ .action(cli.generateTypes);
36
+ await program.parseAsync(process.argv);
37
+ }
38
+
39
+ main();
package/dist/app.js ADDED
@@ -0,0 +1,190 @@
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 { jsx, jsxs } from "preact/jsx-runtime";
6
+ var __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ function App(props) {
8
+ return /* @__PURE__ */ jsxs("html", {
9
+ children: [
10
+ /* @__PURE__ */ jsxs("head", {
11
+ children: [
12
+ /* @__PURE__ */ jsx("title", {
13
+ children: props.title
14
+ }),
15
+ /* @__PURE__ */ jsx("link", {
16
+ rel: "preconnect",
17
+ href: "https://fonts.googleapis.com"
18
+ }),
19
+ /* @__PURE__ */ jsx("link", {
20
+ rel: "preconnect",
21
+ href: "https://fonts.gstatic.com",
22
+ crossOrigin: "anonymous"
23
+ }),
24
+ /* @__PURE__ */ jsx("link", {
25
+ rel: "stylesheet",
26
+ href: "https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;900&display=swap"
27
+ }),
28
+ /* @__PURE__ */ jsx("link", {
29
+ rel: "stylesheet",
30
+ href: "https://fonts.googleapis.com/css2?family=Google+Sans:wght@500&display=swap"
31
+ }),
32
+ /* @__PURE__ */ jsx("link", {
33
+ rel: "stylesheet",
34
+ href: "{CSS_URL}"
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 this page 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: "{JS_URL}"
64
+ })
65
+ ]
66
+ })
67
+ ]
68
+ });
69
+ }
70
+ async function renderApp(req, res, options) {
71
+ const collectionModules = import.meta.glob("/collections/*.schema.ts", {
72
+ eager: true
73
+ });
74
+ const collections = {};
75
+ Object.keys(collectionModules).forEach((moduleId) => {
76
+ const collectionId = path.parse(moduleId).base.split(".")[0];
77
+ const module = collectionModules[moduleId];
78
+ const collection = module.default;
79
+ collections[collectionId] = collection;
80
+ });
81
+ const rootConfig = options.rootConfig || {};
82
+ const cmsConfig = options.cmsConfig || {};
83
+ const ctx = {
84
+ rootConfig: {
85
+ projectId: cmsConfig.id || "default",
86
+ domain: rootConfig.domain || "https://example.com"
87
+ },
88
+ firebaseConfig: options.firebaseConfig,
89
+ collections
90
+ };
91
+ const mainHtml = renderToString(/* @__PURE__ */ jsx(App, {
92
+ title: "Root.js CMS",
93
+ ctx
94
+ }));
95
+ let html = `<!doctype html>
96
+ ${mainHtml}`;
97
+ if (req.viteServer) {
98
+ const uiCssPath = path.join(__dirname, "ui/ui.css");
99
+ const uiJsPath = path.join(__dirname, "ui/ui.js");
100
+ const tpl = html.replace("{CSS_URL}", `/@fs${uiCssPath}`).replace("{JS_URL}", `/@fs${uiJsPath}`);
101
+ html = await req.viteServer.transformIndexHtml(req.originalUrl, tpl);
102
+ } else {
103
+ html = html.replace("{CSS_URL}", "/cms/static/ui.css").replace("{JS_URL}", "/cms/static/ui.js");
104
+ }
105
+ res.setHeader("Content-Type", "text/html");
106
+ res.send(html);
107
+ }
108
+ function SignIn(props) {
109
+ return /* @__PURE__ */ jsxs("html", {
110
+ children: [
111
+ /* @__PURE__ */ jsxs("head", {
112
+ children: [
113
+ /* @__PURE__ */ jsx("title", {
114
+ children: props.title
115
+ }),
116
+ /* @__PURE__ */ jsx("link", {
117
+ rel: "preconnect",
118
+ href: "https://fonts.googleapis.com"
119
+ }),
120
+ /* @__PURE__ */ jsx("link", {
121
+ rel: "preconnect",
122
+ href: "https://fonts.gstatic.com",
123
+ crossOrigin: "anonymous"
124
+ }),
125
+ /* @__PURE__ */ jsx("link", {
126
+ rel: "stylesheet",
127
+ href: "https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;900&display=swap"
128
+ }),
129
+ /* @__PURE__ */ jsx("link", {
130
+ rel: "stylesheet",
131
+ href: "{CSS_URL}"
132
+ })
133
+ ]
134
+ }),
135
+ /* @__PURE__ */ jsxs("body", {
136
+ children: [
137
+ /* @__PURE__ */ jsx("div", {
138
+ id: "root",
139
+ children: /* @__PURE__ */ jsxs("div", {
140
+ className: "bootstrap",
141
+ children: [
142
+ /* @__PURE__ */ jsx("h1", {
143
+ className: "bootstrap__loading",
144
+ children: "Loading..."
145
+ }),
146
+ /* @__PURE__ */ jsx("div", {
147
+ className: "bootstrap-error",
148
+ children: "If this page fails to load, try a force refresh by holding the shift key while refreshing the page."
149
+ })
150
+ ]
151
+ })
152
+ }),
153
+ /* @__PURE__ */ jsx("script", {
154
+ dangerouslySetInnerHTML: {
155
+ __html: `window.__ROOT_CTX = ${JSON.stringify(props.ctx)}`
156
+ }
157
+ }),
158
+ /* @__PURE__ */ jsx("script", {
159
+ type: "module",
160
+ src: "{JS_URL}"
161
+ })
162
+ ]
163
+ })
164
+ ]
165
+ });
166
+ }
167
+ async function renderSignIn(req, res, options) {
168
+ const ctx = { firebaseConfig: options.firebaseConfig };
169
+ const mainHtml = renderToString(/* @__PURE__ */ jsx(SignIn, {
170
+ title: "Sign in",
171
+ ctx
172
+ }));
173
+ let html = `<!doctype html>
174
+ ${mainHtml}`;
175
+ if (req.viteServer) {
176
+ const cssPath = path.join(__dirname, "ui/signin.css");
177
+ const jsPath = path.join(__dirname, "ui/signin.js");
178
+ const tpl = html.replace("{CSS_URL}", `/@fs${cssPath}`).replace("{JS_URL}", `/@fs${jsPath}`);
179
+ html = await req.viteServer.transformIndexHtml(req.originalUrl, tpl);
180
+ } else {
181
+ html = html.replace("{CSS_URL}", "/cms/static/signin.css").replace("{JS_URL}", "/cms/static/signin.js");
182
+ }
183
+ res.setHeader("Content-Type", "text/html");
184
+ res.send(html);
185
+ }
186
+ export {
187
+ renderApp,
188
+ renderSignIn
189
+ };
190
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vY29yZS9hcHAudHN4Il0sCiAgInNvdXJjZXNDb250ZW50IjogWyJpbXBvcnQge1JlcXVlc3QsIFJlc3BvbnNlfSBmcm9tICdAYmxpbmtrL3Jvb3QnO1xuaW1wb3J0IHtDb2xsZWN0aW9ufSBmcm9tICcuL3NjaGVtYS5qcyc7XG5pbXBvcnQge3JlbmRlciBhcyByZW5kZXJUb1N0cmluZ30gZnJvbSAncHJlYWN0LXJlbmRlci10by1zdHJpbmcnO1xuaW1wb3J0IHBhdGggZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7ZmlsZVVSTFRvUGF0aH0gZnJvbSAnbm9kZTp1cmwnO1xuXG5jb25zdCBfX2Rpcm5hbWUgPSBwYXRoLmRpcm5hbWUoZmlsZVVSTFRvUGF0aChpbXBvcnQubWV0YS51cmwpKTtcblxuaW50ZXJmYWNlIEFwcFByb3BzIHtcbiAgdGl0bGU6IHN0cmluZztcbiAgY3R4OiBhbnk7XG59XG5cbmZ1bmN0aW9uIEFwcChwcm9wczogQXBwUHJvcHMpIHtcbiAgcmV0dXJuIChcbiAgICA8aHRtbD5cbiAgICAgIDxoZWFkPlxuICAgICAgICA8dGl0bGU+e3Byb3BzLnRpdGxlfTwvdGl0bGU+XG4gICAgICAgIDxsaW5rIHJlbD1cInByZWNvbm5lY3RcIiBocmVmPVwiaHR0cHM6Ly9mb250cy5nb29nbGVhcGlzLmNvbVwiIC8+XG4gICAgICAgIDxsaW5rXG4gICAgICAgICAgcmVsPVwicHJlY29ubmVjdFwiXG4gICAgICAgICAgaHJlZj1cImh0dHBzOi8vZm9udHMuZ3N0YXRpYy5jb21cIlxuICAgICAgICAgIGNyb3NzT3JpZ2luPVwiYW5vbnltb3VzXCJcbiAgICAgICAgLz5cbiAgICAgICAgPGxpbmtcbiAgICAgICAgICByZWw9XCJzdHlsZXNoZWV0XCJcbiAgICAgICAgICBocmVmPVwiaHR0cHM6Ly9mb250cy5nb29nbGVhcGlzLmNvbS9jc3MyP2ZhbWlseT1JbnRlcjp3Z2h0QDMwMDs0MDA7NTAwOzYwMDs3MDA7OTAwJmRpc3BsYXk9c3dhcFwiXG4gICAgICAgIC8+XG4gICAgICAgIDxsaW5rXG4gICAgICAgICAgcmVsPVwic3R5bGVzaGVldFwiXG4gICAgICAgICAgaHJlZj1cImh0dHBzOi8vZm9udHMuZ29vZ2xlYXBpcy5jb20vY3NzMj9mYW1pbHk9R29vZ2xlK1NhbnM6d2dodEA1MDAmZGlzcGxheT1zd2FwXCJcbiAgICAgICAgLz5cbiAgICAgICAgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIGhyZWY9XCJ7Q1NTX1VSTH1cIiAvPlxuICAgICAgPC9oZWFkPlxuICAgICAgPGJvZHk+XG4gICAgICAgIDxkaXYgaWQ9XCJyb290XCI+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJib290c3RyYXBcIj5cbiAgICAgICAgICAgIDxoMSBjbGFzc05hbWU9XCJib290c3RyYXBfX2xvYWRpbmdcIj5Mb2FkaW5nLi4uPC9oMT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYm9vdHN0cmFwLWVycm9yXCI+XG4gICAgICAgICAgICAgIElmIHRoaXMgcGFnZSBmYWlscyB0byBsb2FkLCB0cnkgYSBmb3JjZSByZWZyZXNoIGJ5IGhvbGRpbmcgdGhlXG4gICAgICAgICAgICAgIHNoaWZ0IGtleSB3aGlsZSByZWZyZXNoaW5nIHRoZSBwYWdlLlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8c2NyaXB0XG4gICAgICAgICAgZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUw9e3tcbiAgICAgICAgICAgIF9faHRtbDogYHdpbmRvdy5fX1JPT1RfQ1RYID0gJHtKU09OLnN0cmluZ2lmeShwcm9wcy5jdHgpfWAsXG4gICAgICAgICAgfX1cbiAgICAgICAgLz5cbiAgICAgICAgPHNjcmlwdCB0eXBlPVwibW9kdWxlXCIgc3JjPVwie0pTX1VSTH1cIj48L3NjcmlwdD5cbiAgICAgIDwvYm9keT5cbiAgICA8L2h0bWw+XG4gICk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZW5kZXJBcHAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBvcHRpb25zOiBhbnkpIHtcbiAgY29uc3QgY29sbGVjdGlvbk1vZHVsZXMgPSBpbXBvcnQubWV0YS5nbG9iKCcvY29sbGVjdGlvbnMvKi5zY2hlbWEudHMnLCB7XG4gICAgZWFnZXI6IHRydWUsXG4gIH0pIGFzIGFueTtcbiAgY29uc3QgY29sbGVjdGlvbnM6IFJlY29yZDxzdHJpbmcsIENvbGxlY3Rpb24+ID0ge307XG4gIE9iamVjdC5rZXlzKGNvbGxlY3Rpb25Nb2R1bGVzKS5mb3JFYWNoKChtb2R1bGVJZDogc3RyaW5nKSA9PiB7XG4gICAgY29uc3QgY29sbGVjdGlvbklkID0gcGF0aC5wYXJzZShtb2R1bGVJZCkuYmFzZS5zcGxpdCgnLicpWzBdO1xuICAgIGNvbnN0IG1vZHVsZSA9IGNvbGxlY3Rpb25Nb2R1bGVzW21vZHVsZUlkXTtcbiAgICBjb25zdCBjb2xsZWN0aW9uID0gbW9kdWxlLmRlZmF1bHQgYXMgQ29sbGVjdGlvbjtcbiAgICBjb2xsZWN0aW9uc1tjb2xsZWN0aW9uSWRdID0gY29sbGVjdGlvbjtcbiAgfSk7XG4gIGNvbnN0IHJvb3RDb25maWcgPSBvcHRpb25zLnJvb3RDb25maWcgfHwge307XG4gIGNvbnN0IGNtc0NvbmZpZyA9IG9wdGlvbnMuY21zQ29uZmlnIHx8IHt9O1xuICBjb25zdCBjdHggPSB7XG4gICAgcm9vdENvbmZpZzoge1xuICAgICAgcHJvamVjdElkOiBjbXNDb25maWcuaWQgfHwgJ2RlZmF1bHQnLFxuICAgICAgZG9tYWluOiByb290Q29uZmlnLmRvbWFpbiB8fCAnaHR0cHM6Ly9leGFtcGxlLmNvbScsXG4gICAgfSxcbiAgICBmaXJlYmFzZUNvbmZpZzogb3B0aW9ucy5maXJlYmFzZUNvbmZpZyxcbiAgICBjb2xsZWN0aW9uczogY29sbGVjdGlvbnMsXG4gIH07XG4gIGNvbnN0IG1haW5IdG1sID0gcmVuZGVyVG9TdHJpbmcoPEFwcCB0aXRsZT1cIlJvb3QuanMgQ01TXCIgY3R4PXtjdHh9IC8+KTtcbiAgbGV0IGh0bWwgPSBgPCFkb2N0eXBlIGh0bWw+XFxuJHttYWluSHRtbH1gO1xuICBpZiAocmVxLnZpdGVTZXJ2ZXIpIHtcbiAgICBjb25zdCB1aUNzc1BhdGggPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAndWkvdWkuY3NzJyk7XG4gICAgY29uc3QgdWlKc1BhdGggPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAndWkvdWkuanMnKTtcbiAgICBjb25zdCB0cGwgPSBodG1sXG4gICAgICAucmVwbGFjZSgne0NTU19VUkx9JywgYC9AZnMke3VpQ3NzUGF0aH1gKVxuICAgICAgLnJlcGxhY2UoJ3tKU19VUkx9JywgYC9AZnMke3VpSnNQYXRofWApO1xuICAgIGh0bWwgPSBhd2FpdCByZXEudml0ZVNlcnZlciEudHJhbnNmb3JtSW5kZXhIdG1sKHJlcS5vcmlnaW5hbFVybCwgdHBsKTtcbiAgfSBlbHNlIHtcbiAgICBodG1sID0gaHRtbFxuICAgICAgLnJlcGxhY2UoJ3tDU1NfVVJMfScsICcvY21zL3N0YXRpYy91aS5jc3MnKVxuICAgICAgLnJlcGxhY2UoJ3tKU19VUkx9JywgJy9jbXMvc3RhdGljL3VpLmpzJyk7XG4gIH1cbiAgcmVzLnNldEhlYWRlcignQ29udGVudC1UeXBlJywgJ3RleHQvaHRtbCcpO1xuICByZXMuc2VuZChodG1sKTtcbn1cblxuaW50ZXJmYWNlIFNpZ25JblByb3BzIHtcbiAgdGl0bGU6IHN0cmluZztcbiAgY3R4OiBhbnk7XG59XG5cbmZ1bmN0aW9uIFNpZ25Jbihwcm9wczogU2lnbkluUHJvcHMpIHtcbiAgcmV0dXJuIChcbiAgICA8aHRtbD5cbiAgICAgIDxoZWFkPlxuICAgICAgICA8dGl0bGU+e3Byb3BzLnRpdGxlfTwvdGl0bGU+XG4gICAgICAgIDxsaW5rIHJlbD1cInByZWNvbm5lY3RcIiBocmVmPVwiaHR0cHM6Ly9mb250cy5nb29nbGVhcGlzLmNvbVwiIC8+XG4gICAgICAgIDxsaW5rXG4gICAgICAgICAgcmVsPVwicHJlY29ubmVjdFwiXG4gICAgICAgICAgaHJlZj1cImh0dHBzOi8vZm9udHMuZ3N0YXRpYy5jb21cIlxuICAgICAgICAgIGNyb3NzT3JpZ2luPVwiYW5vbnltb3VzXCJcbiAgICAgICAgLz5cbiAgICAgICAgPGxpbmtcbiAgICAgICAgICByZWw9XCJzdHlsZXNoZWV0XCJcbiAgICAgICAgICBocmVmPVwiaHR0cHM6Ly9mb250cy5nb29nbGVhcGlzLmNvbS9jc3MyP2ZhbWlseT1JbnRlcjp3Z2h0QDMwMDs0MDA7NTAwOzYwMDs3MDA7OTAwJmRpc3BsYXk9c3dhcFwiXG4gICAgICAgIC8+XG4gICAgICAgIDxsaW5rIHJlbD1cInN0eWxlc2hlZXRcIiBocmVmPVwie0NTU19VUkx9XCIgLz5cbiAgICAgIDwvaGVhZD5cbiAgICAgIDxib2R5PlxuICAgICAgICA8ZGl2IGlkPVwicm9vdFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYm9vdHN0cmFwXCI+XG4gICAgICAgICAgICA8aDEgY2xhc3NOYW1lPVwiYm9vdHN0cmFwX19sb2FkaW5nXCI+TG9hZGluZy4uLjwvaDE+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImJvb3RzdHJhcC1lcnJvclwiPlxuICAgICAgICAgICAgICBJZiB0aGlzIHBhZ2UgZmFpbHMgdG8gbG9hZCwgdHJ5IGEgZm9yY2UgcmVmcmVzaCBieSBob2xkaW5nIHRoZVxuICAgICAgICAgICAgICBzaGlmdCBrZXkgd2hpbGUgcmVmcmVzaGluZyB0aGUgcGFnZS5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPHNjcmlwdFxuICAgICAgICAgIGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MPXt7XG4gICAgICAgICAgICBfX2h0bWw6IGB3aW5kb3cuX19ST09UX0NUWCA9ICR7SlNPTi5zdHJpbmdpZnkocHJvcHMuY3R4KX1gLFxuICAgICAgICAgIH19XG4gICAgICAgIC8+XG4gICAgICAgIDxzY3JpcHQgdHlwZT1cIm1vZHVsZVwiIHNyYz1cIntKU19VUkx9XCI+PC9zY3JpcHQ+XG4gICAgICA8L2JvZHk+XG4gICAgPC9odG1sPlxuICApO1xufVxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlbmRlclNpZ25JbihyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG9wdGlvbnM6IGFueSkge1xuICBjb25zdCBjdHggPSB7ZmlyZWJhc2VDb25maWc6IG9wdGlvbnMuZmlyZWJhc2VDb25maWd9O1xuICBjb25zdCBtYWluSHRtbCA9IHJlbmRlclRvU3RyaW5nKDxTaWduSW4gdGl0bGU9XCJTaWduIGluXCIgY3R4PXtjdHh9IC8+KTtcbiAgbGV0IGh0bWwgPSBgPCFkb2N0eXBlIGh0bWw+XFxuJHttYWluSHRtbH1gO1xuICBpZiAocmVxLnZpdGVTZXJ2ZXIpIHtcbiAgICBjb25zdCBjc3NQYXRoID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJ3VpL3NpZ25pbi5jc3MnKTtcbiAgICBjb25zdCBqc1BhdGggPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAndWkvc2lnbmluLmpzJyk7XG4gICAgY29uc3QgdHBsID0gaHRtbFxuICAgICAgLnJlcGxhY2UoJ3tDU1NfVVJMfScsIGAvQGZzJHtjc3NQYXRofWApXG4gICAgICAucmVwbGFjZSgne0pTX1VSTH0nLCBgL0BmcyR7anNQYXRofWApO1xuICAgIGh0bWwgPSBhd2FpdCByZXEudml0ZVNlcnZlciEudHJhbnNmb3JtSW5kZXhIdG1sKHJlcS5vcmlnaW5hbFVybCwgdHBsKTtcbiAgfSBlbHNlIHtcbiAgICBodG1sID0gaHRtbFxuICAgICAgLnJlcGxhY2UoJ3tDU1NfVVJMfScsICcvY21zL3N0YXRpYy9zaWduaW4uY3NzJylcbiAgICAgIC5yZXBsYWNlKCd7SlNfVVJMfScsICcvY21zL3N0YXRpYy9zaWduaW4uanMnKTtcbiAgfVxuICByZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAndGV4dC9odG1sJyk7XG4gIHJlcy5zZW5kKGh0bWwpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUVBLFNBQVEsVUFBVSxzQkFB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
package/dist/cli.js ADDED
@@ -0,0 +1,151 @@
1
+ // cli/commands/init-firebase.ts
2
+ async function initFirebase() {
3
+ console.log("initFirebase()");
4
+ }
5
+
6
+ // core/typegen.ts
7
+ import { promises as fs } from "node:fs";
8
+ import path from "node:path";
9
+ import { createRequire } from "module";
10
+ var require2 = createRequire(import.meta.url);
11
+ var dom = require2("dts-dom");
12
+ var TEMPLATE = `/** Root.js CMS types. This file is autogenerated. */
13
+
14
+ export interface RootCMSDoc<Fields extends {}> {
15
+ /** The id of the doc, e.g. "Pages/foo-bar". */
16
+ id: string;
17
+ /** The collection id of the doc, e.g. "Pages". */
18
+ collectionId: string;
19
+ /** The slug of the doc, e.g. "foo-bar". */
20
+ slug: string;
21
+ /** System-level metadata. */
22
+ sys: {
23
+ createdAt: number;
24
+ createdBy: string;
25
+ modifiedAt: number;
26
+ modifiedBy: string;
27
+ firstPublishedAt?: string;
28
+ firstPublishedBy?: string;
29
+ publishedAt?: string;
30
+ publishedBy?: string;
31
+ };
32
+ /** User-entered field values from the CMS. */
33
+ fields?: Fields;
34
+ }`;
35
+ async function generateSchemaDts(rootDir) {
36
+ console.log(`generating root-cms.d.ts from ${rootDir}...`);
37
+ const schemaModules = import.meta.glob("/**/*.schema.ts", {
38
+ eager: true
39
+ });
40
+ const results = [TEMPLATE];
41
+ for (const fileId in schemaModules) {
42
+ const schema = schemaModules[fileId].default;
43
+ results.push(renderSchema(fileId, schema));
44
+ }
45
+ const output = results.join("\n\n").replaceAll("/** ", "/** ").replaceAll(" */", " */").replace(/\r\n|\r|\n/g, "\n");
46
+ const outputPath = path.resolve(rootDir, "root-cms.d.ts");
47
+ await fs.writeFile(outputPath, output, "utf-8");
48
+ console.log("saved root-cms.d.ts");
49
+ }
50
+ function fieldProperty(field) {
51
+ const prop = dom.create.property(
52
+ field.id,
53
+ fieldType(field),
54
+ dom.DeclarationFlags.Optional
55
+ );
56
+ const jsdoc = [];
57
+ if (field.label) {
58
+ if (field.help) {
59
+ jsdoc.push(`${field.label}. ${field.help}`);
60
+ } else {
61
+ jsdoc.push(field.label);
62
+ }
63
+ }
64
+ if (field.deprecated) {
65
+ jsdoc.push("@deprecated");
66
+ }
67
+ if (jsdoc.length > 0) {
68
+ prop.jsDocComment = jsdoc.join("\n");
69
+ }
70
+ return prop;
71
+ }
72
+ function fieldType(field) {
73
+ if (field.type === "array") {
74
+ return dom.type.array(fieldType(field.of));
75
+ }
76
+ if (field.type === "image") {
77
+ return dom.create.objectType([
78
+ dom.create.property("src", dom.type.string),
79
+ dom.create.property(
80
+ "alt",
81
+ dom.type.string,
82
+ dom.DeclarationFlags.Optional
83
+ ),
84
+ dom.create.property(
85
+ "width",
86
+ dom.type.number,
87
+ dom.DeclarationFlags.Optional
88
+ ),
89
+ dom.create.property(
90
+ "height",
91
+ dom.type.number,
92
+ dom.DeclarationFlags.Optional
93
+ )
94
+ ]);
95
+ }
96
+ if (field.type === "multiselect") {
97
+ return dom.type.array(dom.type.string);
98
+ }
99
+ if (field.type === "select") {
100
+ return dom.type.string;
101
+ }
102
+ if (field.type === "string") {
103
+ return dom.type.string;
104
+ }
105
+ if (field.type === "object") {
106
+ const subproperties = (field.fields || []).map((f) => fieldProperty(f));
107
+ return dom.create.objectType(subproperties);
108
+ }
109
+ return dom.type.unknown;
110
+ }
111
+ function renderSchema(fileId, schema) {
112
+ const jsdoc = `Generated from \`${fileId}\`.`;
113
+ const id = path.parse(fileId).name.split(".")[0];
114
+ const fieldsInterface = `${id}Fields`;
115
+ const fields = dom.create.interface(
116
+ fieldsInterface,
117
+ dom.DeclarationFlags.Export
118
+ );
119
+ fields.jsDocComment = jsdoc;
120
+ for (const field of schema.fields) {
121
+ if (!field.id) {
122
+ continue;
123
+ }
124
+ fields.members.push(fieldProperty(field));
125
+ }
126
+ const fieldsTypeOutput = dom.emit(fields, { singleLineJsDocComments: true }).trim();
127
+ if (fileId.startsWith("/collections/")) {
128
+ const baseType = dom.create.namedTypeReference("RootCMSDoc");
129
+ baseType.typeArguments.push(dom.create.namedTypeReference(fieldsInterface));
130
+ const docType = dom.create.alias(
131
+ `${id}Doc`,
132
+ baseType,
133
+ dom.DeclarationFlags.Export
134
+ );
135
+ docType.jsDocComment = jsdoc;
136
+ const docTypeOutput = dom.emit(docType, { singleLineJsDocComments: true }).trim();
137
+ return fieldsTypeOutput + "\n\n" + docTypeOutput;
138
+ }
139
+ return fieldsTypeOutput;
140
+ }
141
+
142
+ // cli/commands/generate-types.ts
143
+ async function generateTypes() {
144
+ const rootDir = process.cwd();
145
+ generateSchemaDts(rootDir);
146
+ }
147
+ export {
148
+ generateTypes,
149
+ initFirebase
150
+ };
151
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vY2xpL2NvbW1hbmRzL2luaXQtZmlyZWJhc2UudHMiLCAiLi4vY29yZS90eXBlZ2VuLnRzIiwgIi4uL2NsaS9jb21tYW5kcy9nZW5lcmF0ZS10eXBlcy50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGluaXRGaXJlYmFzZSgpIHtcbiAgY29uc29sZS5sb2coJ2luaXRGaXJlYmFzZSgpJyk7XG59XG4iLCAiaW1wb3J0IHtwcm9taXNlcyBhcyBmc30gZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHtGaWVsZCwgU2NoZW1hfSBmcm9tICcuL3NjaGVtYS5qcyc7XG5cbi8vIGBkdHMtZG9tYCBoYXMgaXNzdWVzIHdpdGggdml0ZSBidW5kbGVyLCB3b3JrIGFyb3VuZCB3aXRoIGNyZWF0ZVJlcXVpcmUoKS5cbmltcG9ydCB7Y3JlYXRlUmVxdWlyZX0gZnJvbSAnbW9kdWxlJztcbmNvbnN0IHJlcXVpcmUgPSBjcmVhdGVSZXF1aXJlKGltcG9ydC5tZXRhLnVybCk7XG4vLyBpbXBvcnQgKiBhcyBkb20gZnJvbSAnZHRzLWRvbSc7XG5jb25zdCBkb20gPSByZXF1aXJlKCdkdHMtZG9tJyk7XG5cbi8vIFRoZSBgZHRzLWRvbWAgcGFja2FnZSB1c2VzIDQtc3BhY2UgaW5kZW50cywgdXNlIHRoZSBzYW1lIGZvciBjb25zaXN0ZW5jeS5cbmNvbnN0IFRFTVBMQVRFID0gYC8qKiBSb290LmpzIENNUyB0eXBlcy4gVGhpcyBmaWxlIGlzIGF1dG9nZW5lcmF0ZWQuICovXG5cbmV4cG9ydCBpbnRlcmZhY2UgUm9vdENNU0RvYzxGaWVsZHMgZXh0ZW5kcyB7fT4ge1xuICAgIC8qKiBUaGUgaWQgb2YgdGhlIGRvYywgZS5nLiBcIlBhZ2VzL2Zvby1iYXJcIi4gKi9cbiAgICBpZDogc3RyaW5nO1xuICAgIC8qKiBUaGUgY29sbGVjdGlvbiBpZCBvZiB0aGUgZG9jLCBlLmcuIFwiUGFnZXNcIi4gKi9cbiAgICBjb2xsZWN0aW9uSWQ6IHN0cmluZztcbiAgICAvKiogVGhlIHNsdWcgb2YgdGhlIGRvYywgZS5nLiBcImZvby1iYXJcIi4gKi9cbiAgICBzbHVnOiBzdHJpbmc7XG4gICAgLyoqIFN5c3RlbS1sZXZlbCBtZXRhZGF0YS4gKi9cbiAgICBzeXM6IHtcbiAgICAgICAgY3JlYXRlZEF0OiBudW1iZXI7XG4gICAgICAgIGNyZWF0ZWRCeTogc3RyaW5nO1xuICAgICAgICBtb2RpZmllZEF0OiBudW1iZXI7XG4gICAgICAgIG1vZGlmaWVkQnk6IHN0cmluZztcbiAgICAgICAgZmlyc3RQdWJsaXNoZWRBdD86IHN0cmluZztcbiAgICAgICAgZmlyc3RQdWJsaXNoZWRCeT86IHN0cmluZztcbiAgICAgICAgcHVibGlzaGVkQXQ/OiBzdHJpbmc7XG4gICAgICAgIHB1Ymxpc2hlZEJ5Pzogc3RyaW5nO1xuICAgIH07XG4gICAgLyoqIFVzZXItZW50ZXJlZCBmaWVsZCB2YWx1ZXMgZnJvbSB0aGUgQ01TLiAqL1xuICAgIGZpZWxkcz86IEZpZWxkcztcbn1gO1xuXG4vKipcbiAqIEdlbmVyYXRlcyBhIHJvb3QtY21zLmQudHMgZmlsZSBmcm9tIHRoZSAuc2NoZW1hLnRzIGZpbGVzIGluIHRoZSBwcm9qZWN0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVTY2hlbWFEdHMocm9vdERpcjogc3RyaW5nKSB7XG4gIGNvbnNvbGUubG9nKGBnZW5lcmF0aW5nIHJvb3QtY21zLmQudHMgZnJvbSAke3Jvb3REaXJ9Li4uYCk7XG4gIGNvbnN0IHNjaGVtYU1vZHVsZXMgPSBpbXBvcnQubWV0YS5nbG9iPHtkZWZhdWx0OiBTY2hlbWF9PignLyoqLyouc2NoZW1hLnRzJywge1xuICAgIGVhZ2VyOiB0cnVlLFxuICB9KTtcblxuICBjb25zdCByZXN1bHRzID0gW1RFTVBMQVRFXTtcbiAgZm9yIChjb25zdCBmaWxlSWQgaW4gc2NoZW1hTW9kdWxlcykge1xuICAgIGNvbnN0IHNjaGVtYSA9IHNjaGVtYU1vZHVsZXNbZmlsZUlkXS5kZWZhdWx0O1xuICAgIHJlc3VsdHMucHVzaChyZW5kZXJTY2hlbWEoZmlsZUlkLCBzY2hlbWEpKTtcbiAgfVxuXG4gIGNvbnN0IG91dHB1dCA9IHJlc3VsdHNcbiAgICAuam9pbignXFxuXFxuJylcbiAgICAucmVwbGFjZUFsbCgnLyoqICAnLCAnLyoqICcpXG4gICAgLnJlcGxhY2VBbGwoJyAgKi8nLCAnICovJylcbiAgICAucmVwbGFjZSgvXFxyXFxufFxccnxcXG4vZywgJ1xcbicpO1xuICBjb25zdCBvdXRwdXRQYXRoID0gcGF0aC5yZXNvbHZlKHJvb3REaXIsICdyb290LWNtcy5kLnRzJyk7XG4gIGF3YWl0IGZzLndyaXRlRmlsZShvdXRwdXRQYXRoLCBvdXRwdXQsICd1dGYtOCcpO1xuICBjb25zb2xlLmxvZygnc2F2ZWQgcm9vdC1jbXMuZC50cycpO1xufVxuXG5mdW5jdGlvbiBmaWVsZFByb3BlcnR5KGZpZWxkOiBGaWVsZCk6IGRvbS5Qcm9wZXJ0eURlY2xhcmF0aW9uIHtcbiAgY29uc3QgcHJvcCA9IGRvbS5jcmVhdGUucHJvcGVydHkoXG4gICAgZmllbGQuaWQhLFxuICAgIGZpZWxkVHlwZShmaWVsZCksXG4gICAgZG9tLkRlY2xhcmF0aW9uRmxhZ3MuT3B0aW9uYWxcbiAgKTtcbiAgY29uc3QganNkb2MgPSBbXTtcbiAgaWYgKGZpZWxkLmxhYmVsKSB7XG4gICAgaWYgKGZpZWxkLmhlbHApIHtcbiAgICAgIGpzZG9jLnB1c2goYCR7ZmllbGQubGFiZWx9LiAke2ZpZWxkLmhlbHB9YCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGpzZG9jLnB1c2goZmllbGQubGFiZWwpO1xuICAgIH1cbiAgfVxuICBpZiAoZmllbGQuZGVwcmVjYXRlZCkge1xuICAgIGpzZG9jLnB1c2goJ0BkZXByZWNhdGVkJyk7XG4gIH1cbiAgaWYgKGpzZG9jLmxlbmd0aCA+IDApIHtcbiAgICBwcm9wLmpzRG9jQ29tbWVudCA9IGpzZG9jLmpvaW4oJ1xcbicpO1xuICB9XG4gIHJldHVybiBwcm9wO1xufVxuXG5mdW5jdGlvbiBmaWVsZFR5cGUoZmllbGQ6IEZpZWxkKTogZG9tLlR5cGUge1xuICBpZiAoZmllbGQudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgIHJldHVybiBkb20udHlwZS5hcnJheShmaWVsZFR5cGUoZmllbGQub2YpKTtcbiAgfVxuICBpZiAoZmllbGQudHlwZSA9PT0gJ2ltYWdlJykge1xuICAgIHJldHVybiBkb20uY3JlYXRlLm9iamVjdFR5cGUoW1xuICAgICAgZG9tLmNyZWF0ZS5wcm9wZXJ0eSgnc3JjJywgZG9tLnR5cGUuc3RyaW5nKSxcbiAgICAgIGRvbS5jcmVhdGUucHJvcGVydHkoXG4gICAgICAgICdhbHQnLFxuICAgICAgICBkb20udHlwZS5zdHJpbmcsXG4gICAgICAgIGRvbS5EZWNsYXJhdGlvbkZsYWdzLk9wdGlvbmFsXG4gICAgICApLFxuICAgICAgZG9tLmNyZWF0ZS5wcm9wZXJ0eShcbiAgICAgICAgJ3dpZHRoJyxcbiAgICAgICAgZG9tLnR5cGUubnVtYmVyLFxuICAgICAgICBkb20uRGVjbGFyYXRpb25GbGFncy5PcHRpb25hbFxuICAgICAgKSxcbiAgICAgIGRvbS5jcmVhdGUucHJvcGVydHkoXG4gICAgICAgICdoZWlnaHQnLFxuICAgICAgICBkb20udHlwZS5udW1iZXIsXG4gICAgICAgIGRvbS5EZWNsYXJhdGlvbkZsYWdzLk9wdGlvbmFsXG4gICAgICApLFxuICAgIF0pO1xuICB9XG4gIGlmIChmaWVsZC50eXBlID09PSAnbXVsdGlzZWxlY3QnKSB7XG4gICAgcmV0dXJuIGRvbS50eXBlLmFycmF5KGRvbS50eXBlLnN0cmluZyk7XG4gIH1cbiAgaWYgKGZpZWxkLnR5cGUgPT09ICdzZWxlY3QnKSB7XG4gICAgcmV0dXJuIGRvbS50eXBlLnN0cmluZztcbiAgfVxuICBpZiAoZmllbGQudHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZG9tLnR5cGUuc3RyaW5nO1xuICB9XG4gIGlmIChmaWVsZC50eXBlID09PSAnb2JqZWN0Jykge1xuICAgIGNvbnN0IHN1YnByb3BlcnRpZXMgPSAoZmllbGQuZmllbGRzIHx8IFtdKS5tYXAoKGYpID0+IGZpZWxkUHJvcGVydHkoZikpO1xuICAgIHJldHVybiBkb20uY3JlYXRlLm9iamVjdFR5cGUoc3VicHJvcGVydGllcyk7XG4gIH1cbiAgcmV0dXJuIGRvbS50eXBlLnVua25vd247XG59XG5cbmZ1bmN0aW9uIHJlbmRlclNjaGVtYShmaWxlSWQ6IHN0cmluZywgc2NoZW1hOiBTY2hlbWEpOiBzdHJpbmcge1xuICBjb25zdCBqc2RvYyA9IGBHZW5lcmF0ZWQgZnJvbSBcXGAke2ZpbGVJZH1cXGAuYDtcbiAgY29uc3QgaWQgPSBwYXRoLnBhcnNlKGZpbGVJZCkubmFtZS5zcGxpdCgnLicpWzBdO1xuICBjb25zdCBmaWVsZHNJbnRlcmZhY2UgPSBgJHtpZH1GaWVsZHNgO1xuICBjb25zdCBmaWVsZHMgPSBkb20uY3JlYXRlLmludGVyZmFjZShcbiAgICBmaWVsZHNJbnRlcmZhY2UsXG4gICAgZG9tLkRlY2xhcmF0aW9uRmxhZ3MuRXhwb3J0XG4gICk7XG4gIGZpZWxkcy5qc0RvY0NvbW1lbnQgPSBqc2RvYztcbiAgZm9yIChjb25zdCBmaWVsZCBvZiBzY2hlbWEuZmllbGRzKSB7XG4gICAgaWYgKCFmaWVsZC5pZCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGZpZWxkcy5tZW1iZXJzLnB1c2goZmllbGRQcm9wZXJ0eShmaWVsZCkpO1xuICB9XG5cbiAgY29uc3QgZmllbGRzVHlwZU91dHB1dCA9IGRvbVxuICAgIC5lbWl0KGZpZWxkcywge3NpbmdsZUxpbmVKc0RvY0NvbW1lbnRzOiB0cnVlfSlcbiAgICAudHJpbSgpO1xuICBpZiAoZmlsZUlkLnN0YXJ0c1dpdGgoJy9jb2xsZWN0aW9ucy8nKSkge1xuICAgIGNvbnN0IGJhc2VUeXBlID0gZG9tLmNyZWF0ZS5uYW1lZFR5cGVSZWZlcmVuY2UoJ1Jvb3RDTVNEb2MnKTtcbiAgICBiYXNlVHlwZS50eXBlQXJndW1lbnRzLnB1c2goZG9tLmNyZWF0ZS5uYW1lZFR5cGVSZWZlcmVuY2UoZmllbGRzSW50ZXJmYWNlKSk7XG4gICAgY29uc3QgZG9jVHlwZSA9IGRvbS5jcmVhdGUuYWxpYXMoXG4gICAgICBgJHtpZH1Eb2NgLFxuICAgICAgYmFzZVR5cGUsXG4gICAgICBkb20uRGVjbGFyYXRpb25GbGFncy5FeHBvcnRcbiAgICApO1xuICAgIGRvY1R5cGUuanNEb2NDb21tZW50ID0ganNkb2M7XG5cbiAgICBjb25zdCBkb2NUeXBlT3V0cHV0ID0gZG9tXG4gICAgICAuZW1pdChkb2NUeXBlLCB7c2luZ2xlTGluZUpzRG9jQ29tbWVudHM6IHRydWV9KVxuICAgICAgLnRyaW0oKTtcbiAgICByZXR1cm4gZmllbGRzVHlwZU91dHB1dCArICdcXG5cXG4nICsgZG9jVHlwZU91dHB1dDtcbiAgfVxuICByZXR1cm4gZmllbGRzVHlwZU91dHB1dDtcbn1cbiIsICJpbXBvcnQge2dlbmVyYXRlU2NoZW1hRHRzfSBmcm9tICcuLi8uLi9jb3JlL3R5cGVnZW4nO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVUeXBlcygpIHtcbiAgY29uc3Qgcm9vdERpciA9IHByb2Nlc3MuY3dkKCk7XG4gIGdlbmVyYXRlU2NoZW1hRHRzKHJvb3REaXIpO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUFBLGVBQXNCLGVBQWU7QUFDbkMsVUFBUSxJQUFJLGdCQUFnQjtBQUM5Qjs7O0FDRkEsU0FBUSxZQUFZLFVBQVM7QUFDN0IsT0FBTyxVQUFVO0FBSWpCLFNBQVEscUJBQW9CO0FBQzVCLElBQU1BLFdBQVUsY0FBYyxZQUFZLEdBQUc7QUFFN0MsSUFBTSxNQUFNQSxTQUFRLFNBQVM7QUFHN0IsSUFBTSxXQUFXO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUEyQmpCLGVBQXNC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
package/dist/core.d.ts ADDED
@@ -0,0 +1,218 @@
1
+ import { FunctionalComponent } from 'preact';
2
+ import { RootConfig } from '@blinkk/root';
3
+ import { CMSPlugin } from './plugin.js';
4
+ import 'firebase-admin/auth';
5
+
6
+ interface CommonFieldProps {
7
+ type: string;
8
+ id?: string;
9
+ label?: string;
10
+ help?: string;
11
+ placeholder?: string;
12
+ default?: any;
13
+ hidden?: boolean;
14
+ deprecated?: boolean;
15
+ }
16
+ type StringField = CommonFieldProps & {
17
+ type: 'string';
18
+ default?: string;
19
+ translate?: boolean;
20
+ variant?: 'input' | 'textarea';
21
+ };
22
+ declare function string(field: Omit<StringField, 'type'>): StringField;
23
+ type NumberField = CommonFieldProps & {
24
+ type: 'number';
25
+ default?: number;
26
+ };
27
+ declare function number(field: Omit<NumberField, 'type'>): NumberField;
28
+ type DateField = CommonFieldProps & {
29
+ type: 'date';
30
+ default?: string;
31
+ };
32
+ declare function date(field: Omit<DateField, 'type'>): DateField;
33
+ type DateTimeField = CommonFieldProps & {
34
+ type: 'datetime';
35
+ default?: string;
36
+ };
37
+ declare function datetime(field: Omit<DateTimeField, 'type'>): DateTimeField;
38
+ type BooleanField = CommonFieldProps & {
39
+ type: 'boolean';
40
+ default?: boolean;
41
+ };
42
+ declare function boolean(field: Omit<BooleanField, 'type'>): BooleanField;
43
+ type SelectField = CommonFieldProps & {
44
+ type: 'select';
45
+ default?: string;
46
+ options?: Array<{
47
+ value: string;
48
+ label?: string;
49
+ }> | string[];
50
+ };
51
+ declare function select(field: Omit<SelectField, 'type'>): SelectField;
52
+ type MultiSelectField = Omit<SelectField, 'type'> & {
53
+ type: 'multiselect';
54
+ /** Set to `true` to allow users to create arbitrary values. */
55
+ creatable?: boolean;
56
+ };
57
+ declare function multiselect(field: Omit<MultiSelectField, 'type'>): MultiSelectField;
58
+ type ImageField = CommonFieldProps & {
59
+ type: 'image';
60
+ };
61
+ declare function image(field: Omit<ImageField, 'type'>): ImageField;
62
+ type ObjectField = CommonFieldProps & {
63
+ type: 'object';
64
+ fields: FieldWithId[];
65
+ };
66
+ declare function object(field: Omit<ObjectField, 'type'>): ObjectField;
67
+ type ArrayField = CommonFieldProps & {
68
+ type: 'array';
69
+ default?: any[];
70
+ /**
71
+ * String format for the preview line of an item in the array. Placeholder
72
+ * values should use brackets, e.g. `m{_index:02}: {_type}`.
73
+ *
74
+ * Multiple values can be provided, in which case the first preview line with
75
+ * no missing placeholder values will be used.
76
+ *
77
+ * System added placeholder values:
78
+ *
79
+ * - _index: The 0-based index.
80
+ * - _index:02: A left-padded version of _index to 2 digits.
81
+ * - _index:03: A left-padded version of _index to 3 digits.
82
+ * - _type: For array of one-of fields, the type of the selected field.
83
+ */
84
+ preview?: string | string[];
85
+ of: ObjectLikeField;
86
+ };
87
+ declare function array(field: Omit<ArrayField, 'type'>): ArrayField;
88
+ type OneOfField = CommonFieldProps & {
89
+ type: 'oneof';
90
+ types: Schema[];
91
+ };
92
+ declare function oneOf(field: Omit<OneOfField, 'type'>): OneOfField;
93
+ type Field = StringField | NumberField | DateField | DateTimeField | BooleanField | SelectField | MultiSelectField | ImageField | ObjectField | ArrayField | OneOfField;
94
+ /**
95
+ * Similar to {@link Field} but with a required `id`.
96
+ * TODO(stevenle): fix this.
97
+ */
98
+ type FieldWithId = Field;
99
+ type ObjectLikeField = ImageField | ObjectField | OneOfField;
100
+ interface Schema {
101
+ name: string;
102
+ description?: string;
103
+ fields: FieldWithId[];
104
+ }
105
+ declare function defineSchema(schema: Schema): Schema;
106
+ /** Defines the schema for a collection or reusable component. */
107
+ declare const define: typeof defineSchema;
108
+ type Collection = Schema & {
109
+ /** URL path where the collection serves from. */
110
+ url?: string;
111
+ /** Page component to render the collection for instant previews */
112
+ Component?: FunctionalComponent;
113
+ /**
114
+ * Defines the fields to use for document preview. Defaults to "title" and
115
+ * "image". Use dot notation for nested fields, e.g. "meta.title".
116
+ */
117
+ preview?: {
118
+ title?: string;
119
+ image?: string;
120
+ };
121
+ };
122
+ declare function defineCollection(collection: Collection): Collection;
123
+ declare const collection: typeof defineCollection;
124
+
125
+ type schema_CommonFieldProps = CommonFieldProps;
126
+ type schema_StringField = StringField;
127
+ declare const schema_string: typeof string;
128
+ type schema_NumberField = NumberField;
129
+ declare const schema_number: typeof number;
130
+ type schema_DateField = DateField;
131
+ declare const schema_date: typeof date;
132
+ type schema_DateTimeField = DateTimeField;
133
+ declare const schema_datetime: typeof datetime;
134
+ type schema_BooleanField = BooleanField;
135
+ declare const schema_boolean: typeof boolean;
136
+ type schema_SelectField = SelectField;
137
+ declare const schema_select: typeof select;
138
+ type schema_MultiSelectField = MultiSelectField;
139
+ declare const schema_multiselect: typeof multiselect;
140
+ type schema_ImageField = ImageField;
141
+ declare const schema_image: typeof image;
142
+ type schema_ObjectField = ObjectField;
143
+ declare const schema_object: typeof object;
144
+ type schema_ArrayField = ArrayField;
145
+ declare const schema_array: typeof array;
146
+ type schema_OneOfField = OneOfField;
147
+ declare const schema_oneOf: typeof oneOf;
148
+ type schema_Field = Field;
149
+ type schema_FieldWithId = FieldWithId;
150
+ type schema_ObjectLikeField = ObjectLikeField;
151
+ type schema_Schema = Schema;
152
+ declare const schema_defineSchema: typeof defineSchema;
153
+ declare const schema_define: typeof define;
154
+ type schema_Collection = Collection;
155
+ declare const schema_defineCollection: typeof defineCollection;
156
+ declare const schema_collection: typeof collection;
157
+ declare namespace schema {
158
+ export {
159
+ schema_CommonFieldProps as CommonFieldProps,
160
+ schema_StringField as StringField,
161
+ schema_string as string,
162
+ schema_NumberField as NumberField,
163
+ schema_number as number,
164
+ schema_DateField as DateField,
165
+ schema_date as date,
166
+ schema_DateTimeField as DateTimeField,
167
+ schema_datetime as datetime,
168
+ schema_BooleanField as BooleanField,
169
+ schema_boolean as boolean,
170
+ schema_SelectField as SelectField,
171
+ schema_select as select,
172
+ schema_MultiSelectField as MultiSelectField,
173
+ schema_multiselect as multiselect,
174
+ schema_ImageField as ImageField,
175
+ schema_image as image,
176
+ schema_ObjectField as ObjectField,
177
+ schema_object as object,
178
+ schema_ArrayField as ArrayField,
179
+ schema_array as array,
180
+ schema_OneOfField as OneOfField,
181
+ schema_oneOf as oneOf,
182
+ schema_Field as Field,
183
+ schema_FieldWithId as FieldWithId,
184
+ schema_ObjectLikeField as ObjectLikeField,
185
+ schema_Schema as Schema,
186
+ schema_defineSchema as defineSchema,
187
+ schema_define as define,
188
+ schema_Collection as Collection,
189
+ schema_defineCollection as defineCollection,
190
+ schema_collection as collection,
191
+ };
192
+ }
193
+
194
+ /**
195
+ * Retrieves a doc from Root.js CMS.
196
+ */
197
+ declare function getDoc<T>(rootConfig: RootConfig, collectionId: string, slug: string, options: {
198
+ mode: 'draft' | 'published';
199
+ }): Promise<T | null>;
200
+ /**
201
+ * Walks the data tree and converts any Timestamp objects to millis and any
202
+ * _array maps to normal arrays.
203
+ *
204
+ * E.g.:
205
+ *
206
+ * normalizeData({
207
+ * sys: {modifiedAt: Timestamp(123)},
208
+ * fields: {
209
+ * _array: ['asdf'],
210
+ * asdf: {title: 'hello'}
211
+ * }
212
+ * })
213
+ * // => {sys: {modifiedAt: 123}, fields: {foo: [{title: 'hello'}]}}
214
+ */
215
+ declare function normalizeData(data: any): any;
216
+ declare function getCmsPlugin(rootConfig: RootConfig): CMSPlugin;
217
+
218
+ export { getCmsPlugin, getDoc, normalizeData, schema };