@cosmicdrift/kumiko-types 0.188.0 → 0.190.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.190.0",
|
|
4
4
|
"description": "Framework-Type-Definitions für Kumiko — FeatureDefinition, BootCheck-Types und die reinen Engine-Types. Erlaubt Downstream-Konsumenten, gegen die Type-Contracts zu bauen, ohne das ganze Framework-Package zu importieren. Enthaelt keine identitaets-sensitiven Runtime-Werte mehr (Error-Klassen leben seit #1629 in kumiko-framework, Brand-Symbole nutzen Symbol.for) und ist deshalb eine plain dependency, keine peerDependency.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -194,6 +194,10 @@
|
|
|
194
194
|
"types": "./src/file-provider-resolver-types.ts",
|
|
195
195
|
"default": "./src/file-provider-resolver-types.ts"
|
|
196
196
|
},
|
|
197
|
+
"./derivatives-types": {
|
|
198
|
+
"types": "./src/derivatives-types.ts",
|
|
199
|
+
"default": "./src/derivatives-types.ts"
|
|
200
|
+
},
|
|
197
201
|
"./event-store-executor-types": {
|
|
198
202
|
"types": "./src/event-store-executor-types.ts",
|
|
199
203
|
"default": "./src/event-store-executor-types.ts"
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Derived-file-variants (thumbnails, resized/reformatted images, …) — pure
|
|
2
|
+
// types, no runtime logic. Client-visible package: no `node:*` imports.
|
|
3
|
+
|
|
4
|
+
export type VariantFit = "cover" | "inside" | "contain";
|
|
5
|
+
export type VariantFormat = "webp" | "avif" | "jpeg";
|
|
6
|
+
|
|
7
|
+
export type VariantSpec = {
|
|
8
|
+
// Default "inside" when omitted (renderer-side default, Schnitt 2).
|
|
9
|
+
readonly fit?: VariantFit;
|
|
10
|
+
readonly size?: { readonly width: number; readonly height: number };
|
|
11
|
+
// Alternative to `size` — longest edge in pixels, aspect preserved.
|
|
12
|
+
readonly maxEdge?: number;
|
|
13
|
+
readonly format?: VariantFormat;
|
|
14
|
+
readonly quality?: number;
|
|
15
|
+
// Whole-image blur radius.
|
|
16
|
+
readonly blur?: number;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// A renderer turns the original bytes + a spec into the derived bytes for one
|
|
20
|
+
// variant. Registered per MIME-type (exact or `<type>/*` wildcard) via the
|
|
21
|
+
// `derivativeRenderer` extension point — see EXT_DERIVATIVE_RENDERER.
|
|
22
|
+
//
|
|
23
|
+
// The renderer must produce `spec.format` when set, and the source's own
|
|
24
|
+
// format otherwise. It never reports back what it produced: the caller
|
|
25
|
+
// derives the output mimeType from the spec alone (see outputMimeType in
|
|
26
|
+
// derivatives-context.ts), because a cache hit has no renderer run to read
|
|
27
|
+
// a mimeType off, and a spec-derived value is the only one both branches
|
|
28
|
+
// can share.
|
|
29
|
+
export type DerivativeRendererPlugin = {
|
|
30
|
+
readonly render: (
|
|
31
|
+
input: Uint8Array,
|
|
32
|
+
spec: VariantSpec,
|
|
33
|
+
sourceMimeType: string,
|
|
34
|
+
) => Promise<Uint8Array>;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type VariantResult = {
|
|
38
|
+
readonly storageKey: string;
|
|
39
|
+
readonly mimeType: string;
|
|
40
|
+
// true = rendered during this call, false = an existing derivative was
|
|
41
|
+
// found and returned unchanged.
|
|
42
|
+
readonly rendered: boolean;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// The `ctx.derivatives` service — derive-on-first-use variants of a tracked
|
|
46
|
+
// FileRef. `name` feeds only the readable key-prefix; `spec` determines the
|
|
47
|
+
// content hash, so a spec change always produces a fresh URL instead of
|
|
48
|
+
// silently overwriting what's cached under the old pixels.
|
|
49
|
+
export type DerivativesContext = {
|
|
50
|
+
readonly variant: (fileRefId: string, spec: VariantSpec, name: string) => Promise<VariantResult>;
|
|
51
|
+
};
|
|
@@ -21,6 +21,10 @@ export type PgType =
|
|
|
21
21
|
| "jsonb"
|
|
22
22
|
| "timestamptz"
|
|
23
23
|
| "timestamptz(3)"
|
|
24
|
+
// Calendar day, no time-of-day/timezone component — Temporal.PlainDate.
|
|
25
|
+
// Distinct from timestamptz: a `date` field is a pure calendar concept
|
|
26
|
+
// (invoice date, lease term) and must never round-trip through an Instant.
|
|
27
|
+
| "date"
|
|
24
28
|
// Exact decimal — precision/scale are encoded in the type string so the
|
|
25
29
|
// DDL renderer and read-coercion need no side-channel metadata.
|
|
26
30
|
| `numeric(${number},${number})`;
|
package/src/handlers.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { Redis } from "ioredis";
|
|
|
2
2
|
import type { ZodType } from "zod";
|
|
3
3
|
import type { ConfigAccessor, ConfigAccessorFactory, ConfigResolver } from "./config";
|
|
4
4
|
import type { DbConnection } from "./db-connection";
|
|
5
|
+
import type { DerivativesContext } from "./derivatives-types";
|
|
5
6
|
import type { EntityCache } from "./entity-cache";
|
|
6
7
|
import type { KumikoEventTypeMap } from "./event-type-map";
|
|
7
8
|
import type { FileContext } from "./file-handle-types";
|
|
@@ -239,6 +240,9 @@ type SharedContextFields = {
|
|
|
239
240
|
// GDPR jobs all resolve through the same file-foundation provider. Hooks/
|
|
240
241
|
// handlers use ctx.files.ref(key) instead of receiving binaries in payloads.
|
|
241
242
|
readonly files?: FileContext;
|
|
243
|
+
// Derive-on-first-use variants (thumbnails, resized/reformatted images) of a
|
|
244
|
+
// tracked FileRef. Present whenever `files` resolves — see files above.
|
|
245
|
+
readonly derivatives?: DerivativesContext;
|
|
242
246
|
// Boot-built, per-tenant file-provider resolver. Set by buildServer when a
|
|
243
247
|
// `file-provider-*` plugin is mounted; the dispatcher reads it to materialise
|
|
244
248
|
// ctx.files (and the upload routes + MSP-applies use the same resolver).
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DerivativesContext } from "./derivatives-types";
|
|
1
2
|
import type { StoredEvent } from "./event-store-types";
|
|
2
3
|
import type { KumikoEventTypeMap } from "./event-type-map";
|
|
3
4
|
import type { FileContext } from "./file-handle-types";
|
|
@@ -35,4 +36,7 @@ export type MultiStreamApplyContext<TMap extends object = KumikoEventTypeMap> =
|
|
|
35
36
|
// `ctx.files.ref(payload.storageKey).read()` and write derivates via
|
|
36
37
|
// `.derive("thumb").write(...)` — binaries never ride through events.
|
|
37
38
|
readonly files?: FileContext;
|
|
39
|
+
// Derive-on-first-use variants, mirrors AppContext.derivatives. Present
|
|
40
|
+
// exactly when `files` is — same file-foundation-provider precondition.
|
|
41
|
+
readonly derivatives?: DerivativesContext;
|
|
38
42
|
};
|
package/src/screen.ts
CHANGED
|
@@ -593,6 +593,22 @@ export type EntityEditScreenDefinition = {
|
|
|
593
593
|
* (History-/Audit-Erhalt): unterdrückt den Löschen-Button im
|
|
594
594
|
* Update-Form. */
|
|
595
595
|
readonly allowDelete?: boolean;
|
|
596
|
+
/** Default false. `true` for singleton entities (exactly one record per
|
|
597
|
+
* tenant: organization, settings, tenant profile). A call without an
|
|
598
|
+
* `entityId` first resolves the existing record via `<entity>:list`
|
|
599
|
+
* (limit 1) and renders the update branch with prefill on a hit,
|
|
600
|
+
* instead of blindly creating another one. The create branch only
|
|
601
|
+
* fires when the table is empty (and `allowCreate: false` still
|
|
602
|
+
* applies there). */
|
|
603
|
+
readonly singleton?: boolean;
|
|
604
|
+
/** Navigate to this screen ID after a successful save (create or update).
|
|
605
|
+
* Either a same-feature short screen-ID, or a fully-qualified
|
|
606
|
+
* cross-feature screen QN (`<feature>:screen:<id>`) — the nav-router
|
|
607
|
+
* resolves both against the schema; boot-validator checks the target
|
|
608
|
+
* resolves to a registered screen. Overrides the default post-save
|
|
609
|
+
* target (the entity's list screen); delete is unaffected and still
|
|
610
|
+
* always navigates to the list. */
|
|
611
|
+
readonly redirect?: string;
|
|
596
612
|
/** Optionaler per-Field-Label-i18n-Key (Field-Name → Key), überschreibt
|
|
597
613
|
* die Default-Konvention `<feature>:entity:<entity>:field:<name>`.
|
|
598
614
|
* Primär für configEdit: dessen Pseudo-Entity `__config-edit__` hat
|
|
@@ -639,18 +655,20 @@ export type ActionFormScreenDefinition = {
|
|
|
639
655
|
/** i18n-key für den Submit-Button. Default: i18n-Default des
|
|
640
656
|
* Renderers (typischerweise "actions.submit"). */
|
|
641
657
|
readonly submitLabel?: string;
|
|
642
|
-
/** Nach erfolgreichem Submit zu dieser Screen-ID navigieren
|
|
643
|
-
* ID
|
|
644
|
-
* zum vollen Pfad)
|
|
645
|
-
* Wenn nicht gesetzt, bleibt der User auf
|
|
646
|
-
* Validator prüft dass
|
|
658
|
+
/** Nach erfolgreichem Submit zu dieser Screen-ID navigieren: entweder
|
|
659
|
+
* kurze ID (z.B. "item-list" — gleiche Feature, der nav-Router
|
|
660
|
+
* resolved zum vollen Pfad) oder voll-qualifizierte Cross-Feature-QN
|
|
661
|
+
* (`<feature>:screen:<id>`). Wenn nicht gesetzt, bleibt der User auf
|
|
662
|
+
* dem Form-Screen. Boot-Validator prüft dass das Ziel einen
|
|
663
|
+
* registrierten Screen meint. */
|
|
647
664
|
readonly redirect?: string;
|
|
648
665
|
/** Ziel des Abbrechen-Buttons. Default: `redirect` (historisches
|
|
649
666
|
* Verhalten — Cancel und Submit-Redirect landen dann am selben Ort).
|
|
650
667
|
* `false` = kein Abbrechen-Button; richtig für Single-Action-Screens
|
|
651
668
|
* ohne verwerfbaren Zustand (z.B. "Test-Mail senden"), wo Abbrechen
|
|
652
|
-
* nur ein zweiter Weg zum selben Ziel wäre.
|
|
653
|
-
* String-Targets wie `redirect
|
|
669
|
+
* nur ein zweiter Weg zum selben Ziel wäre. Akzeptiert dieselben
|
|
670
|
+
* String-Targets wie `redirect` (kurze ID oder Cross-Feature-QN);
|
|
671
|
+
* Boot-Validator prüft das. */
|
|
654
672
|
readonly cancelTarget?: string | false;
|
|
655
673
|
readonly slots?: ScreenSlots;
|
|
656
674
|
readonly access?: AccessRule;
|