@cogenta/core 0.4.0 → 0.7.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.
Files changed (108) hide show
  1. package/CHANGELOG.md +3532 -0
  2. package/dist/config/env.d.ts +21 -0
  3. package/dist/config/env.d.ts.map +1 -1
  4. package/dist/config/env.js +72 -0
  5. package/dist/config/env.js.map +1 -1
  6. package/dist/config/index.d.ts +2 -0
  7. package/dist/config/index.d.ts.map +1 -1
  8. package/dist/config/index.js +1 -0
  9. package/dist/config/index.js.map +1 -1
  10. package/dist/config/load-config.d.ts +9 -0
  11. package/dist/config/load-config.d.ts.map +1 -1
  12. package/dist/config/load-config.js +39 -15
  13. package/dist/config/load-config.js.map +1 -1
  14. package/dist/config/resolve-config.d.ts.map +1 -1
  15. package/dist/config/resolve-config.js +39 -0
  16. package/dist/config/resolve-config.js.map +1 -1
  17. package/dist/config/schema.d.ts +49 -0
  18. package/dist/config/schema.d.ts.map +1 -1
  19. package/dist/config/schema.js +149 -1
  20. package/dist/config/schema.js.map +1 -1
  21. package/dist/config/secret-hygiene.d.ts +55 -0
  22. package/dist/config/secret-hygiene.d.ts.map +1 -0
  23. package/dist/config/secret-hygiene.js +94 -0
  24. package/dist/config/secret-hygiene.js.map +1 -0
  25. package/dist/config/types.d.ts +166 -0
  26. package/dist/config/types.d.ts.map +1 -1
  27. package/dist/config/types.js +4 -0
  28. package/dist/config/types.js.map +1 -1
  29. package/dist/drivers/index.d.ts +1 -1
  30. package/dist/drivers/index.d.ts.map +1 -1
  31. package/dist/drivers/index.js.map +1 -1
  32. package/dist/drivers/registry.d.ts.map +1 -1
  33. package/dist/drivers/registry.js +15 -8
  34. package/dist/drivers/registry.js.map +1 -1
  35. package/dist/drivers/types.d.ts +23 -0
  36. package/dist/drivers/types.d.ts.map +1 -1
  37. package/dist/errors/codes.d.ts +1 -1
  38. package/dist/errors/codes.d.ts.map +1 -1
  39. package/dist/errors/codes.js +244 -0
  40. package/dist/errors/codes.js.map +1 -1
  41. package/dist/index.d.ts +2 -0
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js +2 -0
  44. package/dist/index.js.map +1 -1
  45. package/dist/logger/error-log.d.ts +48 -0
  46. package/dist/logger/error-log.d.ts.map +1 -0
  47. package/dist/logger/error-log.js +57 -0
  48. package/dist/logger/error-log.js.map +1 -0
  49. package/dist/logger/index.d.ts +2 -0
  50. package/dist/logger/index.d.ts.map +1 -1
  51. package/dist/logger/index.js +1 -0
  52. package/dist/logger/index.js.map +1 -1
  53. package/dist/media/exif.d.ts +46 -0
  54. package/dist/media/exif.d.ts.map +1 -0
  55. package/dist/media/exif.js +291 -0
  56. package/dist/media/exif.js.map +1 -0
  57. package/dist/media/folder-path.d.ts +16 -0
  58. package/dist/media/folder-path.d.ts.map +1 -0
  59. package/dist/media/folder-path.js +51 -0
  60. package/dist/media/folder-path.js.map +1 -0
  61. package/dist/media/folder-store.d.ts +26 -0
  62. package/dist/media/folder-store.d.ts.map +1 -0
  63. package/dist/media/folder-store.js +361 -0
  64. package/dist/media/folder-store.js.map +1 -0
  65. package/dist/media/index.d.ts +5 -2
  66. package/dist/media/index.d.ts.map +1 -1
  67. package/dist/media/index.js +4 -1
  68. package/dist/media/index.js.map +1 -1
  69. package/dist/media/sql-fragments.d.ts +19 -0
  70. package/dist/media/sql-fragments.d.ts.map +1 -0
  71. package/dist/media/sql-fragments.js +29 -0
  72. package/dist/media/sql-fragments.js.map +1 -0
  73. package/dist/media/store.d.ts +1 -0
  74. package/dist/media/store.d.ts.map +1 -1
  75. package/dist/media/store.js +175 -20
  76. package/dist/media/store.js.map +1 -1
  77. package/dist/media/types.d.ts +148 -0
  78. package/dist/media/types.d.ts.map +1 -1
  79. package/dist/queue/bullmq.d.ts +4 -0
  80. package/dist/queue/bullmq.d.ts.map +1 -1
  81. package/dist/queue/bullmq.js +53 -10
  82. package/dist/queue/bullmq.js.map +1 -1
  83. package/dist/queue/database.d.ts.map +1 -1
  84. package/dist/queue/database.js +32 -11
  85. package/dist/queue/database.js.map +1 -1
  86. package/dist/queue/types.d.ts +19 -0
  87. package/dist/queue/types.d.ts.map +1 -1
  88. package/dist/rate-limit/index.d.ts +21 -0
  89. package/dist/rate-limit/index.d.ts.map +1 -0
  90. package/dist/rate-limit/index.js +25 -0
  91. package/dist/rate-limit/index.js.map +1 -0
  92. package/dist/rate-limit/memory.d.ts +17 -0
  93. package/dist/rate-limit/memory.d.ts.map +1 -0
  94. package/dist/rate-limit/memory.js +61 -0
  95. package/dist/rate-limit/memory.js.map +1 -0
  96. package/dist/rate-limit/redis.d.ts +55 -0
  97. package/dist/rate-limit/redis.d.ts.map +1 -0
  98. package/dist/rate-limit/redis.js +134 -0
  99. package/dist/rate-limit/redis.js.map +1 -0
  100. package/dist/rate-limit/types.d.ts +52 -0
  101. package/dist/rate-limit/types.d.ts.map +1 -0
  102. package/dist/rate-limit/types.js +2 -0
  103. package/dist/rate-limit/types.js.map +1 -0
  104. package/dist/version.d.ts +39 -0
  105. package/dist/version.d.ts.map +1 -0
  106. package/dist/version.js +84 -0
  107. package/dist/version.js.map +1 -0
  108. package/package.json +3 -2
@@ -1,9 +1,40 @@
1
- import { randomUUID } from 'node:crypto';
1
+ import { createHash, randomUUID } from 'node:crypto';
2
2
  import { identifier, limit, sql } from '../db/index.js';
3
3
  import { CogentaError } from '../errors/index.js';
4
- const TABLE = 'cogenta_media';
4
+ import { valueList } from './sql-fragments.js';
5
+ export const MEDIA_TABLE = 'cogenta_media';
6
+ const TABLE = MEDIA_TABLE;
5
7
  const DEFAULT_LIMIT = 50;
6
8
  const MAX_LIMIT = 200;
9
+ /**
10
+ * Tags are stored as one delimited text column rather than a join table or a
11
+ * dialect's own JSON type: SQLite, Postgres and MySQL disagree on JSON
12
+ * containment operators (`@>`, `JSON_CONTAINS`, `json_each`), and a
13
+ * materialised-path-style delimited string (the same portability trade
14
+ * ADR-0006 already made for taxonomies) turns "has this tag" into one `LIKE`
15
+ * every dialect answers identically. `\u0001` rather than a comma: a tag is
16
+ * free text an editor typed, and a comma is a character they might type too.
17
+ */
18
+ const TAG_DELIMITER = '\u0001';
19
+ /** Every caller that predates tagging/replace still gets a stable, non-empty value. */
20
+ function defaultContentHash(storageKey) {
21
+ return createHash('sha256').update(storageKey).digest('hex').slice(0, 16);
22
+ }
23
+ function serializeTags(tags) {
24
+ const cleaned = tags.map((tag) => tag.trim()).filter((tag) => tag.length > 0);
25
+ if (cleaned.length === 0)
26
+ return '';
27
+ return `${TAG_DELIMITER}${cleaned.join(TAG_DELIMITER)}${TAG_DELIMITER}`;
28
+ }
29
+ function parseTags(raw) {
30
+ if (raw === null || raw.length === 0)
31
+ return [];
32
+ return raw.split(TAG_DELIMITER).filter((tag) => tag.length > 0);
33
+ }
34
+ /** Escapes `\`, `%` and `_` so a tag containing them cannot widen its own `LIKE` filter. */
35
+ function escapeLikePattern(value) {
36
+ return value.replace(/[\\%_]/gu, (char) => `\\${char}`);
37
+ }
7
38
  function rowToAsset(row) {
8
39
  return {
9
40
  id: row.id,
@@ -18,6 +49,11 @@ function rowToAsset(row) {
18
49
  decorativeJustification: row.decorative_justification,
19
50
  focal: row.focal === null ? null : JSON.parse(row.focal),
20
51
  storageKey: row.storage_key,
52
+ tags: parseTags(row.tags),
53
+ contentHash: row.content_hash === null || row.content_hash === ''
54
+ ? defaultContentHash(row.storage_key)
55
+ : row.content_hash,
56
+ folderId: row.folder_id,
21
57
  createdAt: row.created_at,
22
58
  createdBy: row.created_by,
23
59
  };
@@ -55,15 +91,28 @@ function validateAltPolicy(alt, decorative, justification) {
55
91
  });
56
92
  }
57
93
  }
58
- function encodeCursor(row) {
59
- return Buffer.from(`${row.createdAt}|${row.id}`, 'utf8').toString('base64url');
94
+ const SORT_COLUMNS = {
95
+ createdAt: 'created_at',
96
+ filename: 'filename',
97
+ size: 'size',
98
+ };
99
+ /** The cursor value in the *comparable* JS type for its column — a string for text columns, a number for the numeric `size` column. */
100
+ function sortValueOf(field, row) {
101
+ if (field === 'size')
102
+ return Number(row.size);
103
+ if (field === 'filename')
104
+ return row.filename;
105
+ return row.created_at;
106
+ }
107
+ function encodeCursor(field, value, id) {
108
+ return Buffer.from(`${field}|${String(value)}|${id}`, 'utf8').toString('base64url');
60
109
  }
61
- function decodeCursor(cursor) {
110
+ function decodeCursor(field, cursor) {
62
111
  try {
63
- const [createdAt, id] = Buffer.from(cursor, 'base64url').toString('utf8').split('|');
64
- if (createdAt === undefined || id === undefined)
112
+ const [cursorField, rawValue, id] = Buffer.from(cursor, 'base64url').toString('utf8').split('|');
113
+ if (cursorField !== field || rawValue === undefined || id === undefined)
65
114
  return null;
66
- return { createdAt, id };
115
+ return { value: field === 'size' ? Number(rawValue) : rawValue, id };
67
116
  }
68
117
  catch {
69
118
  return null;
@@ -103,8 +152,62 @@ export function createDatabaseMediaStore(options) {
103
152
  .query(sql `create index ${identifier('cogenta_media_created', db.dialect)}
104
153
  on ${table} (created_at, id)`)
105
154
  .catch(() => undefined); // already there
155
+ // Fiche 11: tags and a replace-tracking content hash, added to a table
156
+ // sites may already have (L2/L10). No portable "add column if not
157
+ // exists" across all three dialects (SQLite has none at all), so — the
158
+ // same pattern `@cogenta/auth`'s `tables.ts` uses for its own
159
+ // after-the-fact columns — this is a `try`, not a check.
160
+ await db
161
+ .query(sql `alter table ${table} add column ${identifier('tags', db.dialect)} text`)
162
+ .catch(() => undefined);
163
+ await db
164
+ .query(sql `alter table ${table} add column ${identifier('content_hash', db.dialect)} varchar(64)`)
165
+ .catch(() => undefined);
166
+ await db
167
+ .query(sql `create index ${identifier('cogenta_media_filename', db.dialect)}
168
+ on ${table} (filename, id)`)
169
+ .catch(() => undefined);
170
+ await db
171
+ .query(sql `create index ${identifier('cogenta_media_size', db.dialect)}
172
+ on ${table} (size, id)`)
173
+ .catch(() => undefined);
174
+ // Fiche 46: same try-not-check pattern as `tags`/`content_hash` above,
175
+ // added to a table sites may already have. Nothing here backfills a
176
+ // value — every asset that predates folders keeps `folder_id is null`
177
+ // (unclassified) forever, which is the whole point (see `MediaAsset`'s
178
+ // own doc comment): forcing existing media into a default folder would
179
+ // silently reshuffle a library nobody asked to reorganise.
180
+ await db
181
+ .query(sql `alter table ${table} add column ${identifier('folder_id', db.dialect)} varchar(64)`)
182
+ .catch(() => undefined);
183
+ await db
184
+ .query(sql `create index ${identifier('cogenta_media_folder', db.dialect)}
185
+ on ${table} (folder_id, id)`)
186
+ .catch(() => undefined);
106
187
  ready = true;
107
188
  }
189
+ function filtersFor(listOptions) {
190
+ const kindFilter = listOptions.kind === undefined ? sql `` : sql `and kind = ${listOptions.kind}`;
191
+ const tagFilter = listOptions.tag === undefined || listOptions.tag.trim().length === 0
192
+ ? sql ``
193
+ : sql `and tags like ${`%${TAG_DELIMITER}${escapeLikePattern(listOptions.tag.trim())}${TAG_DELIMITER}%`} escape '\\'`;
194
+ const fromFilter = listOptions.from === undefined ? sql `` : sql `and created_at >= ${listOptions.from}`;
195
+ const toFilter = listOptions.to === undefined ? sql `` : sql `and created_at <= ${listOptions.to}`;
196
+ // `folderIds` (an already-resolved subtree, from the router's own
197
+ // `?includeSubfolders=1` handling) wins over the single-`folderId` exact
198
+ // match when both happen to be set — a caller asking for a subtree never
199
+ // also wants the plain equality.
200
+ const folderFilter = listOptions.folderIds !== undefined
201
+ ? listOptions.folderIds.length === 0
202
+ ? sql `and 1 = 0`
203
+ : sql `and folder_id in (${valueList(listOptions.folderIds)})`
204
+ : listOptions.folderId === undefined
205
+ ? sql ``
206
+ : listOptions.folderId === null
207
+ ? sql `and folder_id is null`
208
+ : sql `and folder_id = ${listOptions.folderId}`;
209
+ return sql `${kindFilter} ${tagFilter} ${fromFilter} ${toFilter} ${folderFilter}`;
210
+ }
108
211
  return {
109
212
  create: async (input) => {
110
213
  await ensureTable();
@@ -114,15 +217,18 @@ export function createDatabaseMediaStore(options) {
114
217
  validateAltPolicy(alt, decorative, justification);
115
218
  const id = input.id ?? randomUUID();
116
219
  const createdAt = new Date().toISOString();
220
+ const tags = input.tags ?? [];
221
+ const contentHash = input.contentHash ?? defaultContentHash(input.storageKey);
222
+ const folderId = input.folderId ?? null;
117
223
  await db.query(sql `
118
224
  insert into ${table}
119
225
  (id, kind, filename, mime_type, size, width, height, alt, decorative,
120
- decorative_justification, focal, storage_key, created_at, created_by)
226
+ decorative_justification, focal, storage_key, tags, content_hash, folder_id, created_at, created_by)
121
227
  values
122
228
  (${id}, ${input.kind}, ${input.filename}, ${input.mimeType}, ${input.size},
123
229
  ${input.width ?? null}, ${input.height ?? null}, ${alt}, ${decorative},
124
230
  ${justification}, ${input.focal === undefined || input.focal === null ? null : JSON.stringify(input.focal)},
125
- ${input.storageKey}, ${createdAt}, ${input.createdBy ?? null})`);
231
+ ${input.storageKey}, ${serializeTags(tags)}, ${contentHash}, ${folderId}, ${createdAt}, ${input.createdBy ?? null})`);
126
232
  return {
127
233
  id,
128
234
  kind: input.kind,
@@ -136,6 +242,9 @@ export function createDatabaseMediaStore(options) {
136
242
  decorativeJustification: justification,
137
243
  focal: input.focal ?? null,
138
244
  storageKey: input.storageKey,
245
+ tags,
246
+ contentHash,
247
+ folderId,
139
248
  createdAt,
140
249
  createdBy: input.createdBy ?? null,
141
250
  };
@@ -149,26 +258,41 @@ export function createDatabaseMediaStore(options) {
149
258
  list: async (listOptions = {}) => {
150
259
  await ensureTable();
151
260
  const pageSize = Math.min(listOptions.limit ?? DEFAULT_LIMIT, MAX_LIMIT);
152
- const cursor = listOptions.cursor === undefined ? null : decodeCursor(listOptions.cursor);
153
- const kindFilter = listOptions.kind === undefined ? sql `` : sql `and kind = ${listOptions.kind}`;
261
+ const sortField = listOptions.sort ?? 'createdAt';
262
+ const direction = listOptions.direction ?? 'desc';
263
+ const sortColumn = identifier(SORT_COLUMNS[sortField], db.dialect);
264
+ const cmp = direction === 'desc' ? sql `<` : sql `>`;
265
+ const order = direction === 'desc' ? sql `desc` : sql `asc`;
266
+ const cursor = listOptions.cursor === undefined ? null : decodeCursor(sortField, listOptions.cursor);
267
+ const filters = filtersFor(listOptions);
154
268
  const cursorFilter = cursor === null
155
269
  ? sql ``
156
- : sql `and (created_at < ${cursor.createdAt}
157
- or (created_at = ${cursor.createdAt} and id < ${cursor.id}))`;
270
+ : sql `and (${sortColumn} ${cmp} ${cursor.value}
271
+ or (${sortColumn} = ${cursor.value} and id ${cmp} ${cursor.id}))`;
158
272
  const result = await db.query(sql `
159
273
  select * from ${table}
160
- where 1 = 1 ${kindFilter} ${cursorFilter}
161
- order by created_at desc, id desc
274
+ where 1 = 1 ${filters} ${cursorFilter}
275
+ order by ${sortColumn} ${order}, id ${order}
162
276
  limit ${limit(pageSize + 1)}`);
163
277
  const hasMore = result.rows.length > pageSize;
164
- const page = result.rows.slice(0, pageSize).map(rowToAsset);
165
- const last = page[page.length - 1];
278
+ const rows = result.rows.slice(0, pageSize);
279
+ const page = rows.map(rowToAsset);
280
+ const lastRow = rows[rows.length - 1];
166
281
  return {
167
282
  items: page,
168
283
  hasMore,
169
- nextCursor: hasMore && last !== undefined ? encodeCursor(last) : null,
284
+ nextCursor: hasMore && lastRow !== undefined
285
+ ? encodeCursor(sortField, sortValueOf(sortField, lastRow), lastRow.id)
286
+ : null,
170
287
  };
171
288
  },
289
+ count: async (listOptions = {}) => {
290
+ await ensureTable();
291
+ const filters = filtersFor(listOptions);
292
+ const result = await db.query(sql `
293
+ select count(*) as c from ${table} where 1 = 1 ${filters}`);
294
+ return Number(result.rows[0]?.c ?? 0);
295
+ },
172
296
  update: async (id, input) => {
173
297
  await ensureTable();
174
298
  const existing = await db.query(sql `select * from ${table} where id = ${id}`);
@@ -187,12 +311,16 @@ export function createDatabaseMediaStore(options) {
187
311
  : input.focal === null
188
312
  ? null
189
313
  : JSON.stringify(input.focal);
314
+ const tags = input.tags === undefined ? current.tags : serializeTags(input.tags);
315
+ const folderId = input.folderId === undefined ? current.folder_id : input.folderId;
190
316
  await db.query(sql `
191
317
  update ${table}
192
318
  set alt = ${alt},
193
319
  decorative = ${decorative},
194
320
  decorative_justification = ${justification},
195
- focal = ${focal}
321
+ focal = ${focal},
322
+ tags = ${tags},
323
+ folder_id = ${folderId}
196
324
  where id = ${id}`);
197
325
  return rowToAsset({
198
326
  ...current,
@@ -200,6 +328,33 @@ export function createDatabaseMediaStore(options) {
200
328
  decorative,
201
329
  decorative_justification: justification,
202
330
  focal,
331
+ tags,
332
+ folder_id: folderId,
333
+ });
334
+ },
335
+ replace: async (id, input) => {
336
+ await ensureTable();
337
+ const existing = await db.query(sql `select * from ${table} where id = ${id}`);
338
+ const current = existing.rows[0];
339
+ if (current === undefined)
340
+ throw notFound(id);
341
+ await db.query(sql `
342
+ update ${table}
343
+ set mime_type = ${input.mimeType},
344
+ size = ${input.size},
345
+ width = ${input.width ?? null},
346
+ height = ${input.height ?? null},
347
+ storage_key = ${input.storageKey},
348
+ content_hash = ${input.contentHash}
349
+ where id = ${id}`);
350
+ return rowToAsset({
351
+ ...current,
352
+ mime_type: input.mimeType,
353
+ size: input.size,
354
+ width: input.width ?? null,
355
+ height: input.height ?? null,
356
+ storage_key: input.storageKey,
357
+ content_hash: input.contentHash,
203
358
  });
204
359
  },
205
360
  delete: async (id) => {
@@ -1 +1 @@
1
- {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/media/store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/media/store.ts"],"names":[],"mappings":"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"}
@@ -26,6 +26,30 @@ export interface MediaAsset {
26
26
  readonly focal: FocalPoint | null;
27
27
  /** The `StorageDriver` key the original lives under. */
28
28
  readonly storageKey: string;
29
+ /**
30
+ * Free-form labels an editor attaches (fiche 11 task 5). Not a hierarchy —
31
+ * an asset commonly belongs to more than one subject at once, which a
32
+ * single-parent folder tree cannot express without picking one.
33
+ */
34
+ readonly tags: readonly string[];
35
+ /**
36
+ * A short hash of the stored bytes, used only to bust an intermediate or
37
+ * browser cache when the original is replaced in place (fiche 11 task 4):
38
+ * `/_image?id=…` is otherwise a stable URL serving a year-long
39
+ * `Cache-Control: immutable` response (L10 task 5), so replacing the bytes
40
+ * behind it changes nothing a visitor's browser already cached until this
41
+ * value — folded into the URL as `&v=` — changes too. Never a secret and
42
+ * never used for integrity: a content hash, not a checksum of trust.
43
+ */
44
+ readonly contentHash: string;
45
+ /**
46
+ * The `MediaFolder` this asset sits in, or `null` when it has never been
47
+ * filed anywhere (fiche 46). `null` is "unclassified", not "in the root
48
+ * `contents` folder" — every asset uploaded before folders existed keeps
49
+ * this value forever unless an editor actually moves it, so the migration
50
+ * that added this column never silently reclassifies anything.
51
+ */
52
+ readonly folderId: string | null;
29
53
  readonly createdAt: string;
30
54
  readonly createdBy: string | null;
31
55
  }
@@ -42,6 +66,11 @@ export interface CreateMediaInput {
42
66
  readonly decorativeJustification?: string | null;
43
67
  readonly focal?: FocalPoint | null;
44
68
  readonly storageKey: string;
69
+ readonly tags?: readonly string[];
70
+ /** Derived from `storageKey` when absent — every caller that predates tagging still gets a stable value. */
71
+ readonly contentHash?: string;
72
+ /** Absent or `null` means unclassified — the same default every asset uploaded before fiche 46 already has. */
73
+ readonly folderId?: string | null;
45
74
  readonly createdBy?: string | null;
46
75
  }
47
76
  export interface UpdateMediaInput {
@@ -49,22 +78,141 @@ export interface UpdateMediaInput {
49
78
  readonly decorative?: boolean;
50
79
  readonly decorativeJustification?: string | null;
51
80
  readonly focal?: FocalPoint | null;
81
+ /** Replaces the whole set — a caller that wants to add one tag reads first, same as every other field here. */
82
+ readonly tags?: readonly string[];
83
+ /**
84
+ * Moves the asset. Absent leaves it where it is; `null` clears it back to
85
+ * unclassified; a folder id files it there. The single-asset and bulk
86
+ * "move" routes (`media-router.ts`) are both a thin wrapper over this —
87
+ * there is no separate move-only method on the store, the same way
88
+ * `update` already carries every other in-place change.
89
+ */
90
+ readonly folderId?: string | null;
52
91
  }
92
+ /**
93
+ * Overwrites the bytes behind an existing id (fiche 11 task 4) — "replace",
94
+ * never "re-upload": every entry and block already holding this id keeps
95
+ * working, unchanged, the moment this returns. `alt`, `decorative`, `tags`
96
+ * and `focal` are deliberately untouched — a replaced logo is still the same
97
+ * subject, so its description should not silently revert to empty.
98
+ */
99
+ export interface ReplaceMediaInput {
100
+ readonly mimeType: string;
101
+ readonly size: number;
102
+ readonly width?: number | null;
103
+ readonly height?: number | null;
104
+ readonly storageKey: string;
105
+ readonly contentHash: string;
106
+ }
107
+ export type MediaSortField = 'createdAt' | 'filename' | 'size';
53
108
  export interface ListMediaOptions {
54
109
  readonly kind?: MediaKind;
110
+ /** Exact match on one tag. Combined with `kind`/date range/free-text `q`, whichever the caller (the REST layer) also applies. */
111
+ readonly tag?: string;
112
+ /** Inclusive lower bound on `createdAt`, ISO 8601. */
113
+ readonly from?: string;
114
+ /** Inclusive upper bound on `createdAt`, ISO 8601. */
115
+ readonly to?: string;
116
+ readonly sort?: MediaSortField;
117
+ readonly direction?: 'asc' | 'desc';
55
118
  readonly limit?: number;
56
119
  readonly cursor?: string;
120
+ /**
121
+ * Exact match on one folder. `null` means "unclassified" (`folder_id is
122
+ * null`) — a real, listable state, not "no filter". Absent means no
123
+ * filtering by folder at all. Combined with `folderIds` below only by the
124
+ * REST layer, never both at once.
125
+ */
126
+ readonly folderId?: string | null;
127
+ /**
128
+ * Matches any of these folder ids — how "include subfolders" is
129
+ * implemented (`media-router.ts`'s `?folderId=&includeSubfolders=1`
130
+ * resolves the folder's whole subtree via `MediaFolderStore.subtreeIds`
131
+ * first, then passes the resolved set here). Deliberately not a tree
132
+ * concept on `MediaStore` itself: this store knows nothing about folder
133
+ * hierarchy, only about matching a column against a set of ids.
134
+ */
135
+ readonly folderIds?: readonly string[];
57
136
  }
58
137
  export interface MediaPage {
59
138
  readonly items: readonly MediaAsset[];
60
139
  readonly nextCursor: string | null;
61
140
  readonly hasMore: boolean;
62
141
  }
142
+ /**
143
+ * A folder in the media library's tree (fiche 46).
144
+ *
145
+ * Not contract A: a folder classifies files, not content, the same
146
+ * separation the fiche 11 decision already drew for tags ("étiquettes
147
+ * plutôt que dossiers" — folders are the hierarchy that decision noted the
148
+ * taxonomy machinery could provide if ever asked for; this is that ask).
149
+ * `path` is a materialised path exactly like a taxonomy term's (ADR-0022) —
150
+ * see `folder-path.ts` for why it is a *local* copy of that arithmetic
151
+ * rather than an import: `@cogenta/core` cannot depend on `@cogenta/schema`,
152
+ * which is where the taxonomy version lives.
153
+ */
154
+ export interface MediaFolder {
155
+ readonly id: string;
156
+ readonly parentId: string | null;
157
+ readonly name: string;
158
+ readonly path: string;
159
+ /** Position among siblings, for a stable, editor-controlled order. */
160
+ readonly position: number;
161
+ readonly createdAt: string;
162
+ }
163
+ export interface CreateMediaFolderInput {
164
+ readonly id?: string;
165
+ readonly name: string;
166
+ /** `null` or absent creates a root folder. */
167
+ readonly parentId?: string | null;
168
+ /** Left out, the folder goes last among its siblings. */
169
+ readonly position?: number;
170
+ }
171
+ export interface UpdateMediaFolderInput {
172
+ readonly name?: string;
173
+ readonly position?: number;
174
+ }
175
+ export interface ListMediaFoldersOptions {
176
+ /** Only the direct children of this folder; `null` means the roots. Omitted returns the whole tree, flattened depth-first. */
177
+ readonly parentId?: string | null;
178
+ }
179
+ export interface MediaFolderStore {
180
+ create(input: CreateMediaFolderInput): Promise<MediaFolder>;
181
+ read(id: string): Promise<MediaFolder | null>;
182
+ /** Renames and/or repositions — never reparents, that is `move`. */
183
+ update(id: string, input: UpdateMediaFolderInput): Promise<MediaFolder>;
184
+ /** Re-parents a folder and rewrites its whole subtree's paths. */
185
+ move(id: string, parentId: string | null): Promise<MediaFolder>;
186
+ /**
187
+ * Refuses when the folder still has subfolders or media assets in it
188
+ * (`MEDIA_FOLDER_NOT_EMPTY`) — always, including the bootstrap `contents`
189
+ * root: nothing here treats it as more special than any other folder once
190
+ * it exists.
191
+ */
192
+ delete(id: string): Promise<boolean>;
193
+ list(options?: ListMediaFoldersOptions): Promise<readonly MediaFolder[]>;
194
+ /** This folder's id plus every descendant's — how `?includeSubfolders=1` is resolved. */
195
+ subtreeIds(id: string): Promise<readonly string[]>;
196
+ /**
197
+ * Idempotent bootstrap: returns the root folder named `name` if one
198
+ * exists, otherwise creates it. Called once at server startup for the
199
+ * default `contents` root (fiche 46 task 6) — safe to call on every
200
+ * restart of an already-provisioned site.
201
+ */
202
+ ensureRoot(name: string): Promise<MediaFolder>;
203
+ }
63
204
  export interface MediaStore {
64
205
  create(input: CreateMediaInput): Promise<MediaAsset>;
65
206
  get(id: string): Promise<MediaAsset | null>;
66
207
  list(options?: ListMediaOptions): Promise<MediaPage>;
208
+ /**
209
+ * How many assets match `options` in total — ignoring `limit`/`cursor` —
210
+ * so the admin screen can show "2,000 assets" instead of only "there is
211
+ * another page" (fiche 11 task 2).
212
+ */
213
+ count(options?: Omit<ListMediaOptions, 'limit' | 'cursor'>): Promise<number>;
67
214
  update(id: string, input: UpdateMediaInput): Promise<MediaAsset>;
215
+ replace(id: string, input: ReplaceMediaInput): Promise<MediaAsset>;
68
216
  delete(id: string): Promise<void>;
69
217
  }
70
218
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/media/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/media/types.ts"],"names":[],"mappings":"AAAA,oHAAoH;AACpH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,eAAO,MAAM,WAAW,YAAI,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAU,CAAA;AACvE,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAA;AAEpD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,+IAA+I;IAC/I,QAAQ,CAAC,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/C,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAA;IACjC,wDAAwD;IACxD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IAChC;;;;;;;;OAQG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,CAAA;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,4GAA4G;IAC5G,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,+GAA+G;IAC/G,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAA;IAC7B,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,GAAG,IAAI,CAAA;IAClC,+GAA+G;IAC/G,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAClC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAA;AAE9D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAA;IACzB,iIAAiI;IACjI,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,sDAAsD;IACtD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,CAAA;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACvC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAA;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAC1B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,MAAM,WAAW,uBAAuB;IACtC,8HAA8H;IAC9H,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAClC;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IAC3D,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IAC7C,oEAAoE;IACpE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IACvE,kEAAkE;IAClE,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IAC/D;;;;;OAKG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACpC,IAAI,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAAA;IACxE,yFAAyF;IACzF,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAA;IAClD;;;;;OAKG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;CAC/C;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACpD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;IAC3C,IAAI,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;IACpD;;;;OAIG;IACH,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,OAAO,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC5E,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IAChE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IAClE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAClC"}
@@ -51,10 +51,14 @@ interface BullmqJobLike {
51
51
  moveToCompleted(returnValue: unknown, token: string, fetchNext?: boolean): Promise<unknown>;
52
52
  moveToFailed(error: Error, token: string, fetchNext?: boolean): Promise<unknown>;
53
53
  remove(): Promise<void>;
54
+ /** bullmq's own re-queue: moves a `failed` job back to `waiting` with a fresh attempt count. */
55
+ retry(state?: 'failed' | 'completed'): Promise<void>;
54
56
  }
55
57
  interface BullmqQueueLike {
56
58
  add(name: string, data: unknown, options?: BullmqAddOptionsLike): Promise<BullmqJobLike>;
57
59
  getJob(id: string): Promise<BullmqJobLike | undefined>;
60
+ /** `types` is bullmq's own vocabulary: 'waiting' | 'active' | 'completed' | 'failed' | 'delayed' | 'paused'. */
61
+ getJobs(types: readonly string[], start?: number, end?: number): Promise<BullmqJobLike[]>;
58
62
  getBackend(): BullmqBackendLike;
59
63
  close(): Promise<void>;
60
64
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bullmq.d.ts","sourceRoot":"","sources":["../../src/queue/bullmq.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bullmq.d.ts","sourceRoot":"","sources":["../../src/queue/bullmq.ts"],"names":[],"mappings":"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"}
@@ -66,6 +66,31 @@ function toJobStatus(state) {
66
66
  return 'pending';
67
67
  }
68
68
  }
69
+ /** The inverse of `toJobStatus`, for `getJobs`'s type filter. `cancelled` has no bullmq state of its own — it lives only in the tombstone hash, so `list()` never asks bullmq for it directly. */
70
+ function fromJobStatus(status) {
71
+ switch (status) {
72
+ case 'completed':
73
+ return 'completed';
74
+ case 'failed':
75
+ return 'failed';
76
+ case 'running':
77
+ return 'active';
78
+ default:
79
+ return 'waiting';
80
+ }
81
+ }
82
+ async function toJobState(job) {
83
+ const failedReason = job.failedReason;
84
+ return {
85
+ id: encodeJobId(job.name, job.id ?? ''),
86
+ name: job.name,
87
+ status: toJobStatus(await job.getState()),
88
+ attempt: job.attemptsMade,
89
+ maxAttempts: job.opts.attempts ?? DEFAULT_MAX_ATTEMPTS,
90
+ runAt: job.timestamp + job.delay,
91
+ lastError: failedReason === undefined || failedReason === '' ? undefined : failedReason,
92
+ };
93
+ }
69
94
  /**
70
95
  * The optimal job queue: Redis, driven through bullmq.
71
96
  *
@@ -247,16 +272,34 @@ export function createBullmqQueue(options) {
247
272
  const job = await queueFor(parsed.name).getJob(parsed.jobId);
248
273
  if (job === undefined)
249
274
  return null;
250
- const failedReason = job.failedReason;
251
- return {
252
- id,
253
- name: job.name,
254
- status: toJobStatus(await job.getState()),
255
- attempt: job.attemptsMade,
256
- maxAttempts: job.opts.attempts ?? DEFAULT_MAX_ATTEMPTS,
257
- runAt: job.timestamp + job.delay,
258
- lastError: failedReason === undefined || failedReason === '' ? undefined : failedReason,
259
- };
275
+ return toJobState(job);
276
+ },
277
+ // Only names this driver has actually touched (processed or enqueued
278
+ // through it) can be searched — bullmq shards jobs by queue name, and
279
+ // there is no global "every name that ever existed" index to scan.
280
+ // `cogenta serve` builds one long-lived driver per queue, so this
281
+ // covers everything a real deployment enqueues.
282
+ list: async (listOptions = {}) => {
283
+ const names = new Set([...handlers.keys(), ...queues.keys()]);
284
+ const types = listOptions.status === undefined
285
+ ? ['waiting', 'delayed', 'active', 'completed', 'failed']
286
+ : [fromJobStatus(listOptions.status)];
287
+ const perQueue = await Promise.all([...names].map((name) => queueFor(name).getJobs([...types], 0, 200)));
288
+ const states = await Promise.all(perQueue.flat().map((job) => toJobState(job)));
289
+ states.sort((a, b) => b.runAt - a.runAt);
290
+ return states.slice(0, listOptions.limit ?? 50);
291
+ },
292
+ retry: async (id) => {
293
+ const parsed = decodeJobId(id);
294
+ if (parsed === null)
295
+ return false;
296
+ const job = await queueFor(parsed.name).getJob(parsed.jobId);
297
+ if (job === undefined)
298
+ return false;
299
+ if (toJobStatus(await job.getState()) !== 'failed')
300
+ return false;
301
+ await job.retry('failed');
302
+ return true;
260
303
  },
261
304
  close: async () => {
262
305
  handlers.clear();