@causa/workspace-google 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +123 -0
- package/dist/configurations/google.d.ts +130 -40
- package/dist/functions/emulator-start-spanner.js +3 -5
- package/dist/functions/google-pubsub-write-topics.d.ts +22 -0
- package/dist/functions/google-pubsub-write-topics.js +80 -0
- package/dist/functions/google-spanner-write-databases.d.ts +22 -0
- package/dist/functions/google-spanner-write-databases.js +73 -0
- package/dist/functions/index.js +3 -1
- package/dist/functions/project-get-artefact-destination-cloud-functions.js +3 -1
- package/dist/functions/project-get-artefact-destination-cloud-run.js +3 -1
- package/dist/services/secret-manager.js +2 -2
- package/package.json +23 -22
package/README.md
CHANGED
|
@@ -1 +1,124 @@
|
|
|
1
1
|
# `@causa/workspace-google` module
|
|
2
|
+
|
|
3
|
+
This repository contains the source code for the `@causa/workspace-google` Causa module. It provides many GCP-related utilities and implementations for `cs` commands. For more information about the Causa CLI `cs`, checkout [its repository](https://github.com/causa-io/cli).
|
|
4
|
+
|
|
5
|
+
## ➕ Requirements
|
|
6
|
+
|
|
7
|
+
The Google module requires [Docker](https://www.docker.com/) in order to run local emulators of GCP services.
|
|
8
|
+
|
|
9
|
+
Although not required, the [`gcloud`](https://cloud.google.com/sdk/gcloud) CLI might be useful, e.g. to set up credentials that will be used by the Causa Google module.
|
|
10
|
+
|
|
11
|
+
## 🎉 Installation
|
|
12
|
+
|
|
13
|
+
Add `@causa/workspace-google` to your Causa configuration in `causa.modules`.
|
|
14
|
+
|
|
15
|
+
## 🔧 Configuration
|
|
16
|
+
|
|
17
|
+
For all the Google-related configuration in your Causa files, look at [the schema for the `GoogleConfiguration`](./src/configurations/google.ts).
|
|
18
|
+
|
|
19
|
+
## ✨ Supported project types and commands
|
|
20
|
+
|
|
21
|
+
### Project types
|
|
22
|
+
|
|
23
|
+
The following Causa `project.type`s are supported:
|
|
24
|
+
|
|
25
|
+
- `serviceContainer`, with `google.cloudRun` as the `serviceContainer.platform`. This will ensure the built Docker images are pushed to the repository set in `google.cloudRun.dockerRepository`.
|
|
26
|
+
- `serverlessFunctions`, with `google.cloudFunctions` as the `serverlessFunctions.platform`. This will push functions archives to the Cloud Storage bucket set in `google.cloudFunctions.archivesStorageLocation`.
|
|
27
|
+
|
|
28
|
+
### Emulators
|
|
29
|
+
|
|
30
|
+
The following emulators are implemented:
|
|
31
|
+
|
|
32
|
+
- `google.firebaseStorage`: The Firebase Storage emulator from the Firebase tools. It supports setting the corresponding security rules. See the `cs google firebaseStorage mergeRules` documentation for more details.
|
|
33
|
+
- `google.firestore`: The Firestore emulator from the `gcloud` tools. If supports setting the corresponding security rules. See the `cs google firestore mergeRules` documentation for more details.
|
|
34
|
+
- `google.identityPlatform`: The Identity Platform (Firebase Auth) emulator from the Firebase tools.
|
|
35
|
+
- `google.pubSub`: The Pub/Sub emulator from the `gcloud` tools. It automatically creates the topics for all event topics found in the Causa workspace. `events.broker` must be set to `google.pubSub` for this.
|
|
36
|
+
- `google.spanner`: The Spanner emulator. It automatically creates all the Spanner databases defined in the Causa workspace, and sets up their DDLs. See the `google.spanner` [configuration](./src/configurations/google.ts) for more details.
|
|
37
|
+
|
|
38
|
+
### Secrets backend
|
|
39
|
+
|
|
40
|
+
This module implements the `google.secretManager` secret backend, allowing fetching secrets from the Google Secret Manager service. Here are some example of how secrets with the `google.secretManager` backend should be defined:
|
|
41
|
+
|
|
42
|
+
```yaml
|
|
43
|
+
secrets:
|
|
44
|
+
simpleSecret:
|
|
45
|
+
id: simple-secret
|
|
46
|
+
secretWithProject:
|
|
47
|
+
id: projects/gcp-project/secrets/my-secret
|
|
48
|
+
secretWithVersion:
|
|
49
|
+
id: projects/gcp-project/secrets/my-secret/versions/12
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
When the GCP project is not specified in the secret ID, it is inferred from `google.secretManager.project`, or `google.project` (in this order). This allows defining the GCP project a single time if needed.
|
|
53
|
+
|
|
54
|
+
## 🔨 Custom `google` commands
|
|
55
|
+
|
|
56
|
+
This modules adds a new command to the CLI: `cs google`. Here is the list of subcommands that are exposed.
|
|
57
|
+
|
|
58
|
+
### App Check
|
|
59
|
+
|
|
60
|
+
The `cs google appCheck genToken` command generates an App Check token, which can be used to authenticate calls to APIs that are protected by Firebase App Check.
|
|
61
|
+
|
|
62
|
+
A token is generated for a specific Firebase application. This can be set using the `-a, --app <app>` argument. If it is not set, any Firebase application will be selected automatically using the Firebase API.
|
|
63
|
+
|
|
64
|
+
An App Check token must be signed using an admin service account in the same project as the app. Firebase automatically creates such an account when it is initialized from a GCP project. This command can take care of automatically finding this account. However, if you want to save on API calls, the email for any service account with Firebase admin permissions can be set in `google.firebase.adminServiceAccount`.
|
|
65
|
+
|
|
66
|
+
### Enable services
|
|
67
|
+
|
|
68
|
+
The `cs google enableServices` command will enable all the GCP services defined in `google.services`. This command is also exposed as an infrastructure processors, under the name `GoogleServicesEnable`.
|
|
69
|
+
|
|
70
|
+
### Firebase Storage
|
|
71
|
+
|
|
72
|
+
The `cs google firebaseStorage mergeRules` command merges several Firebase security rules files together into a single file that can be used as configuration for both the Firebase Storage emulator, and the Firebase Storage production service.
|
|
73
|
+
|
|
74
|
+
Input files are found using the glob patterns defined in `google.firebaseStorage.securityRuleFiles`. Input files should not include the header, i.e. they should defined what is **inside**:
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
rules_version = '2';
|
|
78
|
+
|
|
79
|
+
service firebase.storage {
|
|
80
|
+
match /b/{bucket}/o {
|
|
81
|
+
// Only include what is inside those brackets.
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The output Firebase security rules file can be set in `google.firebaseStorage.securityRuleFile`.
|
|
87
|
+
|
|
88
|
+
### Firestore
|
|
89
|
+
|
|
90
|
+
The `cs google firestore mergeRules` command merges several Firebase security rules files together into a single file that can be used as configuration for both the Firestore emulator, and the Firestore production service.
|
|
91
|
+
|
|
92
|
+
This command is extremely similar to `cs google firebaseStorage mergeRules`. Input files are defined in `google.firestore.securityRuleFiles`, and the output file is defined in `google.firestore.securityRuleFile`.
|
|
93
|
+
|
|
94
|
+
### Identity Platform
|
|
95
|
+
|
|
96
|
+
The `cs google identityPlatform genToken` command generates an Identity Platform (formerly Firebase Auth) ID token, which can be used to authenticate calls to API protected by Identity Platform.
|
|
97
|
+
|
|
98
|
+
This command is similar to `cs google appCheck genToken` in that it requires a service account with Firebase admin permissions to sign the token. See the corresponding command for more information.
|
|
99
|
+
|
|
100
|
+
## 🧱 Infrastructure processors
|
|
101
|
+
|
|
102
|
+
The Google module provides several infrastructure processors, which can be used to set up the Causa workspace before running infrastructure-related operations.
|
|
103
|
+
|
|
104
|
+
### `GoogleFirebaseStorageMergeRules`
|
|
105
|
+
|
|
106
|
+
[GoogleFirebaseStorageMergeRules](./src/functions/google-firebase-storage-merge-rules.ts) is the same underlying function as the `cs google firebaseStorage mergeRules` command. It allows preparing the Firebase Storage security rules before possibly deploying them along with the infrastructure. See the corresponding command for more details.
|
|
107
|
+
|
|
108
|
+
### `GoogleFirestoreMergeRules`
|
|
109
|
+
|
|
110
|
+
[GoogleFirestoreMergeRules](./src/functions/google-firestore-merge-rules.ts) is the same underlying function as the `cs google firestore mergeRules` command. It allows preparing the Firestore security rules before possibly deploying them along with the infrastructure. See the corresponding command for more details.
|
|
111
|
+
|
|
112
|
+
### `GoogleServicesEnable`
|
|
113
|
+
|
|
114
|
+
[GoogleServicesEnable](./src/functions/google-services-enable.ts) is the same underlying function as the `cs google enableServices` command. It enables GCP services before preparing or deploying the infrastructure.
|
|
115
|
+
|
|
116
|
+
Although infrastructure as code tools usually expose this feature as well (e.g. the [`google_project_service`](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_service) Terraform resource), it might be more convenient to enable all the required services before running those tools. It avoids having to define dependencies between the services and all the actual resources being deployed.
|
|
117
|
+
|
|
118
|
+
### `GoogleSpannerWriteDatabases`
|
|
119
|
+
|
|
120
|
+
[GoogleSpannerWriteDatabases](./src/functions/google-spanner-write-databases.ts) writes a configuration file for each Spanner database, such that it can be picked up by the Causa Spanner Terraform module. This allows automatic setup of Spanner databases and their DDLs.
|
|
121
|
+
|
|
122
|
+
### `GooglePubSubWriteTopics`
|
|
123
|
+
|
|
124
|
+
[GooglePubSubWriteTopics](./src/functions/google-pubsub-write-topics.ts) writes a configuration file for each event topic, such that it can be picked up by the Causa Pub/Sub Terraform module. This allows automatic setup of Pub/Sub topics, and optionally of the corresponding BigQuery tables.
|
|
@@ -5,35 +5,35 @@ export type GoogleConfiguration = {
|
|
|
5
5
|
/**
|
|
6
6
|
* Configuration for everything Google / GCP-related.
|
|
7
7
|
*/
|
|
8
|
-
google?: {
|
|
8
|
+
readonly google?: {
|
|
9
9
|
/**
|
|
10
10
|
* The ID of the default GCP project used when performing operations.
|
|
11
11
|
*/
|
|
12
|
-
project?: string;
|
|
12
|
+
readonly project?: string;
|
|
13
13
|
/**
|
|
14
14
|
* The ID of a local GCP project (which does not exist on GCP).
|
|
15
15
|
* This is for example used by emulators. It should usually start with `demo-` to be compatible with some emulators.
|
|
16
16
|
*/
|
|
17
|
-
localProject?: string;
|
|
17
|
+
readonly localProject?: string;
|
|
18
18
|
/**
|
|
19
19
|
* The list of GCP services on which the project depends.
|
|
20
20
|
* This is useful to automatically enable those services in the GCP project.
|
|
21
21
|
*/
|
|
22
|
-
services?: string[];
|
|
22
|
+
readonly services?: string[];
|
|
23
23
|
/**
|
|
24
24
|
* Configuration for the `gcloud` command.
|
|
25
25
|
* This applies to Dockerized calls to `gcloud` using the official `gcloud` Docker image.
|
|
26
26
|
*/
|
|
27
|
-
gcloud?: {
|
|
27
|
+
readonly gcloud?: {
|
|
28
28
|
/**
|
|
29
29
|
* The version of the `gcloud` command.
|
|
30
30
|
*/
|
|
31
|
-
version?: string;
|
|
31
|
+
readonly version?: string;
|
|
32
32
|
};
|
|
33
33
|
/**
|
|
34
34
|
* Configuration for the Firebase project.
|
|
35
35
|
*/
|
|
36
|
-
firebase?: {
|
|
36
|
+
readonly firebase?: {
|
|
37
37
|
/**
|
|
38
38
|
* An existing service account that can be used to sign Identity Platform custom token.
|
|
39
39
|
* Generating custom tokens by signing them using end-user credentials does not work with Identity Platform.
|
|
@@ -42,156 +42,246 @@ export type GoogleConfiguration = {
|
|
|
42
42
|
* If this is not set and is needed by an operation, an attempt will be made to find this service account in the
|
|
43
43
|
* current `google.project`.
|
|
44
44
|
*/
|
|
45
|
-
adminServiceAccount?: string;
|
|
45
|
+
readonly adminServiceAccount?: string;
|
|
46
46
|
/**
|
|
47
47
|
* The Firebase API key used by clients. Used to perform requests to Firebase as an end user.
|
|
48
48
|
* This can be found in the GCP or Firebase Console.
|
|
49
49
|
* If this is not set and is needed by an operation, an attempt will be made to find the key automatically using
|
|
50
50
|
* the API.
|
|
51
51
|
*/
|
|
52
|
-
apiKey?: string;
|
|
52
|
+
readonly apiKey?: string;
|
|
53
53
|
/**
|
|
54
54
|
* The Firebase app ID used by clients.
|
|
55
55
|
* This can be found in the Firebase Console. Each platform (Android, iOS, Web) has its own app ID.
|
|
56
56
|
* If this is not set and is needed by an operation, an attempt will be made to find the first eligible app ID
|
|
57
57
|
* using the Firebase API.
|
|
58
58
|
*/
|
|
59
|
-
appId?: string;
|
|
59
|
+
readonly appId?: string;
|
|
60
60
|
/**
|
|
61
61
|
* The domain name for the project.
|
|
62
62
|
* If not set, this default to `<GCP project>.firebaseapp.com`.
|
|
63
63
|
*/
|
|
64
|
-
authDomain?: string;
|
|
64
|
+
readonly authDomain?: string;
|
|
65
65
|
/**
|
|
66
66
|
* Configuration for Firebase tools (the CLI).
|
|
67
67
|
* This applies to Dockerized calls to the `firebase` CLI.
|
|
68
68
|
*/
|
|
69
|
-
tools?: {
|
|
69
|
+
readonly tools?: {
|
|
70
70
|
/**
|
|
71
71
|
* The version of the CLI to use.
|
|
72
72
|
*/
|
|
73
|
-
version?: string;
|
|
73
|
+
readonly version?: string;
|
|
74
74
|
};
|
|
75
75
|
};
|
|
76
76
|
/**
|
|
77
77
|
* Configuration for the Secret Manager service.
|
|
78
78
|
*/
|
|
79
|
-
secretManager?: {
|
|
79
|
+
readonly secretManager?: {
|
|
80
80
|
/**
|
|
81
81
|
* The ID of the default GCP project referenced when fetching secrets.
|
|
82
82
|
*/
|
|
83
|
-
project?: string;
|
|
83
|
+
readonly project?: string;
|
|
84
84
|
};
|
|
85
85
|
/**
|
|
86
86
|
* Configuration for the Firebase Storage service.
|
|
87
87
|
*/
|
|
88
|
-
firebaseStorage?: {
|
|
88
|
+
readonly firebaseStorage?: {
|
|
89
89
|
/**
|
|
90
90
|
* Configuration for the emulator.
|
|
91
91
|
*/
|
|
92
|
-
emulator?: {
|
|
92
|
+
readonly emulator?: {
|
|
93
93
|
/**
|
|
94
94
|
* The name of the local Docker container running the emulator.
|
|
95
95
|
*/
|
|
96
|
-
containerName?: string;
|
|
96
|
+
readonly containerName?: string;
|
|
97
97
|
};
|
|
98
98
|
/**
|
|
99
99
|
* A list of glob patterns to find files in the workspace defining Firebase Storage security rules.
|
|
100
100
|
*/
|
|
101
|
-
securityRuleFiles?: string[];
|
|
101
|
+
readonly securityRuleFiles?: string[];
|
|
102
102
|
/**
|
|
103
103
|
* The file path, relative to the workspace root, where the merged security rules file is written.
|
|
104
104
|
*/
|
|
105
|
-
securityRuleFile?: string;
|
|
105
|
+
readonly securityRuleFile?: string;
|
|
106
106
|
};
|
|
107
107
|
/**
|
|
108
108
|
* Configuration for the Identity Platform (formerly Firebase Auth) service.
|
|
109
109
|
*/
|
|
110
|
-
identityPlatform?: {
|
|
110
|
+
readonly identityPlatform?: {
|
|
111
111
|
/**
|
|
112
112
|
* Configuration for the emulator.
|
|
113
113
|
*/
|
|
114
|
-
emulator?: {
|
|
114
|
+
readonly emulator?: {
|
|
115
115
|
/**
|
|
116
116
|
* The name of the local Docker container running the emulator.
|
|
117
117
|
*/
|
|
118
|
-
containerName?: string;
|
|
118
|
+
readonly containerName?: string;
|
|
119
119
|
};
|
|
120
120
|
};
|
|
121
121
|
/**
|
|
122
122
|
* Configuration for the Firestore service.
|
|
123
123
|
*/
|
|
124
|
-
firestore?: {
|
|
124
|
+
readonly firestore?: {
|
|
125
125
|
/**
|
|
126
126
|
* Configuration for the emulator.
|
|
127
127
|
*/
|
|
128
|
-
emulator?: {
|
|
128
|
+
readonly emulator?: {
|
|
129
129
|
/**
|
|
130
130
|
* The name of the local Docker container running the emulator.
|
|
131
131
|
*/
|
|
132
|
-
containerName?: string;
|
|
132
|
+
readonly containerName?: string;
|
|
133
133
|
};
|
|
134
134
|
/**
|
|
135
135
|
* A list of glob patterns to find files in the workspace defining Firestore security rules.
|
|
136
136
|
*/
|
|
137
|
-
securityRuleFiles?: string[];
|
|
137
|
+
readonly securityRuleFiles?: string[];
|
|
138
138
|
/**
|
|
139
139
|
* The file path, relative to the workspace root, where the merged security rules file is written.
|
|
140
140
|
*/
|
|
141
|
-
securityRuleFile?: string;
|
|
141
|
+
readonly securityRuleFile?: string;
|
|
142
142
|
};
|
|
143
143
|
/**
|
|
144
144
|
* Configuration for the Pub/Sub service.
|
|
145
145
|
*/
|
|
146
|
-
pubSub?: {
|
|
146
|
+
readonly pubSub?: {
|
|
147
147
|
/**
|
|
148
148
|
* Configuration for the emulator.
|
|
149
149
|
*/
|
|
150
|
-
emulator?: {
|
|
150
|
+
readonly emulator?: {
|
|
151
151
|
/**
|
|
152
152
|
* The name of the local Docker container running the emulator.
|
|
153
153
|
*/
|
|
154
|
-
containerName?: string;
|
|
154
|
+
readonly containerName?: string;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* The directory where the topic configuration files are written by the `GooglePubSubWriteTopics` processor.
|
|
158
|
+
*/
|
|
159
|
+
readonly topicConfigurationsDirectory?: string;
|
|
160
|
+
/**
|
|
161
|
+
* Configuration for the storage of Pub/Sub events in BigQuery.
|
|
162
|
+
*/
|
|
163
|
+
readonly bigQueryStorage?: {
|
|
164
|
+
/**
|
|
165
|
+
* The ID of the BigQuery dataset where raw Pub/Sub events should be stored.
|
|
166
|
+
*/
|
|
167
|
+
readonly rawEventsDatasetId?: string;
|
|
155
168
|
};
|
|
156
169
|
};
|
|
157
170
|
/**
|
|
158
171
|
* Configuration for the Spanner service.
|
|
159
172
|
*/
|
|
160
|
-
spanner?: {
|
|
173
|
+
readonly spanner?: {
|
|
161
174
|
/**
|
|
162
175
|
* Configuration for the emulator.
|
|
163
176
|
*/
|
|
164
|
-
emulator?: {
|
|
177
|
+
readonly emulator?: {
|
|
165
178
|
/**
|
|
166
179
|
* The name of the local Docker container running the emulator.
|
|
167
180
|
*/
|
|
168
|
-
containerName?: string;
|
|
181
|
+
readonly containerName?: string;
|
|
169
182
|
/**
|
|
170
183
|
* The version of the Spanner emulator Docker image to use.
|
|
171
184
|
*/
|
|
172
|
-
version?: string;
|
|
185
|
+
readonly version?: string;
|
|
173
186
|
/**
|
|
174
187
|
* The name of the Spanner instance that will automatically be created in the emulator.
|
|
175
188
|
*/
|
|
176
|
-
instanceName?: string;
|
|
189
|
+
readonly instanceName?: string;
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* Configuration for the Spanner instance.
|
|
193
|
+
*/
|
|
194
|
+
readonly instance?: {
|
|
195
|
+
/**
|
|
196
|
+
* The name of the Spanner instance.
|
|
197
|
+
*/
|
|
198
|
+
readonly name?: string;
|
|
199
|
+
/**
|
|
200
|
+
* The instance geographic configuration.
|
|
201
|
+
* See https://cloud.google.com/spanner/docs/instance-configurations for more details.
|
|
202
|
+
*/
|
|
203
|
+
readonly configuration?: string;
|
|
204
|
+
/**
|
|
205
|
+
* The compute capacity of the instance.
|
|
206
|
+
* See https://cloud.google.com/spanner/docs/compute-capacity for more details.
|
|
207
|
+
*/
|
|
208
|
+
readonly processingUnits?: number;
|
|
177
209
|
};
|
|
178
210
|
/**
|
|
179
211
|
* Defines how DDLs are found for the Spanner databases in the workspace.
|
|
180
212
|
*/
|
|
181
|
-
ddls?: {
|
|
213
|
+
readonly ddls?: {
|
|
182
214
|
/**
|
|
183
215
|
* The format string using groups from the regular expression used to make the database names.
|
|
184
216
|
*/
|
|
185
|
-
format?: string;
|
|
217
|
+
readonly format?: string;
|
|
186
218
|
/**
|
|
187
219
|
* A list of glob patterns used to find SQL files containing DDL statements for the Spanner databases.
|
|
188
220
|
*/
|
|
189
|
-
globs?: string[];
|
|
221
|
+
readonly globs?: string[];
|
|
190
222
|
/**
|
|
191
223
|
* The regular expression used to extract groups from the SQL file paths.
|
|
192
224
|
*/
|
|
193
|
-
regularExpression?: string;
|
|
225
|
+
readonly regularExpression?: string;
|
|
194
226
|
};
|
|
227
|
+
/**
|
|
228
|
+
* The directory where the database configuration files are written by the `GoogleSpannerWriteDatabases`
|
|
229
|
+
* processor.
|
|
230
|
+
*/
|
|
231
|
+
readonly databaseConfigurationsDirectory?: string;
|
|
232
|
+
};
|
|
233
|
+
/**
|
|
234
|
+
* Configuration for Cloud Functions.
|
|
235
|
+
*/
|
|
236
|
+
readonly cloudFunctions?: {
|
|
237
|
+
/**
|
|
238
|
+
* The Cloud Storage URI where Cloud Functions archives should be uploaded.
|
|
239
|
+
*/
|
|
240
|
+
readonly archivesStorageLocation?: string;
|
|
241
|
+
};
|
|
242
|
+
/**
|
|
243
|
+
* Configuration for Cloud Run containers.
|
|
244
|
+
*/
|
|
245
|
+
readonly cloudRun?: {
|
|
246
|
+
/**
|
|
247
|
+
* The Docker repository where Cloud Run containers should be uploaded.
|
|
248
|
+
*/
|
|
249
|
+
readonly dockerRepository?: string;
|
|
250
|
+
/**
|
|
251
|
+
* The location where Cloud Run services should be deployed.
|
|
252
|
+
*/
|
|
253
|
+
readonly location?: string;
|
|
254
|
+
/**
|
|
255
|
+
* A map where keys are the name of environment variables, and values are secret versions IDs (e.g.
|
|
256
|
+
* `projects/my-project/secrets/my-secret/versions/1`).
|
|
257
|
+
*/
|
|
258
|
+
readonly secretEnvironmentVariables?: Record<string, string>;
|
|
259
|
+
/**
|
|
260
|
+
* Whether the container is running between requests and can perform background operations.
|
|
261
|
+
*/
|
|
262
|
+
readonly cpuAlwaysAllocated?: boolean;
|
|
263
|
+
/**
|
|
264
|
+
* The max duration the instance is allowed for responding to a request, in seconds.
|
|
265
|
+
*/
|
|
266
|
+
readonly timeout?: number;
|
|
267
|
+
/**
|
|
268
|
+
* The maximum allowed in-flight (concurrent) requests per container.
|
|
269
|
+
*/
|
|
270
|
+
readonly requestConcurrency?: number;
|
|
271
|
+
/**
|
|
272
|
+
* The type of allowed ingress that can reach the container.
|
|
273
|
+
* See https://cloud.google.com/run/docs/securing/ingress#settings for more details.
|
|
274
|
+
*/
|
|
275
|
+
readonly ingress?: 'all' | 'internal' | 'internal-and-cloud-load-balancing';
|
|
276
|
+
/**
|
|
277
|
+
* The name of the VPC access connector through which egress traffic should be routed.
|
|
278
|
+
*/
|
|
279
|
+
readonly vpcAccessConnector?: string;
|
|
280
|
+
/**
|
|
281
|
+
* The setting for egress traffic that goes through the VPC access connector.
|
|
282
|
+
* See https://cloud.google.com/run/docs/configuring/connecting-vpc#manage for more details.
|
|
283
|
+
*/
|
|
284
|
+
readonly vpcAccessConnectorEgressSettings?: 'all-traffic' | 'private-ranges-only';
|
|
195
285
|
};
|
|
196
286
|
};
|
|
197
287
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DockerEmulatorService, EmulatorStart, } from '@causa/workspace-core';
|
|
2
2
|
import { Spanner } from '@google-cloud/spanner';
|
|
3
|
-
import {
|
|
3
|
+
import { credentials } from '@grpc/grpc-js';
|
|
4
4
|
import { getLocalGcpProject, } from '../configurations/index.js';
|
|
5
5
|
import { SPANNER_EMULATOR_NAME, SPANNER_GRPC_PORT, SPANNER_HTTP_PORT, SPANNER_IMAGE, getSpannerContainerName, } from '../emulators/index.js';
|
|
6
6
|
import { GoogleSpannerListDatabases } from './google-spanner-list-databases.js';
|
|
@@ -75,7 +75,7 @@ export class EmulatorStartForSpanner extends EmulatorStart {
|
|
|
75
75
|
servicePath: '127.0.0.1',
|
|
76
76
|
port: SPANNER_GRPC_PORT,
|
|
77
77
|
projectId: getLocalGcpProject(context),
|
|
78
|
-
sslCreds:
|
|
78
|
+
sslCreds: credentials.createInsecure(),
|
|
79
79
|
});
|
|
80
80
|
const [instance, operation] = await spanner.createInstance(instanceName, {
|
|
81
81
|
config: 'emulator-config',
|
|
@@ -98,9 +98,7 @@ export class EmulatorStartForSpanner extends EmulatorStart {
|
|
|
98
98
|
context.logger.info(`🗃️ Creating Spanner emulator database '${database.id}'.`);
|
|
99
99
|
// Discarding `DROP TABLE` statements as the emulator does not seem to handle them properly.
|
|
100
100
|
const ddls = database.ddls.filter((statement) => !statement.toUpperCase().startsWith('DROP TABLE'));
|
|
101
|
-
const
|
|
102
|
-
schema: ddls,
|
|
103
|
-
});
|
|
101
|
+
const operation = (await instance.createDatabase(database.id, { schema: ddls }))[1];
|
|
104
102
|
await operation.promise();
|
|
105
103
|
}));
|
|
106
104
|
return databases.length === 0
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ProcessorResult, WorkspaceContext, WorkspaceFunction } from '@causa/workspace';
|
|
2
|
+
import { InfrastructureProcessor } from '@causa/workspace-core';
|
|
3
|
+
/**
|
|
4
|
+
* A function that uses {@link EventTopicList} to find all the topics in the workspace, and writes their configurations
|
|
5
|
+
* to a directory.
|
|
6
|
+
* The `google.pubSub.topicConfigurationsDirectory` configuration can be used to specify the output location of the
|
|
7
|
+
* topic configurations.
|
|
8
|
+
* This function returns a partial configuration, such that it can be used as a processor.
|
|
9
|
+
*/
|
|
10
|
+
export declare class GooglePubSubWriteTopics extends WorkspaceFunction<Promise<ProcessorResult>> implements InfrastructureProcessor {
|
|
11
|
+
readonly tearDown?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Returns the path to the directory where Pub/Sub topic configurations should be written.
|
|
14
|
+
* It is either fetched from the workspace configuration, or the default value is used.
|
|
15
|
+
*
|
|
16
|
+
* @param context The {@link WorkspaceContext}.
|
|
17
|
+
* @returns The path to the directory where topic configurations should be written.
|
|
18
|
+
*/
|
|
19
|
+
private getConfigurationsDirectory;
|
|
20
|
+
_call(context: WorkspaceContext): Promise<ProcessorResult>;
|
|
21
|
+
_supports(): boolean;
|
|
22
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { WorkspaceFunction, } from '@causa/workspace';
|
|
11
|
+
import { EventTopicList, } from '@causa/workspace-core';
|
|
12
|
+
import { CAUSA_FOLDER } from '@causa/workspace/initialization';
|
|
13
|
+
import { AllowMissing } from '@causa/workspace/validation';
|
|
14
|
+
import { IsBoolean } from 'class-validator';
|
|
15
|
+
import { mkdir, rm, writeFile } from 'fs/promises';
|
|
16
|
+
import { join } from 'path';
|
|
17
|
+
/**
|
|
18
|
+
* The default directory where Pub/Sub topic configurations are written, relative to the workspace root.
|
|
19
|
+
*/
|
|
20
|
+
const DEFAULT_TOPIC_CONFIGURATIONS_DIRECTORY = join(CAUSA_FOLDER, 'pubsub-topics');
|
|
21
|
+
/**
|
|
22
|
+
* A function that uses {@link EventTopicList} to find all the topics in the workspace, and writes their configurations
|
|
23
|
+
* to a directory.
|
|
24
|
+
* The `google.pubSub.topicConfigurationsDirectory` configuration can be used to specify the output location of the
|
|
25
|
+
* topic configurations.
|
|
26
|
+
* This function returns a partial configuration, such that it can be used as a processor.
|
|
27
|
+
*/
|
|
28
|
+
export class GooglePubSubWriteTopics extends WorkspaceFunction {
|
|
29
|
+
tearDown;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the path to the directory where Pub/Sub topic configurations should be written.
|
|
32
|
+
* It is either fetched from the workspace configuration, or the default value is used.
|
|
33
|
+
*
|
|
34
|
+
* @param context The {@link WorkspaceContext}.
|
|
35
|
+
* @returns The path to the directory where topic configurations should be written.
|
|
36
|
+
*/
|
|
37
|
+
getConfigurationsDirectory(context) {
|
|
38
|
+
return (context
|
|
39
|
+
.asConfiguration()
|
|
40
|
+
.get('google.pubSub.topicConfigurationsDirectory') ??
|
|
41
|
+
DEFAULT_TOPIC_CONFIGURATIONS_DIRECTORY);
|
|
42
|
+
}
|
|
43
|
+
async _call(context) {
|
|
44
|
+
const topicConfigurationsDirectory = this.getConfigurationsDirectory(context);
|
|
45
|
+
const absoluteDir = join(context.rootPath, topicConfigurationsDirectory);
|
|
46
|
+
await rm(absoluteDir, { recursive: true, force: true });
|
|
47
|
+
if (this.tearDown) {
|
|
48
|
+
context.logger.debug(`📫 Tore down Pub/Sub topic configurations directory '${absoluteDir}'.`);
|
|
49
|
+
return { configuration: {} };
|
|
50
|
+
}
|
|
51
|
+
context.logger.info('️📫 Listing and writing Pub/Sub topic configurations.');
|
|
52
|
+
const topics = await context.call(EventTopicList, {});
|
|
53
|
+
context.logger.debug(`📫 Writing configurations for Pub/Sub topics: ${topics
|
|
54
|
+
.map((d) => `'${d.id}'`)
|
|
55
|
+
.join(', ')}.`);
|
|
56
|
+
await mkdir(absoluteDir, { recursive: true });
|
|
57
|
+
await Promise.all(topics.map(async (topic) => {
|
|
58
|
+
const topicConfiguration = {
|
|
59
|
+
...topic,
|
|
60
|
+
bigQueryTableName: topic.id.replace(/[-\.]/g, '_'),
|
|
61
|
+
};
|
|
62
|
+
const topicFile = join(absoluteDir, `${topic.id}.json`);
|
|
63
|
+
await writeFile(topicFile, JSON.stringify(topicConfiguration));
|
|
64
|
+
}));
|
|
65
|
+
context.logger.debug(`️📫 Wrote Pub/Sub topic configurations in '${absoluteDir}'.`);
|
|
66
|
+
return {
|
|
67
|
+
configuration: {
|
|
68
|
+
google: { pubSub: { topicConfigurationsDirectory } },
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
_supports() {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
__decorate([
|
|
77
|
+
IsBoolean(),
|
|
78
|
+
AllowMissing(),
|
|
79
|
+
__metadata("design:type", Boolean)
|
|
80
|
+
], GooglePubSubWriteTopics.prototype, "tearDown", void 0);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ProcessorResult, WorkspaceContext, WorkspaceFunction } from '@causa/workspace';
|
|
2
|
+
import { InfrastructureProcessor } from '@causa/workspace-core';
|
|
3
|
+
/**
|
|
4
|
+
* A function that uses {@link GoogleSpannerListDatabases} to find all the Spanner databases in the workspace, and
|
|
5
|
+
* writes their configurations to a directory.
|
|
6
|
+
* The `google.spanner.databaseConfigurationsDirectory` configuration can be used to specify the output location of the
|
|
7
|
+
* database configurations.
|
|
8
|
+
* This function returns a partial configuration, such that it can be used as a processor.
|
|
9
|
+
*/
|
|
10
|
+
export declare class GoogleSpannerWriteDatabases extends WorkspaceFunction<Promise<ProcessorResult>> implements InfrastructureProcessor {
|
|
11
|
+
readonly tearDown?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Returns the path to the directory where Spanner databases configurations should be written.
|
|
14
|
+
* It is either fetched from the workspace configuration, or the default value is used.
|
|
15
|
+
*
|
|
16
|
+
* @param context The {@link WorkspaceContext}.
|
|
17
|
+
* @returns The path to the directory where database configurations should be written.
|
|
18
|
+
*/
|
|
19
|
+
private getConfigurationsDirectory;
|
|
20
|
+
_call(context: WorkspaceContext): Promise<ProcessorResult>;
|
|
21
|
+
_supports(): boolean;
|
|
22
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { WorkspaceFunction, } from '@causa/workspace';
|
|
11
|
+
import { CAUSA_FOLDER } from '@causa/workspace/initialization';
|
|
12
|
+
import { AllowMissing } from '@causa/workspace/validation';
|
|
13
|
+
import { IsBoolean } from 'class-validator';
|
|
14
|
+
import { mkdir, rm, writeFile } from 'fs/promises';
|
|
15
|
+
import { join } from 'path';
|
|
16
|
+
import { GoogleSpannerListDatabases } from './google-spanner-list-databases.js';
|
|
17
|
+
/**
|
|
18
|
+
* The default directory where Spanner database configurations are written, relative to the workspace root.
|
|
19
|
+
*/
|
|
20
|
+
const DEFAULT_DATABASE_CONFIGURATIONS_DIRECTORY = join(CAUSA_FOLDER, 'spanner-databases');
|
|
21
|
+
/**
|
|
22
|
+
* A function that uses {@link GoogleSpannerListDatabases} to find all the Spanner databases in the workspace, and
|
|
23
|
+
* writes their configurations to a directory.
|
|
24
|
+
* The `google.spanner.databaseConfigurationsDirectory` configuration can be used to specify the output location of the
|
|
25
|
+
* database configurations.
|
|
26
|
+
* This function returns a partial configuration, such that it can be used as a processor.
|
|
27
|
+
*/
|
|
28
|
+
export class GoogleSpannerWriteDatabases extends WorkspaceFunction {
|
|
29
|
+
tearDown;
|
|
30
|
+
/**
|
|
31
|
+
* Returns the path to the directory where Spanner databases configurations should be written.
|
|
32
|
+
* It is either fetched from the workspace configuration, or the default value is used.
|
|
33
|
+
*
|
|
34
|
+
* @param context The {@link WorkspaceContext}.
|
|
35
|
+
* @returns The path to the directory where database configurations should be written.
|
|
36
|
+
*/
|
|
37
|
+
getConfigurationsDirectory(context) {
|
|
38
|
+
return (context
|
|
39
|
+
.asConfiguration()
|
|
40
|
+
.get('google.spanner.databaseConfigurationsDirectory') ??
|
|
41
|
+
DEFAULT_DATABASE_CONFIGURATIONS_DIRECTORY);
|
|
42
|
+
}
|
|
43
|
+
async _call(context) {
|
|
44
|
+
const databaseConfigurationsDirectory = this.getConfigurationsDirectory(context);
|
|
45
|
+
const absoluteDir = join(context.rootPath, databaseConfigurationsDirectory);
|
|
46
|
+
await rm(absoluteDir, { recursive: true, force: true });
|
|
47
|
+
if (this.tearDown) {
|
|
48
|
+
context.logger.debug(`️🗃️ Tore down Spanner database configurations directory '${absoluteDir}'.`);
|
|
49
|
+
return { configuration: {} };
|
|
50
|
+
}
|
|
51
|
+
context.logger.info('🗃️ Listing and writing Spanner database configurations.');
|
|
52
|
+
const databases = await context.call(GoogleSpannerListDatabases, {});
|
|
53
|
+
await mkdir(absoluteDir, { recursive: true });
|
|
54
|
+
context.logger.debug(`🗃️ Writing configurations for Spanner databases: ${databases
|
|
55
|
+
.map((d) => `'${d.id}'`)
|
|
56
|
+
.join(', ')}.`);
|
|
57
|
+
await Promise.all(databases.map((database) => writeFile(join(absoluteDir, `${database.id}.json`), JSON.stringify(database))));
|
|
58
|
+
context.logger.debug(`🗃️ Wrote Spanner database configurations in '${absoluteDir}'.`);
|
|
59
|
+
return {
|
|
60
|
+
configuration: {
|
|
61
|
+
google: { spanner: { databaseConfigurationsDirectory } },
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
_supports() {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
__decorate([
|
|
70
|
+
IsBoolean(),
|
|
71
|
+
AllowMissing(),
|
|
72
|
+
__metadata("design:type", Boolean)
|
|
73
|
+
], GoogleSpannerWriteDatabases.prototype, "tearDown", void 0);
|
package/dist/functions/index.js
CHANGED
|
@@ -13,12 +13,14 @@ import { GoogleFirebaseStorageMergeRules } from './google-firebase-storage-merge
|
|
|
13
13
|
import { GoogleFirestoreMergeRules } from './google-firestore-merge-rules.js';
|
|
14
14
|
import { GoogleIdentityPlatformGenerateCustomToken } from './google-identity-platform-generate-custom-token.js';
|
|
15
15
|
import { GoogleIdentityPlatformGenerateToken } from './google-identity-platform-generate-token.js';
|
|
16
|
+
import { GooglePubSubWriteTopics } from './google-pubsub-write-topics.js';
|
|
16
17
|
import { GoogleServicesEnable } from './google-services-enable.js';
|
|
17
18
|
import { GoogleSpannerListDatabases } from './google-spanner-list-databases.js';
|
|
19
|
+
import { GoogleSpannerWriteDatabases } from './google-spanner-write-databases.js';
|
|
18
20
|
import { ProjectGetArtefactDestinationForCloudFunctions } from './project-get-artefact-destination-cloud-functions.js';
|
|
19
21
|
import { ProjectGetArtefactDestinationForCloudRun } from './project-get-artefact-destination-cloud-run.js';
|
|
20
22
|
import { ProjectPushArtefactForCloudFunctions } from './project-push-artefact-cloud-functions.js';
|
|
21
23
|
import { SecretFetchForGoogleSecretManager } from './secret-fetch-secret-manager.js';
|
|
22
24
|
export function registerFunctions(context) {
|
|
23
|
-
context.registerFunctionImplementations(EmulatorStartForFirebaseStorage, EmulatorStartForFirestore, EmulatorStartForIdentityPlatform, EmulatorStartForPubSub, EmulatorStartForSpanner, EmulatorStopForFirebaseStorage, EmulatorStopForFirestore, EmulatorStopForIdentityPlatform, EmulatorStopForPubSub, EmulatorStopForSpanner, GoogleAppCheckGenerateToken, GoogleFirebaseStorageMergeRules, GoogleFirestoreMergeRules, GoogleIdentityPlatformGenerateCustomToken, GoogleIdentityPlatformGenerateToken, GoogleServicesEnable, GoogleSpannerListDatabases, ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDestinationForCloudRun, ProjectPushArtefactForCloudFunctions, SecretFetchForGoogleSecretManager);
|
|
25
|
+
context.registerFunctionImplementations(EmulatorStartForFirebaseStorage, EmulatorStartForFirestore, EmulatorStartForIdentityPlatform, EmulatorStartForPubSub, EmulatorStartForSpanner, EmulatorStopForFirebaseStorage, EmulatorStopForFirestore, EmulatorStopForIdentityPlatform, EmulatorStopForPubSub, EmulatorStopForSpanner, GoogleAppCheckGenerateToken, GoogleFirebaseStorageMergeRules, GoogleFirestoreMergeRules, GoogleIdentityPlatformGenerateCustomToken, GoogleIdentityPlatformGenerateToken, GooglePubSubWriteTopics, GoogleServicesEnable, GoogleSpannerListDatabases, GoogleSpannerWriteDatabases, ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDestinationForCloudRun, ProjectPushArtefactForCloudFunctions, SecretFetchForGoogleSecretManager);
|
|
24
26
|
}
|
|
@@ -7,7 +7,9 @@ import { ProjectGetArtefactDestination, } from '@causa/workspace-core';
|
|
|
7
7
|
export class ProjectGetArtefactDestinationForCloudFunctions extends ProjectGetArtefactDestination {
|
|
8
8
|
async _call(context) {
|
|
9
9
|
const projectName = context.getOrThrow('project.name');
|
|
10
|
-
const archivesStorageLocation = context
|
|
10
|
+
const archivesStorageLocation = context
|
|
11
|
+
.asConfiguration()
|
|
12
|
+
.getOrThrow('google.cloudFunctions.archivesStorageLocation');
|
|
11
13
|
return `${archivesStorageLocation}/${projectName}/${this.tag}.zip`;
|
|
12
14
|
}
|
|
13
15
|
_supports(context) {
|
|
@@ -6,7 +6,9 @@ import { ProjectGetArtefactDestination, } from '@causa/workspace-core';
|
|
|
6
6
|
export class ProjectGetArtefactDestinationForCloudRun extends ProjectGetArtefactDestination {
|
|
7
7
|
async _call(context) {
|
|
8
8
|
const projectName = context.getOrThrow('project.name');
|
|
9
|
-
const dockerRepository = context
|
|
9
|
+
const dockerRepository = context
|
|
10
|
+
.asConfiguration()
|
|
11
|
+
.getOrThrow('google.cloudRun.dockerRepository');
|
|
10
12
|
return `${dockerRepository}/${projectName}:${this.tag}`;
|
|
11
13
|
}
|
|
12
14
|
_supports(context) {
|
|
@@ -13,9 +13,9 @@ export class GoogleSecretManagerService {
|
|
|
13
13
|
*/
|
|
14
14
|
client;
|
|
15
15
|
constructor(context) {
|
|
16
|
+
const conf = context.asConfiguration();
|
|
16
17
|
this.defaultProject =
|
|
17
|
-
|
|
18
|
-
context.get('google.project');
|
|
18
|
+
conf.get('google.secretManager.project') ?? conf.get('google.project');
|
|
19
19
|
this.client = new SecretManagerServiceClient();
|
|
20
20
|
}
|
|
21
21
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@causa/workspace-google",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "The Causa workspace module providing many functionalities related to GCP and its services.",
|
|
5
5
|
"repository": "github:causa-io/workspace-module-google",
|
|
6
6
|
"license": "ISC",
|
|
@@ -29,38 +29,39 @@
|
|
|
29
29
|
"test:cov": "npm run test -- --coverage"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@causa/cli": ">= 0.
|
|
33
|
-
"@causa/workspace": ">= 0.
|
|
34
|
-
"@causa/workspace-core": ">= 0.
|
|
32
|
+
"@causa/cli": ">= 0.4.0 < 1.0.0",
|
|
33
|
+
"@causa/workspace": ">= 0.12.0 < 1.0.0",
|
|
34
|
+
"@causa/workspace-core": ">= 0.8.0 < 1.0.0",
|
|
35
35
|
"@google-cloud/apikeys": "^0.2.2",
|
|
36
36
|
"@google-cloud/iam-credentials": "^2.0.4",
|
|
37
|
-
"@google-cloud/pubsub": "^3.7.
|
|
37
|
+
"@google-cloud/pubsub": "^3.7.3",
|
|
38
38
|
"@google-cloud/secret-manager": "^4.2.2",
|
|
39
39
|
"@google-cloud/service-usage": "^2.2.2",
|
|
40
|
-
"@google-cloud/spanner": "^6.
|
|
41
|
-
"@google-cloud/storage": "^6.
|
|
40
|
+
"@google-cloud/spanner": "^6.14.0",
|
|
41
|
+
"@google-cloud/storage": "^6.12.0",
|
|
42
|
+
"@grpc/grpc-js": "^1.8.20",
|
|
42
43
|
"class-validator": "^0.14.0",
|
|
43
|
-
"firebase": "^
|
|
44
|
-
"firebase-admin": "^11.
|
|
45
|
-
"globby": "^13.
|
|
46
|
-
"
|
|
47
|
-
"googleapis": "^118.0.0",
|
|
44
|
+
"firebase": "^10.1.0",
|
|
45
|
+
"firebase-admin": "^11.10.1",
|
|
46
|
+
"globby": "^13.2.2",
|
|
47
|
+
"googleapis": "^123.0.0",
|
|
48
48
|
"uuid": "^9.0.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@tsconfig/node18": "^2.0
|
|
52
|
-
"@types/jest": "^29.5.
|
|
53
|
-
"@types/node": "^18.
|
|
54
|
-
"@types/uuid": "^9.0.
|
|
51
|
+
"@tsconfig/node18": "^18.2.0",
|
|
52
|
+
"@types/jest": "^29.5.3",
|
|
53
|
+
"@types/node": "^18.17.1",
|
|
54
|
+
"@types/uuid": "^9.0.2",
|
|
55
|
+
"@typescript-eslint/eslint-plugin": "^6.2.0",
|
|
55
56
|
"copyfiles": "^2.4.1",
|
|
56
|
-
"eslint": "^8.
|
|
57
|
+
"eslint": "^8.45.0",
|
|
57
58
|
"eslint-config-prettier": "^8.8.0",
|
|
58
|
-
"eslint-plugin-prettier": "^
|
|
59
|
-
"jest": "^29.
|
|
60
|
-
"jest-extended": "^
|
|
59
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
60
|
+
"jest": "^29.6.1",
|
|
61
|
+
"jest-extended": "^4.0.0",
|
|
61
62
|
"rimraf": "^5.0.1",
|
|
62
|
-
"ts-jest": "^29.1.
|
|
63
|
+
"ts-jest": "^29.1.1",
|
|
63
64
|
"ts-node": "^10.9.1",
|
|
64
|
-
"typescript": "^5.1.
|
|
65
|
+
"typescript": "^5.1.6"
|
|
65
66
|
}
|
|
66
67
|
}
|