@cosmicdrift/kumiko-framework 0.154.2 → 0.155.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-framework",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.155.0",
|
|
4
4
|
"description": "Framework core — engine, pipeline, API, DB, and every other bit that makes Kumiko go.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -193,7 +193,7 @@
|
|
|
193
193
|
"zod": "^4.4.3"
|
|
194
194
|
},
|
|
195
195
|
"devDependencies": {
|
|
196
|
-
"@cosmicdrift/kumiko-dispatcher-live": "0.
|
|
196
|
+
"@cosmicdrift/kumiko-dispatcher-live": "0.155.0",
|
|
197
197
|
"bun-types": "^1.3.13",
|
|
198
198
|
"pino-pretty": "^13.1.3"
|
|
199
199
|
},
|
|
@@ -86,7 +86,7 @@ export function defineFeature<const TName extends string, TExports = undefined>(
|
|
|
86
86
|
}
|
|
87
87
|
state.uiHints = hints;
|
|
88
88
|
},
|
|
89
|
-
...buildEntityHandlerMethods(state, name
|
|
89
|
+
...buildEntityHandlerMethods(state, name),
|
|
90
90
|
...buildConfigEventsJobsMethods(state, name),
|
|
91
91
|
...buildUiExtensionsMethods(state, name),
|
|
92
92
|
};
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import type { ZodType, z } from "zod";
|
|
2
2
|
import { toTableName } from "../db/table-builder";
|
|
3
3
|
import type { QueryHandlerDefinition, WriteHandlerDefinition } from "./define-handler";
|
|
4
|
-
import { type RegisterEntityCrudOptions, registerEntityCrud } from "./entity-handlers";
|
|
5
4
|
import type { FeatureBuilderState } from "./feature-builder-state";
|
|
6
5
|
import { splitNamedDefinition } from "./object-form";
|
|
7
6
|
import type {
|
|
8
7
|
AccessRule,
|
|
9
8
|
EntityDefinition,
|
|
10
9
|
EntityRef,
|
|
11
|
-
FeatureRegistrar,
|
|
12
10
|
HandlerRef,
|
|
13
11
|
NameOrRef,
|
|
14
12
|
QueryHandlerFn,
|
|
@@ -47,14 +45,11 @@ function tryMapEntity(state: FeatureBuilderState, name: string, handlerName: str
|
|
|
47
45
|
}
|
|
48
46
|
}
|
|
49
47
|
|
|
50
|
-
// Builds entity/
|
|
51
|
-
// methods that create or reference entities.
|
|
52
|
-
// registrar (self-reference into registerEntityCrud); getRegistrar is a lazy
|
|
53
|
-
// thunk since the registrar object doesn't exist yet while this is composed.
|
|
48
|
+
// Builds entity/relation/writeHandler/queryHandler — the registrar
|
|
49
|
+
// methods that create or reference entities.
|
|
54
50
|
export function buildEntityHandlerMethods<TName extends string>(
|
|
55
51
|
state: FeatureBuilderState,
|
|
56
52
|
name: TName,
|
|
57
|
-
getRegistrar: () => FeatureRegistrar<TName>,
|
|
58
53
|
) {
|
|
59
54
|
return {
|
|
60
55
|
entity(
|
|
@@ -70,14 +65,6 @@ export function buildEntityHandlerMethods<TName extends string>(
|
|
|
70
65
|
if (options?.table !== undefined) state.entityTables[entityName] = options.table;
|
|
71
66
|
return { name: entityName, table: entityDefinition.table ?? toTableName(entityName) };
|
|
72
67
|
},
|
|
73
|
-
crud(
|
|
74
|
-
entityName: string,
|
|
75
|
-
definition: EntityDefinition,
|
|
76
|
-
options?: RegisterEntityCrudOptions,
|
|
77
|
-
): EntityRef {
|
|
78
|
-
registerEntityCrud(getRegistrar(), entityName, definition, options);
|
|
79
|
-
return { name: entityName, table: definition.table ?? toTableName(entityName) };
|
|
80
|
-
},
|
|
81
68
|
relation(
|
|
82
69
|
entityRefOrDefinition:
|
|
83
70
|
| NameOrRef
|
|
@@ -7,7 +7,6 @@ import type { EntityTableMeta } from "../../db/entity-table-meta";
|
|
|
7
7
|
type PgTable = unknown;
|
|
8
8
|
|
|
9
9
|
import type { QueryHandlerDefinition, WriteHandlerDefinition } from "../define-handler";
|
|
10
|
-
import type { RegisterEntityCrudOptions } from "../entity-handlers";
|
|
11
10
|
import type {
|
|
12
11
|
ConfigKeyDefinition,
|
|
13
12
|
ConfigKeyHandle,
|
|
@@ -439,11 +438,6 @@ export type FeatureRegistrar<TFeature extends string = string> = {
|
|
|
439
438
|
): EntityRef;
|
|
440
439
|
entity(definition: { readonly name: string } & EntityDefinition): EntityRef;
|
|
441
440
|
|
|
442
|
-
// One-call CRUD for an event-sourced entity — delegates to registerEntityCrud():
|
|
443
|
-
// r.entity + create/update/delete/restore/list/detail handlers per verb flag.
|
|
444
|
-
// Access stays explicit — no openToAll default.
|
|
445
|
-
crud(name: string, definition: EntityDefinition, options?: RegisterEntityCrudOptions): EntityRef;
|
|
446
|
-
|
|
447
441
|
writeHandler<TName extends string, TSchema extends ZodType>(
|
|
448
442
|
def: WriteHandlerDefinition<TName, TSchema>,
|
|
449
443
|
): HandlerRef;
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
2
|
-
import { defineFeature } from "../define-feature";
|
|
3
|
-
import { registerEntityCrud } from "../entity-handlers";
|
|
4
|
-
import { createEntity, createTextField } from "../factories";
|
|
5
|
-
|
|
6
|
-
const taskEntity = createEntity({
|
|
7
|
-
table: "crud_sugar_tasks",
|
|
8
|
-
fields: {
|
|
9
|
-
title: createTextField({ required: true }),
|
|
10
|
-
},
|
|
11
|
-
softDelete: true,
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
const access = {
|
|
15
|
-
write: { access: { roles: ["Admin"] } },
|
|
16
|
-
read: { access: { openToAll: true } },
|
|
17
|
-
} as const;
|
|
18
|
-
|
|
19
|
-
describe("r.crud", () => {
|
|
20
|
-
test("registers the same entity + handlers as registerEntityCrud", () => {
|
|
21
|
-
const viaCrud = defineFeature("crud-sugar", (r) => {
|
|
22
|
-
r.crud("task", taskEntity, access);
|
|
23
|
-
});
|
|
24
|
-
const viaHelper = defineFeature("crud-sugar", (r) => {
|
|
25
|
-
registerEntityCrud(r, "task", taskEntity, access);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
expect(viaCrud.entities).toEqual(viaHelper.entities);
|
|
29
|
-
expect(Object.keys(viaCrud.writeHandlers)).toEqual(Object.keys(viaHelper.writeHandlers));
|
|
30
|
-
expect(Object.keys(viaCrud.queryHandlers)).toEqual(Object.keys(viaHelper.queryHandlers));
|
|
31
|
-
expect(Object.keys(viaCrud.writeHandlers)).toEqual([
|
|
32
|
-
"task:create",
|
|
33
|
-
"task:update",
|
|
34
|
-
"task:delete",
|
|
35
|
-
"task:restore",
|
|
36
|
-
]);
|
|
37
|
-
expect(Object.keys(viaCrud.queryHandlers)).toEqual(["task:list", "task:detail"]);
|
|
38
|
-
expect(viaCrud.writeHandlers["task:create"]?.access).toEqual({ roles: ["Admin"] });
|
|
39
|
-
expect(viaCrud.queryHandlers["task:list"]?.access).toEqual({ openToAll: true });
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test("returns an EntityRef like r.entity", () => {
|
|
43
|
-
defineFeature("crud-sugar", (r) => {
|
|
44
|
-
const ref = r.crud("task", taskEntity, access);
|
|
45
|
-
expect(ref).toEqual({ name: "task", table: "crud_sugar_tasks" });
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
test("verbs opt-out skips handlers", () => {
|
|
50
|
-
const feature = defineFeature("crud-sugar", (r) => {
|
|
51
|
-
r.crud("task", taskEntity, { ...access, verbs: { delete: false, restore: false } });
|
|
52
|
-
});
|
|
53
|
-
expect(Object.keys(feature.writeHandlers)).toEqual(["task:create", "task:update"]);
|
|
54
|
-
});
|
|
55
|
-
});
|