@causa/workspace-google 0.12.2 → 0.13.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/dist/backfilling/bigquery.d.ts +1 -1
  2. package/dist/backfilling/pubsub.d.ts +1 -1
  3. package/dist/backfilling/pubsub.js +1 -1
  4. package/dist/code-generation/google-firestore-renderer.d.ts +1 -1
  5. package/dist/code-generation/google-firestore-renderer.js +7 -8
  6. package/dist/code-generation/google-spanner-renderer.d.ts +1 -1
  7. package/dist/code-generation/google-spanner-renderer.js +5 -6
  8. package/dist/code-generation/utils.d.ts +2 -2
  9. package/dist/code-generation/utils.js +1 -1
  10. package/dist/configurations/generated.d.ts +725 -0
  11. package/dist/configurations/generated.js +1311 -0
  12. package/dist/configurations/index.d.ts +1 -1
  13. package/dist/configurations/index.js +1 -0
  14. package/dist/configurations/schemas/google.yaml +466 -0
  15. package/dist/configurations/schemas/service-container-cloud-run.yaml +197 -0
  16. package/dist/functions/causa/index.d.ts +1 -0
  17. package/dist/functions/causa/index.js +1 -0
  18. package/dist/functions/causa/list-schemas.d.ts +9 -0
  19. package/dist/functions/causa/list-schemas.js +23 -0
  20. package/dist/functions/emulator/start-firebase-storage.js +1 -1
  21. package/dist/functions/emulator/start-firestore.js +1 -1
  22. package/dist/functions/emulator/start-identity-platform.js +1 -1
  23. package/dist/functions/emulator/start-pubsub.call.d.ts +4 -0
  24. package/dist/functions/emulator/start-pubsub.call.js +57 -0
  25. package/dist/functions/emulator/start-pubsub.d.ts +0 -22
  26. package/dist/functions/emulator/start-pubsub.js +4 -75
  27. package/dist/functions/emulator/start-spanner.call.d.ts +4 -0
  28. package/dist/functions/emulator/start-spanner.call.js +92 -0
  29. package/dist/functions/emulator/start-spanner.d.ts +0 -38
  30. package/dist/functions/emulator/start-spanner.js +4 -124
  31. package/dist/functions/emulator/stop-firebase-storage.js +2 -1
  32. package/dist/functions/emulator/stop-firestore.js +2 -1
  33. package/dist/functions/emulator/stop-identity-platform.js +2 -1
  34. package/dist/functions/emulator/stop-pubsub.js +2 -1
  35. package/dist/functions/emulator/stop-spanner.js +2 -1
  36. package/dist/functions/event-topic/broker-create-topic-pubsub.call.d.ts +3 -0
  37. package/dist/functions/event-topic/broker-create-topic-pubsub.call.js +15 -0
  38. package/dist/functions/event-topic/broker-create-topic-pubsub.js +2 -14
  39. package/dist/functions/event-topic/broker-create-trigger-cloud-run.call.d.ts +3 -0
  40. package/dist/functions/event-topic/broker-create-trigger-cloud-run.call.js +24 -0
  41. package/dist/functions/event-topic/broker-create-trigger-cloud-run.js +2 -19
  42. package/dist/functions/event-topic/broker-delete-topic-pubsub.call.d.ts +3 -0
  43. package/dist/functions/event-topic/broker-delete-topic-pubsub.call.js +15 -0
  44. package/dist/functions/event-topic/broker-delete-topic-pubsub.js +2 -14
  45. package/dist/functions/event-topic/broker-delete-trigger-resource-cloud-run-invoker-role.call.d.ts +3 -0
  46. package/dist/functions/event-topic/broker-delete-trigger-resource-cloud-run-invoker-role.call.js +16 -0
  47. package/dist/functions/event-topic/broker-delete-trigger-resource-cloud-run-invoker-role.js +2 -11
  48. package/dist/functions/event-topic/broker-delete-trigger-resource-pubsub-subscription.call.d.ts +3 -0
  49. package/dist/functions/event-topic/broker-delete-trigger-resource-pubsub-subscription.call.js +16 -0
  50. package/dist/functions/event-topic/broker-delete-trigger-resource-pubsub-subscription.js +2 -18
  51. package/dist/functions/event-topic/broker-delete-trigger-resource-service-account.call.d.ts +3 -0
  52. package/dist/functions/event-topic/broker-delete-trigger-resource-service-account.call.js +15 -0
  53. package/dist/functions/event-topic/broker-delete-trigger-resource-service-account.js +2 -14
  54. package/dist/functions/event-topic/broker-publish-events-google.call.d.ts +3 -0
  55. package/dist/functions/event-topic/broker-publish-events-google.call.js +29 -0
  56. package/dist/functions/event-topic/broker-publish-events-google.d.ts +0 -7
  57. package/dist/functions/event-topic/broker-publish-events-google.js +3 -34
  58. package/dist/functions/google-app-check/generate-token.call.d.ts +3 -0
  59. package/dist/functions/google-app-check/generate-token.call.js +17 -0
  60. package/dist/functions/google-app-check/generate-token.js +2 -16
  61. package/dist/functions/google-identity-platform/generate-custom-token.call.d.ts +3 -0
  62. package/dist/functions/google-identity-platform/generate-custom-token.call.js +8 -0
  63. package/dist/functions/google-identity-platform/generate-custom-token.js +2 -7
  64. package/dist/functions/google-identity-platform/generate-token.call.d.ts +3 -0
  65. package/dist/functions/google-identity-platform/generate-token.call.js +13 -0
  66. package/dist/functions/google-identity-platform/generate-token.js +2 -12
  67. package/dist/functions/google-services/enable.call.d.ts +7 -0
  68. package/dist/functions/google-services/enable.call.js +35 -0
  69. package/dist/functions/google-services/enable.js +2 -34
  70. package/dist/functions/index.js +2 -1
  71. package/dist/functions/project/push-artefact-cloud-functions.call.d.ts +3 -0
  72. package/dist/functions/project/push-artefact-cloud-functions.call.js +19 -0
  73. package/dist/functions/project/push-artefact-cloud-functions.js +3 -18
  74. package/dist/functions/secret/fetch-access-token.call.d.ts +3 -0
  75. package/dist/functions/secret/fetch-access-token.call.js +10 -0
  76. package/dist/functions/secret/fetch-access-token.js +2 -8
  77. package/dist/functions/secret/fetch-secret-manager.call.d.ts +3 -0
  78. package/dist/functions/secret/fetch-secret-manager.call.js +32 -0
  79. package/dist/functions/secret/fetch-secret-manager.js +2 -29
  80. package/dist/functions/typescript/get-decorator-renderer-google-firestore.d.ts +3 -3
  81. package/dist/functions/typescript/get-decorator-renderer-google-firestore.js +4 -4
  82. package/dist/functions/typescript/get-decorator-renderer-google-spanner.d.ts +3 -3
  83. package/dist/functions/typescript/get-decorator-renderer-google-spanner.js +4 -4
  84. package/dist/index.d.ts +1 -2
  85. package/dist/index.js +1 -2
  86. package/dist/services/firebase-emulator.d.ts +1 -1
  87. package/dist/services/firebase-emulator.js +1 -1
  88. package/dist/services/gcloud-emulator.d.ts +1 -1
  89. package/dist/services/gcloud-emulator.js +1 -1
  90. package/package.json +14 -11
  91. package/dist/configurations/google.d.ts +0 -305
  92. package/dist/configurations/google.js +0 -1
@@ -1,6 +1,5 @@
1
- import { WorkspaceContext } from '@causa/workspace';
1
+ import { callDeferred, WorkspaceContext } from '@causa/workspace';
2
2
  import { EventTopicBrokerCreateTrigger, } from '@causa/workspace-core';
3
- import { CloudRunPubSubTriggerService } from '../../services/index.js';
4
3
  /**
5
4
  * The regular expression used to match Cloud Run trigger IDs, consisting of the service ID and the path to the trigger.
6
5
  * [[projects/<projectId>/]locations/<location>/]services/<name>/path-to-trigger
@@ -13,23 +12,7 @@ const CLOUD_RUN_TRIGGER_ID_REGEX = /^(?:(?:projects\/(?<projectId>[\w-]+)\/)?loc
13
12
  */
14
13
  export class EventTopicBrokerCreateTriggerForCloudRun extends EventTopicBrokerCreateTrigger {
15
14
  async _call(context) {
16
- const match = this.trigger.match(CLOUD_RUN_TRIGGER_ID_REGEX);
17
- if (!match?.groups) {
18
- throw new Error('Oops.');
19
- }
20
- const googleConf = context.asConfiguration();
21
- const projectId = match.groups.projectId ?? googleConf.getOrThrow('google.project');
22
- const location = match.groups.location ??
23
- googleConf.getOrThrow('google.cloudRun.location');
24
- const name = match.groups.name;
25
- const path = match.groups.path;
26
- if (!name || !path) {
27
- throw new Error('Oops.');
28
- }
29
- const serviceId = `projects/${projectId}/locations/${location}/services/${name}`;
30
- return await context
31
- .service(CloudRunPubSubTriggerService)
32
- .create(this.backfillId, this.topicId, serviceId, path);
15
+ return await callDeferred(this, context, import.meta.url);
33
16
  }
34
17
  _supports(context) {
35
18
  return (this.trigger.match(CLOUD_RUN_TRIGGER_ID_REGEX) != null &&
@@ -0,0 +1,3 @@
1
+ import type { WorkspaceContext } from '@causa/workspace';
2
+ import type { EventTopicBrokerDeleteTopicForPubSub } from './broker-delete-topic-pubsub.js';
3
+ export default function call(this: EventTopicBrokerDeleteTopicForPubSub, context: WorkspaceContext): Promise<void>;
@@ -0,0 +1,15 @@
1
+ import { grpc } from 'google-gax';
2
+ import { PubSubService } from '../../services/pubsub.js';
3
+ export default async function call(context) {
4
+ context.logger.info(`📫 Deleting Pub/Sub topic '${this.id}'.`);
5
+ try {
6
+ await context.service(PubSubService).pubSub.topic(this.id).delete();
7
+ }
8
+ catch (error) {
9
+ if (error.code === grpc.status.NOT_FOUND) {
10
+ context.logger.warn(`⚠️ Pub/Sub topic to delete '${this.id}' does not exist. It might have already been deleted.`);
11
+ return;
12
+ }
13
+ throw error;
14
+ }
15
+ }
@@ -1,24 +1,12 @@
1
- import { WorkspaceContext } from '@causa/workspace';
1
+ import { callDeferred, WorkspaceContext } from '@causa/workspace';
2
2
  import { EventTopicBrokerDeleteTopic, } from '@causa/workspace-core';
3
- import { grpc } from 'google-gax';
4
- import { PubSubService } from '../../services/index.js';
5
3
  /**
6
4
  * Implements {@link EventTopicBrokerDeleteTopic} for Pub/Sub.
7
5
  * The `id` argument should be a full Pub/Sub topic ID, e.g. `projects/<projectId>/topics/<topicId>`.
8
6
  */
9
7
  export class EventTopicBrokerDeleteTopicForPubSub extends EventTopicBrokerDeleteTopic {
10
8
  async _call(context) {
11
- context.logger.info(`📫 Deleting Pub/Sub topic '${this.id}'.`);
12
- try {
13
- await context.service(PubSubService).pubSub.topic(this.id).delete();
14
- }
15
- catch (error) {
16
- if (error.code === grpc.status.NOT_FOUND) {
17
- context.logger.warn(`⚠️ Pub/Sub topic to delete '${this.id}' does not exist. It might have already been deleted.`);
18
- return;
19
- }
20
- throw error;
21
- }
9
+ return await callDeferred(this, context, import.meta.url);
22
10
  }
23
11
  _supports(context) {
24
12
  return (context.asConfiguration().get('events.broker') ===
@@ -0,0 +1,3 @@
1
+ import type { WorkspaceContext } from '@causa/workspace';
2
+ import type { EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole } from './broker-delete-trigger-resource-cloud-run-invoker-role.js';
3
+ export default function call(this: EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole, context: WorkspaceContext): Promise<void>;
@@ -0,0 +1,16 @@
1
+ import { CloudRunService } from '../../services/cloud-run.js';
2
+ /**
3
+ * The regular expression that matches a resource ID representing a Cloud Run invoker role for a given service account.
4
+ */
5
+ const CLOUD_RUN_INVOKER_ID_REGEX = /^(?<serviceId>projects\/[\w-]+\/locations\/[\w-]+\/services\/[\w-]+)\/invokerBindings\/(?<pubSubServiceAccount>.+)$/;
6
+ export default async function call(context) {
7
+ const match = this.id.match(CLOUD_RUN_INVOKER_ID_REGEX);
8
+ if (!match?.groups) {
9
+ throw new Error('Invalid Cloud Run invoker binding resource ID.');
10
+ }
11
+ const { serviceId, pubSubServiceAccount } = match.groups;
12
+ context.logger.info(`🛂 Removing invoker role on Cloud Run service '${serviceId}' for Pub/Sub service account '${pubSubServiceAccount}'.`);
13
+ await context
14
+ .service(CloudRunService)
15
+ .removeInvokerBinding(serviceId, pubSubServiceAccount);
16
+ }
@@ -1,6 +1,5 @@
1
- import { WorkspaceContext } from '@causa/workspace';
1
+ import { callDeferred, WorkspaceContext } from '@causa/workspace';
2
2
  import { EventTopicBrokerDeleteTriggerResource, } from '@causa/workspace-core';
3
- import { CloudRunService } from '../../services/index.js';
4
3
  /**
5
4
  * The regular expression that matches a resource ID representing a Cloud Run invoker role for a given service account.
6
5
  */
@@ -12,15 +11,7 @@ const CLOUD_RUN_INVOKER_ID_REGEX = /^(?<serviceId>projects\/[\w-]+\/locations\/[
12
11
  */
13
12
  export class EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole extends EventTopicBrokerDeleteTriggerResource {
14
13
  async _call(context) {
15
- const match = this.id.match(CLOUD_RUN_INVOKER_ID_REGEX);
16
- if (!match?.groups) {
17
- throw new Error('Invalid Cloud Run invoker binding resource ID.');
18
- }
19
- const { serviceId, pubSubServiceAccount } = match.groups;
20
- context.logger.info(`🛂 Removing invoker role on Cloud Run service '${serviceId}' for Pub/Sub service account '${pubSubServiceAccount}'.`);
21
- await context
22
- .service(CloudRunService)
23
- .removeInvokerBinding(serviceId, pubSubServiceAccount);
14
+ return await callDeferred(this, context, import.meta.url);
24
15
  }
25
16
  _supports(context) {
26
17
  return (this.id.match(CLOUD_RUN_INVOKER_ID_REGEX) != null &&
@@ -0,0 +1,3 @@
1
+ import type { WorkspaceContext } from '@causa/workspace';
2
+ import type { EventTopicBrokerDeleteTriggerResourceForPubSubSubscription } from './broker-delete-trigger-resource-pubsub-subscription.js';
3
+ export default function call(this: EventTopicBrokerDeleteTriggerResourceForPubSubSubscription, context: WorkspaceContext): Promise<void>;
@@ -0,0 +1,16 @@
1
+ import { grpc } from 'google-gax';
2
+ import { PubSubService } from '../../services/pubsub.js';
3
+ export default async function call(context) {
4
+ context.logger.info(`📫 Deleting Pub/Sub subscription '${this.id}'.`);
5
+ try {
6
+ await context.service(PubSubService).pubSub.subscription(this.id).delete();
7
+ }
8
+ catch (error) {
9
+ if (error.code === grpc.status.NOT_FOUND) {
10
+ context.logger.warn(`⚠️ Pub/Sub subscription '${this.id}' does not exist. It might have already been deleted.`);
11
+ }
12
+ else {
13
+ throw error;
14
+ }
15
+ }
16
+ }
@@ -1,28 +1,12 @@
1
- import { WorkspaceContext } from '@causa/workspace';
1
+ import { callDeferred, WorkspaceContext } from '@causa/workspace';
2
2
  import { EventTopicBrokerDeleteTriggerResource, } from '@causa/workspace-core';
3
- import { grpc } from 'google-gax';
4
- import { PubSubService } from '../../services/index.js';
5
3
  /**
6
4
  * Implements {@link EventTopicBrokerDeleteTriggerResource} for Pub/Sub subscriptions.
7
5
  * Pub/Sub subscriptions are for example used when creating Cloud Run triggers.
8
6
  */
9
7
  export class EventTopicBrokerDeleteTriggerResourceForPubSubSubscription extends EventTopicBrokerDeleteTriggerResource {
10
8
  async _call(context) {
11
- context.logger.info(`📫 Deleting Pub/Sub subscription '${this.id}'.`);
12
- try {
13
- await context
14
- .service(PubSubService)
15
- .pubSub.subscription(this.id)
16
- .delete();
17
- }
18
- catch (error) {
19
- if (error.code === grpc.status.NOT_FOUND) {
20
- context.logger.warn(`⚠️ Pub/Sub subscription '${this.id}' does not exist. It might have already been deleted.`);
21
- }
22
- else {
23
- throw error;
24
- }
25
- }
9
+ return await callDeferred(this, context, import.meta.url);
26
10
  }
27
11
  _supports(context) {
28
12
  return (this.id.match(/^projects\/[\w-]+\/subscriptions\/[\w-]+$/) != null &&
@@ -0,0 +1,3 @@
1
+ import type { WorkspaceContext } from '@causa/workspace';
2
+ import type { EventTopicBrokerDeleteTriggerResourceForServiceAccount } from './broker-delete-trigger-resource-service-account.js';
3
+ export default function call(this: EventTopicBrokerDeleteTriggerResourceForServiceAccount, context: WorkspaceContext): Promise<void>;
@@ -0,0 +1,15 @@
1
+ import { IamService } from '../../services/iam.js';
2
+ export default async function call(context) {
3
+ context.logger.info(`🛂 Deleting Pub/Sub backfilling service account '${this.id}'.`);
4
+ try {
5
+ await context.service(IamService).deleteServiceAccount(this.id);
6
+ }
7
+ catch (error) {
8
+ if (error.code === 404) {
9
+ context.logger.warn(`⚠️ Pub/Sub backfilling service account '${this.id}' does not exist. It might have already been deleted.`);
10
+ }
11
+ else {
12
+ throw error;
13
+ }
14
+ }
15
+ }
@@ -1,6 +1,5 @@
1
- import { WorkspaceContext } from '@causa/workspace';
1
+ import { callDeferred, WorkspaceContext } from '@causa/workspace';
2
2
  import { EventTopicBrokerDeleteTriggerResource, } from '@causa/workspace-core';
3
- import { IamService } from '../../services/index.js';
4
3
  /**
5
4
  * Implements {@link EventTopicBrokerDeleteTriggerResource} for GCP service accounts.
6
5
  * Service accounts are used by Pub/Sub push subscriptions to authenticate requests when pushing messages (e.g. to Cloud
@@ -8,18 +7,7 @@ import { IamService } from '../../services/index.js';
8
7
  */
9
8
  export class EventTopicBrokerDeleteTriggerResourceForServiceAccount extends EventTopicBrokerDeleteTriggerResource {
10
9
  async _call(context) {
11
- context.logger.info(`🛂 Deleting Pub/Sub backfilling service account '${this.id}'.`);
12
- try {
13
- await context.service(IamService).deleteServiceAccount(this.id);
14
- }
15
- catch (error) {
16
- if (error.code === 404) {
17
- context.logger.warn(`⚠️ Pub/Sub backfilling service account '${this.id}' does not exist. It might have already been deleted.`);
18
- }
19
- else {
20
- throw error;
21
- }
22
- }
10
+ return await callDeferred(this, context, import.meta.url);
23
11
  }
24
12
  _supports(context) {
25
13
  return (this.id.match(/^projects\/[\w-]+\/serviceAccounts\/[^/]+$/) != null &&
@@ -0,0 +1,3 @@
1
+ import type { WorkspaceContext } from '@causa/workspace';
2
+ import type { EventTopicBrokerPublishEventsForGoogle } from './broker-publish-events-google.js';
3
+ export default function call(this: EventTopicBrokerPublishEventsForGoogle, context: WorkspaceContext): Promise<void>;
@@ -0,0 +1,29 @@
1
+ import { JsonFilesEventSource, } from '@causa/workspace-core/backfill';
2
+ import { BigQueryEventsSource, PubSubBackfillEventPublisher, } from '../../backfilling/index.js';
3
+ async function createSource(self, context) {
4
+ if (!self.source) {
5
+ const googleConf = context.asConfiguration();
6
+ const projectId = googleConf.getOrThrow('google.project');
7
+ const rawEventsDatasetId = googleConf.get('google.pubSub.bigQueryStorage.rawEventsDatasetId');
8
+ if (!rawEventsDatasetId) {
9
+ throw new Error('Cannot use the default event source because BigQuery storage is not configured.');
10
+ }
11
+ const tableName = self.eventTopic.replace(/[-\.]/g, '_');
12
+ const tableId = `${projectId}.${rawEventsDatasetId}.${tableName}`;
13
+ return new BigQueryEventsSource(context, tableId);
14
+ }
15
+ const bqSource = await BigQueryEventsSource.fromSourceAndFilter(context, self.source, self.filter);
16
+ if (bqSource) {
17
+ return bqSource;
18
+ }
19
+ const jsonFilesSource = await JsonFilesEventSource.fromSourceAndFilter(context, self.source, self.filter);
20
+ if (jsonFilesSource) {
21
+ return jsonFilesSource;
22
+ }
23
+ throw new Error(`The event source '${self.source}' is not supported.`);
24
+ }
25
+ export default async function call(context) {
26
+ const source = await createSource(this, context);
27
+ const publisher = new PubSubBackfillEventPublisher(context, this.topicId);
28
+ await publisher.publishFromSource(source);
29
+ }
@@ -5,13 +5,6 @@ import { EventTopicBrokerPublishEvents } from '@causa/workspace-core';
5
5
  * The supported message broker is Pub/Sub.
6
6
  */
7
7
  export declare class EventTopicBrokerPublishEventsForGoogle extends EventTopicBrokerPublishEvents {
8
- /**
9
- * Tries to create a {@link BackfillEventsSource} from the provided `source` and `filter`.
10
- *
11
- * @param context The {@link WorkspaceContext}.
12
- * @returns The {@link BackfillEventsSource} to use for backfilling.
13
- */
14
- private createSource;
15
8
  _call(context: WorkspaceContext): Promise<void>;
16
9
  _supports(context: WorkspaceContext): boolean;
17
10
  }
@@ -1,43 +1,12 @@
1
- import { WorkspaceContext } from '@causa/workspace';
2
- import { EventTopicBrokerPublishEvents, JsonFilesEventSource, } from '@causa/workspace-core';
3
- import { BigQueryEventsSource, PubSubBackfillEventPublisher, } from '../../backfilling/index.js';
1
+ import { callDeferred, WorkspaceContext } from '@causa/workspace';
2
+ import { EventTopicBrokerPublishEvents, } from '@causa/workspace-core';
4
3
  /**
5
4
  * Implements {@link EventTopicBrokerPublishEvents} for a Google / GCP stack.
6
5
  * The supported message broker is Pub/Sub.
7
6
  */
8
7
  export class EventTopicBrokerPublishEventsForGoogle extends EventTopicBrokerPublishEvents {
9
- /**
10
- * Tries to create a {@link BackfillEventsSource} from the provided `source` and `filter`.
11
- *
12
- * @param context The {@link WorkspaceContext}.
13
- * @returns The {@link BackfillEventsSource} to use for backfilling.
14
- */
15
- async createSource(context) {
16
- if (!this.source) {
17
- const googleConf = context.asConfiguration();
18
- const projectId = googleConf.getOrThrow('google.project');
19
- const rawEventsDatasetId = googleConf.get('google.pubSub.bigQueryStorage.rawEventsDatasetId');
20
- if (!rawEventsDatasetId) {
21
- throw new Error('Cannot use the default event source because BigQuery storage is not configured.');
22
- }
23
- const tableName = this.eventTopic.replace(/[-\.]/g, '_');
24
- const tableId = `${projectId}.${rawEventsDatasetId}.${tableName}`;
25
- return new BigQueryEventsSource(context, tableId);
26
- }
27
- const bqSource = await BigQueryEventsSource.fromSourceAndFilter(context, this.source, this.filter);
28
- if (bqSource) {
29
- return bqSource;
30
- }
31
- const jsonFilesSource = await JsonFilesEventSource.fromSourceAndFilter(context, this.source, this.filter);
32
- if (jsonFilesSource) {
33
- return jsonFilesSource;
34
- }
35
- throw new Error(`The event source '${this.source}' is not supported.`);
36
- }
37
8
  async _call(context) {
38
- const source = await this.createSource(context);
39
- const publisher = new PubSubBackfillEventPublisher(context, this.topicId);
40
- await publisher.publishFromSource(source);
9
+ return await callDeferred(this, context, import.meta.url);
41
10
  }
42
11
  _supports(context) {
43
12
  return (context.asConfiguration().get('events.broker') ===
@@ -0,0 +1,3 @@
1
+ import type { WorkspaceContext } from '@causa/workspace';
2
+ import type { GoogleAppCheckGenerateToken } from './generate-token.js';
3
+ export default function call(this: GoogleAppCheckGenerateToken, context: WorkspaceContext): Promise<string>;
@@ -0,0 +1,17 @@
1
+ import { getAppCheck } from 'firebase-admin/app-check';
2
+ import { FirebaseAppService } from '../../services/firebase-app.js';
3
+ /**
4
+ * The time to live of generated tokens, in seconds.
5
+ */
6
+ const TOKEN_TTL = 3600;
7
+ export default async function call(context) {
8
+ const firebaseAppService = context.service(FirebaseAppService);
9
+ const app = await firebaseAppService.getAdminAppForAdminServiceAccount();
10
+ const appId = this.app ?? (await firebaseAppService.getAppId());
11
+ context.logger.info(`🛂 Generating AppCheck token for Firebase application '${appId}'.`);
12
+ const appCheck = getAppCheck(app);
13
+ const { token } = await appCheck.createToken(appId, {
14
+ ttlMillis: TOKEN_TTL * 1000,
15
+ });
16
+ return token;
17
+ }
@@ -8,16 +8,10 @@ var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
10
  import { CliCommand, CliOption } from '@causa/cli';
11
- import { WorkspaceContext, WorkspaceFunction } from '@causa/workspace';
11
+ import { callDeferred, WorkspaceContext, WorkspaceFunction, } from '@causa/workspace';
12
12
  import { AllowMissing } from '@causa/workspace/validation';
13
13
  import { IsString } from 'class-validator';
14
- import { getAppCheck } from 'firebase-admin/app-check';
15
14
  import { appCheckCommandDefinition } from '../../cli/index.js';
16
- import { FirebaseAppService } from '../../services/index.js';
17
- /**
18
- * The time to live of generated tokens, in seconds.
19
- */
20
- const TOKEN_TTL = 3600;
21
15
  /**
22
16
  * Generates a new AppCheck token.
23
17
  */
@@ -28,15 +22,7 @@ let GoogleAppCheckGenerateToken = class GoogleAppCheckGenerateToken extends Work
28
22
  */
29
23
  app;
30
24
  async _call(context) {
31
- const firebaseAppService = context.service(FirebaseAppService);
32
- const app = await firebaseAppService.getAdminAppForAdminServiceAccount();
33
- const appId = this.app ?? (await firebaseAppService.getAppId());
34
- context.logger.info(`🛂 Generating AppCheck token for Firebase application '${appId}'.`);
35
- const appCheck = getAppCheck(app);
36
- const { token } = await appCheck.createToken(appId, {
37
- ttlMillis: TOKEN_TTL * 1000,
38
- });
39
- return token;
25
+ return await callDeferred(this, context, import.meta.url);
40
26
  }
41
27
  _supports() {
42
28
  return true;
@@ -0,0 +1,3 @@
1
+ import type { WorkspaceContext } from '@causa/workspace';
2
+ import type { GoogleIdentityPlatformGenerateCustomToken } from './generate-custom-token.js';
3
+ export default function call(this: GoogleIdentityPlatformGenerateCustomToken, context: WorkspaceContext): Promise<string>;
@@ -0,0 +1,8 @@
1
+ import { getAuth } from 'firebase-admin/auth';
2
+ import { FirebaseAppService } from '../../services/firebase-app.js';
3
+ export default async function call(context) {
4
+ const adminApp = await context
5
+ .service(FirebaseAppService)
6
+ .getAdminAppForAdminServiceAccount();
7
+ return await getAuth(adminApp).createCustomToken(this.user, this.claims);
8
+ }
@@ -7,11 +7,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
- import { WorkspaceContext, WorkspaceFunction } from '@causa/workspace';
10
+ import { callDeferred, WorkspaceContext, WorkspaceFunction, } from '@causa/workspace';
11
11
  import { AllowMissing } from '@causa/workspace/validation';
12
12
  import { IsObject, IsString } from 'class-validator';
13
- import { getAuth } from 'firebase-admin/auth';
14
- import { FirebaseAppService } from '../../services/index.js';
15
13
  /**
16
14
  * Generates a custom token that can be used to sign in to Identity Platform as a given user.
17
15
  * Optionally, custom claims can be set in the token.
@@ -29,10 +27,7 @@ export class GoogleIdentityPlatformGenerateCustomToken extends WorkspaceFunction
29
27
  */
30
28
  claims;
31
29
  async _call(context) {
32
- const adminApp = await context
33
- .service(FirebaseAppService)
34
- .getAdminAppForAdminServiceAccount();
35
- return await getAuth(adminApp).createCustomToken(this.user, this.claims);
30
+ return await callDeferred(this, context, import.meta.url);
36
31
  }
37
32
  _supports() {
38
33
  return true;
@@ -0,0 +1,3 @@
1
+ import type { WorkspaceContext } from '@causa/workspace';
2
+ import type { GoogleIdentityPlatformGenerateToken } from './generate-token.js';
3
+ export default function call(this: GoogleIdentityPlatformGenerateToken, context: WorkspaceContext): Promise<string>;
@@ -0,0 +1,13 @@
1
+ import { getAuth, signInWithCustomToken } from 'firebase/auth';
2
+ import { FirebaseAppService } from '../../services/firebase-app.js';
3
+ import { GoogleIdentityPlatformGenerateCustomToken } from './generate-custom-token.js';
4
+ export default async function call(context) {
5
+ context.logger.info(`🛂 Signing in user '${this.user}' with a custom token.`);
6
+ const customToken = await context.call(GoogleIdentityPlatformGenerateCustomToken, { user: this.user, claims: this.claims });
7
+ const app = await context.service(FirebaseAppService).getApp();
8
+ const auth = getAuth(app);
9
+ const credentials = await signInWithCustomToken(auth, customToken);
10
+ return this.refreshToken
11
+ ? credentials.user.refreshToken
12
+ : await credentials.user.getIdToken();
13
+ }
@@ -8,14 +8,11 @@ var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
10
  import { CliArgument, CliCommand, CliOption } from '@causa/cli';
11
- import { WorkspaceContext, WorkspaceFunction } from '@causa/workspace';
11
+ import { callDeferred, WorkspaceContext, WorkspaceFunction, } from '@causa/workspace';
12
12
  import { AllowMissing } from '@causa/workspace/validation';
13
13
  import { Transform } from 'class-transformer';
14
14
  import { IsBoolean, IsObject, IsString } from 'class-validator';
15
- import { getAuth, signInWithCustomToken } from 'firebase/auth';
16
15
  import { identityPlatformCommandDefinition } from '../../cli/index.js';
17
- import { FirebaseAppService } from '../../services/index.js';
18
- import { GoogleIdentityPlatformGenerateCustomToken } from './generate-custom-token.js';
19
16
  /**
20
17
  * Generates an ID token for an Identity Platform end user.
21
18
  * For this function to succeed, the `google.project` should be set, which usually means setting the environment in the
@@ -35,14 +32,7 @@ let GoogleIdentityPlatformGenerateToken = class GoogleIdentityPlatformGenerateTo
35
32
  */
36
33
  refreshToken;
37
34
  async _call(context) {
38
- context.logger.info(`🛂 Signing in user '${this.user}' with a custom token.`);
39
- const customToken = await context.call(GoogleIdentityPlatformGenerateCustomToken, { user: this.user, claims: this.claims });
40
- const app = await context.service(FirebaseAppService).getApp();
41
- const auth = getAuth(app);
42
- const credentials = await signInWithCustomToken(auth, customToken);
43
- return this.refreshToken
44
- ? credentials.user.refreshToken
45
- : await credentials.user.getIdToken();
35
+ return await callDeferred(this, context, import.meta.url);
46
36
  }
47
37
  _supports() {
48
38
  return true;
@@ -0,0 +1,7 @@
1
+ import type { WorkspaceContext } from '@causa/workspace';
2
+ import type { GoogleConfiguration } from '../../configurations/index.js';
3
+ import type { GoogleServicesEnable } from './enable.js';
4
+ export default function call(this: GoogleServicesEnable, context: WorkspaceContext): Promise<{
5
+ configuration: GoogleConfiguration;
6
+ services: string[];
7
+ }>;
@@ -0,0 +1,35 @@
1
+ import { ServiceUsageClient } from '@google-cloud/service-usage';
2
+ /**
3
+ * The maximum number of GCP services that can be enabled at the same time.
4
+ */
5
+ const MAX_SERVICE_BATCH = 20;
6
+ export default async function call(context) {
7
+ if (this.tearDown) {
8
+ return { configuration: {}, services: [] };
9
+ }
10
+ const googleConf = context.asConfiguration();
11
+ const gcpProject = googleConf.getOrThrow('google.project');
12
+ const services = googleConf.get('google.services');
13
+ if (!services) {
14
+ // Although not very useful, this ensures the services configuration is set after the processor has run.
15
+ return { configuration: { google: { services: [] } }, services: [] };
16
+ }
17
+ // There is little chance the client would be reused, so it is not cached or exposed as a service.
18
+ const serviceUsageClient = new ServiceUsageClient();
19
+ const servicesToEnable = [...services];
20
+ const parent = `projects/${gcpProject}`;
21
+ while (servicesToEnable.length > 0) {
22
+ const serviceIds = servicesToEnable.splice(0, MAX_SERVICE_BATCH);
23
+ context.logger.info(`➕ Enabling GCP service(s) ${serviceIds
24
+ .map((s) => `'${s}'`)
25
+ .join(', ')} in project '${gcpProject}'.`);
26
+ const [operation] = await serviceUsageClient.batchEnableServices({
27
+ parent,
28
+ serviceIds,
29
+ });
30
+ await operation.promise();
31
+ }
32
+ // If `google.services` was already set, returning it would duplicate the list due to the configuration merging
33
+ // strategy (concatenating arrays).
34
+ return { configuration: {}, services };
35
+ }
@@ -8,49 +8,17 @@ var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
10
  import { CliCommand } from '@causa/cli';
11
- import { WorkspaceContext, WorkspaceFunction } from '@causa/workspace';
11
+ import { callDeferred, WorkspaceContext, WorkspaceFunction, } from '@causa/workspace';
12
12
  import { AllowMissing } from '@causa/workspace/validation';
13
- import { ServiceUsageClient } from '@google-cloud/service-usage';
14
13
  import { IsBoolean } from 'class-validator';
15
14
  import { googleCommandDefinition } from '../../cli/index.js';
16
- /**
17
- * The maximum number of GCP services that can be enabled at the same time.
18
- */
19
- const MAX_SERVICE_BATCH = 20;
20
15
  /**
21
16
  * Enables GCP services defined in `google.services` for the GCP project defined in `google.project`.
22
17
  */
23
18
  let GoogleServicesEnable = class GoogleServicesEnable extends WorkspaceFunction {
24
19
  tearDown;
25
20
  async _call(context) {
26
- if (this.tearDown) {
27
- return { configuration: {}, services: [] };
28
- }
29
- const googleConf = context.asConfiguration();
30
- const gcpProject = googleConf.getOrThrow('google.project');
31
- const services = googleConf.get('google.services');
32
- if (!services) {
33
- // Although not very useful, this ensures the services configuration is set after the processor has run.
34
- return { configuration: { google: { services: [] } }, services: [] };
35
- }
36
- // There is little chance the client would be reused, so it is not cached or exposed as a service.
37
- const serviceUsageClient = new ServiceUsageClient();
38
- const servicesToEnable = [...services];
39
- const parent = `projects/${gcpProject}`;
40
- while (servicesToEnable.length > 0) {
41
- const serviceIds = servicesToEnable.splice(0, MAX_SERVICE_BATCH);
42
- context.logger.info(`➕ Enabling GCP service(s) ${serviceIds
43
- .map((s) => `'${s}'`)
44
- .join(', ')} in project '${gcpProject}'.`);
45
- const [operation] = await serviceUsageClient.batchEnableServices({
46
- parent,
47
- serviceIds,
48
- });
49
- await operation.promise();
50
- }
51
- // If `google.services` was already set, returning it would duplicate the list due to the configuration merging
52
- // strategy (concatenating arrays).
53
- return { configuration: {}, services };
21
+ return await callDeferred(this, context, import.meta.url);
54
22
  }
55
23
  _supports() {
56
24
  return true;
@@ -1,3 +1,4 @@
1
+ import { CausaListConfigurationSchemasForGoogle } from './causa/index.js';
1
2
  import { EmulatorStartForFirebaseStorage, EmulatorStartForFirestore, EmulatorStartForIdentityPlatform, EmulatorStartForPubSub, EmulatorStartForSpanner, EmulatorStopForFirebaseStorage, EmulatorStopForFirestore, EmulatorStopForIdentityPlatform, EmulatorStopForPubSub, EmulatorStopForSpanner, } from './emulator/index.js';
2
3
  import { EventTopicBrokerCreateTopicForPubSub, EventTopicBrokerCreateTriggerForCloudRun, EventTopicBrokerDeleteTopicForPubSub, EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole, EventTopicBrokerDeleteTriggerResourceForPubSubSubscription, EventTopicBrokerDeleteTriggerResourceForServiceAccount, EventTopicBrokerGetTopicIdForPubSub, EventTopicBrokerPublishEventsForGoogle, } from './event-topic/index.js';
3
4
  import { GoogleAppCheckGenerateToken } from './google-app-check/index.js';
@@ -11,5 +12,5 @@ import { ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDesti
11
12
  import { SecretFetchForGoogleAccessToken, SecretFetchForGoogleSecretManager, } from './secret/index.js';
12
13
  import { TypeScriptGetDecoratorRendererForGoogleFirestore, TypeScriptGetDecoratorRendererForGoogleSpanner, } from './typescript/index.js';
13
14
  export function registerFunctions(context) {
14
- context.registerFunctionImplementations(EmulatorStartForFirebaseStorage, EmulatorStartForFirestore, EmulatorStartForIdentityPlatform, EmulatorStartForPubSub, EmulatorStartForSpanner, EmulatorStopForFirebaseStorage, EmulatorStopForFirestore, EmulatorStopForIdentityPlatform, EmulatorStopForPubSub, EmulatorStopForSpanner, EventTopicBrokerCreateTopicForPubSub, EventTopicBrokerCreateTriggerForCloudRun, EventTopicBrokerDeleteTopicForPubSub, EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole, EventTopicBrokerDeleteTriggerResourceForPubSubSubscription, EventTopicBrokerDeleteTriggerResourceForServiceAccount, EventTopicBrokerGetTopicIdForPubSub, EventTopicBrokerPublishEventsForGoogle, GoogleAppCheckGenerateToken, GoogleFirebaseStorageMergeRules, GoogleFirestoreMergeRules, GoogleIdentityPlatformGenerateCustomToken, GoogleIdentityPlatformGenerateToken, GooglePubSubWriteTopics, GoogleServicesEnable, GoogleSpannerListDatabases, GoogleSpannerWriteDatabases, ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDestinationForCloudRun, ProjectPushArtefactForCloudFunctions, SecretFetchForGoogleAccessToken, SecretFetchForGoogleSecretManager, TypeScriptGetDecoratorRendererForGoogleFirestore, TypeScriptGetDecoratorRendererForGoogleSpanner);
15
+ context.registerFunctionImplementations(CausaListConfigurationSchemasForGoogle, EmulatorStartForFirebaseStorage, EmulatorStartForFirestore, EmulatorStartForIdentityPlatform, EmulatorStartForPubSub, EmulatorStartForSpanner, EmulatorStopForFirebaseStorage, EmulatorStopForFirestore, EmulatorStopForIdentityPlatform, EmulatorStopForPubSub, EmulatorStopForSpanner, EventTopicBrokerCreateTopicForPubSub, EventTopicBrokerCreateTriggerForCloudRun, EventTopicBrokerDeleteTopicForPubSub, EventTopicBrokerDeleteTriggerResourceForCloudRunInvokerRole, EventTopicBrokerDeleteTriggerResourceForPubSubSubscription, EventTopicBrokerDeleteTriggerResourceForServiceAccount, EventTopicBrokerGetTopicIdForPubSub, EventTopicBrokerPublishEventsForGoogle, GoogleAppCheckGenerateToken, GoogleFirebaseStorageMergeRules, GoogleFirestoreMergeRules, GoogleIdentityPlatformGenerateCustomToken, GoogleIdentityPlatformGenerateToken, GooglePubSubWriteTopics, GoogleServicesEnable, GoogleSpannerListDatabases, GoogleSpannerWriteDatabases, ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDestinationForCloudRun, ProjectPushArtefactForCloudFunctions, SecretFetchForGoogleAccessToken, SecretFetchForGoogleSecretManager, TypeScriptGetDecoratorRendererForGoogleFirestore, TypeScriptGetDecoratorRendererForGoogleSpanner);
15
16
  }
@@ -0,0 +1,3 @@
1
+ import type { WorkspaceContext } from '@causa/workspace';
2
+ import type { ProjectPushArtefactForCloudFunctions } from './push-artefact-cloud-functions.js';
3
+ export default function call(this: ProjectPushArtefactForCloudFunctions, context: WorkspaceContext): Promise<string>;
@@ -0,0 +1,19 @@
1
+ import { ArtefactAlreadyExistsError } from '@causa/workspace-core';
2
+ import { rm } from 'fs/promises';
3
+ import { CloudStorageService } from '../../services/storage.js';
4
+ export default async function call(context) {
5
+ context.logger.info(`🚚 Pushing Cloud Functions archive to Cloud Storage.`);
6
+ const storageService = context.service(CloudStorageService);
7
+ const destination = storageService.getFileFromGsUri(this.destination);
8
+ if (!this.overwrite) {
9
+ const [exists] = await destination.exists();
10
+ if (exists) {
11
+ throw new ArtefactAlreadyExistsError(this.destination);
12
+ }
13
+ }
14
+ await destination.bucket.upload(this.artefact, { destination });
15
+ context.logger.info(`🚚 Successfully pushed archive to '${this.destination}'.`);
16
+ context.logger.debug(`🔥 Removing local artefact '${this.artefact}'.`);
17
+ await rm(this.artefact);
18
+ return this.destination;
19
+ }