@cosmicdrift/kumiko-framework 0.361.0 → 0.363.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/api/auth-middleware.js +7 -5
- package/dist/api/redis-sse-broker.js +10 -8
- package/dist/api/routes.js +2 -2
- package/dist/api/server.js +3 -0
- package/dist/bun-db/query.d.ts +6 -4
- package/dist/bun-db/query.js +66 -92
- package/dist/crypto/kek-source.js +5 -3
- package/dist/crypto/pii-field-encryption.d.ts +4 -1
- package/dist/crypto/pii-field-encryption.js +2 -2
- package/dist/db/apply-entity-event.js +2 -2
- package/dist/db/cursor.js +2 -1
- package/dist/db/dialect.d.ts +1 -0
- package/dist/db/dialect.js +28 -13
- package/dist/db/entity-table-from-registry.js +1 -1
- package/dist/db/entity-table-meta.js +5 -13
- package/dist/db/event-store-executor-context.js +6 -6
- package/dist/db/event-store-executor-read.js +9 -9
- package/dist/db/migrate-generator.js +5 -3
- package/dist/db/migrate-runner.js +31 -35
- package/dist/db/parent-ref-clause.js +2 -2
- package/dist/db/queries/backfill-pii.js +11 -9
- package/dist/db/queries/es-ops.js +1 -1
- package/dist/db/queries/event-consumer.d.ts +6 -6
- package/dist/db/queries/event-consumer.js +17 -17
- package/dist/db/queries/event-store-admin.js +6 -6
- package/dist/db/queries/event-store-transfer.js +2 -2
- package/dist/db/queries/event-store.d.ts +1 -1
- package/dist/db/queries/event-store.js +2 -2
- package/dist/db/queries/pii-backfill-state.js +2 -2
- package/dist/db/queries/projection-rebuild.d.ts +1 -1
- package/dist/db/queries/raw-sql.js +1 -1
- package/dist/db/queries/test-stack.js +1 -1
- package/dist/db/reference-data.js +3 -5
- package/dist/db/table-builder.js +6 -4
- package/dist/db/table-introspection.d.ts +16 -0
- package/dist/db/table-introspection.js +76 -0
- package/dist/db/tenant-db.d.ts +3 -2
- package/dist/db/tenant-db.js +4 -10
- package/dist/derivatives/variant-key.js +2 -1
- package/dist/engine/boot-validator/access-declarations.js +29 -18
- package/dist/engine/boot-validator/card-meta-overflow.js +5 -2
- package/dist/engine/boot-validator/entity-list-screens.js +1 -1
- package/dist/engine/boot-validator/pii-retention.js +1 -1
- package/dist/engine/boot-validator/screens.js +2 -1
- package/dist/engine/build-app-schema.js +1 -0
- package/dist/engine/changeset-changes.js +3 -3
- package/dist/engine/define-handler.js +3 -6
- package/dist/engine/embedded-derived.js +10 -6
- package/dist/engine/extensions/escape-hatch-usage.js +2 -1
- package/dist/engine/factories.js +5 -6
- package/dist/engine/feature-ast/extractors/events.js +43 -33
- package/dist/engine/feature-ast/extractors/round3.d.ts +2 -2
- package/dist/engine/feature-ast/extractors/round3.js +4 -4
- package/dist/engine/feature-ast/patcher.d.ts +3 -3
- package/dist/engine/feature-ast/patcher.js +3 -3
- package/dist/engine/feature-ast/pattern-change-schema.d.ts +8 -8
- package/dist/engine/feature-ast/pattern-change-schema.js +3 -3
- package/dist/engine/feature-ast/patterns.d.ts +3 -3
- package/dist/engine/feature-ast/render.js +6 -3
- package/dist/engine/feature-changelog.d.ts +2 -1
- package/dist/engine/feature-changelog.js +8 -6
- package/dist/engine/feature-config-events-jobs.d.ts +17 -7
- package/dist/engine/feature-config-events-jobs.js +20 -5
- package/dist/engine/feature-ui-extensions.js +2 -3
- package/dist/engine/index.d.ts +2 -1
- package/dist/engine/index.js +1 -0
- package/dist/engine/ownership.js +7 -20
- package/dist/engine/pattern-library/mixed-schemas.js +0 -1
- package/dist/engine/registry-ingest.d.ts +2 -1
- package/dist/engine/registry-ingest.js +85 -2
- package/dist/engine/registry-validate.d.ts +1 -0
- package/dist/engine/registry-validate.js +38 -8
- package/dist/engine/registry.js +2 -1
- package/dist/engine/schema-builder.js +1 -3
- package/dist/engine/soft-delete-cleanup.js +2 -1
- package/dist/engine/steps/call-feature.js +1 -3
- package/dist/engine/steps/unsafe-projection-upsert.js +2 -13
- package/dist/engine/template-variables.d.ts +29 -0
- package/dist/engine/template-variables.js +77 -0
- package/dist/engine/tier-resolver-extension.js +2 -3
- package/dist/engine/types/index.d.ts +2 -2
- package/dist/engine/validate-projection-allowlist.js +12 -13
- package/dist/engine/where-rule-lint.js +8 -7
- package/dist/errors/reasons.d.ts +1 -0
- package/dist/errors/reasons.js +2 -0
- package/dist/files/bind-referenced-files.write.d.ts +16 -0
- package/dist/files/bind-referenced-files.write.js +109 -0
- package/dist/files/feature.d.ts +1 -0
- package/dist/files/feature.js +2 -0
- package/dist/files/file-routes.d.ts +2 -1
- package/dist/files/file-routes.js +10 -3
- package/dist/files/local-provider.js +2 -1
- package/dist/files/record-write-check.d.ts +1 -0
- package/dist/files/record-write-check.js +9 -9
- package/dist/i18n/index.d.ts +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/mail-registry.d.ts +2 -0
- package/dist/i18n/mail-registry.js +7 -0
- package/dist/jobs/job-runner.js +5 -5
- package/dist/pipeline/dispatch-query.js +2 -3
- package/dist/pipeline/dispatch-shared.js +45 -14
- package/dist/pipeline/event-dispatcher-delivery.js +2 -3
- package/dist/pipeline/index.d.ts +1 -0
- package/dist/pipeline/index.js +1 -0
- package/dist/pipeline/member-read-only-transaction.js +1 -1
- package/dist/pipeline/notify-scope.d.ts +13 -0
- package/dist/pipeline/notify-scope.js +32 -0
- package/dist/pipeline/system-hooks.js +2 -1
- package/dist/pipeline/system-identity-switch.js +2 -2
- package/dist/pipeline/write-origin.js +2 -2
- package/dist/search/meilisearch-adapter.js +3 -4
- package/dist/secrets/stored-envelope.js +7 -7
- package/dist/stack/push-entity-projection-tables.js +2 -3
- package/dist/stack/table-helpers.js +10 -26
- package/dist/stack/test-stack.js +2 -5
- package/dist/testing/multipart-helper.d.ts +0 -6
- package/dist/testing/multipart-helper.js +5 -5
- package/dist/testing/without-ambient-temporal.js +4 -4
- package/dist/ui-types/card-column-roles.d.ts +5 -0
- package/dist/ui-types/card-column-roles.js +22 -4
- package/dist/ui-types/index.d.ts +1 -1
- package/dist/ui-types/index.js +1 -1
- package/dist/utils/is-plain-object.d.ts +1 -2
- package/dist/utils/is-plain-object.js +1 -4
- package/package.json +4 -4
- package/src/changes.json +88 -0
|
@@ -48,7 +48,7 @@ function validateWriteOnlyField(featureName, entityName, fieldName, field) {
|
|
|
48
48
|
const where = `[Feature ${featureName}] Field "${fieldName}" on entity "${entityName}"`;
|
|
49
49
|
if (field.type === "embedded") {
|
|
50
50
|
for (const [subName, subField] of Object.entries(field.schema)) {
|
|
51
|
-
if (subField.writeOnly === true) {
|
|
51
|
+
if ("writeOnly" in subField && subField.writeOnly === true) {
|
|
52
52
|
// @cast-boundary schema-walk
|
|
53
53
|
throw new Error(`${where} declares writeOnly on embedded sub-field "${subName}" — writeOnly is only supported on top-level text fields.`);
|
|
54
54
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { resolveActionIcon } from "@cosmicdrift/kumiko-types/action-icon";
|
|
7
7
|
import { NO_WIDGET_FIELD_TYPES, optionsQueryFieldRefs, SELECT_OPTION_TONES, } from "@cosmicdrift/kumiko-types/fields";
|
|
8
8
|
import { NAV_ICON_KEYS } from "@cosmicdrift/kumiko-types/nav-icon";
|
|
9
|
+
import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
9
10
|
import { rowMetaFieldNames } from "../../db/table-builder.js";
|
|
10
11
|
import { REFERENCE_LOOKUP_SOURCES } from "../../ui-types/list-row-meta.js";
|
|
11
12
|
import { isEncryptedAtRest } from "../config-helpers.js";
|
|
@@ -275,7 +276,7 @@ function validateWizardLayout(featureName, screenId, screenType, layout, feature
|
|
|
275
276
|
// for an unregistered key instead of crashing — this check makes the same
|
|
276
277
|
// gap fail loudly at boot instead of silently at render.
|
|
277
278
|
function isRegisteredIcon(icon) {
|
|
278
|
-
return NAV_ICON_KEYS
|
|
279
|
+
return isOneOf(NAV_ICON_KEYS, icon);
|
|
279
280
|
}
|
|
280
281
|
export function validateActionHasIcon(featureName, screenId, screenType, context, action) {
|
|
281
282
|
const resolved = resolveActionIcon(action.id, action.icon);
|
|
@@ -409,6 +409,7 @@ function projectEntity(entityName, entity) {
|
|
|
409
409
|
...(typeof entity.defaultCurrency === "string" && {
|
|
410
410
|
defaultCurrency: entity.defaultCurrency,
|
|
411
411
|
}),
|
|
412
|
+
...(entity.lockedWhen !== undefined && { lockedWhen: entity.lockedWhen }),
|
|
412
413
|
};
|
|
413
414
|
}
|
|
414
415
|
// Nur valueType durch — die derive-fn ist Server-only und NICHT JSON-safe
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
2
|
+
import { CHANGELOG_TYPES, validateChangelog } from "./feature-changelog.js";
|
|
2
3
|
const BLOCK_RE = /<!--\s*kumiko-changes\s*\n([\s\S]*?)\n\s*-->/g;
|
|
3
|
-
const TYPE_VALUES = new Set(["breaking", "improvement", "fix"]);
|
|
4
4
|
const KEY_RE = /^(feature|type|title|detail|migration|codemod|manualAfterCodemod):(?:\s(.*))?$/;
|
|
5
5
|
function requiredField(fields, field, source) {
|
|
6
6
|
const value = fields.get(field)?.trim();
|
|
@@ -95,7 +95,7 @@ function parseManualAfterCodemod(fields, source) {
|
|
|
95
95
|
function buildChange(fields, prose, source) {
|
|
96
96
|
const feature = requiredField(fields, "feature", source);
|
|
97
97
|
const rawType = requiredField(fields, "type", source);
|
|
98
|
-
if (!
|
|
98
|
+
if (!isOneOf(CHANGELOG_TYPES, rawType)) {
|
|
99
99
|
throw new Error(`${source}: kumiko-changes type must be breaking, improvement, or fix`);
|
|
100
100
|
}
|
|
101
101
|
const { title, detail } = resolveTitleAndDetail(fields, prose, source);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ENTITY_CONVENTION_QUERY_BRAND } from "@cosmicdrift/kumiko-types/handlers";
|
|
2
|
+
import { propertyOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
2
3
|
import { runPipeline } from "./run-pipeline.js";
|
|
3
4
|
export function defineWriteHandler(def,
|
|
4
5
|
// R6: a phantom rest-param. When the inferred response `TData` carries a
|
|
@@ -88,14 +89,10 @@ export function defineQueryHandler(def,
|
|
|
88
89
|
// brand through into the stored registry entry.
|
|
89
90
|
export const PAGED_QUERY_HANDLER_BRAND = "__kumikoPagedQueryHandler";
|
|
90
91
|
export function isPagedQueryHandler(def) {
|
|
91
|
-
|
|
92
|
-
// otherwise-typed handler definition; the property may legitimately be
|
|
93
|
-
// absent, which is exactly the case this function distinguishes.
|
|
94
|
-
return def[PAGED_QUERY_HANDLER_BRAND] === true;
|
|
92
|
+
return propertyOf(def, PAGED_QUERY_HANDLER_BRAND) === true;
|
|
95
93
|
}
|
|
96
94
|
export function isEntityConventionQueryHandler(def) {
|
|
97
|
-
|
|
98
|
-
return def[ENTITY_CONVENTION_QUERY_BRAND] === true;
|
|
95
|
+
return propertyOf(def, ENTITY_CONVENTION_QUERY_BRAND) === true;
|
|
99
96
|
}
|
|
100
97
|
// A projectionList screen's query must resolve to { rows, nextCursor, total? }
|
|
101
98
|
// (CursorResult<T>) — the renderer used to read rowsQuery.data?.rows and
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
1
2
|
/** Computes a derived cell from its source values. Missing/non-numeric
|
|
2
3
|
* sources: "multiply" with any missing source → undefined; "sum"/"subtract"
|
|
3
4
|
* treat missing as 0 only when at least one source is present — if every
|
|
@@ -6,9 +7,13 @@
|
|
|
6
7
|
* to the target sub-field's declared precision afterward. */
|
|
7
8
|
export function computeDerivedCellValue(op, values) {
|
|
8
9
|
if (op === "multiply") {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
let product = 1;
|
|
11
|
+
for (const value of values) {
|
|
12
|
+
if (value === undefined)
|
|
13
|
+
return undefined;
|
|
14
|
+
product *= value;
|
|
15
|
+
}
|
|
16
|
+
return product;
|
|
12
17
|
}
|
|
13
18
|
if (values.every((value) => value === undefined))
|
|
14
19
|
return undefined;
|
|
@@ -58,10 +63,9 @@ function roundHalfAwayFromZero(value, decimals) {
|
|
|
58
63
|
* it's written back, so a fractional product lands on a value the target
|
|
59
64
|
* type can actually represent. */
|
|
60
65
|
export function withDerivedCells(row, derived, schema) {
|
|
61
|
-
if (
|
|
66
|
+
if (!isPlainObject(row))
|
|
62
67
|
return row;
|
|
63
|
-
const
|
|
64
|
-
const copy = { ...source };
|
|
68
|
+
const copy = { ...row };
|
|
65
69
|
for (const [cellName, def] of Object.entries(derived)) {
|
|
66
70
|
const sourceValues = def.from.map((sourceField) => {
|
|
67
71
|
const value = copy[sourceField];
|
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
// validation (feature-ui-extensions.ts's useExtension) already rejects an
|
|
4
4
|
// empty reason, but options stays `Record<string, unknown>`, so orchestrators
|
|
5
5
|
// re-narrow at read time instead of trusting the shape.
|
|
6
|
+
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
6
7
|
export function extensionUsageEscapeHatchReason(usage) {
|
|
7
8
|
const escapeHatch = usage.options?.["escapeHatch"];
|
|
8
|
-
if (
|
|
9
|
+
if (!isPlainObject(escapeHatch))
|
|
9
10
|
return undefined;
|
|
10
11
|
const { reason, grants } = escapeHatch;
|
|
11
12
|
if (Array.isArray(grants) && !grants.includes("unsafeRaw"))
|
package/dist/engine/factories.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isOneOf } from "@cosmicdrift/kumiko-types/type-guards";
|
|
1
2
|
// `personal: { of: "id" }` means the row itself is the subject, not a
|
|
2
3
|
// referenced user — resolves to `recordOwned` instead of `userOwned`.
|
|
3
4
|
const RECORD_OWNER_FIELD = "id";
|
|
@@ -75,15 +76,13 @@ function isNonEmptyString(value) {
|
|
|
75
76
|
// Fail-closed stance gate (kumiko-framework#2921) for the two text-shaped
|
|
76
77
|
// factories — runs before expandPersonalAnnotations so an untyped JS caller
|
|
77
78
|
// (no compiler to stop it) can't slip an unannotated text field past the
|
|
78
|
-
// type layer either.
|
|
79
|
-
//
|
|
80
|
-
//
|
|
79
|
+
// type layer either. The typed signature above already rejects a
|
|
80
|
+
// missing/malformed shape at compile time; this re-checks the same shape at
|
|
81
|
+
// runtime, hence the nullable parameter.
|
|
81
82
|
function assertTextFieldStance(factoryName, overrides) {
|
|
82
83
|
if (overrides === null || typeof overrides !== "object") {
|
|
83
84
|
throw missingTextFieldStanceError(factoryName);
|
|
84
85
|
}
|
|
85
|
-
// @cast-boundary runtime-guard — re-validated field by field below before
|
|
86
|
-
// any value is trusted.
|
|
87
86
|
const { personal, find, reason } = overrides;
|
|
88
87
|
if (personal === undefined || personal === null) {
|
|
89
88
|
throw missingTextFieldStanceError(factoryName);
|
|
@@ -106,7 +105,7 @@ function assertTextFieldStance(factoryName, overrides) {
|
|
|
106
105
|
throw missingTextFieldStanceError(factoryName);
|
|
107
106
|
}
|
|
108
107
|
const validFinds = TEXT_FIELD_STANCE_FIND_VALUES[factoryName];
|
|
109
|
-
if (typeof find !== "string" || !validFinds
|
|
108
|
+
if (typeof find !== "string" || !isOneOf(validFinds, find)) {
|
|
110
109
|
throw missingTextFieldStanceError(factoryName);
|
|
111
110
|
}
|
|
112
111
|
}
|
|
@@ -200,37 +200,45 @@ export function extractNotification(call, sourceFile) {
|
|
|
200
200
|
return fail("notification", sourceLocationFromNode(call, sourceFile), "second argument must be an inline definition object");
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
?.getInitializer()
|
|
207
|
-
?.asKind(SyntaxKind.ObjectLiteralExpression);
|
|
208
|
-
if (!triggerObj) {
|
|
209
|
-
return fail("notification", sourceLocationFromNode(call, sourceFile), "missing or non-object `trigger` property");
|
|
210
|
-
}
|
|
211
|
-
const onInit = triggerObj
|
|
212
|
-
.getProperty("on")
|
|
213
|
-
?.asKind(SyntaxKind.PropertyAssignment)
|
|
214
|
-
?.getInitializer();
|
|
215
|
-
const onName = onInit ? readNameOrRef(onInit) : undefined;
|
|
216
|
-
if (!onName) {
|
|
217
|
-
return fail("notification", sourceLocationFromNode(call, sourceFile), "trigger.on must be a string literal or inline { name } object");
|
|
203
|
+
const triggerProp = defObj.getProperty("trigger");
|
|
204
|
+
if (!triggerProp && (defObj.getProperty("recipient") || defObj.getProperty("data"))) {
|
|
205
|
+
return fail("notification", sourceLocationFromNode(call, sourceFile), "recipient and data require a `trigger`");
|
|
218
206
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
207
|
+
let onName;
|
|
208
|
+
let recipientFn;
|
|
209
|
+
let dataFn;
|
|
210
|
+
if (triggerProp) {
|
|
211
|
+
const triggerObj = triggerProp
|
|
212
|
+
.asKind(SyntaxKind.PropertyAssignment)
|
|
213
|
+
?.getInitializer()
|
|
214
|
+
?.asKind(SyntaxKind.ObjectLiteralExpression);
|
|
215
|
+
if (!triggerObj) {
|
|
216
|
+
return fail("notification", sourceLocationFromNode(call, sourceFile), "non-object `trigger` property");
|
|
217
|
+
}
|
|
218
|
+
const onInit = triggerObj
|
|
219
|
+
.getProperty("on")
|
|
220
|
+
?.asKind(SyntaxKind.PropertyAssignment)
|
|
221
|
+
?.getInitializer();
|
|
222
|
+
onName = onInit ? readNameOrRef(onInit) : undefined;
|
|
223
|
+
if (!onName) {
|
|
224
|
+
return fail("notification", sourceLocationFromNode(call, sourceFile), "trigger.on must be a string literal or inline { name } object");
|
|
225
|
+
}
|
|
226
|
+
const recipientInit = defObj
|
|
227
|
+
.getProperty("recipient")
|
|
228
|
+
?.asKind(SyntaxKind.PropertyAssignment)
|
|
229
|
+
?.getInitializer();
|
|
230
|
+
recipientFn = recipientInit ? findFunctionLiteral(recipientInit) : undefined;
|
|
231
|
+
if (!recipientFn) {
|
|
232
|
+
return fail("notification", sourceLocationFromNode(call, sourceFile), "recipient must be an inline arrow function or function expression");
|
|
233
|
+
}
|
|
234
|
+
const dataInit = defObj
|
|
235
|
+
.getProperty("data")
|
|
236
|
+
?.asKind(SyntaxKind.PropertyAssignment)
|
|
237
|
+
?.getInitializer();
|
|
238
|
+
dataFn = dataInit ? findFunctionLiteral(dataInit) : undefined;
|
|
239
|
+
if (!dataFn) {
|
|
240
|
+
return fail("notification", sourceLocationFromNode(call, sourceFile), "data must be an inline arrow function or function expression");
|
|
241
|
+
}
|
|
234
242
|
}
|
|
235
243
|
let templates;
|
|
236
244
|
const templatesObj = defObj
|
|
@@ -257,9 +265,11 @@ export function extractNotification(call, sourceFile) {
|
|
|
257
265
|
kind: "notification",
|
|
258
266
|
source: sourceLocationFromNode(call, sourceFile),
|
|
259
267
|
notificationName,
|
|
260
|
-
trigger: { on: onName },
|
|
261
|
-
|
|
262
|
-
|
|
268
|
+
...(onName !== undefined && { trigger: { on: onName } }),
|
|
269
|
+
...(recipientFn !== undefined && {
|
|
270
|
+
recipientBody: sourceLocationFromNode(recipientFn, sourceFile),
|
|
271
|
+
}),
|
|
272
|
+
...(dataFn !== undefined && { dataBody: sourceLocationFromNode(dataFn, sourceFile) }),
|
|
263
273
|
...(templates !== undefined && { templates }),
|
|
264
274
|
});
|
|
265
275
|
}
|
|
@@ -2,7 +2,7 @@ import type { CallExpression, SourceFile } from "ts-morph";
|
|
|
2
2
|
import type { ClaimKeyType } from "../../types/handlers.js";
|
|
3
3
|
import type { ParseError } from "../parse.js";
|
|
4
4
|
import type { ClaimKeyPattern, ConfigPattern, MetricPattern, ReferenceDataPattern, SecretNamespacePattern, SecretPattern, TranslationsPattern, UseExtensionPattern } from "../patterns.js";
|
|
5
|
-
import { type ExtractOutput } from "./shared.js";
|
|
5
|
+
import { type ExtractOutput, type ReadDataLiteralOptions } from "./shared.js";
|
|
6
6
|
export type NamedOptionsResult = {
|
|
7
7
|
readonly kind: "ok";
|
|
8
8
|
readonly name: string;
|
|
@@ -11,7 +11,7 @@ export type NamedOptionsResult = {
|
|
|
11
11
|
readonly kind: "error";
|
|
12
12
|
readonly error: ParseError;
|
|
13
13
|
};
|
|
14
|
-
export declare function readNamedOptions(call: CallExpression, sourceFile: SourceFile, methodName: string): NamedOptionsResult;
|
|
14
|
+
export declare function readNamedOptions(call: CallExpression, sourceFile: SourceFile, methodName: string, readOptions?: ReadDataLiteralOptions): NamedOptionsResult;
|
|
15
15
|
export declare function extractConfig(call: CallExpression, sourceFile: SourceFile): ExtractOutput<ConfigPattern>;
|
|
16
16
|
export declare function extractTranslations(call: CallExpression, sourceFile: SourceFile): ExtractOutput<TranslationsPattern>;
|
|
17
17
|
export declare function extractMetric(call: CallExpression, sourceFile: SourceFile): ExtractOutput<MetricPattern>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SyntaxKind } from "ts-morph";
|
|
2
2
|
import { sourceLocationFromNode } from "../source-location.js";
|
|
3
3
|
import { fail, isPlainObject, ok, readDataLiteralNode, readNameLiteral, readNameLiteralRef, readNameOrRef, } from "./shared.js";
|
|
4
|
-
export function readNamedOptions(call, sourceFile, methodName) {
|
|
4
|
+
export function readNamedOptions(call, sourceFile, methodName, readOptions = {}) {
|
|
5
5
|
const args = call.getArguments();
|
|
6
6
|
const first = args[0];
|
|
7
7
|
if (!first) {
|
|
@@ -17,7 +17,7 @@ export function readNamedOptions(call, sourceFile, methodName) {
|
|
|
17
17
|
if (!nameInit) {
|
|
18
18
|
return fail(methodName, sourceLocationFromNode(call, sourceFile), "object form requires a string-literal `name` property");
|
|
19
19
|
}
|
|
20
|
-
const data = readDataLiteralNode(obj);
|
|
20
|
+
const data = readDataLiteralNode(obj, readOptions);
|
|
21
21
|
if (!isPlainObject(data)) {
|
|
22
22
|
return fail(methodName, sourceLocationFromNode(call, sourceFile), "argument could not be read as a plain object");
|
|
23
23
|
}
|
|
@@ -32,7 +32,7 @@ export function readNamedOptions(call, sourceFile, methodName) {
|
|
|
32
32
|
if (!optionsArg) {
|
|
33
33
|
return fail(methodName, sourceLocationFromNode(call, sourceFile), "expected an options object as second argument");
|
|
34
34
|
}
|
|
35
|
-
const options = readDataLiteralNode(optionsArg);
|
|
35
|
+
const options = readDataLiteralNode(optionsArg, readOptions);
|
|
36
36
|
if (!isPlainObject(options)) {
|
|
37
37
|
return fail(methodName, sourceLocationFromNode(call, sourceFile), "options could not be read as a plain object");
|
|
38
38
|
}
|
|
@@ -88,7 +88,7 @@ export function extractMetric(call, sourceFile) {
|
|
|
88
88
|
});
|
|
89
89
|
}
|
|
90
90
|
export function extractSecret(call, sourceFile) {
|
|
91
|
-
const parsed = readNamedOptions(call, sourceFile, "secret");
|
|
91
|
+
const parsed = readNamedOptions(call, sourceFile, "secret", { functionValuesAsRaw: true });
|
|
92
92
|
if (parsed.kind === "error")
|
|
93
93
|
return parsed;
|
|
94
94
|
return ok({
|
|
@@ -69,11 +69,11 @@ export type AddJobArgs = {
|
|
|
69
69
|
};
|
|
70
70
|
export type AddNotificationArgs = {
|
|
71
71
|
readonly name: string;
|
|
72
|
-
readonly trigger
|
|
72
|
+
readonly trigger?: {
|
|
73
73
|
readonly on: string;
|
|
74
74
|
};
|
|
75
|
-
readonly recipientSource
|
|
76
|
-
readonly dataSource
|
|
75
|
+
readonly recipientSource?: string;
|
|
76
|
+
readonly dataSource?: string;
|
|
77
77
|
readonly templates?: Readonly<Record<string, string>>;
|
|
78
78
|
};
|
|
79
79
|
export type AddHttpRouteArgs = {
|
|
@@ -205,9 +205,9 @@ export function createFeaturePatcher(sourceFile) {
|
|
|
205
205
|
kind: "notification",
|
|
206
206
|
source: SYNTHETIC_LOC,
|
|
207
207
|
notificationName: name,
|
|
208
|
-
trigger,
|
|
209
|
-
recipientBody: rawLoc(recipientSource),
|
|
210
|
-
dataBody: rawLoc(dataSource),
|
|
208
|
+
...(trigger !== undefined && { trigger }),
|
|
209
|
+
...(recipientSource !== undefined && { recipientBody: rawLoc(recipientSource) }),
|
|
210
|
+
...(dataSource !== undefined && { dataBody: rawLoc(dataSource) }),
|
|
211
211
|
...(templateLocs !== undefined && { templates: templateLocs }),
|
|
212
212
|
});
|
|
213
213
|
},
|
|
@@ -366,11 +366,11 @@ export declare const PATTERN_SCHEMAS_BY_KIND: {
|
|
|
366
366
|
kind: z.ZodLiteral<"notification">;
|
|
367
367
|
source: z.ZodType<SourceLocation, unknown, z.core.$ZodTypeInternals<SourceLocation, unknown>>;
|
|
368
368
|
notificationName: z.ZodString;
|
|
369
|
-
trigger: z.ZodObject<{
|
|
369
|
+
trigger: z.ZodOptional<z.ZodObject<{
|
|
370
370
|
on: z.ZodString;
|
|
371
|
-
}, z.core.$strict
|
|
372
|
-
recipientBody: z.ZodType<SourceLocation, unknown, z.core.$ZodTypeInternals<SourceLocation, unknown
|
|
373
|
-
dataBody: z.ZodType<SourceLocation, unknown, z.core.$ZodTypeInternals<SourceLocation, unknown
|
|
371
|
+
}, z.core.$strict>>;
|
|
372
|
+
recipientBody: z.ZodOptional<z.ZodType<SourceLocation, unknown, z.core.$ZodTypeInternals<SourceLocation, unknown>>>;
|
|
373
|
+
dataBody: z.ZodOptional<z.ZodType<SourceLocation, unknown, z.core.$ZodTypeInternals<SourceLocation, unknown>>>;
|
|
374
374
|
templates: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<SourceLocation, unknown, z.core.$ZodTypeInternals<SourceLocation, unknown>>>>;
|
|
375
375
|
}, z.core.$strict>;
|
|
376
376
|
authClaims: z.ZodObject<{
|
|
@@ -883,11 +883,11 @@ export declare const patternSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
883
883
|
kind: z.ZodLiteral<"notification">;
|
|
884
884
|
source: z.ZodType<SourceLocation, unknown, z.core.$ZodTypeInternals<SourceLocation, unknown>>;
|
|
885
885
|
notificationName: z.ZodString;
|
|
886
|
-
trigger: z.ZodObject<{
|
|
886
|
+
trigger: z.ZodOptional<z.ZodObject<{
|
|
887
887
|
on: z.ZodString;
|
|
888
|
-
}, z.core.$strict
|
|
889
|
-
recipientBody: z.ZodType<SourceLocation, unknown, z.core.$ZodTypeInternals<SourceLocation, unknown
|
|
890
|
-
dataBody: z.ZodType<SourceLocation, unknown, z.core.$ZodTypeInternals<SourceLocation, unknown
|
|
888
|
+
}, z.core.$strict>>;
|
|
889
|
+
recipientBody: z.ZodOptional<z.ZodType<SourceLocation, unknown, z.core.$ZodTypeInternals<SourceLocation, unknown>>>;
|
|
890
|
+
dataBody: z.ZodOptional<z.ZodType<SourceLocation, unknown, z.core.$ZodTypeInternals<SourceLocation, unknown>>>;
|
|
891
891
|
templates: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<SourceLocation, unknown, z.core.$ZodTypeInternals<SourceLocation, unknown>>>>;
|
|
892
892
|
}, z.core.$strict>, z.ZodObject<{
|
|
893
893
|
kind: z.ZodLiteral<"authClaims">;
|
|
@@ -562,9 +562,9 @@ const notificationSchema = z
|
|
|
562
562
|
kind: z.literal("notification"),
|
|
563
563
|
source: sourceFieldSchema,
|
|
564
564
|
notificationName: z.string(),
|
|
565
|
-
trigger: z.object({ on: z.string() }).strict(),
|
|
566
|
-
recipientBody: sourceBodySchema,
|
|
567
|
-
dataBody: sourceBodySchema,
|
|
565
|
+
trigger: z.object({ on: z.string() }).strict().optional(),
|
|
566
|
+
recipientBody: sourceBodySchema.optional(),
|
|
567
|
+
dataBody: sourceBodySchema.optional(),
|
|
568
568
|
templates: z.record(z.string(), sourceBodySchema).optional(),
|
|
569
569
|
})
|
|
570
570
|
.strict();
|
|
@@ -190,11 +190,11 @@ export type NotificationPattern = {
|
|
|
190
190
|
readonly kind: "notification";
|
|
191
191
|
readonly source: SourceLocation;
|
|
192
192
|
readonly notificationName: string;
|
|
193
|
-
readonly trigger
|
|
193
|
+
readonly trigger?: {
|
|
194
194
|
readonly on: string;
|
|
195
195
|
};
|
|
196
|
-
readonly recipientBody
|
|
197
|
-
readonly dataBody
|
|
196
|
+
readonly recipientBody?: SourceLocation;
|
|
197
|
+
readonly dataBody?: SourceLocation;
|
|
198
198
|
readonly templates?: Readonly<Record<string, SourceLocation>>;
|
|
199
199
|
};
|
|
200
200
|
export type AuthClaimsPattern = {
|
|
@@ -497,9 +497,12 @@ function renderJob(p) {
|
|
|
497
497
|
function renderNotification(p) {
|
|
498
498
|
const lines = ["r.notification({"];
|
|
499
499
|
lines.push(` name: ${JSON.stringify(p.notificationName)},`);
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
500
|
+
if (p.trigger)
|
|
501
|
+
lines.push(` trigger: { on: ${JSON.stringify(p.trigger.on)} },`);
|
|
502
|
+
if (p.recipientBody)
|
|
503
|
+
lines.push(` recipient: ${p.recipientBody.raw},`);
|
|
504
|
+
if (p.dataBody)
|
|
505
|
+
lines.push(` data: ${p.dataBody.raw},`);
|
|
503
506
|
if (p.templates && Object.keys(p.templates).length > 0) {
|
|
504
507
|
lines.push(" templates: {");
|
|
505
508
|
for (const [k, loc] of Object.entries(p.templates)) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export
|
|
1
|
+
export declare const CHANGELOG_TYPES: readonly ["breaking", "improvement", "fix"];
|
|
2
|
+
export type ChangelogType = (typeof CHANGELOG_TYPES)[number];
|
|
2
3
|
export type ChangelogEntry = {
|
|
3
4
|
readonly version: string;
|
|
4
5
|
readonly type: ChangelogType;
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
//
|
|
6
6
|
// File I/O stays in the CLI (`bin/commands/upgrade.ts`) — this module is
|
|
7
7
|
// pure parse/validate so engine stays off the node:fs allowlist.
|
|
8
|
+
import { isOneOf, isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
9
|
+
export const CHANGELOG_TYPES = ["breaking", "improvement", "fix"];
|
|
8
10
|
/** Parse a changes.json body. Callers own file I/O. */
|
|
9
11
|
export function parseFeatureChangelog(raw, featureName) {
|
|
10
12
|
try {
|
|
@@ -24,16 +26,16 @@ export function parseFeatureChangelog(raw, featureName) {
|
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
function isChangelogEntry(value) {
|
|
27
|
-
if (
|
|
29
|
+
if (!isPlainObject(value))
|
|
28
30
|
return false;
|
|
29
|
-
|
|
30
|
-
if (typeof obj["version"] !== "string")
|
|
31
|
+
if (typeof value["version"] !== "string")
|
|
31
32
|
return false;
|
|
32
|
-
if (!
|
|
33
|
+
if (!isOneOf(CHANGELOG_TYPES, value["type"]))
|
|
33
34
|
return false;
|
|
34
|
-
if (typeof
|
|
35
|
+
if (typeof value["title"] !== "string")
|
|
35
36
|
return false;
|
|
36
|
-
if (
|
|
37
|
+
if (value["manualAfterCodemod"] !== undefined &&
|
|
38
|
+
typeof value["manualAfterCodemod"] !== "boolean") {
|
|
37
39
|
return false;
|
|
38
40
|
}
|
|
39
41
|
return true;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type * as z from "zod";
|
|
2
2
|
import { type ZodType } from "zod";
|
|
3
3
|
import type { FeatureBuilderState } from "./feature-builder-state.js";
|
|
4
|
-
import type { AuthClaimsFn, ClaimKeyHandle, ClaimKeyType, ConfigKeyDefinition, ConfigKeyHandle, ConfigKeyType, ConfigSeedDef, DeclarativeEventMigration, EventDef, EventPiiStance, EventUpcastFn, JobDefinition, JobHandlerFn, MetricOptions, NameOrRef, NotificationDataFn, NotificationRecipientFn, NotificationTemplateFn, QualifiedEventName, SecretKeyHandle, SecretNamespaceHandle, SecretNamespaceOptions, SecretOptions, TranslationsDef } from "./types/index.js";
|
|
4
|
+
import type { AuthClaimsFn, ClaimKeyHandle, ClaimKeyType, ConfigKeyDefinition, ConfigKeyHandle, ConfigKeyType, ConfigSeedDef, DeclarativeEventMigration, EventDef, EventPiiStance, EventUpcastFn, JobDefinition, JobHandlerFn, MetricOptions, NameOrRef, NotificationDataFn, NotificationLocalizedTemplate, NotificationRecipientFn, NotificationRecordMapping, NotificationTemplateBody, NotificationTemplateFn, NotificationTemplateMeta, QualifiedEventName, SecretKeyHandle, SecretNamespaceHandle, SecretNamespaceOptions, SecretOptions, TemplateVariables, TranslationsDef } from "./types/index.js";
|
|
5
5
|
export declare function buildConfigEventsJobsMethods<TName extends string>(state: FeatureBuilderState, name: TName): {
|
|
6
6
|
config: {
|
|
7
7
|
<T extends ConfigKeyType>(keyName: string, def: ConfigKeyDefinition<T>): ConfigKeyHandle<T>;
|
|
@@ -14,19 +14,29 @@ export declare function buildConfigEventsJobsMethods<TName extends string>(state
|
|
|
14
14
|
notification(notificationNameOrDefinition: string | ({
|
|
15
15
|
readonly name: string;
|
|
16
16
|
} & {
|
|
17
|
-
readonly trigger
|
|
17
|
+
readonly trigger?: {
|
|
18
18
|
readonly on: NameOrRef;
|
|
19
19
|
};
|
|
20
|
-
readonly recipient
|
|
21
|
-
readonly data
|
|
20
|
+
readonly recipient?: NotificationRecipientFn;
|
|
21
|
+
readonly data?: NotificationDataFn;
|
|
22
22
|
readonly templates?: Readonly<Record<string, NotificationTemplateFn>>;
|
|
23
|
+
readonly variables?: TemplateVariables;
|
|
24
|
+
readonly record?: NotificationRecordMapping;
|
|
25
|
+
readonly template?: Readonly<Record<string, NotificationTemplateBody>>;
|
|
26
|
+
readonly meta?: Readonly<Record<string, NotificationTemplateMeta>>;
|
|
27
|
+
readonly localizedTemplate?: () => NotificationLocalizedTemplate;
|
|
23
28
|
}), definition?: {
|
|
24
|
-
readonly trigger
|
|
29
|
+
readonly trigger?: {
|
|
25
30
|
readonly on: NameOrRef;
|
|
26
31
|
};
|
|
27
|
-
readonly recipient
|
|
28
|
-
readonly data
|
|
32
|
+
readonly recipient?: NotificationRecipientFn;
|
|
33
|
+
readonly data?: NotificationDataFn;
|
|
29
34
|
readonly templates?: Readonly<Record<string, NotificationTemplateFn>>;
|
|
35
|
+
readonly variables?: TemplateVariables;
|
|
36
|
+
readonly record?: NotificationRecordMapping;
|
|
37
|
+
readonly template?: Readonly<Record<string, NotificationTemplateBody>>;
|
|
38
|
+
readonly meta?: Readonly<Record<string, NotificationTemplateMeta>>;
|
|
39
|
+
readonly localizedTemplate?: () => NotificationLocalizedTemplate;
|
|
30
40
|
}): void;
|
|
31
41
|
translations(def: TranslationsDef): void;
|
|
32
42
|
defineEvent: <const TInner extends string, TPayload>(eventName: TInner, schema: ZodType<TPayload>, options: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { escapeHatchGrantsProblem, normalizeEventPiiSubject, } from "@cosmicdrift/kumiko-types/handlers";
|
|
2
|
+
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
2
3
|
import { ZodObject } from "zod";
|
|
3
4
|
import { isValidIanaTimeZone } from "../time/iana.js";
|
|
4
5
|
import { resolveName } from "./handler-helpers.js";
|
|
@@ -197,10 +198,25 @@ export function buildConfigEventsJobsMethods(state, name) {
|
|
|
197
198
|
: splitNamedDefinition(notificationNameOrDefinition);
|
|
198
199
|
state.notifications[notificationName] = {
|
|
199
200
|
name: notificationName,
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
201
|
+
...(resolvedDefinition.trigger !== undefined
|
|
202
|
+
? { trigger: { on: resolveName(resolvedDefinition.trigger.on) } }
|
|
203
|
+
: {}),
|
|
204
|
+
...(resolvedDefinition.recipient !== undefined
|
|
205
|
+
? { recipient: resolvedDefinition.recipient }
|
|
206
|
+
: {}),
|
|
207
|
+
...(resolvedDefinition.data !== undefined ? { data: resolvedDefinition.data } : {}),
|
|
203
208
|
templates: resolvedDefinition.templates,
|
|
209
|
+
...(resolvedDefinition.variables !== undefined
|
|
210
|
+
? { variables: resolvedDefinition.variables }
|
|
211
|
+
: {}),
|
|
212
|
+
...(resolvedDefinition.record !== undefined ? { record: resolvedDefinition.record } : {}),
|
|
213
|
+
...(resolvedDefinition.template !== undefined
|
|
214
|
+
? { template: resolvedDefinition.template }
|
|
215
|
+
: {}),
|
|
216
|
+
...(resolvedDefinition.meta !== undefined ? { meta: resolvedDefinition.meta } : {}),
|
|
217
|
+
...(resolvedDefinition.localizedTemplate !== undefined
|
|
218
|
+
? { localizedTemplate: resolvedDefinition.localizedTemplate }
|
|
219
|
+
: {}),
|
|
204
220
|
};
|
|
205
221
|
},
|
|
206
222
|
translations(def) {
|
|
@@ -366,10 +382,9 @@ function compileEventMigration(spec) {
|
|
|
366
382
|
renameTargets.set(to, from);
|
|
367
383
|
}
|
|
368
384
|
return (payload) => {
|
|
369
|
-
if (
|
|
385
|
+
if (!isPlainObject(payload)) {
|
|
370
386
|
throw new Error("Declarative event migration expects an object payload");
|
|
371
387
|
}
|
|
372
|
-
// @cast-boundary parse — payload is guarded as a plain object above
|
|
373
388
|
const next = { ...payload };
|
|
374
389
|
for (const [from, to] of Object.entries(spec.rename ?? {})) {
|
|
375
390
|
if (from in next) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { escapeHatchGrantsProblem } from "@cosmicdrift/kumiko-types/handlers";
|
|
2
|
+
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
2
3
|
import { WEBSOCKET_MAX_CONNECTIONS_PER_USER_LIMIT, WEBSOCKET_MAX_PAYLOAD_BYTES, WEBSOCKET_ROUTE_PATH_PREFIX, } from "@cosmicdrift/kumiko-types/websocket-route";
|
|
3
4
|
import { bindHookEscapeHatchGrant } from "../pipeline/system-identity-switch.js";
|
|
4
5
|
import { LifecycleHookTypes } from "./constants.js";
|
|
@@ -209,9 +210,7 @@ export function buildUiExtensionsMethods(state, name) {
|
|
|
209
210
|
// for every extension regardless of its typed hook shape.
|
|
210
211
|
const escapeHatch = optionsBag?.["escapeHatch"];
|
|
211
212
|
if (escapeHatch !== undefined) {
|
|
212
|
-
const reason =
|
|
213
|
-
? escapeHatch.reason
|
|
214
|
-
: undefined;
|
|
213
|
+
const reason = isPlainObject(escapeHatch) ? escapeHatch["reason"] : undefined;
|
|
215
214
|
if (typeof reason !== "string" || reason.trim().length === 0) {
|
|
216
215
|
throw new Error(`[Feature ${name}] r.useExtension("${extensionName}", "${resolvedEntityName}", ...) declares an invalid { escapeHatch } — ` +
|
|
217
216
|
`must be { reason: "<non-empty string>" } explaining why this usage needs unfiltered db access.`);
|
package/dist/engine/index.d.ts
CHANGED
|
@@ -77,10 +77,11 @@ export { describeWorkflowStepError } from "./steps/describe-workflow-step-error.
|
|
|
77
77
|
export { unwrapWorkflowStepError, WorkflowStepError } from "./steps/workflow-step-error.js";
|
|
78
78
|
export { WORKFLOW_SYSTEM_EVENT_DEFS } from "./steps/workflow-system-events.js";
|
|
79
79
|
export { ANONYMOUS_ROLE, ANONYMOUS_USER_ID, createAnonymousUser, createSystemUser, SYSTEM_ROLE, SYSTEM_USER_ID, } from "./system-user.js";
|
|
80
|
+
export { assertNotificationVariables, templateVariable, templateVariablesToZod, } from "./template-variables.js";
|
|
80
81
|
export { type EffectiveFeaturesResolver, findTierResolverUsage, isTierResolverPlugin, TENANT_TIER_RESOLVER_EXT, type TierResolverPlugin, type TrialGate, } from "./tier-resolver-extension.js";
|
|
81
82
|
export { findOverDeepTransferChain, resolveTransferAdjacency as resolveEntityTransferAdjacency, type TransferAdjacency, type TransferEdge, type TransferEdgeLink, } from "./transfer-adjacency.js";
|
|
82
83
|
export { isSystemTenant, isUuid, parseTenantId, SYSTEM_TENANT_ID } from "./types/identifiers.js";
|
|
83
|
-
export type { AccessRule, ActionFormScreenDefinition, ActiveMembership, ActiveMembershipRejection, ActiveMembershipResult, AgentExposure, AgentHandlerHints, AgentRisk, AppContext, AppendEventArgs, AppendEventFn, AuthClaimsContext, AuthClaimsFn, AuthClaimsHookDef, BelongsToRelation, BigIntFieldDef, BooleanFieldDef, CamelToKebab, ChatSendFailureCode, ClaimKeyDefinition, ClaimKeyHandle, ClaimKeyJsType, ClaimKeyType, ConcurrencyMode, ConfigAccessor, ConfigAccessorFactory, ConfigBacking, ConfigCascade, ConfigCascadeLevel, ConfigDefinition, ConfigEditScreenDefinition, ConfigKeyAccess, ConfigKeyDefinition, ConfigKeyHandle, ConfigKeyType, ConfigMask, ConfigResolver, ConfigScope, ConfigSecretsReader, ConfigSeedDef, ConfigStoredRow, ConfigStoredRowWithSource, ConfigValidateContext, ConfigValidateFn, ConfigValue, ConfigValueSource, ConfigValueWithSource, ContentCollectionDefinition, CreateSeedOptions, CreateTenantSeedOptions, CreateUserSeedOptions, CustomScreenDefinition, CustomScreenRoute, DashboardChartPanel, DashboardCustomPanel, DashboardDateParam, DashboardFeedPanel, DashboardFilterDefinition, DashboardI18nText, DashboardListPanel, DashboardMoneyParam, DashboardPanelDefinition, DashboardPanelVisibility, DashboardProgressListPanel, DashboardScreenDefinition, DashboardScreenPanel, DashboardStatGroupPanel, DashboardStatPanel, DashboardText, DashboardTextParam, DashboardValueFormat, DateFieldDef, DecimalFieldDef, DeleteContext, DeliveryErrorCode, DeliveryFailureCode, DeliverySkipReason, DeriveContext, DerivedFieldDef, DerivedFieldsMap, DerivedValueType, EditExtensionSection, EditFieldPrefill, EditFieldSpec, EditFieldsSection, EditLayout, EditRelatedListSection, EditSectionSpec, EmbeddedListEditSpec, EntityDefinition, EntityEditAction, EntityEditActionPlacement, EntityEditScreenDefinition, EntityId, EntityListExpandableRow, EntityListScreenDefinition, EntityRef, EntityRelations, EscapeHatchAuditSink, EscapeHatchDeclaration, EscapeHatchKind, EscapeHatchReporter, EscapeHatchTarget, EscapeHatchUseEvent, EventDef, ExtensionOptionsArgs, ExtensionOptionsFor, FeatureDefinition, FeatureRegistrar, FieldAccess, FieldCondition, FieldDefinition, FieldFormatRegistry, FieldIconKey, FieldRenderer, FileFieldDef, FilesFieldDef, Findability, FormatSpec, FormWidth, HandlerContext, HasManyRelation, HookMap, ImageFieldDef, ImagesFieldDef, JobBackoff, JobBackoffStrategy, JobContext, JobDefinition, JobHandlerFn, JobTrigger, JobTriggerEvent, JsonbFieldDef, KumikoEntityTypeMap, KumikoEventTypeMap, KumikoExtensionOptionsMap, KumikoHandlerPayloadMap, KumikoHandlerResultMap, LifecycleHookType, ListColumnSpec, ListFacetSpec, ListPaginationMode, ListSortDir, ListSortSpec, LongTextFindability, ManyToManyRelation, MemberReader, MetricNavigate, MetricSpec, MspErrorMode, MspErrorPolicy, MultiSelectFieldDef, MultiStreamApplyFn, MultiStreamProjectionDefinition, NameOrRef, NavDefinition, NavIconKey, NotificationDataFn, NotificationDefinition, NotificationRecipientFn, NotificationTemplateFn, NotifyDelivery, NotifyDeliveryStatus, NotifyFactory, NotifyFn, NotifyJobDispatcher, NotifyOptions, NotifyPriority, NotifyResult, NumberFieldDef, OnDeleteStrategy, OpenToAllAccessRule, OpenToAllDeclaration, OpenToAllPersonalData, ParentRefDef, PersonalAnnotations, PersonalAnnotationsLongText, PersonalAnnotationsNoFind, PersonalSubject, PlatformComponent, PluralForms, PostDeleteHookFn, PostSaveHookFn, PreDeleteHookFn, PreQueryHookFn, PreSaveHookFn, ProjectionDefinition, ProjectionDetailScreenDefinition, ProjectionListScreenDefinition, ProjectionTable, QualifiedEventName, QueryEvent, QueryHandlerDef, QueryHandlerFn, RateLimitPer, RecordHeaderSpec, RecordHeaderSubtitlePart, ReferenceDataDef, Registry, RelationDefinition, ResolvedPiiFlags, RetentionDef, RoleAccessPersonalData, RoleAccessRule, RowAction, RowActionNavigate, RowActionNavigateBase, RowActionWriteHandler, RowFieldExtractor, SaveContext, ScreenDefinition, ScreenFilter, ScreenFilterOp, ScreenNavSugar, ScreenSlots, SecretKeyDefinition, SecretKeyHandle, SecretMintConfirmStep, SecretMintScreenDefinition, SecretNamespaceDefinition, SecretNamespaceHandle, SecretNamespaceOptions, SecretReveal, SecretRevealField, SecretsEditScreenDefinition, SecretsEditSection, SelectFieldDef, SessionUser, SessionUserOrigin, StreamHandlerDef, StreamHandlerFn, Subscribe, TargetRef, TenantId, TenantWriteTarget, TextFieldDef, ToolbarAction, TranslationEntry, TranslationKeys, TranslationsDef, TranslationValue, TreeAction, TreeActionDef, TreeActionsHandle, TreeChildrenSubscribe, TreeNode, TreeNodeState, UnitKey, UnsafeAppendEventFn, ValidationError, ValidationHookFn, WorkspaceDefinition, WriteEvent, WriteHandlerDef, WriteHandlerFn, WriteResult, } from "./types/index.js";
|
|
84
|
+
export type { AccessRule, ActionFormScreenDefinition, ActiveMembership, ActiveMembershipRejection, ActiveMembershipResult, AgentExposure, AgentHandlerHints, AgentRisk, AppContext, AppendEventArgs, AppendEventFn, AuthClaimsContext, AuthClaimsFn, AuthClaimsHookDef, BelongsToRelation, BigIntFieldDef, BooleanFieldDef, CamelToKebab, ChatSendFailureCode, ClaimKeyDefinition, ClaimKeyHandle, ClaimKeyJsType, ClaimKeyType, ConcurrencyMode, ConfigAccessor, ConfigAccessorFactory, ConfigBacking, ConfigCascade, ConfigCascadeLevel, ConfigDefinition, ConfigEditScreenDefinition, ConfigKeyAccess, ConfigKeyDefinition, ConfigKeyHandle, ConfigKeyType, ConfigMask, ConfigResolver, ConfigScope, ConfigSecretsReader, ConfigSeedDef, ConfigStoredRow, ConfigStoredRowWithSource, ConfigValidateContext, ConfigValidateFn, ConfigValue, ConfigValueSource, ConfigValueWithSource, ContentCollectionDefinition, CreateSeedOptions, CreateTenantSeedOptions, CreateUserSeedOptions, CustomScreenDefinition, CustomScreenRoute, DashboardChartPanel, DashboardCustomPanel, DashboardDateParam, DashboardFeedPanel, DashboardFilterDefinition, DashboardI18nText, DashboardListPanel, DashboardMoneyParam, DashboardPanelDefinition, DashboardPanelVisibility, DashboardProgressListPanel, DashboardScreenDefinition, DashboardScreenPanel, DashboardStatGroupPanel, DashboardStatPanel, DashboardText, DashboardTextParam, DashboardValueFormat, DateFieldDef, DecimalFieldDef, DeleteContext, DeliveryErrorCode, DeliveryFailureCode, DeliverySkipReason, DeriveContext, DerivedFieldDef, DerivedFieldsMap, DerivedValueType, EditExtensionSection, EditFieldPrefill, EditFieldSpec, EditFieldsSection, EditLayout, EditRelatedListSection, EditSectionSpec, EmbeddedListEditSpec, EntityDefinition, EntityEditAction, EntityEditActionPlacement, EntityEditScreenDefinition, EntityId, EntityListExpandableRow, EntityListScreenDefinition, EntityRef, EntityRelations, EscapeHatchAuditSink, EscapeHatchDeclaration, EscapeHatchKind, EscapeHatchReporter, EscapeHatchTarget, EscapeHatchUseEvent, EventDef, ExtensionOptionsArgs, ExtensionOptionsFor, FeatureDefinition, FeatureRegistrar, FieldAccess, FieldCondition, FieldDefinition, FieldFormatRegistry, FieldIconKey, FieldRenderer, FileFieldDef, FilesFieldDef, Findability, FormatSpec, FormWidth, HandlerContext, HasManyRelation, HookMap, ImageFieldDef, ImagesFieldDef, JobBackoff, JobBackoffStrategy, JobContext, JobDefinition, JobHandlerFn, JobTrigger, JobTriggerEvent, JsonbFieldDef, KumikoEntityTypeMap, KumikoEventTypeMap, KumikoExtensionOptionsMap, KumikoHandlerPayloadMap, KumikoHandlerResultMap, LifecycleHookType, ListColumnSpec, ListFacetSpec, ListPaginationMode, ListSortDir, ListSortSpec, LongTextFindability, ManyToManyRelation, MemberReader, MetricNavigate, MetricSpec, MspErrorMode, MspErrorPolicy, MultiSelectFieldDef, MultiStreamApplyFn, MultiStreamProjectionDefinition, NameOrRef, NavDefinition, NavIconKey, NotificationDataFn, NotificationDefinition, NotificationLocalizedTemplate, NotificationRecipientFn, NotificationRecordMapping, NotificationTemplateBody, NotificationTemplateFn, NotificationTemplateMeta, NotifyDeferred, NotifyDelivery, NotifyDeliveryStatus, NotifyDispatched, NotifyFactory, NotifyFn, NotifyJobDispatcher, NotifyOptions, NotifyPriority, NotifyResult, NumberFieldDef, OnDeleteStrategy, OpenToAllAccessRule, OpenToAllDeclaration, OpenToAllPersonalData, ParentRefDef, PersonalAnnotations, PersonalAnnotationsLongText, PersonalAnnotationsNoFind, PersonalSubject, PlatformComponent, PluralForms, PostDeleteHookFn, PostSaveHookFn, PreDeleteHookFn, PreQueryHookFn, PreSaveHookFn, ProjectionDefinition, ProjectionDetailScreenDefinition, ProjectionListScreenDefinition, ProjectionTable, QualifiedEventName, QueryEvent, QueryHandlerDef, QueryHandlerFn, RateLimitPer, RecordHeaderSpec, RecordHeaderSubtitlePart, ReferenceDataDef, Registry, RelationDefinition, ResolvedPiiFlags, RetentionDef, RoleAccessPersonalData, RoleAccessRule, RowAction, RowActionNavigate, RowActionNavigateBase, RowActionWriteHandler, RowFieldExtractor, SaveContext, ScreenDefinition, ScreenFilter, ScreenFilterOp, ScreenNavSugar, ScreenSlots, SecretKeyDefinition, SecretKeyHandle, SecretMintConfirmStep, SecretMintScreenDefinition, SecretNamespaceDefinition, SecretNamespaceHandle, SecretNamespaceOptions, SecretReveal, SecretRevealField, SecretsEditScreenDefinition, SecretsEditSection, SelectFieldDef, SessionUser, SessionUserOrigin, StreamHandlerDef, StreamHandlerFn, Subscribe, TargetRef, TemplateListVariableDef, TemplateScalarVariableDef, TemplateVariableDef, TemplateVariables, TenantId, TenantWriteTarget, TextFieldDef, ToolbarAction, TranslationEntry, TranslationKeys, TranslationsDef, TranslationValue, TreeAction, TreeActionDef, TreeActionsHandle, TreeChildrenSubscribe, TreeNode, TreeNodeState, UnitKey, UnsafeAppendEventFn, ValidationError, ValidationHookFn, WorkspaceDefinition, WriteEvent, WriteHandlerDef, WriteHandlerFn, WriteResult, } from "./types/index.js";
|
|
84
85
|
export { DEFAULT_CURRENCIES, DEFAULT_LOCALES, DELIVERY_FAILURE_CODES, DELIVERY_SKIP_REASONS, HookPhases, HTTP_ERROR_CODE_PATTERN, isAgentVisibleScreen, isDeliveryErrorCode, isOpenToAllGranted, resolveAgentExposure, } from "./types/index.js";
|
|
85
86
|
export type { AwaitedEventType, PipelineBuildCtx, PipelineCtx, PipelineDef, StepBuilder, StepDef, StepFailureStrategy, StepInstance, StepKind, StepNamespace, StepResolver, } from "./types/step.js";
|
|
86
87
|
export { runValidation } from "./validation.js";
|
package/dist/engine/index.js
CHANGED
|
@@ -70,6 +70,7 @@ export { describeWorkflowStepError } from "./steps/describe-workflow-step-error.
|
|
|
70
70
|
export { unwrapWorkflowStepError, WorkflowStepError } from "./steps/workflow-step-error.js";
|
|
71
71
|
export { WORKFLOW_SYSTEM_EVENT_DEFS } from "./steps/workflow-system-events.js";
|
|
72
72
|
export { ANONYMOUS_ROLE, ANONYMOUS_USER_ID, createAnonymousUser, createSystemUser, SYSTEM_ROLE, SYSTEM_USER_ID, } from "./system-user.js";
|
|
73
|
+
export { assertNotificationVariables, templateVariable, templateVariablesToZod, } from "./template-variables.js";
|
|
73
74
|
export { findTierResolverUsage, isTierResolverPlugin, TENANT_TIER_RESOLVER_EXT, } from "./tier-resolver-extension.js";
|
|
74
75
|
export { findOverDeepTransferChain, resolveTransferAdjacency as resolveEntityTransferAdjacency, } from "./transfer-adjacency.js";
|
|
75
76
|
export { isSystemTenant, isUuid, parseTenantId, SYSTEM_TENANT_ID } from "./types/identifiers.js";
|