@causa/runtime-google 1.2.0 → 1.3.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/spanner/index.d.ts +2 -2
- package/dist/spanner/index.js +1 -1
- package/dist/transaction/firestore-pubsub/readonly-state-transaction.d.ts +19 -0
- package/dist/transaction/firestore-pubsub/readonly-state-transaction.js +27 -6
- package/dist/transaction/firestore-pubsub/state-transaction.js +8 -8
- package/dist/transaction/firestore-pubsub/types.d.ts +2 -0
- package/package.json +9 -9
package/dist/spanner/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { SpannerColumn } from './column.decorator.js';
|
|
2
|
-
export {
|
|
2
|
+
export { catchSpannerDatabaseErrors, getDefaultSpannerDatabaseForCloudFunction, SPANNER_SESSION_POOL_OPTIONS_FOR_CLOUD_FUNCTIONS, SPANNER_SESSION_POOL_OPTIONS_FOR_SERVICE, } from './database.js';
|
|
3
3
|
export { SpannerEntityManager } from './entity-manager.js';
|
|
4
|
-
export type { SpannerKey, SpannerReadOnlyTransaction, SpannerReadWriteTransaction, } from './entity-manager.js';
|
|
4
|
+
export type { SpannerKey, SpannerReadOnlyTransaction, SpannerReadWriteTransaction, SqlStatement, } from './entity-manager.js';
|
|
5
5
|
export * from './errors.js';
|
|
6
6
|
export { SpannerHealthIndicator } from './healthcheck.js';
|
|
7
7
|
export { SpannerModule } from './module.js';
|
package/dist/spanner/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { SpannerColumn } from './column.decorator.js';
|
|
2
|
-
export {
|
|
2
|
+
export { catchSpannerDatabaseErrors, getDefaultSpannerDatabaseForCloudFunction, SPANNER_SESSION_POOL_OPTIONS_FOR_CLOUD_FUNCTIONS, SPANNER_SESSION_POOL_OPTIONS_FOR_SERVICE, } from './database.js';
|
|
3
3
|
export { SpannerEntityManager } from './entity-manager.js';
|
|
4
4
|
export * from './errors.js';
|
|
5
5
|
export { SpannerHealthIndicator } from './healthcheck.js';
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import type { ReadOnlyStateTransaction, ReadOnlyTransactionOption } from '@causa/runtime';
|
|
2
2
|
import type { Type } from '@nestjs/common';
|
|
3
3
|
import { Transaction } from 'firebase-admin/firestore';
|
|
4
|
+
import { type SoftDeletedFirestoreCollectionMetadata } from './soft-deleted-collection.decorator.js';
|
|
4
5
|
import type { FirestoreCollectionResolver } from './types.js';
|
|
5
6
|
/**
|
|
6
7
|
* Option for a function that accepts a {@link FirestoreReadOnlyStateTransaction}.
|
|
7
8
|
*/
|
|
8
9
|
export type FirestoreReadOnlyStateTransactionOption = ReadOnlyTransactionOption<FirestoreReadOnlyStateTransaction>;
|
|
10
|
+
/**
|
|
11
|
+
* Information about soft-deletion for a given document.
|
|
12
|
+
*/
|
|
13
|
+
export type SoftDeleteInfo<T extends object> = Omit<SoftDeletedFirestoreCollectionMetadata, 'deletedDocumentsCollectionSuffix'> & {
|
|
14
|
+
/**
|
|
15
|
+
* The reference to the soft-deleted document.
|
|
16
|
+
*/
|
|
17
|
+
ref: FirebaseFirestore.DocumentReference<T>;
|
|
18
|
+
};
|
|
9
19
|
/**
|
|
10
20
|
* A {@link ReadOnlyStateTransaction} that uses Firestore for state storage.
|
|
11
21
|
*
|
|
@@ -33,5 +43,14 @@ export declare class FirestoreReadOnlyStateTransaction implements ReadOnlyStateT
|
|
|
33
43
|
* The resolver that provides the Firestore collections for a given document type.
|
|
34
44
|
*/
|
|
35
45
|
collectionResolver: FirestoreCollectionResolver);
|
|
46
|
+
/**
|
|
47
|
+
* Returns the soft-delete information for a given document, if the document type supports soft-deletion.
|
|
48
|
+
*
|
|
49
|
+
* @param activeDocRef The reference to the active document.
|
|
50
|
+
* @param type The type of the document.
|
|
51
|
+
* @returns The soft-delete information for the document, or `null` if the document type does not support
|
|
52
|
+
* soft-deletion.
|
|
53
|
+
*/
|
|
54
|
+
protected getSoftDeleteInfo<T extends object>(activeDocRef: FirebaseFirestore.DocumentReference<T>, type: Type<T>): SoftDeleteInfo<T> | null;
|
|
36
55
|
get<T extends object>(type: Type<T>, entity: Partial<T>): Promise<T | null>;
|
|
37
56
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Transaction } from 'firebase-admin/firestore';
|
|
2
|
-
import { getReferenceForFirestoreDocument } from '../../firestore/index.js';
|
|
2
|
+
import { getReferenceForFirestoreDocument, makeFirestoreDataConverter, } from '../../firestore/index.js';
|
|
3
|
+
import { getSoftDeletedFirestoreCollectionMetadataForType, } from './soft-deleted-collection.decorator.js';
|
|
3
4
|
/**
|
|
4
5
|
* A {@link ReadOnlyStateTransaction} that uses Firestore for state storage.
|
|
5
6
|
*
|
|
@@ -24,24 +25,44 @@ export class FirestoreReadOnlyStateTransaction {
|
|
|
24
25
|
this.firestoreTransaction = firestoreTransaction;
|
|
25
26
|
this.collectionResolver = collectionResolver;
|
|
26
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Returns the soft-delete information for a given document, if the document type supports soft-deletion.
|
|
30
|
+
*
|
|
31
|
+
* @param activeDocRef The reference to the active document.
|
|
32
|
+
* @param type The type of the document.
|
|
33
|
+
* @returns The soft-delete information for the document, or `null` if the document type does not support
|
|
34
|
+
* soft-deletion.
|
|
35
|
+
*/
|
|
36
|
+
getSoftDeleteInfo(activeDocRef, type) {
|
|
37
|
+
const softDeleteMetadata = getSoftDeletedFirestoreCollectionMetadataForType(type);
|
|
38
|
+
if (!softDeleteMetadata) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const { deletedDocumentsCollectionSuffix: suffix, ...info } = softDeleteMetadata;
|
|
42
|
+
const softDeleteCollection = activeDocRef.firestore
|
|
43
|
+
.collection(`${activeDocRef.parent.path}${suffix}`)
|
|
44
|
+
.withConverter(makeFirestoreDataConverter(type));
|
|
45
|
+
const ref = softDeleteCollection.doc(activeDocRef.id);
|
|
46
|
+
return { ...info, ref };
|
|
47
|
+
}
|
|
27
48
|
async get(type, entity) {
|
|
28
|
-
const { activeCollection
|
|
49
|
+
const { activeCollection } = this.collectionResolver.getCollectionsForType(type);
|
|
29
50
|
const activeDocRef = getReferenceForFirestoreDocument(activeCollection, entity, type);
|
|
30
51
|
const activeSnapshot = await this.firestoreTransaction.get(activeDocRef);
|
|
31
52
|
const activeDocument = activeSnapshot.data();
|
|
32
53
|
if (activeDocument) {
|
|
33
54
|
return activeDocument;
|
|
34
55
|
}
|
|
35
|
-
|
|
56
|
+
const softDeleteInfo = this.getSoftDeleteInfo(activeDocRef, type);
|
|
57
|
+
if (!softDeleteInfo) {
|
|
36
58
|
return null;
|
|
37
59
|
}
|
|
38
|
-
const
|
|
39
|
-
const deletedSnapshot = await this.firestoreTransaction.get(deletedDocRef);
|
|
60
|
+
const deletedSnapshot = await this.firestoreTransaction.get(softDeleteInfo.ref);
|
|
40
61
|
const deletedDocument = deletedSnapshot.data();
|
|
41
62
|
if (!deletedDocument) {
|
|
42
63
|
return null;
|
|
43
64
|
}
|
|
44
|
-
delete deletedDocument[
|
|
65
|
+
delete deletedDocument[softDeleteInfo.expirationField];
|
|
45
66
|
return deletedDocument;
|
|
46
67
|
}
|
|
47
68
|
}
|
|
@@ -22,26 +22,26 @@ export class FirestoreStateTransaction extends FirestoreReadOnlyStateTransaction
|
|
|
22
22
|
async delete(typeOrEntity, key) {
|
|
23
23
|
const type = (key === undefined ? typeOrEntity.constructor : typeOrEntity);
|
|
24
24
|
key ??= typeOrEntity;
|
|
25
|
-
const { activeCollection
|
|
25
|
+
const { activeCollection } = this.collectionResolver.getCollectionsForType(type);
|
|
26
26
|
const activeDocRef = getReferenceForFirestoreDocument(activeCollection, key, type);
|
|
27
27
|
this.firestoreTransaction.delete(activeDocRef);
|
|
28
|
-
|
|
28
|
+
const softDeleteInfo = this.getSoftDeleteInfo(activeDocRef, type);
|
|
29
|
+
if (!softDeleteInfo) {
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
31
|
-
|
|
32
|
-
this.firestoreTransaction.delete(deletedDocRef);
|
|
32
|
+
this.firestoreTransaction.delete(softDeleteInfo.ref);
|
|
33
33
|
}
|
|
34
34
|
async set(entity) {
|
|
35
35
|
const documentType = entity.constructor;
|
|
36
|
-
const { activeCollection
|
|
36
|
+
const { activeCollection } = this.collectionResolver.getCollectionsForType(documentType);
|
|
37
37
|
const activeDocRef = getReferenceForFirestoreDocument(activeCollection, entity);
|
|
38
|
-
|
|
38
|
+
const softDeleteInfo = this.getSoftDeleteInfo(activeDocRef, documentType);
|
|
39
|
+
if (!softDeleteInfo) {
|
|
39
40
|
this.firestoreTransaction.set(activeDocRef, entity);
|
|
40
41
|
return;
|
|
41
42
|
}
|
|
42
|
-
const deletedDocRef
|
|
43
|
+
const { ref: deletedDocRef, expirationDelay, expirationField, } = softDeleteInfo;
|
|
43
44
|
if ('deletedAt' in entity && entity.deletedAt instanceof Date) {
|
|
44
|
-
const { expirationDelay, expirationField } = softDelete;
|
|
45
45
|
const expiresAt = new Date(entity.deletedAt.getTime() + expirationDelay);
|
|
46
46
|
const deletedDoc = plainToInstance(documentType, {
|
|
47
47
|
...entity,
|
|
@@ -12,6 +12,8 @@ export type FirestoreCollectionsForDocumentType<T> = {
|
|
|
12
12
|
/**
|
|
13
13
|
* Configuration about the soft-delete collection, where documents are stored when their `deletedAt` field is not
|
|
14
14
|
* `null`. This can be `null` if the document type does not declare a soft-delete collection.
|
|
15
|
+
*
|
|
16
|
+
* @deprecated Use `SoftDeleteInfo` in `FirestoreReadOnlyStateTransaction.getSoftDeleteInfo` instead.
|
|
15
17
|
*/
|
|
16
18
|
readonly softDelete: ({
|
|
17
19
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@causa/runtime-google",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "An extension to the Causa runtime SDK (`@causa/runtime`), providing Google-specific features.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
"test:cov": "npm run test -- --coverage"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@causa/runtime": "^1.
|
|
35
|
+
"@causa/runtime": "^1.3.0",
|
|
36
36
|
"@google-cloud/precise-date": "^5.0.0",
|
|
37
37
|
"@google-cloud/pubsub": "^5.2.0",
|
|
38
|
-
"@google-cloud/spanner": "^8.2.
|
|
39
|
-
"@google-cloud/tasks": "^6.2.
|
|
38
|
+
"@google-cloud/spanner": "^8.2.2",
|
|
39
|
+
"@google-cloud/tasks": "^6.2.1",
|
|
40
40
|
"@grpc/grpc-js": "^1.14.0",
|
|
41
41
|
"@nestjs/common": "^11.1.6",
|
|
42
42
|
"@nestjs/config": "^4.0.2",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"firebase-admin": "^13.5.0",
|
|
50
50
|
"jsonwebtoken": "^9.0.2",
|
|
51
51
|
"passport-http-bearer": "^1.0.1",
|
|
52
|
-
"pino": "^9.
|
|
52
|
+
"pino": "^9.13.1",
|
|
53
53
|
"reflect-metadata": "^0.2.2"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
@@ -59,21 +59,21 @@
|
|
|
59
59
|
"@tsconfig/node22": "^22.0.2",
|
|
60
60
|
"@types/jest": "^30.0.0",
|
|
61
61
|
"@types/jsonwebtoken": "^9.0.10",
|
|
62
|
-
"@types/node": "^22.18.
|
|
62
|
+
"@types/node": "^22.18.11",
|
|
63
63
|
"@types/passport-http-bearer": "^1.0.42",
|
|
64
64
|
"@types/supertest": "^6.0.3",
|
|
65
65
|
"@types/uuid": "^11.0.0",
|
|
66
66
|
"dotenv": "^17.2.3",
|
|
67
|
-
"eslint": "^9.
|
|
67
|
+
"eslint": "^9.38.0",
|
|
68
68
|
"eslint-config-prettier": "^10.1.8",
|
|
69
69
|
"eslint-plugin-prettier": "^5.5.4",
|
|
70
70
|
"jest": "^30.2.0",
|
|
71
71
|
"jest-extended": "^6.0.0",
|
|
72
|
-
"pino-pretty": "^13.1.
|
|
72
|
+
"pino-pretty": "^13.1.2",
|
|
73
73
|
"rimraf": "^6.0.1",
|
|
74
74
|
"supertest": "^7.1.4",
|
|
75
75
|
"typescript": "^5.9.3",
|
|
76
|
-
"typescript-eslint": "^8.
|
|
76
|
+
"typescript-eslint": "^8.46.1",
|
|
77
77
|
"uuid": "^13.0.0"
|
|
78
78
|
}
|
|
79
79
|
}
|