@causa/workspace-google 0.5.0 → 0.6.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 +8 -0
- package/dist/functions/emulator/start-spanner.d.ts +8 -0
- package/dist/functions/emulator/start-spanner.js +26 -11
- package/dist/functions/google-app-check/generate-token.js +2 -1
- package/dist/functions/google-firebase-storage/merge-rules.js +2 -1
- package/dist/functions/google-firestore/merge-rules.js +2 -1
- package/dist/functions/google-identity-platform/generate-token.js +2 -1
- package/dist/functions/google-services/enable.js +2 -1
- package/dist/functions/index.js +2 -2
- package/dist/functions/secret/fetch-access-token.d.ts +18 -0
- package/dist/functions/secret/fetch-access-token.js +30 -0
- package/dist/functions/secret/index.d.ts +1 -0
- package/dist/functions/secret/index.js +1 -0
- package/dist/services/google-apis.d.ts +3 -2
- package/dist/services/google-apis.js +3 -2
- package/package.json +29 -28
package/README.md
CHANGED
|
@@ -57,6 +57,14 @@ 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
|
+
|
|
60
68
|
## 🔨 Custom `google` commands
|
|
61
69
|
|
|
62
70
|
This modules adds a new command to the CLI: `cs google`. Here is the list of subcommands that are exposed.
|
|
@@ -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
|
|
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, ...
|
|
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
|
|
63
|
+
* Creates the Spanner instance and databases within the emulator.
|
|
65
64
|
*
|
|
66
65
|
* @param context The {@link WorkspaceContext}.
|
|
67
|
-
* @returns The
|
|
66
|
+
* @returns The configuration for the created instance and databases.
|
|
68
67
|
*/
|
|
69
|
-
async
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 };
|
package/dist/functions/index.js
CHANGED
|
@@ -8,7 +8,7 @@ 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
12
|
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);
|
|
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, SecretFetchForGoogleAccessToken, SecretFetchForGoogleSecretManager);
|
|
14
14
|
}
|
|
@@ -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,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<
|
|
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
|
-
|
|
13
|
-
|
|
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.
|
|
3
|
+
"version": "0.6.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",
|
|
@@ -31,41 +31,42 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@causa/cli": ">= 0.4.0 < 1.0.0",
|
|
33
33
|
"@causa/workspace": ">= 0.12.0 < 1.0.0",
|
|
34
|
-
"@causa/workspace-core": ">= 0.
|
|
35
|
-
"@google-cloud/apikeys": "^0.
|
|
36
|
-
"@google-cloud/bigquery": "^7.
|
|
37
|
-
"@google-cloud/iam-credentials": "^
|
|
38
|
-
"@google-cloud/pubsub": "^4.0.
|
|
39
|
-
"@google-cloud/resource-manager": "^
|
|
40
|
-
"@google-cloud/run": "^0.
|
|
41
|
-
"@google-cloud/secret-manager": "^
|
|
42
|
-
"@google-cloud/service-usage": "^
|
|
43
|
-
"@google-cloud/spanner": "^
|
|
44
|
-
"@google-cloud/storage": "^7.
|
|
45
|
-
"@grpc/grpc-js": "
|
|
34
|
+
"@causa/workspace-core": ">= 0.16.0 < 1.0.0",
|
|
35
|
+
"@google-cloud/apikeys": "^1.0.1",
|
|
36
|
+
"@google-cloud/bigquery": "^7.3.0",
|
|
37
|
+
"@google-cloud/iam-credentials": "^3.0.1",
|
|
38
|
+
"@google-cloud/pubsub": "^4.0.6",
|
|
39
|
+
"@google-cloud/resource-manager": "^5.0.1",
|
|
40
|
+
"@google-cloud/run": "^1.0.1",
|
|
41
|
+
"@google-cloud/secret-manager": "^5.0.1",
|
|
42
|
+
"@google-cloud/service-usage": "^3.1.0",
|
|
43
|
+
"@google-cloud/spanner": "^7.0.0",
|
|
44
|
+
"@google-cloud/storage": "^7.1.0",
|
|
45
|
+
"@grpc/grpc-js": "^1.9.4",
|
|
46
46
|
"class-validator": "^0.14.0",
|
|
47
|
-
"firebase": "^10.
|
|
48
|
-
"firebase-admin": "^11.
|
|
47
|
+
"firebase": "^10.4.0",
|
|
48
|
+
"firebase-admin": "^11.11.0",
|
|
49
49
|
"globby": "^13.2.2",
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
50
|
+
"google-auth-library": "^9.0.0",
|
|
51
|
+
"googleapis": "^126.0.1",
|
|
52
|
+
"pino": "^8.15.1",
|
|
53
|
+
"uuid": "^9.0.1"
|
|
53
54
|
},
|
|
54
55
|
"devDependencies": {
|
|
55
|
-
"@tsconfig/node18": "^18.2.
|
|
56
|
-
"@types/jest": "^29.5.
|
|
57
|
-
"@types/node": "^18.
|
|
58
|
-
"@types/uuid": "^9.0.
|
|
59
|
-
"@typescript-eslint/eslint-plugin": "^6.
|
|
56
|
+
"@tsconfig/node18": "^18.2.2",
|
|
57
|
+
"@types/jest": "^29.5.5",
|
|
58
|
+
"@types/node": "^18.18.0",
|
|
59
|
+
"@types/uuid": "^9.0.4",
|
|
60
|
+
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
|
60
61
|
"copyfiles": "^2.4.1",
|
|
61
|
-
"eslint": "^8.
|
|
62
|
-
"eslint-config-prettier": "^
|
|
62
|
+
"eslint": "^8.50.0",
|
|
63
|
+
"eslint-config-prettier": "^9.0.0",
|
|
63
64
|
"eslint-plugin-prettier": "^5.0.0",
|
|
64
|
-
"jest": "^29.
|
|
65
|
+
"jest": "^29.7.0",
|
|
65
66
|
"jest-extended": "^4.0.1",
|
|
66
|
-
"rimraf": "^5.0.
|
|
67
|
+
"rimraf": "^5.0.5",
|
|
67
68
|
"ts-jest": "^29.1.1",
|
|
68
69
|
"ts-node": "^10.9.1",
|
|
69
|
-
"typescript": "^5.
|
|
70
|
+
"typescript": "^5.2.2"
|
|
70
71
|
}
|
|
71
72
|
}
|