@ikenga/mcp-meetings 0.1.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/LICENSE +201 -0
- package/dist/index.d.ts +132 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +97 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +72 -0
- package/dist/index.test.js.map +1 -0
- package/dist/integration.test.d.ts +2 -0
- package/dist/integration.test.d.ts.map +1 -0
- package/dist/integration.test.js +181 -0
- package/dist/integration.test.js.map +1 -0
- package/dist/sqlite.d.ts +49 -0
- package/dist/sqlite.d.ts.map +1 -0
- package/dist/sqlite.js +303 -0
- package/dist/sqlite.js.map +1 -0
- package/dist/sqlite.test.d.ts +2 -0
- package/dist/sqlite.test.d.ts.map +1 -0
- package/dist/sqlite.test.js +36 -0
- package/dist/sqlite.test.js.map +1 -0
- package/dist/tools/recorder.d.ts +94 -0
- package/dist/tools/recorder.d.ts.map +1 -0
- package/dist/tools/recorder.js +187 -0
- package/dist/tools/recorder.js.map +1 -0
- package/dist/tools/recorder.test.d.ts +2 -0
- package/dist/tools/recorder.test.d.ts.map +1 -0
- package/dist/tools/recorder.test.js +94 -0
- package/dist/tools/recorder.test.js.map +1 -0
- package/dist/tools/search.d.ts +35 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +112 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/search.test.d.ts +2 -0
- package/dist/tools/search.test.d.ts.map +1 -0
- package/dist/tools/search.test.js +116 -0
- package/dist/tools/search.test.js.map +1 -0
- package/manifest.json +39 -0
- package/package.json +38 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { describe, it, before, after } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import os from 'node:os';
|
|
6
|
+
import crypto from 'node:crypto';
|
|
7
|
+
import { MeetingsDbClient } from '@ikenga/meetings-contract';
|
|
8
|
+
import { BetterSqliteExecutor } from './sqlite.js';
|
|
9
|
+
import { handleSearchTool } from './tools/search.js';
|
|
10
|
+
import { handleRecorderTool } from './tools/recorder.js';
|
|
11
|
+
describe('MCP Meetings Real SQLite Integration Test', () => {
|
|
12
|
+
let tmpDbPath;
|
|
13
|
+
let executor;
|
|
14
|
+
let client;
|
|
15
|
+
const meetingId = '7b053bb1-29a3-4e07-bfc5-3c4e40d08033';
|
|
16
|
+
const speaker1Id = '8c053bb1-29a3-4e07-bfc5-3c4e40d08034';
|
|
17
|
+
const speaker2Id = '9d053bb1-29a3-4e07-bfc5-3c4e40d08035';
|
|
18
|
+
const transcript1Id = 'ae053bb1-29a3-4e07-bfc5-3c4e40d08036';
|
|
19
|
+
const transcript2Id = 'bf053bb1-29a3-4e07-bfc5-3c4e40d08037';
|
|
20
|
+
const summaryId = 'd1053bb1-29a3-4e07-bfc5-3c4e40d08039';
|
|
21
|
+
before(async () => {
|
|
22
|
+
tmpDbPath = path.join(os.tmpdir(), `test-meetings-${Date.now()}-${crypto.randomBytes(4).toString('hex')}.db`);
|
|
23
|
+
executor = new BetterSqliteExecutor(tmpDbPath);
|
|
24
|
+
client = new MeetingsDbClient(executor);
|
|
25
|
+
// Insert meeting row with nullable columns explicitly NULL in SQLite
|
|
26
|
+
await executor.exec(`
|
|
27
|
+
INSERT INTO meetings (
|
|
28
|
+
id, title, platform, url, status, start_time, end_time, duration_seconds, video_path, audio_path, created_at, updated_at
|
|
29
|
+
) VALUES (
|
|
30
|
+
'${meetingId}',
|
|
31
|
+
'test meeting 1',
|
|
32
|
+
'google_meet',
|
|
33
|
+
'https://meet.google.com/test-abc-xyz',
|
|
34
|
+
'completed',
|
|
35
|
+
'2026-09-02T10:00:00.000Z',
|
|
36
|
+
'2026-09-02T10:45:00.000Z',
|
|
37
|
+
2700,
|
|
38
|
+
NULL,
|
|
39
|
+
NULL,
|
|
40
|
+
'2026-09-02T09:55:00.000Z',
|
|
41
|
+
'2026-09-02T10:46:00.000Z'
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
INSERT INTO meeting_speakers (
|
|
45
|
+
id, meeting_id, name, avatar_url, contact_id, speaker_source
|
|
46
|
+
) VALUES (
|
|
47
|
+
'${speaker1Id}',
|
|
48
|
+
'${meetingId}',
|
|
49
|
+
'Speaker 1',
|
|
50
|
+
NULL,
|
|
51
|
+
NULL,
|
|
52
|
+
'dom_cue'
|
|
53
|
+
), (
|
|
54
|
+
'${speaker2Id}',
|
|
55
|
+
'${meetingId}',
|
|
56
|
+
'Speaker 2',
|
|
57
|
+
NULL,
|
|
58
|
+
NULL,
|
|
59
|
+
'audio_embedding'
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
INSERT INTO meeting_transcripts (
|
|
63
|
+
id, meeting_id, speaker_id, speaker_name, speaker_source, start_ms, end_ms, text, confidence, words_json
|
|
64
|
+
) VALUES (
|
|
65
|
+
'${transcript1Id}',
|
|
66
|
+
'${meetingId}',
|
|
67
|
+
'${speaker1Id}',
|
|
68
|
+
'Speaker 1',
|
|
69
|
+
'dom_cue',
|
|
70
|
+
0,
|
|
71
|
+
4500,
|
|
72
|
+
'test transcript segment alpha with sample search target phrase',
|
|
73
|
+
0.98,
|
|
74
|
+
NULL
|
|
75
|
+
), (
|
|
76
|
+
'${transcript2Id}',
|
|
77
|
+
'${meetingId}',
|
|
78
|
+
'${speaker2Id}',
|
|
79
|
+
'Speaker 2',
|
|
80
|
+
'audio_embedding',
|
|
81
|
+
5000,
|
|
82
|
+
10200,
|
|
83
|
+
'test transcript segment beta with target phrase and additional details',
|
|
84
|
+
0.99,
|
|
85
|
+
NULL
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
INSERT INTO meeting_summaries (
|
|
89
|
+
id, meeting_id, executive_summary, key_decisions_json, topics_json, created_at
|
|
90
|
+
) VALUES (
|
|
91
|
+
'${summaryId}',
|
|
92
|
+
'${meetingId}',
|
|
93
|
+
'test executive summary lorem ipsum for test meeting 1',
|
|
94
|
+
'["test decision 1", "test decision 2"]',
|
|
95
|
+
'["topic 1", "topic 2"]',
|
|
96
|
+
NULL
|
|
97
|
+
);
|
|
98
|
+
`);
|
|
99
|
+
});
|
|
100
|
+
after(() => {
|
|
101
|
+
executor.close();
|
|
102
|
+
if (fs.existsSync(tmpDbPath)) {
|
|
103
|
+
try {
|
|
104
|
+
fs.unlinkSync(tmpDbPath);
|
|
105
|
+
}
|
|
106
|
+
catch { }
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
it('searches transcripts across meeting 7b053bb1-29a3-4e07-bfc5-3c4e40d08033 with real SQLite', async () => {
|
|
110
|
+
const res = await handleSearchTool(client, 'search_transcripts', {
|
|
111
|
+
query: 'target phrase',
|
|
112
|
+
meeting_id: meetingId,
|
|
113
|
+
});
|
|
114
|
+
assert.equal(res.count, 2);
|
|
115
|
+
assert.equal(res.segments.length, 2);
|
|
116
|
+
assert.equal(res.segments[0]?.speaker, 'Speaker 1');
|
|
117
|
+
assert.equal(res.segments[0]?.start_ms, 0);
|
|
118
|
+
assert.equal(res.segments[1]?.speaker, 'Speaker 2');
|
|
119
|
+
assert.equal(res.segments[1]?.start_ms, 5000);
|
|
120
|
+
assert.ok(res.segments[1]?.text.includes('target phrase'));
|
|
121
|
+
});
|
|
122
|
+
it('retrieves full meeting transcript and speakers for meeting 7b053bb1-29a3-4e07-bfc5-3c4e40d08033', async () => {
|
|
123
|
+
const res = await handleSearchTool(client, 'get_meeting_transcript', {
|
|
124
|
+
meeting_id: meetingId,
|
|
125
|
+
});
|
|
126
|
+
assert.equal(res.meeting_id, meetingId);
|
|
127
|
+
assert.equal(res.segment_count, 2);
|
|
128
|
+
assert.equal(res.speakers.length, 2);
|
|
129
|
+
assert.equal(res.speakers[0]?.name, 'Speaker 1');
|
|
130
|
+
assert.equal(res.speakers[1]?.name, 'Speaker 2');
|
|
131
|
+
});
|
|
132
|
+
it('retrieves meeting summary without failing on SQLite NULL created_at', async () => {
|
|
133
|
+
const res = await handleSearchTool(client, 'get_meeting_summary', {
|
|
134
|
+
meeting_id: meetingId,
|
|
135
|
+
});
|
|
136
|
+
assert.equal(res.found, true);
|
|
137
|
+
assert.equal(res.meeting_id, meetingId);
|
|
138
|
+
assert.ok(res.executive_summary.includes('test executive summary'));
|
|
139
|
+
assert.equal(res.key_decisions.length, 2);
|
|
140
|
+
assert.deepEqual(res.key_decisions, [
|
|
141
|
+
'test decision 1',
|
|
142
|
+
'test decision 2',
|
|
143
|
+
]);
|
|
144
|
+
});
|
|
145
|
+
it('records and updates meetings via recorder tools in SQLite', async () => {
|
|
146
|
+
// 1. Start recording
|
|
147
|
+
const startRes = await handleRecorderTool(client, 'start_recording', {
|
|
148
|
+
title: 'test recording 2',
|
|
149
|
+
});
|
|
150
|
+
assert.equal(startRes.ok, true);
|
|
151
|
+
assert.equal(startRes.status, 'recording');
|
|
152
|
+
const newId = startRes.meeting_id;
|
|
153
|
+
assert.ok(newId);
|
|
154
|
+
// 2. Stop recording
|
|
155
|
+
const stopRes = await handleRecorderTool(client, 'stop_recording', {
|
|
156
|
+
meeting_id: newId,
|
|
157
|
+
});
|
|
158
|
+
assert.equal(stopRes.ok, true);
|
|
159
|
+
assert.equal(stopRes.status, 'completed');
|
|
160
|
+
// 3. Schedule recording
|
|
161
|
+
const schedRes = await handleRecorderTool(client, 'schedule_recording', {
|
|
162
|
+
title: 'test scheduled meeting 3',
|
|
163
|
+
start_time: '2026-09-10T14:00:00.000Z',
|
|
164
|
+
platform: 'google_meet',
|
|
165
|
+
url: 'https://meet.google.com/test-link',
|
|
166
|
+
});
|
|
167
|
+
assert.equal(schedRes.ok, true);
|
|
168
|
+
assert.equal(schedRes.status, 'scheduled');
|
|
169
|
+
assert.equal(schedRes.title, 'test scheduled meeting 3');
|
|
170
|
+
// 4. List meetings
|
|
171
|
+
const listRes = await handleRecorderTool(client, 'list_meetings', {
|
|
172
|
+
limit: 10,
|
|
173
|
+
});
|
|
174
|
+
assert.ok(listRes.count >= 3);
|
|
175
|
+
const titles = listRes.meetings.map((m) => m.title);
|
|
176
|
+
assert.ok(titles.includes('test meeting 1'));
|
|
177
|
+
assert.ok(titles.includes('test recording 2'));
|
|
178
|
+
assert.ok(titles.includes('test scheduled meeting 3'));
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
//# sourceMappingURL=integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../src/integration.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,QAAQ,CAAC,2CAA2C,EAAE,GAAG,EAAE;IACzD,IAAI,SAAiB,CAAC;IACtB,IAAI,QAA8B,CAAC;IACnC,IAAI,MAAwB,CAAC;IAE7B,MAAM,SAAS,GAAG,sCAAsC,CAAC;IACzD,MAAM,UAAU,GAAG,sCAAsC,CAAC;IAC1D,MAAM,UAAU,GAAG,sCAAsC,CAAC;IAC1D,MAAM,aAAa,GAAG,sCAAsC,CAAC;IAC7D,MAAM,aAAa,GAAG,sCAAsC,CAAC;IAC7D,MAAM,SAAS,GAAG,sCAAsC,CAAC;IAEzD,MAAM,CAAC,KAAK,IAAI,EAAE;QAChB,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,iBAAiB,IAAI,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9G,QAAQ,GAAG,IAAI,oBAAoB,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,GAAG,IAAI,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAExC,qEAAqE;QACrE,MAAM,QAAQ,CAAC,IAAI,CAAC;;;;WAIb,SAAS;;;;;;;;;;;;;;;;;WAiBT,UAAU;WACV,SAAS;;;;;;WAMT,UAAU;WACV,SAAS;;;;;;;;;;WAUT,aAAa;WACb,SAAS;WACT,UAAU;;;;;;;;;WASV,aAAa;WACb,SAAS;WACT,UAAU;;;;;;;;;;;;;WAaV,SAAS;WACT,SAAS;;;;;;KAMf,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,GAAG,EAAE;QACT,QAAQ,CAAC,KAAK,EAAE,CAAC;QACjB,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;YAC3B,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2FAA2F,EAAE,KAAK,IAAI,EAAE;QACzG,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,oBAAoB,EAAE;YAC/D,KAAK,EAAE,eAAe;YACtB,UAAU,EAAE,SAAS;SACtB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC9C,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iGAAiG,EAAE,KAAK,IAAI,EAAE;QAC/G,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,wBAAwB,EAAE;YACnE,UAAU,EAAE,SAAS;SACtB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACrC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,KAAK,IAAI,EAAE;QACnF,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,qBAAqB,EAAE;YAChE,UAAU,EAAE,SAAS;SACtB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC9B,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACxC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,iBAAiB,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC,CAAC;QACpE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,aAAa,EAAE;YAClC,iBAAiB;YACjB,iBAAiB;SAClB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,qBAAqB;QACrB,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,EAAE;YACnE,KAAK,EAAE,kBAAkB;SAC1B,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC;QAClC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QAEjB,oBAAoB;QACpB,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,EAAE;YACjE,UAAU,EAAE,KAAK;SAClB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAE1C,wBAAwB;QACxB,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,oBAAoB,EAAE;YACtE,KAAK,EAAE,0BAA0B;YACjC,UAAU,EAAE,0BAA0B;YACtC,QAAQ,EAAE,aAAa;YACvB,GAAG,EAAE,mCAAmC;SACzC,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,0BAA0B,CAAC,CAAC;QAEzD,mBAAmB;QACnB,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,eAAe,EAAE;YAChE,KAAK,EAAE,EAAE;SACV,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;QAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACzD,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/sqlite.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import { SqlExecutor } from '@ikenga/meetings-contract';
|
|
3
|
+
export declare function resolveDatabasePath(customPath?: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* Normalizes SQLite rows: converts `null` values to `undefined` so that
|
|
6
|
+
* Zod schemas with `.optional()` parse without throwing invalid_type errors.
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeRow<T>(row: any): T;
|
|
9
|
+
/**
|
|
10
|
+
* The tables this pkg is allowed to touch.
|
|
11
|
+
*
|
|
12
|
+
* Mirrors `permissions["sqlite.tables"]` in the com.ikenga.meetings manifest.
|
|
13
|
+
* That manifest scope is enforced by the shell for the IFRAME path
|
|
14
|
+
* (`host.dbQuery` / `host.dbExec` check it in pkg-iframe-host.tsx) — but a pkg's
|
|
15
|
+
* BACKEND process has no scoped accessor available to it, so opening the
|
|
16
|
+
* database with better-sqlite3 means holding a connection with full read/write
|
|
17
|
+
* over every table in `ikenga.db`: tasks, email, finance, everything.
|
|
18
|
+
*
|
|
19
|
+
* That is a real widening of trust and it should not be incidental. This guard
|
|
20
|
+
* re-imposes the manifest scope in code, so a bug — or a prompt injection
|
|
21
|
+
* reaching a tool argument — cannot reach beyond the meetings domain. It is not
|
|
22
|
+
* a substitute for host-side enforcement; it is the best a pkg can do for itself
|
|
23
|
+
* until a scoped backend accessor exists.
|
|
24
|
+
*/
|
|
25
|
+
export declare const ALLOWED_TABLES: readonly ["meetings", "meeting_speakers", "meeting_transcripts", "meeting_action_items", "meeting_summaries"];
|
|
26
|
+
/** Every table name a statement references, lowercased. */
|
|
27
|
+
export declare function tablesReferenced(sql: string): string[];
|
|
28
|
+
/** Throw unless every table a statement touches is in the pkg's scope. */
|
|
29
|
+
export declare function assertInScope(sql: string): void;
|
|
30
|
+
export declare class BetterSqliteExecutor implements SqlExecutor {
|
|
31
|
+
readonly db: Database.Database;
|
|
32
|
+
/** True only for a database this pkg created for itself (tests). */
|
|
33
|
+
private readonly ownsSchema;
|
|
34
|
+
constructor(dbPathOrInstance?: string | Database.Database);
|
|
35
|
+
private initSchema;
|
|
36
|
+
query<T = unknown>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
37
|
+
exec(sql: string, params?: unknown[]): Promise<void | unknown>;
|
|
38
|
+
close(): void;
|
|
39
|
+
}
|
|
40
|
+
export declare class InMemorySqlExecutor implements SqlExecutor {
|
|
41
|
+
private meetingsMap;
|
|
42
|
+
private transcriptsMap;
|
|
43
|
+
private speakersMap;
|
|
44
|
+
private summariesMap;
|
|
45
|
+
private actionsMap;
|
|
46
|
+
query<T = unknown>(sql: string, params?: unknown[]): Promise<T[]>;
|
|
47
|
+
exec(sql: string, params?: unknown[]): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAItC,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,wBAAgB,mBAAmB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAiB/D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,CAa3C;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,+GAMjB,CAAC;AAEX,2DAA2D;AAC3D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAQtD;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAS/C;AAED,qBAAa,oBAAqB,YAAW,WAAW;IACtD,SAAgB,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;IACtC,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;gBAEzB,gBAAgB,GAAE,MAAM,GAAG,QAAQ,CAAC,QAAgC;IAyChF,OAAO,CAAC,UAAU;IAoEZ,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAOrE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC;IASxE,KAAK,IAAI,IAAI;CAGd;AAED,qBAAa,mBAAoB,YAAW,WAAW;IACrD,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,UAAU,CAA4B;IAExC,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAgCrE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,OAAO,EAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAsC/D"}
|
package/dist/sqlite.js
ADDED
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
export function resolveDatabasePath(customPath) {
|
|
6
|
+
if (customPath)
|
|
7
|
+
return customPath;
|
|
8
|
+
if (process.env.IKENGA_DB)
|
|
9
|
+
return process.env.IKENGA_DB;
|
|
10
|
+
if (process.env.SQLITE_PATH)
|
|
11
|
+
return process.env.SQLITE_PATH;
|
|
12
|
+
if (process.env.MEETINGS_DB_PATH)
|
|
13
|
+
return process.env.MEETINGS_DB_PATH;
|
|
14
|
+
const localSharePath = path.join(os.homedir(), '.local/share/app.ikenga/ikenga.db');
|
|
15
|
+
if (fs.existsSync(localSharePath)) {
|
|
16
|
+
return localSharePath;
|
|
17
|
+
}
|
|
18
|
+
const dotIkengaPath = path.join(os.homedir(), '.ikenga/ikenga.db');
|
|
19
|
+
if (fs.existsSync(dotIkengaPath)) {
|
|
20
|
+
return dotIkengaPath;
|
|
21
|
+
}
|
|
22
|
+
return localSharePath;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Normalizes SQLite rows: converts `null` values to `undefined` so that
|
|
26
|
+
* Zod schemas with `.optional()` parse without throwing invalid_type errors.
|
|
27
|
+
*/
|
|
28
|
+
export function normalizeRow(row) {
|
|
29
|
+
if (!row || typeof row !== 'object')
|
|
30
|
+
return row;
|
|
31
|
+
const out = Array.isArray(row) ? [] : {};
|
|
32
|
+
for (const [k, v] of Object.entries(row)) {
|
|
33
|
+
if (v === null) {
|
|
34
|
+
out[k] = undefined;
|
|
35
|
+
}
|
|
36
|
+
else if (typeof v === 'object') {
|
|
37
|
+
out[k] = normalizeRow(v);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
out[k] = v;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The tables this pkg is allowed to touch.
|
|
47
|
+
*
|
|
48
|
+
* Mirrors `permissions["sqlite.tables"]` in the com.ikenga.meetings manifest.
|
|
49
|
+
* That manifest scope is enforced by the shell for the IFRAME path
|
|
50
|
+
* (`host.dbQuery` / `host.dbExec` check it in pkg-iframe-host.tsx) — but a pkg's
|
|
51
|
+
* BACKEND process has no scoped accessor available to it, so opening the
|
|
52
|
+
* database with better-sqlite3 means holding a connection with full read/write
|
|
53
|
+
* over every table in `ikenga.db`: tasks, email, finance, everything.
|
|
54
|
+
*
|
|
55
|
+
* That is a real widening of trust and it should not be incidental. This guard
|
|
56
|
+
* re-imposes the manifest scope in code, so a bug — or a prompt injection
|
|
57
|
+
* reaching a tool argument — cannot reach beyond the meetings domain. It is not
|
|
58
|
+
* a substitute for host-side enforcement; it is the best a pkg can do for itself
|
|
59
|
+
* until a scoped backend accessor exists.
|
|
60
|
+
*/
|
|
61
|
+
export const ALLOWED_TABLES = [
|
|
62
|
+
'meetings',
|
|
63
|
+
'meeting_speakers',
|
|
64
|
+
'meeting_transcripts',
|
|
65
|
+
'meeting_action_items',
|
|
66
|
+
'meeting_summaries',
|
|
67
|
+
];
|
|
68
|
+
/** Every table name a statement references, lowercased. */
|
|
69
|
+
export function tablesReferenced(sql) {
|
|
70
|
+
const found = new Set();
|
|
71
|
+
const re = /\b(?:from|join|into|update|table)\s+["'`\[]?([A-Za-z_][A-Za-z0-9_]*)["'`\]]?/gi;
|
|
72
|
+
let m;
|
|
73
|
+
while ((m = re.exec(sql)) !== null) {
|
|
74
|
+
if (m[1])
|
|
75
|
+
found.add(m[1].toLowerCase());
|
|
76
|
+
}
|
|
77
|
+
return [...found];
|
|
78
|
+
}
|
|
79
|
+
/** Throw unless every table a statement touches is in the pkg's scope. */
|
|
80
|
+
export function assertInScope(sql) {
|
|
81
|
+
const allowed = new Set(ALLOWED_TABLES);
|
|
82
|
+
const out = tablesReferenced(sql).filter((t) => !allowed.has(t));
|
|
83
|
+
if (out.length > 0) {
|
|
84
|
+
throw new Error(`meetings pkg may not touch table(s): ${out.join(', ')}. ` +
|
|
85
|
+
`Allowed: ${ALLOWED_TABLES.join(', ')}.`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export class BetterSqliteExecutor {
|
|
89
|
+
db;
|
|
90
|
+
/** True only for a database this pkg created for itself (tests). */
|
|
91
|
+
ownsSchema;
|
|
92
|
+
constructor(dbPathOrInstance = resolveDatabasePath()) {
|
|
93
|
+
const livePath = resolveDatabasePath();
|
|
94
|
+
this.ownsSchema =
|
|
95
|
+
typeof dbPathOrInstance === 'string'
|
|
96
|
+
? dbPathOrInstance === ':memory:' || path.resolve(dbPathOrInstance) !== path.resolve(livePath)
|
|
97
|
+
: false;
|
|
98
|
+
if (typeof dbPathOrInstance === 'string') {
|
|
99
|
+
if (dbPathOrInstance !== ':memory:') {
|
|
100
|
+
const dir = path.dirname(dbPathOrInstance);
|
|
101
|
+
if (!fs.existsSync(dir)) {
|
|
102
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
this.db = new Database(dbPathOrInstance);
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
this.db = dbPathOrInstance;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
this.db.pragma('journal_mode = WAL');
|
|
112
|
+
this.db.pragma('busy_timeout = 5000');
|
|
113
|
+
this.db.pragma('synchronous = NORMAL');
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// Pragmas may not apply to all database configurations
|
|
117
|
+
}
|
|
118
|
+
// Schema is owned by the shell's migration runner (0063_meetings_domain,
|
|
119
|
+
// recorded in `_pa_migrations`), NOT by this pkg.
|
|
120
|
+
//
|
|
121
|
+
// Creating tables here would put DDL into the user's canonical database
|
|
122
|
+
// from a pkg process, outside the migration ledger. If this inline schema
|
|
123
|
+
// ever drifted from the migration, the divergence would be silent and
|
|
124
|
+
// unattributable. So the tables are only created for a database this pkg
|
|
125
|
+
// owns outright — an in-memory or explicitly-pathed test database — and
|
|
126
|
+
// never for the live one.
|
|
127
|
+
if (this.ownsSchema) {
|
|
128
|
+
this.initSchema();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
initSchema() {
|
|
132
|
+
this.db.exec(`
|
|
133
|
+
CREATE TABLE IF NOT EXISTS meetings (
|
|
134
|
+
id TEXT PRIMARY KEY,
|
|
135
|
+
title TEXT NOT NULL,
|
|
136
|
+
platform TEXT NOT NULL,
|
|
137
|
+
url TEXT,
|
|
138
|
+
status TEXT NOT NULL,
|
|
139
|
+
start_time TEXT NOT NULL,
|
|
140
|
+
end_time TEXT,
|
|
141
|
+
duration_seconds INTEGER NOT NULL DEFAULT 0,
|
|
142
|
+
video_path TEXT,
|
|
143
|
+
audio_path TEXT,
|
|
144
|
+
created_at TEXT NOT NULL,
|
|
145
|
+
updated_at TEXT NOT NULL
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
CREATE TABLE IF NOT EXISTS meeting_speakers (
|
|
149
|
+
id TEXT PRIMARY KEY,
|
|
150
|
+
meeting_id TEXT NOT NULL,
|
|
151
|
+
name TEXT NOT NULL,
|
|
152
|
+
avatar_url TEXT,
|
|
153
|
+
contact_id TEXT,
|
|
154
|
+
speaker_source TEXT NOT NULL DEFAULT 'dom_cue'
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
CREATE TABLE IF NOT EXISTS meeting_transcripts (
|
|
158
|
+
id TEXT PRIMARY KEY,
|
|
159
|
+
meeting_id TEXT NOT NULL,
|
|
160
|
+
speaker_id TEXT,
|
|
161
|
+
speaker_name TEXT,
|
|
162
|
+
speaker_source TEXT,
|
|
163
|
+
start_ms INTEGER NOT NULL,
|
|
164
|
+
end_ms INTEGER NOT NULL,
|
|
165
|
+
text TEXT NOT NULL,
|
|
166
|
+
confidence REAL NOT NULL DEFAULT 1.0,
|
|
167
|
+
words_json TEXT
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
CREATE TABLE IF NOT EXISTS meeting_action_items (
|
|
171
|
+
id TEXT PRIMARY KEY,
|
|
172
|
+
meeting_id TEXT NOT NULL,
|
|
173
|
+
title TEXT NOT NULL,
|
|
174
|
+
assignee TEXT,
|
|
175
|
+
due_date TEXT,
|
|
176
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
177
|
+
task_id TEXT
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
CREATE TABLE IF NOT EXISTS meeting_summaries (
|
|
181
|
+
id TEXT PRIMARY KEY,
|
|
182
|
+
meeting_id TEXT NOT NULL,
|
|
183
|
+
executive_summary TEXT NOT NULL,
|
|
184
|
+
key_decisions_json TEXT NOT NULL DEFAULT '[]',
|
|
185
|
+
topics_json TEXT NOT NULL DEFAULT '[]',
|
|
186
|
+
created_at TEXT
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
CREATE INDEX IF NOT EXISTS idx_meetings_status ON meetings(status);
|
|
190
|
+
CREATE INDEX IF NOT EXISTS idx_meetings_created_at ON meetings(created_at);
|
|
191
|
+
CREATE INDEX IF NOT EXISTS idx_meeting_speakers_meeting_id ON meeting_speakers(meeting_id);
|
|
192
|
+
CREATE INDEX IF NOT EXISTS idx_meeting_transcripts_meeting_id ON meeting_transcripts(meeting_id);
|
|
193
|
+
CREATE INDEX IF NOT EXISTS idx_meeting_transcripts_start_ms ON meeting_transcripts(meeting_id, start_ms);
|
|
194
|
+
CREATE INDEX IF NOT EXISTS idx_meeting_action_items_meeting_id ON meeting_action_items(meeting_id);
|
|
195
|
+
CREATE INDEX IF NOT EXISTS idx_meeting_summaries_meeting_id ON meeting_summaries(meeting_id);
|
|
196
|
+
`);
|
|
197
|
+
}
|
|
198
|
+
async query(sql, params = []) {
|
|
199
|
+
assertInScope(sql);
|
|
200
|
+
const stmt = this.db.prepare(sql);
|
|
201
|
+
const rows = stmt.all(...params);
|
|
202
|
+
return rows.map((r) => normalizeRow(r));
|
|
203
|
+
}
|
|
204
|
+
async exec(sql, params = []) {
|
|
205
|
+
assertInScope(sql);
|
|
206
|
+
if (params && params.length > 0) {
|
|
207
|
+
const stmt = this.db.prepare(sql);
|
|
208
|
+
return stmt.run(...params);
|
|
209
|
+
}
|
|
210
|
+
return this.db.exec(sql);
|
|
211
|
+
}
|
|
212
|
+
close() {
|
|
213
|
+
this.db.close();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
export class InMemorySqlExecutor {
|
|
217
|
+
meetingsMap = new Map();
|
|
218
|
+
transcriptsMap = new Map();
|
|
219
|
+
speakersMap = new Map();
|
|
220
|
+
summariesMap = new Map();
|
|
221
|
+
actionsMap = new Map();
|
|
222
|
+
async query(sql, params = []) {
|
|
223
|
+
let results = [];
|
|
224
|
+
if (sql.includes('SELECT * FROM meetings WHERE id = ?')) {
|
|
225
|
+
const id = String(params[0]);
|
|
226
|
+
const found = this.meetingsMap.get(id);
|
|
227
|
+
results = found ? [found] : [];
|
|
228
|
+
}
|
|
229
|
+
else if (sql.includes('SELECT * FROM meetings')) {
|
|
230
|
+
results = Array.from(this.meetingsMap.values());
|
|
231
|
+
}
|
|
232
|
+
else if (sql.includes('SELECT * FROM meeting_transcripts WHERE text LIKE ?')) {
|
|
233
|
+
const all = [];
|
|
234
|
+
for (const list of this.transcriptsMap.values()) {
|
|
235
|
+
all.push(...list);
|
|
236
|
+
}
|
|
237
|
+
const rawPattern = String(params[0] ?? '').replace(/%/g, '').toLowerCase();
|
|
238
|
+
results = all.filter((r) => r.text?.toLowerCase().includes(rawPattern));
|
|
239
|
+
}
|
|
240
|
+
else if (sql.includes('SELECT * FROM meeting_transcripts WHERE meeting_id = ?')) {
|
|
241
|
+
const id = String(params[0]);
|
|
242
|
+
results = this.transcriptsMap.get(id) ?? [];
|
|
243
|
+
}
|
|
244
|
+
else if (sql.includes('SELECT * FROM meeting_speakers WHERE meeting_id = ?')) {
|
|
245
|
+
const id = String(params[0]);
|
|
246
|
+
results = this.speakersMap.get(id) ?? [];
|
|
247
|
+
}
|
|
248
|
+
else if (sql.includes('SELECT * FROM meeting_summaries WHERE meeting_id = ?')) {
|
|
249
|
+
const id = String(params[0]);
|
|
250
|
+
const found = this.summariesMap.get(id);
|
|
251
|
+
results = found ? [found] : [];
|
|
252
|
+
}
|
|
253
|
+
else if (sql.includes('SELECT * FROM meeting_action_items WHERE meeting_id = ?')) {
|
|
254
|
+
const id = String(params[0]);
|
|
255
|
+
results = this.actionsMap.get(id) ?? [];
|
|
256
|
+
}
|
|
257
|
+
return results.map((r) => normalizeRow(r));
|
|
258
|
+
}
|
|
259
|
+
async exec(sql, params = []) {
|
|
260
|
+
if (sql.includes('INSERT INTO meetings')) {
|
|
261
|
+
const [id, title, platform, url, status, start_time, end_time, duration_seconds, video_path, audio_path, created_at, updated_at] = params;
|
|
262
|
+
this.meetingsMap.set(String(id), {
|
|
263
|
+
id, title, platform, url, status, start_time, end_time, duration_seconds, video_path, audio_path, created_at, updated_at
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
else if (sql.includes('UPDATE meetings SET')) {
|
|
267
|
+
const id = String(params[params.length - 1]);
|
|
268
|
+
const existing = this.meetingsMap.get(id);
|
|
269
|
+
if (existing) {
|
|
270
|
+
existing.status = params[0];
|
|
271
|
+
existing.updated_at = params[1];
|
|
272
|
+
if (params.length > 3) {
|
|
273
|
+
existing.end_time = params[2];
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
else if (sql.includes('INSERT INTO meeting_speakers')) {
|
|
278
|
+
const [id, meeting_id, name, avatar_url, contact_id, speaker_source] = params;
|
|
279
|
+
const list = this.speakersMap.get(String(meeting_id)) ?? [];
|
|
280
|
+
list.push({ id, meeting_id, name, avatar_url, contact_id, speaker_source });
|
|
281
|
+
this.speakersMap.set(String(meeting_id), list);
|
|
282
|
+
}
|
|
283
|
+
else if (sql.includes('INSERT INTO meeting_transcripts')) {
|
|
284
|
+
const [id, meeting_id, speaker_id, speaker_name, speaker_source, start_ms, end_ms, text, confidence, words_json] = params;
|
|
285
|
+
const list = this.transcriptsMap.get(String(meeting_id)) ?? [];
|
|
286
|
+
list.push({ id, meeting_id, speaker_id, speaker_name, speaker_source, start_ms, end_ms, text, confidence, words_json });
|
|
287
|
+
this.transcriptsMap.set(String(meeting_id), list);
|
|
288
|
+
}
|
|
289
|
+
else if (sql.includes('INSERT INTO meeting_summaries')) {
|
|
290
|
+
const [id, meeting_id, executive_summary, key_decisions_json, topics_json, created_at] = params;
|
|
291
|
+
this.summariesMap.set(String(meeting_id), {
|
|
292
|
+
id, meeting_id, executive_summary, key_decisions_json, topics_json, created_at
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
else if (sql.includes('INSERT INTO meeting_action_items')) {
|
|
296
|
+
const [id, meeting_id, title, assignee, due_date, status, task_id] = params;
|
|
297
|
+
const list = this.actionsMap.get(String(meeting_id)) ?? [];
|
|
298
|
+
list.push({ id, meeting_id, title, assignee, due_date, status, task_id });
|
|
299
|
+
this.actionsMap.set(String(meeting_id), list);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.test.d.ts","sourceRoot":"","sources":["../src/sqlite.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { assertInScope, tablesReferenced, ALLOWED_TABLES } from './sqlite.js';
|
|
4
|
+
/**
|
|
5
|
+
* A pkg's backend process opens ikenga.db with full read/write over every
|
|
6
|
+
* table — there is no scoped accessor for it the way `host.dbQuery` scopes the
|
|
7
|
+
* iframe. These tests pin the in-code guard that re-imposes the manifest scope.
|
|
8
|
+
* Fabricated rows were written into the user's real database earlier in this
|
|
9
|
+
* plan's history through exactly this unguarded path.
|
|
10
|
+
*/
|
|
11
|
+
describe('meetings pkg sqlite scope guard', () => {
|
|
12
|
+
it('allows the pkg its own tables', () => {
|
|
13
|
+
for (const t of ALLOWED_TABLES) {
|
|
14
|
+
assertInScope(`SELECT * FROM ${t} WHERE id = ?`);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
it('refuses tables belonging to other domains', () => {
|
|
18
|
+
for (const sql of [
|
|
19
|
+
'SELECT * FROM tasks',
|
|
20
|
+
'INSERT INTO email_index (id) VALUES (?)',
|
|
21
|
+
'UPDATE deals SET amount = ?',
|
|
22
|
+
'DELETE FROM _pa_migrations',
|
|
23
|
+
]) {
|
|
24
|
+
assert.throws(() => assertInScope(sql), /may not touch table/, sql);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
it('catches a joined table, not just the leading one', () => {
|
|
28
|
+
assert.throws(() => assertInScope('SELECT * FROM meetings JOIN tasks ON tasks.id = meetings.id'), /tasks/);
|
|
29
|
+
});
|
|
30
|
+
it('extracts every referenced table', () => {
|
|
31
|
+
const t = tablesReferenced('SELECT * FROM meetings JOIN meeting_speakers ON 1=1');
|
|
32
|
+
assert.ok(t.includes('meetings'));
|
|
33
|
+
assert.ok(t.includes('meeting_speakers'));
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
//# sourceMappingURL=sqlite.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.test.js","sourceRoot":"","sources":["../src/sqlite.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9E;;;;;;GAMG;AACH,QAAQ,CAAC,iCAAiC,EAAE,GAAG,EAAE;IAC/C,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;YAC/B,aAAa,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;QACnD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,KAAK,MAAM,GAAG,IAAI;YAChB,qBAAqB;YACrB,yCAAyC;YACzC,6BAA6B;YAC7B,4BAA4B;SAC7B,EAAE,CAAC;YACF,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,qBAAqB,EAAE,GAAG,CAAC,CAAC;QACtE,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CAAC,aAAa,CAAC,6DAA6D,CAAC,EAClF,OAAO,CACR,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,GAAG,gBAAgB,CAAC,qDAAqD,CAAC,CAAC;QAClF,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|