@functional-systems/lambdadb 0.3.1 → 0.3.3

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 (123) hide show
  1. package/README.md +1 -1
  2. package/dist/commonjs/client.d.ts +3 -0
  3. package/dist/commonjs/client.d.ts.map +1 -1
  4. package/dist/commonjs/client.js +49 -5
  5. package/dist/commonjs/client.js.map +1 -1
  6. package/dist/commonjs/lib/matchers.d.ts.map +1 -1
  7. package/dist/commonjs/lib/matchers.js +17 -1
  8. package/dist/commonjs/lib/matchers.js.map +1 -1
  9. package/dist/commonjs/lib/schemas.d.ts +6 -0
  10. package/dist/commonjs/lib/schemas.d.ts.map +1 -1
  11. package/dist/commonjs/lib/schemas.js +9 -0
  12. package/dist/commonjs/lib/schemas.js.map +1 -1
  13. package/dist/commonjs/models/collectionresponse.js +4 -4
  14. package/dist/commonjs/models/collectionresponse.js.map +1 -1
  15. package/dist/commonjs/models/errors/badrequesterror.d.ts.map +1 -1
  16. package/dist/commonjs/models/errors/badrequesterror.js +2 -1
  17. package/dist/commonjs/models/errors/badrequesterror.js.map +1 -1
  18. package/dist/commonjs/models/errors/internalservererror.d.ts.map +1 -1
  19. package/dist/commonjs/models/errors/internalservererror.js +2 -1
  20. package/dist/commonjs/models/errors/internalservererror.js.map +1 -1
  21. package/dist/commonjs/models/errors/resourcealreadyexistserror.d.ts.map +1 -1
  22. package/dist/commonjs/models/errors/resourcealreadyexistserror.js +2 -1
  23. package/dist/commonjs/models/errors/resourcealreadyexistserror.js.map +1 -1
  24. package/dist/commonjs/models/errors/resourcenotfounderror.d.ts.map +1 -1
  25. package/dist/commonjs/models/errors/resourcenotfounderror.js +2 -1
  26. package/dist/commonjs/models/errors/resourcenotfounderror.js.map +1 -1
  27. package/dist/commonjs/models/errors/toomanyrequestserror.d.ts.map +1 -1
  28. package/dist/commonjs/models/errors/toomanyrequestserror.js +2 -1
  29. package/dist/commonjs/models/errors/toomanyrequestserror.js.map +1 -1
  30. package/dist/commonjs/models/errors/unauthenticatederror.d.ts.map +1 -1
  31. package/dist/commonjs/models/errors/unauthenticatederror.js +2 -1
  32. package/dist/commonjs/models/errors/unauthenticatederror.js.map +1 -1
  33. package/dist/commonjs/models/indexconfigsunion.js +2 -2
  34. package/dist/commonjs/models/indexconfigsunion.js.map +1 -1
  35. package/dist/commonjs/models/operations/fetchdocs.js +1 -1
  36. package/dist/commonjs/models/operations/fetchdocs.js.map +1 -1
  37. package/dist/commonjs/models/operations/getbulkupsertdocs.js +3 -3
  38. package/dist/commonjs/models/operations/getbulkupsertdocs.js.map +1 -1
  39. package/dist/commonjs/models/operations/listcollections.js +1 -1
  40. package/dist/commonjs/models/operations/listcollections.js.map +1 -1
  41. package/dist/commonjs/models/operations/listdocs.d.ts +17 -3
  42. package/dist/commonjs/models/operations/listdocs.d.ts.map +1 -1
  43. package/dist/commonjs/models/operations/listdocs.js +10 -3
  44. package/dist/commonjs/models/operations/listdocs.js.map +1 -1
  45. package/dist/commonjs/models/operations/querycollection.js +3 -3
  46. package/dist/commonjs/models/operations/querycollection.js.map +1 -1
  47. package/dist/commonjs/models/partitionconfig.js +3 -3
  48. package/dist/commonjs/models/partitionconfig.js.map +1 -1
  49. package/dist/commonjs/types/public.d.ts +1 -1
  50. package/dist/commonjs/types/public.d.ts.map +1 -1
  51. package/dist/commonjs/types/public.js.map +1 -1
  52. package/dist/esm/client.d.ts +3 -0
  53. package/dist/esm/client.d.ts.map +1 -1
  54. package/dist/esm/client.js +49 -5
  55. package/dist/esm/client.js.map +1 -1
  56. package/dist/esm/lib/matchers.d.ts.map +1 -1
  57. package/dist/esm/lib/matchers.js +17 -1
  58. package/dist/esm/lib/matchers.js.map +1 -1
  59. package/dist/esm/lib/schemas.d.ts +6 -0
  60. package/dist/esm/lib/schemas.d.ts.map +1 -1
  61. package/dist/esm/lib/schemas.js +9 -1
  62. package/dist/esm/lib/schemas.js.map +1 -1
  63. package/dist/esm/models/collectionresponse.js +5 -5
  64. package/dist/esm/models/collectionresponse.js.map +1 -1
  65. package/dist/esm/models/errors/badrequesterror.d.ts.map +1 -1
  66. package/dist/esm/models/errors/badrequesterror.js +2 -1
  67. package/dist/esm/models/errors/badrequesterror.js.map +1 -1
  68. package/dist/esm/models/errors/internalservererror.d.ts.map +1 -1
  69. package/dist/esm/models/errors/internalservererror.js +2 -1
  70. package/dist/esm/models/errors/internalservererror.js.map +1 -1
  71. package/dist/esm/models/errors/resourcealreadyexistserror.d.ts.map +1 -1
  72. package/dist/esm/models/errors/resourcealreadyexistserror.js +2 -1
  73. package/dist/esm/models/errors/resourcealreadyexistserror.js.map +1 -1
  74. package/dist/esm/models/errors/resourcenotfounderror.d.ts.map +1 -1
  75. package/dist/esm/models/errors/resourcenotfounderror.js +2 -1
  76. package/dist/esm/models/errors/resourcenotfounderror.js.map +1 -1
  77. package/dist/esm/models/errors/toomanyrequestserror.d.ts.map +1 -1
  78. package/dist/esm/models/errors/toomanyrequestserror.js +2 -1
  79. package/dist/esm/models/errors/toomanyrequestserror.js.map +1 -1
  80. package/dist/esm/models/errors/unauthenticatederror.d.ts.map +1 -1
  81. package/dist/esm/models/errors/unauthenticatederror.js +2 -1
  82. package/dist/esm/models/errors/unauthenticatederror.js.map +1 -1
  83. package/dist/esm/models/indexconfigsunion.js +3 -3
  84. package/dist/esm/models/indexconfigsunion.js.map +1 -1
  85. package/dist/esm/models/operations/fetchdocs.js +2 -2
  86. package/dist/esm/models/operations/fetchdocs.js.map +1 -1
  87. package/dist/esm/models/operations/getbulkupsertdocs.js +4 -4
  88. package/dist/esm/models/operations/getbulkupsertdocs.js.map +1 -1
  89. package/dist/esm/models/operations/listcollections.js +2 -2
  90. package/dist/esm/models/operations/listcollections.js.map +1 -1
  91. package/dist/esm/models/operations/listdocs.d.ts +17 -3
  92. package/dist/esm/models/operations/listdocs.d.ts.map +1 -1
  93. package/dist/esm/models/operations/listdocs.js +10 -3
  94. package/dist/esm/models/operations/listdocs.js.map +1 -1
  95. package/dist/esm/models/operations/querycollection.js +4 -4
  96. package/dist/esm/models/operations/querycollection.js.map +1 -1
  97. package/dist/esm/models/partitionconfig.js +4 -4
  98. package/dist/esm/models/partitionconfig.js.map +1 -1
  99. package/dist/esm/types/public.d.ts +1 -1
  100. package/dist/esm/types/public.d.ts.map +1 -1
  101. package/dist/esm/types/public.js.map +1 -1
  102. package/package.json +2 -2
  103. package/src/client.ts +53 -5
  104. package/src/lib/matchers.ts +18 -1
  105. package/src/lib/schemas.ts +12 -0
  106. package/src/models/collectionresponse.ts +5 -5
  107. package/src/models/errors/badrequesterror.ts +2 -1
  108. package/src/models/errors/internalservererror.ts +2 -1
  109. package/src/models/errors/resourcealreadyexistserror.ts +2 -1
  110. package/src/models/errors/resourcenotfounderror.ts +2 -1
  111. package/src/models/errors/toomanyrequestserror.ts +2 -1
  112. package/src/models/errors/unauthenticatederror.ts +2 -1
  113. package/src/models/indexconfigsunion.ts +3 -3
  114. package/src/models/operations/fetchdocs.ts +2 -2
  115. package/src/models/operations/getbulkupsertdocs.ts +4 -4
  116. package/src/models/operations/listcollections.ts +2 -2
  117. package/src/models/operations/listdocs.ts +29 -4
  118. package/src/models/operations/querycollection.ts +4 -4
  119. package/src/models/partitionconfig.ts +4 -4
  120. package/src/types/public.ts +4 -1
  121. package/test/null-response.test.mjs +73 -0
  122. package/test/public-api.test.mjs +210 -0
  123. package/.devcontainer/devcontainer.json +0 -45
@@ -0,0 +1,210 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import {
5
+ BadRequestError,
6
+ HTTPClient,
7
+ LambdaDBClient,
8
+ } from "../dist/esm/index.js";
9
+
10
+ const BASE_URL = "https://api.test";
11
+ const PROJECT_NAME = "project-one";
12
+
13
+ function jsonResponse(body, init = {}) {
14
+ return new Response(JSON.stringify(body), {
15
+ status: 200,
16
+ headers: { "content-type": "application/json" },
17
+ ...init,
18
+ });
19
+ }
20
+
21
+ function collectionFixture(collectionName, overrides = {}) {
22
+ return {
23
+ projectName: PROJECT_NAME,
24
+ collectionName,
25
+ indexConfigs: {},
26
+ numPartitions: 1,
27
+ numDocs: 2,
28
+ sourceProjectName: null,
29
+ sourceCollectionName: null,
30
+ sourceCollectionVersionId: null,
31
+ collectionStatus: "ACTIVE",
32
+ createdAt: 1700000000,
33
+ updatedAt: 1700000100,
34
+ dataUpdatedAt: 1700000200,
35
+ ...overrides,
36
+ };
37
+ }
38
+
39
+ function createClient(handler) {
40
+ const calls = [];
41
+ const httpClient = new HTTPClient({
42
+ fetcher: async (request) => {
43
+ const body = await request.clone().text();
44
+ const call = {
45
+ body,
46
+ headers: Object.fromEntries(request.headers.entries()),
47
+ method: request.method,
48
+ url: new URL(request.url),
49
+ };
50
+ calls.push(call);
51
+ return handler(call, calls.length - 1);
52
+ },
53
+ });
54
+
55
+ const client = new LambdaDBClient({
56
+ baseUrl: BASE_URL,
57
+ httpClient,
58
+ projectApiKey: "test-key",
59
+ projectName: PROJECT_NAME,
60
+ });
61
+
62
+ return { calls, client };
63
+ }
64
+
65
+ test("public client lists collections with project URL, auth header, and Date conversion", async () => {
66
+ const { calls, client } = createClient(() =>
67
+ jsonResponse({
68
+ collections: [collectionFixture("alpha")],
69
+ nextPageToken: null,
70
+ })
71
+ );
72
+
73
+ const result = await client.listCollections({ size: 5 });
74
+
75
+ assert.equal(calls.length, 1);
76
+ assert.equal(calls[0].method, "GET");
77
+ assert.equal(calls[0].url.pathname, "/projects/project-one/collections");
78
+ assert.equal(calls[0].url.searchParams.get("size"), "5");
79
+ assert.equal(calls[0].headers["x-api-key"], "test-key");
80
+ assert.equal(result.nextPageToken, undefined);
81
+ assert.equal(result.collections[0].collectionName, "alpha");
82
+ assert.ok(result.collections[0].createdAt instanceof Date);
83
+ assert.equal(result.collections[0].createdAt.toISOString(), "2023-11-14T22:13:20.000Z");
84
+ });
85
+
86
+ test("public pagination helpers collect all collection pages", async () => {
87
+ const { calls, client } = createClient((call, index) => {
88
+ if (index === 0) {
89
+ return jsonResponse({
90
+ collections: [collectionFixture("alpha")],
91
+ nextPageToken: "next-page",
92
+ });
93
+ }
94
+
95
+ assert.equal(call.url.searchParams.get("pageToken"), "next-page");
96
+ return jsonResponse({
97
+ collections: [collectionFixture("beta")],
98
+ nextPageToken: null,
99
+ });
100
+ });
101
+
102
+ const result = await client.listAllCollections({ size: 1 });
103
+
104
+ assert.equal(calls.length, 2);
105
+ assert.deepEqual(
106
+ result.collections.map((collection) => collection.collectionName),
107
+ ["alpha", "beta"],
108
+ );
109
+ });
110
+
111
+ test("collection docs helpers paginate through the user-facing scoped API", async () => {
112
+ const { calls, client } = createClient((call, index) => {
113
+ assert.equal(call.method, "GET");
114
+ assert.equal(call.url.pathname, "/projects/project-one/collections/items/docs");
115
+
116
+ if (index === 0) {
117
+ return jsonResponse({
118
+ total: 2,
119
+ docs: [{ collection: "items", doc: { id: "a" } }],
120
+ nextPageToken: "docs-page-2",
121
+ isDocsInline: true,
122
+ docsUrl: null,
123
+ });
124
+ }
125
+
126
+ assert.equal(call.url.searchParams.get("pageToken"), "docs-page-2");
127
+ return jsonResponse({
128
+ total: 2,
129
+ docs: [{ collection: "items", doc: { id: "b" } }],
130
+ nextPageToken: null,
131
+ isDocsInline: true,
132
+ docsUrl: null,
133
+ });
134
+ });
135
+
136
+ const result = await client.collection("items").docs.listAll({ size: 1 });
137
+
138
+ assert.equal(calls.length, 2);
139
+ assert.equal(result.total, 2);
140
+ assert.deepEqual(result.docs, [
141
+ { collection: "items", doc: { id: "a" } },
142
+ { collection: "items", doc: { id: "b" } },
143
+ ]);
144
+ });
145
+
146
+ test("collection query fetches docsUrl and returns inline docs through the public API", async () => {
147
+ const originalFetch = globalThis.fetch;
148
+ const docsUrlCalls = [];
149
+ globalThis.fetch = async (input) => {
150
+ docsUrlCalls.push(String(input));
151
+ return jsonResponse({
152
+ docs: [{ collection: "items", score: 0.9, doc: { id: "a" } }],
153
+ });
154
+ };
155
+
156
+ try {
157
+ const { calls, client } = createClient((call) => {
158
+ assert.equal(call.method, "POST");
159
+ assert.equal(call.url.pathname, "/projects/project-one/collections/items/query");
160
+ assert.deepEqual(JSON.parse(call.body), {
161
+ query: { text: "hello" },
162
+ consistentRead: false,
163
+ includeVectors: false,
164
+ });
165
+
166
+ return jsonResponse({
167
+ took: 7,
168
+ maxScore: null,
169
+ total: 1,
170
+ docs: [],
171
+ isDocsInline: false,
172
+ docsUrl: "https://download.test/query-docs.json",
173
+ });
174
+ });
175
+
176
+ const result = await client.collection("items").querySafe({
177
+ query: { text: "hello" },
178
+ });
179
+
180
+ assert.equal(calls.length, 1);
181
+ assert.deepEqual(docsUrlCalls, ["https://download.test/query-docs.json"]);
182
+ assert.equal(result.ok, true);
183
+ assert.equal(result.value.isDocsInline, true);
184
+ assert.deepEqual(result.value.docs, [
185
+ { collection: "items", score: 0.9, doc: { id: "a" } },
186
+ ]);
187
+ } finally {
188
+ globalThis.fetch = originalFetch;
189
+ }
190
+ });
191
+
192
+ test("public safe methods expose typed API errors", async () => {
193
+ const { client } = createClient((call) => {
194
+ assert.equal(call.method, "POST");
195
+ assert.equal(call.url.pathname, "/projects/project-one/collections");
196
+
197
+ return jsonResponse(
198
+ { message: null },
199
+ { status: 400 },
200
+ );
201
+ });
202
+
203
+ const result = await client.createCollectionSafe({ collectionName: "items" });
204
+
205
+ assert.equal(result.ok, false);
206
+ assert.ok(result.error instanceof BadRequestError);
207
+ assert.equal(result.error.statusCode, 400);
208
+ assert.equal(result.error.body, "{\"message\":null}");
209
+ assert.equal(result.error.data$.message, undefined);
210
+ });
@@ -1,45 +0,0 @@
1
- // For format details, see https://aka.ms/devcontainer.json. For config options, see the
2
- // README at: https://github.com/devcontainers/images/tree/main/src/typescript-node
3
- {
4
- "name": "TypeScript",
5
- "image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bullseye",
6
- // Features to add to the dev container. More info: https://containers.dev/features.
7
- // "features": {},
8
- // Use 'forwardPorts' to make a list of ports inside the container available locally.
9
- // "forwardPorts": [],
10
- // Use 'postCreateCommand' to run commands after the container is created.
11
- "postCreateCommand": "sudo chmod +x ./.devcontainer/setup.sh && ./.devcontainer/setup.sh",
12
- "customizations": {
13
- "vscode": {
14
- "extensions": [
15
- "ms-vscode.vscode-typescript-tslint-plugin",
16
- "esbenp.prettier-vscode",
17
- "github.vscode-pull-request-github"
18
- ],
19
- "settings": {
20
- "files.eol": "\n",
21
- "editor.formatOnSave": true,
22
- "typescript.tsc.autoDetect": "on",
23
- "typescript.updateImportsOnFileMove.enabled": "always",
24
- "typescript.preferences.importModuleSpecifier": "relative",
25
- "[typescript]": {
26
- "editor.codeActionsOnSave": {
27
- "source.organizeImports": true
28
- }
29
- },
30
- "[typescriptreact]": {
31
- "editor.codeActionsOnSave": {
32
- "source.organizeImports": true
33
- }
34
- }
35
- }
36
- },
37
- "codespaces": {
38
- "openFiles": [
39
- ".devcontainer/README.md"
40
- ]
41
- }
42
- }
43
- // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
44
- // "remoteUser": "root"
45
- }