smoodly 0.0.8 → 0.0.9
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/README.md +145 -11
- package/dist/admin/forms/FieldWidget.d.ts +7 -3
- package/dist/admin/forms/FieldWidget.js +85 -7
- package/dist/admin/forms/list.d.ts +18 -0
- package/dist/admin/forms/list.js +81 -0
- package/dist/admin/richtext.d.ts +13 -11
- package/dist/admin/richtext.js +94 -13
- package/dist/admin/serialize.d.ts +4 -0
- package/dist/admin/serialize.js +3 -0
- package/dist/admin/shell/EntryForm.js +1 -1
- package/dist/admin/shell/SharedForm.js +1 -1
- package/dist/admin/ui/theme.d.ts +1 -1
- package/dist/admin/ui/theme.js +13 -0
- package/dist/admin/validate.d.ts +7 -2
- package/dist/admin/validate.js +43 -13
- package/dist/entry-store.js +7 -1
- package/dist/fields.d.ts +16 -1
- package/dist/fields.js +49 -4
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/refs.js +5 -0
- package/dist/resolve.js +3 -0
- package/dist/richtext-render.d.ts +3 -0
- package/dist/richtext-render.js +62 -0
- package/dist/shared-id.d.ts +3 -0
- package/dist/shared-id.js +36 -0
- package/dist/sql-space.d.ts +4 -0
- package/dist/sql-space.js +5 -1
- package/dist/sql.js +1 -1
- package/dist/supabase-entry-store.d.ts +8 -0
- package/dist/supabase-entry-store.js +37 -2
- package/package.json +1 -1
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
// untouched.
|
|
9
9
|
import { collectionDepth, collectionOrder } from "./collections.js";
|
|
10
10
|
import { DEFAULT_ENTRY_LOCALES, entryErrors, entryFieldsIn, entryLocaleRow, entryRefEdges, entryTitleIn, isSharedSchema, schemaOf, splitFields, } from "./entry-store.js";
|
|
11
|
+
import { sharedEntryId } from "./shared-id.js";
|
|
11
12
|
import { SupabasePathIndex } from "./supabase-path-index.js";
|
|
12
13
|
import { assertDepth, assertSupportedLocale, entryPathRows, slugOf } from "./paths.js";
|
|
13
14
|
// entries.id is a Postgres uuid column: filtering on a non-UUID string
|
|
@@ -54,6 +55,29 @@ export class SupabaseEntryStore {
|
|
|
54
55
|
schema(collection) {
|
|
55
56
|
return schemaOf(this.schemas, collection);
|
|
56
57
|
}
|
|
58
|
+
/** The space this client acts in — the ONE function the policies and
|
|
59
|
+
* the insert trigger read (src/sql-space.ts): a key's claim in the
|
|
60
|
+
* cloud, the default space under the service role. Constant for the
|
|
61
|
+
* life of the client, so the PROMISE is cached and concurrent creates
|
|
62
|
+
* share one round trip; a failed lookup is not cached. */
|
|
63
|
+
space() {
|
|
64
|
+
if (!this.spaceId) {
|
|
65
|
+
this.spaceId = this.fetchSpace().catch((e) => {
|
|
66
|
+
// A failed lookup is not cached: the next write retries it.
|
|
67
|
+
this.spaceId = undefined;
|
|
68
|
+
throw e;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return this.spaceId;
|
|
72
|
+
}
|
|
73
|
+
async fetchSpace() {
|
|
74
|
+
const res = await this.db.rpc("smoodly_current_space");
|
|
75
|
+
if (res.error)
|
|
76
|
+
this.fail(res.error.message);
|
|
77
|
+
if (typeof res.data !== "string")
|
|
78
|
+
this.fail("smoodly_current_space() returned no space — is the schema up to date?");
|
|
79
|
+
return res.data;
|
|
80
|
+
}
|
|
57
81
|
// ── reads ──
|
|
58
82
|
async fetch(collection, id) {
|
|
59
83
|
if (!UUID_RE.test(id))
|
|
@@ -253,9 +277,20 @@ export class SupabaseEntryStore {
|
|
|
253
277
|
this.assertParentHasLocale(parent, options.locale);
|
|
254
278
|
const { shared, localized, slug } = splitFields(fields, schema);
|
|
255
279
|
await this.assertSiblingSlug(collection, parentId, options.locale, slug);
|
|
256
|
-
|
|
257
|
-
|
|
280
|
+
// A shared item's row id is DERIVED from (space, name), not generated
|
|
281
|
+
// (spec 2026-09-07 §10): the SELECT above is a fast path two racing
|
|
282
|
+
// materializations can both pass, so the primary key is the backstop
|
|
283
|
+
// — a duplicate would be unremovable, since `delete` refuses every
|
|
284
|
+
// shared row.
|
|
285
|
+
const row = { collection, parent_id: parentId, fields: shared };
|
|
286
|
+
if (isSharedSchema(schema))
|
|
287
|
+
row.id = await sharedEntryId(await this.space(), collection);
|
|
288
|
+
const inserted = await this.db.from("entries").insert(row).select("id").single();
|
|
289
|
+
if (inserted.error) {
|
|
290
|
+
if (isSharedSchema(schema) && inserted.error.code === UNIQUE_VIOLATION)
|
|
291
|
+
throw entryErrors.singleton(collection);
|
|
258
292
|
this.fail(inserted.error.message);
|
|
293
|
+
}
|
|
259
294
|
const id = inserted.data.id;
|
|
260
295
|
try {
|
|
261
296
|
await this.insertLocale(id, options.locale, { slug, fields: localized });
|
package/package.json
CHANGED