@coffer-org/server 2.7.0 → 3.0.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/dist/mutate.js CHANGED
@@ -2,6 +2,7 @@ import { serialize } from '@mikro-orm/core';
2
2
  import { buildZodObject, buildZodObjectPartial, fieldEntries } from '@coffer-org/sdk/shelf';
3
3
  import { isJsonStored, decodeVmsg } from '@coffer-org/sdk/fields';
4
4
  import { resolveFlag } from '@coffer-org/sdk/condition';
5
+ import { applyDerived } from '@coffer-org/sdk/derive';
5
6
  import { getEm } from "./db.js";
6
7
  import { selectRows } from "./read-rows.js";
7
8
  import { normalizeFileFields, dropUnchangedFileFields, touchesFileFields } from "./file-fields.js";
@@ -87,6 +88,11 @@ export async function createRecord(m, entityName, input, ctx, afterBase) {
87
88
  await tx.flush();
88
89
  id = entity.id;
89
90
  await writeCollections(tx, m, id, collections);
91
+ const derived = applyDerived(m.fields, { ...parsedData, id });
92
+ if (Object.keys(derived).length) {
93
+ await tx.nativeUpdate(entityName, { id }, encodeJson(m, encodeTemporal(m, flattenEmbedded(m, derived))));
94
+ Object.assign(parsedData, derived);
95
+ }
90
96
  const _extends = afterBase ? await afterBase(tx, id) : undefined;
91
97
  writeEvent(tx, ctx.actor, 'create', `${m.library}/${m.shelf}`, id, null, {
92
98
  ...parsedData,
@@ -144,6 +150,11 @@ export async function updateRecord(m, entityName, id, input, ctx, afterBase) {
144
150
  await tx.upsert(entityName, dbRow);
145
151
  await writeCollections(tx, m, id, collections);
146
152
  const allCollections = await readCollections(tx, m, id);
153
+ const derived = applyDerived(m.fields, { ...merged, ...allCollections });
154
+ if (Object.keys(derived).length) {
155
+ await tx.nativeUpdate(entityName, { id }, encodeJson(m, encodeTemporal(m, flattenEmbedded(m, derived))));
156
+ Object.assign(merged, derived);
157
+ }
147
158
  const _extends = afterBase ? await afterBase(tx, id) : undefined;
148
159
  const after = { ...merged, ...allCollections, updated_at: ts, ...(_extends ? { _extends } : {}) };
149
160
  writeEvent(tx, ctx.actor, 'update', `${m.library}/${m.shelf}`, id, existing, after);
@@ -0,0 +1,6 @@
1
+ import type { ShelfDef } from '@coffer-org/sdk/shelf';
2
+ export interface RecomputeResult {
3
+ scanned: number;
4
+ changed: number;
5
+ }
6
+ export declare function recomputeDerivedFields(m: ShelfDef, entityName: string): Promise<RecomputeResult>;
@@ -0,0 +1,40 @@
1
+ import { derivedEntries, applyDerived } from '@coffer-org/sdk/derive';
2
+ import { getEm } from "./db.js";
3
+ import { selectRows } from "./read-rows.js";
4
+ import { encodeJson } from "./mutate.js";
5
+ import { encodeTemporal, decodeTemporal } from "./temporal.js";
6
+ import { flattenEmbedded, nestEmbedded, readCollections } from "./collection-io.js";
7
+ function sameValue(a, b) {
8
+ if (a instanceof Date && b instanceof Date)
9
+ return a.getTime() === b.getTime();
10
+ if (a instanceof Date || b instanceof Date)
11
+ return false;
12
+ return a === b;
13
+ }
14
+ export async function recomputeDerivedFields(m, entityName) {
15
+ if (derivedEntries(m.fields).length === 0)
16
+ return { scanned: 0, changed: 0 };
17
+ const fork = getEm().fork();
18
+ const rows = await selectRows(fork, entityName, {}, { orderBy: { id: 'asc' } });
19
+ let changed = 0;
20
+ for (const row of rows) {
21
+ const id = row['id'];
22
+ const flat = decodeTemporal(m, row);
23
+ const nested = nestEmbedded(m, flat);
24
+ const collections = await readCollections(fork, m, id);
25
+ const derived = applyDerived(m.fields, { ...nested, ...collections });
26
+ if (Object.keys(derived).length === 0)
27
+ continue;
28
+ const encoded = encodeJson(m, encodeTemporal(m, flattenEmbedded(m, derived)));
29
+ const dirty = {};
30
+ for (const [k, v] of Object.entries(encoded)) {
31
+ if (!sameValue(row[k], v))
32
+ dirty[k] = v;
33
+ }
34
+ if (Object.keys(dirty).length === 0)
35
+ continue;
36
+ await fork.nativeUpdate(entityName, { id }, dirty);
37
+ changed += 1;
38
+ }
39
+ return { scanned: rows.length, changed };
40
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coffer-org/server",
3
- "version": "2.7.0",
3
+ "version": "3.0.0",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=24"
@@ -24,8 +24,8 @@
24
24
  "postpack": "node ../../scripts/swap-exports.mjs src"
25
25
  },
26
26
  "dependencies": {
27
- "@coffer-org/core": "^2.1.4",
28
- "@coffer-org/sdk": "^2.2.1",
27
+ "@coffer-org/core": "^3.0.0",
28
+ "@coffer-org/sdk": "^3.0.0",
29
29
  "@extractus/oembed-extractor": "^4.1.0",
30
30
  "@fastify/cors": "^11.2.0",
31
31
  "@fastify/multipart": "^10.0.0",