@roit/roit-data-firestore 1.2.46 → 1.2.47
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/archive/ArchiveService.d.ts +39 -32
- package/dist/archive/ArchiveService.js +65 -54
- package/dist/archive/IArchivePlugin.d.ts +47 -33
- package/dist/archive/IArchivePlugin.js +21 -6
- package/dist/archive/index.d.ts +1 -1
- package/dist/archive/index.js +3 -1
- package/dist/query/ManualQueryHelper.d.ts +1 -1
- package/dist/query/ManualQueryHelper.js +9 -8
- package/dist/query/QueryPredicateFunctionTransform.js +2 -1
- package/dist/template/FunctionCreateOrUpdateTemplate.txt +3 -7
- package/dist/template/FunctionDeleteTemplate.txt +3 -2
- package/dist/template/FunctionUpdatePartialTemplate.txt +4 -7
- package/dist/template/FunctionUpdateTemplate.txt +4 -7
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Interface
|
|
2
|
+
* Interface for options to update an archived document
|
|
3
3
|
*/
|
|
4
4
|
interface UpdateArchivedDocumentOptions {
|
|
5
|
-
/**
|
|
5
|
+
/** If true, removes the archived document after the update (unarchiving) */
|
|
6
6
|
unarchive?: boolean;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* Result of archive operations
|
|
10
10
|
*/
|
|
11
11
|
interface ArchiveOperationResult {
|
|
12
12
|
success: boolean;
|
|
@@ -18,72 +18,79 @@ export declare class ArchiveService {
|
|
|
18
18
|
private static readonly lock;
|
|
19
19
|
private static isInitializing;
|
|
20
20
|
private config;
|
|
21
|
-
/** ProjectId
|
|
21
|
+
/** ProjectId of the Firestore being archived (for path organization) */
|
|
22
22
|
private projectId;
|
|
23
23
|
private isInitialized;
|
|
24
24
|
private logger;
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* Private constructor to prevent direct instantiation
|
|
27
27
|
*/
|
|
28
28
|
private constructor();
|
|
29
29
|
static getInstance(): Promise<ArchiveService>;
|
|
30
30
|
private initialize;
|
|
31
31
|
static resetInstance(): void;
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
33
|
+
* Checks if the archive is enabled
|
|
34
|
+
* Requires the firestore-archive plugin to be registered
|
|
35
35
|
*/
|
|
36
36
|
isEnabled(): boolean;
|
|
37
37
|
/**
|
|
38
|
-
*
|
|
38
|
+
* Checks if a document is archived
|
|
39
39
|
*/
|
|
40
40
|
isDocumentArchived(documentData: any): boolean;
|
|
41
41
|
/**
|
|
42
|
-
*
|
|
42
|
+
* Returns the Cloud Storage path of the archived payload for a stub document.
|
|
43
|
+
*
|
|
44
|
+
* Marker-only: reads from `_rfa.archivePath`.
|
|
45
|
+
* Returns the trimmed string or undefined when missing/invalid.
|
|
46
|
+
*/
|
|
47
|
+
static getArchivePath(documentData: any): string | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Checks if a document is archived and retrieves its complete data
|
|
43
50
|
*/
|
|
44
51
|
getArchivedDocument(collectionName: string, doc: any): Promise<Record<string, any> | null>;
|
|
45
52
|
/**
|
|
46
|
-
*
|
|
47
|
-
*
|
|
53
|
+
* Updates an archived document in Cloud Storage
|
|
54
|
+
* Used when an archived document is updated in Firestore
|
|
48
55
|
*
|
|
49
|
-
* @param collectionName -
|
|
50
|
-
* @param docId - ID
|
|
51
|
-
* @param newData -
|
|
52
|
-
* @param archivePath -
|
|
53
|
-
* @param options -
|
|
54
|
-
* @returns
|
|
56
|
+
* @param collectionName - Collection name
|
|
57
|
+
* @param docId - Document ID
|
|
58
|
+
* @param newData - New data to merge with the archived document
|
|
59
|
+
* @param archivePath - Full object path in Storage, usually the stub's `_rfa.archivePath`.
|
|
60
|
+
* @param options - Update options
|
|
61
|
+
* @returns Operation result and merged data
|
|
55
62
|
*/
|
|
56
63
|
updateArchivedDocument(collectionName: string, docId: string, newData: Record<string, any>, archivePath: string, options?: UpdateArchivedDocumentOptions): Promise<{
|
|
57
64
|
result: ArchiveOperationResult;
|
|
58
65
|
mergedData?: Record<string, any>;
|
|
59
66
|
}>;
|
|
60
67
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
68
|
+
* Deletes an archived document from Cloud Storage
|
|
69
|
+
* Used when a document is permanently deleted or restored
|
|
63
70
|
*
|
|
64
|
-
* @param collectionName -
|
|
65
|
-
* @param docId - ID
|
|
66
|
-
* @param archivePath -
|
|
67
|
-
* @returns
|
|
71
|
+
* @param collectionName - Collection name
|
|
72
|
+
* @param docId - Document ID
|
|
73
|
+
* @param archivePath - Full object path in Storage, usually the stub's `_rfa.archivePath`.
|
|
74
|
+
* @returns Operation result
|
|
68
75
|
*/
|
|
69
76
|
deleteArchivedDocument(collectionName: string, docId: string, archivePath: string): Promise<ArchiveOperationResult>;
|
|
70
77
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
78
|
+
* Retrieves complete data of an archived document and prepares it for restoration
|
|
79
|
+
* Combines the stub data (Firestore) with the archived data (Storage)
|
|
73
80
|
*
|
|
74
|
-
* @param collectionName -
|
|
75
|
-
* @param stubData -
|
|
76
|
-
* @returns
|
|
81
|
+
* @param collectionName - Collection name
|
|
82
|
+
* @param stubData - Stub data in Firestore (includes _rfa)
|
|
83
|
+
* @returns Complete merged data or null if not found
|
|
77
84
|
*/
|
|
78
85
|
getCompleteArchivedDocument(collectionName: string, stubData: Record<string, any>): Promise<Record<string, any> | null>;
|
|
79
86
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
87
|
+
* Clears the cache of archived documents
|
|
88
|
+
* Delegates to the firestore-archive plugin
|
|
82
89
|
*/
|
|
83
90
|
clearArchivedCache(collectionName?: string, docId?: string): Promise<void>;
|
|
84
91
|
/**
|
|
85
|
-
*
|
|
86
|
-
* (
|
|
92
|
+
* Returns the projectId of the Firestore being archived
|
|
93
|
+
* (used for path organization in Storage)
|
|
87
94
|
*/
|
|
88
95
|
getProjectId(): string;
|
|
89
96
|
}
|
|
@@ -4,7 +4,7 @@ exports.ArchiveService = void 0;
|
|
|
4
4
|
const ArchiveConfig_1 = require("../config/ArchiveConfig");
|
|
5
5
|
const index_1 = require("./index");
|
|
6
6
|
/**
|
|
7
|
-
* Logger
|
|
7
|
+
* Logger for ArchiveService
|
|
8
8
|
*/
|
|
9
9
|
class ArchiveLogger {
|
|
10
10
|
constructor(debug) {
|
|
@@ -30,23 +30,23 @@ class ArchiveLogger {
|
|
|
30
30
|
}
|
|
31
31
|
class ArchiveService {
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
33
|
+
* Private constructor to prevent direct instantiation
|
|
34
34
|
*/
|
|
35
35
|
constructor() {
|
|
36
36
|
this.isInitialized = false;
|
|
37
|
-
//
|
|
37
|
+
// Empty constructor - initialization will be done in initialize()
|
|
38
38
|
}
|
|
39
39
|
static async getInstance() {
|
|
40
|
-
//
|
|
40
|
+
// If an instance already exists, return it
|
|
41
41
|
if (ArchiveService.instance && ArchiveService.instance.isInitialized) {
|
|
42
42
|
return ArchiveService.instance;
|
|
43
43
|
}
|
|
44
|
-
//
|
|
44
|
+
// If initializing, wait
|
|
45
45
|
if (ArchiveService.isInitializing) {
|
|
46
46
|
await ArchiveService.lock;
|
|
47
47
|
return ArchiveService.instance;
|
|
48
48
|
}
|
|
49
|
-
//
|
|
49
|
+
// Initialize the instance
|
|
50
50
|
ArchiveService.isInitializing = true;
|
|
51
51
|
try {
|
|
52
52
|
if (!ArchiveService.instance) {
|
|
@@ -65,20 +65,20 @@ class ArchiveService {
|
|
|
65
65
|
}
|
|
66
66
|
this.config = ArchiveConfig_1.ArchiveConfig.getConfig();
|
|
67
67
|
this.logger = new ArchiveLogger(this.config.debug);
|
|
68
|
-
// ProjectId
|
|
68
|
+
// ProjectId of the Firestore being archived (used for paths in Storage)
|
|
69
69
|
this.projectId = this.config.projectId;
|
|
70
70
|
if (!this.projectId) {
|
|
71
|
-
this.logger.warn('projectId
|
|
71
|
+
this.logger.warn('projectId not configured - using environment variable');
|
|
72
72
|
this.projectId = process.env.FIRESTORE_PROJECTID || process.env.GCP_PROJECT || '';
|
|
73
73
|
}
|
|
74
74
|
this.logger.debug(`Configuração: projectId=${this.projectId}, enabled=${this.config.enabled}`);
|
|
75
75
|
if (!this.config.enabled) {
|
|
76
|
-
this.logger.info('
|
|
76
|
+
this.logger.info('Archive disabled via configuration');
|
|
77
77
|
this.isInitialized = true;
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
80
80
|
if (!(0, index_1.hasArchivePlugin)()) {
|
|
81
|
-
this.logger.warn('Plugin firestore-archive
|
|
81
|
+
this.logger.warn('Plugin firestore-archive not registered - archive disabled');
|
|
82
82
|
}
|
|
83
83
|
this.isInitialized = true;
|
|
84
84
|
}
|
|
@@ -87,15 +87,15 @@ class ArchiveService {
|
|
|
87
87
|
ArchiveService.isInitializing = false;
|
|
88
88
|
}
|
|
89
89
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
90
|
+
* Checks if the archive is enabled
|
|
91
|
+
* Requires the firestore-archive plugin to be registered
|
|
92
92
|
*/
|
|
93
93
|
isEnabled() {
|
|
94
|
-
//
|
|
94
|
+
// Archive only works with registered plugin
|
|
95
95
|
return this.config.enabled && (0, index_1.hasArchivePlugin)();
|
|
96
96
|
}
|
|
97
97
|
/**
|
|
98
|
-
*
|
|
98
|
+
* Checks if a document is archived
|
|
99
99
|
*/
|
|
100
100
|
isDocumentArchived(documentData) {
|
|
101
101
|
if (!this.isEnabled()) {
|
|
@@ -104,20 +104,31 @@ class ArchiveService {
|
|
|
104
104
|
return (0, index_1.getArchivePlugin)().isDocumentArchived(documentData);
|
|
105
105
|
}
|
|
106
106
|
/**
|
|
107
|
-
*
|
|
107
|
+
* Returns the Cloud Storage path of the archived payload for a stub document.
|
|
108
|
+
*
|
|
109
|
+
* Marker-only: reads from `_rfa.archivePath`.
|
|
110
|
+
* Returns the trimmed string or undefined when missing/invalid.
|
|
111
|
+
*/
|
|
112
|
+
static getArchivePath(documentData) {
|
|
113
|
+
const marker = (0, index_1.getArchiveMarker)(documentData);
|
|
114
|
+
if (!marker || typeof marker.archivePath !== 'string')
|
|
115
|
+
return undefined;
|
|
116
|
+
const trimmed = marker.archivePath.trim();
|
|
117
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Checks if a document is archived and retrieves its complete data
|
|
108
121
|
*/
|
|
109
122
|
async getArchivedDocument(collectionName, doc) {
|
|
110
123
|
if (!this.isEnabled()) {
|
|
111
124
|
return null;
|
|
112
125
|
}
|
|
113
126
|
const docId = doc.id;
|
|
114
|
-
const archivePath =
|
|
115
|
-
|
|
116
|
-
:
|
|
117
|
-
if (!archivePath || archivePath.trim().length === 0) {
|
|
118
|
-
throw new Error(`ArchiveService.getArchivedDocument: fbArchivePath is required. collection=${collectionName} docId=${docId}`);
|
|
127
|
+
const archivePath = ArchiveService.getArchivePath(doc) || '';
|
|
128
|
+
if (!archivePath) {
|
|
129
|
+
throw new Error(`ArchiveService.getArchivedDocument: ${index_1.ARCHIVE_METADATA_FIELDS.ARCHIVE_PATH} is required. collection=${collectionName} docId=${docId}`);
|
|
119
130
|
}
|
|
120
|
-
//
|
|
131
|
+
// Delegate to plugin (isEnabled already ensures it exists)
|
|
121
132
|
return (0, index_1.getArchivePlugin)().getArchivedDocument({
|
|
122
133
|
collection: collectionName,
|
|
123
134
|
docId,
|
|
@@ -126,24 +137,24 @@ class ArchiveService {
|
|
|
126
137
|
});
|
|
127
138
|
}
|
|
128
139
|
/**
|
|
129
|
-
*
|
|
130
|
-
*
|
|
140
|
+
* Updates an archived document in Cloud Storage
|
|
141
|
+
* Used when an archived document is updated in Firestore
|
|
131
142
|
*
|
|
132
|
-
* @param collectionName -
|
|
133
|
-
* @param docId - ID
|
|
134
|
-
* @param newData -
|
|
135
|
-
* @param archivePath -
|
|
136
|
-
* @param options -
|
|
137
|
-
* @returns
|
|
143
|
+
* @param collectionName - Collection name
|
|
144
|
+
* @param docId - Document ID
|
|
145
|
+
* @param newData - New data to merge with the archived document
|
|
146
|
+
* @param archivePath - Full object path in Storage, usually the stub's `_rfa.archivePath`.
|
|
147
|
+
* @param options - Update options
|
|
148
|
+
* @returns Operation result and merged data
|
|
138
149
|
*/
|
|
139
150
|
async updateArchivedDocument(collectionName, docId, newData, archivePath, options) {
|
|
140
151
|
if (!this.isEnabled()) {
|
|
141
152
|
return { result: { success: false, message: 'Arquivamento desabilitado ou plugin não registrado' } };
|
|
142
153
|
}
|
|
143
154
|
if (!archivePath || typeof archivePath !== 'string' || archivePath.trim().length === 0) {
|
|
144
|
-
throw new Error(`ArchiveService.updateArchivedDocument:
|
|
155
|
+
throw new Error(`ArchiveService.updateArchivedDocument: ${index_1.ARCHIVE_METADATA_FIELDS.ARCHIVE_PATH} is required. collection=${collectionName} docId=${docId}`);
|
|
145
156
|
}
|
|
146
|
-
//
|
|
157
|
+
// Delegate to plugin (isEnabled already ensures it exists)
|
|
147
158
|
return (0, index_1.getArchivePlugin)().updateArchivedDocument({
|
|
148
159
|
collection: collectionName,
|
|
149
160
|
docId,
|
|
@@ -154,22 +165,22 @@ class ArchiveService {
|
|
|
154
165
|
});
|
|
155
166
|
}
|
|
156
167
|
/**
|
|
157
|
-
*
|
|
158
|
-
*
|
|
168
|
+
* Deletes an archived document from Cloud Storage
|
|
169
|
+
* Used when a document is permanently deleted or restored
|
|
159
170
|
*
|
|
160
|
-
* @param collectionName -
|
|
161
|
-
* @param docId - ID
|
|
162
|
-
* @param archivePath -
|
|
163
|
-
* @returns
|
|
171
|
+
* @param collectionName - Collection name
|
|
172
|
+
* @param docId - Document ID
|
|
173
|
+
* @param archivePath - Full object path in Storage, usually the stub's `_rfa.archivePath`.
|
|
174
|
+
* @returns Operation result
|
|
164
175
|
*/
|
|
165
176
|
async deleteArchivedDocument(collectionName, docId, archivePath) {
|
|
166
177
|
if (!this.isEnabled()) {
|
|
167
|
-
return { success: false, message: '
|
|
178
|
+
return { success: false, message: 'Archive disabled or plugin not registered' };
|
|
168
179
|
}
|
|
169
180
|
if (!archivePath || typeof archivePath !== 'string' || archivePath.trim().length === 0) {
|
|
170
|
-
throw new Error(`ArchiveService.deleteArchivedDocument:
|
|
181
|
+
throw new Error(`ArchiveService.deleteArchivedDocument: ${index_1.ARCHIVE_METADATA_FIELDS.ARCHIVE_PATH} is required. collection=${collectionName} docId=${docId}`);
|
|
171
182
|
}
|
|
172
|
-
//
|
|
183
|
+
// Delegate to plugin (isEnabled already ensures it exists)
|
|
173
184
|
return (0, index_1.getArchivePlugin)().deleteArchivedDocument({
|
|
174
185
|
collection: collectionName,
|
|
175
186
|
docId,
|
|
@@ -178,12 +189,12 @@ class ArchiveService {
|
|
|
178
189
|
});
|
|
179
190
|
}
|
|
180
191
|
/**
|
|
181
|
-
*
|
|
182
|
-
*
|
|
192
|
+
* Retrieves complete data of an archived document and prepares it for restoration
|
|
193
|
+
* Combines the stub data (Firestore) with the archived data (Storage)
|
|
183
194
|
*
|
|
184
|
-
* @param collectionName -
|
|
185
|
-
* @param stubData -
|
|
186
|
-
* @returns
|
|
195
|
+
* @param collectionName - Collection name
|
|
196
|
+
* @param stubData - Stub data in Firestore (includes _rfa)
|
|
197
|
+
* @returns Complete merged data or null if not found
|
|
187
198
|
*/
|
|
188
199
|
async getCompleteArchivedDocument(collectionName, stubData) {
|
|
189
200
|
if (!this.isDocumentArchived(stubData)) {
|
|
@@ -191,16 +202,16 @@ class ArchiveService {
|
|
|
191
202
|
}
|
|
192
203
|
const archivedData = await this.getArchivedDocument(collectionName, stubData);
|
|
193
204
|
if (!archivedData) {
|
|
194
|
-
this.logger.warn(`
|
|
195
|
-
return stubData; //
|
|
205
|
+
this.logger.warn(`Archived data not found for document: ${collectionName}/${stubData.id}`);
|
|
206
|
+
return stubData; // Return stub if archived data is not found
|
|
196
207
|
}
|
|
197
|
-
//
|
|
198
|
-
const
|
|
199
|
-
return { ...stubData, ...archivedData,
|
|
208
|
+
// Merge: storage data overwrites the stub, except the marker _rfa
|
|
209
|
+
const marker = stubData?.[index_1.ARCHIVE_MARKER_KEY];
|
|
210
|
+
return { ...stubData, ...archivedData, [index_1.ARCHIVE_MARKER_KEY]: marker };
|
|
200
211
|
}
|
|
201
212
|
/**
|
|
202
|
-
*
|
|
203
|
-
*
|
|
213
|
+
* Clears the cache of archived documents
|
|
214
|
+
* Delegates to the firestore-archive plugin
|
|
204
215
|
*/
|
|
205
216
|
async clearArchivedCache(collectionName, docId) {
|
|
206
217
|
if (!this.isEnabled()) {
|
|
@@ -209,8 +220,8 @@ class ArchiveService {
|
|
|
209
220
|
await (0, index_1.getArchivePlugin)().invalidateCache(collectionName, docId);
|
|
210
221
|
}
|
|
211
222
|
/**
|
|
212
|
-
*
|
|
213
|
-
* (
|
|
223
|
+
* Returns the projectId of the Firestore being archived
|
|
224
|
+
* (used for path organization in Storage)
|
|
214
225
|
*/
|
|
215
226
|
getProjectId() {
|
|
216
227
|
return this.projectId;
|
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Interface
|
|
2
|
+
* Interface for archive plugins
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* This interface defines the contract that archive plugins must implement.
|
|
5
|
+
* The `firestore-archive` plugin implements this interface.
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
8
8
|
* ```typescript
|
|
9
9
|
* import { registerArchivePlugin } from '@roit/roit-data-firestore';
|
|
10
10
|
* import { createArchivePlugin } from 'firestore-archive';
|
|
11
11
|
*
|
|
12
|
-
* //
|
|
12
|
+
* // Register the plugin at the beginning of the application
|
|
13
13
|
* registerArchivePlugin(createArchivePlugin());
|
|
14
14
|
* ```
|
|
15
15
|
*/
|
|
16
16
|
export interface IArchivePlugin {
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
18
|
+
* Checks if the archive is enabled
|
|
19
19
|
*/
|
|
20
20
|
isEnabled(): boolean;
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
22
|
+
* Checks if a document is archived (has _rfa.archivedAt)
|
|
23
23
|
*/
|
|
24
24
|
isDocumentArchived(doc: Record<string, unknown>): boolean;
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* Retrieves an archived document from Storage.
|
|
27
27
|
*
|
|
28
|
-
* @param collection -
|
|
29
|
-
* @param docId - ID
|
|
30
|
-
* @param archivePath -
|
|
31
|
-
* @param projectId - ID
|
|
32
|
-
* @returns
|
|
28
|
+
* @param collection - Collection name
|
|
29
|
+
* @param docId - Document ID
|
|
30
|
+
* @param archivePath - Full object path in Storage, usually the stub's `_rfa.archivePath`.
|
|
31
|
+
* @param projectId - Project ID (optional)
|
|
32
|
+
* @returns Operation result
|
|
33
33
|
*/
|
|
34
34
|
getArchivedDocument(params: {
|
|
35
35
|
collection: string;
|
|
@@ -38,15 +38,15 @@ export interface IArchivePlugin {
|
|
|
38
38
|
projectId?: string;
|
|
39
39
|
}): Promise<Record<string, unknown> | null>;
|
|
40
40
|
/**
|
|
41
|
-
*
|
|
41
|
+
* Updates an archived document (merge Storage data with new data)
|
|
42
42
|
*
|
|
43
|
-
* @param collection -
|
|
44
|
-
* @param docId - ID
|
|
45
|
-
* @param newData -
|
|
46
|
-
* @param options -
|
|
47
|
-
* @param projectId - ID
|
|
48
|
-
* @param archivePath -
|
|
49
|
-
* @returns
|
|
43
|
+
* @param collection - Collection name
|
|
44
|
+
* @param docId - Document ID
|
|
45
|
+
* @param newData - New data to merge
|
|
46
|
+
* @param options - Options (unarchive: true to remove from Storage)
|
|
47
|
+
* @param projectId - Project ID (optional)
|
|
48
|
+
* @param archivePath - Full object path in Storage, usually the stub's `_rfa.archivePath`. Required when unarchive=true
|
|
49
|
+
* @returns Merged data
|
|
50
50
|
*/
|
|
51
51
|
updateArchivedDocument(params: {
|
|
52
52
|
collection: string;
|
|
@@ -66,12 +66,12 @@ export interface IArchivePlugin {
|
|
|
66
66
|
mergedData?: Record<string, unknown>;
|
|
67
67
|
}>;
|
|
68
68
|
/**
|
|
69
|
-
*
|
|
69
|
+
* Deletes an archived document from Storage
|
|
70
70
|
*
|
|
71
|
-
* @param collection -
|
|
72
|
-
* @param docId - ID
|
|
73
|
-
* @param projectId - ID
|
|
74
|
-
* @returns
|
|
71
|
+
* @param collection - Collection name
|
|
72
|
+
* @param docId - Document ID
|
|
73
|
+
* @param projectId - Project ID (optional)
|
|
74
|
+
* @returns Operation result
|
|
75
75
|
*/
|
|
76
76
|
deleteArchivedDocument(params: {
|
|
77
77
|
collection: string;
|
|
@@ -84,19 +84,33 @@ export interface IArchivePlugin {
|
|
|
84
84
|
error?: Error;
|
|
85
85
|
}>;
|
|
86
86
|
/**
|
|
87
|
-
*
|
|
87
|
+
* Invalidates the cache of archived documents
|
|
88
88
|
*
|
|
89
|
-
* @param collection -
|
|
90
|
-
* @param docId - ID
|
|
89
|
+
* @param collection - Collection name (optional)
|
|
90
|
+
* @param docId - Document ID (optional)
|
|
91
91
|
*/
|
|
92
92
|
invalidateCache(collection?: string, docId?: string): Promise<void>;
|
|
93
93
|
}
|
|
94
94
|
/**
|
|
95
|
-
*
|
|
95
|
+
* Archive marker key in Firestore (marker-only).
|
|
96
|
+
*/
|
|
97
|
+
export declare const ARCHIVE_MARKER_KEY: "_rfa";
|
|
98
|
+
export type ArchiveMarker = {
|
|
99
|
+
archivedAt?: string;
|
|
100
|
+
archiveHash?: string;
|
|
101
|
+
archivePath?: string;
|
|
102
|
+
restoredAt?: string;
|
|
103
|
+
version?: number | string;
|
|
104
|
+
};
|
|
105
|
+
export declare function getArchiveMarker(doc: Record<string, unknown> | null | undefined): ArchiveMarker | null;
|
|
106
|
+
/**
|
|
107
|
+
* Paths (dot-notation) for archive metadata in Firestore.
|
|
108
|
+
* Use these values in Firestore queries/updates; do not use for direct indexing in JS objects.
|
|
96
109
|
*/
|
|
97
110
|
export declare const ARCHIVE_METADATA_FIELDS: {
|
|
98
|
-
readonly ARCHIVED_AT: "
|
|
99
|
-
readonly ARCHIVE_HASH: "
|
|
100
|
-
readonly ARCHIVE_PATH: "
|
|
101
|
-
readonly RESTORED_AT: "
|
|
111
|
+
readonly ARCHIVED_AT: "_rfa.archivedAt";
|
|
112
|
+
readonly ARCHIVE_HASH: "_rfa.archiveHash";
|
|
113
|
+
readonly ARCHIVE_PATH: "_rfa.archivePath";
|
|
114
|
+
readonly RESTORED_AT: "_rfa.restoredAt";
|
|
115
|
+
readonly VERSION: "_rfa.version";
|
|
102
116
|
};
|
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ARCHIVE_METADATA_FIELDS = void 0;
|
|
3
|
+
exports.ARCHIVE_METADATA_FIELDS = exports.getArchiveMarker = exports.ARCHIVE_MARKER_KEY = void 0;
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Archive marker key in Firestore (marker-only).
|
|
6
|
+
*/
|
|
7
|
+
exports.ARCHIVE_MARKER_KEY = '_rfa';
|
|
8
|
+
function getArchiveMarker(doc) {
|
|
9
|
+
if (!doc)
|
|
10
|
+
return null;
|
|
11
|
+
const marker = doc[exports.ARCHIVE_MARKER_KEY];
|
|
12
|
+
if (!marker || typeof marker !== 'object')
|
|
13
|
+
return null;
|
|
14
|
+
return marker;
|
|
15
|
+
}
|
|
16
|
+
exports.getArchiveMarker = getArchiveMarker;
|
|
17
|
+
/**
|
|
18
|
+
* Paths (dot-notation) for archive metadata in Firestore.
|
|
19
|
+
* Use these values in Firestore queries/updates; do not use for direct indexing in JS objects.
|
|
6
20
|
*/
|
|
7
21
|
exports.ARCHIVE_METADATA_FIELDS = {
|
|
8
|
-
ARCHIVED_AT:
|
|
9
|
-
ARCHIVE_HASH:
|
|
10
|
-
ARCHIVE_PATH:
|
|
11
|
-
RESTORED_AT:
|
|
22
|
+
ARCHIVED_AT: `${exports.ARCHIVE_MARKER_KEY}.archivedAt`,
|
|
23
|
+
ARCHIVE_HASH: `${exports.ARCHIVE_MARKER_KEY}.archiveHash`,
|
|
24
|
+
ARCHIVE_PATH: `${exports.ARCHIVE_MARKER_KEY}.archivePath`,
|
|
25
|
+
RESTORED_AT: `${exports.ARCHIVE_MARKER_KEY}.restoredAt`,
|
|
26
|
+
VERSION: `${exports.ARCHIVE_MARKER_KEY}.version`,
|
|
12
27
|
};
|
package/dist/archive/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { IArchivePlugin, ARCHIVE_METADATA_FIELDS } from './IArchivePlugin';
|
|
1
|
+
export { IArchivePlugin, ARCHIVE_METADATA_FIELDS, ARCHIVE_MARKER_KEY, ArchiveMarker, getArchiveMarker, } from './IArchivePlugin';
|
|
2
2
|
export { registerArchivePlugin, getArchivePlugin, hasArchivePlugin, resetArchivePlugin, ArchivePluginRegistry, } from './ArchivePluginRegistry';
|
package/dist/archive/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ArchivePluginRegistry = exports.resetArchivePlugin = exports.hasArchivePlugin = exports.getArchivePlugin = exports.registerArchivePlugin = exports.ARCHIVE_METADATA_FIELDS = void 0;
|
|
3
|
+
exports.ArchivePluginRegistry = exports.resetArchivePlugin = exports.hasArchivePlugin = exports.getArchivePlugin = exports.registerArchivePlugin = exports.getArchiveMarker = exports.ARCHIVE_MARKER_KEY = exports.ARCHIVE_METADATA_FIELDS = void 0;
|
|
4
4
|
var IArchivePlugin_1 = require("./IArchivePlugin");
|
|
5
5
|
Object.defineProperty(exports, "ARCHIVE_METADATA_FIELDS", { enumerable: true, get: function () { return IArchivePlugin_1.ARCHIVE_METADATA_FIELDS; } });
|
|
6
|
+
Object.defineProperty(exports, "ARCHIVE_MARKER_KEY", { enumerable: true, get: function () { return IArchivePlugin_1.ARCHIVE_MARKER_KEY; } });
|
|
7
|
+
Object.defineProperty(exports, "getArchiveMarker", { enumerable: true, get: function () { return IArchivePlugin_1.getArchiveMarker; } });
|
|
6
8
|
var ArchivePluginRegistry_1 = require("./ArchivePluginRegistry");
|
|
7
9
|
Object.defineProperty(exports, "registerArchivePlugin", { enumerable: true, get: function () { return ArchivePluginRegistry_1.registerArchivePlugin; } });
|
|
8
10
|
Object.defineProperty(exports, "getArchivePlugin", { enumerable: true, get: function () { return ArchivePluginRegistry_1.getArchivePlugin; } });
|
|
@@ -4,7 +4,7 @@ export declare class ManualQueryHelper {
|
|
|
4
4
|
static executeQueryManual(className: string, config: Config, queryRef?: boolean): Promise<any>;
|
|
5
5
|
static executeQueryManualPaginated(className: string, config: Config): Promise<QueryResult>;
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Processes archived documents, retrieving their complete data from Cloud Storage
|
|
8
8
|
*/
|
|
9
9
|
private static processArchivedDocuments;
|
|
10
10
|
static handleExecuteQueryManual(className: string, config: Config, options: Options, queryRef?: boolean): Promise<QueryResult>;
|
|
@@ -7,7 +7,7 @@ const MQuery_1 = require("../model/MQuery");
|
|
|
7
7
|
const QueryCreatorConfig_1 = require("./QueryCreatorConfig");
|
|
8
8
|
const QueryPredicateFunctionTransform_1 = require("./QueryPredicateFunctionTransform");
|
|
9
9
|
const ArchiveService_1 = require("../archive/ArchiveService");
|
|
10
|
-
|
|
10
|
+
const archive_1 = require("../archive");
|
|
11
11
|
class ManualQueryHelper {
|
|
12
12
|
static async executeQueryManual(className, config, queryRef = false) {
|
|
13
13
|
const result = await this.handleExecuteQueryManual(className, config, { showCount: false }, queryRef);
|
|
@@ -21,11 +21,11 @@ class ManualQueryHelper {
|
|
|
21
21
|
return this.handleExecuteQueryManual(className, config, { showCount: true });
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
24
|
+
* Processes archived documents, retrieving their complete data from Cloud Storage
|
|
25
25
|
*/
|
|
26
26
|
static async processArchivedDocuments(docs, collectionName) {
|
|
27
27
|
const archiveService = await ArchiveService_1.ArchiveService.getInstance();
|
|
28
|
-
//
|
|
28
|
+
// Checks if the archive is enabled
|
|
29
29
|
if (!archiveService.isEnabled()) {
|
|
30
30
|
return docs;
|
|
31
31
|
}
|
|
@@ -36,17 +36,18 @@ class ManualQueryHelper {
|
|
|
36
36
|
return null;
|
|
37
37
|
}
|
|
38
38
|
try {
|
|
39
|
-
//
|
|
39
|
+
// The ArchiveService now manages the cache internally based on the configuration
|
|
40
40
|
const archivedData = await archiveService.getArchivedDocument(collectionName, doc);
|
|
41
41
|
if (archivedData) {
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
|
|
42
|
+
// Merges the stub data with the archived data (the stub keeps _rfa)
|
|
43
|
+
// Preserve the marker from stub to prevent archivedData from overwriting it
|
|
44
|
+
const marker = doc?.[archive_1.ARCHIVE_MARKER_KEY];
|
|
45
|
+
return { ...doc, ...archivedData, [archive_1.ARCHIVE_MARKER_KEY]: marker };
|
|
45
46
|
}
|
|
46
47
|
return doc;
|
|
47
48
|
}
|
|
48
49
|
catch (error) {
|
|
49
|
-
console.warn(`
|
|
50
|
+
console.warn(`Error retrieving archived document ${doc.id}:`, error);
|
|
50
51
|
return doc;
|
|
51
52
|
}
|
|
52
53
|
});
|
|
@@ -82,7 +82,8 @@ class QueryPredicateFunctionTransform {
|
|
|
82
82
|
aggregateCount: firestore_1.AggregateField.count,
|
|
83
83
|
startTracer: Tracer_1.startTracer,
|
|
84
84
|
archiveService: ArchiveService_1.ArchiveService.getInstance(),
|
|
85
|
-
ARCHIVE_FIELDS: archive_1.ARCHIVE_METADATA_FIELDS
|
|
85
|
+
ARCHIVE_FIELDS: archive_1.ARCHIVE_METADATA_FIELDS,
|
|
86
|
+
getArchivePath: ArchiveService_1.ArchiveService.getArchivePath
|
|
86
87
|
};
|
|
87
88
|
if (!options?.collection) {
|
|
88
89
|
throw new Error(`Collection is required`);
|