@cosmicdrift/kumiko-framework 0.336.0 → 0.337.1
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 +43 -19
- package/dist/api/auth-routes.d.ts +1 -0
- package/dist/api/auth-routes.js +20 -0
- package/dist/api/redis-sse-broker.d.ts +1 -0
- package/dist/api/redis-sse-broker.js +4 -5
- package/dist/api/routes.js +1 -1
- package/dist/api/server.js +3 -3
- package/dist/api/sse-route.js +14 -1
- package/dist/bun-db/query.js +6 -4
- package/dist/crypto/event-pii.js +3 -3
- package/dist/crypto/kek-source.js +1 -0
- package/dist/db/blind-index-cleanup.js +1 -1
- package/dist/db/event-store-executor-read.js +15 -4
- package/dist/db/queries/event-consumer.d.ts +2 -2
- package/dist/db/queries/event-consumer.js +5 -4
- package/dist/db/queries/event-store.js +6 -6
- package/dist/db/queries/projection-rebuild.js +4 -4
- package/dist/db/queries/seed-context.js +6 -6
- package/dist/derivatives/derivatives-context.js +5 -2
- package/dist/engine/boot-validator/access-declarations.js +2 -1
- package/dist/engine/boot-validator/projection-list-screens.d.ts +1 -1
- package/dist/engine/boot-validator/projection-list-screens.js +13 -0
- package/dist/engine/boot-validator/screens.js +12 -0
- package/dist/engine/build-app-schema.js +2 -1
- package/dist/engine/build-config-feature-schema.js +4 -0
- package/dist/engine/define-feature.js +1 -0
- package/dist/engine/define-handler.js +3 -5
- package/dist/engine/feature-ast/extractors/index.d.ts +1 -1
- package/dist/engine/feature-ast/extractors/index.js +1 -1
- package/dist/engine/feature-ast/extractors/jobs-routes.js +6 -2
- package/dist/engine/feature-ast/extractors/round3.d.ts +2 -1
- package/dist/engine/feature-ast/extractors/round3.js +11 -0
- package/dist/engine/feature-ast/extractors/shared.js +1 -3
- package/dist/engine/feature-ast/index.d.ts +1 -1
- package/dist/engine/feature-ast/parse.js +3 -1
- package/dist/engine/feature-ast/patch.d.ts +3 -0
- package/dist/engine/feature-ast/patch.js +8 -11
- package/dist/engine/feature-ast/patcher.d.ts +6 -1
- package/dist/engine/feature-ast/patcher.js +3 -0
- package/dist/engine/feature-ast/pattern-change-schema.d.ts +590 -1
- package/dist/engine/feature-ast/pattern-change-schema.js +17 -2
- package/dist/engine/feature-ast/patterns.d.ts +8 -2
- package/dist/engine/feature-ast/patterns.js +1 -0
- package/dist/engine/feature-ast/render.js +9 -0
- package/dist/engine/feature-builder-state.d.ts +2 -1
- package/dist/engine/feature-builder-state.js +1 -0
- package/dist/engine/feature-config-events-jobs.d.ts +4 -1
- package/dist/engine/feature-config-events-jobs.js +20 -0
- package/dist/engine/feature-ui-extensions.js +15 -21
- package/dist/engine/index.d.ts +1 -1
- package/dist/engine/pattern-library/library.js +2 -1
- package/dist/engine/pattern-library/static-schemas.d.ts +1 -0
- package/dist/engine/pattern-library/static-schemas.js +47 -4
- package/dist/engine/registry-facade.js +7 -0
- package/dist/engine/registry-ingest.js +7 -0
- package/dist/engine/registry-state.d.ts +2 -1
- package/dist/engine/registry-state.js +1 -0
- package/dist/engine/registry-validate.d.ts +1 -1
- package/dist/engine/registry-validate.js +39 -17
- package/dist/engine/registry.js +2 -2
- package/dist/engine/types/index.d.ts +2 -2
- package/dist/engine/types/index.js +1 -1
- package/dist/engine/types/screen.d.ts +1 -1
- package/dist/engine/types/screen.js +1 -1
- package/dist/errors/classes.d.ts +5 -0
- package/dist/errors/classes.js +15 -0
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/i18n/required-surface-keys.js +3 -5
- package/dist/migrations/pending-rebuilds.d.ts +2 -0
- package/dist/migrations/pending-rebuilds.js +7 -3
- package/dist/pipeline/dispatch-batch.js +2 -2
- package/dist/pipeline/dispatch-query.js +3 -5
- package/dist/pipeline/dispatch-stream.js +2 -4
- package/dist/pipeline/dispatch-write.js +2 -4
- package/dist/pipeline/dispatcher.js +1 -1
- package/dist/pipeline/event-dispatcher-delivery.d.ts +0 -1
- package/dist/pipeline/event-dispatcher-delivery.js +1 -8
- package/dist/pipeline/event-dispatcher.js +16 -25
- package/dist/pipeline/handler-access-error.d.ts +3 -0
- package/dist/pipeline/handler-access-error.js +17 -0
- package/dist/pipeline/irreversible-operation-gate.js +9 -3
- package/dist/pipeline/member-read-only-transaction.js +8 -3
- package/dist/pipeline/system-hooks.js +7 -1
- package/dist/pipeline/system-identity-switch.js +1 -1
- package/dist/search/meilisearch-adapter.js +0 -2
- package/dist/stack/push-entity-projection-tables.js +5 -3
- package/dist/stack/redis.d.ts +1 -0
- package/dist/stack/redis.js +11 -2
- package/dist/stack/table-helpers.d.ts +3 -1
- package/dist/stack/table-helpers.js +9 -7
- package/dist/stack/test-stack.js +1 -7
- package/dist/testing/handler-context.js +3 -6
- package/dist/ui-types/index.d.ts +1 -1
- package/dist/ui-types/index.js +1 -1
- package/dist/upgrade-cli.js +29 -2
- package/package.json +4 -4
- package/src/changes.json +98 -0
- package/src/scripts/codemod/collect-source-files.ts +48 -0
- package/src/scripts/codemod/migrate-cross-tenant.ts +3 -23
- package/src/scripts/codemod/migrate-db-raw.ts +6 -23
- package/src/scripts/codemod/migrate-open-to-all.ts +4 -24
- package/src/scripts/codemod/pii-personal-migration.ts +11 -21
- package/src/scripts/codemod/unprocessable-error-details-reason.ts +47 -3
|
@@ -413,6 +413,14 @@ const secretSchema = z
|
|
|
413
413
|
options: passthroughSchema(),
|
|
414
414
|
})
|
|
415
415
|
.strict();
|
|
416
|
+
const secretNamespaceSchema = z
|
|
417
|
+
.object({
|
|
418
|
+
kind: z.literal("secretNamespace"),
|
|
419
|
+
source: sourceFieldSchema,
|
|
420
|
+
shortName: z.string(),
|
|
421
|
+
options: passthroughSchema(),
|
|
422
|
+
})
|
|
423
|
+
.strict();
|
|
416
424
|
const claimKeySchema = z
|
|
417
425
|
.object({
|
|
418
426
|
kind: z.literal("claimKey"),
|
|
@@ -707,6 +715,7 @@ export const PATTERN_SCHEMAS_BY_KIND = {
|
|
|
707
715
|
uiHints: uiHintsSchema,
|
|
708
716
|
metric: metricSchema,
|
|
709
717
|
secret: secretSchema,
|
|
718
|
+
secretNamespace: secretNamespaceSchema,
|
|
710
719
|
claimKey: claimKeySchema,
|
|
711
720
|
referenceData: referenceDataSchema,
|
|
712
721
|
readsConfig: readsConfigSchema,
|
|
@@ -733,7 +742,7 @@ export const PATTERN_SCHEMAS_BY_KIND = {
|
|
|
733
742
|
"ai.classify": aiClassifySchema,
|
|
734
743
|
unknown: unknownPatternSchema,
|
|
735
744
|
};
|
|
736
|
-
const patternSchema = z.discriminatedUnion("kind", [
|
|
745
|
+
export const patternSchema = z.discriminatedUnion("kind", [
|
|
737
746
|
entitySchema,
|
|
738
747
|
relationSchema,
|
|
739
748
|
navSchema,
|
|
@@ -748,6 +757,7 @@ const patternSchema = z.discriminatedUnion("kind", [
|
|
|
748
757
|
uiHintsSchema,
|
|
749
758
|
metricSchema,
|
|
750
759
|
secretSchema,
|
|
760
|
+
secretNamespaceSchema,
|
|
751
761
|
claimKeySchema,
|
|
752
762
|
referenceDataSchema,
|
|
753
763
|
readsConfigSchema,
|
|
@@ -810,6 +820,9 @@ const patternIdMetricSchema = z
|
|
|
810
820
|
const patternIdSecretSchema = z
|
|
811
821
|
.object({ kind: z.literal("secret"), shortName: z.string() })
|
|
812
822
|
.strict();
|
|
823
|
+
const patternIdSecretNamespaceSchema = z
|
|
824
|
+
.object({ kind: z.literal("secretNamespace"), shortName: z.string() })
|
|
825
|
+
.strict();
|
|
813
826
|
const patternIdClaimKeySchema = z
|
|
814
827
|
.object({ kind: z.literal("claimKey"), shortName: z.string() })
|
|
815
828
|
.strict();
|
|
@@ -870,6 +883,7 @@ export const PATTERN_ID_SCHEMAS_BY_KIND = {
|
|
|
870
883
|
hook: patternIdHookSchema,
|
|
871
884
|
metric: patternIdMetricSchema,
|
|
872
885
|
secret: patternIdSecretSchema,
|
|
886
|
+
secretNamespace: patternIdSecretNamespaceSchema,
|
|
873
887
|
claimKey: patternIdClaimKeySchema,
|
|
874
888
|
referenceData: patternIdReferenceDataSchema,
|
|
875
889
|
useExtension: patternIdUseExtensionSchema,
|
|
@@ -895,7 +909,7 @@ export const PATTERN_ID_SCHEMAS_BY_KIND = {
|
|
|
895
909
|
authClaims: patternIdAuthClaimsSchema,
|
|
896
910
|
treeActions: patternIdTreeActionsSchema,
|
|
897
911
|
};
|
|
898
|
-
const patternIdSchema = z.discriminatedUnion("kind", [
|
|
912
|
+
export const patternIdSchema = z.discriminatedUnion("kind", [
|
|
899
913
|
patternIdEntitySchema,
|
|
900
914
|
patternIdRelationSchema,
|
|
901
915
|
patternIdNavSchema,
|
|
@@ -907,6 +921,7 @@ const patternIdSchema = z.discriminatedUnion("kind", [
|
|
|
907
921
|
patternIdHookSchema,
|
|
908
922
|
patternIdMetricSchema,
|
|
909
923
|
patternIdSecretSchema,
|
|
924
|
+
patternIdSecretNamespaceSchema,
|
|
910
925
|
patternIdClaimKeySchema,
|
|
911
926
|
patternIdReferenceDataSchema,
|
|
912
927
|
patternIdUseExtensionSchema,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LifecycleHookType } from "../constants.js";
|
|
2
2
|
import type { ConfigKeyDefinition, ConfigKeyType, JobDefinition, ReferenceDataDef, RunIn, TranslationKeys } from "../types/config.js";
|
|
3
|
-
import type { MetricOptions, SecretOptions } from "../types/feature.js";
|
|
3
|
+
import type { MetricOptions, SecretNamespaceOptions, SecretOptions } from "../types/feature.js";
|
|
4
4
|
import type { EntityDefinition } from "../types/fields.js";
|
|
5
5
|
import type { AccessRule, AgentHandlerHints, ClaimKeyType, EscapeHatchDeclaration, RateLimitDeclaration } from "../types/handlers.js";
|
|
6
6
|
import type { HookPhase } from "../types/hooks.js";
|
|
@@ -86,6 +86,12 @@ export type SecretPattern = {
|
|
|
86
86
|
readonly shortName: string;
|
|
87
87
|
readonly options: SecretOptions;
|
|
88
88
|
};
|
|
89
|
+
export type SecretNamespacePattern = {
|
|
90
|
+
readonly kind: "secretNamespace";
|
|
91
|
+
readonly source: SourceLocation;
|
|
92
|
+
readonly shortName: string;
|
|
93
|
+
readonly options: SecretNamespaceOptions;
|
|
94
|
+
};
|
|
89
95
|
export type ClaimKeyPattern = {
|
|
90
96
|
readonly kind: "claimKey";
|
|
91
97
|
readonly source: SourceLocation;
|
|
@@ -295,7 +301,7 @@ export type UnknownPattern = {
|
|
|
295
301
|
readonly source: SourceLocation;
|
|
296
302
|
readonly methodName: string;
|
|
297
303
|
};
|
|
298
|
-
export type FeaturePattern = EntityPattern | RelationPattern | NavPattern | WorkspacePattern | ConfigPattern | TranslationsPattern | RequiresPattern | OptionalRequiresPattern | SystemScopePattern | ToggleablePattern | DescribePattern | UiHintsPattern | MetricPattern | SecretPattern | ClaimKeyPattern | ReferenceDataPattern | ReadsConfigPattern | UseExtensionPattern | UsesApiPattern | ExposesApiPattern | TreeActionsPattern | ScreenPattern | WriteHandlerPattern | QueryHandlerPattern | StreamHandlerPattern | HookPattern | JobPattern | NotificationPattern | AuthClaimsPattern | HttpRoutePattern | ProjectionPattern | MultiStreamProjectionPattern | DefineEventPattern | ExtendsRegistrarPattern | EnvSchemaPattern | AiGeneratePattern | AiExtractPattern | AiClassifyPattern | UnknownPattern;
|
|
304
|
+
export type FeaturePattern = EntityPattern | RelationPattern | NavPattern | WorkspacePattern | ConfigPattern | TranslationsPattern | RequiresPattern | OptionalRequiresPattern | SystemScopePattern | ToggleablePattern | DescribePattern | UiHintsPattern | MetricPattern | SecretPattern | SecretNamespacePattern | ClaimKeyPattern | ReferenceDataPattern | ReadsConfigPattern | UseExtensionPattern | UsesApiPattern | ExposesApiPattern | TreeActionsPattern | ScreenPattern | WriteHandlerPattern | QueryHandlerPattern | StreamHandlerPattern | HookPattern | JobPattern | NotificationPattern | AuthClaimsPattern | HttpRoutePattern | ProjectionPattern | MultiStreamProjectionPattern | DefineEventPattern | ExtendsRegistrarPattern | EnvSchemaPattern | AiGeneratePattern | AiExtractPattern | AiClassifyPattern | UnknownPattern;
|
|
299
305
|
export type FeaturePatternKind = FeaturePattern["kind"];
|
|
300
306
|
export type Editability = "static" | "mixed" | "opaque";
|
|
301
307
|
export declare function getEditability(pattern: FeaturePattern): Editability;
|
|
@@ -61,6 +61,8 @@ export function renderPattern(pattern) {
|
|
|
61
61
|
return renderMetric(pattern);
|
|
62
62
|
case "secret":
|
|
63
63
|
return renderSecret(pattern);
|
|
64
|
+
case "secretNamespace":
|
|
65
|
+
return renderSecretNamespace(pattern);
|
|
64
66
|
case "claimKey":
|
|
65
67
|
return renderClaimKey(pattern);
|
|
66
68
|
case "referenceData":
|
|
@@ -245,6 +247,13 @@ function renderSecret(p) {
|
|
|
245
247
|
const merged = { name: p.shortName, ...p.options };
|
|
246
248
|
return `r.secret(${renderValue(merged)});`;
|
|
247
249
|
}
|
|
250
|
+
function renderSecretNamespace(p) {
|
|
251
|
+
if (isRawRefSentinel(p.options)) {
|
|
252
|
+
return `r.secretNamespace(${JSON.stringify(p.shortName)}, ${p.options.__raw});`;
|
|
253
|
+
}
|
|
254
|
+
const merged = { name: p.shortName, ...p.options };
|
|
255
|
+
return `r.secretNamespace(${renderValue(merged)});`;
|
|
256
|
+
}
|
|
248
257
|
function renderClaimKey(p) {
|
|
249
258
|
return `r.claimKey(${renderValue({ name: p.shortName, type: p.claimType })});`;
|
|
250
259
|
}
|
|
@@ -2,7 +2,7 @@ import type { WebSocketRouteDefinition } from "@cosmicdrift/kumiko-types/websock
|
|
|
2
2
|
import type * as z from "zod";
|
|
3
3
|
import type { ZodType } from "zod";
|
|
4
4
|
import type { HttpRouteDefinition } from "./types/http-route.js";
|
|
5
|
-
import type { AuthClaimsFn, BootCheckFn, ClaimKeyDefinition, ConfigKeyDefinition, ConfigSeedDef, EntityDefinition, EntityProjectionExtension, EventMigrationDef, ExtensionSelectorDef, FeatureMetricDef, JobDefinition, LifecycleHookFn, MultiStreamProjectionDefinition, NotificationDefinition, OwnedFn, PhasedHook, PostDeleteHookFn, PostQueryHookFn, PostSaveHookFn, PreDeleteHookFn, ProjectionDefinition, QueryHandlerDef, ReferenceDataDef, RegistrarExtensionDef, RegistrarExtensionRegistration, RelationDefinition, SearchPayloadContributorFn, SecretKeyDefinition, StoreTableEntry, StreamHandlerDef, TranslationKeys, TreeActionDef, UiHints, ValidationHookFn, WriteHandlerDef } from "./types/index.js";
|
|
5
|
+
import type { AuthClaimsFn, BootCheckFn, ClaimKeyDefinition, ConfigKeyDefinition, ConfigSeedDef, EntityDefinition, EntityProjectionExtension, EventMigrationDef, ExtensionSelectorDef, FeatureMetricDef, JobDefinition, LifecycleHookFn, MultiStreamProjectionDefinition, NotificationDefinition, OwnedFn, PhasedHook, PostDeleteHookFn, PostQueryHookFn, PostSaveHookFn, PreDeleteHookFn, ProjectionDefinition, QueryHandlerDef, ReferenceDataDef, RegistrarExtensionDef, RegistrarExtensionRegistration, RelationDefinition, SearchPayloadContributorFn, SecretKeyDefinition, SecretNamespaceDefinition, StoreTableEntry, StreamHandlerDef, TranslationKeys, TreeActionDef, UiHints, ValidationHookFn, WriteHandlerDef } from "./types/index.js";
|
|
6
6
|
import type { ContentCollectionDefinition, NavDefinition } from "./types/nav.js";
|
|
7
7
|
import type { ScreenDefinition } from "./types/screen.js";
|
|
8
8
|
import type { WorkspaceDefinition } from "./types/workspace.js";
|
|
@@ -46,6 +46,7 @@ export type FeatureBuilderState = {
|
|
|
46
46
|
handlerEntityMappings: Record<string, string>;
|
|
47
47
|
metrics: Record<string, FeatureMetricDef>;
|
|
48
48
|
secretKeys: Record<string, SecretKeyDefinition>;
|
|
49
|
+
secretNamespaces: Record<string, SecretNamespaceDefinition>;
|
|
49
50
|
projections: Record<string, ProjectionDefinition>;
|
|
50
51
|
multiStreamProjections: Record<string, MultiStreamProjectionDefinition>;
|
|
51
52
|
entityProjectionExtensions: Record<string, EntityProjectionExtension[]>;
|
|
@@ -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, 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, NotificationRecipientFn, NotificationTemplateFn, QualifiedEventName, SecretKeyHandle, SecretNamespaceHandle, SecretNamespaceOptions, SecretOptions, 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>;
|
|
@@ -48,6 +48,9 @@ export declare function buildConfigEventsJobsMethods<TName extends string>(state
|
|
|
48
48
|
secret(shortNameOrDefinition: string | ({
|
|
49
49
|
readonly name: string;
|
|
50
50
|
} & SecretOptions), options?: SecretOptions): SecretKeyHandle;
|
|
51
|
+
secretNamespace(shortNameOrDefinition: string | ({
|
|
52
|
+
readonly name: string;
|
|
53
|
+
} & SecretNamespaceOptions), options?: SecretNamespaceOptions): SecretNamespaceHandle;
|
|
51
54
|
claimKey<T extends ClaimKeyType>(shortNameOrDefinition: string | {
|
|
52
55
|
readonly name: string;
|
|
53
56
|
readonly type: T;
|
|
@@ -235,6 +235,10 @@ export function buildConfigEventsJobsMethods(state, name) {
|
|
|
235
235
|
throw new Error(`[Feature ${name}] Secret "${shortName}" already registered. ` +
|
|
236
236
|
`Secret key names must be unique per feature.`);
|
|
237
237
|
}
|
|
238
|
+
if (secretOptions.writeRoles !== undefined && secretOptions.writeRoles.length === 0) {
|
|
239
|
+
throw new Error(`[Feature ${name}] Secret "${shortName}" declares an empty writeRoles list, ` +
|
|
240
|
+
`which nobody could ever satisfy. Omit writeRoles to fall back to the secrets handler access.`);
|
|
241
|
+
}
|
|
238
242
|
// Qualified name follows the framework's "<feature>:<type>:<name>"
|
|
239
243
|
// QN convention — same pattern config / jobs / events use. toKebab
|
|
240
244
|
// handles the common input shapes ("stripe.apiKey" → "stripe-api-key")
|
|
@@ -248,6 +252,22 @@ export function buildConfigEventsJobsMethods(state, name) {
|
|
|
248
252
|
};
|
|
249
253
|
return { name: qualifiedName };
|
|
250
254
|
},
|
|
255
|
+
secretNamespace(shortNameOrDefinition, options) {
|
|
256
|
+
const [shortName, namespaceOptions] = typeof shortNameOrDefinition === "string"
|
|
257
|
+
? [shortNameOrDefinition, options]
|
|
258
|
+
: splitNamedDefinition(shortNameOrDefinition);
|
|
259
|
+
if (state.secretNamespaces[shortName]) {
|
|
260
|
+
throw new Error(`[Feature ${name}] Secret namespace "${shortName}" already registered. ` +
|
|
261
|
+
`Secret namespace names must be unique per feature.`);
|
|
262
|
+
}
|
|
263
|
+
if (namespaceOptions.writeRoles !== undefined && namespaceOptions.writeRoles.length === 0) {
|
|
264
|
+
throw new Error(`[Feature ${name}] Secret namespace "${shortName}" declares an empty writeRoles list, ` +
|
|
265
|
+
`which nobody could ever satisfy. Omit writeRoles to fall back to the secrets handler access.`);
|
|
266
|
+
}
|
|
267
|
+
const qualifiedPrefix = `${toKebab(name)}:${toKebab(shortName)}.`;
|
|
268
|
+
state.secretNamespaces[shortName] = { shortName, qualifiedPrefix, ...namespaceOptions };
|
|
269
|
+
return { prefix: qualifiedPrefix, keyFor: (suffix) => `${qualifiedPrefix}${suffix}` };
|
|
270
|
+
},
|
|
251
271
|
claimKey(shortNameOrDefinition, options) {
|
|
252
272
|
const shortName = typeof shortNameOrDefinition === "string"
|
|
253
273
|
? shortNameOrDefinition
|
|
@@ -99,7 +99,10 @@ export function buildUiExtensionsMethods(state, name) {
|
|
|
99
99
|
`Nav ids must be unique per feature — remove the standalone ` +
|
|
100
100
|
`r.nav("${navDefinition.id}", ...) call or the screen's inline nav.`);
|
|
101
101
|
}
|
|
102
|
-
|
|
102
|
+
// Explicit `undefined` values (e.g. `icon: cond ? "x" : undefined`) would trip
|
|
103
|
+
// buildAppSchema's JSON-safety check, so strip them for every nav path.
|
|
104
|
+
// @cast-boundary engine-bridge — filtering undefined keeps the NavDefinition shape.
|
|
105
|
+
state.navs[navDefinition.id] = Object.fromEntries(Object.entries(navDefinition).filter(([, value]) => value !== undefined));
|
|
103
106
|
}
|
|
104
107
|
return {
|
|
105
108
|
hook(type, target, fn, options) {
|
|
@@ -337,15 +340,12 @@ export function buildUiExtensionsMethods(state, name) {
|
|
|
337
340
|
// Sugar for the common "one nav entry pointing at this screen"
|
|
338
341
|
// case — synthesizes id/screen from the screen's own id. Beyond
|
|
339
342
|
// label/icon/parent/order, declare a standalone r.nav() instead.
|
|
340
|
-
// Optional fields stay absent rather than explicitly undefined —
|
|
341
|
-
// buildAppSchema's JSON-safety check flags undefined values. Same
|
|
342
|
-
// pattern as r.contentCollection() below.
|
|
343
343
|
registerNav({
|
|
344
344
|
id: definition.id,
|
|
345
345
|
label: definition.nav.label,
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
346
|
+
icon: definition.nav.icon,
|
|
347
|
+
parent: definition.nav.parent,
|
|
348
|
+
order: definition.nav.order,
|
|
349
349
|
screen: `${name}:screen:${definition.id}`,
|
|
350
350
|
});
|
|
351
351
|
}
|
|
@@ -359,26 +359,20 @@ export function buildUiExtensionsMethods(state, name) {
|
|
|
359
359
|
`Collection ids must be unique per feature.`);
|
|
360
360
|
}
|
|
361
361
|
// registerNav owns the kebab + collision checks, including collisions
|
|
362
|
-
// with a plain r.nav() of the same id.
|
|
363
|
-
// rather than explicitly undefined — buildAppSchema's JSON-safety check
|
|
364
|
-
// flags undefined values.
|
|
362
|
+
// with a plain r.nav() of the same id.
|
|
365
363
|
registerNav({
|
|
366
364
|
id: definition.id,
|
|
367
365
|
label: definition.nav.label,
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
366
|
+
icon: definition.nav.icon,
|
|
367
|
+
parent: definition.nav.parent,
|
|
368
|
+
order: definition.nav.order,
|
|
371
369
|
// Nav visibility follows the collection's access unless the caller
|
|
372
370
|
// overrode it — a node the handler would refuse has no business in
|
|
373
371
|
// the sidebar.
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
...(definition.nav.createAction !== undefined && {
|
|
379
|
-
createAction: definition.nav.createAction,
|
|
380
|
-
}),
|
|
381
|
-
...(definition.nav.actions !== undefined && { actions: definition.nav.actions }),
|
|
372
|
+
access: definition.nav.access ?? definition.access,
|
|
373
|
+
workspaces: definition.nav.workspaces,
|
|
374
|
+
createAction: definition.nav.createAction,
|
|
375
|
+
actions: definition.nav.actions,
|
|
382
376
|
// The tree children come from a runtime provider keyed on this QN —
|
|
383
377
|
// a collection without it would render as an empty leaf.
|
|
384
378
|
provider: true,
|
package/dist/engine/index.d.ts
CHANGED
|
@@ -73,7 +73,7 @@ export { describeWorkflowStepError } from "./steps/describe-workflow-step-error.
|
|
|
73
73
|
export { ANONYMOUS_ROLE, ANONYMOUS_USER_ID, createAnonymousUser, createSystemUser, SYSTEM_ROLE, SYSTEM_USER_ID, } from "./system-user.js";
|
|
74
74
|
export { type EffectiveFeaturesResolver, findTierResolverUsage, isTierResolverPlugin, TENANT_TIER_RESOLVER_EXT, type TierResolverPlugin, type TrialGate, } from "./tier-resolver-extension.js";
|
|
75
75
|
export { isSystemTenant, isUuid, parseTenantId, SYSTEM_TENANT_ID } from "./types/identifiers.js";
|
|
76
|
-
export type { AccessRule, ActionFormScreenDefinition, ActiveMembership, ActiveMembershipRejection, ActiveMembershipResult, AgentExposure, AgentHandlerHints, AgentRisk, AppContext, AppendEventArgs, AppendEventFn, AuthClaimsContext, AuthClaimsFn, AuthClaimsHookDef, BelongsToRelation, BigIntFieldDef, BooleanFieldDef, CamelToKebab, ClaimKeyDefinition, ClaimKeyHandle, ClaimKeyJsType, ClaimKeyType, ConcurrencyMode, ConfigAccessor, ConfigAccessorFactory, ConfigBacking, ConfigCascade, ConfigCascadeLevel, ConfigDefinition, ConfigEditScreenDefinition, ConfigKeyAccess, ConfigKeyDefinition, ConfigKeyHandle, ConfigKeyType, ConfigMask, ConfigResolver, ConfigScope, ConfigSecretsReader, ConfigSeedDef, ConfigStoredRow, ConfigStoredRowWithSource, ConfigValue, ConfigValueSource, ConfigValueWithSource, ContentCollectionDefinition, CreateSeedOptions, CreateTenantSeedOptions, CreateUserSeedOptions, CustomScreenDefinition, CustomScreenRoute, DashboardChartPanel, DashboardCustomPanel, DashboardFeedPanel, DashboardFilterDefinition, DashboardListPanel, DashboardPanelDefinition, DashboardPanelVisibility, DashboardProgressListPanel, DashboardScreenDefinition, DashboardScreenPanel, DashboardStatGroupPanel, DashboardStatPanel, DateFieldDef, DecimalFieldDef, DeleteContext, DeriveContext, DerivedFieldDef, DerivedFieldsMap, DerivedValueType, EditExtensionSection, EditFieldSpec, EditFieldsSection, EditLayout, EditRelatedListSection, EditSectionSpec, EntityDefinition, 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, NotifyFactory, NotifyFn, NotifyOptions, NotifyPriority, 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, SecretKeyHandle, SecretMintConfirmStep, SecretMintScreenDefinition, SecretReveal, SecretRevealField, SecretsEditScreenDefinition, SecretsEditSection, SelectFieldDef, SessionUser, SessionUserOrigin, StreamHandlerDef, StreamHandlerFn, Subscribe, TargetRef, TenantId, 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";
|
|
76
|
+
export type { AccessRule, ActionFormScreenDefinition, ActiveMembership, ActiveMembershipRejection, ActiveMembershipResult, AgentExposure, AgentHandlerHints, AgentRisk, AppContext, AppendEventArgs, AppendEventFn, AuthClaimsContext, AuthClaimsFn, AuthClaimsHookDef, BelongsToRelation, BigIntFieldDef, BooleanFieldDef, CamelToKebab, ClaimKeyDefinition, ClaimKeyHandle, ClaimKeyJsType, ClaimKeyType, ConcurrencyMode, ConfigAccessor, ConfigAccessorFactory, ConfigBacking, ConfigCascade, ConfigCascadeLevel, ConfigDefinition, ConfigEditScreenDefinition, ConfigKeyAccess, ConfigKeyDefinition, ConfigKeyHandle, ConfigKeyType, ConfigMask, ConfigResolver, ConfigScope, ConfigSecretsReader, ConfigSeedDef, ConfigStoredRow, ConfigStoredRowWithSource, ConfigValue, ConfigValueSource, ConfigValueWithSource, ContentCollectionDefinition, CreateSeedOptions, CreateTenantSeedOptions, CreateUserSeedOptions, CustomScreenDefinition, CustomScreenRoute, DashboardChartPanel, DashboardCustomPanel, DashboardFeedPanel, DashboardFilterDefinition, DashboardListPanel, DashboardPanelDefinition, DashboardPanelVisibility, DashboardProgressListPanel, DashboardScreenDefinition, DashboardScreenPanel, DashboardStatGroupPanel, DashboardStatPanel, DateFieldDef, DecimalFieldDef, DeleteContext, DeriveContext, DerivedFieldDef, DerivedFieldsMap, DerivedValueType, EditExtensionSection, EditFieldSpec, EditFieldsSection, EditLayout, EditRelatedListSection, EditSectionSpec, EntityDefinition, 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, NotifyFactory, NotifyFn, NotifyOptions, NotifyPriority, 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, 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";
|
|
77
77
|
export { DEFAULT_CURRENCIES, DEFAULT_LOCALES, HookPhases, isAgentVisibleScreen, isOpenToAllGranted, resolveAgentExposure, } from "./types/index.js";
|
|
78
78
|
export type { AwaitedEventType, PipelineBuildCtx, PipelineCtx, PipelineDef, StepBuilder, StepDef, StepFailureStrategy, StepInstance, StepKind, StepNamespace, StepResolver, } from "./types/step.js";
|
|
79
79
|
export { runValidation } from "./validation.js";
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// the Designer/LLM relies on.
|
|
15
15
|
import { aiClassifySchema, aiExtractSchema, aiGenerateSchema, authClaimsSchema, defineEventSchema, hookSchema, httpRouteSchema, jobSchema, multiStreamProjectionSchema, notificationSchema, projectionSchema, queryHandlerSchema, screenSchema, streamHandlerSchema, writeHandlerSchema, } from "./mixed-schemas.js";
|
|
16
16
|
import { envSchemaSchema, exposesApiSchema, extendsRegistrarSchema, treeActionsSchema, unknownSchema, usesApiSchema, } from "./opaque-schemas.js";
|
|
17
|
-
import { claimKeySchema, configSchema, describeSchema, entitySchema, metricSchema, navSchema, optionalRequiresSchema, readsConfigSchema, referenceDataSchema, relationSchema, requiresSchema, secretSchema, systemScopeSchema, toggleableSchema, translationsSchema, uiHintsSchema, useExtensionSchema, workspaceSchema, } from "./static-schemas.js";
|
|
17
|
+
import { claimKeySchema, configSchema, describeSchema, entitySchema, metricSchema, navSchema, optionalRequiresSchema, readsConfigSchema, referenceDataSchema, relationSchema, requiresSchema, secretNamespaceSchema, secretSchema, systemScopeSchema, toggleableSchema, translationsSchema, uiHintsSchema, useExtensionSchema, workspaceSchema, } from "./static-schemas.js";
|
|
18
18
|
export const PATTERN_LIBRARY = {
|
|
19
19
|
requires: requiresSchema,
|
|
20
20
|
optionalRequires: optionalRequiresSchema,
|
|
@@ -31,6 +31,7 @@ export const PATTERN_LIBRARY = {
|
|
|
31
31
|
translations: translationsSchema,
|
|
32
32
|
metric: metricSchema,
|
|
33
33
|
secret: secretSchema,
|
|
34
|
+
secretNamespace: secretNamespaceSchema,
|
|
34
35
|
claimKey: claimKeySchema,
|
|
35
36
|
referenceData: referenceDataSchema,
|
|
36
37
|
useExtension: useExtensionSchema,
|
|
@@ -14,6 +14,7 @@ export declare const configSchema: PatternFormSchema;
|
|
|
14
14
|
export declare const translationsSchema: PatternFormSchema;
|
|
15
15
|
export declare const metricSchema: PatternFormSchema;
|
|
16
16
|
export declare const secretSchema: PatternFormSchema;
|
|
17
|
+
export declare const secretNamespaceSchema: PatternFormSchema;
|
|
17
18
|
export declare const claimKeySchema: PatternFormSchema;
|
|
18
19
|
export declare const referenceDataSchema: PatternFormSchema;
|
|
19
20
|
export declare const useExtensionSchema: PatternFormSchema;
|
|
@@ -351,10 +351,53 @@ export const secretSchema = {
|
|
|
351
351
|
path: "options.scope",
|
|
352
352
|
label: { en: "Scope", de: "Geltungsbereich" },
|
|
353
353
|
input: "select",
|
|
354
|
-
options: [
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
354
|
+
options: [{ value: "tenant", label: { en: "Tenant" } }],
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
path: "options.writeRoles",
|
|
358
|
+
label: { en: "Write roles", de: "Schreibrollen" },
|
|
359
|
+
hint: {
|
|
360
|
+
en: "Roles allowed to set or delete. Leave empty to rely on the secrets handler access alone.",
|
|
361
|
+
de: "Rollen, die setzen oder löschen dürfen. Leer lassen, dann entscheidet allein der Handler-Zugriff.",
|
|
362
|
+
},
|
|
363
|
+
input: "string-list",
|
|
364
|
+
},
|
|
365
|
+
],
|
|
366
|
+
};
|
|
367
|
+
export const secretNamespaceSchema = {
|
|
368
|
+
kind: "secretNamespace",
|
|
369
|
+
label: { en: "Secret namespace", de: "Secret-Namespace" },
|
|
370
|
+
summary: { en: "Family of tenant-scoped secrets with a runtime-chosen name." },
|
|
371
|
+
category: "meta",
|
|
372
|
+
editability: "static",
|
|
373
|
+
fields: [
|
|
374
|
+
{
|
|
375
|
+
path: "shortName",
|
|
376
|
+
label: { en: "Short name", de: "Kurzname" },
|
|
377
|
+
input: "text",
|
|
378
|
+
required: true,
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
path: "options.label",
|
|
382
|
+
label: { en: "UI label (i18n)", de: "UI-Label (i18n)" },
|
|
383
|
+
hint: { en: "{ en: 'Webhook token', de: 'Webhook-Token' }" },
|
|
384
|
+
input: "json-readonly",
|
|
385
|
+
required: true,
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
path: "options.scope",
|
|
389
|
+
label: { en: "Scope", de: "Geltungsbereich" },
|
|
390
|
+
input: "select",
|
|
391
|
+
options: [{ value: "tenant", label: { en: "Tenant" } }],
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
path: "options.writeRoles",
|
|
395
|
+
label: { en: "Write roles", de: "Schreibrollen" },
|
|
396
|
+
hint: {
|
|
397
|
+
en: "Roles allowed to set or delete. Leave empty to rely on the secrets handler access alone.",
|
|
398
|
+
de: "Rollen, die setzen oder löschen dürfen. Leer lassen, dann entscheidet allein der Handler-Zugriff.",
|
|
399
|
+
},
|
|
400
|
+
input: "string-list",
|
|
358
401
|
},
|
|
359
402
|
],
|
|
360
403
|
};
|
|
@@ -125,6 +125,13 @@ export function buildRegistryFacade(state) {
|
|
|
125
125
|
getSecretKey(qualifiedName) {
|
|
126
126
|
return state.secretKeyMap.get(qualifiedName);
|
|
127
127
|
},
|
|
128
|
+
findSecretNamespace(key) {
|
|
129
|
+
for (const [prefix, def] of state.secretNamespaceMap) {
|
|
130
|
+
if (key.startsWith(prefix))
|
|
131
|
+
return def;
|
|
132
|
+
}
|
|
133
|
+
return undefined;
|
|
134
|
+
},
|
|
128
135
|
getConfigKey(qualifiedKey) {
|
|
129
136
|
return state.configKeyMap.get(qualifiedKey);
|
|
130
137
|
},
|
|
@@ -221,6 +221,13 @@ export function populateMetricsAndSecrets(state, feature) {
|
|
|
221
221
|
}
|
|
222
222
|
state.secretKeyMap.set(def.qualifiedName, def);
|
|
223
223
|
}
|
|
224
|
+
for (const def of Object.values(feature.secretNamespaces ?? {})) {
|
|
225
|
+
if (state.secretNamespaceMap.has(def.qualifiedPrefix)) {
|
|
226
|
+
throw new Error(`[Kumiko Secrets] Secret namespace "${def.qualifiedPrefix}" registered multiple times. ` +
|
|
227
|
+
"Namespace prefixes must be globally unique across features.");
|
|
228
|
+
}
|
|
229
|
+
state.secretNamespaceMap.set(def.qualifiedPrefix, def);
|
|
230
|
+
}
|
|
224
231
|
}
|
|
225
232
|
// Explicit + multi-stream projections (source-entity indexed) + store tables +
|
|
226
233
|
// unmanaged tables (both cross-feature-uniqueness-by-physical-name guarded).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type QnType, qualifyEntityName } from "./qualified-name.js";
|
|
2
|
-
import type { AuthClaimsHookDef, ClaimKeyDefinition, ConfigKeyDefinition, ConfigSeedDef, EntityDefinition, EntityProjectionExtension, EventDef, EventUpcastFn, ExtensionSelectorPanel, FeatureDefinition, FeatureMetricDef, HookPhase, JobDefinition, MultiStreamProjectionDefinition, NavDefinition, NotificationDefinition, OwnedFn, PhasedHook, PostDeleteHookFn, PostQueryHookFn, PostSaveHookFn, PreDeleteHookFn, PreQueryHookFn, PreSaveHookFn, ProjectionDefinition, QueryHandlerDef, ReferenceDataDef, RegistrarExtensionDef, RegistrarExtensionRegistration, RelationDefinition, ScreenDefinition, SearchPayloadContributorFn, SecretKeyDefinition, StoreTableDef, StreamHandlerDef, TranslationValue, TreeActionDef, WorkspaceDefinition, WriteHandlerDef } from "./types/index.js";
|
|
2
|
+
import type { AuthClaimsHookDef, ClaimKeyDefinition, ConfigKeyDefinition, ConfigSeedDef, EntityDefinition, EntityProjectionExtension, EventDef, EventUpcastFn, ExtensionSelectorPanel, FeatureDefinition, FeatureMetricDef, HookPhase, JobDefinition, MultiStreamProjectionDefinition, NavDefinition, NotificationDefinition, OwnedFn, PhasedHook, PostDeleteHookFn, PostQueryHookFn, PostSaveHookFn, PreDeleteHookFn, PreQueryHookFn, PreSaveHookFn, ProjectionDefinition, QueryHandlerDef, ReferenceDataDef, RegistrarExtensionDef, RegistrarExtensionRegistration, RelationDefinition, ScreenDefinition, SearchPayloadContributorFn, SecretKeyDefinition, SecretNamespaceDefinition, StoreTableDef, StreamHandlerDef, TranslationValue, TreeActionDef, WorkspaceDefinition, WriteHandlerDef } from "./types/index.js";
|
|
3
3
|
export type IncomingRelation = {
|
|
4
4
|
sourceEntity: string;
|
|
5
5
|
relationName: string;
|
|
@@ -54,6 +54,7 @@ export type RegistryState = {
|
|
|
54
54
|
readonly featureName: string;
|
|
55
55
|
}>;
|
|
56
56
|
secretKeyMap: Map<string, SecretKeyDefinition>;
|
|
57
|
+
secretNamespaceMap: Map<string, SecretNamespaceDefinition>;
|
|
57
58
|
projectionMap: Map<string, ProjectionDefinition>;
|
|
58
59
|
projectionsBySource: Map<string, ProjectionDefinition[]>;
|
|
59
60
|
multiStreamProjectionMap: Map<string, MultiStreamProjectionDefinition>;
|
|
@@ -122,6 +122,7 @@ export function createInitialState() {
|
|
|
122
122
|
mergedTranslations: {},
|
|
123
123
|
metricMap: new Map(),
|
|
124
124
|
secretKeyMap: new Map(),
|
|
125
|
+
secretNamespaceMap: new Map(),
|
|
125
126
|
projectionMap: new Map(),
|
|
126
127
|
projectionsBySource: new Map(),
|
|
127
128
|
multiStreamProjectionMap: new Map(),
|
|
@@ -16,7 +16,7 @@ export declare function validateRequiredFeatures(state: RegistryState, features:
|
|
|
16
16
|
export declare function resolveNotificationTriggersAndRegisterHooks(state: RegistryState): void;
|
|
17
17
|
export declare function validateLifecycleHookTargets(state: RegistryState): void;
|
|
18
18
|
export declare function validateEntityHookTargets(state: RegistryState, features: readonly FeatureDefinition[]): void;
|
|
19
|
-
export declare function
|
|
19
|
+
export declare function resolveJobTriggers(state: RegistryState): void;
|
|
20
20
|
export declare function validateLiveEntities(state: RegistryState): void;
|
|
21
21
|
export declare function validateBootGates(state: RegistryState): void;
|
|
22
22
|
export declare function validateJobBackoff(state: RegistryState): void;
|
|
@@ -544,29 +544,51 @@ export function validateEntityHookTargets(state, features) {
|
|
|
544
544
|
}
|
|
545
545
|
}
|
|
546
546
|
}
|
|
547
|
-
export function
|
|
548
|
-
//
|
|
549
|
-
//
|
|
550
|
-
//
|
|
551
|
-
//
|
|
552
|
-
//
|
|
553
|
-
//
|
|
554
|
-
// auch wenn nur einer fehlt fail-fast.
|
|
547
|
+
export function resolveJobTriggers(state) {
|
|
548
|
+
// Job event triggers must reference an existing write/query handler OR an
|
|
549
|
+
// existing r.defineEvent registration. The latter is delivered async via the
|
|
550
|
+
// job-trigger event-consumer (server.ts), not the synchronous write-handler
|
|
551
|
+
// dispatch path — see createJobTriggerEventConsumer in
|
|
552
|
+
// pipeline/system-hooks.ts. Short names are qualified against the job's own
|
|
553
|
+
// feature and written back, because the job runner matches by exact QN.
|
|
555
554
|
const allHandlers = allHandlerQns(state);
|
|
556
555
|
for (const [jobName, jobDef] of state.jobMap) {
|
|
557
556
|
if (!("on" in jobDef.trigger))
|
|
558
557
|
continue;
|
|
558
|
+
const featureName = state.jobFeatureMap.get(jobName);
|
|
559
559
|
const triggerOn = jobDef.trigger.on;
|
|
560
|
-
const
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
560
|
+
const resolveTrigger = (trigger) => resolveJobTriggerName(state, allHandlers, jobName, featureName, resolveName(trigger));
|
|
561
|
+
const resolvedOn = isNameOrRefList(triggerOn)
|
|
562
|
+
? triggerOn.map(resolveTrigger)
|
|
563
|
+
: resolveTrigger(triggerOn);
|
|
564
|
+
state.jobMap.set(jobName, { ...jobDef, trigger: { ...jobDef.trigger, on: resolvedOn } });
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
// Array.isArray does not narrow a readonly array out of a union.
|
|
568
|
+
function isNameOrRefList(on) {
|
|
569
|
+
return Array.isArray(on);
|
|
570
|
+
}
|
|
571
|
+
// An already-qualified name (e.g. a misspelled own-feature QN) is not a
|
|
572
|
+
// short name; qualify() rejects it, and the "no handler" error below names it.
|
|
573
|
+
function qualifyShortTriggerName(featureName, type, trigger) {
|
|
574
|
+
try {
|
|
575
|
+
return [qualify(featureName, type, trigger)];
|
|
569
576
|
}
|
|
577
|
+
catch {
|
|
578
|
+
return [];
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
function resolveJobTriggerName(state, allHandlers, jobName, featureName, trigger) {
|
|
582
|
+
if (allHandlers.has(trigger) || state.eventMap.has(trigger))
|
|
583
|
+
return trigger;
|
|
584
|
+
const candidates = featureName === undefined
|
|
585
|
+
? []
|
|
586
|
+
: ["write", "query", "event"].flatMap((type) => qualifyShortTriggerName(featureName, type, trigger));
|
|
587
|
+
const match = candidates.find((qn) => allHandlers.has(qn) || state.eventMap.has(qn));
|
|
588
|
+
if (match !== undefined)
|
|
589
|
+
return match;
|
|
590
|
+
throw new Error(`Job "${jobName}" triggers on "${trigger}" but no handler or event with that name exists. ` +
|
|
591
|
+
`Tried: ${[trigger, ...candidates].map((name) => `"${name}"`).join(", ")}`);
|
|
570
592
|
}
|
|
571
593
|
export function validateLiveEntities(state) {
|
|
572
594
|
for (const [handlerQn, handler] of state.queryHandlerMap) {
|
package/dist/engine/registry.js
CHANGED
|
@@ -3,7 +3,7 @@ import { dedupeFeatures } from "./dedupe-features.js";
|
|
|
3
3
|
import { buildRegistryFacade } from "./registry-facade.js";
|
|
4
4
|
import { populateClaimsAndAuth, populateConfigKeys, populateEvents, populateExtensionsAndSeeds, populateFeatureCore, populateHandlers, populateHooks, populateJobsAndNotifications, populateMetricsAndSecrets, populateProjectionsAndTables, populateScreensNavWorkspaces, populateTranslations, } from "./registry-ingest.js";
|
|
5
5
|
import { createInitialState } from "./registry-state.js";
|
|
6
|
-
import { applyExtensionUsages, autoWireSoftDeleteJobs, buildEventUpcasterChains, buildImplicitProjections, buildIncomingRelations, buildSearchableSortableCaches, computeHasRateLimitedHandler, finalizeWorkspaceNavMembership, populateHandlerEntityMappings, publishEventPiiCatalog, resolveNotificationTriggersAndRegisterHooks, validateBootGates, validateEntityHookTargets, validateEventMigrationVersions, validateExtensionSelectors, validateExtensionUsageTargets, validateFieldAccessHandlersAreEntityMapped, validateJobBackoff,
|
|
6
|
+
import { applyExtensionUsages, autoWireSoftDeleteJobs, buildEventUpcasterChains, buildImplicitProjections, buildIncomingRelations, buildSearchableSortableCaches, computeHasRateLimitedHandler, finalizeWorkspaceNavMembership, populateHandlerEntityMappings, publishEventPiiCatalog, resolveJobTriggers, resolveNotificationTriggersAndRegisterHooks, validateBootGates, validateEntityHookTargets, validateEventMigrationVersions, validateExtensionSelectors, validateExtensionUsageTargets, validateFieldAccessHandlersAreEntityMapped, validateJobBackoff, validateLifecycleHookTargets, validateLiveEntities, validateProjectionApplyKeys, validateRelationTargetsExist, validateRequiredFeatures, } from "./registry-validate.js";
|
|
7
7
|
// This is where the magic happens. By "magic" I mean: precomputed maps.
|
|
8
8
|
// I build everything once at boot (hooks, relations, searchable fields, ...)
|
|
9
9
|
// so nothing has to iterate over objects at runtime. O(1) instead of O(n*m).
|
|
@@ -41,7 +41,7 @@ export function createRegistry(rawFeatures) {
|
|
|
41
41
|
resolveNotificationTriggersAndRegisterHooks(state);
|
|
42
42
|
validateLifecycleHookTargets(state);
|
|
43
43
|
validateEntityHookTargets(state, features);
|
|
44
|
-
|
|
44
|
+
resolveJobTriggers(state);
|
|
45
45
|
validateBootGates(state);
|
|
46
46
|
validateLiveEntities(state);
|
|
47
47
|
validateJobBackoff(state);
|
|
@@ -4,7 +4,7 @@ export type { QueryHandlerDefinition, StreamHandlerDefinition, WriteHandlerDefin
|
|
|
4
4
|
export type { EntityCrudRegistrar, EntityCrudVerb, EntityHandlerOptions, EntityQueryHandlerOptions, EntityWriteHandlerOptions, RegisterEntityCrudOptions, } from "@cosmicdrift/kumiko-types/entity-handlers";
|
|
5
5
|
export type { KumikoEntityTypeMap, KumikoEventTypeMap, KumikoHandlerPayloadMap, KumikoHandlerResultMap, } from "@cosmicdrift/kumiko-types/event-type-map";
|
|
6
6
|
export type { ExtensionOptionsArgs, ExtensionOptionsFor, KumikoExtensionOptionsMap, } from "@cosmicdrift/kumiko-types/extension-options-map";
|
|
7
|
-
export type { BootCheckContext, BootCheckFn, FeatureDefinition, FeatureMetricDef, FeatureMetricType, FeatureRegistrar, MetricOptions, Registry, SecretKeyDefinition, SecretKeyHandle, SecretOptions, StoreTableDef, StoreTableEntry, StoreTableOptions, UiHintOption, UiHints, } from "@cosmicdrift/kumiko-types/feature";
|
|
7
|
+
export type { BootCheckContext, BootCheckFn, FeatureDefinition, FeatureMetricDef, FeatureMetricType, FeatureRegistrar, MetricOptions, Registry, SecretKeyDefinition, SecretKeyHandle, SecretNamespaceDefinition, SecretNamespaceHandle, SecretNamespaceOptions, SecretOptions, StoreTableDef, StoreTableEntry, StoreTableOptions, UiHintOption, UiHints, } from "@cosmicdrift/kumiko-types/feature";
|
|
8
8
|
export type { FieldIconKey } from "@cosmicdrift/kumiko-types/field-icon";
|
|
9
9
|
export type { AnyFileFieldDef, BigIntFieldDef, BooleanFieldDef, ClientDerivedFieldDef, DateFieldDef, DecimalFieldDef, DefaultCurrency, DeriveContext, DerivedFieldDef, DerivedFieldsMap, DerivedValueType, EmbeddedDerivedCellDef, EmbeddedFieldDef, EmbeddedSubFieldDef, EntityDefinition, EntityIndexDef, FieldAccess, FieldDefinition, FieldsMap, FileFieldDef, FilesFieldDef, Findability, ImageFieldDef, ImagesFieldDef, JsonbFieldDef, LocatedTimestampFieldDef, LongTextFieldDef, LongTextFindability, MoneyCurrencySource, MoneyFieldDef, MultiSelectFieldDef, NumberFieldDef, OptionsQueryPayload, OptionsQueryPayloadValue, ParentRefDef, PersonalAnnotations, PersonalAnnotationsLongText, PersonalAnnotationsNoFind, PersonalSubject, ReferenceFieldDef, ResolvedPiiFlags, RetentionDef, SelectFieldDef, SelectOptionTone, TextFieldDef, TimestampFieldDef, TransitionMap, TzFieldDef, } from "@cosmicdrift/kumiko-types/fields";
|
|
10
10
|
export type { AccessRule, ActiveMembership, ActiveMembershipRejection, ActiveMembershipResult, AgentExposure, AgentHandlerHints, AgentRisk, AggregateStreamHandle, AppContext, AppendEventArgs, AppendEventFn, AuthClaimsContext, AuthClaimsFn, AuthClaimsHookDef, CamelToKebab, ClaimKeyDefinition, ClaimKeyHandle, ClaimKeyJsType, ClaimKeyType, DeclarativeEventMigration, DispatchWriteRef, EntityRef, EscapeHatchAuditSink, EscapeHatchDeclaration, EscapeHatchKind, EscapeHatchReporter, EscapeHatchTarget, EscapeHatchUseEvent, EventDef, EventMigrationDef, EventPiiFields, EventPiiStance, EventUpcastCtx, EventUpcastFn, FetchForWritingArgs, HandlerContext, HandlerRef, JobContext, JobRunnerRef, JobTriggerEvent, MemberReader, NameOrRef, NotifyFactory, NotifyFn, NotifyOptions, NotifyPriority, OpenToAllAccessRule, OpenToAllDeclaration, OpenToAllPersonalData, QualifiedEventName, QueryEvent, QueryHandlerDef, QueryHandlerFn, RateLimitDeclaration, RateLimitDisabled, RateLimitOption, RateLimitPer, RoleAccessPersonalData, RoleAccessRule, SessionUser, SessionUserOrigin, StreamHandlerDef, StreamHandlerFn, TryAppendEventFn, TryAppendEventResult, UnsafeAppendEventFn, WriteEvent, WriteHandlerDef, WriteHandlerFn, WriteResult, } from "@cosmicdrift/kumiko-types/handlers";
|
|
@@ -18,7 +18,7 @@ export type { FromRule, FromRuleKind, OwnershipClause, OwnershipMap, OwnershipRe
|
|
|
18
18
|
export type { EntityProjectionExtension, MspErrorMode, MspErrorPolicy, MultiStreamApplyFn, MultiStreamProjectionDefinition, ProjectionDefinition, ProjectionTable, SingleStreamApplyFn, } from "@cosmicdrift/kumiko-types/projection";
|
|
19
19
|
export type { BelongsToRelation, EntityRelations, HasManyRelation, ManyToManyRelation, RelationDefinition, } from "@cosmicdrift/kumiko-types/relations";
|
|
20
20
|
export type { ActionFormScreenDefinition, ConfigEditScreenDefinition, CustomScreenDefinition, CustomScreenRoute, DashboardChartPanel, DashboardCustomPanel, DashboardFeedPanel, DashboardFilterDefinition, DashboardListPanel, DashboardPanelDefinition, DashboardPanelVisibility, DashboardProgressListPanel, DashboardScreenDefinition, DashboardScreenPanel, DashboardStatGroupPanel, DashboardStatPanel, EditExtensionSection, EditFieldSpec, EditFieldsSection, EditLayout, EditRelatedListSection, EditSectionSpec, EditWriteFormSection, EntityEditScreenDefinition, EntityListExpandableRow, EntityListScreenDefinition, FieldCondition, FieldFormatRegistry, FieldRenderer, FormatSpec, FormWidth, ListColumnSpec, ListFacetSpec, ListPaginationMode, ListSortDir, ListSortSpec, MetricNavigate, MetricSpec, PlatformComponent, ProjectionDetailScreenDefinition, ProjectionListScreenDefinition, RecordHeaderSpec, RecordHeaderSubtitlePart, RowAction, RowActionNavigate, RowActionNavigateBase, RowActionWriteHandler, RowFieldExtractor, ScreenDefinition, ScreenFilter, ScreenFilterOp, ScreenNavSugar, ScreenSlots, SecretMintConfirmStep, SecretMintScreenDefinition, SecretReveal, SecretRevealField, SecretsEditScreenDefinition, SecretsEditSection, ToolbarAction, UnitKey, } from "@cosmicdrift/kumiko-types/screen";
|
|
21
|
-
export { metricField } from "@cosmicdrift/kumiko-types/screen";
|
|
21
|
+
export { metricField, relatedListGroupHeaderLabel, relatedListGroupKey, } from "@cosmicdrift/kumiko-types/screen";
|
|
22
22
|
export type { TargetRef } from "@cosmicdrift/kumiko-types/target-ref";
|
|
23
23
|
export type { Subscribe, TreeAction, TreeActionDef, TreeActionsHandle, TreeChildrenSubscribe, TreeNode, TreeNodeState, } from "@cosmicdrift/kumiko-types/tree-node";
|
|
24
24
|
export type { WebSocketConnection, WebSocketMessageData, WebSocketRouteConnectDeps, WebSocketRouteDefinition, WebSocketSessionHandlers, } from "@cosmicdrift/kumiko-types/websocket-route";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
export { isAgentVisibleScreen, resolveAgentExposure, } from "@cosmicdrift/kumiko-types/agent-exposure";
|
|
4
4
|
export { isOpenToAllGranted, isRateLimitDisabled, isUiAccessGranted, } from "@cosmicdrift/kumiko-types/handlers";
|
|
5
5
|
export { isSystemTenant, isUuid, parseTenantId, SYSTEM_TENANT_ID, } from "@cosmicdrift/kumiko-types/identifiers";
|
|
6
|
-
export { metricField } from "@cosmicdrift/kumiko-types/screen";
|
|
6
|
+
export { metricField, relatedListGroupHeaderLabel, relatedListGroupKey, } from "@cosmicdrift/kumiko-types/screen";
|
|
7
7
|
export { DEFAULT_CURRENCIES, DEFAULT_LOCALES, isFileField } from "../field-helpers.js";
|
|
8
8
|
export { resolveName, withResponseData } from "../handler-helpers.js";
|
|
9
9
|
export { HookPhases } from "../hook-helpers.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export type * from "@cosmicdrift/kumiko-types/screen";
|
|
2
|
-
export { metricField } from "@cosmicdrift/kumiko-types/screen";
|
|
2
|
+
export { metricField, relatedListGroupHeaderLabel, relatedListGroupKey, } from "@cosmicdrift/kumiko-types/screen";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { metricField } from "@cosmicdrift/kumiko-types/screen";
|
|
1
|
+
export { metricField, relatedListGroupHeaderLabel, relatedListGroupKey, } from "@cosmicdrift/kumiko-types/screen";
|
package/dist/errors/classes.d.ts
CHANGED
|
@@ -24,6 +24,11 @@ export declare class AccessDeniedError extends KumikoError {
|
|
|
24
24
|
readonly httpStatus = 403;
|
|
25
25
|
constructor(opts?: Pick<ErrorOpts, "message" | "i18nKey" | "i18nParams" | "details" | "cause">);
|
|
26
26
|
}
|
|
27
|
+
export declare class UnauthenticatedError extends KumikoError {
|
|
28
|
+
readonly code = "unauthenticated";
|
|
29
|
+
readonly httpStatus = 401;
|
|
30
|
+
constructor(opts?: Pick<ErrorOpts, "message" | "details" | "cause">);
|
|
31
|
+
}
|
|
27
32
|
export type NotFoundDetails = {
|
|
28
33
|
readonly entity: string;
|
|
29
34
|
readonly id?: string;
|