@byline/db-postgres 2.7.0 → 3.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.
- package/dist/database/schema/index.d.ts +190 -0
- package/dist/database/schema/index.js +60 -1
- package/dist/index.d.ts +55 -4
- package/dist/index.js +5 -1
- package/dist/modules/storage/storage-commands.d.ts +141 -3
- package/dist/modules/storage/storage-commands.js +388 -10
- package/dist/modules/storage/storage-queries.d.ts +90 -12
- package/dist/modules/storage/storage-queries.js +285 -48
- package/dist/modules/storage/tests/storage-document-available-locales.test.d.ts +8 -0
- package/dist/modules/storage/tests/storage-document-available-locales.test.js +198 -0
- package/dist/modules/storage/tests/storage-locale-fallback.test.d.ts +8 -0
- package/dist/modules/storage/tests/storage-locale-fallback.test.js +615 -0
- package/package.json +4 -4
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This Source Code is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) Infonomic Company Limited
|
|
7
|
+
*/
|
|
8
|
+
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
9
|
+
import { setupTestDB, teardownTestDB } from '../../../lib/test-helper.js';
|
|
10
|
+
let commandBuilders;
|
|
11
|
+
let queryBuilders;
|
|
12
|
+
const timestamp = Date.now();
|
|
13
|
+
const AdvertiseCollectionConfig = {
|
|
14
|
+
path: `advertise-${timestamp}`,
|
|
15
|
+
labels: { singular: 'AdvertiseTest', plural: 'AdvertiseTests' },
|
|
16
|
+
fields: [{ name: 'title', type: 'text', localized: true }],
|
|
17
|
+
};
|
|
18
|
+
let testCollection = {};
|
|
19
|
+
function readById(documentId) {
|
|
20
|
+
return queryBuilders.documents.getDocumentById({
|
|
21
|
+
collection_id: testCollection.id,
|
|
22
|
+
document_id: documentId,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
describe('byline_document_available_locales integration', () => {
|
|
26
|
+
beforeAll(async () => {
|
|
27
|
+
const testDB = setupTestDB([AdvertiseCollectionConfig]);
|
|
28
|
+
commandBuilders = testDB.commandBuilders;
|
|
29
|
+
queryBuilders = testDB.queryBuilders;
|
|
30
|
+
const result = await commandBuilders.collections.create(AdvertiseCollectionConfig.path, AdvertiseCollectionConfig);
|
|
31
|
+
const collection = result[0];
|
|
32
|
+
if (collection == null) {
|
|
33
|
+
throw new Error('Failed to create test collection');
|
|
34
|
+
}
|
|
35
|
+
testCollection = { id: collection.id, name: collection.path };
|
|
36
|
+
});
|
|
37
|
+
afterAll(async () => {
|
|
38
|
+
try {
|
|
39
|
+
await commandBuilders.collections.delete(testCollection.id);
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.error('Failed to cleanup test collection:', error);
|
|
43
|
+
}
|
|
44
|
+
await teardownTestDB();
|
|
45
|
+
});
|
|
46
|
+
it('surfaces the advertised set on a detail read, sorted', async () => {
|
|
47
|
+
const created = await commandBuilders.documents.createDocumentVersion({
|
|
48
|
+
collectionId: testCollection.id,
|
|
49
|
+
collectionVersion: 1,
|
|
50
|
+
collectionConfig: AdvertiseCollectionConfig,
|
|
51
|
+
action: 'create',
|
|
52
|
+
documentData: { title: 'Hello' },
|
|
53
|
+
availableLocales: ['fr', 'en', 'de'],
|
|
54
|
+
locale: 'all',
|
|
55
|
+
status: 'draft',
|
|
56
|
+
});
|
|
57
|
+
const doc = await readById(created.document.document_id);
|
|
58
|
+
expect(doc?.availableLocales, 'sorted advertised locales').toEqual(['de', 'en', 'fr']);
|
|
59
|
+
});
|
|
60
|
+
it('defaults to an empty set when no advertised locales were ever written', async () => {
|
|
61
|
+
const created = await commandBuilders.documents.createDocumentVersion({
|
|
62
|
+
collectionId: testCollection.id,
|
|
63
|
+
collectionVersion: 1,
|
|
64
|
+
collectionConfig: AdvertiseCollectionConfig,
|
|
65
|
+
action: 'create',
|
|
66
|
+
documentData: { title: 'None' },
|
|
67
|
+
locale: 'all',
|
|
68
|
+
status: 'draft',
|
|
69
|
+
});
|
|
70
|
+
const doc = await readById(created.document.document_id);
|
|
71
|
+
expect(doc?.availableLocales).toEqual([]);
|
|
72
|
+
});
|
|
73
|
+
it('replaces the set wholesale on re-save (not merged)', async () => {
|
|
74
|
+
const first = await commandBuilders.documents.createDocumentVersion({
|
|
75
|
+
collectionId: testCollection.id,
|
|
76
|
+
collectionVersion: 1,
|
|
77
|
+
collectionConfig: AdvertiseCollectionConfig,
|
|
78
|
+
action: 'create',
|
|
79
|
+
documentData: { title: 'V1' },
|
|
80
|
+
availableLocales: ['en', 'fr'],
|
|
81
|
+
locale: 'all',
|
|
82
|
+
status: 'draft',
|
|
83
|
+
});
|
|
84
|
+
const documentId = first.document.document_id;
|
|
85
|
+
await commandBuilders.documents.createDocumentVersion({
|
|
86
|
+
documentId,
|
|
87
|
+
collectionId: testCollection.id,
|
|
88
|
+
collectionVersion: 1,
|
|
89
|
+
collectionConfig: AdvertiseCollectionConfig,
|
|
90
|
+
action: 'update',
|
|
91
|
+
documentData: { title: 'V2' },
|
|
92
|
+
availableLocales: ['de'],
|
|
93
|
+
locale: 'all',
|
|
94
|
+
status: 'draft',
|
|
95
|
+
previousVersionId: first.document.id,
|
|
96
|
+
});
|
|
97
|
+
const doc = await readById(documentId);
|
|
98
|
+
expect(doc?.availableLocales, 'fr/en gone, only de remains').toEqual(['de']);
|
|
99
|
+
});
|
|
100
|
+
it('leaves the set untouched when the param is omitted (sticky across versions)', async () => {
|
|
101
|
+
const first = await commandBuilders.documents.createDocumentVersion({
|
|
102
|
+
collectionId: testCollection.id,
|
|
103
|
+
collectionVersion: 1,
|
|
104
|
+
collectionConfig: AdvertiseCollectionConfig,
|
|
105
|
+
action: 'create',
|
|
106
|
+
documentData: { title: 'Sticky V1' },
|
|
107
|
+
availableLocales: ['en', 'de'],
|
|
108
|
+
locale: 'all',
|
|
109
|
+
status: 'draft',
|
|
110
|
+
});
|
|
111
|
+
const documentId = first.document.document_id;
|
|
112
|
+
// New version, no availableLocales param — advertising must carry forward.
|
|
113
|
+
await commandBuilders.documents.createDocumentVersion({
|
|
114
|
+
documentId,
|
|
115
|
+
collectionId: testCollection.id,
|
|
116
|
+
collectionVersion: 1,
|
|
117
|
+
collectionConfig: AdvertiseCollectionConfig,
|
|
118
|
+
action: 'update',
|
|
119
|
+
documentData: { title: 'Sticky V2' },
|
|
120
|
+
locale: 'all',
|
|
121
|
+
status: 'draft',
|
|
122
|
+
previousVersionId: first.document.id,
|
|
123
|
+
});
|
|
124
|
+
const doc = await readById(documentId);
|
|
125
|
+
expect(doc?.availableLocales, 'editorial intent carried forward').toEqual(['de', 'en']);
|
|
126
|
+
});
|
|
127
|
+
it('clears the set when given an empty array', async () => {
|
|
128
|
+
const first = await commandBuilders.documents.createDocumentVersion({
|
|
129
|
+
collectionId: testCollection.id,
|
|
130
|
+
collectionVersion: 1,
|
|
131
|
+
collectionConfig: AdvertiseCollectionConfig,
|
|
132
|
+
action: 'create',
|
|
133
|
+
documentData: { title: 'Clear V1' },
|
|
134
|
+
availableLocales: ['en', 'fr'],
|
|
135
|
+
locale: 'all',
|
|
136
|
+
status: 'draft',
|
|
137
|
+
});
|
|
138
|
+
const documentId = first.document.document_id;
|
|
139
|
+
await commandBuilders.documents.createDocumentVersion({
|
|
140
|
+
documentId,
|
|
141
|
+
collectionId: testCollection.id,
|
|
142
|
+
collectionVersion: 1,
|
|
143
|
+
collectionConfig: AdvertiseCollectionConfig,
|
|
144
|
+
action: 'update',
|
|
145
|
+
documentData: { title: 'Clear V2' },
|
|
146
|
+
availableLocales: [],
|
|
147
|
+
locale: 'all',
|
|
148
|
+
status: 'draft',
|
|
149
|
+
previousVersionId: first.document.id,
|
|
150
|
+
});
|
|
151
|
+
const doc = await readById(documentId);
|
|
152
|
+
expect(doc?.availableLocales, 'empty array clears advertising').toEqual([]);
|
|
153
|
+
});
|
|
154
|
+
it('deduplicates caller-supplied duplicate locales', async () => {
|
|
155
|
+
const created = await commandBuilders.documents.createDocumentVersion({
|
|
156
|
+
collectionId: testCollection.id,
|
|
157
|
+
collectionVersion: 1,
|
|
158
|
+
collectionConfig: AdvertiseCollectionConfig,
|
|
159
|
+
action: 'create',
|
|
160
|
+
documentData: { title: 'Dupes' },
|
|
161
|
+
availableLocales: ['en', 'en', 'fr', 'fr', 'fr'],
|
|
162
|
+
locale: 'all',
|
|
163
|
+
status: 'draft',
|
|
164
|
+
});
|
|
165
|
+
const doc = await readById(created.document.document_id);
|
|
166
|
+
expect(doc?.availableLocales, 'duplicates collapse, no PK violation').toEqual(['en', 'fr']);
|
|
167
|
+
});
|
|
168
|
+
it('surfaces the advertised set per row on a list read', async () => {
|
|
169
|
+
const a = await commandBuilders.documents.createDocumentVersion({
|
|
170
|
+
collectionId: testCollection.id,
|
|
171
|
+
collectionVersion: 1,
|
|
172
|
+
collectionConfig: AdvertiseCollectionConfig,
|
|
173
|
+
action: 'create',
|
|
174
|
+
documentData: { title: 'List-A' },
|
|
175
|
+
availableLocales: ['en', 'fr'],
|
|
176
|
+
locale: 'all',
|
|
177
|
+
status: 'draft',
|
|
178
|
+
});
|
|
179
|
+
const b = await commandBuilders.documents.createDocumentVersion({
|
|
180
|
+
collectionId: testCollection.id,
|
|
181
|
+
collectionVersion: 1,
|
|
182
|
+
collectionConfig: AdvertiseCollectionConfig,
|
|
183
|
+
action: 'create',
|
|
184
|
+
documentData: { title: 'List-B' },
|
|
185
|
+
availableLocales: ['de'],
|
|
186
|
+
locale: 'all',
|
|
187
|
+
status: 'draft',
|
|
188
|
+
});
|
|
189
|
+
const { documents } = await queryBuilders.documents.findDocuments({
|
|
190
|
+
collection_id: testCollection.id,
|
|
191
|
+
locale: 'all',
|
|
192
|
+
pageSize: 200,
|
|
193
|
+
});
|
|
194
|
+
const byId = new Map(documents.map((d) => [d.document_id, d]));
|
|
195
|
+
expect(byId.get(a.document.document_id)?.availableLocales).toEqual(['en', 'fr']);
|
|
196
|
+
expect(byId.get(b.document.document_id)?.availableLocales).toEqual(['de']);
|
|
197
|
+
});
|
|
198
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This Source Code is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) Infonomic Company Limited
|
|
7
|
+
*/
|
|
8
|
+
export {};
|