@electric-ax/agents-server 0.4.20 → 0.5.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/entrypoint.js +107 -7
- package/dist/index.cjs +106 -6
- package/dist/index.d.cts +2484 -2431
- package/dist/index.d.ts +2483 -2432
- package/dist/index.js +107 -7
- package/drizzle/0016_entity_type_externally_writable_collections.sql +1 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +4 -4
- package/src/db/schema.ts +4 -0
- package/src/electric-agents-types.ts +23 -0
- package/src/entity-manager.ts +126 -0
- package/src/entity-registry.ts +14 -0
- package/src/routing/entities-router.ts +61 -2
- package/src/routing/entity-types-router.ts +56 -0
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { Type, type Static } from '@sinclair/typebox'
|
|
6
6
|
import { Router, json, status } from 'itty-router'
|
|
7
|
+
import { COMMENTS_CONTRACT } from '@electric-ax/agents-runtime'
|
|
7
8
|
import { dispatchPolicySchema } from '../dispatch-policy-schema.js'
|
|
8
9
|
import { ElectricAgentsError } from '../entity-manager.js'
|
|
9
10
|
import {
|
|
@@ -45,6 +46,29 @@ type PublicEntityTypeResponse = ElectricAgentsEntityType & {
|
|
|
45
46
|
|
|
46
47
|
const jsonObjectSchema = Type.Record(Type.String(), Type.Unknown())
|
|
47
48
|
const schemaMapSchema = Type.Record(Type.String(), jsonObjectSchema)
|
|
49
|
+
// `principalColumn` is accepted and ignored: older runtimes still send it
|
|
50
|
+
// (the column is fixed to `_principal` now), and rejecting it would break
|
|
51
|
+
// registration during version skew.
|
|
52
|
+
const externallyWritableCollectionsSchema = Type.Record(
|
|
53
|
+
Type.String(),
|
|
54
|
+
Type.Object(
|
|
55
|
+
{
|
|
56
|
+
type: Type.String(),
|
|
57
|
+
contract: Type.Optional(Type.String()),
|
|
58
|
+
operations: Type.Optional(
|
|
59
|
+
Type.Array(
|
|
60
|
+
Type.Union([
|
|
61
|
+
Type.Literal(`insert`),
|
|
62
|
+
Type.Literal(`update`),
|
|
63
|
+
Type.Literal(`delete`),
|
|
64
|
+
])
|
|
65
|
+
)
|
|
66
|
+
),
|
|
67
|
+
principalColumn: Type.Optional(Type.String()),
|
|
68
|
+
},
|
|
69
|
+
{ additionalProperties: false }
|
|
70
|
+
)
|
|
71
|
+
)
|
|
48
72
|
const slashCommandArgumentSchema = Type.Object(
|
|
49
73
|
{
|
|
50
74
|
name: Type.String(),
|
|
@@ -93,6 +117,9 @@ const registerEntityTypeBodySchema = Type.Object(
|
|
|
93
117
|
permission_grants: Type.Optional(
|
|
94
118
|
Type.Array(typePermissionGrantInputSchema)
|
|
95
119
|
),
|
|
120
|
+
externally_writable_collections: Type.Optional(
|
|
121
|
+
externallyWritableCollectionsSchema
|
|
122
|
+
),
|
|
96
123
|
},
|
|
97
124
|
{ additionalProperties: false }
|
|
98
125
|
)
|
|
@@ -445,9 +472,37 @@ function parseExpiresAt(value: string | undefined): Date | undefined {
|
|
|
445
472
|
return expiresAt
|
|
446
473
|
}
|
|
447
474
|
|
|
475
|
+
/**
|
|
476
|
+
* The `comments` collection name is reserved for the canonical comments
|
|
477
|
+
* contract: the UI keys its comment affordances on it, so a divergent
|
|
478
|
+
* collection registered under that name (or the contract mounted under
|
|
479
|
+
* another name) would break that assumption silently.
|
|
480
|
+
*/
|
|
481
|
+
function validateExternallyWritableCollections(
|
|
482
|
+
collections: RegisterEntityTypeRequest[`externally_writable_collections`]
|
|
483
|
+
): void {
|
|
484
|
+
for (const [name, config] of Object.entries(collections ?? {})) {
|
|
485
|
+
if (name === `comments` && config.contract !== COMMENTS_CONTRACT) {
|
|
486
|
+
throw new ElectricAgentsError(
|
|
487
|
+
ErrCodeInvalidRequest,
|
|
488
|
+
`The externally-writable collection name "comments" is reserved for the "${COMMENTS_CONTRACT}" contract`,
|
|
489
|
+
400
|
|
490
|
+
)
|
|
491
|
+
}
|
|
492
|
+
if (config.contract === COMMENTS_CONTRACT && name !== `comments`) {
|
|
493
|
+
throw new ElectricAgentsError(
|
|
494
|
+
ErrCodeInvalidRequest,
|
|
495
|
+
`The "${COMMENTS_CONTRACT}" contract must be registered under the collection name "comments"`,
|
|
496
|
+
400
|
|
497
|
+
)
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
448
502
|
function normalizeEntityTypeRequest(
|
|
449
503
|
parsed: RegisterEntityTypeBody | RegisterEntityTypeRequest
|
|
450
504
|
): RegisterEntityTypeRequest {
|
|
505
|
+
validateExternallyWritableCollections(parsed.externally_writable_collections)
|
|
451
506
|
const serveEndpoint = rewriteLoopbackWebhookUrl(parsed.serve_endpoint)
|
|
452
507
|
return {
|
|
453
508
|
name: parsed.name ?? ``,
|
|
@@ -465,6 +520,7 @@ function normalizeEntityTypeRequest(
|
|
|
465
520
|
} as RegisterEntityTypeRequest[`default_dispatch_policy`])
|
|
466
521
|
: undefined),
|
|
467
522
|
permission_grants: parsed.permission_grants,
|
|
523
|
+
externally_writable_collections: parsed.externally_writable_collections,
|
|
468
524
|
}
|
|
469
525
|
}
|
|
470
526
|
|