@hollware/server 1.0.0-rc.0 → 1.0.0-rc.2
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/{ceremonies-CI3DkOEL.mjs → ceremonies-zTn1U6BD.mjs} +1 -1
- package/dist/index.d.mts +73 -2
- package/dist/index.mjs +477 -85
- package/dist/{store-DjA9s95l.mjs → store-ApxKV0Sc.mjs} +34 -0
- package/migrations/0017_assets.sql +42 -0
- package/migrations/meta/0017_snapshot.json +2993 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +3 -3
|
@@ -726,6 +726,40 @@ sqliteTable("audit_log", {
|
|
|
726
726
|
check("audit_log_json", sql`(${t.actorMeta} IS NULL OR json_valid(${t.actorMeta})) AND (${t.detail} IS NULL OR json_valid(${t.detail}))`),
|
|
727
727
|
check("audit_log_sizes", sql`length(${t.action}) <= 64 AND (${t.detail} IS NULL OR length(${t.detail}) <= 2000) AND (${t.actorMeta} IS NULL OR length(${t.actorMeta}) <= 2000)`)
|
|
728
728
|
]);
|
|
729
|
+
sqliteTable("assets", {
|
|
730
|
+
id: id("ast"),
|
|
731
|
+
siteId: siteId(),
|
|
732
|
+
sha256: text("sha256").notNull(),
|
|
733
|
+
/** The media type of the file served: the converted one, or the original kept as it came. */
|
|
734
|
+
format: text("format").notNull(),
|
|
735
|
+
/** In pixels; `null` for an SVG, which has no fixed size. */
|
|
736
|
+
width: integer("width"),
|
|
737
|
+
height: integer("height"),
|
|
738
|
+
bytes: integer("bytes").notNull(),
|
|
739
|
+
originalFormat: text("original_format").notNull(),
|
|
740
|
+
originalBytes: integer("original_bytes").notNull(),
|
|
741
|
+
alt: text("alt").notNull(),
|
|
742
|
+
filename: text("filename").notNull(),
|
|
743
|
+
/** The person whose token or session uploaded it. */
|
|
744
|
+
createdBy: text("created_by").notNull(),
|
|
745
|
+
...timestamps()
|
|
746
|
+
}, (t) => [
|
|
747
|
+
unique("assets_id_site").on(t.id, t.siteId),
|
|
748
|
+
unique("assets_sha256").on(t.siteId, t.sha256),
|
|
749
|
+
index("assets_site_time").on(t.siteId, t.createdAt, t.id),
|
|
750
|
+
foreignKey({
|
|
751
|
+
name: "assets_site",
|
|
752
|
+
columns: [t.siteId],
|
|
753
|
+
foreignColumns: [sites.id]
|
|
754
|
+
}),
|
|
755
|
+
foreignKey({
|
|
756
|
+
name: "assets_creator",
|
|
757
|
+
columns: [t.createdBy],
|
|
758
|
+
foreignColumns: [users.id]
|
|
759
|
+
}),
|
|
760
|
+
check("assets_formats", sql`${t.format} IN ('image/jpeg', 'image/png', 'image/webp', 'image/avif', 'image/gif', 'image/svg+xml') AND ${t.originalFormat} IN ('image/jpeg', 'image/png', 'image/webp', 'image/avif', 'image/gif', 'image/svg+xml')`),
|
|
761
|
+
check("assets_sizes", sql`${t.bytes} > 0 AND ${t.originalBytes} BETWEEN 1 AND 10485760 AND length(${t.alt}) BETWEEN 1 AND 500 AND length(${t.filename}) BETWEEN 1 AND 200 AND length(${t.sha256}) = 64`)
|
|
762
|
+
]);
|
|
729
763
|
//#endregion
|
|
730
764
|
//#region src/identity/secrets.ts
|
|
731
765
|
/**
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
-- Generated by drizzle-kit, then edited by hand (ADR-023): the triggers at the end are not in the
|
|
2
|
+
-- schema, since drizzle-kit does not model them; append-only.workerd.test.ts lists them after
|
|
3
|
+
-- every migration.
|
|
4
|
+
--
|
|
5
|
+
-- The images of a site (ADR-038). An asset is never deleted, since a revision may name it, and
|
|
6
|
+
-- nothing of it changes but its alt: its id is the hash of its bytes, and R2 holds those bytes.
|
|
7
|
+
CREATE TABLE `assets` (
|
|
8
|
+
`id` text PRIMARY KEY NOT NULL,
|
|
9
|
+
`site_id` text NOT NULL,
|
|
10
|
+
`sha256` text NOT NULL,
|
|
11
|
+
`format` text NOT NULL,
|
|
12
|
+
`width` integer,
|
|
13
|
+
`height` integer,
|
|
14
|
+
`bytes` integer NOT NULL,
|
|
15
|
+
`original_format` text NOT NULL,
|
|
16
|
+
`original_bytes` integer NOT NULL,
|
|
17
|
+
`alt` text NOT NULL,
|
|
18
|
+
`filename` text NOT NULL,
|
|
19
|
+
`created_by` text NOT NULL,
|
|
20
|
+
`created_at` text NOT NULL,
|
|
21
|
+
`updated_at` text NOT NULL,
|
|
22
|
+
FOREIGN KEY (`site_id`) REFERENCES `sites`(`id`) ON UPDATE no action ON DELETE no action,
|
|
23
|
+
FOREIGN KEY (`created_by`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action,
|
|
24
|
+
CONSTRAINT "assets_formats" CHECK("assets"."format" IN ('image/jpeg', 'image/png', 'image/webp', 'image/avif', 'image/gif', 'image/svg+xml') AND "assets"."original_format" IN ('image/jpeg', 'image/png', 'image/webp', 'image/avif', 'image/gif', 'image/svg+xml')),
|
|
25
|
+
CONSTRAINT "assets_sizes" CHECK("assets"."bytes" > 0 AND "assets"."original_bytes" BETWEEN 1 AND 10485760 AND length("assets"."alt") BETWEEN 1 AND 500 AND length("assets"."filename") BETWEEN 1 AND 200 AND length("assets"."sha256") = 64)
|
|
26
|
+
);
|
|
27
|
+
--> statement-breakpoint
|
|
28
|
+
CREATE INDEX `assets_site_time` ON `assets` (`site_id`,`created_at`,`id`);--> statement-breakpoint
|
|
29
|
+
CREATE UNIQUE INDEX `assets_id_site` ON `assets` (`id`,`site_id`);--> statement-breakpoint
|
|
30
|
+
CREATE UNIQUE INDEX `assets_sha256` ON `assets` (`site_id`,`sha256`);
|
|
31
|
+
--> statement-breakpoint
|
|
32
|
+
CREATE TRIGGER `assets_no_delete`
|
|
33
|
+
BEFORE DELETE ON `assets`
|
|
34
|
+
BEGIN
|
|
35
|
+
SELECT RAISE(ABORT, 'append-only: an asset is never deleted, since a revision may name it');
|
|
36
|
+
END;
|
|
37
|
+
--> statement-breakpoint
|
|
38
|
+
CREATE TRIGGER `assets_immutable`
|
|
39
|
+
BEFORE UPDATE OF `id`, `site_id`, `sha256`, `format`, `width`, `height`, `bytes`, `original_format`, `original_bytes`, `filename`, `created_by`, `created_at` ON `assets`
|
|
40
|
+
BEGIN
|
|
41
|
+
SELECT RAISE(ABORT, 'append-only: only the alt of an asset changes');
|
|
42
|
+
END;
|