@uniweb/build 0.14.17 → 0.14.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniweb/build",
3
- "version": "0.14.17",
3
+ "version": "0.14.18",
4
4
  "description": "Build tooling for the Uniweb Component Web Platform",
5
5
  "type": "module",
6
6
  "exports": {
@@ -63,9 +63,9 @@
63
63
  "@uniweb/theming": "0.1.4"
64
64
  },
65
65
  "optionalDependencies": {
66
- "@uniweb/content-reader": "1.1.12",
66
+ "@uniweb/runtime": "0.8.20",
67
67
  "@uniweb/schemas": "0.2.3",
68
- "@uniweb/runtime": "0.8.20"
68
+ "@uniweb/content-reader": "1.1.12"
69
69
  },
70
70
  "peerDependencies": {
71
71
  "vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
@@ -409,6 +409,21 @@ function normalizeSection(section, ref, path, briefState) {
409
409
  if (section.nestable) out.nestable = true
410
410
  }
411
411
 
412
+ // `append_only` — a multi whose records are insert-only: the backend accepts
413
+ // appends but refuses edits or deletes of existing items, so the section is
414
+ // tamper-evident (activity logs, submissions, audit trails). Carried into the IR
415
+ // verbatim for the submission lowering to emit as the model's `append_only`.
416
+ // Like `nestable`, only a `multi` section can be append-only.
417
+ if (section.append_only !== undefined) {
418
+ if (typeof section.append_only !== 'boolean') {
419
+ throw new Error(`Data schema '${ref}': section '${path}' 'append_only' must be a boolean.`)
420
+ }
421
+ if (section.append_only && kind !== 'multi') {
422
+ throw new Error(`Data schema '${ref}': section '${path}' is 'append_only: true' but kind '${kind}' — only a 'multi' section can be append-only.`)
423
+ }
424
+ if (section.append_only) out.append_only = true
425
+ }
426
+
412
427
  return out
413
428
  }
414
429
 
@@ -135,14 +135,15 @@ function lowerSectionsForm(sectionsMap, resolve, optResolve) {
135
135
  // Lower one section to its declaration body (the caller keys it by name; a nested
136
136
  // section gets a `type: section` marker prepended in lowerField). `kind: multi` →
137
137
  // `multiple: true`; `binder` is derived (no marker — it falls out of "all fields
138
- // are type: section"); `nestable` → `self_nesting`; authored cross-cutting
139
- // `constraints` pass through as a bare array. Leaves and nested sections share one
140
- // ordered `fields:` namespace.
138
+ // are type: section"); `nestable` → `self_nesting`; `append_only` (insert-only
139
+ // records) passes through; authored cross-cutting `constraints` pass through as a
140
+ // bare array. Leaves and nested sections share one ordered `fields:` namespace.
141
141
  function lowerSection(def, resolve, optResolve) {
142
142
  const out = {}
143
143
  if ((def.kind || 'single') === 'multi') out.multiple = true
144
144
  if (def.brief === true) out.brief = true
145
145
  if (def.nestable) out.self_nesting = true
146
+ if (def.append_only) out.append_only = true
146
147
 
147
148
  const fields = {}
148
149
  for (const [key, rawField] of Object.entries(def.fields || {})) {