@caretcms/core 0.1.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.
- package/LICENSE +21 -0
- package/README.md +191 -0
- package/dist/browser-runtime.d.ts +12 -0
- package/dist/browser-runtime.d.ts.map +1 -0
- package/dist/browser-runtime.js +298 -0
- package/dist/browser-runtime.js.map +1 -0
- package/dist/index.d.ts +81 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +343 -0
- package/dist/index.js.map +1 -0
- package/dist/loader.d.ts +61 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +80 -0
- package/dist/loader.js.map +1 -0
- package/dist/providers/storage/filesystem.d.ts +7 -0
- package/dist/providers/storage/filesystem.d.ts.map +1 -0
- package/dist/providers/storage/filesystem.js +6 -0
- package/dist/providers/storage/filesystem.js.map +1 -0
- package/dist/providers/uploads/local.d.ts +6 -0
- package/dist/providers/uploads/local.d.ts.map +1 -0
- package/dist/providers/uploads/local.js +6 -0
- package/dist/providers/uploads/local.js.map +1 -0
- package/dist/runtime/auth/cookie-utils.d.ts +3 -0
- package/dist/runtime/auth/cookie-utils.d.ts.map +1 -0
- package/dist/runtime/auth/cookie-utils.js +33 -0
- package/dist/runtime/auth/cookie-utils.js.map +1 -0
- package/dist/runtime/auth/demo-session.d.ts +24 -0
- package/dist/runtime/auth/demo-session.d.ts.map +1 -0
- package/dist/runtime/auth/demo-session.js +42 -0
- package/dist/runtime/auth/demo-session.js.map +1 -0
- package/dist/runtime/auth/rate-limiter.d.ts +26 -0
- package/dist/runtime/auth/rate-limiter.d.ts.map +1 -0
- package/dist/runtime/auth/rate-limiter.js +65 -0
- package/dist/runtime/auth/rate-limiter.js.map +1 -0
- package/dist/runtime/auth/session.d.ts +14 -0
- package/dist/runtime/auth/session.d.ts.map +1 -0
- package/dist/runtime/auth/session.js +128 -0
- package/dist/runtime/auth/session.js.map +1 -0
- package/dist/runtime/bind.d.ts +14 -0
- package/dist/runtime/bind.d.ts.map +1 -0
- package/dist/runtime/bind.js +19 -0
- package/dist/runtime/bind.js.map +1 -0
- package/dist/runtime/config.d.ts +20 -0
- package/dist/runtime/config.d.ts.map +1 -0
- package/dist/runtime/config.js +40 -0
- package/dist/runtime/config.js.map +1 -0
- package/dist/runtime/content.d.ts +28 -0
- package/dist/runtime/content.d.ts.map +1 -0
- package/dist/runtime/content.js +37 -0
- package/dist/runtime/content.js.map +1 -0
- package/dist/runtime/index.d.ts +14 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +16 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/middleware.d.ts +14 -0
- package/dist/runtime/middleware.d.ts.map +1 -0
- package/dist/runtime/middleware.js +80 -0
- package/dist/runtime/middleware.js.map +1 -0
- package/dist/runtime/mutations/contracts.d.ts +91 -0
- package/dist/runtime/mutations/contracts.d.ts.map +1 -0
- package/dist/runtime/mutations/contracts.js +320 -0
- package/dist/runtime/mutations/contracts.js.map +1 -0
- package/dist/runtime/mutations/engine.d.ts +23 -0
- package/dist/runtime/mutations/engine.d.ts.map +1 -0
- package/dist/runtime/mutations/engine.js +255 -0
- package/dist/runtime/mutations/engine.js.map +1 -0
- package/dist/runtime/providers.d.ts +9 -0
- package/dist/runtime/providers.d.ts.map +1 -0
- package/dist/runtime/providers.js +44 -0
- package/dist/runtime/providers.js.map +1 -0
- package/dist/runtime/request-context.d.ts +11 -0
- package/dist/runtime/request-context.d.ts.map +1 -0
- package/dist/runtime/request-context.js +16 -0
- package/dist/runtime/request-context.js.map +1 -0
- package/dist/runtime/rewrite.d.ts +13 -0
- package/dist/runtime/rewrite.d.ts.map +1 -0
- package/dist/runtime/rewrite.js +253 -0
- package/dist/runtime/rewrite.js.map +1 -0
- package/dist/runtime/routes/_helpers.d.ts +17 -0
- package/dist/runtime/routes/_helpers.d.ts.map +1 -0
- package/dist/runtime/routes/_helpers.js +38 -0
- package/dist/runtime/routes/_helpers.js.map +1 -0
- package/dist/runtime/routes/admin-entry.d.ts +3 -0
- package/dist/runtime/routes/admin-entry.d.ts.map +1 -0
- package/dist/runtime/routes/admin-entry.js +170 -0
- package/dist/runtime/routes/admin-entry.js.map +1 -0
- package/dist/runtime/routes/admin.d.ts +3 -0
- package/dist/runtime/routes/admin.d.ts.map +1 -0
- package/dist/runtime/routes/admin.js +189 -0
- package/dist/runtime/routes/admin.js.map +1 -0
- package/dist/runtime/routes/auth-login.d.ts +4 -0
- package/dist/runtime/routes/auth-login.d.ts.map +1 -0
- package/dist/runtime/routes/auth-login.js +71 -0
- package/dist/runtime/routes/auth-login.js.map +1 -0
- package/dist/runtime/routes/auth-logout.d.ts +4 -0
- package/dist/runtime/routes/auth-logout.d.ts.map +1 -0
- package/dist/runtime/routes/auth-logout.js +47 -0
- package/dist/runtime/routes/auth-logout.js.map +1 -0
- package/dist/runtime/routes/auth-session.d.ts +3 -0
- package/dist/runtime/routes/auth-session.d.ts.map +1 -0
- package/dist/runtime/routes/auth-session.js +8 -0
- package/dist/runtime/routes/auth-session.js.map +1 -0
- package/dist/runtime/routes/collection-list.d.ts +3 -0
- package/dist/runtime/routes/collection-list.d.ts.map +1 -0
- package/dist/runtime/routes/collection-list.js +420 -0
- package/dist/runtime/routes/collection-list.js.map +1 -0
- package/dist/runtime/routes/collections-metadata.d.ts +3 -0
- package/dist/runtime/routes/collections-metadata.d.ts.map +1 -0
- package/dist/runtime/routes/collections-metadata.js +17 -0
- package/dist/runtime/routes/collections-metadata.js.map +1 -0
- package/dist/runtime/routes/editor-assets.d.ts +3 -0
- package/dist/runtime/routes/editor-assets.d.ts.map +1 -0
- package/dist/runtime/routes/editor-assets.js +73 -0
- package/dist/runtime/routes/editor-assets.js.map +1 -0
- package/dist/runtime/routes/entries.d.ts +3 -0
- package/dist/runtime/routes/entries.d.ts.map +1 -0
- package/dist/runtime/routes/entries.js +96 -0
- package/dist/runtime/routes/entries.js.map +1 -0
- package/dist/runtime/routes/history.d.ts +4 -0
- package/dist/runtime/routes/history.d.ts.map +1 -0
- package/dist/runtime/routes/history.js +54 -0
- package/dist/runtime/routes/history.js.map +1 -0
- package/dist/runtime/routes/mutate.d.ts +4 -0
- package/dist/runtime/routes/mutate.d.ts.map +1 -0
- package/dist/runtime/routes/mutate.js +38 -0
- package/dist/runtime/routes/mutate.js.map +1 -0
- package/dist/runtime/routes/schema.d.ts +3 -0
- package/dist/runtime/routes/schema.d.ts.map +1 -0
- package/dist/runtime/routes/schema.js +58 -0
- package/dist/runtime/routes/schema.js.map +1 -0
- package/dist/runtime/routes/studio-home.d.ts +3 -0
- package/dist/runtime/routes/studio-home.d.ts.map +1 -0
- package/dist/runtime/routes/studio-home.js +99 -0
- package/dist/runtime/routes/studio-home.js.map +1 -0
- package/dist/runtime/routes/theme-stylesheet.d.ts +3 -0
- package/dist/runtime/routes/theme-stylesheet.d.ts.map +1 -0
- package/dist/runtime/routes/theme-stylesheet.js +32 -0
- package/dist/runtime/routes/theme-stylesheet.js.map +1 -0
- package/dist/runtime/routes/upload.d.ts +3 -0
- package/dist/runtime/routes/upload.d.ts.map +1 -0
- package/dist/runtime/routes/upload.js +33 -0
- package/dist/runtime/routes/upload.js.map +1 -0
- package/dist/runtime/sanitize-html.d.ts +8 -0
- package/dist/runtime/sanitize-html.d.ts.map +1 -0
- package/dist/runtime/sanitize-html.js +86 -0
- package/dist/runtime/sanitize-html.js.map +1 -0
- package/dist/runtime/schema/template.d.ts +15 -0
- package/dist/runtime/schema/template.d.ts.map +1 -0
- package/dist/runtime/schema/template.js +38 -0
- package/dist/runtime/schema/template.js.map +1 -0
- package/dist/runtime/schema-registry.d.ts +17 -0
- package/dist/runtime/schema-registry.d.ts.map +1 -0
- package/dist/runtime/schema-registry.js +16 -0
- package/dist/runtime/schema-registry.js.map +1 -0
- package/dist/runtime/storage/filesystem-adapter.d.ts +36 -0
- package/dist/runtime/storage/filesystem-adapter.d.ts.map +1 -0
- package/dist/runtime/storage/filesystem-adapter.js +291 -0
- package/dist/runtime/storage/filesystem-adapter.js.map +1 -0
- package/dist/runtime/storage/filesystem-upload-handler.d.ts +11 -0
- package/dist/runtime/storage/filesystem-upload-handler.d.ts.map +1 -0
- package/dist/runtime/storage/filesystem-upload-handler.js +20 -0
- package/dist/runtime/storage/filesystem-upload-handler.js.map +1 -0
- package/dist/runtime/storage/image-validation.d.ts +28 -0
- package/dist/runtime/storage/image-validation.d.ts.map +1 -0
- package/dist/runtime/storage/image-validation.js +94 -0
- package/dist/runtime/storage/image-validation.js.map +1 -0
- package/dist/runtime/storage/in-memory-adapter.d.ts +29 -0
- package/dist/runtime/storage/in-memory-adapter.d.ts.map +1 -0
- package/dist/runtime/storage/in-memory-adapter.js +110 -0
- package/dist/runtime/storage/in-memory-adapter.js.map +1 -0
- package/dist/runtime/storage/quota-upload-handler.d.ts +27 -0
- package/dist/runtime/storage/quota-upload-handler.d.ts.map +1 -0
- package/dist/runtime/storage/quota-upload-handler.js +34 -0
- package/dist/runtime/storage/quota-upload-handler.js.map +1 -0
- package/dist/runtime/storage/session-overlay-adapter.d.ts +33 -0
- package/dist/runtime/storage/session-overlay-adapter.d.ts.map +1 -0
- package/dist/runtime/storage/session-overlay-adapter.js +121 -0
- package/dist/runtime/storage/session-overlay-adapter.js.map +1 -0
- package/dist/runtime/themes/preset-tokens.d.ts +17 -0
- package/dist/runtime/themes/preset-tokens.d.ts.map +1 -0
- package/dist/runtime/themes/preset-tokens.js +47 -0
- package/dist/runtime/themes/preset-tokens.js.map +1 -0
- package/dist/runtime/utils.d.ts +6 -0
- package/dist/runtime/utils.d.ts.map +1 -0
- package/dist/runtime/utils.js +29 -0
- package/dist/runtime/utils.js.map +1 -0
- package/dist/runtime/views/studio-layout.d.ts +25 -0
- package/dist/runtime/views/studio-layout.d.ts.map +1 -0
- package/dist/runtime/views/studio-layout.js +108 -0
- package/dist/runtime/views/studio-layout.js.map +1 -0
- package/dist/schema-utils.d.ts +16 -0
- package/dist/schema-utils.d.ts.map +1 -0
- package/dist/schema-utils.js +62 -0
- package/dist/schema-utils.js.map +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/editor-runtime.d.ts +6 -0
- package/editor-runtime.js +2 -0
- package/package.json +88 -0
- package/static/cms/admin-entry.css +207 -0
- package/static/cms/admin-entry.js +1083 -0
- package/static/cms/editor/config.js +118 -0
- package/static/cms/editor/content-map.css +141 -0
- package/static/cms/editor/content-map.js +172 -0
- package/static/cms/editor/guards.js +72 -0
- package/static/cms/editor/helpers.js +51 -0
- package/static/cms/editor/image-edit.js +151 -0
- package/static/cms/editor/image-utils.js +84 -0
- package/static/cms/editor/image.css +133 -0
- package/static/cms/editor/link-follow.js +144 -0
- package/static/cms/editor/link-ui.css +199 -0
- package/static/cms/editor/linkify.js +55 -0
- package/static/cms/editor/panel.css +91 -0
- package/static/cms/editor/panel.js +70 -0
- package/static/cms/editor/rich-toolbar.css +67 -0
- package/static/cms/editor/rich-toolbar.js +200 -0
- package/static/cms/editor/sanitize.js +89 -0
- package/static/cms/editor/save-queue.js +166 -0
- package/static/cms/editor/section-controls/activation.js +10 -0
- package/static/cms/editor/section-controls/api.js +87 -0
- package/static/cms/editor/section-controls/constants.js +24 -0
- package/static/cms/editor/section-controls/index.js +622 -0
- package/static/cms/editor/section-controls/model.js +76 -0
- package/static/cms/editor/section-controls/mutations.js +112 -0
- package/static/cms/editor/section-controls/page-context.js +34 -0
- package/static/cms/editor/section-controls/pickers.js +196 -0
- package/static/cms/editor/section-controls/reorder.js +92 -0
- package/static/cms/editor/section-controls/selection.js +54 -0
- package/static/cms/editor/section-controls/spacing-drag.js +83 -0
- package/static/cms/editor/section-controls/ui-elements.js +54 -0
- package/static/cms/editor/section-controls/utils.js +35 -0
- package/static/cms/editor/section-controls.css +349 -0
- package/static/cms/editor/section-controls.js +1 -0
- package/static/cms/editor/security.js +48 -0
- package/static/cms/editor/sync.js +72 -0
- package/static/cms/editor/text-edit.js +151 -0
- package/static/cms/editor/text-link-interactions.js +254 -0
- package/static/cms/editor/toast.css +50 -0
- package/static/cms/editor/toast.js +29 -0
- package/static/cms/editor/tokens-and-text.css +93 -0
- package/static/cms/editor/toolbar.css +249 -0
- package/static/cms/editor/toolbar.js +117 -0
- package/static/cms/editor.css +12 -0
- package/static/cms/editor.js +116 -0
- package/static/cms/studio-login.css +300 -0
- package/static/cms/studio-tokens.css +85 -0
- package/static/cms/studio.css +437 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { CollectionMetadata, EntryData, HistoryEntry, StorageAdapter } from "../../types.js";
|
|
2
|
+
export declare class InMemoryAdapter implements StorageAdapter {
|
|
3
|
+
private collections;
|
|
4
|
+
private revisions;
|
|
5
|
+
private history;
|
|
6
|
+
private collectionMeta;
|
|
7
|
+
private revisionKey;
|
|
8
|
+
/** Preload entries for testing or demo bootstrap. */
|
|
9
|
+
preload(collection: string, entries: Array<{
|
|
10
|
+
id: string;
|
|
11
|
+
data: Record<string, unknown>;
|
|
12
|
+
}>): void;
|
|
13
|
+
discoverCollections(): Promise<string[]>;
|
|
14
|
+
isKnownCollection(collection: string): Promise<boolean>;
|
|
15
|
+
getEntry(collection: string, id: string): Promise<EntryData | null>;
|
|
16
|
+
listEntryIds(collection: string): Promise<string[]>;
|
|
17
|
+
listEntries(collection: string): Promise<EntryData[]>;
|
|
18
|
+
writeEntry(collection: string, id: string, data: Record<string, unknown>): Promise<void>;
|
|
19
|
+
deleteEntry(collection: string, id: string): Promise<void>;
|
|
20
|
+
getRevision(collection: string, id: string): Promise<number>;
|
|
21
|
+
bumpRevision(collection: string, id: string): Promise<number>;
|
|
22
|
+
getHistory(collection: string, id: string): Promise<HistoryEntry[]>;
|
|
23
|
+
appendHistory(collection: string, id: string, entry: HistoryEntry): Promise<void>;
|
|
24
|
+
createCollection(metadata: CollectionMetadata): Promise<void>;
|
|
25
|
+
deleteCollection(collection: string): Promise<void>;
|
|
26
|
+
getCollectionMetadata(collection: string): Promise<CollectionMetadata | null>;
|
|
27
|
+
listCollectionMetadata(): Promise<CollectionMetadata[]>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=in-memory-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-adapter.d.ts","sourceRoot":"","sources":["../../../src/runtime/storage/in-memory-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAIlG,qBAAa,eAAgB,YAAW,cAAc;IACpD,OAAO,CAAC,WAAW,CAA2D;IAC9E,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,cAAc,CAAyC;IAE/D,OAAO,CAAC,WAAW;IAInB,qDAAqD;IACrD,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,GAAG,IAAI;IAW1F,mBAAmB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIxC,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvD,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAMnE,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAMnD,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAQrD,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IASxF,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1D,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI5D,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ7D,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAKnE,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IASjF,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAO7D,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBnD,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAK7E,sBAAsB,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;CAK9D"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const HISTORY_LIMIT = 50;
|
|
2
|
+
export class InMemoryAdapter {
|
|
3
|
+
collections = new Map();
|
|
4
|
+
revisions = new Map();
|
|
5
|
+
history = new Map();
|
|
6
|
+
collectionMeta = new Map();
|
|
7
|
+
revisionKey(collection, id) {
|
|
8
|
+
return `${collection}::${id}`;
|
|
9
|
+
}
|
|
10
|
+
/** Preload entries for testing or demo bootstrap. */
|
|
11
|
+
preload(collection, entries) {
|
|
12
|
+
let col = this.collections.get(collection);
|
|
13
|
+
if (!col) {
|
|
14
|
+
col = new Map();
|
|
15
|
+
this.collections.set(collection, col);
|
|
16
|
+
}
|
|
17
|
+
for (const entry of entries) {
|
|
18
|
+
col.set(entry.id, structuredClone(entry.data));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async discoverCollections() {
|
|
22
|
+
return [...this.collections.keys()].sort((a, b) => a.localeCompare(b));
|
|
23
|
+
}
|
|
24
|
+
async isKnownCollection(collection) {
|
|
25
|
+
return this.collections.has(collection);
|
|
26
|
+
}
|
|
27
|
+
async getEntry(collection, id) {
|
|
28
|
+
const data = this.collections.get(collection)?.get(id);
|
|
29
|
+
if (!data)
|
|
30
|
+
return null;
|
|
31
|
+
return { id, data: structuredClone(data) };
|
|
32
|
+
}
|
|
33
|
+
async listEntryIds(collection) {
|
|
34
|
+
const col = this.collections.get(collection);
|
|
35
|
+
if (!col)
|
|
36
|
+
return [];
|
|
37
|
+
return [...col.keys()].sort((a, b) => a.localeCompare(b));
|
|
38
|
+
}
|
|
39
|
+
async listEntries(collection) {
|
|
40
|
+
const col = this.collections.get(collection);
|
|
41
|
+
if (!col)
|
|
42
|
+
return [];
|
|
43
|
+
return [...col.entries()]
|
|
44
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
45
|
+
.map(([id, data]) => ({ id, data: structuredClone(data) }));
|
|
46
|
+
}
|
|
47
|
+
async writeEntry(collection, id, data) {
|
|
48
|
+
let col = this.collections.get(collection);
|
|
49
|
+
if (!col) {
|
|
50
|
+
col = new Map();
|
|
51
|
+
this.collections.set(collection, col);
|
|
52
|
+
}
|
|
53
|
+
col.set(id, structuredClone(data));
|
|
54
|
+
}
|
|
55
|
+
async deleteEntry(collection, id) {
|
|
56
|
+
this.collections.get(collection)?.delete(id);
|
|
57
|
+
}
|
|
58
|
+
async getRevision(collection, id) {
|
|
59
|
+
return this.revisions.get(this.revisionKey(collection, id)) ?? 0;
|
|
60
|
+
}
|
|
61
|
+
async bumpRevision(collection, id) {
|
|
62
|
+
const key = this.revisionKey(collection, id);
|
|
63
|
+
const current = this.revisions.get(key) ?? 0;
|
|
64
|
+
const next = current + 1;
|
|
65
|
+
this.revisions.set(key, next);
|
|
66
|
+
return next;
|
|
67
|
+
}
|
|
68
|
+
async getHistory(collection, id) {
|
|
69
|
+
const entries = this.history.get(this.revisionKey(collection, id));
|
|
70
|
+
return entries ? structuredClone(entries) : [];
|
|
71
|
+
}
|
|
72
|
+
async appendHistory(collection, id, entry) {
|
|
73
|
+
const key = this.revisionKey(collection, id);
|
|
74
|
+
const current = this.history.get(key) ?? [];
|
|
75
|
+
const next = [structuredClone(entry), ...current].slice(0, HISTORY_LIMIT);
|
|
76
|
+
this.history.set(key, next);
|
|
77
|
+
}
|
|
78
|
+
// --- Collection Management ---
|
|
79
|
+
async createCollection(metadata) {
|
|
80
|
+
this.collectionMeta.set(metadata.id, structuredClone(metadata));
|
|
81
|
+
if (!this.collections.has(metadata.id)) {
|
|
82
|
+
this.collections.set(metadata.id, new Map());
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async deleteCollection(collection) {
|
|
86
|
+
this.collectionMeta.delete(collection);
|
|
87
|
+
this.collections.delete(collection);
|
|
88
|
+
// Clear revisions and history for this collection
|
|
89
|
+
const keysToDelete = [];
|
|
90
|
+
this.revisions.forEach((_, key) => {
|
|
91
|
+
if (key.startsWith(`${collection}::`)) {
|
|
92
|
+
keysToDelete.push(key);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
keysToDelete.forEach((key) => {
|
|
96
|
+
this.revisions.delete(key);
|
|
97
|
+
this.history.delete(key);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async getCollectionMetadata(collection) {
|
|
101
|
+
const meta = this.collectionMeta.get(collection);
|
|
102
|
+
return meta ? structuredClone(meta) : null;
|
|
103
|
+
}
|
|
104
|
+
async listCollectionMetadata() {
|
|
105
|
+
return [...this.collectionMeta.values()]
|
|
106
|
+
.map((m) => structuredClone(m))
|
|
107
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=in-memory-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-adapter.js","sourceRoot":"","sources":["../../../src/runtime/storage/in-memory-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { UploadHandler, UploadContext } from "../../types.js";
|
|
2
|
+
export interface QuotaCounter {
|
|
3
|
+
read(sessionId: string): Promise<number>;
|
|
4
|
+
write(sessionId: string, used: number): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export interface QuotaUploadHandlerOptions {
|
|
7
|
+
inner: UploadHandler;
|
|
8
|
+
counter: QuotaCounter;
|
|
9
|
+
perSessionBytes?: number;
|
|
10
|
+
perFileBytes?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Decorates an UploadHandler with per-session size limits. Reads the running
|
|
14
|
+
* session usage from the supplied counter, rejects oversized files, and
|
|
15
|
+
* persists the new total after each successful upload.
|
|
16
|
+
*/
|
|
17
|
+
export declare class QuotaUploadHandler implements UploadHandler {
|
|
18
|
+
private readonly inner;
|
|
19
|
+
private readonly counter;
|
|
20
|
+
private readonly perSessionBytes;
|
|
21
|
+
private readonly perFileBytes;
|
|
22
|
+
constructor(options: QuotaUploadHandlerOptions);
|
|
23
|
+
upload(file: File, ctx?: UploadContext): Promise<{
|
|
24
|
+
url: string;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=quota-upload-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota-upload-handler.d.ts","sourceRoot":"","sources":["../../../src/runtime/storage/quota-upload-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,EAAE,YAAY,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,aAAa;IACtD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,OAAO,EAAE,yBAAyB;IAOxC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CAmBxE"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decorates an UploadHandler with per-session size limits. Reads the running
|
|
3
|
+
* session usage from the supplied counter, rejects oversized files, and
|
|
4
|
+
* persists the new total after each successful upload.
|
|
5
|
+
*/
|
|
6
|
+
export class QuotaUploadHandler {
|
|
7
|
+
inner;
|
|
8
|
+
counter;
|
|
9
|
+
perSessionBytes;
|
|
10
|
+
perFileBytes;
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this.inner = options.inner;
|
|
13
|
+
this.counter = options.counter;
|
|
14
|
+
this.perSessionBytes = options.perSessionBytes ?? 25 * 1024 * 1024;
|
|
15
|
+
this.perFileBytes = options.perFileBytes ?? 5 * 1024 * 1024;
|
|
16
|
+
}
|
|
17
|
+
async upload(file, ctx) {
|
|
18
|
+
if (!ctx?.sessionId) {
|
|
19
|
+
return this.inner.upload(file, ctx);
|
|
20
|
+
}
|
|
21
|
+
if (file.size > this.perFileBytes) {
|
|
22
|
+
const limitMb = Math.floor(this.perFileBytes / (1024 * 1024));
|
|
23
|
+
throw new Error(`File too large (${limitMb}MB max in sandbox)`);
|
|
24
|
+
}
|
|
25
|
+
const used = await this.counter.read(ctx.sessionId);
|
|
26
|
+
if (used + file.size > this.perSessionBytes) {
|
|
27
|
+
throw new Error("Sandbox storage full — close this tab to start a fresh session.");
|
|
28
|
+
}
|
|
29
|
+
const result = await this.inner.upload(file, ctx);
|
|
30
|
+
await this.counter.write(ctx.sessionId, used + file.size);
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=quota-upload-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota-upload-handler.js","sourceRoot":"","sources":["../../../src/runtime/storage/quota-upload-handler.ts"],"names":[],"mappings":"AAcA;;;;GAIG;AACH,MAAM,OAAO,kBAAkB;IACZ,KAAK,CAAgB;IACrB,OAAO,CAAe;IACtB,eAAe,CAAS;IACxB,YAAY,CAAS;IAEtC,YAAY,OAAkC;QAC5C,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;QACnE,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAU,EAAE,GAAmB;QAC1C,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACtC,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YAClC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC;YAC9D,MAAM,IAAI,KAAK,CAAC,mBAAmB,OAAO,oBAAoB,CAAC,CAAC;QAClE,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpD,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YAC5C,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACrF,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAClD,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { CollectionMetadata, EntryData, HistoryEntry, StorageAdapter } from "../../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Overlay adapter for demo / multi-tenant sandbox use. Reads check the overlay
|
|
4
|
+
* first and fall back to the shared base adapter; writes go only to the overlay.
|
|
5
|
+
*
|
|
6
|
+
* Visitor edits a single field → only that key lands in the overlay; everything
|
|
7
|
+
* else is served from the seeded base. Storage cost is bounded to deltas.
|
|
8
|
+
*
|
|
9
|
+
* Deletes write a tombstone sentinel into the overlay rather than removing the
|
|
10
|
+
* overlay key, so deleting a base-only entry stays deleted for the session
|
|
11
|
+
* instead of falling through to the seeded value on the next read.
|
|
12
|
+
*/
|
|
13
|
+
export declare class SessionOverlayAdapter implements StorageAdapter {
|
|
14
|
+
private readonly base;
|
|
15
|
+
private readonly overlay;
|
|
16
|
+
constructor(base: StorageAdapter, overlay: StorageAdapter);
|
|
17
|
+
discoverCollections(): Promise<string[]>;
|
|
18
|
+
isKnownCollection(collection: string): Promise<boolean>;
|
|
19
|
+
getEntry(collection: string, id: string): Promise<EntryData | null>;
|
|
20
|
+
listEntryIds(collection: string): Promise<string[]>;
|
|
21
|
+
listEntries(collection: string): Promise<EntryData[]>;
|
|
22
|
+
writeEntry(collection: string, id: string, data: Record<string, unknown>): Promise<void>;
|
|
23
|
+
deleteEntry(collection: string, id: string): Promise<void>;
|
|
24
|
+
getRevision(collection: string, id: string): Promise<number>;
|
|
25
|
+
bumpRevision(collection: string, id: string): Promise<number>;
|
|
26
|
+
getHistory(collection: string, id: string): Promise<HistoryEntry[]>;
|
|
27
|
+
appendHistory(collection: string, id: string, entry: HistoryEntry): Promise<void>;
|
|
28
|
+
createCollection(metadata: CollectionMetadata): Promise<void>;
|
|
29
|
+
deleteCollection(collection: string): Promise<void>;
|
|
30
|
+
getCollectionMetadata(collection: string): Promise<CollectionMetadata | null>;
|
|
31
|
+
listCollectionMetadata(): Promise<CollectionMetadata[]>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=session-overlay-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-overlay-adapter.d.ts","sourceRoot":"","sources":["../../../src/runtime/storage/session-overlay-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,cAAc,EACf,MAAM,gBAAgB,CAAC;AAQxB;;;;;;;;;;GAUG;AACH,qBAAa,qBAAsB,YAAW,cAAc;IAExD,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADP,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,cAAc;IAGpC,mBAAmB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAQxC,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKvD,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAOnE,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IA4BnD,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAMrD,UAAU,CACd,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC;IAIV,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO1D,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI5D,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI7D,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAInE,aAAa,CACjB,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC;IAIV,gBAAgB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7D,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInD,qBAAqB,CACzB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAM/B,sBAAsB,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;CAU9D"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const TOMBSTONE_KEY = "__caret_tombstone__";
|
|
2
|
+
function isTombstone(entry) {
|
|
3
|
+
return Boolean(entry && entry.data?.[TOMBSTONE_KEY] === true);
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Overlay adapter for demo / multi-tenant sandbox use. Reads check the overlay
|
|
7
|
+
* first and fall back to the shared base adapter; writes go only to the overlay.
|
|
8
|
+
*
|
|
9
|
+
* Visitor edits a single field → only that key lands in the overlay; everything
|
|
10
|
+
* else is served from the seeded base. Storage cost is bounded to deltas.
|
|
11
|
+
*
|
|
12
|
+
* Deletes write a tombstone sentinel into the overlay rather than removing the
|
|
13
|
+
* overlay key, so deleting a base-only entry stays deleted for the session
|
|
14
|
+
* instead of falling through to the seeded value on the next read.
|
|
15
|
+
*/
|
|
16
|
+
export class SessionOverlayAdapter {
|
|
17
|
+
base;
|
|
18
|
+
overlay;
|
|
19
|
+
constructor(base, overlay) {
|
|
20
|
+
this.base = base;
|
|
21
|
+
this.overlay = overlay;
|
|
22
|
+
}
|
|
23
|
+
async discoverCollections() {
|
|
24
|
+
const [base, ov] = await Promise.all([
|
|
25
|
+
this.base.discoverCollections(),
|
|
26
|
+
this.overlay.discoverCollections(),
|
|
27
|
+
]);
|
|
28
|
+
return [...new Set([...base, ...ov])].sort((a, b) => a.localeCompare(b));
|
|
29
|
+
}
|
|
30
|
+
async isKnownCollection(collection) {
|
|
31
|
+
if (await this.overlay.isKnownCollection(collection))
|
|
32
|
+
return true;
|
|
33
|
+
return this.base.isKnownCollection(collection);
|
|
34
|
+
}
|
|
35
|
+
async getEntry(collection, id) {
|
|
36
|
+
const overlaid = await this.overlay.getEntry(collection, id);
|
|
37
|
+
if (isTombstone(overlaid))
|
|
38
|
+
return null;
|
|
39
|
+
if (overlaid)
|
|
40
|
+
return overlaid;
|
|
41
|
+
return this.base.getEntry(collection, id);
|
|
42
|
+
}
|
|
43
|
+
async listEntryIds(collection) {
|
|
44
|
+
const [baseIds, overlayIds] = await Promise.all([
|
|
45
|
+
this.base.listEntryIds(collection),
|
|
46
|
+
this.overlay.listEntryIds(collection),
|
|
47
|
+
]);
|
|
48
|
+
// Resolve overlay entries once so we know which ids are tombstoned.
|
|
49
|
+
const overlayEntries = await Promise.all(overlayIds.map(async (id) => ({
|
|
50
|
+
id,
|
|
51
|
+
entry: await this.overlay.getEntry(collection, id),
|
|
52
|
+
})));
|
|
53
|
+
const tombstoned = new Set();
|
|
54
|
+
const liveOverlayIds = new Set();
|
|
55
|
+
for (const { id, entry } of overlayEntries) {
|
|
56
|
+
if (isTombstone(entry))
|
|
57
|
+
tombstoned.add(id);
|
|
58
|
+
else
|
|
59
|
+
liveOverlayIds.add(id);
|
|
60
|
+
}
|
|
61
|
+
const merged = new Set();
|
|
62
|
+
for (const id of baseIds) {
|
|
63
|
+
if (!tombstoned.has(id))
|
|
64
|
+
merged.add(id);
|
|
65
|
+
}
|
|
66
|
+
for (const id of liveOverlayIds)
|
|
67
|
+
merged.add(id);
|
|
68
|
+
return [...merged].sort((a, b) => a.localeCompare(b));
|
|
69
|
+
}
|
|
70
|
+
async listEntries(collection) {
|
|
71
|
+
const ids = await this.listEntryIds(collection);
|
|
72
|
+
const entries = await Promise.all(ids.map((id) => this.getEntry(collection, id)));
|
|
73
|
+
return entries.filter((entry) => Boolean(entry));
|
|
74
|
+
}
|
|
75
|
+
async writeEntry(collection, id, data) {
|
|
76
|
+
await this.overlay.writeEntry(collection, id, data);
|
|
77
|
+
}
|
|
78
|
+
async deleteEntry(collection, id) {
|
|
79
|
+
// Write a tombstone instead of deleting. A plain overlay delete would be
|
|
80
|
+
// a no-op for any entry that lives only in the base, and the next read
|
|
81
|
+
// would resurrect it from the seeded data.
|
|
82
|
+
await this.overlay.writeEntry(collection, id, { [TOMBSTONE_KEY]: true });
|
|
83
|
+
}
|
|
84
|
+
async getRevision(collection, id) {
|
|
85
|
+
return this.overlay.getRevision(collection, id);
|
|
86
|
+
}
|
|
87
|
+
async bumpRevision(collection, id) {
|
|
88
|
+
return this.overlay.bumpRevision(collection, id);
|
|
89
|
+
}
|
|
90
|
+
async getHistory(collection, id) {
|
|
91
|
+
return this.overlay.getHistory(collection, id);
|
|
92
|
+
}
|
|
93
|
+
async appendHistory(collection, id, entry) {
|
|
94
|
+
await this.overlay.appendHistory(collection, id, entry);
|
|
95
|
+
}
|
|
96
|
+
async createCollection(metadata) {
|
|
97
|
+
await this.overlay.createCollection(metadata);
|
|
98
|
+
}
|
|
99
|
+
async deleteCollection(collection) {
|
|
100
|
+
await this.overlay.deleteCollection(collection);
|
|
101
|
+
}
|
|
102
|
+
async getCollectionMetadata(collection) {
|
|
103
|
+
const overlaid = await this.overlay.getCollectionMetadata(collection);
|
|
104
|
+
if (overlaid)
|
|
105
|
+
return overlaid;
|
|
106
|
+
return this.base.getCollectionMetadata(collection);
|
|
107
|
+
}
|
|
108
|
+
async listCollectionMetadata() {
|
|
109
|
+
const [base, ov] = await Promise.all([
|
|
110
|
+
this.base.listCollectionMetadata(),
|
|
111
|
+
this.overlay.listCollectionMetadata(),
|
|
112
|
+
]);
|
|
113
|
+
const merged = new Map();
|
|
114
|
+
for (const meta of base)
|
|
115
|
+
merged.set(meta.id, meta);
|
|
116
|
+
for (const meta of ov)
|
|
117
|
+
merged.set(meta.id, meta);
|
|
118
|
+
return [...merged.values()].sort((a, b) => a.id.localeCompare(b.id));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=session-overlay-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-overlay-adapter.js","sourceRoot":"","sources":["../../../src/runtime/storage/session-overlay-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Studio chrome theme tokens.
|
|
3
|
+
*
|
|
4
|
+
* Only one preset ships with core: `studio`, the neutral dark chrome
|
|
5
|
+
* that matches the inline editor's "click to edit" blue. Distributable
|
|
6
|
+
* site themes live in separate packages (e.g. @caretcms/theme-*),
|
|
7
|
+
* not in this preset registry.
|
|
8
|
+
*
|
|
9
|
+
* The values below populate the --color-theme-* / --font-theme-* tokens
|
|
10
|
+
* declared in static/cms/studio-tokens.css. The studio-* aliases inherit
|
|
11
|
+
* automatically.
|
|
12
|
+
*/
|
|
13
|
+
export type ThemeTokens = Record<string, string>;
|
|
14
|
+
export declare const PRESET_TOKENS: Record<string, ThemeTokens>;
|
|
15
|
+
export declare const DEFAULT_PRESET_ID = "studio";
|
|
16
|
+
export declare function getPresetTokens(themeId: string): ThemeTokens;
|
|
17
|
+
//# sourceMappingURL=preset-tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preset-tokens.d.ts","sourceRoot":"","sources":["../../../src/runtime/themes/preset-tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AA8BjD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAErD,CAAC;AAEF,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAE1C,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAE5D"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Studio chrome theme tokens.
|
|
3
|
+
*
|
|
4
|
+
* Only one preset ships with core: `studio`, the neutral dark chrome
|
|
5
|
+
* that matches the inline editor's "click to edit" blue. Distributable
|
|
6
|
+
* site themes live in separate packages (e.g. @caretcms/theme-*),
|
|
7
|
+
* not in this preset registry.
|
|
8
|
+
*
|
|
9
|
+
* The values below populate the --color-theme-* / --font-theme-* tokens
|
|
10
|
+
* declared in static/cms/studio-tokens.css. The studio-* aliases inherit
|
|
11
|
+
* automatically.
|
|
12
|
+
*/
|
|
13
|
+
const STUDIO = {
|
|
14
|
+
// Surface
|
|
15
|
+
"--color-theme-bg-deep": "#0c0e12",
|
|
16
|
+
"--color-theme-surface": "#14171c",
|
|
17
|
+
"--color-theme-surface-elevated": "#1c2027",
|
|
18
|
+
"--color-theme-surface-muted": "rgba(255, 255, 255, 0.03)",
|
|
19
|
+
// Border
|
|
20
|
+
"--color-theme-border-subtle": "rgba(255, 255, 255, 0.06)",
|
|
21
|
+
"--color-theme-border": "rgba(255, 255, 255, 0.10)",
|
|
22
|
+
// Accent — matches the inline editor's "editable" blue (#3b82f6)
|
|
23
|
+
"--color-theme-accent": "#3b82f6",
|
|
24
|
+
"--color-theme-accent-soft": "rgba(59, 130, 246, 0.12)",
|
|
25
|
+
"--color-theme-accent-strong": "rgba(59, 130, 246, 0.24)",
|
|
26
|
+
"--color-theme-on-accent": "#ffffff",
|
|
27
|
+
// Text
|
|
28
|
+
"--color-theme-text": "rgba(255, 255, 255, 0.92)",
|
|
29
|
+
"--color-theme-text-muted": "rgba(255, 255, 255, 0.55)",
|
|
30
|
+
"--color-theme-text-dim": "rgba(255, 255, 255, 0.32)",
|
|
31
|
+
// State
|
|
32
|
+
"--color-theme-success": "#22c55e",
|
|
33
|
+
"--color-theme-danger": "#ef4444",
|
|
34
|
+
"--color-theme-info": "#3b82f6",
|
|
35
|
+
"--color-theme-warning": "#eab308",
|
|
36
|
+
// Typography — one family, system-friendly, no editorial drama
|
|
37
|
+
"--font-theme-body": "Inter, system-ui, -apple-system, 'Segoe UI', sans-serif",
|
|
38
|
+
"--font-theme-heading": "Inter, system-ui, -apple-system, 'Segoe UI', sans-serif",
|
|
39
|
+
};
|
|
40
|
+
export const PRESET_TOKENS = {
|
|
41
|
+
studio: STUDIO,
|
|
42
|
+
};
|
|
43
|
+
export const DEFAULT_PRESET_ID = "studio";
|
|
44
|
+
export function getPresetTokens(themeId) {
|
|
45
|
+
return PRESET_TOKENS[themeId] ?? PRESET_TOKENS[DEFAULT_PRESET_ID];
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=preset-tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preset-tokens.js","sourceRoot":"","sources":["../../../src/runtime/themes/preset-tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,MAAM,MAAM,GAAgB;IAC1B,UAAU;IACV,uBAAuB,EAAE,SAAS;IAClC,uBAAuB,EAAE,SAAS;IAClC,gCAAgC,EAAE,SAAS;IAC3C,6BAA6B,EAAE,2BAA2B;IAC1D,SAAS;IACT,6BAA6B,EAAE,2BAA2B;IAC1D,sBAAsB,EAAE,2BAA2B;IACnD,iEAAiE;IACjE,sBAAsB,EAAE,SAAS;IACjC,2BAA2B,EAAE,0BAA0B;IACvD,6BAA6B,EAAE,0BAA0B;IACzD,yBAAyB,EAAE,SAAS;IACpC,OAAO;IACP,oBAAoB,EAAE,2BAA2B;IACjD,0BAA0B,EAAE,2BAA2B;IACvD,wBAAwB,EAAE,2BAA2B;IACrD,QAAQ;IACR,uBAAuB,EAAE,SAAS;IAClC,sBAAsB,EAAE,SAAS;IACjC,oBAAoB,EAAE,SAAS;IAC/B,uBAAuB,EAAE,SAAS;IAClC,+DAA+D;IAC/D,mBAAmB,EAAE,yDAAyD;IAC9E,sBAAsB,EAAE,yDAAyD;CAClF,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAgC;IACxD,MAAM,EAAE,MAAM;CACf,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC;AAE1C,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,OAAO,aAAa,CAAC,OAAO,CAAC,IAAI,aAAa,CAAC,iBAAiB,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared deep-value helper used by bind and mutation engine.
|
|
3
|
+
*/
|
|
4
|
+
/** Set a deeply nested value by dot-path. Mutates `obj` in place. */
|
|
5
|
+
export declare function setNestedValue(obj: Record<string, unknown>, path: string, value: unknown): void;
|
|
6
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/runtime/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,qEAAqE;AACrE,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,GACb,IAAI,CAmBN"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared deep-value helper used by bind and mutation engine.
|
|
3
|
+
*/
|
|
4
|
+
const FORBIDDEN_KEYS = new Set(["__proto__", "prototype", "constructor"]);
|
|
5
|
+
function assertSafeKey(key) {
|
|
6
|
+
if (FORBIDDEN_KEYS.has(key)) {
|
|
7
|
+
throw new Error(`Forbidden key in path: ${key}`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/** Set a deeply nested value by dot-path. Mutates `obj` in place. */
|
|
11
|
+
export function setNestedValue(obj, path, value) {
|
|
12
|
+
const keys = path.split(".");
|
|
13
|
+
if (keys.length === 0)
|
|
14
|
+
throw new Error("Invalid field path");
|
|
15
|
+
let current = obj;
|
|
16
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
17
|
+
const key = keys[i];
|
|
18
|
+
assertSafeKey(key);
|
|
19
|
+
const next = current[key];
|
|
20
|
+
if (typeof next !== "object" || next === null) {
|
|
21
|
+
current[key] = /^\d+$/.test(keys[i + 1]) ? [] : {};
|
|
22
|
+
}
|
|
23
|
+
current = current[key];
|
|
24
|
+
}
|
|
25
|
+
const last = keys[keys.length - 1];
|
|
26
|
+
assertSafeKey(last);
|
|
27
|
+
current[last] = value;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/runtime/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;AAE1E,SAAS,aAAa,CAAC,GAAW;IAChC,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,cAAc,CAC5B,GAA4B,EAC5B,IAAY,EACZ,KAAc;IAEd,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC7D,IAAI,OAAO,GAA4B,GAAG,CAAC;IAE3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,aAAa,CAAC,GAAG,CAAC,CAAC;QAEnB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,GAAG,CAA4B,CAAC;IACpD,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACnC,aAAa,CAAC,IAAI,CAAC,CAAC;IACpB,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared HTML chrome for studio pages (dashboard, collection list, entry editor).
|
|
3
|
+
* Renders the document, theme stylesheet links, sticky header with brand mark,
|
|
4
|
+
* breadcrumb trail, and slots in the page-specific body content.
|
|
5
|
+
*/
|
|
6
|
+
import type { CaretRuntimeConfig } from "../config.js";
|
|
7
|
+
export declare function escapeHtml(value: string): string;
|
|
8
|
+
export type Crumb = {
|
|
9
|
+
label: string;
|
|
10
|
+
href?: string;
|
|
11
|
+
};
|
|
12
|
+
export type StudioLayoutOptions = {
|
|
13
|
+
runtime: CaretRuntimeConfig;
|
|
14
|
+
title: string;
|
|
15
|
+
breadcrumb?: Crumb[];
|
|
16
|
+
body: string;
|
|
17
|
+
/** Extra inline <style> block for page-specific tweaks. */
|
|
18
|
+
extraStyles?: string;
|
|
19
|
+
/** Inline <script> body executed at end of <body>. */
|
|
20
|
+
inlineScript?: string;
|
|
21
|
+
};
|
|
22
|
+
export declare function renderStudioPage(opts: StudioLayoutOptions): string;
|
|
23
|
+
export declare function htmlResponse(content: string, status?: number): Response;
|
|
24
|
+
export declare function redirectResponse(location: string): Response;
|
|
25
|
+
//# sourceMappingURL=studio-layout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"studio-layout.d.ts","sourceRoot":"","sources":["../../../src/runtime/views/studio-layout.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOhD;AAED,MAAM,MAAM,KAAK,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAErD,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,kBAAkB,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AA8BF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAyDlE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAM,GAAG,QAAQ,CAKpE;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAK3D"}
|