@blinkk/root-cms 2.5.16 → 3.0.1-alpha.1
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 +6 -8
- package/dist/{chunk-JGLMVZE4.js → chunk-BBOESYH7.js} +10 -14
- package/dist/{chunk-HDIPAT3C.js → chunk-R4LKO3EZ.js} +25 -25
- package/dist/{chunk-JUCNU5AP.js → chunk-SNZ4S4IC.js} +23 -83
- package/dist/chunk-UTSL2E2P.js +921 -0
- package/dist/cli.js +1 -1
- package/dist/{client-B_oDIGeJ.d.ts → client-DdB4xpM6.d.ts} +127 -35
- package/dist/client.d.ts +2 -2
- package/dist/client.js +1 -1
- package/dist/core.d.ts +3 -3
- package/dist/core.js +7 -1
- package/dist/functions.js +2 -2
- package/dist/plugin.d.ts +2 -2
- package/dist/plugin.js +88 -4
- package/dist/project.d.ts +3 -16
- package/dist/project.js +1 -3
- package/dist/{schema-D7MOj-YC.d.ts → schema-rjBOZk-j.d.ts} +61 -1
- package/dist/ui/signin.css +1 -1
- package/dist/ui/signin.js +3 -3
- package/dist/ui/ui.css +1 -1
- package/dist/ui/ui.js +166 -160
- package/dist/ui/ui.js.LEGAL.txt +14 -3
- package/package.json +11 -15
- package/dist/chunk-DKM5LHW3.js +0 -157
package/dist/app.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getServerVersion
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-BBOESYH7.js";
|
|
4
4
|
import {
|
|
5
5
|
getCollectionSchema,
|
|
6
6
|
getProjectSchemas
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-R4LKO3EZ.js";
|
|
8
8
|
import "./chunk-MLKGABMK.js";
|
|
9
9
|
|
|
10
10
|
// core/app.tsx
|
|
11
11
|
import crypto from "crypto";
|
|
12
12
|
import path from "path";
|
|
13
|
-
import {
|
|
13
|
+
import { renderJsxToString } from "@blinkk/root/jsx";
|
|
14
14
|
import { jsx, jsxs } from "preact/jsx-runtime";
|
|
15
15
|
var DEFAULT_FAVICON_URL = "https://lh3.googleusercontent.com/ijK50TfQlV_yJw3i-CMlnD6osH4PboZBILZrJcWhoNMEmoyCD5e1bAxXbaOPe5w4gG_Scf37EXrmZ6p8sP2lue5fLZ419m5JyLMs=e385-w256";
|
|
16
16
|
function App(props) {
|
|
@@ -139,7 +139,7 @@ async function renderApp(req, res, options) {
|
|
|
139
139
|
};
|
|
140
140
|
const projectName = cmsConfig.name || cmsConfig.id || "";
|
|
141
141
|
const title = getCmsTitle(projectName, cmsConfig.minimalBranding);
|
|
142
|
-
const mainHtml =
|
|
142
|
+
const mainHtml = renderJsxToString(
|
|
143
143
|
/* @__PURE__ */ jsx(App, { title, ctx, favicon: cmsConfig.favicon })
|
|
144
144
|
);
|
|
145
145
|
const nonce = generateNonce();
|
|
@@ -234,10 +234,8 @@ async function renderSignIn(req, res, options) {
|
|
|
234
234
|
ctx.warning = "Dev warning: Server may be misconfigured. See logs for more information.";
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
const mainHtml = renderToString(
|
|
240
|
-
/* @__PURE__ */ jsx(SignIn, { title, ctx, favicon: options.cmsConfig.favicon })
|
|
237
|
+
const mainHtml = renderJsxToString(
|
|
238
|
+
/* @__PURE__ */ jsx(SignIn, { title: "Sign in", ctx, favicon: options.cmsConfig.favicon })
|
|
241
239
|
);
|
|
242
240
|
const nonce = generateNonce();
|
|
243
241
|
const html = `<!doctype html>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// package.json
|
|
2
2
|
var package_default = {
|
|
3
3
|
name: "@blinkk/root-cms",
|
|
4
|
-
version: "
|
|
4
|
+
version: "3.0.1-alpha.1",
|
|
5
5
|
author: "s@blinkk.com",
|
|
6
6
|
license: "MIT",
|
|
7
7
|
engines: {
|
|
@@ -12,9 +12,6 @@ var package_default = {
|
|
|
12
12
|
url: "git+https://github.com/blinkk/rootjs.git",
|
|
13
13
|
directory: "packages/root-cms"
|
|
14
14
|
},
|
|
15
|
-
publishConfig: {
|
|
16
|
-
provenance: true
|
|
17
|
-
},
|
|
18
15
|
files: [
|
|
19
16
|
"dist/**/*"
|
|
20
17
|
],
|
|
@@ -88,10 +85,12 @@ var package_default = {
|
|
|
88
85
|
"date-fns-tz": "3.2.0",
|
|
89
86
|
diff: "8.0.2",
|
|
90
87
|
"dts-dom": "3.7.0",
|
|
88
|
+
"@mantine/spotlight": "4.2.12",
|
|
91
89
|
"fnv-plus": "1.3.1",
|
|
92
90
|
genkit: "1.26.0",
|
|
93
91
|
jsonwebtoken: "9.0.2",
|
|
94
92
|
kleur: "4.1.5",
|
|
93
|
+
minisearch: "7.2.0",
|
|
95
94
|
sirv: "2.0.3",
|
|
96
95
|
"tiny-glob": "0.2.9"
|
|
97
96
|
},
|
|
@@ -125,7 +124,6 @@ var package_default = {
|
|
|
125
124
|
"@mantine/hooks": "4.2.12",
|
|
126
125
|
"@mantine/modals": "4.2.12",
|
|
127
126
|
"@mantine/notifications": "4.2.12",
|
|
128
|
-
"@mantine/spotlight": "4.2.12",
|
|
129
127
|
"@preact/compat": "18.3.1",
|
|
130
128
|
"@tabler/icons-preact": "3.35.0",
|
|
131
129
|
"@testing-library/preact": "3.2.4",
|
|
@@ -138,8 +136,8 @@ var package_default = {
|
|
|
138
136
|
"@types/google.accounts": "0.0.14",
|
|
139
137
|
"@types/jsonwebtoken": "9.0.1",
|
|
140
138
|
"@types/node": "24.3.1",
|
|
141
|
-
"@vitest/browser": "4.
|
|
142
|
-
"@vitest/browser-playwright": "4.
|
|
139
|
+
"@vitest/browser": "4.1.2",
|
|
140
|
+
"@vitest/browser-playwright": "4.1.2",
|
|
143
141
|
concurrently: "7.6.0",
|
|
144
142
|
esbuild: "0.25.9",
|
|
145
143
|
firebase: "12.2.1",
|
|
@@ -157,23 +155,21 @@ var package_default = {
|
|
|
157
155
|
playwright: "1.56.1",
|
|
158
156
|
preact: "10.27.1",
|
|
159
157
|
"preact-iso": "2.11.1",
|
|
160
|
-
"preact-render-to-string": "6.6.
|
|
158
|
+
"preact-render-to-string": "6.6.7",
|
|
161
159
|
react: "npm:@preact/compat@18.3.1",
|
|
162
160
|
"react-dom": "npm:@preact/compat@18.3.1",
|
|
163
161
|
"react-easy-crop": "5.5.6",
|
|
164
162
|
"react-json-view-compare": "2.0.2",
|
|
165
163
|
tsup: "8.5.0",
|
|
166
164
|
typescript: "5.9.2",
|
|
167
|
-
vite: "
|
|
168
|
-
vitest: "4.
|
|
165
|
+
vite: "8.0.3",
|
|
166
|
+
vitest: "4.1.2",
|
|
169
167
|
yjs: "13.6.27"
|
|
170
168
|
},
|
|
171
169
|
peerDependencies: {
|
|
172
|
-
"@blinkk/root": "
|
|
170
|
+
"@blinkk/root": "3.0.1-alpha.1",
|
|
173
171
|
"firebase-admin": ">=11",
|
|
174
|
-
"firebase-functions": ">=4"
|
|
175
|
-
preact: ">=10",
|
|
176
|
-
"preact-render-to-string": ">=5"
|
|
172
|
+
"firebase-functions": ">=4"
|
|
177
173
|
},
|
|
178
174
|
peerDependenciesMeta: {
|
|
179
175
|
"firebase-functions": {
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
// core/project.ts
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
{ eager: true }
|
|
10
|
-
);
|
|
2
|
+
var _SCHEMA_MODULES = {};
|
|
3
|
+
try {
|
|
4
|
+
const mod = await import("virtual:root/schemas");
|
|
5
|
+
_SCHEMA_MODULES = mod.SCHEMA_MODULES || {};
|
|
6
|
+
} catch {
|
|
7
|
+
}
|
|
8
|
+
var SCHEMA_MODULES = _SCHEMA_MODULES;
|
|
11
9
|
function getProjectSchemas() {
|
|
12
10
|
const schemas = {};
|
|
13
11
|
for (const fileId in SCHEMA_MODULES) {
|
|
@@ -57,10 +55,10 @@ function testValidCollectionId(id) {
|
|
|
57
55
|
function isSchemaPattern(value) {
|
|
58
56
|
return typeof value === "object" && value !== null && "_schemaPattern" in value && value._schemaPattern === true;
|
|
59
57
|
}
|
|
60
|
-
function buildSchemaNameMap(
|
|
58
|
+
function buildSchemaNameMap() {
|
|
61
59
|
const nameMap = {};
|
|
62
|
-
for (const fileId in
|
|
63
|
-
const module =
|
|
60
|
+
for (const fileId in SCHEMA_MODULES) {
|
|
61
|
+
const module = SCHEMA_MODULES[fileId];
|
|
64
62
|
if (module.default && module.default.name) {
|
|
65
63
|
nameMap[module.default.name] = module.default;
|
|
66
64
|
}
|
|
@@ -71,16 +69,16 @@ function globToRegex(pattern) {
|
|
|
71
69
|
const regexStr = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "{{DOUBLE_STAR}}").replace(/\*/g, "[^/]*").replace(/\{\{DOUBLE_STAR\}\}/g, ".*");
|
|
72
70
|
return new RegExp(`^${regexStr}$`);
|
|
73
71
|
}
|
|
74
|
-
function resolveSchemaPattern(pattern
|
|
72
|
+
function resolveSchemaPattern(pattern) {
|
|
75
73
|
const regex = globToRegex(pattern.pattern);
|
|
76
74
|
const excludeSet = new Set(pattern.exclude || []);
|
|
77
75
|
const names = [];
|
|
78
76
|
const schemas = {};
|
|
79
|
-
for (const fileId in
|
|
77
|
+
for (const fileId in SCHEMA_MODULES) {
|
|
80
78
|
if (!regex.test(fileId)) {
|
|
81
79
|
continue;
|
|
82
80
|
}
|
|
83
|
-
const module =
|
|
81
|
+
const module = SCHEMA_MODULES[fileId];
|
|
84
82
|
if (!module.default || !module.default.name) {
|
|
85
83
|
continue;
|
|
86
84
|
}
|
|
@@ -88,25 +86,28 @@ function resolveSchemaPattern(pattern, schemaModules = SCHEMA_MODULES) {
|
|
|
88
86
|
if (excludeSet.has(schemaName)) {
|
|
89
87
|
continue;
|
|
90
88
|
}
|
|
91
|
-
|
|
89
|
+
let schemaObj = module.default;
|
|
92
90
|
if (pattern.omitFields && pattern.omitFields.length > 0) {
|
|
93
91
|
const omitSet = new Set(pattern.omitFields);
|
|
94
|
-
schemaObj
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
schemaObj = {
|
|
93
|
+
...schemaObj,
|
|
94
|
+
fields: schemaObj.fields.filter(
|
|
95
|
+
(f) => !omitSet.has(f.id || "")
|
|
96
|
+
)
|
|
97
|
+
};
|
|
97
98
|
}
|
|
98
99
|
names.push(schemaName);
|
|
99
100
|
schemas[schemaName] = schemaObj;
|
|
100
101
|
}
|
|
101
102
|
return { names, schemas };
|
|
102
103
|
}
|
|
103
|
-
function convertOneOfTypes(collection
|
|
104
|
+
function convertOneOfTypes(collection) {
|
|
104
105
|
const clone = structuredClone(collection);
|
|
105
106
|
const types = clone.types || {};
|
|
106
|
-
const schemaNameMap = buildSchemaNameMap(
|
|
107
|
+
const schemaNameMap = buildSchemaNameMap();
|
|
107
108
|
function handleOneOfField(field) {
|
|
108
109
|
if (isSchemaPattern(field.types)) {
|
|
109
|
-
const resolved = resolveSchemaPattern(field.types
|
|
110
|
+
const resolved = resolveSchemaPattern(field.types);
|
|
110
111
|
for (const [name, schemaObj] of Object.entries(resolved.schemas)) {
|
|
111
112
|
if (!types[name]) {
|
|
112
113
|
types[name] = schemaObj;
|
|
@@ -123,7 +124,7 @@ function convertOneOfTypes(collection, schemaModules = SCHEMA_MODULES) {
|
|
|
123
124
|
if (typeof sub === "string") {
|
|
124
125
|
names.push(sub);
|
|
125
126
|
if (!types[sub] && schemaNameMap[sub]) {
|
|
126
|
-
const resolvedSchema =
|
|
127
|
+
const resolvedSchema = schemaNameMap[sub];
|
|
127
128
|
types[sub] = resolvedSchema;
|
|
128
129
|
if (resolvedSchema.fields) {
|
|
129
130
|
walk(resolvedSchema);
|
|
@@ -165,6 +166,5 @@ export {
|
|
|
165
166
|
SCHEMA_MODULES,
|
|
166
167
|
getProjectSchemas,
|
|
167
168
|
resolveOneOfPatterns,
|
|
168
|
-
getCollectionSchema
|
|
169
|
-
convertOneOfTypes
|
|
169
|
+
getCollectionSchema
|
|
170
170
|
};
|
|
@@ -1501,41 +1501,10 @@ ${errorMessages}`);
|
|
|
1501
1501
|
const docRef = this.db.doc(dbPath);
|
|
1502
1502
|
const doc = await docRef.get();
|
|
1503
1503
|
if (doc.exists) {
|
|
1504
|
-
|
|
1505
|
-
if (dataSource.archivedAt) {
|
|
1506
|
-
console.warn(
|
|
1507
|
-
`warning: data source "${dataSourceId}" is archived` + (dataSource.archivedBy ? ` (archived by ${dataSource.archivedBy})` : "")
|
|
1508
|
-
);
|
|
1509
|
-
}
|
|
1510
|
-
return dataSource;
|
|
1504
|
+
return doc.data();
|
|
1511
1505
|
}
|
|
1512
1506
|
return null;
|
|
1513
1507
|
}
|
|
1514
|
-
/**
|
|
1515
|
-
* Archives a data source. Archived data sources cannot be synced or published.
|
|
1516
|
-
*/
|
|
1517
|
-
async archiveDataSource(dataSourceId, options) {
|
|
1518
|
-
const dbPath = `Projects/${this.projectId}/DataSources/${dataSourceId}`;
|
|
1519
|
-
const docRef = this.db.doc(dbPath);
|
|
1520
|
-
const archivedBy = options?.archivedBy || "root-cms-client";
|
|
1521
|
-
await docRef.update({
|
|
1522
|
-
archivedAt: Timestamp2.now(),
|
|
1523
|
-
archivedBy
|
|
1524
|
-
});
|
|
1525
|
-
console.log(`archived data source: ${dataSourceId}`);
|
|
1526
|
-
}
|
|
1527
|
-
/**
|
|
1528
|
-
* Unarchives a data source.
|
|
1529
|
-
*/
|
|
1530
|
-
async unarchiveDataSource(dataSourceId) {
|
|
1531
|
-
const dbPath = `Projects/${this.projectId}/DataSources/${dataSourceId}`;
|
|
1532
|
-
const docRef = this.db.doc(dbPath);
|
|
1533
|
-
await docRef.update({
|
|
1534
|
-
archivedAt: FieldValue2.delete(),
|
|
1535
|
-
archivedBy: FieldValue2.delete()
|
|
1536
|
-
});
|
|
1537
|
-
console.log(`unarchived data source: ${dataSourceId}`);
|
|
1538
|
-
}
|
|
1539
1508
|
/**
|
|
1540
1509
|
* Syncs a data source to draft state.
|
|
1541
1510
|
*/
|
|
@@ -1544,9 +1513,6 @@ ${errorMessages}`);
|
|
|
1544
1513
|
if (!dataSource) {
|
|
1545
1514
|
throw new Error(`data source not found: ${dataSourceId}`);
|
|
1546
1515
|
}
|
|
1547
|
-
if (dataSource.archivedAt) {
|
|
1548
|
-
throw new Error(`data source is archived: ${dataSourceId}`);
|
|
1549
|
-
}
|
|
1550
1516
|
const result = await this.fetchData(dataSource);
|
|
1551
1517
|
const dataSourceDocRef = this.db.doc(
|
|
1552
1518
|
`Projects/${this.projectId}/DataSources/${dataSourceId}`
|
|
@@ -1579,9 +1545,6 @@ ${errorMessages}`);
|
|
|
1579
1545
|
if (!dataSource) {
|
|
1580
1546
|
throw new Error(`data source not found: ${dataSourceId}`);
|
|
1581
1547
|
}
|
|
1582
|
-
if (dataSource.archivedAt) {
|
|
1583
|
-
throw new Error(`data source is archived: ${dataSourceId}`);
|
|
1584
|
-
}
|
|
1585
1548
|
const dataSourceDocRef = this.db.doc(
|
|
1586
1549
|
`Projects/${this.projectId}/DataSources/${dataSourceId}`
|
|
1587
1550
|
);
|
|
@@ -1615,40 +1578,6 @@ ${errorMessages}`);
|
|
|
1615
1578
|
console.log(`published data ${dataSourceId}`);
|
|
1616
1579
|
console.log(`published by: ${publishedBy}`);
|
|
1617
1580
|
}
|
|
1618
|
-
/**
|
|
1619
|
-
* Unpublishes a data source. Removes the `publishedAt`/`publishedBy`
|
|
1620
|
-
* metadata from the DataSource doc and deletes the `Data/published` doc.
|
|
1621
|
-
*/
|
|
1622
|
-
async unpublishDataSource(dataSourceId) {
|
|
1623
|
-
const dataSource = await this.getDataSource(dataSourceId);
|
|
1624
|
-
if (!dataSource) {
|
|
1625
|
-
throw new Error(`data source not found: ${dataSourceId}`);
|
|
1626
|
-
}
|
|
1627
|
-
const dataSourceDocRef = this.db.doc(
|
|
1628
|
-
`Projects/${this.projectId}/DataSources/${dataSourceId}`
|
|
1629
|
-
);
|
|
1630
|
-
const dataDocRefDraft = this.db.doc(
|
|
1631
|
-
`Projects/${this.projectId}/DataSources/${dataSourceId}/Data/draft`
|
|
1632
|
-
);
|
|
1633
|
-
const dataDocRefPublished = this.db.doc(
|
|
1634
|
-
`Projects/${this.projectId}/DataSources/${dataSourceId}/Data/published`
|
|
1635
|
-
);
|
|
1636
|
-
const batch = this.db.batch();
|
|
1637
|
-
batch.update(dataSourceDocRef, {
|
|
1638
|
-
publishedAt: FieldValue2.delete(),
|
|
1639
|
-
publishedBy: FieldValue2.delete()
|
|
1640
|
-
});
|
|
1641
|
-
const draftSnapshot = await dataDocRefDraft.get();
|
|
1642
|
-
if (draftSnapshot.exists) {
|
|
1643
|
-
batch.update(dataDocRefDraft, {
|
|
1644
|
-
"dataSource.publishedAt": FieldValue2.delete(),
|
|
1645
|
-
"dataSource.publishedBy": FieldValue2.delete()
|
|
1646
|
-
});
|
|
1647
|
-
}
|
|
1648
|
-
batch.delete(dataDocRefPublished);
|
|
1649
|
-
await batch.commit();
|
|
1650
|
-
console.log(`unpublished data source: ${dataSourceId}`);
|
|
1651
|
-
}
|
|
1652
1581
|
async publishDataSources(dataSourceIds, options) {
|
|
1653
1582
|
const publishedBy = options?.publishedBy || "root-cms-client";
|
|
1654
1583
|
const batch = options?.batch || this.db.batch();
|
|
@@ -1657,9 +1586,6 @@ ${errorMessages}`);
|
|
|
1657
1586
|
if (!dataSource) {
|
|
1658
1587
|
throw new Error(`data source not found: ${id}`);
|
|
1659
1588
|
}
|
|
1660
|
-
if (dataSource.archivedAt) {
|
|
1661
|
-
throw new Error(`data source is archived: ${id}`);
|
|
1662
|
-
}
|
|
1663
1589
|
const dataSourceDocRef = this.db.doc(
|
|
1664
1590
|
`Projects/${this.projectId}/DataSources/${id}`
|
|
1665
1591
|
);
|
|
@@ -1825,14 +1751,7 @@ ${errorMessages}`);
|
|
|
1825
1751
|
const docRef = this.dbDataSourceDataRef(dataSourceId, { mode });
|
|
1826
1752
|
const doc = await docRef.get();
|
|
1827
1753
|
if (doc.exists) {
|
|
1828
|
-
|
|
1829
|
-
if (dataSourceData.dataSource?.archivedAt) {
|
|
1830
|
-
const archivedBy = dataSourceData.dataSource.archivedBy;
|
|
1831
|
-
console.warn(
|
|
1832
|
-
`warning: data source "${dataSourceId}" is archived` + (archivedBy ? ` (archived by ${archivedBy})` : "")
|
|
1833
|
-
);
|
|
1834
|
-
}
|
|
1835
|
-
return dataSourceData;
|
|
1754
|
+
return doc.data();
|
|
1836
1755
|
}
|
|
1837
1756
|
return null;
|
|
1838
1757
|
}
|
|
@@ -1947,6 +1866,27 @@ ${errorMessages}`);
|
|
|
1947
1866
|
console.error(err);
|
|
1948
1867
|
}
|
|
1949
1868
|
}
|
|
1869
|
+
const notifications = cmsPluginConfig.notifications;
|
|
1870
|
+
if (notifications && notifications.length > 0) {
|
|
1871
|
+
const ctx = {
|
|
1872
|
+
rootConfig: this.rootConfig,
|
|
1873
|
+
cmsClient: this,
|
|
1874
|
+
user: data.by ? { email: data.by } : void 0
|
|
1875
|
+
};
|
|
1876
|
+
for (const service of notifications) {
|
|
1877
|
+
if (!service.onAction) {
|
|
1878
|
+
continue;
|
|
1879
|
+
}
|
|
1880
|
+
try {
|
|
1881
|
+
await service.onAction(ctx, data);
|
|
1882
|
+
} catch (err) {
|
|
1883
|
+
console.error(
|
|
1884
|
+
`notification service "${service.id}" onAction failed:`,
|
|
1885
|
+
err
|
|
1886
|
+
);
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
}
|
|
1950
1890
|
}
|
|
1951
1891
|
/**
|
|
1952
1892
|
* Creates a batch request that is capable of fetching one or more docs,
|