@form-engine-ts/storage-mongodb 2.2.0 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/index.cjs +33 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +40 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -26,3 +26,7 @@ const submissions = await storage.listSubmissions(schema.id, schema.version, {
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
The caller owns the MongoDB connection lifecycle. Collection names can be customized in the factory options. `createIndexes()` creates named indexes for form/timestamp range scans and locale queries. Range boundaries are inclusive, and MongoDB sorts by submission time and then ID. `clearResponses(formId)` preserves schemas and other forms; `clear()` removes documents only from the configured collections and does not drop collections or indexes.
|
|
29
|
+
|
|
30
|
+
`listSubmissionPage(formId, { version, pageSize, cursor, since, until, locale })` performs bounded reads using the
|
|
31
|
+
compound `submittedAt`/response-ID cursor. Run `createIndexes()` after upgrading to create the matching compound index.
|
|
32
|
+
`metadataFilters` and custom `filter` predicates are applied before page sizing.
|
package/dist/index.cjs
CHANGED
|
@@ -118,6 +118,38 @@ function createMongoDbStorage(options) {
|
|
|
118
118
|
}).sort({ submittedAt: 1, _id: 1 }).toArray();
|
|
119
119
|
return documents.map(parseSubmissionDocument);
|
|
120
120
|
},
|
|
121
|
+
async listSubmissionPage(formId, options2 = {}) {
|
|
122
|
+
const pageSize = (0, import_core.normalizeSubmissionPageSize)(options2.pageSize);
|
|
123
|
+
const cursor = options2.cursor === void 0 ? void 0 : (0, import_core.decodeSubmissionCursor)(options2.cursor);
|
|
124
|
+
const submittedAt = options2.since === void 0 && options2.until === void 0 ? void 0 : {
|
|
125
|
+
...options2.since === void 0 ? {} : { $gte: options2.since },
|
|
126
|
+
...options2.until === void 0 ? {} : { $lte: options2.until }
|
|
127
|
+
};
|
|
128
|
+
const filter = {
|
|
129
|
+
formId,
|
|
130
|
+
...options2.version === void 0 ? {} : { formVersion: options2.version },
|
|
131
|
+
...options2.locale === void 0 ? {} : { "submission.locale": options2.locale },
|
|
132
|
+
...submittedAt === void 0 ? {} : { submittedAt },
|
|
133
|
+
...cursor === void 0 ? {} : {
|
|
134
|
+
$or: [
|
|
135
|
+
{ submittedAt: { $gt: cursor.submittedAt } },
|
|
136
|
+
{ submittedAt: cursor.submittedAt, _id: { $gt: cursor.responseId } }
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
const sorted = submissions.find(filter).sort({ submittedAt: 1, _id: 1 });
|
|
141
|
+
const requiresClientFiltering = options2.filter !== void 0 || options2.metadataFilters !== void 0;
|
|
142
|
+
const documents = requiresClientFiltering ? await sorted.toArray() : await sorted.limit(pageSize + 1).toArray();
|
|
143
|
+
const candidates = documents.map(parseSubmissionDocument).filter((item) => (0, import_core.matchesSubmissionPageFilters)(item, options2));
|
|
144
|
+
const hasMore = candidates.length > pageSize;
|
|
145
|
+
const items = candidates.slice(0, pageSize);
|
|
146
|
+
const last = items.at(-1);
|
|
147
|
+
return {
|
|
148
|
+
items,
|
|
149
|
+
hasMore,
|
|
150
|
+
...hasMore && last !== void 0 ? { nextCursor: (0, import_core.encodeSubmissionCursor)({ submittedAt: last.submittedAt, responseId: last.id }) } : {}
|
|
151
|
+
};
|
|
152
|
+
},
|
|
121
153
|
async deleteSubmission(submissionId) {
|
|
122
154
|
await submissions.deleteOne({ _id: submissionId });
|
|
123
155
|
},
|
|
@@ -129,7 +161,7 @@ function createMongoDbStorage(options) {
|
|
|
129
161
|
},
|
|
130
162
|
async createIndexes() {
|
|
131
163
|
await submissions.createIndexes([
|
|
132
|
-
{ key: { formId: 1, submittedAt: 1 }, name: "
|
|
164
|
+
{ key: { formId: 1, submittedAt: 1, _id: 1 }, name: "form_responses_form_submitted_at_id" },
|
|
133
165
|
{ key: { "submission.locale": 1 }, name: "form_responses_locale" }
|
|
134
166
|
]);
|
|
135
167
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PagedSubmissionStorageAdapter } from '@form-engine-ts/core';
|
|
2
2
|
import { Db } from 'mongodb';
|
|
3
3
|
|
|
4
4
|
interface MongoDbStorageOptions {
|
|
@@ -6,7 +6,7 @@ interface MongoDbStorageOptions {
|
|
|
6
6
|
readonly schemasCollectionName?: string;
|
|
7
7
|
readonly responsesCollectionName?: string;
|
|
8
8
|
}
|
|
9
|
-
interface MongoDbStorageAdapter extends
|
|
9
|
+
interface MongoDbStorageAdapter extends PagedSubmissionStorageAdapter {
|
|
10
10
|
createIndexes(): Promise<void>;
|
|
11
11
|
}
|
|
12
12
|
declare function createMongoDbStorage(options: MongoDbStorageOptions): MongoDbStorageAdapter;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PagedSubmissionStorageAdapter } from '@form-engine-ts/core';
|
|
2
2
|
import { Db } from 'mongodb';
|
|
3
3
|
|
|
4
4
|
interface MongoDbStorageOptions {
|
|
@@ -6,7 +6,7 @@ interface MongoDbStorageOptions {
|
|
|
6
6
|
readonly schemasCollectionName?: string;
|
|
7
7
|
readonly responsesCollectionName?: string;
|
|
8
8
|
}
|
|
9
|
-
interface MongoDbStorageAdapter extends
|
|
9
|
+
interface MongoDbStorageAdapter extends PagedSubmissionStorageAdapter {
|
|
10
10
|
createIndexes(): Promise<void>;
|
|
11
11
|
}
|
|
12
12
|
declare function createMongoDbStorage(options: MongoDbStorageOptions): MongoDbStorageAdapter;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
assertValidFormSchema,
|
|
4
|
+
decodeSubmissionCursor,
|
|
5
|
+
encodeSubmissionCursor,
|
|
6
|
+
matchesSubmissionPageFilters,
|
|
7
|
+
normalizeSubmissionPageSize
|
|
8
|
+
} from "@form-engine-ts/core";
|
|
3
9
|
function cloneJson(value) {
|
|
4
10
|
return JSON.parse(JSON.stringify(value));
|
|
5
11
|
}
|
|
@@ -94,6 +100,38 @@ function createMongoDbStorage(options) {
|
|
|
94
100
|
}).sort({ submittedAt: 1, _id: 1 }).toArray();
|
|
95
101
|
return documents.map(parseSubmissionDocument);
|
|
96
102
|
},
|
|
103
|
+
async listSubmissionPage(formId, options2 = {}) {
|
|
104
|
+
const pageSize = normalizeSubmissionPageSize(options2.pageSize);
|
|
105
|
+
const cursor = options2.cursor === void 0 ? void 0 : decodeSubmissionCursor(options2.cursor);
|
|
106
|
+
const submittedAt = options2.since === void 0 && options2.until === void 0 ? void 0 : {
|
|
107
|
+
...options2.since === void 0 ? {} : { $gte: options2.since },
|
|
108
|
+
...options2.until === void 0 ? {} : { $lte: options2.until }
|
|
109
|
+
};
|
|
110
|
+
const filter = {
|
|
111
|
+
formId,
|
|
112
|
+
...options2.version === void 0 ? {} : { formVersion: options2.version },
|
|
113
|
+
...options2.locale === void 0 ? {} : { "submission.locale": options2.locale },
|
|
114
|
+
...submittedAt === void 0 ? {} : { submittedAt },
|
|
115
|
+
...cursor === void 0 ? {} : {
|
|
116
|
+
$or: [
|
|
117
|
+
{ submittedAt: { $gt: cursor.submittedAt } },
|
|
118
|
+
{ submittedAt: cursor.submittedAt, _id: { $gt: cursor.responseId } }
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
const sorted = submissions.find(filter).sort({ submittedAt: 1, _id: 1 });
|
|
123
|
+
const requiresClientFiltering = options2.filter !== void 0 || options2.metadataFilters !== void 0;
|
|
124
|
+
const documents = requiresClientFiltering ? await sorted.toArray() : await sorted.limit(pageSize + 1).toArray();
|
|
125
|
+
const candidates = documents.map(parseSubmissionDocument).filter((item) => matchesSubmissionPageFilters(item, options2));
|
|
126
|
+
const hasMore = candidates.length > pageSize;
|
|
127
|
+
const items = candidates.slice(0, pageSize);
|
|
128
|
+
const last = items.at(-1);
|
|
129
|
+
return {
|
|
130
|
+
items,
|
|
131
|
+
hasMore,
|
|
132
|
+
...hasMore && last !== void 0 ? { nextCursor: encodeSubmissionCursor({ submittedAt: last.submittedAt, responseId: last.id }) } : {}
|
|
133
|
+
};
|
|
134
|
+
},
|
|
97
135
|
async deleteSubmission(submissionId) {
|
|
98
136
|
await submissions.deleteOne({ _id: submissionId });
|
|
99
137
|
},
|
|
@@ -105,7 +143,7 @@ function createMongoDbStorage(options) {
|
|
|
105
143
|
},
|
|
106
144
|
async createIndexes() {
|
|
107
145
|
await submissions.createIndexes([
|
|
108
|
-
{ key: { formId: 1, submittedAt: 1 }, name: "
|
|
146
|
+
{ key: { formId: 1, submittedAt: 1, _id: 1 }, name: "form_responses_form_submitted_at_id" },
|
|
109
147
|
{ key: { "submission.locale": 1 }, name: "form_responses_locale" }
|
|
110
148
|
]);
|
|
111
149
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@form-engine-ts/storage-mongodb",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"typescript"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@form-engine-ts/core": "2.
|
|
42
|
+
"@form-engine-ts/core": "2.5.1"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"mongodb": "^6.0.0"
|