@causa/workspace-google 0.5.0 → 0.7.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 CHANGED
@@ -57,6 +57,40 @@ secrets:
57
57
 
58
58
  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.
59
59
 
60
+ A second secret backend, `google.accessToken`, does not fetch secrets from a source but rather returns a GCP access token, which can be used to access Google services:
61
+
62
+ ```yaml
63
+ secrets:
64
+ gcpAccessToken:
65
+ backend: google.accessToken
66
+ ```
67
+
68
+ ### Code generation
69
+
70
+ This module implements the `google.spanner` TypeScript decorator renderer, which can be used to add `@SpannerTable` and `@SpannerColumn` decorators to classes generated from events. Below is an example of how to enable it for a JSONSchema object:
71
+
72
+ ```yaml
73
+ title: MyClass
74
+ type: object
75
+ additionalProperties: false
76
+ causa:
77
+ # This must be set for the decorators to be added to both the class and its properties.
78
+ # The content of the object will be passed as the argument to the `@SpannerTable` decorator.
79
+ tsGoogleSpannerTable:
80
+ primaryKey: [id]
81
+ properties:
82
+ id:
83
+ type: string
84
+ format: uuid
85
+ # In most cases, the property-level `tsGoogleSpannerColumn` attribute does not need to be set. The decorator configuration will be automatically inferred.
86
+ # If needed, the content of `tsGoogleSpannerColumn` will be passed as the argument to the `@SpannerColumn` decorator.
87
+ # causa:
88
+ # tsGoogleSpannerColumn:
89
+ # isJson: false
90
+ myProperty:
91
+ type: string
92
+ ```
93
+
60
94
  ## 🔨 Custom `google` commands
61
95
 
62
96
  This modules adds a new command to the CLI: `cs google`. Here is the list of subcommands that are exposed.
@@ -0,0 +1,11 @@
1
+ import { ClassContext, ClassPropertyContext, TypeScriptDecorator, TypeScriptDecoratorsRenderer } from '@causa/workspace-typescript';
2
+ /**
3
+ * A {@link TypeScriptDecoratorsRenderer} that adds Google Spanner decorators from the Causa Google runtime.
4
+ *
5
+ * If an object schema is marked with the `tsGoogleSpannerTable` attribute, the `@SpannerTable` decorator is added to
6
+ * the class, and `@SpannerColumn` decorators are added to all its properties.
7
+ */
8
+ export declare class GoogleSpannerRenderer extends TypeScriptDecoratorsRenderer {
9
+ decoratorsForClass(context: ClassContext): TypeScriptDecorator[];
10
+ decoratorsForProperty(context: ClassPropertyContext): TypeScriptDecorator[];
11
+ }
@@ -0,0 +1,94 @@
1
+ import { TypeScriptDecoratorsRenderer, getSingleType, typeScriptSourceForObject, } from '@causa/workspace-typescript';
2
+ import { panic } from 'quicktype-core';
3
+ /**
4
+ * The name of the Causa attribute that should be present for a class to be decorated with Google Spanner decorators.
5
+ */
6
+ const GOOGLE_SPANNER_TABLE_ATTRIBUTE = 'tsGoogleSpannerTable';
7
+ /**
8
+ * The name of the Causa attribute that can be present on a class to only generate `@SpannerColumn` decorators for its
9
+ * properties, but not a `@SpannerTable` decorator for the class itself.
10
+ */
11
+ const GOOGLE_SPANNER_NESTED_TYPE_ATTRIBUTE = 'tsGoogleSpannerNestedType';
12
+ /**
13
+ * The name of the optional Causa attribute that can be present on an object property schema to specify options for the
14
+ * `@SpannerColumn` decorator.
15
+ */
16
+ const GOOGLE_SPANNER_COLUMN_ATTRIBUTE = 'tsGoogleSpannerColumn';
17
+ /**
18
+ * The name of the `decoratorOptions` key that can be used to specify the name of the property that should be used as
19
+ * the soft deletion column.
20
+ */
21
+ const GOOGLE_SPANNER_SOFT_DELETION_COLUMN_OPTION = 'googleSpannerSoftDeletionColumn';
22
+ /**
23
+ * The name of the Causa module for the TypeScript Google runtime.
24
+ */
25
+ const CAUSA_GOOGLE_MODULE = '@causa/runtime-google';
26
+ /**
27
+ * The list of options that can be passed to the `@SpannerColumn` decorator and that indicates that the JSONSchema
28
+ * specifies the type of the column. In this case, the renderer should not infer any type information.
29
+ */
30
+ const TYPE_INFO_COLUMN_ATTRIBUTE_NAMES = [
31
+ 'nestedType',
32
+ 'nullifyNested',
33
+ 'isBigInt',
34
+ 'isInt',
35
+ 'isPreciseDate',
36
+ 'isJson',
37
+ ];
38
+ /**
39
+ * A {@link TypeScriptDecoratorsRenderer} that adds Google Spanner decorators from the Causa Google runtime.
40
+ *
41
+ * If an object schema is marked with the `tsGoogleSpannerTable` attribute, the `@SpannerTable` decorator is added to
42
+ * the class, and `@SpannerColumn` decorators are added to all its properties.
43
+ */
44
+ export class GoogleSpannerRenderer extends TypeScriptDecoratorsRenderer {
45
+ decoratorsForClass(context) {
46
+ const tableAttribute = context.objectAttributes[GOOGLE_SPANNER_TABLE_ATTRIBUTE];
47
+ if (!tableAttribute) {
48
+ return [];
49
+ }
50
+ if (typeof tableAttribute !== 'object' ||
51
+ !('primaryKey' in tableAttribute) ||
52
+ !Array.isArray(tableAttribute.primaryKey)) {
53
+ panic(`Invalid ${GOOGLE_SPANNER_TABLE_ATTRIBUTE} attribute on ${context.classType.getNames()}`);
54
+ }
55
+ const optionsSource = typeScriptSourceForObject(tableAttribute);
56
+ const decorators = [];
57
+ this.addDecoratorToList(decorators, context, 'SpannerTable', CAUSA_GOOGLE_MODULE, ['@SpannerTable(', optionsSource, ')']);
58
+ return decorators;
59
+ }
60
+ decoratorsForProperty(context) {
61
+ if (!context.objectAttributes[GOOGLE_SPANNER_TABLE_ATTRIBUTE] &&
62
+ !context.objectAttributes[GOOGLE_SPANNER_NESTED_TYPE_ATTRIBUTE]) {
63
+ return [];
64
+ }
65
+ const rawColumnAttributes = context.propertyAttributes[GOOGLE_SPANNER_COLUMN_ATTRIBUTE] ?? {};
66
+ const columnAttributes = typeof rawColumnAttributes === 'object' ? rawColumnAttributes : {};
67
+ const softDeletionColumn = this.decoratorOptions[GOOGLE_SPANNER_SOFT_DELETION_COLUMN_OPTION];
68
+ if (softDeletionColumn && context.jsonName === softDeletionColumn) {
69
+ columnAttributes.softDelete = true;
70
+ }
71
+ if (!context.propertyAttributes.tsType) {
72
+ const singleTypeInfo = getSingleType(context.property.type);
73
+ const schemaOverridesTypeInfo = TYPE_INFO_COLUMN_ATTRIBUTE_NAMES.some((name) => name in columnAttributes);
74
+ if (!schemaOverridesTypeInfo && singleTypeInfo) {
75
+ switch (singleTypeInfo.type.kind) {
76
+ case 'class':
77
+ case 'object':
78
+ case 'map':
79
+ columnAttributes.isJson = true;
80
+ break;
81
+ case 'integer':
82
+ columnAttributes.isInt = true;
83
+ break;
84
+ }
85
+ }
86
+ }
87
+ const optionsSource = typeScriptSourceForObject(columnAttributes, {
88
+ encoder: (key, value) => key === 'nestedType' ? value : JSON.stringify(value),
89
+ });
90
+ const decorators = [];
91
+ this.addDecoratorToList(decorators, context, 'SpannerColumn', CAUSA_GOOGLE_MODULE, ['@SpannerColumn(', optionsSource, ')']);
92
+ return decorators;
93
+ }
94
+ }
@@ -0,0 +1 @@
1
+ export { GoogleSpannerRenderer } from './google-spanner-renderer.js';
@@ -0,0 +1 @@
1
+ export { GoogleSpannerRenderer } from './google-spanner-renderer.js';
@@ -22,9 +22,17 @@ export declare class EmulatorStartForSpanner extends EmulatorStart {
22
22
  * @returns The configuration for the Spanner emulator.
23
23
  */
24
24
  private startSpannerEmulator;
25
+ /**
26
+ * Creates the Spanner instance and databases within the emulator.
27
+ *
28
+ * @param context The {@link WorkspaceContext}.
29
+ * @returns The configuration for the created instance and databases.
30
+ */
31
+ private initializeEmulator;
25
32
  /**
26
33
  * Creates a local instance within the Spanner emulator.
27
34
  *
35
+ * @param spanner The {@link Spanner} client.
28
36
  * @param context The {@link WorkspaceContext}.
29
37
  * @returns The created Spanner {@link Instance} and the corresponding client configuration.
30
38
  */
@@ -27,10 +27,9 @@ export class EmulatorStartForSpanner extends EmulatorStart {
27
27
  return {};
28
28
  }
29
29
  const emulatorConf = await this.startSpannerEmulator(context);
30
- const { instance, instanceConf } = await this.createInstance(context);
31
- const databaseConf = await this.createDatabases(instance, context);
30
+ const instanceAndDatabaseConf = await this.initializeEmulator(context);
32
31
  context.logger.info('🗃️ Successfully initialized Spanner emulator.');
33
- return { ...emulatorConf, ...instanceConf, ...databaseConf };
32
+ return { ...emulatorConf, ...instanceAndDatabaseConf };
34
33
  }
35
34
  /**
36
35
  * Starts the Spanner emulator.
@@ -61,22 +60,35 @@ export class EmulatorStartForSpanner extends EmulatorStart {
61
60
  };
62
61
  }
63
62
  /**
64
- * Creates a local instance within the Spanner emulator.
63
+ * Creates the Spanner instance and databases within the emulator.
65
64
  *
66
65
  * @param context The {@link WorkspaceContext}.
67
- * @returns The created Spanner {@link Instance} and the corresponding client configuration.
66
+ * @returns The configuration for the created instance and databases.
68
67
  */
69
- async createInstance(context) {
70
- const instanceName = context
71
- .asConfiguration()
72
- .get('google.spanner.emulator.instanceName') ?? 'local';
73
- context.logger.info(`🗃️ Creating Spanner emulator instance '${instanceName}'.`);
68
+ async initializeEmulator(context) {
74
69
  const spanner = new Spanner({
75
70
  servicePath: '127.0.0.1',
76
71
  port: SPANNER_GRPC_PORT,
77
72
  projectId: getLocalGcpProject(context),
78
73
  sslCreds: credentials.createInsecure(),
79
74
  });
75
+ const { instance, instanceConf } = await this.createInstance(spanner, context);
76
+ const databaseConf = await this.createDatabases(instance, context);
77
+ spanner.close();
78
+ return { ...instanceConf, ...databaseConf };
79
+ }
80
+ /**
81
+ * Creates a local instance within the Spanner emulator.
82
+ *
83
+ * @param spanner The {@link Spanner} client.
84
+ * @param context The {@link WorkspaceContext}.
85
+ * @returns The created Spanner {@link Instance} and the corresponding client configuration.
86
+ */
87
+ async createInstance(spanner, context) {
88
+ const instanceName = context
89
+ .asConfiguration()
90
+ .get('google.spanner.emulator.instanceName') ?? 'local';
91
+ context.logger.info(`🗃️ Creating Spanner emulator instance '${instanceName}'.`);
80
92
  const [instance, operation] = await spanner.createInstance(instanceName, {
81
93
  config: 'emulator-config',
82
94
  displayName: instanceName,
@@ -98,8 +110,11 @@ export class EmulatorStartForSpanner extends EmulatorStart {
98
110
  context.logger.info(`🗃️ Creating Spanner emulator database '${database.id}'.`);
99
111
  // Discarding `DROP TABLE` statements as the emulator does not seem to handle them properly.
100
112
  const ddls = database.ddls.filter((statement) => !statement.toUpperCase().startsWith('DROP TABLE'));
101
- const operation = (await instance.createDatabase(database.id, { schema: ddls }))[1];
113
+ const [db, operation] = await instance.createDatabase(database.id, {
114
+ schema: ddls,
115
+ });
102
116
  await operation.promise();
117
+ await db.close();
103
118
  }));
104
119
  return databases.length === 0
105
120
  ? {}
@@ -21,7 +21,7 @@ const TOKEN_TTL = 3600;
21
21
  /**
22
22
  * Generates a new AppCheck token.
23
23
  */
24
- export let GoogleAppCheckGenerateToken = class GoogleAppCheckGenerateToken extends WorkspaceFunction {
24
+ let GoogleAppCheckGenerateToken = class GoogleAppCheckGenerateToken extends WorkspaceFunction {
25
25
  /**
26
26
  * The ID of the Firebase app for which the token will be generated.
27
27
  * If `undefined`, a Firebase app ID will be found in the configuration or using the API.
@@ -64,3 +64,4 @@ If the Firebase app ID is not specified, it will:
64
64
  outputFn: (token) => console.log(token),
65
65
  })
66
66
  ], GoogleAppCheckGenerateToken);
67
+ export { GoogleAppCheckGenerateToken };
@@ -27,7 +27,7 @@ const DEFAULT_FIREBASE_STORAGE_SECURITY_RULE_FILE = 'storage.rules';
27
27
  * Returns a configuration with `google.firebaseStorage.securityRuleFile` set, such that the function can be used as a
28
28
  * processor.
29
29
  */
30
- export let GoogleFirebaseStorageMergeRules = class GoogleFirebaseStorageMergeRules extends WorkspaceFunction {
30
+ let GoogleFirebaseStorageMergeRules = class GoogleFirebaseStorageMergeRules extends WorkspaceFunction {
31
31
  tearDown;
32
32
  async _call(context) {
33
33
  if (this.tearDown) {
@@ -69,3 +69,4 @@ Input files are looked for in the workspace using the globs defined in google.fi
69
69
  outputFn: ({ securityRuleFile }) => console.log(securityRuleFile),
70
70
  })
71
71
  ], GoogleFirebaseStorageMergeRules);
72
+ export { GoogleFirebaseStorageMergeRules };
@@ -27,7 +27,7 @@ const DEFAULT_FIRESTORE_SECURITY_RULE_FILE = 'firestore.rules';
27
27
  * Returns a configuration with `google.firestore.securityRuleFile` set, such that the function can be used as a
28
28
  * processor.
29
29
  */
30
- export let GoogleFirestoreMergeRules = class GoogleFirestoreMergeRules extends WorkspaceFunction {
30
+ let GoogleFirestoreMergeRules = class GoogleFirestoreMergeRules extends WorkspaceFunction {
31
31
  tearDown;
32
32
  async _call(context) {
33
33
  if (this.tearDown) {
@@ -69,3 +69,4 @@ Input files are looked for in the workspace using the globs defined in google.fi
69
69
  outputFn: ({ securityRuleFile }) => console.log(securityRuleFile),
70
70
  })
71
71
  ], GoogleFirestoreMergeRules);
72
+ export { GoogleFirestoreMergeRules };
@@ -21,7 +21,7 @@ import { GoogleIdentityPlatformGenerateCustomToken } from './generate-custom-tok
21
21
  * For this function to succeed, the `google.project` should be set, which usually means setting the environment in the
22
22
  * context. Also `google.firebase` children can be used to configure (and speed up) how tokens are generated.
23
23
  */
24
- export let GoogleIdentityPlatformGenerateToken = class GoogleIdentityPlatformGenerateToken extends WorkspaceFunction {
24
+ let GoogleIdentityPlatformGenerateToken = class GoogleIdentityPlatformGenerateToken extends WorkspaceFunction {
25
25
  /**
26
26
  * The ID of the user for which the token will be generated.
27
27
  */
@@ -71,3 +71,4 @@ Optional custom claims can be included in the signed token.`,
71
71
  outputFn: (token) => console.log(token),
72
72
  })
73
73
  ], GoogleIdentityPlatformGenerateToken);
74
+ export { GoogleIdentityPlatformGenerateToken };
@@ -20,7 +20,7 @@ const MAX_SERVICE_BATCH = 20;
20
20
  /**
21
21
  * Enables GCP services defined in `google.services` for the GCP project defined in `google.project`.
22
22
  */
23
- export let GoogleServicesEnable = class GoogleServicesEnable extends WorkspaceFunction {
23
+ let GoogleServicesEnable = class GoogleServicesEnable extends WorkspaceFunction {
24
24
  tearDown;
25
25
  async _call(context) {
26
26
  if (this.tearDown) {
@@ -72,3 +72,4 @@ They will be enabled in the 'google.project' GCP project.`,
72
72
  outputFn: ({ services }) => console.log(services.join('\n')),
73
73
  })
74
74
  ], GoogleServicesEnable);
75
+ export { GoogleServicesEnable };
@@ -8,7 +8,8 @@ import { GooglePubSubWriteTopics } from './google-pubsub/index.js';
8
8
  import { GoogleServicesEnable } from './google-services/index.js';
9
9
  import { GoogleSpannerListDatabases, GoogleSpannerWriteDatabases, } from './google-spanner/index.js';
10
10
  import { ProjectGetArtefactDestinationForCloudFunctions, ProjectGetArtefactDestinationForCloudRun, ProjectPushArtefactForCloudFunctions, } from './project/index.js';
11
- import { SecretFetchForGoogleSecretManager } from './secret/index.js';
11
+ import { SecretFetchForGoogleAccessToken, SecretFetchForGoogleSecretManager, } from './secret/index.js';
12
+ import { TypeScriptGetDecoratorRendererForGoogleSpanner } from './typescript/index.js';
12
13
  export function registerFunctions(context) {
13
- 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, SecretFetchForGoogleSecretManager);
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, TypeScriptGetDecoratorRendererForGoogleSpanner);
14
15
  }
@@ -0,0 +1,18 @@
1
+ import { SecretFetch, WorkspaceContext } from '@causa/workspace';
2
+ /**
3
+ * An error thrown when the auth client does not return a token.
4
+ */
5
+ export declare class AuthClientResponseError extends Error {
6
+ constructor();
7
+ }
8
+ /**
9
+ * Implements {@link SecretFetch} to retrieve a Google access token.
10
+ * This backend does not require any configuration, as it does not fetch a specific secret and can only return a single
11
+ * value. A Google access token can be used to authenticate with other Google services. The returned token is configured
12
+ * with the current user (or service account)'s credentials, and for the configured GCP project (if any).
13
+ * The backend ID is `google.accessToken`.
14
+ */
15
+ export declare class SecretFetchForGoogleAccessToken extends SecretFetch {
16
+ _call(context: WorkspaceContext): Promise<string>;
17
+ _supports(): boolean;
18
+ }
@@ -0,0 +1,30 @@
1
+ import { SecretFetch } from '@causa/workspace';
2
+ import { GoogleApisService } from '../../services/index.js';
3
+ /**
4
+ * An error thrown when the auth client does not return a token.
5
+ */
6
+ export class AuthClientResponseError extends Error {
7
+ constructor() {
8
+ super('Failed to retrieve the Google access token from the auth client response.');
9
+ }
10
+ }
11
+ /**
12
+ * Implements {@link SecretFetch} to retrieve a Google access token.
13
+ * This backend does not require any configuration, as it does not fetch a specific secret and can only return a single
14
+ * value. A Google access token can be used to authenticate with other Google services. The returned token is configured
15
+ * with the current user (or service account)'s credentials, and for the configured GCP project (if any).
16
+ * The backend ID is `google.accessToken`.
17
+ */
18
+ export class SecretFetchForGoogleAccessToken extends SecretFetch {
19
+ async _call(context) {
20
+ const authClient = await context.service(GoogleApisService).getAuthClient();
21
+ const { token } = await authClient.getAccessToken();
22
+ if (!token) {
23
+ throw new AuthClientResponseError();
24
+ }
25
+ return token;
26
+ }
27
+ _supports() {
28
+ return this.backend === 'google.accessToken';
29
+ }
30
+ }
@@ -1 +1,2 @@
1
+ export { SecretFetchForGoogleAccessToken } from './fetch-access-token.js';
1
2
  export { SecretFetchForGoogleSecretManager } from './fetch-secret-manager.js';
@@ -1 +1,2 @@
1
+ export { SecretFetchForGoogleAccessToken } from './fetch-access-token.js';
1
2
  export { SecretFetchForGoogleSecretManager } from './fetch-secret-manager.js';
@@ -0,0 +1,10 @@
1
+ import { WorkspaceContext } from '@causa/workspace';
2
+ import { TypeScriptDecoratorsRenderer, TypeScriptGetDecoratorRenderer } from '@causa/workspace-typescript';
3
+ /**
4
+ * Implements {@link TypeScriptGetDecoratorRenderer} for the {@link GoogleSpannerRenderer}.
5
+ * The configuration name for the renderer is `google.spanner`.
6
+ */
7
+ export declare class TypeScriptGetDecoratorRendererForGoogleSpanner extends TypeScriptGetDecoratorRenderer {
8
+ _call(): new (...args: any[]) => TypeScriptDecoratorsRenderer;
9
+ _supports(context: WorkspaceContext): boolean;
10
+ }
@@ -0,0 +1,21 @@
1
+ import { TypeScriptGetDecoratorRenderer, } from '@causa/workspace-typescript';
2
+ import { GoogleSpannerRenderer } from '../../code-generation/index.js';
3
+ /**
4
+ * Implements {@link TypeScriptGetDecoratorRenderer} for the {@link GoogleSpannerRenderer}.
5
+ * The configuration name for the renderer is `google.spanner`.
6
+ */
7
+ export class TypeScriptGetDecoratorRendererForGoogleSpanner extends TypeScriptGetDecoratorRenderer {
8
+ _call() {
9
+ return GoogleSpannerRenderer;
10
+ }
11
+ _supports(context) {
12
+ if (context.get('project.language') !== 'typescript') {
13
+ return false;
14
+ }
15
+ const decoratorRenderers = context
16
+ .asConfiguration()
17
+ .get('typescript.codeGeneration.decoratorRenderers') ?? [];
18
+ return (decoratorRenderers.length === 0 ||
19
+ decoratorRenderers.includes('google.spanner'));
20
+ }
21
+ }
@@ -0,0 +1 @@
1
+ export { TypeScriptGetDecoratorRendererForGoogleSpanner } from './get-decorator-renderer-google-spanner.js';
@@ -0,0 +1 @@
1
+ export { TypeScriptGetDecoratorRendererForGoogleSpanner } from './get-decorator-renderer-google-spanner.js';
@@ -1,4 +1,5 @@
1
1
  import { WorkspaceContext } from '@causa/workspace';
2
+ import { AuthClient } from 'google-auth-library';
2
3
  import { GoogleApis } from 'googleapis';
3
4
  import { ApiClient, OptionsOfApiClient } from './google-apis.types.js';
4
5
  /**
@@ -9,7 +10,7 @@ export declare class GoogleApisService {
9
10
  /**
10
11
  * The GCP project ID read from the {@link WorkspaceContext} configuration.
11
12
  */
12
- readonly projectId: string;
13
+ readonly projectId: string | undefined;
13
14
  constructor(context: WorkspaceContext);
14
15
  /**
15
16
  * The promise returning the `JSONClient` configured with the {@link GoogleApisService.projectId}.
@@ -20,7 +21,7 @@ export declare class GoogleApisService {
20
21
  *
21
22
  * @returns The auth client.
22
23
  */
23
- getAuthClient(): Promise<any>;
24
+ getAuthClient(): Promise<AuthClient>;
24
25
  /**
25
26
  * Creates a new client for one of Google's APIs.
26
27
  * Authentication is automatically configured.
@@ -9,8 +9,9 @@ export class GoogleApisService {
9
9
  */
10
10
  projectId;
11
11
  constructor(context) {
12
- const googleConf = context.asConfiguration();
13
- this.projectId = googleConf.getOrThrow('google.project');
12
+ this.projectId = context
13
+ .asConfiguration()
14
+ .get('google.project');
14
15
  }
15
16
  /**
16
17
  * The promise returning the `JSONClient` configured with the {@link GoogleApisService.projectId}.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@causa/workspace-google",
3
- "version": "0.5.0",
3
+ "version": "0.7.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,43 +29,46 @@
29
29
  "test:cov": "npm run test -- --coverage"
30
30
  },
31
31
  "dependencies": {
32
- "@causa/cli": ">= 0.4.0 < 1.0.0",
33
- "@causa/workspace": ">= 0.12.0 < 1.0.0",
34
- "@causa/workspace-core": ">= 0.14.1 < 1.0.0",
35
- "@google-cloud/apikeys": "^0.2.2",
36
- "@google-cloud/bigquery": "^7.1.1",
37
- "@google-cloud/iam-credentials": "^2.0.4",
38
- "@google-cloud/pubsub": "^4.0.0",
39
- "@google-cloud/resource-manager": "^4.3.0",
40
- "@google-cloud/run": "^0.6.0",
41
- "@google-cloud/secret-manager": "^4.2.2",
42
- "@google-cloud/service-usage": "^2.2.2",
43
- "@google-cloud/spanner": "^6.15.0",
44
- "@google-cloud/storage": "^7.0.0",
45
- "@grpc/grpc-js": "~1.8.21",
32
+ "@causa/cli": ">= 0.4.1 < 1.0.0",
33
+ "@causa/workspace": ">= 0.12.1 < 1.0.0",
34
+ "@causa/workspace-core": ">= 0.19.1 < 1.0.0",
35
+ "@causa/workspace-typescript": ">= 0.7.0",
36
+ "@google-cloud/apikeys": "^1.0.1",
37
+ "@google-cloud/bigquery": "^7.3.0",
38
+ "@google-cloud/iam-credentials": "^3.0.1",
39
+ "@google-cloud/pubsub": "^4.0.6",
40
+ "@google-cloud/resource-manager": "^5.0.1",
41
+ "@google-cloud/run": "^1.0.2",
42
+ "@google-cloud/secret-manager": "^5.0.1",
43
+ "@google-cloud/service-usage": "^3.1.0",
44
+ "@google-cloud/spanner": "^7.0.0",
45
+ "@google-cloud/storage": "^7.5.0",
46
+ "@grpc/grpc-js": "^1.9.9",
46
47
  "class-validator": "^0.14.0",
47
- "firebase": "^10.1.0",
48
- "firebase-admin": "^11.10.1",
48
+ "firebase": "^10.5.2",
49
+ "firebase-admin": "^11.11.0",
49
50
  "globby": "^13.2.2",
50
- "googleapis": "^123.0.0",
51
- "pino": "^8.15.0",
52
- "uuid": "^9.0.0"
51
+ "google-auth-library": "^9.2.0",
52
+ "googleapis": "^128.0.0",
53
+ "pino": "^8.16.1",
54
+ "quicktype-core": "^23.0.77",
55
+ "uuid": "^9.0.1"
53
56
  },
54
57
  "devDependencies": {
55
- "@tsconfig/node18": "^18.2.0",
56
- "@types/jest": "^29.5.3",
57
- "@types/node": "^18.17.2",
58
- "@types/uuid": "^9.0.2",
59
- "@typescript-eslint/eslint-plugin": "^6.2.1",
58
+ "@tsconfig/node18": "^18.2.2",
59
+ "@types/jest": "^29.5.7",
60
+ "@types/node": "^18.18.8",
61
+ "@types/uuid": "^9.0.6",
62
+ "@typescript-eslint/eslint-plugin": "^6.9.1",
60
63
  "copyfiles": "^2.4.1",
61
- "eslint": "^8.46.0",
62
- "eslint-config-prettier": "^8.10.0",
63
- "eslint-plugin-prettier": "^5.0.0",
64
- "jest": "^29.6.2",
65
- "jest-extended": "^4.0.1",
66
- "rimraf": "^5.0.1",
64
+ "eslint": "^8.52.0",
65
+ "eslint-config-prettier": "^9.0.0",
66
+ "eslint-plugin-prettier": "^5.0.1",
67
+ "jest": "^29.7.0",
68
+ "jest-extended": "^4.0.2",
69
+ "rimraf": "^5.0.5",
67
70
  "ts-jest": "^29.1.1",
68
71
  "ts-node": "^10.9.1",
69
- "typescript": "^5.1.6"
72
+ "typescript": "^5.2.2"
70
73
  }
71
74
  }