@ai-matrx/associations 0.9.33 → 0.10.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/CHANGELOG.md +6 -0
- package/dist/{CommentThread-CaUsmcYj.d.cts → CommentThread-D1rzo_pu.d.cts} +43 -35
- package/dist/{CommentThread-CaUsmcYj.d.ts → CommentThread-D1rzo_pu.d.ts} +43 -35
- package/dist/core/index.cjs +62 -51
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +12 -2
- package/dist/core/index.d.ts +12 -2
- package/dist/core/index.js +62 -51
- package/dist/core/index.js.map +1 -1
- package/dist/index.cjs +6 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -33
- package/dist/index.d.ts +59 -33
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +4 -2
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +4 -2
- package/dist/react/index.js.map +1 -1
- package/dist/react/lazy/index.d.cts +1 -1
- package/dist/react/lazy/index.d.ts +1 -1
- package/package.json +10 -10
package/dist/core/index.d.cts
CHANGED
|
@@ -372,9 +372,19 @@ type EntityRowResult = {
|
|
|
372
372
|
interface CreateEntityRowArgs {
|
|
373
373
|
/** The new row's human name — written to the registry `titleColumn`. */
|
|
374
374
|
title: string;
|
|
375
|
-
/**
|
|
375
|
+
/**
|
|
376
|
+
* The organization the new row belongs to. REQUIRED by
|
|
377
|
+
* `public.entity_row_create`: every creatable token's table carries
|
|
378
|
+
* `organization_id`, and the door refuses a row with nobody owning it.
|
|
379
|
+
*/
|
|
376
380
|
orgId?: string | null;
|
|
377
|
-
/**
|
|
381
|
+
/**
|
|
382
|
+
* 🚨 NO LONGER WRITABLE THROUGH THIS SERVICE (DOORS-ONLY-4). The door writes the
|
|
383
|
+
* name, the owner and the organization and nothing else, so a non-empty value here
|
|
384
|
+
* is REFUSED with the columns named rather than dropped on the floor. A token whose
|
|
385
|
+
* table needs more than a name is created by its own feature's create service; this
|
|
386
|
+
* generic path then only renames it.
|
|
387
|
+
*/
|
|
378
388
|
extraColumns?: Record<string, unknown>;
|
|
379
389
|
}
|
|
380
390
|
interface EntityRowsServiceApi {
|
package/dist/core/index.d.ts
CHANGED
|
@@ -372,9 +372,19 @@ type EntityRowResult = {
|
|
|
372
372
|
interface CreateEntityRowArgs {
|
|
373
373
|
/** The new row's human name — written to the registry `titleColumn`. */
|
|
374
374
|
title: string;
|
|
375
|
-
/**
|
|
375
|
+
/**
|
|
376
|
+
* The organization the new row belongs to. REQUIRED by
|
|
377
|
+
* `public.entity_row_create`: every creatable token's table carries
|
|
378
|
+
* `organization_id`, and the door refuses a row with nobody owning it.
|
|
379
|
+
*/
|
|
376
380
|
orgId?: string | null;
|
|
377
|
-
/**
|
|
381
|
+
/**
|
|
382
|
+
* 🚨 NO LONGER WRITABLE THROUGH THIS SERVICE (DOORS-ONLY-4). The door writes the
|
|
383
|
+
* name, the owner and the organization and nothing else, so a non-empty value here
|
|
384
|
+
* is REFUSED with the columns named rather than dropped on the floor. A token whose
|
|
385
|
+
* table needs more than a name is created by its own feature's create service; this
|
|
386
|
+
* generic path then only renames it.
|
|
387
|
+
*/
|
|
378
388
|
extraColumns?: Record<string, unknown>;
|
|
379
389
|
}
|
|
380
390
|
interface EntityRowsServiceApi {
|
package/dist/core/index.js
CHANGED
|
@@ -881,6 +881,8 @@ var ENTITY_TYPE_METADATA = {
|
|
|
881
881
|
"template_context_items": { token: "template_context_items", schema: "context", table: "template_context_items", label: "Template Context Items", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
882
882
|
"template_scope_types": { token: "template_scope_types", schema: "context", table: "template_scope_types", label: "Template Scope Types", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
883
883
|
"templates": { token: "templates", schema: "context", table: "templates", label: "Templates", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
884
|
+
"test_handset_inbox": { token: "test_handset_inbox", schema: "communication", table: "test_handset_inbox", label: "Test Handset Inbox", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
885
|
+
"test_handset_verification": { token: "test_handset_verification", schema: "communication", table: "test_handset_verification", label: "Test Handset Verification", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
884
886
|
"thread": { token: "thread", schema: "workspace", table: "threads", label: "Thread", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: true, titleColumn: "title", contentRole: null, referenceCategory: null },
|
|
885
887
|
"tool": { token: "tool", schema: "tool", table: "definition", label: "Tool", baseTier: 1, isComponent: false, isModule: false, isListed: false, scopeable: true, category: "Tools", referencePickable: true, titleColumn: "name", contentRole: null, referenceCategory: null },
|
|
886
888
|
"tool_binding": { token: "tool_binding", schema: "tool", table: "binding", label: "Tool binding", baseTier: 1, isComponent: true, isModule: false, isListed: false, scopeable: true, category: null, referencePickable: false, titleColumn: null, contentRole: null, referenceCategory: null },
|
|
@@ -1874,6 +1876,8 @@ var ENTITY_TYPE_TOKENS = [
|
|
|
1874
1876
|
"template_context_items",
|
|
1875
1877
|
"template_scope_types",
|
|
1876
1878
|
"templates",
|
|
1879
|
+
"test_handset_inbox",
|
|
1880
|
+
"test_handset_verification",
|
|
1877
1881
|
"thread",
|
|
1878
1882
|
"tool",
|
|
1879
1883
|
"tool_binding",
|
|
@@ -3143,31 +3147,7 @@ function createTitlesService(deps, candidates) {
|
|
|
3143
3147
|
|
|
3144
3148
|
// src/core/entityRows.ts
|
|
3145
3149
|
function createEntityRowsService(deps, titles) {
|
|
3146
|
-
const { dataSource,
|
|
3147
|
-
function tableFor(token, schema, table) {
|
|
3148
|
-
if (schema && schema !== "public") {
|
|
3149
|
-
if (!dataSource.schema) {
|
|
3150
|
-
const error = `dataSource has no schema() capability \u2014 entity-row writes for "${token}" (${schema}.${table}) need a table-capable dataSource (a real supabase-js client)`;
|
|
3151
|
-
errorSink({
|
|
3152
|
-
code: "datasource_missing_table_capability",
|
|
3153
|
-
message: `[entityRows] ${error}`,
|
|
3154
|
-
context: { token, schema, table }
|
|
3155
|
-
});
|
|
3156
|
-
return { ok: false, error };
|
|
3157
|
-
}
|
|
3158
|
-
return { ok: true, query: dataSource.schema(schema).from(table) };
|
|
3159
|
-
}
|
|
3160
|
-
if (!dataSource.from) {
|
|
3161
|
-
const error = `dataSource has no from() capability \u2014 entity-row writes for "${token}" need a table-capable dataSource (a real supabase-js client)`;
|
|
3162
|
-
errorSink({
|
|
3163
|
-
code: "datasource_missing_table_capability",
|
|
3164
|
-
message: `[entityRows] ${error}`,
|
|
3165
|
-
context: { token, schema, table }
|
|
3166
|
-
});
|
|
3167
|
-
return { ok: false, error };
|
|
3168
|
-
}
|
|
3169
|
-
return { ok: true, query: dataSource.from(table) };
|
|
3170
|
-
}
|
|
3150
|
+
const { dataSource, registry, errorSink } = deps;
|
|
3171
3151
|
function requireTitleColumn(token, op) {
|
|
3172
3152
|
const info = registry.getEntityInfo(token);
|
|
3173
3153
|
if (!info.titleColumn) {
|
|
@@ -3179,43 +3159,68 @@ function createEntityRowsService(deps, titles) {
|
|
|
3179
3159
|
});
|
|
3180
3160
|
return { ok: false, error };
|
|
3181
3161
|
}
|
|
3182
|
-
return { ok: true
|
|
3162
|
+
return { ok: true };
|
|
3183
3163
|
}
|
|
3184
3164
|
return {
|
|
3185
3165
|
/**
|
|
3186
|
-
*
|
|
3187
|
-
*
|
|
3188
|
-
*
|
|
3189
|
-
*
|
|
3166
|
+
* Create one row of `token`'s backing table named `title`, through
|
|
3167
|
+
* `public.entity_row_create`. The door stamps `created_by` from `auth.uid()`,
|
|
3168
|
+
* checks the caller can act in the organization, and refuses machinery tokens and
|
|
3169
|
+
* tables with no organization by name. Returns the new row's id + title. The
|
|
3170
|
+
* caller wires associations afterwards — this layer never writes edges.
|
|
3190
3171
|
*/
|
|
3191
3172
|
async createEntityRow(token, args) {
|
|
3192
3173
|
const gate = requireTitleColumn(token, "creating rows");
|
|
3193
3174
|
if (!gate.ok) return gate;
|
|
3194
|
-
const info = registry.getEntityInfo(token);
|
|
3195
3175
|
const title = args.title.trim();
|
|
3196
3176
|
if (!title) return { ok: false, error: "Name is required" };
|
|
3177
|
+
const extras = Object.keys(args.extraColumns ?? {});
|
|
3178
|
+
if (extras.length > 0) {
|
|
3179
|
+
const error = `A new ${registry.getEntityInfo(token).label} cannot be created here with ${extras.join(", ")}: the shared create door writes the name, the owner and the organization and nothing else. Create it with this feature's own create service, then attach it.`;
|
|
3180
|
+
errorSink({
|
|
3181
|
+
code: "entity_row_extra_columns_unsupported",
|
|
3182
|
+
message: `[createEntityRow] extraColumns are not writable through entity_row_create for "${token}": ${extras.join(", ")}`,
|
|
3183
|
+
context: { token, extras }
|
|
3184
|
+
});
|
|
3185
|
+
return { ok: false, error };
|
|
3186
|
+
}
|
|
3187
|
+
if (!args.orgId) {
|
|
3188
|
+
const error = `Name the organization this ${registry.getEntityInfo(token).label} belongs to.`;
|
|
3189
|
+
errorSink({
|
|
3190
|
+
code: "entity_row_missing_organization",
|
|
3191
|
+
message: `[createEntityRow] no organization supplied for "${token}"; entity_row_create requires one`,
|
|
3192
|
+
context: { token }
|
|
3193
|
+
});
|
|
3194
|
+
return { ok: false, error };
|
|
3195
|
+
}
|
|
3197
3196
|
try {
|
|
3198
|
-
const
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
...info.ownerColumn ? { [info.ownerColumn]: userId } : {},
|
|
3204
|
-
...info.orgColumn && args.orgId ? { [info.orgColumn]: args.orgId } : {},
|
|
3205
|
-
...args.extraColumns ?? {}
|
|
3206
|
-
};
|
|
3207
|
-
const { data, error } = await table.query.insert(row).select("id").single();
|
|
3197
|
+
const { data, error } = await dataSource.rpc("entity_row_create", {
|
|
3198
|
+
p_token: token,
|
|
3199
|
+
p_title: title,
|
|
3200
|
+
p_organization_id: args.orgId
|
|
3201
|
+
});
|
|
3208
3202
|
if (error) {
|
|
3209
3203
|
errorSink({
|
|
3210
3204
|
code: "entity_row_insert_failed",
|
|
3211
|
-
message: `[createEntityRow]
|
|
3205
|
+
message: `[createEntityRow] entity_row_create failed for "${token}": ${error.message}`,
|
|
3212
3206
|
context: { token, detail: error }
|
|
3213
3207
|
});
|
|
3214
3208
|
return { ok: false, error: error.message };
|
|
3215
3209
|
}
|
|
3216
|
-
const
|
|
3217
|
-
|
|
3218
|
-
|
|
3210
|
+
const row = data;
|
|
3211
|
+
if (!row || typeof row.id !== "string" || !row.id) {
|
|
3212
|
+
const msg = "The create door returned no record.";
|
|
3213
|
+
errorSink({
|
|
3214
|
+
code: "entity_row_insert_failed",
|
|
3215
|
+
message: `[createEntityRow] entity_row_create returned no id for "${token}"`,
|
|
3216
|
+
context: { token, detail: data }
|
|
3217
|
+
});
|
|
3218
|
+
return { ok: false, error: msg };
|
|
3219
|
+
}
|
|
3220
|
+
const id = row.id;
|
|
3221
|
+
const named = typeof row.title === "string" && row.title ? row.title : title;
|
|
3222
|
+
titles.prime(token, id, named);
|
|
3223
|
+
return { ok: true, data: { id, title: named } };
|
|
3219
3224
|
} catch (e) {
|
|
3220
3225
|
const msg = e instanceof Error ? e.message : "Failed to create";
|
|
3221
3226
|
errorSink({
|
|
@@ -3226,21 +3231,27 @@ function createEntityRowsService(deps, titles) {
|
|
|
3226
3231
|
return { ok: false, error: msg };
|
|
3227
3232
|
}
|
|
3228
3233
|
},
|
|
3229
|
-
/**
|
|
3234
|
+
/**
|
|
3235
|
+
* Rename one row of `token`'s table through `public.entity_row_rename`. The door
|
|
3236
|
+
* decides on the one ladder — the row's author, `editor` on the row, or a platform
|
|
3237
|
+
* admin — and answers "there is no such thing here" rather than telling a caller
|
|
3238
|
+
* that somebody else's row exists.
|
|
3239
|
+
*/
|
|
3230
3240
|
async renameEntityRow(token, id, title) {
|
|
3231
3241
|
const gate = requireTitleColumn(token, "renaming rows");
|
|
3232
3242
|
if (!gate.ok) return gate;
|
|
3233
|
-
const info = registry.getEntityInfo(token);
|
|
3234
3243
|
const trimmed = title.trim();
|
|
3235
3244
|
if (!trimmed) return { ok: false, error: "Name is required" };
|
|
3236
3245
|
try {
|
|
3237
|
-
const
|
|
3238
|
-
|
|
3239
|
-
|
|
3246
|
+
const { error } = await dataSource.rpc("entity_row_rename", {
|
|
3247
|
+
p_token: token,
|
|
3248
|
+
p_id: id,
|
|
3249
|
+
p_title: trimmed
|
|
3250
|
+
});
|
|
3240
3251
|
if (error) {
|
|
3241
3252
|
errorSink({
|
|
3242
3253
|
code: "entity_row_update_failed",
|
|
3243
|
-
message: `[renameEntityRow]
|
|
3254
|
+
message: `[renameEntityRow] entity_row_rename failed for "${token}": ${error.message}`,
|
|
3244
3255
|
context: { token, id, detail: error }
|
|
3245
3256
|
});
|
|
3246
3257
|
return { ok: false, error: error.message };
|