@coffer-org/server 1.7.1 → 1.8.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/auth-api.js +3 -3
- package/dist/background-scheduler.d.ts +22 -0
- package/dist/background-scheduler.js +101 -0
- package/dist/collection-io.d.ts +7 -7
- package/dist/collection-io.js +2 -2
- package/dist/connector-identity.d.ts +5 -0
- package/dist/connector-identity.js +32 -0
- package/dist/embed-openai.d.ts +10 -0
- package/dist/embed-openai.js +28 -0
- package/dist/entity-schema.d.ts +6 -5
- package/dist/entity-schema.js +24 -10
- package/dist/extend-io.d.ts +5 -3
- package/dist/extend-io.js +17 -10
- package/dist/extend-table.d.ts +4 -3
- package/dist/extend-table.js +10 -18
- package/dist/field-masking.d.ts +7 -0
- package/dist/field-masking.js +60 -0
- package/dist/index-signal.d.ts +3 -0
- package/dist/index-signal.js +14 -0
- package/dist/index.js +59 -159
- package/dist/local-api.d.ts +3 -3
- package/dist/local-api.js +6 -6
- package/dist/mcp-http.d.ts +5 -0
- package/dist/mcp-http.js +37 -0
- package/dist/mcp-http.test-helpers.d.ts +17 -0
- package/dist/mcp-http.test-helpers.js +117 -0
- package/dist/mcp-local.d.ts +10 -0
- package/dist/mcp-local.js +57 -0
- package/dist/mcp-tools.d.ts +61 -0
- package/dist/mcp-tools.js +225 -0
- package/dist/msg-log.d.ts +0 -1
- package/dist/msg-log.js +2 -2
- package/dist/mutate.d.ts +7 -5
- package/dist/mutate.js +20 -8
- package/dist/plugin-hooks.d.ts +10 -0
- package/dist/plugin-hooks.js +8 -0
- package/dist/plugin-runtime.d.ts +1 -0
- package/dist/plugin-runtime.js +30 -6
- package/dist/plugins-api.d.ts +1 -1
- package/dist/plugins-api.js +21 -11
- package/dist/records-api.d.ts +8 -8
- package/dist/records-api.js +35 -32
- package/dist/registry-context.d.ts +1 -1
- package/dist/registry-context.js +2 -2
- package/dist/schema-api.js +5 -5
- package/dist/settings-write.d.ts +19 -0
- package/dist/settings-write.js +60 -0
- package/dist/temporal.d.ts +3 -3
- package/dist/temporal.js +1 -1
- package/dist/thread-store.d.ts +20 -0
- package/dist/thread-store.js +27 -0
- package/dist/uploads.d.ts +1 -0
- package/dist/uploads.js +4 -0
- package/package.json +6 -6
package/dist/plugins-api.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { join } from 'node:path';
|
|
1
|
+
import { dirname, join, resolve, sep } from 'node:path';
|
|
2
2
|
import { createReadStream, existsSync, readFileSync } from 'node:fs';
|
|
3
3
|
import { discoverPluginAssets, discoverRuntime } from "./plugin-discovery.js";
|
|
4
4
|
import { getPlugins, readDisabled } from "./plugin-runtime.js";
|
|
@@ -16,7 +16,7 @@ export async function buildPluginListResponse(plugins, assets, disabled) {
|
|
|
16
16
|
packageName: a?.packageName ?? null,
|
|
17
17
|
dependsOn: p.dependsOn,
|
|
18
18
|
enabled: !disabled.has(p.id),
|
|
19
|
-
|
|
19
|
+
libraries: (p.libraries ?? []).map((v) => v.meta.id),
|
|
20
20
|
extends: (p.extends_ ?? []).map((e) => e.id),
|
|
21
21
|
hasSettings: Boolean(p.settings && p.settings.fields.length > 0),
|
|
22
22
|
schema: a?.schema,
|
|
@@ -39,20 +39,30 @@ export async function registerPluginsApi(app) {
|
|
|
39
39
|
});
|
|
40
40
|
app.get('/plugins/:id/:file', async (req, reply) => {
|
|
41
41
|
const { id, file } = req.params;
|
|
42
|
-
const key = ASSET_KEY[file];
|
|
43
|
-
if (!key)
|
|
44
|
-
return reply.code(404).send({ error: 'unknown_asset' });
|
|
45
42
|
const rec = (await discoverPluginAssets()).find((a) => a.id === id);
|
|
46
43
|
if (!rec)
|
|
47
44
|
return reply.code(404).send({ error: 'unknown_plugin' });
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
const pkgDir = join(nmRoot(), rec.packageName);
|
|
46
|
+
const pkg = JSON.parse(readFileSync(join(pkgDir, 'package.json'), 'utf8'));
|
|
47
|
+
const key = ASSET_KEY[file];
|
|
48
|
+
let abs;
|
|
49
|
+
if (key) {
|
|
50
|
+
const rel = pkg.coffer?.[key];
|
|
51
|
+
if (!rel)
|
|
52
|
+
return reply.code(404).send({ error: 'asset_not_built' });
|
|
53
|
+
abs = join(pkgDir, rel);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if (!/^[\w.-]+\.(js|css)$/.test(file))
|
|
57
|
+
return reply.code(404).send({ error: 'unknown_asset' });
|
|
58
|
+
const distDir = resolve(pkgDir, dirname(pkg.coffer?.web ?? pkg.coffer?.schema ?? 'dist/web.js'));
|
|
59
|
+
abs = resolve(distDir, file);
|
|
60
|
+
if (abs !== distDir && !abs.startsWith(distDir + sep))
|
|
61
|
+
return reply.code(404).send({ error: 'unknown_asset' });
|
|
62
|
+
}
|
|
53
63
|
if (!existsSync(abs))
|
|
54
64
|
return reply.code(404).send({ error: 'asset_missing' });
|
|
55
|
-
reply.type(
|
|
65
|
+
reply.type(abs.endsWith('.css') ? 'text/css' : 'text/javascript');
|
|
56
66
|
return reply.send(createReadStream(abs));
|
|
57
67
|
});
|
|
58
68
|
}
|
package/dist/records-api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ShelfDef } from '@coffer-org/sdk/shelf';
|
|
2
2
|
export declare class UnknownTypeError extends Error {
|
|
3
3
|
}
|
|
4
4
|
export type RecordListQuery = {
|
|
@@ -7,13 +7,13 @@ export type RecordListQuery = {
|
|
|
7
7
|
[field: string]: string | number | undefined;
|
|
8
8
|
};
|
|
9
9
|
export declare function coerceFilter(v: string, column: string): unknown;
|
|
10
|
-
export declare function withExtends(record: Record<string, unknown>,
|
|
11
|
-
export declare function rowMatch(mdef:
|
|
10
|
+
export declare function withExtends(record: Record<string, unknown>, library: string, shelf: string): Promise<Record<string, unknown>>;
|
|
11
|
+
export declare function rowMatch(mdef: ShelfDef, row: Record<string, unknown>, tokens: string[]): {
|
|
12
12
|
score: number;
|
|
13
13
|
snippet: string;
|
|
14
14
|
} | null;
|
|
15
|
-
export declare function recordList(
|
|
16
|
-
export declare function recordGet(
|
|
17
|
-
export declare function recordCreate(
|
|
18
|
-
export declare function recordUpdate(
|
|
19
|
-
export declare function recordDelete(
|
|
15
|
+
export declare function recordList(library: string, type: string, query?: RecordListQuery): Promise<Record<string, unknown>[]>;
|
|
16
|
+
export declare function recordGet(library: string, type: string, id: number): Promise<Record<string, unknown> | null>;
|
|
17
|
+
export declare function recordCreate(library: string, type: string, body: unknown, actor?: string): Promise<Record<string, unknown>>;
|
|
18
|
+
export declare function recordUpdate(library: string, type: string, id: number, body: unknown, actor?: string): Promise<Record<string, unknown>>;
|
|
19
|
+
export declare function recordDelete(library: string, type: string, id: number, actor?: string): Promise<void>;
|
package/dist/records-api.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { fieldMap, textSearchKeys, titleKey, recordTitle } from '@coffer-org/sdk/
|
|
1
|
+
import { fieldMap, textSearchKeys, titleKey, recordTitle } from '@coffer-org/sdk/shelf';
|
|
2
2
|
import { tokenize, matchScoreFolded, foldText } from '@coffer-org/core/search';
|
|
3
3
|
import { serialize } from '@mikro-orm/core';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { getShelf, getExtendsFor } from "./registry-context.js";
|
|
5
|
+
import { shelfTableName } from "./entity-schema.js";
|
|
6
6
|
import { getExtendRecord } from "./extend-table.js";
|
|
7
7
|
import { getEm } from "./db.js";
|
|
8
8
|
import { decodeTemporal, dtStringToDate } from "./temporal.js";
|
|
9
|
-
import { splitBody, saveExtends, deleteExtends, validateExtends } from "./extend-io.js";
|
|
9
|
+
import { splitBody, saveExtends, deleteExtends, validateExtends, readExtends } from "./extend-io.js";
|
|
10
10
|
import { createRecord, updateRecord, getRecord, deleteRecord } from "./mutate.js";
|
|
11
11
|
export class UnknownTypeError extends Error {
|
|
12
12
|
}
|
|
13
|
-
function resolve(
|
|
14
|
-
const m =
|
|
13
|
+
function resolve(library, type) {
|
|
14
|
+
const m = getShelf(library, type);
|
|
15
15
|
if (!m)
|
|
16
|
-
throw new UnknownTypeError(`unknown_type ${
|
|
17
|
-
return { m, ename:
|
|
16
|
+
throw new UnknownTypeError(`unknown_type ${library}/${type}`);
|
|
17
|
+
return { m, ename: shelfTableName(m.library, m.shelf) };
|
|
18
18
|
}
|
|
19
19
|
export function coerceFilter(v, column) {
|
|
20
20
|
if (column === 'integer' || column === 'real') {
|
|
@@ -27,8 +27,8 @@ export function coerceFilter(v, column) {
|
|
|
27
27
|
return dtStringToDate(v);
|
|
28
28
|
return v;
|
|
29
29
|
}
|
|
30
|
-
export async function withExtends(record,
|
|
31
|
-
const matchedExtends = getExtendsFor(
|
|
30
|
+
export async function withExtends(record, library, shelf) {
|
|
31
|
+
const matchedExtends = getExtendsFor(library, shelf);
|
|
32
32
|
if (!matchedExtends.length)
|
|
33
33
|
return record;
|
|
34
34
|
const _extends = {};
|
|
@@ -54,8 +54,8 @@ export function rowMatch(mdef, row, tokens) {
|
|
|
54
54
|
const snippet = raw.length > 120 ? raw.slice(0, 120) + '…' : raw;
|
|
55
55
|
return { score, snippet };
|
|
56
56
|
}
|
|
57
|
-
export async function recordList(
|
|
58
|
-
const { m, ename } = resolve(
|
|
57
|
+
export async function recordList(library, type, query = {}) {
|
|
58
|
+
const { m, ename } = resolve(library, type);
|
|
59
59
|
const { q, ...filterParams } = query;
|
|
60
60
|
const where = {};
|
|
61
61
|
const fm = fieldMap(m.fields);
|
|
@@ -82,35 +82,38 @@ export async function recordList(vault, type, query = {}) {
|
|
|
82
82
|
if (tokens.length > 0)
|
|
83
83
|
rows = rows.filter((row) => rowMatch(m, row, tokens) !== null);
|
|
84
84
|
const decoded = rows.map((r) => decodeTemporal(m, r));
|
|
85
|
-
return Promise.all(decoded.map((row) => withExtends(row,
|
|
85
|
+
return Promise.all(decoded.map((row) => withExtends(row, library, type)));
|
|
86
86
|
}
|
|
87
|
-
export async function recordGet(
|
|
88
|
-
const { m, ename } = resolve(
|
|
87
|
+
export async function recordGet(library, type, id) {
|
|
88
|
+
const { m, ename } = resolve(library, type);
|
|
89
89
|
if (m.standalone === false)
|
|
90
90
|
return null;
|
|
91
91
|
const row = await getRecord(m, ename, id);
|
|
92
92
|
if (!row)
|
|
93
93
|
return null;
|
|
94
|
-
return withExtends(row,
|
|
94
|
+
return withExtends(row, library, type);
|
|
95
95
|
}
|
|
96
|
-
export async function recordCreate(
|
|
97
|
-
const { m, ename } = resolve(
|
|
96
|
+
export async function recordCreate(library, type, body, actor = 'gui') {
|
|
97
|
+
const { m, ename } = resolve(library, type);
|
|
98
98
|
const { base, extData } = splitBody(body);
|
|
99
|
-
validateExtends(
|
|
100
|
-
const row = await createRecord(m, ename, base, { actor })
|
|
101
|
-
|
|
102
|
-
|
|
99
|
+
validateExtends(library, type, extData);
|
|
100
|
+
const row = await createRecord(m, ename, base, { actor }, async (tx, id) => {
|
|
101
|
+
await saveExtends(tx, library, type, id, extData);
|
|
102
|
+
return readExtends(tx, library, type, id);
|
|
103
|
+
});
|
|
104
|
+
return withExtends(row, library, type);
|
|
103
105
|
}
|
|
104
|
-
export async function recordUpdate(
|
|
105
|
-
const { m, ename } = resolve(
|
|
106
|
+
export async function recordUpdate(library, type, id, body, actor = 'gui') {
|
|
107
|
+
const { m, ename } = resolve(library, type);
|
|
106
108
|
const { base, extData } = splitBody(body);
|
|
107
|
-
validateExtends(
|
|
108
|
-
const row = await updateRecord(m, ename, id, base, { actor })
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
validateExtends(library, type, extData);
|
|
110
|
+
const row = await updateRecord(m, ename, id, base, { actor }, async (tx) => {
|
|
111
|
+
await saveExtends(tx, library, type, id, extData);
|
|
112
|
+
return readExtends(tx, library, type, id);
|
|
113
|
+
});
|
|
114
|
+
return withExtends(row, library, type);
|
|
111
115
|
}
|
|
112
|
-
export async function recordDelete(
|
|
113
|
-
const { m, ename } = resolve(
|
|
114
|
-
await deleteRecord(m, ename, id, { actor });
|
|
115
|
-
await deleteExtends(vault, type, id);
|
|
116
|
+
export async function recordDelete(library, type, id, actor = 'gui') {
|
|
117
|
+
const { m, ename } = resolve(library, type);
|
|
118
|
+
await deleteRecord(m, ename, id, { actor }, (tx) => deleteExtends(tx, library, type, id));
|
|
116
119
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Registry } from '@coffer-org/core/compose';
|
|
2
2
|
export declare function setActiveRegistry(reg: Registry): void;
|
|
3
3
|
export declare function getActiveRegistry(): Registry;
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const getShelf: Registry['getShelf'];
|
|
5
5
|
export declare const getExtendsFor: Registry['getExtendsFor'];
|
package/dist/registry-context.js
CHANGED
|
@@ -10,5 +10,5 @@ function current() {
|
|
|
10
10
|
export function getActiveRegistry() {
|
|
11
11
|
return current();
|
|
12
12
|
}
|
|
13
|
-
export const
|
|
14
|
-
export const getExtendsFor = (
|
|
13
|
+
export const getShelf = (library, shelf) => current().getShelf(library, shelf);
|
|
14
|
+
export const getExtendsFor = (library, shelf) => current().getExtendsFor(library, shelf);
|
package/dist/schema-api.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { shelfToClient } from '@coffer-org/sdk/shelf';
|
|
2
2
|
import { extendToClient } from '@coffer-org/sdk/extend';
|
|
3
3
|
import { getActiveRegistry } from "./registry-context.js";
|
|
4
4
|
export function buildClientSchema() {
|
|
5
|
-
const {
|
|
6
|
-
return
|
|
5
|
+
const { libraries, extends_ } = getActiveRegistry();
|
|
6
|
+
return libraries.map((v) => ({
|
|
7
7
|
...v.meta,
|
|
8
|
-
|
|
9
|
-
extends: extends_.filter((e) => e.attachTo.some((r) => r.
|
|
8
|
+
shelves: v.shelves.map(shelfToClient),
|
|
9
|
+
extends: extends_.filter((e) => e.attachTo.some((r) => r.library === v.meta.id)).map(extendToClient),
|
|
10
10
|
}));
|
|
11
11
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { LayoutEl } from '@coffer-org/sdk/fields';
|
|
2
|
+
import type { EntityManager } from '@mikro-orm/core';
|
|
3
|
+
import type { PluginManifest } from '@coffer-org/sdk/plugin';
|
|
4
|
+
export interface SettingsFieldInfo {
|
|
5
|
+
key: string;
|
|
6
|
+
kind: string;
|
|
7
|
+
label?: string;
|
|
8
|
+
required: boolean;
|
|
9
|
+
options?: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare function describeSettingsFields(fields: LayoutEl[]): SettingsFieldInfo[];
|
|
12
|
+
export declare function buildSettingsBody(pluginId: string, fields: LayoutEl[], incoming: Record<string, unknown>, existing: Record<string, unknown>): Record<string, unknown>;
|
|
13
|
+
export declare function writePluginSettings(em: EntityManager, pluginId: string, incoming: Record<string, unknown>, actor: string, plugins?: PluginManifest[]): Promise<Record<string, unknown>>;
|
|
14
|
+
export declare function listSettings(plugins?: PluginManifest[]): Promise<{
|
|
15
|
+
plugin: string;
|
|
16
|
+
label: string;
|
|
17
|
+
fields: SettingsFieldInfo[];
|
|
18
|
+
values: Record<string, unknown>;
|
|
19
|
+
}[]>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { fieldEntries, buildZodObject } from '@coffer-org/sdk/shelf';
|
|
2
|
+
import { preserveTree, maskTree } from "./field-masking.js";
|
|
3
|
+
import { ValidationError, NotFoundError, toIssue } from "./mutate.js";
|
|
4
|
+
import { getPlugins, getPluginSettings } from "./plugin-runtime.js";
|
|
5
|
+
export function describeSettingsFields(fields) {
|
|
6
|
+
return fieldEntries(fields).map(([key, f]) => ({
|
|
7
|
+
key,
|
|
8
|
+
kind: f.kind,
|
|
9
|
+
label: f.label,
|
|
10
|
+
required: f.required === true,
|
|
11
|
+
...(f.options ? { options: f.options.map((o) => o.value) } : {}),
|
|
12
|
+
}));
|
|
13
|
+
}
|
|
14
|
+
function settingsShelf(pluginId, fields) {
|
|
15
|
+
return { library: '_settings', shelf: pluginId, label: `${pluginId}.plugin.label`, fields };
|
|
16
|
+
}
|
|
17
|
+
export function buildSettingsBody(pluginId, fields, incoming, existing) {
|
|
18
|
+
const body = preserveTree(fields, incoming, existing);
|
|
19
|
+
const parsed = buildZodObject(settingsShelf(pluginId, fields)).safeParse(body);
|
|
20
|
+
if (!parsed.success)
|
|
21
|
+
throw new ValidationError(parsed.error.issues.map(toIssue));
|
|
22
|
+
return parsed.data;
|
|
23
|
+
}
|
|
24
|
+
function withSettings(plugins) {
|
|
25
|
+
return plugins.filter((p) => p.settings && p.settings.fields.length > 0);
|
|
26
|
+
}
|
|
27
|
+
export async function writePluginSettings(em, pluginId, incoming, actor, plugins) {
|
|
28
|
+
const all = plugins ?? (await getPlugins());
|
|
29
|
+
const p = all.find((x) => x.id === pluginId);
|
|
30
|
+
if (!p || !p.settings || p.settings.fields.length === 0) {
|
|
31
|
+
throw new NotFoundError();
|
|
32
|
+
}
|
|
33
|
+
const fields = p.settings.fields;
|
|
34
|
+
const existing = await getPluginSettings(pluginId);
|
|
35
|
+
const data = buildSettingsBody(pluginId, fields, incoming, existing);
|
|
36
|
+
const row = { plugin_id: pluginId, ...data };
|
|
37
|
+
await em.upsert(`_settings__${pluginId}`, row);
|
|
38
|
+
const masked = maskTree(fields, row);
|
|
39
|
+
em.create('_Event', {
|
|
40
|
+
ts: new Date().toISOString(),
|
|
41
|
+
actor,
|
|
42
|
+
op: 'settings',
|
|
43
|
+
type: pluginId,
|
|
44
|
+
record_id: null,
|
|
45
|
+
before: JSON.stringify(maskTree(fields, existing)),
|
|
46
|
+
after: JSON.stringify(masked),
|
|
47
|
+
});
|
|
48
|
+
await em.flush();
|
|
49
|
+
return masked;
|
|
50
|
+
}
|
|
51
|
+
export async function listSettings(plugins) {
|
|
52
|
+
const all = withSettings(plugins ?? (await getPlugins()));
|
|
53
|
+
const out = [];
|
|
54
|
+
for (const p of all) {
|
|
55
|
+
const fields = p.settings.fields;
|
|
56
|
+
const values = maskTree(fields, await getPluginSettings(p.id));
|
|
57
|
+
out.push({ plugin: p.id, label: p.settings.label, fields: describeSettingsFields(fields), values });
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
package/dist/temporal.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ShelfDef } from '@coffer-org/sdk/shelf';
|
|
2
2
|
export declare function dtStringToDate(s: string): Date;
|
|
3
3
|
export declare function dateToDtString(d: Date): string;
|
|
4
|
-
export declare function encodeTemporal(m:
|
|
5
|
-
export declare function decodeTemporal(m:
|
|
4
|
+
export declare function encodeTemporal(m: ShelfDef, row: Record<string, unknown>): Record<string, unknown>;
|
|
5
|
+
export declare function decodeTemporal(m: ShelfDef, row: Record<string, unknown>): Record<string, unknown>;
|
package/dist/temporal.js
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface StoredMsg {
|
|
2
|
+
msgId: string;
|
|
3
|
+
role: 'user' | 'assistant';
|
|
4
|
+
sender: string | null;
|
|
5
|
+
text: string;
|
|
6
|
+
ts: number;
|
|
7
|
+
replyToId: string | null;
|
|
8
|
+
}
|
|
9
|
+
export declare function getThreadMessage(connector: string, chatId: string, msgId: string): Promise<StoredMsg | null>;
|
|
10
|
+
export declare function putThreadMessage(m: {
|
|
11
|
+
connector: string;
|
|
12
|
+
chatId: string;
|
|
13
|
+
msgId: string;
|
|
14
|
+
role: 'user' | 'assistant';
|
|
15
|
+
sender?: string | null;
|
|
16
|
+
text: string;
|
|
17
|
+
ts: number;
|
|
18
|
+
replyToId: string | null;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
export declare function pruneThreadMessages(connector: string, cutoffTs: number): Promise<void>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getEm } from "./db.js";
|
|
2
|
+
function toStored(r) {
|
|
3
|
+
return { msgId: r.msg_id, role: r.role, sender: r.sender, text: r.text, ts: r.ts, replyToId: r.reply_to_id };
|
|
4
|
+
}
|
|
5
|
+
export async function getThreadMessage(connector, chatId, msgId) {
|
|
6
|
+
const em = getEm().fork();
|
|
7
|
+
const row = (await em.findOne('_ThreadMessage', { connector, chat_id: chatId, msg_id: msgId }));
|
|
8
|
+
return row ? toStored(row) : null;
|
|
9
|
+
}
|
|
10
|
+
export async function putThreadMessage(m) {
|
|
11
|
+
const em = getEm().fork();
|
|
12
|
+
await em.upsert('_ThreadMessage', {
|
|
13
|
+
connector: m.connector,
|
|
14
|
+
chat_id: m.chatId,
|
|
15
|
+
msg_id: m.msgId,
|
|
16
|
+
role: m.role,
|
|
17
|
+
sender: m.sender ?? null,
|
|
18
|
+
text: m.text,
|
|
19
|
+
ts: m.ts,
|
|
20
|
+
reply_to_id: m.replyToId,
|
|
21
|
+
});
|
|
22
|
+
await em.flush();
|
|
23
|
+
}
|
|
24
|
+
export async function pruneThreadMessages(connector, cutoffTs) {
|
|
25
|
+
const em = getEm().fork();
|
|
26
|
+
await em.nativeDelete('_ThreadMessage', { connector, ts: { $lt: cutoffTs } });
|
|
27
|
+
}
|
package/dist/uploads.d.ts
CHANGED
package/dist/uploads.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { copyFileSync, mkdirSync } from 'node:fs';
|
|
2
2
|
import { basename, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
3
4
|
export function uploadsDir() {
|
|
4
5
|
const dir = process.env.UPLOADS ?? join(process.cwd(), 'data', 'uploads');
|
|
5
6
|
mkdirSync(dir, { recursive: true });
|
|
@@ -10,3 +11,6 @@ export function seedAsset(absPath) {
|
|
|
10
11
|
copyFileSync(absPath, join(uploadsDir(), name));
|
|
11
12
|
return { name };
|
|
12
13
|
}
|
|
14
|
+
export function seedAssetPath(metaUrl) {
|
|
15
|
+
return (rel) => fileURLToPath(new URL(`../../seed/assets/${rel}`, metaUrl));
|
|
16
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coffer-org/server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=24"
|
|
@@ -24,14 +24,14 @@
|
|
|
24
24
|
"postpack": "node ../../scripts/swap-exports.mjs src"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@coffer-org/core": "^1.
|
|
28
|
-
"@coffer-org/sdk": "^1.
|
|
27
|
+
"@coffer-org/core": "^1.4.0",
|
|
28
|
+
"@coffer-org/sdk": "^1.5.0",
|
|
29
29
|
"@extractus/oembed-extractor": "^4.1.0",
|
|
30
30
|
"@fastify/cors": "^11.2.0",
|
|
31
31
|
"@fastify/multipart": "^10.0.0",
|
|
32
32
|
"@fastify/static": "^9.1.3",
|
|
33
|
-
"@mikro-orm/core": "^7.1.
|
|
34
|
-
"@mikro-orm/sqlite": "^7.1.
|
|
33
|
+
"@mikro-orm/core": "^7.1.6",
|
|
34
|
+
"@mikro-orm/sqlite": "^7.1.6",
|
|
35
35
|
"fastify": "^5.2.1",
|
|
36
36
|
"open-graph-scraper": "^6.11.0",
|
|
37
37
|
"pino": "^9.14.0",
|
|
@@ -39,6 +39,6 @@
|
|
|
39
39
|
"zod": "^4.4.3"
|
|
40
40
|
},
|
|
41
41
|
"optionalDependencies": {
|
|
42
|
-
"@mikro-orm/postgresql": "7.1.
|
|
42
|
+
"@mikro-orm/postgresql": "^7.1.6"
|
|
43
43
|
}
|
|
44
44
|
}
|