@mcp-abap-adt/hana-vector-rag 26.0.0 → 28.0.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.
Files changed (44) hide show
  1. package/README.md +42 -5
  2. package/dist/__tests__/catalog.test.d.ts +2 -0
  3. package/dist/__tests__/catalog.test.d.ts.map +1 -0
  4. package/dist/__tests__/catalog.test.js +266 -0
  5. package/dist/__tests__/catalog.test.js.map +1 -0
  6. package/dist/__tests__/connection.test.js +11 -11
  7. package/dist/__tests__/connection.test.js.map +1 -1
  8. package/dist/__tests__/credential.test.d.ts +2 -0
  9. package/dist/__tests__/credential.test.d.ts.map +1 -0
  10. package/dist/__tests__/credential.test.js +32 -0
  11. package/dist/__tests__/credential.test.js.map +1 -0
  12. package/dist/__tests__/fake-hana.d.ts +19 -0
  13. package/dist/__tests__/fake-hana.d.ts.map +1 -0
  14. package/dist/__tests__/fake-hana.js +87 -0
  15. package/dist/__tests__/fake-hana.js.map +1 -0
  16. package/dist/__tests__/hana-vector-rag-provider.test.js +10 -11
  17. package/dist/__tests__/hana-vector-rag-provider.test.js.map +1 -1
  18. package/dist/__tests__/hana-vector-rag.test.js +178 -8
  19. package/dist/__tests__/hana-vector-rag.test.js.map +1 -1
  20. package/dist/catalog.d.ts +18 -0
  21. package/dist/catalog.d.ts.map +1 -0
  22. package/dist/catalog.js +43 -0
  23. package/dist/catalog.js.map +1 -0
  24. package/dist/connection.d.ts +25 -3
  25. package/dist/connection.d.ts.map +1 -1
  26. package/dist/connection.js +7 -5
  27. package/dist/connection.js.map +1 -1
  28. package/dist/hana-vector-rag-provider.d.ts +47 -15
  29. package/dist/hana-vector-rag-provider.d.ts.map +1 -1
  30. package/dist/hana-vector-rag-provider.js +197 -24
  31. package/dist/hana-vector-rag-provider.js.map +1 -1
  32. package/dist/hana-vector-rag.d.ts +12 -2
  33. package/dist/hana-vector-rag.d.ts.map +1 -1
  34. package/dist/hana-vector-rag.js +120 -49
  35. package/dist/hana-vector-rag.js.map +1 -1
  36. package/dist/index.d.ts +2 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +2 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/schema.d.ts +3 -1
  41. package/dist/schema.d.ts.map +1 -1
  42. package/dist/schema.js +3 -2
  43. package/dist/schema.js.map +1 -1
  44. package/package.json +6 -3
package/README.md CHANGED
@@ -18,16 +18,53 @@ npm install @mcp-abap-adt/hana-vector-rag @sap/hana-client
18
18
  ## Minimal config
19
19
 
20
20
  ```yaml
21
+ # the address only; the login is a credential (required — HANA has no anonymous login)
21
22
  rag:
22
- type: hana-vector
23
- connectionString: hdbsql://user:pass@host:443
24
- collectionName: llm_agent_docs
25
- dimension: 1536
26
- autoCreateSchema: true
23
+ store:
24
+ type: hana-vector
25
+ connectionString: hdbsql://host:443
26
+ collectionName: llm_agent_docs
27
+ dimension: 1536
28
+ autoCreateSchema: true
29
+ credentialRef: RAG_HANA # the llm-agent binary reads RAG_HANA_USER and RAG_HANA_PASSWORD
27
30
  ```
28
31
 
32
+ In code: `new HanaVectorRag({ connectionString: 'hdbsql://host:443', credential: staticLogin(user, password), … })`
33
+ — `credential` is **required**, and a bare-string `connection` is refused at construction.
34
+
29
35
  See the monorepo root README for full configuration surface.
30
36
 
37
+ ## Catalog and the rights it needs
38
+
39
+ `HanaVectorRagProvider` keeps one record per collection in a catalog table of its own
40
+ (`rag_collection_catalog` by default, `catalogTable` to rename it), in the configured schema or the
41
+ connection's current one. `createCollection` creates the collection's table and then writes its
42
+ record; `deleteCollection` deletes the record first, then drops the table; `describeCollections`
43
+ reads the catalog back. The database user the connection uses needs:
44
+
45
+ | with `autoCreateSchema` | rights |
46
+ |---|---|
47
+ | `true` (default) | `CREATE ANY` on the schema (the catalog table on first use, one table per collection); `SELECT`, `INSERT`, `DELETE` on the catalog; `DROP` on the collection tables (it owns those it created); `SELECT` on `SYS.TABLES` (granted to `PUBLIC` by default) |
48
+ | `false` | no creating DDL is issued: the operator creates the catalog with `createCatalogTableSql(table)` (exported) and each collection table. The user needs `SELECT`, `INSERT`, `DELETE` on the catalog, `SELECT`, `INSERT`, `UPDATE`, `DELETE` on the collection tables, and `DROP` on them — the flag governs creation only, and `deleteCollection` still drops the table |
49
+
50
+ Without those rights `createCollection` fails where it used to succeed. A collection created before
51
+ this release has a table and no record: take it over once with
52
+ `createCollection(..., { adoptExisting: true })`.
53
+
54
+ ## Connections, and `clientFactory` for per-session hydration
55
+
56
+ `openCollection` builds a collection's handles without a statement and without a connection; a
57
+ handle connects on its first query or write. Without `clientFactory`, each handle then opens a
58
+ connection of its own — one physical connection per collection handle, which nothing closes.
59
+ Per-session hydration opens every one of a caller's catalog records in every session, so a
60
+ deployment that hydrates per session should pass **`clientFactory` returning one shared client**:
61
+ every handle and the provider's own catalog work then run on that client.
62
+
63
+ ```ts
64
+ const shared = await createHanaClient({ host, credential: staticLogin(user, password), collectionName: '_' });
65
+ new HanaVectorRagProvider({ name: 'hana', embedder, connection, clientFactory: () => shared });
66
+ ```
67
+
31
68
  ## License
32
69
 
33
70
  **GNU Lesser General Public License v3.0 only** (`LGPL-3.0-only`) — see
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=catalog.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/catalog.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,266 @@
1
+ import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
3
+ import { CatalogRecordDeleteError, staticLogin } from '@mcp-abap-adt/llm-agent';
4
+ import { HanaVectorRag } from '../hana-vector-rag.js';
5
+ import { HanaVectorRagProvider } from '../hana-vector-rag-provider.js';
6
+ import { fakeHana } from './fake-hana.js';
7
+ const CATALOG = 'rag_collection_catalog';
8
+ const STORE = 'my_notes_a1b2c3d4e5f6';
9
+ const embedder = { embed: async () => ({ vector: [0, 0, 0] }) };
10
+ const createOpts = {
11
+ scope: 'session',
12
+ sessionId: 's-1',
13
+ collectionName: 'my notes',
14
+ attributes: { role: 'analyst' },
15
+ };
16
+ const row = (over = {}) => ({
17
+ storeName: STORE,
18
+ name: 'my notes',
19
+ scope: 'global',
20
+ userId: null,
21
+ sessionId: null,
22
+ attributesJson: null,
23
+ ...over,
24
+ });
25
+ function providerOn(fake, autoCreateSchema = true) {
26
+ return new HanaVectorRagProvider({
27
+ name: 'hana',
28
+ embedder,
29
+ connection: {
30
+ host: 'h',
31
+ collectionName: '__unused',
32
+ credential: staticLogin('u', 'p'),
33
+ },
34
+ defaultDimension: 3,
35
+ autoCreateSchema,
36
+ clientFactory: () => fake.client,
37
+ });
38
+ }
39
+ const at = (fake, re) => fake.statements.findIndex((s) => re.test(s));
40
+ const storeCreate = new RegExp(`^CREATE TABLE "${STORE}"`);
41
+ const recordInsert = new RegExp(`^INSERT INTO "${CATALOG}"`);
42
+ describe('hana catalog: createCollection', () => {
43
+ it('creates the store with a statement that fails if it exists, and records it last', async () => {
44
+ const fake = fakeHana();
45
+ const res = await providerOn(fake).createCollection(STORE, createOpts);
46
+ assert.equal(res.ok, true);
47
+ const createdAt = at(fake, storeCreate);
48
+ assert.ok(createdAt >= 0 && at(fake, recordInsert) > createdAt);
49
+ assert.equal(at(fake, new RegExp(`CREATE TABLE IF NOT EXISTS "${STORE}"`)), -1);
50
+ const described = await providerOn(fake).describeCollections();
51
+ assert.ok(described.ok);
52
+ assert.deepEqual(described.value.records, [
53
+ {
54
+ scope: 'session',
55
+ sessionId: 's-1',
56
+ storeName: STORE,
57
+ name: 'my notes',
58
+ attributes: { role: 'analyst' },
59
+ },
60
+ ]);
61
+ });
62
+ it('refuses a collection whose record exists', async () => {
63
+ const fake = fakeHana();
64
+ fake.tables.add(CATALOG);
65
+ fake.tables.add(STORE);
66
+ fake.records.set(STORE, row());
67
+ const res = await providerOn(fake).createCollection(STORE, createOpts);
68
+ assert.equal(!res.ok && res.error.code, 'RAG_DUPLICATE_COLLECTION');
69
+ assert.equal(at(fake, storeCreate), -1);
70
+ });
71
+ it('refuses a store that exists without a record, naming it, and adopts it on request', async () => {
72
+ const fake = fakeHana();
73
+ fake.tables.add(STORE);
74
+ const refused = await providerOn(fake).createCollection(STORE, createOpts);
75
+ assert.equal(!refused.ok && refused.error.code, 'RAG_ORPHAN_STORE');
76
+ assert.match(!refused.ok ? refused.error.message : '', new RegExp(STORE));
77
+ const adopted = await providerOn(fake).createCollection(STORE, {
78
+ ...createOpts,
79
+ adoptExisting: true,
80
+ });
81
+ assert.equal(adopted.ok, true);
82
+ assert.ok(fake.records.has(STORE));
83
+ });
84
+ it('refuses adoptExisting for a store that is not there, and creates nothing', async () => {
85
+ const fake = fakeHana();
86
+ const res = await providerOn(fake).createCollection(STORE, {
87
+ ...createOpts,
88
+ adoptExisting: true,
89
+ });
90
+ assert.equal(!res.ok && res.error.code, 'RAG_CREATE_ERROR');
91
+ assert.ok(!fake.tables.has(STORE) && !fake.records.has(STORE));
92
+ });
93
+ it('leaves the store in place when the record cannot be written', async () => {
94
+ const fake = fakeHana();
95
+ fake.failOn = recordInsert;
96
+ const res = await providerOn(fake).createCollection(STORE, createOpts);
97
+ assert.equal(!res.ok && res.error.code, 'RAG_ORPHAN_STORE');
98
+ assert.ok(fake.tables.has(STORE));
99
+ assert.equal(at(fake, /^DROP TABLE/), -1);
100
+ });
101
+ it('loses cleanly to a registry that recorded the same store first', async () => {
102
+ const fake = fakeHana();
103
+ fake.beforeInsertRecord = () => {
104
+ fake.records.set(STORE, row());
105
+ };
106
+ const res = await providerOn(fake).createCollection(STORE, createOpts);
107
+ assert.equal(!res.ok && res.error.code, 'RAG_DUPLICATE_COLLECTION');
108
+ assert.ok(fake.tables.has(STORE));
109
+ });
110
+ it('refuses an owner without its key before any statement', async () => {
111
+ const fake = fakeHana();
112
+ const res = await providerOn(fake).createCollection(STORE, {
113
+ scope: 'session',
114
+ });
115
+ assert.equal(!res.ok && res.error.code, 'RAG_INVALID_OWNER');
116
+ assert.deepEqual(fake.statements, []);
117
+ });
118
+ it('with autoCreateSchema false issues no DDL, requires the store, and records it', async () => {
119
+ const fake = fakeHana();
120
+ fake.tables.add(CATALOG);
121
+ const missing = await providerOn(fake, false).createCollection(STORE, createOpts);
122
+ assert.equal(missing.ok, false);
123
+ fake.tables.add(STORE);
124
+ assert.equal((await providerOn(fake, false).createCollection(STORE, createOpts)).ok, true);
125
+ assert.equal(at(fake, /^CREATE /), -1);
126
+ });
127
+ });
128
+ describe('hana catalog: describeCollections', () => {
129
+ it('returns nothing, and creates nothing, when no catalog exists yet', async () => {
130
+ const fake = fakeHana();
131
+ assert.deepEqual(await providerOn(fake).describeCollections(), {
132
+ ok: true,
133
+ value: { records: [], rejected: [] },
134
+ });
135
+ assert.equal(at(fake, /^CREATE /), -1);
136
+ });
137
+ it('decodes an NCLOB handed back as a Buffer, and rejects malformed rows', async () => {
138
+ const fake = fakeHana();
139
+ fake.tables.add(CATALOG);
140
+ fake.records.set('a_1', row({
141
+ storeName: 'a_1',
142
+ attributesJson: Buffer.from('{"k":[1]}', 'utf8'),
143
+ }));
144
+ fake.records.set('b_1', row({ storeName: 'b_1', scope: 'session' }));
145
+ const res = await providerOn(fake).describeCollections();
146
+ assert.ok(res.ok);
147
+ assert.deepEqual(res.value.records, [
148
+ {
149
+ scope: 'global',
150
+ storeName: 'a_1',
151
+ name: 'my notes',
152
+ attributes: { k: [1] },
153
+ },
154
+ ]);
155
+ assert.deepEqual(res.value.rejected.map((r) => r.storeName), ['b_1']);
156
+ });
157
+ });
158
+ describe('hana catalog: openCollection', () => {
159
+ it('builds handles without a statement, and a write to a missing store fails instead of creating it', async () => {
160
+ const fake = fakeHana();
161
+ const record = {
162
+ storeName: STORE,
163
+ name: 'n',
164
+ scope: 'global',
165
+ };
166
+ const opened = await providerOn(fake).openCollection(record);
167
+ assert.ok(opened.ok);
168
+ assert.deepEqual(fake.statements, []);
169
+ assert.equal((await opened.value.editor.upsert('hello', { id: 'r1' })).ok, false);
170
+ assert.ok(!fake.tables.has(STORE));
171
+ assert.equal(at(fake, /^CREATE /), -1);
172
+ });
173
+ });
174
+ describe('hana: a handle connects on first use, never at openCollection', () => {
175
+ // Without clientFactory each handle opens its own connection. Per-session
176
+ // hydration opens one handle per record per session, so a handle that
177
+ // connected in its constructor opened a connection nobody used or closed.
178
+ // Resolving the credential is the first step of a connect, so counting its
179
+ // reads counts connection attempts without a driver.
180
+ it('openCollection reads no credential; the first use does', async () => {
181
+ let reads = 0;
182
+ const credential = {
183
+ ...staticLogin('u', 'pw'),
184
+ secret: async () => {
185
+ reads++;
186
+ throw new Error('no HANA here');
187
+ },
188
+ };
189
+ const provider = new HanaVectorRagProvider({
190
+ name: 'hana',
191
+ embedder,
192
+ connection: { host: 'h', collectionName: '__unused', credential },
193
+ });
194
+ const opened = await provider.openCollection({
195
+ storeName: STORE,
196
+ name: 'n',
197
+ scope: 'global',
198
+ });
199
+ assert.ok(opened.ok);
200
+ await new Promise((r) => setImmediate(r));
201
+ assert.equal(reads, 0, 'openCollection must open no connection');
202
+ const first = await opened.value.rag.healthCheck();
203
+ assert.equal(first.ok, false);
204
+ assert.equal(reads, 1);
205
+ // A failed connect is not memoized: the next use tries again.
206
+ await opened.value.rag.healthCheck();
207
+ assert.equal(reads, 2);
208
+ });
209
+ });
210
+ describe('hana: a failed first connect is retried on the schema path too', () => {
211
+ // A directly configured store (autoCreateSchema defaults to true) reaches the
212
+ // connection through ensureSchema; a failed bootstrap must not be kept either.
213
+ it('getById after a failed connect tries to connect again', async () => {
214
+ let reads = 0;
215
+ const credential = {
216
+ ...staticLogin('u', 'pw'),
217
+ secret: async () => {
218
+ reads++;
219
+ throw new Error('no HANA here');
220
+ },
221
+ };
222
+ const rag = new HanaVectorRag({
223
+ host: 'h',
224
+ collectionName: 'docs',
225
+ dimension: 3,
226
+ embedder,
227
+ credential,
228
+ });
229
+ assert.equal((await rag.getById('x')).ok, false);
230
+ assert.equal(reads, 1);
231
+ assert.equal((await rag.getById('x')).ok, false);
232
+ assert.equal(reads, 2);
233
+ });
234
+ });
235
+ describe('hana catalog: deleteCollection', () => {
236
+ const seeded = () => {
237
+ const fake = fakeHana();
238
+ fake.tables.add(CATALOG);
239
+ fake.tables.add(STORE);
240
+ fake.records.set(STORE, row());
241
+ return fake;
242
+ };
243
+ it('deletes the record before the data', async () => {
244
+ const fake = seeded();
245
+ assert.equal((await providerOn(fake).deleteCollection(STORE)).ok, true);
246
+ const recordAt = at(fake, new RegExp(`^DELETE FROM "${CATALOG}"`));
247
+ assert.ok(recordAt >= 0 &&
248
+ at(fake, new RegExp(`^DROP TABLE IF EXISTS "${STORE}"`)) > recordAt);
249
+ });
250
+ it('leaves record and data alone when the record cannot be deleted', async () => {
251
+ const fake = seeded();
252
+ fake.failOn = new RegExp(`^DELETE FROM "${CATALOG}"`);
253
+ const res = await providerOn(fake).deleteCollection(STORE);
254
+ assert.ok(!res.ok && res.error instanceof CatalogRecordDeleteError);
255
+ assert.equal(at(fake, /^DROP TABLE/), -1);
256
+ assert.ok(fake.records.has(STORE) && fake.tables.has(STORE));
257
+ });
258
+ it('reports a data failure after the record is gone as a plain delete error', async () => {
259
+ const fake = seeded();
260
+ fake.failOn = /^DROP TABLE/;
261
+ const res = await providerOn(fake).deleteCollection(STORE);
262
+ assert.equal(!res.ok && res.error.code, 'RAG_DELETE_ERROR');
263
+ assert.ok(!fake.records.has(STORE));
264
+ });
265
+ });
266
+ //# sourceMappingURL=catalog.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.test.js","sourceRoot":"","sources":["../../src/__tests__/catalog.test.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,13 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import { describe, it } from 'node:test';
3
+ import { staticLogin } from '@mcp-abap-adt/llm-agent';
3
4
  import { resolveHanaConnectArgs } from '../connection.js';
4
5
  describe('resolveHanaConnectArgs', () => {
5
- it('accepts explicit fields', () => {
6
- const args = resolveHanaConnectArgs({
6
+ it('accepts explicit fields', async () => {
7
+ const args = await resolveHanaConnectArgs({
7
8
  host: 'h.example.com',
8
9
  port: 443,
9
- user: 'U1',
10
- password: 'pw',
10
+ credential: staticLogin('U1', 'pw'),
11
11
  collectionName: 't',
12
12
  });
13
13
  assert.equal(args.serverNode, 'h.example.com:443');
@@ -15,19 +15,19 @@ describe('resolveHanaConnectArgs', () => {
15
15
  assert.equal(args.pwd, 'pw');
16
16
  assert.equal(args.encrypt, 'true');
17
17
  });
18
- it('parses hdbsql URL', () => {
19
- const args = resolveHanaConnectArgs({
20
- connectionString: 'hdbsql://u:p@host.example:443',
18
+ it('parses hdbsql URL carrying the address only', async () => {
19
+ const args = await resolveHanaConnectArgs({
20
+ connectionString: 'hdbsql://host.example:443',
21
+ credential: staticLogin('u', 'p'),
21
22
  collectionName: 't',
22
23
  });
23
24
  assert.equal(args.serverNode, 'host.example:443');
24
25
  assert.equal(args.uid, 'u');
25
26
  assert.equal(args.pwd, 'p');
26
27
  });
27
- it('rejects missing host', () => {
28
- assert.throws(() => resolveHanaConnectArgs({
29
- user: 'u',
30
- password: 'p',
28
+ it('rejects missing host', async () => {
29
+ await assert.rejects(() => resolveHanaConnectArgs({
30
+ credential: staticLogin('u', 'p'),
31
31
  collectionName: 't',
32
32
  }), /host/i);
33
33
  });
@@ -1 +1 @@
1
- {"version":3,"file":"connection.test.js","sourceRoot":"","sources":["../../src/__tests__/connection.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,IAAI,GAAG,sBAAsB,CAAC;YAClC,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,GAAG;YACT,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,IAAI;YACd,cAAc,EAAE,GAAG;SACpB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mBAAmB,EAAE,GAAG,EAAE;QAC3B,MAAM,IAAI,GAAG,sBAAsB,CAAC;YAClC,gBAAgB,EAAE,+BAA+B;YACjD,cAAc,EAAE,GAAG;SACpB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC5B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,GAAG,EAAE;QAC9B,MAAM,CAAC,MAAM,CACX,GAAG,EAAE,CACH,sBAAsB,CAAC;YACrB,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,GAAG;YACb,cAAc,EAAE,GAAG;SACpB,CAAC,EACJ,OAAO,CACR,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"connection.test.js","sourceRoot":"","sources":["../../src/__tests__/connection.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC;YACxC,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,GAAG;YACT,UAAU,EAAE,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC;YACnC,cAAc,EAAE,GAAG;SACpB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC7B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC;YACxC,gBAAgB,EAAE,2BAA2B;YAC7C,UAAU,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC;YACjC,cAAc,EAAE,GAAG;SACpB,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC5B,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,MAAM,CAAC,OAAO,CAClB,GAAG,EAAE,CACH,sBAAsB,CAAC;YACrB,UAAU,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC;YACjC,cAAc,EAAE,GAAG;SACpB,CAAC,EACJ,OAAO,CACR,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=credential.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/credential.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,32 @@
1
+ import assert from 'node:assert/strict';
2
+ import { describe, it } from 'node:test';
3
+ import { staticLogin } from '@mcp-abap-adt/llm-agent';
4
+ import { resolveHanaConnectArgs } from '../connection.js';
5
+ describe('resolveHanaConnectArgs', () => {
6
+ it('takes the identity and the secret from the credential', async () => {
7
+ const args = await resolveHanaConnectArgs({
8
+ host: 'h',
9
+ collectionName: 't',
10
+ credential: staticLogin('cred_user', 'cred_pw'),
11
+ });
12
+ assert.equal(args.uid, 'cred_user');
13
+ assert.equal(args.pwd, 'cred_pw');
14
+ });
15
+ it('accepts a connection string that carries the ADDRESS only', async () => {
16
+ const args = await resolveHanaConnectArgs({
17
+ connectionString: 'hdbsql://h:443',
18
+ collectionName: 't',
19
+ credential: staticLogin('cred_user', 'cred_pw'),
20
+ });
21
+ assert.equal(args.uid, 'cred_user');
22
+ assert.equal(args.pwd, 'cred_pw');
23
+ });
24
+ it('REFUSES a connection string carrying credentials, naming the fix', async () => {
25
+ await assert.rejects(() => resolveHanaConnectArgs({
26
+ connectionString: 'hdbsql://u:pw@h:443',
27
+ collectionName: 't',
28
+ credential: staticLogin('cred_user', 'cred_pw'),
29
+ }), /staticLogin/, 'silently ignoring the embedded password is the failure this replaces');
30
+ });
31
+ });
32
+ //# sourceMappingURL=credential.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential.test.js","sourceRoot":"","sources":["../../src/__tests__/credential.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC;YACxC,IAAI,EAAE,GAAG;YACT,cAAc,EAAE,GAAG;YACnB,UAAU,EAAE,WAAW,CAAC,WAAW,EAAE,SAAS,CAAC;SAChD,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,IAAI,GAAG,MAAM,sBAAsB,CAAC;YACxC,gBAAgB,EAAE,gBAAgB;YAClC,cAAc,EAAE,GAAG;YACnB,UAAU,EAAE,WAAW,CAAC,WAAW,EAAE,SAAS,CAAC;SAChD,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,MAAM,MAAM,CAAC,OAAO,CAClB,GAAG,EAAE,CACH,sBAAsB,CAAC;YACrB,gBAAgB,EAAE,qBAAqB;YACvC,cAAc,EAAE,GAAG;YACnB,UAAU,EAAE,WAAW,CAAC,WAAW,EAAE,SAAS,CAAC;SAChD,CAAC,EACJ,aAAa,EACb,sEAAsE,CACvE,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { HanaClient } from '../hana-vector-rag.js';
2
+ export type FakeCatalogRow = {
3
+ storeName: string;
4
+ name: unknown;
5
+ scope: unknown;
6
+ userId: unknown;
7
+ sessionId: unknown;
8
+ attributesJson: unknown;
9
+ };
10
+ export type FakeHana = {
11
+ readonly client: HanaClient;
12
+ readonly tables: Set<string>;
13
+ readonly records: Map<string, FakeCatalogRow>;
14
+ readonly statements: string[];
15
+ failOn?: RegExp;
16
+ beforeInsertRecord?: () => void;
17
+ };
18
+ export declare function fakeHana(catalog?: string): FakeHana;
19
+ //# sourceMappingURL=fake-hana.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake-hana.d.ts","sourceRoot":"","sources":["../../src/__tests__/fake-hana.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;CACjC,CAAC;AAIF,wBAAgB,QAAQ,CAAC,OAAO,SAA2B,GAAG,QAAQ,CAcrE"}
@@ -0,0 +1,87 @@
1
+ export function fakeHana(catalog = 'rag_collection_catalog') {
2
+ const fake = {
3
+ tables: new Set(),
4
+ records: new Map(),
5
+ statements: [],
6
+ client: {
7
+ exec: async (sql, params = []) => ({
8
+ rowCount: answer(fake, catalog, sql, params).length,
9
+ }),
10
+ query: async (sql, params = []) => answer(fake, catalog, sql, params),
11
+ close: async () => { },
12
+ },
13
+ };
14
+ return fake;
15
+ }
16
+ function requireTable(fake, table) {
17
+ if (!fake.tables.has(table))
18
+ throw new Error(`invalid table name: ${table}`);
19
+ }
20
+ function answer(fake, catalog, sql, params) {
21
+ fake.statements.push(sql);
22
+ if (fake.failOn?.test(sql))
23
+ throw new Error(`refused by the test: ${sql.slice(0, 60)}`);
24
+ const q = `"${catalog}"`;
25
+ if (sql.startsWith('SELECT COUNT(*) AS "n" FROM SYS.TABLES')) {
26
+ return [{ n: fake.tables.has(String(params[params.length - 1])) ? 1 : 0 }];
27
+ }
28
+ const create = sql.match(/^CREATE TABLE (IF NOT EXISTS )?"([^"]+)"/);
29
+ if (create) {
30
+ const [, ifNotExists, table] = create;
31
+ if (fake.tables.has(table)) {
32
+ if (ifNotExists)
33
+ return [];
34
+ throw new Error(`cannot use duplicate table name: ${table}`);
35
+ }
36
+ fake.tables.add(table);
37
+ return [];
38
+ }
39
+ const probe = sql.match(/^SELECT COUNT\(\*\) AS "n" FROM "([^"]+)" WHERE 1 = 0$/);
40
+ if (probe) {
41
+ requireTable(fake, probe[1]);
42
+ return [{ n: 0 }];
43
+ }
44
+ if (sql.startsWith(`SELECT 1 AS "present" FROM ${q}`)) {
45
+ requireTable(fake, catalog);
46
+ return fake.records.has(String(params[0])) ? [{ present: 1 }] : [];
47
+ }
48
+ if (sql.startsWith(`INSERT INTO ${q}`)) {
49
+ requireTable(fake, catalog);
50
+ fake.beforeInsertRecord?.();
51
+ const storeName = String(params[0]);
52
+ if (fake.records.has(storeName))
53
+ throw new Error('unique constraint violated');
54
+ fake.records.set(storeName, {
55
+ storeName,
56
+ name: params[1],
57
+ scope: params[2],
58
+ userId: params[3],
59
+ sessionId: params[4],
60
+ attributesJson: params[5],
61
+ });
62
+ return [{}];
63
+ }
64
+ if (sql.startsWith('SELECT store_name AS "storeName"')) {
65
+ requireTable(fake, catalog);
66
+ return [...fake.records.values()];
67
+ }
68
+ if (sql.startsWith(`DELETE FROM ${q}`)) {
69
+ requireTable(fake, catalog);
70
+ return fake.records.delete(String(params[0])) ? [{}] : [];
71
+ }
72
+ const drop = sql.match(/^DROP TABLE IF EXISTS "([^"]+)"$/);
73
+ if (drop) {
74
+ fake.tables.delete(drop[1]);
75
+ return [];
76
+ }
77
+ const write = sql.match(/^UPSERT "([^"]+)" \(id, text, vector, metadata\)/);
78
+ if (write) {
79
+ requireTable(fake, write[1]);
80
+ return [{}];
81
+ }
82
+ if (sql.startsWith('SELECT TABLE_NAME FROM SYS.TABLES')) {
83
+ return [...fake.tables].map((t) => ({ TABLE_NAME: t }));
84
+ }
85
+ throw new Error(`fake hana: unhandled statement: ${sql}`);
86
+ }
87
+ //# sourceMappingURL=fake-hana.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fake-hana.js","sourceRoot":"","sources":["../../src/__tests__/fake-hana.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import assert from 'node:assert/strict';
2
2
  import { describe, it } from 'node:test';
3
+ import { staticLogin } from '@mcp-abap-adt/llm-agent';
3
4
  import { HanaVectorRagProvider } from '../hana-vector-rag-provider.js';
4
5
  function makeEmbedder() {
5
6
  return {
@@ -32,8 +33,7 @@ describe('HanaVectorRagProvider', () => {
32
33
  connection: {
33
34
  collectionName: '__ignored',
34
35
  host: 'h',
35
- user: 'u',
36
- password: 'p',
36
+ credential: staticLogin('u', 'p'),
37
37
  },
38
38
  defaultDimension: 3,
39
39
  autoCreateSchema: true,
@@ -56,8 +56,7 @@ describe('HanaVectorRagProvider', () => {
56
56
  connection: {
57
57
  collectionName: '__ignored',
58
58
  host: 'h',
59
- user: 'u',
60
- password: 'p',
59
+ credential: staticLogin('u', 'p'),
61
60
  },
62
61
  defaultDimension: 3,
63
62
  autoCreateSchema: false,
@@ -75,8 +74,7 @@ describe('HanaVectorRagProvider', () => {
75
74
  connection: {
76
75
  collectionName: '__ignored',
77
76
  host: 'h',
78
- user: 'u',
79
- password: 'p',
77
+ credential: staticLogin('u', 'p'),
80
78
  },
81
79
  clientFactory: () => client,
82
80
  });
@@ -95,8 +93,7 @@ describe('HanaVectorRagProvider', () => {
95
93
  connection: {
96
94
  collectionName: '__ignored',
97
95
  host: 'h',
98
- user: 'u',
99
- password: 'p',
96
+ credential: staticLogin('u', 'p'),
100
97
  },
101
98
  clientFactory: () => client,
102
99
  });
@@ -114,13 +111,15 @@ describe('HanaVectorRagProvider', () => {
114
111
  connection: {
115
112
  collectionName: '__ignored',
116
113
  host: 'h',
117
- user: 'u',
118
- password: 'p',
114
+ credential: staticLogin('u', 'p'),
119
115
  },
120
116
  clientFactory: () => client,
121
117
  supportedScopes: ['global'],
122
118
  });
123
- const r = await provider.createCollection('docs', { scope: 'session' });
119
+ const r = await provider.createCollection('docs', {
120
+ scope: 'session',
121
+ sessionId: 's1',
122
+ });
124
123
  assert.equal(r.ok, false);
125
124
  });
126
125
  });