@causa/workspace-google 0.18.0-beta.2 → 0.18.0-beta.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.
- package/dist/configurations/generated.d.ts +30 -0
- package/dist/configurations/generated.js +60 -0
- package/dist/configurations/schemas/google.yaml +43 -0
- package/dist/emulators/firebase-storage.d.ts +9 -1
- package/dist/emulators/firebase-storage.js +13 -1
- package/dist/emulators/firestore.d.ts +9 -1
- package/dist/emulators/firestore.js +13 -1
- package/dist/emulators/identity-platform.d.ts +9 -1
- package/dist/emulators/identity-platform.js +13 -1
- package/dist/emulators/pubsub.d.ts +9 -1
- package/dist/emulators/pubsub.js +13 -1
- package/dist/emulators/spanner.d.ts +18 -2
- package/dist/emulators/spanner.js +26 -2
- package/dist/functions/emulator/start-firebase-storage.js +4 -3
- package/dist/functions/emulator/start-firestore.js +5 -10
- package/dist/functions/emulator/start-identity-platform.js +4 -7
- package/dist/functions/emulator/start-pubsub.call.js +10 -9
- package/dist/functions/emulator/start-spanner.call.js +14 -13
- package/dist/functions/event-topic/broker-delete-trigger-resource-pubsub-subscription.js +2 -1
- package/dist/functions/event-topic/broker-wait-for-processing-pubsub.call.d.ts +2 -0
- package/dist/functions/event-topic/broker-wait-for-processing-pubsub.call.js +119 -0
- package/dist/functions/event-topic/broker-wait-for-processing-pubsub.d.ts +16 -0
- package/dist/functions/event-topic/broker-wait-for-processing-pubsub.js +23 -0
- package/dist/functions/event-topic/index.d.ts +1 -0
- package/dist/functions/event-topic/index.js +1 -0
- package/dist/functions/index.js +2 -2
- package/dist/services/cloud-monitoring.d.ts +44 -0
- package/dist/services/cloud-monitoring.js +61 -0
- package/dist/services/index.d.ts +2 -1
- package/dist/services/index.js +2 -1
- package/dist/services/pubsub.d.ts +1 -0
- package/dist/services/pubsub.js +1 -0
- package/dist/services/pubsub.utils.d.ts +9 -0
- package/dist/services/pubsub.utils.js +11 -0
- package/package.json +6 -5
|
@@ -173,6 +173,11 @@ export declare class GoogleFirebaseStorageEmulator {
|
|
|
173
173
|
* The name of the local Docker container running the emulator.
|
|
174
174
|
*/
|
|
175
175
|
readonly containerName?: string;
|
|
176
|
+
/**
|
|
177
|
+
* The host port to which the Firebase Storage emulator is bound.
|
|
178
|
+
* Override this to run several workspaces in parallel on the same machine. Defaults to `9199`.
|
|
179
|
+
*/
|
|
180
|
+
readonly port?: number;
|
|
176
181
|
[property: string]: any;
|
|
177
182
|
}
|
|
178
183
|
/**
|
|
@@ -203,6 +208,11 @@ export declare class GoogleFirestoreEmulator {
|
|
|
203
208
|
* The name of the local Docker container running the emulator.
|
|
204
209
|
*/
|
|
205
210
|
readonly containerName?: string;
|
|
211
|
+
/**
|
|
212
|
+
* The host port to which the Firestore emulator is bound.
|
|
213
|
+
* Override this to run several workspaces in parallel on the same machine. Defaults to `8080`.
|
|
214
|
+
*/
|
|
215
|
+
readonly port?: number;
|
|
206
216
|
[property: string]: any;
|
|
207
217
|
}
|
|
208
218
|
/**
|
|
@@ -245,6 +255,11 @@ export declare class GoogleIdentityPlatformEmulator {
|
|
|
245
255
|
* The name of the local Docker container running the emulator.
|
|
246
256
|
*/
|
|
247
257
|
readonly containerName?: string;
|
|
258
|
+
/**
|
|
259
|
+
* The host port to which the Identity Platform (Firebase Auth) emulator is bound.
|
|
260
|
+
* Override this to run several workspaces in parallel on the same machine. Defaults to `9099`.
|
|
261
|
+
*/
|
|
262
|
+
readonly port?: number;
|
|
248
263
|
[property: string]: any;
|
|
249
264
|
}
|
|
250
265
|
/**
|
|
@@ -294,6 +309,11 @@ export declare class GooglePubSubEmulator {
|
|
|
294
309
|
* The name of the local Docker container running the emulator.
|
|
295
310
|
*/
|
|
296
311
|
readonly containerName?: string;
|
|
312
|
+
/**
|
|
313
|
+
* The host port to which the Pub/Sub emulator is bound.
|
|
314
|
+
* Override this to run several workspaces in parallel on the same machine. Defaults to `8085`.
|
|
315
|
+
*/
|
|
316
|
+
readonly port?: number;
|
|
297
317
|
[property: string]: any;
|
|
298
318
|
}
|
|
299
319
|
/**
|
|
@@ -393,6 +413,16 @@ export declare class GoogleSpannerEmulator {
|
|
|
393
413
|
* The name of the local Docker container running the emulator.
|
|
394
414
|
*/
|
|
395
415
|
readonly containerName?: string;
|
|
416
|
+
/**
|
|
417
|
+
* The host port to which the Spanner emulator gRPC API is bound.
|
|
418
|
+
* Override this to run several workspaces in parallel on the same machine. Defaults to `9010`.
|
|
419
|
+
*/
|
|
420
|
+
readonly grpcPort?: number;
|
|
421
|
+
/**
|
|
422
|
+
* The host port to which the Spanner emulator HTTP API is bound.
|
|
423
|
+
* Override this to run several workspaces in parallel on the same machine. Defaults to `9020`.
|
|
424
|
+
*/
|
|
425
|
+
readonly httpPort?: number;
|
|
396
426
|
/**
|
|
397
427
|
* The name of the Spanner instance that will automatically be created in the emulator.
|
|
398
428
|
*/
|
|
@@ -301,12 +301,22 @@ export class GoogleFirebaseStorageEmulator {
|
|
|
301
301
|
* The name of the local Docker container running the emulator.
|
|
302
302
|
*/
|
|
303
303
|
containerName;
|
|
304
|
+
/**
|
|
305
|
+
* The host port to which the Firebase Storage emulator is bound.
|
|
306
|
+
* Override this to run several workspaces in parallel on the same machine. Defaults to `9199`.
|
|
307
|
+
*/
|
|
308
|
+
port;
|
|
304
309
|
}
|
|
305
310
|
__decorate([
|
|
306
311
|
AllowMissing(),
|
|
307
312
|
IsString(),
|
|
308
313
|
__metadata("design:type", String)
|
|
309
314
|
], GoogleFirebaseStorageEmulator.prototype, "containerName", void 0);
|
|
315
|
+
__decorate([
|
|
316
|
+
AllowMissing(),
|
|
317
|
+
IsNumber(),
|
|
318
|
+
__metadata("design:type", Number)
|
|
319
|
+
], GoogleFirebaseStorageEmulator.prototype, "port", void 0);
|
|
310
320
|
/**
|
|
311
321
|
* Configuration for the Firebase Storage service.
|
|
312
322
|
*/
|
|
@@ -353,12 +363,22 @@ export class GoogleFirestoreEmulator {
|
|
|
353
363
|
* The name of the local Docker container running the emulator.
|
|
354
364
|
*/
|
|
355
365
|
containerName;
|
|
366
|
+
/**
|
|
367
|
+
* The host port to which the Firestore emulator is bound.
|
|
368
|
+
* Override this to run several workspaces in parallel on the same machine. Defaults to `8080`.
|
|
369
|
+
*/
|
|
370
|
+
port;
|
|
356
371
|
}
|
|
357
372
|
__decorate([
|
|
358
373
|
AllowMissing(),
|
|
359
374
|
IsString(),
|
|
360
375
|
__metadata("design:type", String)
|
|
361
376
|
], GoogleFirestoreEmulator.prototype, "containerName", void 0);
|
|
377
|
+
__decorate([
|
|
378
|
+
AllowMissing(),
|
|
379
|
+
IsNumber(),
|
|
380
|
+
__metadata("design:type", Number)
|
|
381
|
+
], GoogleFirestoreEmulator.prototype, "port", void 0);
|
|
362
382
|
/**
|
|
363
383
|
* Configuration for the Firestore service.
|
|
364
384
|
*/
|
|
@@ -423,12 +443,22 @@ export class GoogleIdentityPlatformEmulator {
|
|
|
423
443
|
* The name of the local Docker container running the emulator.
|
|
424
444
|
*/
|
|
425
445
|
containerName;
|
|
446
|
+
/**
|
|
447
|
+
* The host port to which the Identity Platform (Firebase Auth) emulator is bound.
|
|
448
|
+
* Override this to run several workspaces in parallel on the same machine. Defaults to `9099`.
|
|
449
|
+
*/
|
|
450
|
+
port;
|
|
426
451
|
}
|
|
427
452
|
__decorate([
|
|
428
453
|
AllowMissing(),
|
|
429
454
|
IsString(),
|
|
430
455
|
__metadata("design:type", String)
|
|
431
456
|
], GoogleIdentityPlatformEmulator.prototype, "containerName", void 0);
|
|
457
|
+
__decorate([
|
|
458
|
+
AllowMissing(),
|
|
459
|
+
IsNumber(),
|
|
460
|
+
__metadata("design:type", Number)
|
|
461
|
+
], GoogleIdentityPlatformEmulator.prototype, "port", void 0);
|
|
432
462
|
/**
|
|
433
463
|
* Configuration for the Identity Platform (formerly Firebase Auth) service.
|
|
434
464
|
*/
|
|
@@ -501,12 +531,22 @@ export class GooglePubSubEmulator {
|
|
|
501
531
|
* The name of the local Docker container running the emulator.
|
|
502
532
|
*/
|
|
503
533
|
containerName;
|
|
534
|
+
/**
|
|
535
|
+
* The host port to which the Pub/Sub emulator is bound.
|
|
536
|
+
* Override this to run several workspaces in parallel on the same machine. Defaults to `8085`.
|
|
537
|
+
*/
|
|
538
|
+
port;
|
|
504
539
|
}
|
|
505
540
|
__decorate([
|
|
506
541
|
AllowMissing(),
|
|
507
542
|
IsString(),
|
|
508
543
|
__metadata("design:type", String)
|
|
509
544
|
], GooglePubSubEmulator.prototype, "containerName", void 0);
|
|
545
|
+
__decorate([
|
|
546
|
+
AllowMissing(),
|
|
547
|
+
IsNumber(),
|
|
548
|
+
__metadata("design:type", Number)
|
|
549
|
+
], GooglePubSubEmulator.prototype, "port", void 0);
|
|
510
550
|
/**
|
|
511
551
|
* Configuration for the Pub/Sub service.
|
|
512
552
|
*/
|
|
@@ -684,6 +724,16 @@ export class GoogleSpannerEmulator {
|
|
|
684
724
|
* The name of the local Docker container running the emulator.
|
|
685
725
|
*/
|
|
686
726
|
containerName;
|
|
727
|
+
/**
|
|
728
|
+
* The host port to which the Spanner emulator gRPC API is bound.
|
|
729
|
+
* Override this to run several workspaces in parallel on the same machine. Defaults to `9010`.
|
|
730
|
+
*/
|
|
731
|
+
grpcPort;
|
|
732
|
+
/**
|
|
733
|
+
* The host port to which the Spanner emulator HTTP API is bound.
|
|
734
|
+
* Override this to run several workspaces in parallel on the same machine. Defaults to `9020`.
|
|
735
|
+
*/
|
|
736
|
+
httpPort;
|
|
687
737
|
/**
|
|
688
738
|
* The name of the Spanner instance that will automatically be created in the emulator.
|
|
689
739
|
*/
|
|
@@ -698,6 +748,16 @@ __decorate([
|
|
|
698
748
|
IsString(),
|
|
699
749
|
__metadata("design:type", String)
|
|
700
750
|
], GoogleSpannerEmulator.prototype, "containerName", void 0);
|
|
751
|
+
__decorate([
|
|
752
|
+
AllowMissing(),
|
|
753
|
+
IsNumber(),
|
|
754
|
+
__metadata("design:type", Number)
|
|
755
|
+
], GoogleSpannerEmulator.prototype, "grpcPort", void 0);
|
|
756
|
+
__decorate([
|
|
757
|
+
AllowMissing(),
|
|
758
|
+
IsNumber(),
|
|
759
|
+
__metadata("design:type", Number)
|
|
760
|
+
], GoogleSpannerEmulator.prototype, "httpPort", void 0);
|
|
701
761
|
__decorate([
|
|
702
762
|
AllowMissing(),
|
|
703
763
|
IsString(),
|
|
@@ -125,6 +125,13 @@ properties:
|
|
|
125
125
|
containerName:
|
|
126
126
|
type: string
|
|
127
127
|
description: The name of the local Docker container running the emulator.
|
|
128
|
+
port:
|
|
129
|
+
type: number
|
|
130
|
+
description: >-
|
|
131
|
+
The host port to which the Firebase Storage emulator is bound.
|
|
132
|
+
|
|
133
|
+
Override this to run several workspaces in parallel on the
|
|
134
|
+
same machine. Defaults to `9199`.
|
|
128
135
|
securityRuleFiles:
|
|
129
136
|
type: array
|
|
130
137
|
items:
|
|
@@ -149,6 +156,14 @@ properties:
|
|
|
149
156
|
containerName:
|
|
150
157
|
type: string
|
|
151
158
|
description: The name of the local Docker container running the emulator.
|
|
159
|
+
port:
|
|
160
|
+
type: number
|
|
161
|
+
description: >-
|
|
162
|
+
The host port to which the Identity Platform (Firebase Auth)
|
|
163
|
+
emulator is bound.
|
|
164
|
+
|
|
165
|
+
Override this to run several workspaces in parallel on the
|
|
166
|
+
same machine. Defaults to `9099`.
|
|
152
167
|
firestore:
|
|
153
168
|
title: GoogleFirestore
|
|
154
169
|
type: object
|
|
@@ -162,6 +177,13 @@ properties:
|
|
|
162
177
|
containerName:
|
|
163
178
|
type: string
|
|
164
179
|
description: The name of the local Docker container running the emulator.
|
|
180
|
+
port:
|
|
181
|
+
type: number
|
|
182
|
+
description: >-
|
|
183
|
+
The host port to which the Firestore emulator is bound.
|
|
184
|
+
|
|
185
|
+
Override this to run several workspaces in parallel on the
|
|
186
|
+
same machine. Defaults to `8080`.
|
|
165
187
|
securityRuleFiles:
|
|
166
188
|
type: array
|
|
167
189
|
items:
|
|
@@ -185,6 +207,13 @@ properties:
|
|
|
185
207
|
containerName:
|
|
186
208
|
type: string
|
|
187
209
|
description: The name of the local Docker container running the emulator.
|
|
210
|
+
port:
|
|
211
|
+
type: number
|
|
212
|
+
description: >-
|
|
213
|
+
The host port to which the Pub/Sub emulator is bound.
|
|
214
|
+
|
|
215
|
+
Override this to run several workspaces in parallel on the
|
|
216
|
+
same machine. Defaults to `8085`.
|
|
188
217
|
topicConfigurationsDirectory:
|
|
189
218
|
type: string
|
|
190
219
|
description: The directory where the topic configuration files are written by
|
|
@@ -233,6 +262,20 @@ properties:
|
|
|
233
262
|
type: string
|
|
234
263
|
description: The name of the Spanner instance that will automatically be created
|
|
235
264
|
in the emulator.
|
|
265
|
+
grpcPort:
|
|
266
|
+
type: number
|
|
267
|
+
description: >-
|
|
268
|
+
The host port to which the Spanner emulator gRPC API is bound.
|
|
269
|
+
|
|
270
|
+
Override this to run several workspaces in parallel on the
|
|
271
|
+
same machine. Defaults to `9010`.
|
|
272
|
+
httpPort:
|
|
273
|
+
type: number
|
|
274
|
+
description: >-
|
|
275
|
+
The host port to which the Spanner emulator HTTP API is bound.
|
|
276
|
+
|
|
277
|
+
Override this to run several workspaces in parallel on the
|
|
278
|
+
same machine. Defaults to `9020`.
|
|
236
279
|
instance:
|
|
237
280
|
title: GoogleSpannerInstance
|
|
238
281
|
type: object
|
|
@@ -11,9 +11,17 @@ export declare const FIREBASE_STORAGE_EMULATOR_NAME = "google.firebaseStorage";
|
|
|
11
11
|
*/
|
|
12
12
|
export declare function getFirebaseStorageContainerName(context: WorkspaceContext): string;
|
|
13
13
|
/**
|
|
14
|
-
* The exposed port for Firebase Storage.
|
|
14
|
+
* The default exposed host port for Firebase Storage.
|
|
15
15
|
*/
|
|
16
16
|
export declare const FIREBASE_STORAGE_PORT = 9199;
|
|
17
|
+
/**
|
|
18
|
+
* Returns the host port to which the Firebase Storage emulator should be bound.
|
|
19
|
+
* Reads `google.firebaseStorage.emulator.port`, falling back to {@link FIREBASE_STORAGE_PORT}.
|
|
20
|
+
*
|
|
21
|
+
* @param context The {@link WorkspaceContext}.
|
|
22
|
+
* @returns The host port for the Firebase Storage emulator.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getFirebaseStorageEmulatorPort(context: WorkspaceContext): number;
|
|
17
25
|
/**
|
|
18
26
|
* The location of the Firebase Storage security rules file within the container.
|
|
19
27
|
*/
|
|
@@ -19,9 +19,21 @@ export function getFirebaseStorageContainerName(context) {
|
|
|
19
19
|
return `${workspaceName}-firebase-storage`;
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
|
-
* The exposed port for Firebase Storage.
|
|
22
|
+
* The default exposed host port for Firebase Storage.
|
|
23
23
|
*/
|
|
24
24
|
export const FIREBASE_STORAGE_PORT = 9199;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the host port to which the Firebase Storage emulator should be bound.
|
|
27
|
+
* Reads `google.firebaseStorage.emulator.port`, falling back to {@link FIREBASE_STORAGE_PORT}.
|
|
28
|
+
*
|
|
29
|
+
* @param context The {@link WorkspaceContext}.
|
|
30
|
+
* @returns The host port for the Firebase Storage emulator.
|
|
31
|
+
*/
|
|
32
|
+
export function getFirebaseStorageEmulatorPort(context) {
|
|
33
|
+
return (context
|
|
34
|
+
.asConfiguration()
|
|
35
|
+
.get('google.firebaseStorage.emulator.port') ?? FIREBASE_STORAGE_PORT);
|
|
36
|
+
}
|
|
25
37
|
/**
|
|
26
38
|
* The location of the Firebase Storage security rules file within the container.
|
|
27
39
|
*/
|
|
@@ -15,6 +15,14 @@ export declare function getFirestoreContainerName(context: WorkspaceContext): st
|
|
|
15
15
|
*/
|
|
16
16
|
export declare const FIRESTORE_CONTAINER_RULES_FILE = "/firestore.rules";
|
|
17
17
|
/**
|
|
18
|
-
* The port on which the Firestore emulator listens.
|
|
18
|
+
* The default host port on which the Firestore emulator listens.
|
|
19
19
|
*/
|
|
20
20
|
export declare const FIRESTORE_PORT = 8080;
|
|
21
|
+
/**
|
|
22
|
+
* Returns the host port to which the Firestore emulator should be bound.
|
|
23
|
+
* Reads `google.firestore.emulator.port`, falling back to {@link FIRESTORE_PORT}.
|
|
24
|
+
*
|
|
25
|
+
* @param context The {@link WorkspaceContext}.
|
|
26
|
+
* @returns The host port for the Firestore emulator.
|
|
27
|
+
*/
|
|
28
|
+
export declare function getFirestoreEmulatorPort(context: WorkspaceContext): number;
|
|
@@ -23,6 +23,18 @@ export function getFirestoreContainerName(context) {
|
|
|
23
23
|
*/
|
|
24
24
|
export const FIRESTORE_CONTAINER_RULES_FILE = '/firestore.rules';
|
|
25
25
|
/**
|
|
26
|
-
* The port on which the Firestore emulator listens.
|
|
26
|
+
* The default host port on which the Firestore emulator listens.
|
|
27
27
|
*/
|
|
28
28
|
export const FIRESTORE_PORT = 8080;
|
|
29
|
+
/**
|
|
30
|
+
* Returns the host port to which the Firestore emulator should be bound.
|
|
31
|
+
* Reads `google.firestore.emulator.port`, falling back to {@link FIRESTORE_PORT}.
|
|
32
|
+
*
|
|
33
|
+
* @param context The {@link WorkspaceContext}.
|
|
34
|
+
* @returns The host port for the Firestore emulator.
|
|
35
|
+
*/
|
|
36
|
+
export function getFirestoreEmulatorPort(context) {
|
|
37
|
+
return (context
|
|
38
|
+
.asConfiguration()
|
|
39
|
+
.get('google.firestore.emulator.port') ?? FIRESTORE_PORT);
|
|
40
|
+
}
|
|
@@ -11,6 +11,14 @@ export declare const IDENTITY_PLATFORM_EMULATOR_NAME = "google.identityPlatform"
|
|
|
11
11
|
*/
|
|
12
12
|
export declare function getIdentityPlatformContainerName(context: WorkspaceContext): string;
|
|
13
13
|
/**
|
|
14
|
-
* The port on which the Firebase Auth emulator is listening.
|
|
14
|
+
* The default host port on which the Firebase Auth emulator is listening.
|
|
15
15
|
*/
|
|
16
16
|
export declare const FIREBASE_AUTH_PORT = 9099;
|
|
17
|
+
/**
|
|
18
|
+
* Returns the host port to which the Identity Platform (Firebase Auth) emulator should be bound.
|
|
19
|
+
* Reads `google.identityPlatform.emulator.port`, falling back to {@link FIREBASE_AUTH_PORT}.
|
|
20
|
+
*
|
|
21
|
+
* @param context The {@link WorkspaceContext}.
|
|
22
|
+
* @returns The host port for the Identity Platform emulator.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getIdentityPlatformEmulatorPort(context: WorkspaceContext): number;
|
|
@@ -19,6 +19,18 @@ export function getIdentityPlatformContainerName(context) {
|
|
|
19
19
|
return `${workspaceName}-identity-platform`;
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
|
-
* The port on which the Firebase Auth emulator is listening.
|
|
22
|
+
* The default host port on which the Firebase Auth emulator is listening.
|
|
23
23
|
*/
|
|
24
24
|
export const FIREBASE_AUTH_PORT = 9099;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the host port to which the Identity Platform (Firebase Auth) emulator should be bound.
|
|
27
|
+
* Reads `google.identityPlatform.emulator.port`, falling back to {@link FIREBASE_AUTH_PORT}.
|
|
28
|
+
*
|
|
29
|
+
* @param context The {@link WorkspaceContext}.
|
|
30
|
+
* @returns The host port for the Identity Platform emulator.
|
|
31
|
+
*/
|
|
32
|
+
export function getIdentityPlatformEmulatorPort(context) {
|
|
33
|
+
return (context
|
|
34
|
+
.asConfiguration()
|
|
35
|
+
.get('google.identityPlatform.emulator.port') ?? FIREBASE_AUTH_PORT);
|
|
36
|
+
}
|
|
@@ -11,9 +11,17 @@ export declare const PUBSUB_EMULATOR_NAME = "google.pubSub";
|
|
|
11
11
|
*/
|
|
12
12
|
export declare function getPubSubContainerName(context: WorkspaceContext): string;
|
|
13
13
|
/**
|
|
14
|
-
* The port on which the Pub/Sub emulator is listening.
|
|
14
|
+
* The default host port on which the Pub/Sub emulator is listening.
|
|
15
15
|
*/
|
|
16
16
|
export declare const PUBSUB_PORT = 8085;
|
|
17
|
+
/**
|
|
18
|
+
* Returns the host port to which the Pub/Sub emulator should be bound.
|
|
19
|
+
* Reads `google.pubSub.emulator.port`, falling back to {@link PUBSUB_PORT}.
|
|
20
|
+
*
|
|
21
|
+
* @param context The {@link WorkspaceContext}.
|
|
22
|
+
* @returns The host port for the Pub/Sub emulator.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getPubSubEmulatorPort(context: WorkspaceContext): number;
|
|
17
25
|
/**
|
|
18
26
|
* Formats the name of a Pub/Sub topic as an environment variable.
|
|
19
27
|
* The value of the corresponding environment variable is expected to be the Pub/Sub topic ID, e.g.
|
package/dist/emulators/pubsub.js
CHANGED
|
@@ -19,9 +19,21 @@ export function getPubSubContainerName(context) {
|
|
|
19
19
|
return `${workspaceName}-pubsub`;
|
|
20
20
|
}
|
|
21
21
|
/**
|
|
22
|
-
* The port on which the Pub/Sub emulator is listening.
|
|
22
|
+
* The default host port on which the Pub/Sub emulator is listening.
|
|
23
23
|
*/
|
|
24
24
|
export const PUBSUB_PORT = 8085;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the host port to which the Pub/Sub emulator should be bound.
|
|
27
|
+
* Reads `google.pubSub.emulator.port`, falling back to {@link PUBSUB_PORT}.
|
|
28
|
+
*
|
|
29
|
+
* @param context The {@link WorkspaceContext}.
|
|
30
|
+
* @returns The host port for the Pub/Sub emulator.
|
|
31
|
+
*/
|
|
32
|
+
export function getPubSubEmulatorPort(context) {
|
|
33
|
+
return (context
|
|
34
|
+
.asConfiguration()
|
|
35
|
+
.get('google.pubSub.emulator.port') ?? PUBSUB_PORT);
|
|
36
|
+
}
|
|
25
37
|
/**
|
|
26
38
|
* Formats the name of a Pub/Sub topic as an environment variable.
|
|
27
39
|
* The value of the corresponding environment variable is expected to be the Pub/Sub topic ID, e.g.
|
|
@@ -15,10 +15,26 @@ export declare function getSpannerContainerName(context: WorkspaceContext): stri
|
|
|
15
15
|
*/
|
|
16
16
|
export declare const SPANNER_IMAGE = "gcr.io/cloud-spanner-emulator/emulator";
|
|
17
17
|
/**
|
|
18
|
-
* The port on which the Spanner emulator exposes its gRPC API.
|
|
18
|
+
* The default host port on which the Spanner emulator exposes its gRPC API.
|
|
19
19
|
*/
|
|
20
20
|
export declare const SPANNER_GRPC_PORT = 9010;
|
|
21
21
|
/**
|
|
22
|
-
* The port on which the Spanner emulator exposes its HTTP API.
|
|
22
|
+
* The default host port on which the Spanner emulator exposes its HTTP API.
|
|
23
23
|
*/
|
|
24
24
|
export declare const SPANNER_HTTP_PORT = 9020;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the host port to which the Spanner emulator gRPC API should be bound.
|
|
27
|
+
* Reads `google.spanner.emulator.grpcPort`, falling back to {@link SPANNER_GRPC_PORT}.
|
|
28
|
+
*
|
|
29
|
+
* @param context The {@link WorkspaceContext}.
|
|
30
|
+
* @returns The host gRPC port for the Spanner emulator.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getSpannerEmulatorGrpcPort(context: WorkspaceContext): number;
|
|
33
|
+
/**
|
|
34
|
+
* Returns the host port to which the Spanner emulator HTTP API should be bound.
|
|
35
|
+
* Reads `google.spanner.emulator.httpPort`, falling back to {@link SPANNER_HTTP_PORT}.
|
|
36
|
+
*
|
|
37
|
+
* @param context The {@link WorkspaceContext}.
|
|
38
|
+
* @returns The host HTTP port for the Spanner emulator.
|
|
39
|
+
*/
|
|
40
|
+
export declare function getSpannerEmulatorHttpPort(context: WorkspaceContext): number;
|
|
@@ -23,10 +23,34 @@ export function getSpannerContainerName(context) {
|
|
|
23
23
|
*/
|
|
24
24
|
export const SPANNER_IMAGE = `gcr.io/cloud-spanner-emulator/emulator`;
|
|
25
25
|
/**
|
|
26
|
-
* The port on which the Spanner emulator exposes its gRPC API.
|
|
26
|
+
* The default host port on which the Spanner emulator exposes its gRPC API.
|
|
27
27
|
*/
|
|
28
28
|
export const SPANNER_GRPC_PORT = 9010;
|
|
29
29
|
/**
|
|
30
|
-
* The port on which the Spanner emulator exposes its HTTP API.
|
|
30
|
+
* The default host port on which the Spanner emulator exposes its HTTP API.
|
|
31
31
|
*/
|
|
32
32
|
export const SPANNER_HTTP_PORT = 9020;
|
|
33
|
+
/**
|
|
34
|
+
* Returns the host port to which the Spanner emulator gRPC API should be bound.
|
|
35
|
+
* Reads `google.spanner.emulator.grpcPort`, falling back to {@link SPANNER_GRPC_PORT}.
|
|
36
|
+
*
|
|
37
|
+
* @param context The {@link WorkspaceContext}.
|
|
38
|
+
* @returns The host gRPC port for the Spanner emulator.
|
|
39
|
+
*/
|
|
40
|
+
export function getSpannerEmulatorGrpcPort(context) {
|
|
41
|
+
return (context
|
|
42
|
+
.asConfiguration()
|
|
43
|
+
.get('google.spanner.emulator.grpcPort') ?? SPANNER_GRPC_PORT);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Returns the host port to which the Spanner emulator HTTP API should be bound.
|
|
47
|
+
* Reads `google.spanner.emulator.httpPort`, falling back to {@link SPANNER_HTTP_PORT}.
|
|
48
|
+
*
|
|
49
|
+
* @param context The {@link WorkspaceContext}.
|
|
50
|
+
* @returns The host HTTP port for the Spanner emulator.
|
|
51
|
+
*/
|
|
52
|
+
export function getSpannerEmulatorHttpPort(context) {
|
|
53
|
+
return (context
|
|
54
|
+
.asConfiguration()
|
|
55
|
+
.get('google.spanner.emulator.httpPort') ?? SPANNER_HTTP_PORT);
|
|
56
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EmulatorStart } from '@causa/workspace-core';
|
|
2
2
|
import { fileURLToPath } from 'url';
|
|
3
|
-
import { FIREBASE_CONTAINER_STORAGE_RULES_FILE, FIREBASE_STORAGE_EMULATOR_NAME, FIREBASE_STORAGE_PORT, getFirebaseStorageContainerName, } from '../../emulators/index.js';
|
|
3
|
+
import { FIREBASE_CONTAINER_STORAGE_RULES_FILE, FIREBASE_STORAGE_EMULATOR_NAME, FIREBASE_STORAGE_PORT, getFirebaseStorageContainerName, getFirebaseStorageEmulatorPort, } from '../../emulators/index.js';
|
|
4
4
|
import { FirebaseEmulatorService } from '../../services/firebase-emulator.js';
|
|
5
5
|
import { GoogleFirebaseStorageMergeRules } from '../google-firebase-storage/index.js';
|
|
6
6
|
/**
|
|
@@ -30,12 +30,13 @@ export class EmulatorStartForFirebaseStorage extends EmulatorStart {
|
|
|
30
30
|
const { securityRuleFile } = await this._context.call(GoogleFirebaseStorageMergeRules, {});
|
|
31
31
|
this._context.logger.info('️🍱 Starting Firebase Storage emulator.');
|
|
32
32
|
const containerName = getFirebaseStorageContainerName(this._context);
|
|
33
|
+
const hostPort = getFirebaseStorageEmulatorPort(this._context);
|
|
33
34
|
const firebaseEmulatorService = this._context.service(FirebaseEmulatorService);
|
|
34
35
|
await firebaseEmulatorService.start(containerName, FIREBASE_CONF_FILE, [
|
|
35
36
|
{
|
|
36
37
|
host: '127.0.0.1',
|
|
37
38
|
container: FIREBASE_STORAGE_PORT,
|
|
38
|
-
local:
|
|
39
|
+
local: hostPort,
|
|
39
40
|
},
|
|
40
41
|
], {
|
|
41
42
|
mounts: [
|
|
@@ -51,7 +52,7 @@ export class EmulatorStartForFirebaseStorage extends EmulatorStart {
|
|
|
51
52
|
});
|
|
52
53
|
this._context.logger.info('️🍱 Successfully initialized Firebase Storage emulator.');
|
|
53
54
|
return {
|
|
54
|
-
FIREBASE_STORAGE_EMULATOR_HOST: `127.0.0.1:${
|
|
55
|
+
FIREBASE_STORAGE_EMULATOR_HOST: `127.0.0.1:${hostPort}`,
|
|
55
56
|
GOOGLE_CLOUD_PROJECT: firebaseEmulatorService.localGcpProject,
|
|
56
57
|
GCP_PROJECT: firebaseEmulatorService.localGcpProject,
|
|
57
58
|
GCLOUD_PROJECT: firebaseEmulatorService.localGcpProject,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EmulatorStart } from '@causa/workspace-core';
|
|
2
|
-
import { FIRESTORE_CONTAINER_RULES_FILE, FIRESTORE_EMULATOR_NAME, FIRESTORE_PORT, getFirestoreContainerName, } from '../../emulators/index.js';
|
|
2
|
+
import { FIRESTORE_CONTAINER_RULES_FILE, FIRESTORE_EMULATOR_NAME, FIRESTORE_PORT, getFirestoreContainerName, getFirestoreEmulatorPort, } from '../../emulators/index.js';
|
|
3
3
|
import { GcloudEmulatorService } from '../../services/gcloud-emulator.js';
|
|
4
4
|
import { GoogleFirestoreMergeRules } from '../google-firestore/index.js';
|
|
5
5
|
/**
|
|
@@ -26,14 +26,9 @@ export class EmulatorStartForFirestore extends EmulatorStart {
|
|
|
26
26
|
const { securityRuleFile } = await this._context.call(GoogleFirestoreMergeRules, {});
|
|
27
27
|
this._context.logger.info('🗃️ Starting Firestore emulator.');
|
|
28
28
|
const containerName = getFirestoreContainerName(this._context);
|
|
29
|
+
const hostPort = getFirestoreEmulatorPort(this._context);
|
|
29
30
|
const gcloudEmulatorService = this._context.service(GcloudEmulatorService);
|
|
30
|
-
await gcloudEmulatorService.start('firestore', containerName, [
|
|
31
|
-
{
|
|
32
|
-
host: '127.0.0.1',
|
|
33
|
-
local: FIRESTORE_PORT,
|
|
34
|
-
container: FIRESTORE_PORT,
|
|
35
|
-
},
|
|
36
|
-
], {
|
|
31
|
+
await gcloudEmulatorService.start('firestore', containerName, [{ host: '127.0.0.1', local: hostPort, container: FIRESTORE_PORT }], {
|
|
37
32
|
mounts: [
|
|
38
33
|
{
|
|
39
34
|
type: 'bind',
|
|
@@ -43,11 +38,11 @@ export class EmulatorStartForFirestore extends EmulatorStart {
|
|
|
43
38
|
},
|
|
44
39
|
],
|
|
45
40
|
additionalArguments: ['--rules', FIRESTORE_CONTAINER_RULES_FILE],
|
|
46
|
-
availabilityEndpoint: `http://127.0.0.1:${
|
|
41
|
+
availabilityEndpoint: `http://127.0.0.1:${hostPort}/`,
|
|
47
42
|
});
|
|
48
43
|
this._context.logger.info('🗃️ Successfully initialized Firestore emulator.');
|
|
49
44
|
return {
|
|
50
|
-
FIRESTORE_EMULATOR_HOST: `127.0.0.1:${
|
|
45
|
+
FIRESTORE_EMULATOR_HOST: `127.0.0.1:${hostPort}`,
|
|
51
46
|
GOOGLE_CLOUD_PROJECT: gcloudEmulatorService.localGcpProject,
|
|
52
47
|
GCP_PROJECT: gcloudEmulatorService.localGcpProject,
|
|
53
48
|
GCLOUD_PROJECT: gcloudEmulatorService.localGcpProject,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { EmulatorStart } from '@causa/workspace-core';
|
|
2
2
|
import { fileURLToPath } from 'url';
|
|
3
|
-
import { FIREBASE_AUTH_PORT, IDENTITY_PLATFORM_EMULATOR_NAME, getIdentityPlatformContainerName, } from '../../emulators/index.js';
|
|
3
|
+
import { FIREBASE_AUTH_PORT, IDENTITY_PLATFORM_EMULATOR_NAME, getIdentityPlatformContainerName, getIdentityPlatformEmulatorPort, } from '../../emulators/index.js';
|
|
4
4
|
import { FirebaseEmulatorService } from '../../services/firebase-emulator.js';
|
|
5
5
|
/**
|
|
6
6
|
* The Firebase configuration file enabling only the Auth emulator.
|
|
@@ -27,17 +27,14 @@ export class EmulatorStartForIdentityPlatform extends EmulatorStart {
|
|
|
27
27
|
}
|
|
28
28
|
this._context.logger.info('🛂 Starting the Identity Platform emulator.');
|
|
29
29
|
const containerName = getIdentityPlatformContainerName(this._context);
|
|
30
|
+
const hostPort = getIdentityPlatformEmulatorPort(this._context);
|
|
30
31
|
const firebaseEmulatorService = this._context.service(FirebaseEmulatorService);
|
|
31
32
|
await firebaseEmulatorService.start(containerName, FIREBASE_CONF_FILE, [
|
|
32
|
-
{
|
|
33
|
-
host: '127.0.0.1',
|
|
34
|
-
local: FIREBASE_AUTH_PORT,
|
|
35
|
-
container: FIREBASE_AUTH_PORT,
|
|
36
|
-
},
|
|
33
|
+
{ host: '127.0.0.1', local: hostPort, container: FIREBASE_AUTH_PORT },
|
|
37
34
|
]);
|
|
38
35
|
this._context.logger.info('🛂 Successfully initialized the Identity Platform emulator.');
|
|
39
36
|
return {
|
|
40
|
-
FIREBASE_AUTH_EMULATOR_HOST: `127.0.0.1:${
|
|
37
|
+
FIREBASE_AUTH_EMULATOR_HOST: `127.0.0.1:${hostPort}`,
|
|
41
38
|
GOOGLE_CLOUD_PROJECT: firebaseEmulatorService.localGcpProject,
|
|
42
39
|
GCP_PROJECT: firebaseEmulatorService.localGcpProject,
|
|
43
40
|
GCLOUD_PROJECT: firebaseEmulatorService.localGcpProject,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EventTopicList, } from '@causa/workspace-core';
|
|
2
2
|
import { PubSub } from '@google-cloud/pubsub';
|
|
3
3
|
import { getLocalGcpProject } from '../../configurations/utils.js';
|
|
4
|
-
import { PUBSUB_EMULATOR_NAME, PUBSUB_PORT, formatPubSubTopicAsEnvironmentVariable, getPubSubContainerName, } from '../../emulators/index.js';
|
|
4
|
+
import { PUBSUB_EMULATOR_NAME, PUBSUB_PORT, formatPubSubTopicAsEnvironmentVariable, getPubSubContainerName, getPubSubEmulatorPort, } from '../../emulators/index.js';
|
|
5
5
|
import { GcloudEmulatorService } from '../../services/gcloud-emulator.js';
|
|
6
6
|
export default async function call() {
|
|
7
7
|
const configuration = await startPubSub(this, this._context);
|
|
@@ -11,27 +11,28 @@ async function startPubSub(self, context) {
|
|
|
11
11
|
if (self.dryRun) {
|
|
12
12
|
return {};
|
|
13
13
|
}
|
|
14
|
-
const
|
|
15
|
-
const
|
|
14
|
+
const hostPort = getPubSubEmulatorPort(context);
|
|
15
|
+
const emulatorConf = await startPubSubEmulator(context, hostPort);
|
|
16
|
+
const topicsConf = await createTopicsIfNeeded(context, hostPort);
|
|
16
17
|
context.logger.info('📫 Successfully initialized Pub/Sub emulator.');
|
|
17
18
|
return { ...emulatorConf, ...topicsConf };
|
|
18
19
|
}
|
|
19
|
-
async function startPubSubEmulator(context) {
|
|
20
|
+
async function startPubSubEmulator(context, hostPort) {
|
|
20
21
|
context.logger.info('📫 Starting Pub/Sub emulator.');
|
|
21
22
|
const gcpProject = getLocalGcpProject(context);
|
|
22
23
|
const containerName = getPubSubContainerName(context);
|
|
23
24
|
const gcloudEmulatorService = context.service(GcloudEmulatorService);
|
|
24
|
-
await gcloudEmulatorService.start('pubsub', containerName, [{ host: '127.0.0.1', local:
|
|
25
|
-
availabilityEndpoint: `http://127.0.0.1:${
|
|
25
|
+
await gcloudEmulatorService.start('pubsub', containerName, [{ host: '127.0.0.1', local: hostPort, container: PUBSUB_PORT }], {
|
|
26
|
+
availabilityEndpoint: `http://127.0.0.1:${hostPort}/v1/projects/${gcpProject}/topics`,
|
|
26
27
|
});
|
|
27
28
|
return {
|
|
28
|
-
PUBSUB_EMULATOR_HOST: `127.0.0.1:${
|
|
29
|
+
PUBSUB_EMULATOR_HOST: `127.0.0.1:${hostPort}`,
|
|
29
30
|
GOOGLE_CLOUD_PROJECT: gcloudEmulatorService.localGcpProject,
|
|
30
31
|
GCP_PROJECT: gcloudEmulatorService.localGcpProject,
|
|
31
32
|
GCLOUD_PROJECT: gcloudEmulatorService.localGcpProject,
|
|
32
33
|
};
|
|
33
34
|
}
|
|
34
|
-
async function createTopicsIfNeeded(context) {
|
|
35
|
+
async function createTopicsIfNeeded(context, hostPort) {
|
|
35
36
|
if (context.get('events.broker') !== 'google.pubSub') {
|
|
36
37
|
context.logger.warn('📫️ Pub/Sub is not set as the event broker. Skipping event topics setup.');
|
|
37
38
|
return {};
|
|
@@ -40,7 +41,7 @@ async function createTopicsIfNeeded(context) {
|
|
|
40
41
|
const gcpProject = getLocalGcpProject(context);
|
|
41
42
|
const pubSub = new PubSub({
|
|
42
43
|
projectId: gcpProject,
|
|
43
|
-
apiEndpoint: `127.0.0.1:${
|
|
44
|
+
apiEndpoint: `127.0.0.1:${hostPort}`,
|
|
44
45
|
});
|
|
45
46
|
const envVars = await Promise.all(topics.map(async ({ id }) => {
|
|
46
47
|
context.logger.info(`📫 Creating Pub/Sub emulator topic '${id}'.`);
|
|
@@ -5,7 +5,7 @@ import { Instance, Spanner } from '@google-cloud/spanner';
|
|
|
5
5
|
// version can be loaded.
|
|
6
6
|
import { grpc } from 'google-gax';
|
|
7
7
|
import { getLocalGcpProject, } from '../../configurations/index.js';
|
|
8
|
-
import { SPANNER_EMULATOR_NAME, SPANNER_GRPC_PORT, SPANNER_HTTP_PORT, SPANNER_IMAGE, getSpannerContainerName, } from '../../emulators/index.js';
|
|
8
|
+
import { SPANNER_EMULATOR_NAME, SPANNER_GRPC_PORT, SPANNER_HTTP_PORT, SPANNER_IMAGE, getSpannerContainerName, getSpannerEmulatorGrpcPort, getSpannerEmulatorHttpPort, } from '../../emulators/index.js';
|
|
9
9
|
import { GoogleSpannerListDatabases } from '../google-spanner/index.js';
|
|
10
10
|
export default async function call() {
|
|
11
11
|
const configuration = await startSpanner(this, this._context);
|
|
@@ -15,12 +15,14 @@ async function startSpanner(self, context) {
|
|
|
15
15
|
if (self.dryRun) {
|
|
16
16
|
return {};
|
|
17
17
|
}
|
|
18
|
-
const
|
|
19
|
-
const
|
|
18
|
+
const grpcHostPort = getSpannerEmulatorGrpcPort(context);
|
|
19
|
+
const httpHostPort = getSpannerEmulatorHttpPort(context);
|
|
20
|
+
const emulatorConf = await startSpannerEmulator(context, grpcHostPort, httpHostPort);
|
|
21
|
+
const instanceAndDatabaseConf = await initializeEmulator(context, grpcHostPort);
|
|
20
22
|
context.logger.info('🗃️ Successfully initialized Spanner emulator.');
|
|
21
23
|
return { ...emulatorConf, ...instanceAndDatabaseConf };
|
|
22
24
|
}
|
|
23
|
-
async function startSpannerEmulator(context) {
|
|
25
|
+
async function startSpannerEmulator(context, grpcHostPort, httpHostPort) {
|
|
24
26
|
context.logger.info('🗃️ Starting Spanner emulator.');
|
|
25
27
|
const gcpProject = getLocalGcpProject(context);
|
|
26
28
|
const containerName = getSpannerContainerName(context);
|
|
@@ -28,23 +30,22 @@ async function startSpannerEmulator(context) {
|
|
|
28
30
|
.asConfiguration()
|
|
29
31
|
.get('google.spanner.emulator.version') ?? 'latest';
|
|
30
32
|
const dockerEmulatorService = context.service(DockerEmulatorService);
|
|
31
|
-
await dockerEmulatorService.start(`${SPANNER_IMAGE}:${imageVersion}`, containerName, [
|
|
32
|
-
host: '127.0.0.1',
|
|
33
|
-
local:
|
|
34
|
-
|
|
35
|
-
})
|
|
36
|
-
await dockerEmulatorService.waitForAvailability(containerName, `http://127.0.0.1:${SPANNER_HTTP_PORT}/v1/projects/${gcpProject}/instances`);
|
|
33
|
+
await dockerEmulatorService.start(`${SPANNER_IMAGE}:${imageVersion}`, containerName, [
|
|
34
|
+
{ host: '127.0.0.1', local: grpcHostPort, container: SPANNER_GRPC_PORT },
|
|
35
|
+
{ host: '127.0.0.1', local: httpHostPort, container: SPANNER_HTTP_PORT },
|
|
36
|
+
]);
|
|
37
|
+
await dockerEmulatorService.waitForAvailability(containerName, `http://127.0.0.1:${httpHostPort}/v1/projects/${gcpProject}/instances`);
|
|
37
38
|
return {
|
|
38
|
-
SPANNER_EMULATOR_HOST: `127.0.0.1:${
|
|
39
|
+
SPANNER_EMULATOR_HOST: `127.0.0.1:${grpcHostPort}`,
|
|
39
40
|
GOOGLE_CLOUD_PROJECT: gcpProject,
|
|
40
41
|
GCP_PROJECT: gcpProject,
|
|
41
42
|
GCLOUD_PROJECT: gcpProject,
|
|
42
43
|
};
|
|
43
44
|
}
|
|
44
|
-
async function initializeEmulator(context) {
|
|
45
|
+
async function initializeEmulator(context, port) {
|
|
45
46
|
const spanner = new Spanner({
|
|
46
47
|
servicePath: '127.0.0.1',
|
|
47
|
-
port
|
|
48
|
+
port,
|
|
48
49
|
projectId: getLocalGcpProject(context),
|
|
49
50
|
sslCreds: grpc.credentials.createInsecure(),
|
|
50
51
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { callDeferred } from '@causa/workspace';
|
|
2
2
|
import { EventTopicBrokerDeleteTriggerResource, } from '@causa/workspace-core';
|
|
3
|
+
import { PUBSUB_SUBSCRIPTION_ID_REGEX } from '../../services/pubsub.utils.js';
|
|
3
4
|
/**
|
|
4
5
|
* Implements {@link EventTopicBrokerDeleteTriggerResource} for Pub/Sub subscriptions.
|
|
5
6
|
* Pub/Sub subscriptions are for example used when creating Cloud Run triggers.
|
|
@@ -9,7 +10,7 @@ export class EventTopicBrokerDeleteTriggerResourceForPubSubSubscription extends
|
|
|
9
10
|
return await callDeferred(this, import.meta.url);
|
|
10
11
|
}
|
|
11
12
|
_supports() {
|
|
12
|
-
return (this.id
|
|
13
|
+
return (PUBSUB_SUBSCRIPTION_ID_REGEX.test(this.id) &&
|
|
13
14
|
this._context
|
|
14
15
|
.asConfiguration()
|
|
15
16
|
.get('events.broker') === 'google.pubSub');
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { setTimeout } from 'timers/promises';
|
|
2
|
+
import { CloudMonitoringService, } from '../../services/cloud-monitoring.js';
|
|
3
|
+
import { PUBSUB_SUBSCRIPTION_ID_REGEX, shortSubscriptionId, } from '../../services/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* The interval between two consecutive polls of the Cloud Monitoring API, in milliseconds.
|
|
6
|
+
*/
|
|
7
|
+
const POLL_INTERVAL = 30 * 1000;
|
|
8
|
+
/**
|
|
9
|
+
* The duration of the trailing window of points fetched on each poll, in milliseconds.
|
|
10
|
+
* It must be greater than `QUIET_WINDOW` plus a margin for the Cloud Monitoring export lag.
|
|
11
|
+
*/
|
|
12
|
+
const TRAILING_WINDOW = 10 * 60 * 1000;
|
|
13
|
+
/**
|
|
14
|
+
* The minimum duration (server-time, derived from point timestamps) over which all three monitored metrics must
|
|
15
|
+
* continuously report zero before a subscription is considered drained, in milliseconds.
|
|
16
|
+
*/
|
|
17
|
+
const QUIET_WINDOW = 3 * 60 * 1000;
|
|
18
|
+
/**
|
|
19
|
+
* The alignment period used when querying the cumulative `ack_message_count` metric so that points represent the
|
|
20
|
+
* number of acks within each bucket (delta), rather than the absolute cumulative value, in seconds.
|
|
21
|
+
*/
|
|
22
|
+
const ALIGNMENT_PERIOD = 60;
|
|
23
|
+
/**
|
|
24
|
+
* The overall timeout for waiting on a single subscription, in milliseconds.
|
|
25
|
+
* On timeout the function throws so that the backfill file is preserved for manual cleanup.
|
|
26
|
+
*/
|
|
27
|
+
const TIMEOUT = 60 * 60 * 1000;
|
|
28
|
+
/**
|
|
29
|
+
* Returns the Cloud Monitoring filter for the given metric on the given subscription.
|
|
30
|
+
*/
|
|
31
|
+
function buildFilter(metricType, subscriptionId) {
|
|
32
|
+
return [
|
|
33
|
+
`metric.type = "${metricType}"`,
|
|
34
|
+
`resource.type = "pubsub_subscription"`,
|
|
35
|
+
`resource.labels.subscription_id = "${subscriptionId}"`,
|
|
36
|
+
].join(' AND ');
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Checks whether a gauge metric has been quiet (zero-valued) for at least {@link QUIET_WINDOW}.
|
|
40
|
+
*
|
|
41
|
+
* The check is purely server-side: the latest zero-valued point's timestamp must be at least `QUIET_WINDOW` after the
|
|
42
|
+
* latest non-zero point's timestamp. When no non-zero point exists in the trailing window, the metric is considered
|
|
43
|
+
* quiet (the outer liftoff gate is responsible for distinguishing "cold start" from "already drained").
|
|
44
|
+
*/
|
|
45
|
+
function isGaugeQuiet(points) {
|
|
46
|
+
const lastNonZeroTimestamp = points.filter(({ value }) => value > 0).at(-1)?.timestamp ?? -Infinity;
|
|
47
|
+
const latestZeroTimestamp = points.filter(({ value }) => value === 0).at(-1)?.timestamp ?? -Infinity;
|
|
48
|
+
return latestZeroTimestamp - lastNonZeroTimestamp >= QUIET_WINDOW;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Checks whether a cumulative metric (queried with `ALIGN_DELTA`) has had no non-zero activity in the trailing
|
|
52
|
+
* `QUIET_WINDOW` before the given reference time.
|
|
53
|
+
*
|
|
54
|
+
* Unlike a gauge, Pub/Sub stops writing samples for a cumulative metric while there is no activity. The server-side
|
|
55
|
+
* "still has zero points" anchor used by {@link isGaugeQuiet} therefore does not apply: the absence of points must be
|
|
56
|
+
* interpreted against an external time reference (the query end).
|
|
57
|
+
*/
|
|
58
|
+
function isCumulativeQuiet(points, referenceTime) {
|
|
59
|
+
const lastNonZeroTimestamp = points.filter(({ value }) => value > 0).at(-1)?.timestamp ?? -Infinity;
|
|
60
|
+
return referenceTime.getTime() - lastNonZeroTimestamp >= QUIET_WINDOW;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Observes a single subscription by fetching its three metrics over the configured trailing window and evaluating the
|
|
64
|
+
* liftoff and quiet conditions.
|
|
65
|
+
*/
|
|
66
|
+
async function observeSubscription(context, subscriptionId) {
|
|
67
|
+
const cms = context.service(CloudMonitoringService);
|
|
68
|
+
const end = new Date();
|
|
69
|
+
const start = new Date(end.getTime() - TRAILING_WINDOW);
|
|
70
|
+
const ackFilter = buildFilter('pubsub.googleapis.com/subscription/ack_message_count', subscriptionId);
|
|
71
|
+
const backlogFilter = buildFilter('pubsub.googleapis.com/subscription/num_undelivered_messages', subscriptionId);
|
|
72
|
+
const ageFilter = buildFilter('pubsub.googleapis.com/subscription/oldest_unacked_message_age', subscriptionId);
|
|
73
|
+
const [ackPoints, backlogPoints, agePoints] = await Promise.all([
|
|
74
|
+
cms.listPoints(ackFilter, start, end, {
|
|
75
|
+
aligner: 'ALIGN_DELTA',
|
|
76
|
+
alignmentPeriod: ALIGNMENT_PERIOD,
|
|
77
|
+
}),
|
|
78
|
+
cms.listPoints(backlogFilter, start, end),
|
|
79
|
+
cms.listPoints(ageFilter, start, end),
|
|
80
|
+
]);
|
|
81
|
+
const liftoff = ackPoints.some(({ value }) => value > 0);
|
|
82
|
+
const backlog = backlogPoints.at(-1)?.value ?? null;
|
|
83
|
+
const drained = liftoff &&
|
|
84
|
+
isCumulativeQuiet(ackPoints, end) &&
|
|
85
|
+
isGaugeQuiet(backlogPoints) &&
|
|
86
|
+
isGaugeQuiet(agePoints);
|
|
87
|
+
return { liftoff, backlog, drained };
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Waits for a single subscription to be drained, polling Cloud Monitoring until either the drained state is reached
|
|
91
|
+
* or the overall timeout elapses.
|
|
92
|
+
*/
|
|
93
|
+
async function waitForSubscription(context, subscriptionId) {
|
|
94
|
+
const deadline = Date.now() + TIMEOUT;
|
|
95
|
+
while (true) {
|
|
96
|
+
const { drained, backlog, liftoff } = await observeSubscription(context, subscriptionId);
|
|
97
|
+
if (drained) {
|
|
98
|
+
context.logger.debug(`✅ Subscription '${subscriptionId}' drained: backlog is empty and metrics have been quiet for at least ${QUIET_WINDOW / 1000}s.`);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const backlogLabel = backlog === null ? 'no data yet' : `backlog=${backlog}`;
|
|
102
|
+
context.logger.debug(`⏳ Subscription '${subscriptionId}' not drained yet (liftoff=${liftoff}, ${backlogLabel}).`);
|
|
103
|
+
if (Date.now() >= deadline) {
|
|
104
|
+
throw new Error(`Timed out after ${Math.round(TIMEOUT / 60_000)} minute(s) waiting for subscription '${subscriptionId}' to drain.`);
|
|
105
|
+
}
|
|
106
|
+
await setTimeout(POLL_INTERVAL);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
export default async function call() {
|
|
110
|
+
const subscriptionIds = this.temporaryData.temporaryTriggerResourceIds
|
|
111
|
+
.filter((id) => PUBSUB_SUBSCRIPTION_ID_REGEX.test(id))
|
|
112
|
+
.map(shortSubscriptionId);
|
|
113
|
+
if (subscriptionIds.length === 0) {
|
|
114
|
+
throw new Error(`Cannot wait for processing of backfill on event topic '${this.eventTopic}': no temporary Pub/Sub subscription was created. Only backfills with temporary triggers are supported.`);
|
|
115
|
+
}
|
|
116
|
+
this._context.logger.info(`⏳ Waiting for processing of ${subscriptionIds.length} temporary Pub/Sub subscription(s) for event topic '${this.eventTopic}'.`);
|
|
117
|
+
await Promise.all(subscriptionIds.map((id) => waitForSubscription(this._context, id)));
|
|
118
|
+
this._context.logger.info(`✅ All temporary Pub/Sub subscriptions for event topic '${this.eventTopic}' have been drained.`);
|
|
119
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { EventTopicBrokerWaitForProcessing } from '@causa/workspace-core';
|
|
2
|
+
/**
|
|
3
|
+
* Implements {@link EventTopicBrokerWaitForProcessing} for Pub/Sub temporary subscriptions.
|
|
4
|
+
*
|
|
5
|
+
* Only backfills that created temporary push subscriptions are supported: at least one entry of
|
|
6
|
+
* {@link BackfillTemporaryData.temporaryTriggerResourceIds} must match a subscription ID. If none does, the function
|
|
7
|
+
* throws — there is no observable signal for backfills that publish into existing topics with existing subscriptions.
|
|
8
|
+
*
|
|
9
|
+
* Completion is decided per-subscription from Cloud Monitoring time series (`subscription/ack_message_count`,
|
|
10
|
+
* `subscription/num_undelivered_messages`, `subscription/oldest_unacked_message_age`). See the call file for the exact
|
|
11
|
+
* decision logic.
|
|
12
|
+
*/
|
|
13
|
+
export declare class EventTopicBrokerWaitForProcessingForPubSub extends EventTopicBrokerWaitForProcessing {
|
|
14
|
+
_call(): Promise<void>;
|
|
15
|
+
_supports(): boolean;
|
|
16
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { callDeferred } from '@causa/workspace';
|
|
2
|
+
import { EventTopicBrokerWaitForProcessing, } from '@causa/workspace-core';
|
|
3
|
+
/**
|
|
4
|
+
* Implements {@link EventTopicBrokerWaitForProcessing} for Pub/Sub temporary subscriptions.
|
|
5
|
+
*
|
|
6
|
+
* Only backfills that created temporary push subscriptions are supported: at least one entry of
|
|
7
|
+
* {@link BackfillTemporaryData.temporaryTriggerResourceIds} must match a subscription ID. If none does, the function
|
|
8
|
+
* throws — there is no observable signal for backfills that publish into existing topics with existing subscriptions.
|
|
9
|
+
*
|
|
10
|
+
* Completion is decided per-subscription from Cloud Monitoring time series (`subscription/ack_message_count`,
|
|
11
|
+
* `subscription/num_undelivered_messages`, `subscription/oldest_unacked_message_age`). See the call file for the exact
|
|
12
|
+
* decision logic.
|
|
13
|
+
*/
|
|
14
|
+
export class EventTopicBrokerWaitForProcessingForPubSub extends EventTopicBrokerWaitForProcessing {
|
|
15
|
+
async _call() {
|
|
16
|
+
return await callDeferred(this, import.meta.url);
|
|
17
|
+
}
|
|
18
|
+
_supports() {
|
|
19
|
+
return (this._context
|
|
20
|
+
.asConfiguration()
|
|
21
|
+
.get('events.broker') === 'google.pubSub');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -6,5 +6,6 @@ export { EventTopicBrokerDeleteTriggerResourceForPubSubSubscription } from './br
|
|
|
6
6
|
export { EventTopicBrokerDeleteTriggerResourceForServiceAccount } from './broker-delete-trigger-resource-service-account.js';
|
|
7
7
|
export { EventTopicBrokerGetTopicIdForPubSub } from './broker-get-topic-id-pubsub.js';
|
|
8
8
|
export { EventTopicBrokerPublishEventsForGoogle } from './broker-publish-events-google.js';
|
|
9
|
+
export { EventTopicBrokerWaitForProcessingForPubSub } from './broker-wait-for-processing-pubsub.js';
|
|
9
10
|
export { EventTopicCreateBackfillSourceForBigQuery } from './create-backfill-source-bigquery.js';
|
|
10
11
|
export { EventTopicQueryEventsForBigQuery } from './query-events-bigquery.js';
|
|
@@ -6,5 +6,6 @@ export { EventTopicBrokerDeleteTriggerResourceForPubSubSubscription } from './br
|
|
|
6
6
|
export { EventTopicBrokerDeleteTriggerResourceForServiceAccount } from './broker-delete-trigger-resource-service-account.js';
|
|
7
7
|
export { EventTopicBrokerGetTopicIdForPubSub } from './broker-get-topic-id-pubsub.js';
|
|
8
8
|
export { EventTopicBrokerPublishEventsForGoogle } from './broker-publish-events-google.js';
|
|
9
|
+
export { EventTopicBrokerWaitForProcessingForPubSub } from './broker-wait-for-processing-pubsub.js';
|
|
9
10
|
export { EventTopicCreateBackfillSourceForBigQuery } from './create-backfill-source-bigquery.js';
|
|
10
11
|
export { EventTopicQueryEventsForBigQuery } from './query-events-bigquery.js';
|
package/dist/functions/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CausaListConfigurationSchemasForGoogle } from './causa/index.js';
|
|
2
2
|
import { EmulatorStartForFirebaseStorage, EmulatorStartForFirestore, EmulatorStartForIdentityPlatform, EmulatorStartForPubSub, EmulatorStartForSpanner, EmulatorStopForFirebaseStorage, EmulatorStopForFirestore, EmulatorStopForIdentityPlatform, EmulatorStopForPubSub, EmulatorStopForSpanner, } from './emulator/index.js';
|
|
3
|
-
import { EventTopicBrokerCreateTopicForPubSub, EventTopicBrokerCreateTriggerForCloudRun, EventTopicBrokerDeleteTopicForPubSub, EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole, EventTopicBrokerDeleteTriggerResourceForPubSubSubscription, EventTopicBrokerDeleteTriggerResourceForServiceAccount, EventTopicBrokerGetTopicIdForPubSub, EventTopicBrokerPublishEventsForGoogle, EventTopicCreateBackfillSourceForBigQuery, EventTopicQueryEventsForBigQuery, } from './event-topic/index.js';
|
|
3
|
+
import { EventTopicBrokerCreateTopicForPubSub, EventTopicBrokerCreateTriggerForCloudRun, EventTopicBrokerDeleteTopicForPubSub, EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole, EventTopicBrokerDeleteTriggerResourceForPubSubSubscription, EventTopicBrokerDeleteTriggerResourceForServiceAccount, EventTopicBrokerGetTopicIdForPubSub, EventTopicBrokerPublishEventsForGoogle, EventTopicBrokerWaitForProcessingForPubSub, EventTopicCreateBackfillSourceForBigQuery, EventTopicQueryEventsForBigQuery, } from './event-topic/index.js';
|
|
4
4
|
import { GoogleAppCheckGenerateToken } from './google-app-check/index.js';
|
|
5
5
|
import { GoogleFirebaseStorageMergeRules } from './google-firebase-storage/index.js';
|
|
6
6
|
import { DatabaseQueryRecordsForFirestore, GoogleFirestoreMergeRules, ModelGenerateTypeScriptDecoratorsForGoogleFirestore, ModelSchemaExtractDatabaseForGoogleFirestore, } from './google-firestore/index.js';
|
|
@@ -12,5 +12,5 @@ import { ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDesti
|
|
|
12
12
|
import { SecretFetchForGoogleAccessToken, SecretFetchForGoogleSecretManager, } from './secret/index.js';
|
|
13
13
|
import { ServiceContainerQueryLogsForCloudRun } from './service-container/index.js';
|
|
14
14
|
export function registerFunctions(context) {
|
|
15
|
-
context.registerFunctionImplementations(CausaListConfigurationSchemasForGoogle, DatabaseQueryRecordsForFirestore, DatabaseQueryRecordsForSpanner, EmulatorStartForFirebaseStorage, EmulatorStartForFirestore, EmulatorStartForIdentityPlatform, EmulatorStartForPubSub, EmulatorStartForSpanner, EmulatorStopForFirebaseStorage, EmulatorStopForFirestore, EmulatorStopForIdentityPlatform, EmulatorStopForPubSub, EmulatorStopForSpanner, EventTopicBrokerCreateTopicForPubSub, EventTopicBrokerCreateTriggerForCloudRun, EventTopicBrokerDeleteTopicForPubSub, EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole, EventTopicBrokerDeleteTriggerResourceForPubSubSubscription, EventTopicBrokerDeleteTriggerResourceForServiceAccount, EventTopicBrokerGetTopicIdForPubSub, EventTopicBrokerPublishEventsForGoogle, EventTopicCreateBackfillSourceForBigQuery, EventTopicQueryEventsForBigQuery, GoogleAppCheckGenerateToken, GoogleFirebaseStorageMergeRules, GoogleFirestoreMergeRules, GoogleIdentityPlatformGenerateCustomToken, GoogleIdentityPlatformGenerateToken, GooglePubSubWriteTopics, GoogleServicesEnable, GoogleSpannerListDatabases, GoogleSpannerWriteDatabases, ModelGenerateTypeScriptDecoratorsForGoogleFirestore, ModelGenerateTypeScriptDecoratorsForGoogleSpanner, ModelSchemaExtractDatabaseForGoogleFirestore, ModelSchemaExtractDatabaseForGoogleSpanner, ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDestinationForCloudRun, ProjectPushArtefactForCloudFunctions, SecretFetchForGoogleAccessToken, SecretFetchForGoogleSecretManager, ServiceContainerQueryLogsForCloudRun);
|
|
15
|
+
context.registerFunctionImplementations(CausaListConfigurationSchemasForGoogle, DatabaseQueryRecordsForFirestore, DatabaseQueryRecordsForSpanner, EmulatorStartForFirebaseStorage, EmulatorStartForFirestore, EmulatorStartForIdentityPlatform, EmulatorStartForPubSub, EmulatorStartForSpanner, EmulatorStopForFirebaseStorage, EmulatorStopForFirestore, EmulatorStopForIdentityPlatform, EmulatorStopForPubSub, EmulatorStopForSpanner, EventTopicBrokerCreateTopicForPubSub, EventTopicBrokerCreateTriggerForCloudRun, EventTopicBrokerDeleteTopicForPubSub, EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole, EventTopicBrokerDeleteTriggerResourceForPubSubSubscription, EventTopicBrokerDeleteTriggerResourceForServiceAccount, EventTopicBrokerGetTopicIdForPubSub, EventTopicBrokerPublishEventsForGoogle, EventTopicBrokerWaitForProcessingForPubSub, EventTopicCreateBackfillSourceForBigQuery, EventTopicQueryEventsForBigQuery, GoogleAppCheckGenerateToken, GoogleFirebaseStorageMergeRules, GoogleFirestoreMergeRules, GoogleIdentityPlatformGenerateCustomToken, GoogleIdentityPlatformGenerateToken, GooglePubSubWriteTopics, GoogleServicesEnable, GoogleSpannerListDatabases, GoogleSpannerWriteDatabases, ModelGenerateTypeScriptDecoratorsForGoogleFirestore, ModelGenerateTypeScriptDecoratorsForGoogleSpanner, ModelSchemaExtractDatabaseForGoogleFirestore, ModelSchemaExtractDatabaseForGoogleSpanner, ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDestinationForCloudRun, ProjectPushArtefactForCloudFunctions, SecretFetchForGoogleAccessToken, SecretFetchForGoogleSecretManager, ServiceContainerQueryLogsForCloudRun);
|
|
16
16
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { WorkspaceContext } from '@causa/workspace';
|
|
2
|
+
import { MetricServiceClient } from '@google-cloud/monitoring';
|
|
3
|
+
/**
|
|
4
|
+
* A single metric point with its server-side end timestamp (as milliseconds since epoch) and numeric value.
|
|
5
|
+
*/
|
|
6
|
+
export type MetricPoint = {
|
|
7
|
+
/**
|
|
8
|
+
* The end timestamp of the point's interval, as milliseconds since epoch.
|
|
9
|
+
*/
|
|
10
|
+
readonly timestamp: number;
|
|
11
|
+
/**
|
|
12
|
+
* The numeric value of the point.
|
|
13
|
+
*/
|
|
14
|
+
readonly value: number;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* A service exposing a thin wrapper around the Cloud Monitoring API.
|
|
18
|
+
*/
|
|
19
|
+
export declare class CloudMonitoringService {
|
|
20
|
+
/**
|
|
21
|
+
* The underlying Cloud Monitoring client.
|
|
22
|
+
*/
|
|
23
|
+
readonly client: MetricServiceClient;
|
|
24
|
+
/**
|
|
25
|
+
* The ID of the GCP project from which metrics are read.
|
|
26
|
+
*/
|
|
27
|
+
readonly projectId: string;
|
|
28
|
+
constructor(context: WorkspaceContext);
|
|
29
|
+
/**
|
|
30
|
+
* Fetches the data points for a single time series over the given time interval.
|
|
31
|
+
* Returns the points sorted in ascending timestamp order. Each point's timestamp is the end of the corresponding
|
|
32
|
+
* interval, in milliseconds since epoch. An empty array is returned when no series matches the filter.
|
|
33
|
+
*
|
|
34
|
+
* @param filter The Cloud Monitoring metric filter expression (e.g. `metric.type = "..."`).
|
|
35
|
+
* @param start The inclusive lower bound of the interval to fetch.
|
|
36
|
+
* @param end The exclusive upper bound of the interval to fetch.
|
|
37
|
+
* @param options Optional aggregation options.
|
|
38
|
+
* @returns The list of points, ordered by ascending timestamp.
|
|
39
|
+
*/
|
|
40
|
+
listPoints(filter: string, start: Date, end: Date, options?: {
|
|
41
|
+
readonly alignmentPeriod?: number;
|
|
42
|
+
readonly aligner?: 'ALIGN_NONE' | 'ALIGN_DELTA' | 'ALIGN_RATE' | 'ALIGN_MEAN' | 'ALIGN_MAX';
|
|
43
|
+
}): Promise<MetricPoint[]>;
|
|
44
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { WorkspaceContext } from '@causa/workspace';
|
|
2
|
+
import { MetricServiceClient } from '@google-cloud/monitoring';
|
|
3
|
+
/**
|
|
4
|
+
* A service exposing a thin wrapper around the Cloud Monitoring API.
|
|
5
|
+
*/
|
|
6
|
+
export class CloudMonitoringService {
|
|
7
|
+
/**
|
|
8
|
+
* The underlying Cloud Monitoring client.
|
|
9
|
+
*/
|
|
10
|
+
client;
|
|
11
|
+
/**
|
|
12
|
+
* The ID of the GCP project from which metrics are read.
|
|
13
|
+
*/
|
|
14
|
+
projectId;
|
|
15
|
+
constructor(context) {
|
|
16
|
+
this.projectId = context
|
|
17
|
+
.asConfiguration()
|
|
18
|
+
.getOrThrow('google.project');
|
|
19
|
+
this.client = new MetricServiceClient();
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Fetches the data points for a single time series over the given time interval.
|
|
23
|
+
* Returns the points sorted in ascending timestamp order. Each point's timestamp is the end of the corresponding
|
|
24
|
+
* interval, in milliseconds since epoch. An empty array is returned when no series matches the filter.
|
|
25
|
+
*
|
|
26
|
+
* @param filter The Cloud Monitoring metric filter expression (e.g. `metric.type = "..."`).
|
|
27
|
+
* @param start The inclusive lower bound of the interval to fetch.
|
|
28
|
+
* @param end The exclusive upper bound of the interval to fetch.
|
|
29
|
+
* @param options Optional aggregation options.
|
|
30
|
+
* @returns The list of points, ordered by ascending timestamp.
|
|
31
|
+
*/
|
|
32
|
+
async listPoints(filter, start, end, options = {}) {
|
|
33
|
+
const aggregation = options.aligner && options.alignmentPeriod
|
|
34
|
+
? {
|
|
35
|
+
alignmentPeriod: { seconds: options.alignmentPeriod },
|
|
36
|
+
perSeriesAligner: options.aligner,
|
|
37
|
+
}
|
|
38
|
+
: undefined;
|
|
39
|
+
const [series] = await this.client.listTimeSeries({
|
|
40
|
+
name: `projects/${this.projectId}`,
|
|
41
|
+
filter,
|
|
42
|
+
interval: {
|
|
43
|
+
startTime: { seconds: Math.floor(start.getTime() / 1000) },
|
|
44
|
+
endTime: { seconds: Math.floor(end.getTime() / 1000) },
|
|
45
|
+
},
|
|
46
|
+
aggregation,
|
|
47
|
+
});
|
|
48
|
+
return (series.at(0)?.points ?? [])
|
|
49
|
+
.map(({ interval, value: rawValue }) => {
|
|
50
|
+
const endSeconds = Number(interval?.endTime?.seconds ?? 0);
|
|
51
|
+
const endNanos = interval?.endTime?.nanos ?? 0;
|
|
52
|
+
const timestamp = endSeconds * 1000 + Math.floor(endNanos / 1e6);
|
|
53
|
+
const value = Number(rawValue?.int64Value ??
|
|
54
|
+
rawValue?.doubleValue ??
|
|
55
|
+
rawValue?.distributionValue?.count ??
|
|
56
|
+
0);
|
|
57
|
+
return { timestamp, value };
|
|
58
|
+
})
|
|
59
|
+
.sort((a, b) => a.timestamp - b.timestamp);
|
|
60
|
+
}
|
|
61
|
+
}
|
package/dist/services/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { BigQueryService } from './bigquery.js';
|
|
2
|
+
export { CloudMonitoringService, type MetricPoint, } from './cloud-monitoring.js';
|
|
2
3
|
export { CloudRunPubSubTriggerService } from './cloud-run-pubsub-trigger.js';
|
|
3
4
|
export { CloudRunService } from './cloud-run.js';
|
|
4
5
|
export * from './firebase-app.errors.js';
|
|
@@ -9,7 +10,7 @@ export { GcloudEmulatorService } from './gcloud-emulator.js';
|
|
|
9
10
|
export { GoogleApisService } from './google-apis.js';
|
|
10
11
|
export { IamService } from './iam.js';
|
|
11
12
|
export { LoggingService } from './logging.js';
|
|
12
|
-
export { PubSubService } from './pubsub.js';
|
|
13
|
+
export { PUBSUB_SUBSCRIPTION_ID_REGEX, PubSubService, shortSubscriptionId, } from './pubsub.js';
|
|
13
14
|
export { ResourceManagerService } from './resource-manager.js';
|
|
14
15
|
export { GoogleSecretManagerService } from './secret-manager.js';
|
|
15
16
|
export * from './storage.errors.js';
|
package/dist/services/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { BigQueryService } from './bigquery.js';
|
|
2
|
+
export { CloudMonitoringService, } from './cloud-monitoring.js';
|
|
2
3
|
export { CloudRunPubSubTriggerService } from './cloud-run-pubsub-trigger.js';
|
|
3
4
|
export { CloudRunService } from './cloud-run.js';
|
|
4
5
|
export * from './firebase-app.errors.js';
|
|
@@ -8,7 +9,7 @@ export { GcloudEmulatorService } from './gcloud-emulator.js';
|
|
|
8
9
|
export { GoogleApisService } from './google-apis.js';
|
|
9
10
|
export { IamService } from './iam.js';
|
|
10
11
|
export { LoggingService } from './logging.js';
|
|
11
|
-
export { PubSubService } from './pubsub.js';
|
|
12
|
+
export { PUBSUB_SUBSCRIPTION_ID_REGEX, PubSubService, shortSubscriptionId, } from './pubsub.js';
|
|
12
13
|
export { ResourceManagerService } from './resource-manager.js';
|
|
13
14
|
export { GoogleSecretManagerService } from './secret-manager.js';
|
|
14
15
|
export * from './storage.errors.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { WorkspaceContext } from '@causa/workspace';
|
|
2
2
|
import { PubSub } from '@google-cloud/pubsub';
|
|
3
3
|
import { iam_v1 } from 'googleapis';
|
|
4
|
+
export { PUBSUB_SUBSCRIPTION_ID_REGEX, shortSubscriptionId, } from './pubsub.utils.js';
|
|
4
5
|
/**
|
|
5
6
|
* A service for managing Pub/Sub resources
|
|
6
7
|
*/
|
package/dist/services/pubsub.js
CHANGED
|
@@ -2,6 +2,7 @@ import { WorkspaceContext } from '@causa/workspace';
|
|
|
2
2
|
import { PubSub } from '@google-cloud/pubsub';
|
|
3
3
|
import { iam_v1 } from 'googleapis';
|
|
4
4
|
import { ResourceManagerService } from './resource-manager.js';
|
|
5
|
+
export { PUBSUB_SUBSCRIPTION_ID_REGEX, shortSubscriptionId, } from './pubsub.utils.js';
|
|
5
6
|
/**
|
|
6
7
|
* A service for managing Pub/Sub resources
|
|
7
8
|
*/
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The regular expression matching a Pub/Sub subscription resource ID
|
|
3
|
+
* (e.g. `projects/<projectId>/subscriptions/<name>`).
|
|
4
|
+
*/
|
|
5
|
+
export declare const PUBSUB_SUBSCRIPTION_ID_REGEX: RegExp;
|
|
6
|
+
/**
|
|
7
|
+
* Returns the short subscription ID (the last path segment) for a full subscription resource name.
|
|
8
|
+
*/
|
|
9
|
+
export declare function shortSubscriptionId(id: string): string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The regular expression matching a Pub/Sub subscription resource ID
|
|
3
|
+
* (e.g. `projects/<projectId>/subscriptions/<name>`).
|
|
4
|
+
*/
|
|
5
|
+
export const PUBSUB_SUBSCRIPTION_ID_REGEX = /^projects\/[\w-]+\/subscriptions\/[\w-]+$/;
|
|
6
|
+
/**
|
|
7
|
+
* Returns the short subscription ID (the last path segment) for a full subscription resource name.
|
|
8
|
+
*/
|
|
9
|
+
export function shortSubscriptionId(id) {
|
|
10
|
+
return id.split('/').at(-1) ?? id;
|
|
11
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@causa/workspace-google",
|
|
3
|
-
"version": "0.18.0-beta.
|
|
3
|
+
"version": "0.18.0-beta.3",
|
|
4
4
|
"description": "The Causa workspace module providing many functionalities related to GCP and its services.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,12 +37,13 @@
|
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@causa/cli": ">= 0.8.0-beta.1 < 1.0.0",
|
|
39
39
|
"@causa/workspace": ">= 0.25.0-beta.3 < 1.0.0",
|
|
40
|
-
"@causa/workspace-core": ">= 0.35.0-beta.
|
|
41
|
-
"@causa/workspace-typescript": ">= 0.23.0-beta.
|
|
40
|
+
"@causa/workspace-core": ">= 0.35.0-beta.6 < 1.0.0",
|
|
41
|
+
"@causa/workspace-typescript": ">= 0.23.0-beta.4 < 1.0.0",
|
|
42
42
|
"@google-cloud/apikeys": "^2.2.2",
|
|
43
43
|
"@google-cloud/bigquery": "^8.3.1",
|
|
44
44
|
"@google-cloud/iam-credentials": "^4.2.2",
|
|
45
45
|
"@google-cloud/logging": "^11.2.1",
|
|
46
|
+
"@google-cloud/monitoring": "^5.3.2",
|
|
46
47
|
"@google-cloud/pubsub": "^5.3.0",
|
|
47
48
|
"@google-cloud/resource-manager": "^6.2.2",
|
|
48
49
|
"@google-cloud/run": "^3.2.1",
|
|
@@ -61,7 +62,7 @@
|
|
|
61
62
|
"pino": "^10.3.1"
|
|
62
63
|
},
|
|
63
64
|
"devDependencies": {
|
|
64
|
-
"@swc/core": "^1.15.
|
|
65
|
+
"@swc/core": "^1.15.40",
|
|
65
66
|
"@swc/jest": "^0.2.39",
|
|
66
67
|
"@tsconfig/node22": "^22.0.5",
|
|
67
68
|
"@types/jest": "^30.0.0",
|
|
@@ -75,7 +76,7 @@
|
|
|
75
76
|
"jest-extended": "^7.0.0",
|
|
76
77
|
"rimraf": "^6.1.3",
|
|
77
78
|
"typescript": "^6.0.3",
|
|
78
|
-
"typescript-eslint": "^8.
|
|
79
|
+
"typescript-eslint": "^8.60.0",
|
|
79
80
|
"yaml": "^2.9.0"
|
|
80
81
|
}
|
|
81
82
|
}
|