opticedge-cloud-utils 1.0.5 → 1.0.7
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/.eslintignore +2 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/utils/env.d.ts +1 -0
- package/dist/utils/env.js +10 -0
- package/dist/utils/env.test.d.ts +1 -0
- package/dist/utils/env.test.js +14 -0
- package/dist/utils/task.d.ts +1 -0
- package/dist/utils/task.js +30 -0
- package/dist/utils/task.test.d.ts +1 -0
- package/dist/utils/task.test.js +54 -0
- package/package.json +2 -1
- package/src/index.ts +3 -1
- package/src/utils/env.test.ts +14 -0
- package/src/utils/env.ts +7 -0
- package/src/utils/task.test.ts +94 -0
- package/src/utils/task.ts +39 -0
package/.eslintignore
ADDED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -15,5 +15,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./auth/verify"), exports);
|
|
18
|
-
__exportStar(require("./utils/secrets"), exports);
|
|
19
18
|
__exportStar(require("./db/mongo"), exports);
|
|
19
|
+
__exportStar(require("./utils/env"), exports);
|
|
20
|
+
__exportStar(require("./utils/secrets"), exports);
|
|
21
|
+
__exportStar(require("./utils/task"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getEnv(name: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
// src/utils/env.test.ts
|
|
4
|
+
const env_1 = require("./env");
|
|
5
|
+
describe('getEnv', () => {
|
|
6
|
+
it('should return the value of an existing env var', () => {
|
|
7
|
+
process.env.TEST_KEY = 'test-value';
|
|
8
|
+
expect((0, env_1.getEnv)('TEST_KEY')).toBe('test-value');
|
|
9
|
+
});
|
|
10
|
+
it('should throw an error if the env var is not set', () => {
|
|
11
|
+
delete process.env.MISSING_KEY;
|
|
12
|
+
expect(() => (0, env_1.getEnv)('MISSING_KEY')).toThrow('Missing env var: MISSING_KEY');
|
|
13
|
+
});
|
|
14
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function createTask(projectId: string, region: string, queueId: string, data: unknown, serviceAccount: string, audience: string): Promise<string>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createTask = createTask;
|
|
4
|
+
const tasks_1 = require("@google-cloud/tasks");
|
|
5
|
+
const tasksClient = new tasks_1.CloudTasksClient();
|
|
6
|
+
async function createTask(projectId, region, queueId, data, serviceAccount, audience) {
|
|
7
|
+
if (!projectId || !region || !queueId || !serviceAccount || !audience) {
|
|
8
|
+
throw new Error('Missing required parameters for Cloud Tasks setup');
|
|
9
|
+
}
|
|
10
|
+
const parent = tasksClient.queuePath(projectId, region, queueId);
|
|
11
|
+
const task = {
|
|
12
|
+
httpRequest: {
|
|
13
|
+
httpMethod: tasks_1.protos.google.cloud.tasks.v2.HttpMethod.POST,
|
|
14
|
+
url: audience,
|
|
15
|
+
headers: {
|
|
16
|
+
'Content-Type': 'application/json'
|
|
17
|
+
},
|
|
18
|
+
body: Buffer.from(JSON.stringify(data)).toString('base64'),
|
|
19
|
+
oidcToken: {
|
|
20
|
+
serviceAccountEmail: serviceAccount,
|
|
21
|
+
audience
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const [response] = await tasksClient.createTask({ parent, task });
|
|
26
|
+
if (!response.name) {
|
|
27
|
+
throw new Error('Failed to create task: no name returned');
|
|
28
|
+
}
|
|
29
|
+
return response.name;
|
|
30
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const mockCreateTask = jest.fn();
|
|
4
|
+
const mockQueuePath = jest.fn((projectId, region, queueId) => `projects/${projectId}/locations/${region}/queues/${queueId}`);
|
|
5
|
+
jest.mock('@google-cloud/tasks', () => {
|
|
6
|
+
return {
|
|
7
|
+
CloudTasksClient: jest.fn(() => ({
|
|
8
|
+
createTask: mockCreateTask,
|
|
9
|
+
queuePath: mockQueuePath
|
|
10
|
+
})),
|
|
11
|
+
protos: {
|
|
12
|
+
google: {
|
|
13
|
+
cloud: {
|
|
14
|
+
tasks: {
|
|
15
|
+
v2: {
|
|
16
|
+
HttpMethod: {
|
|
17
|
+
POST: 'POST'
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
const task_1 = require("./task");
|
|
27
|
+
describe('createTask', () => {
|
|
28
|
+
beforeEach(() => {
|
|
29
|
+
mockCreateTask.mockReset();
|
|
30
|
+
});
|
|
31
|
+
it('throws error if any required parameter is missing', async () => {
|
|
32
|
+
// Missing projectId
|
|
33
|
+
await expect((0, task_1.createTask)('', 'region', 'queue', {}, 'serviceAccount', 'audience')).rejects.toThrow('Missing required parameters for Cloud Tasks setup');
|
|
34
|
+
// Missing region
|
|
35
|
+
await expect((0, task_1.createTask)('project', '', 'queue', {}, 'serviceAccount', 'audience')).rejects.toThrow('Missing required parameters for Cloud Tasks setup');
|
|
36
|
+
// Missing queueId
|
|
37
|
+
await expect((0, task_1.createTask)('project', 'region', '', {}, 'serviceAccount', 'audience')).rejects.toThrow('Missing required parameters for Cloud Tasks setup');
|
|
38
|
+
// Missing serviceAccount
|
|
39
|
+
await expect((0, task_1.createTask)('project', 'region', 'queue', {}, '', 'audience')).rejects.toThrow('Missing required parameters for Cloud Tasks setup');
|
|
40
|
+
// Missing audience
|
|
41
|
+
await expect((0, task_1.createTask)('project', 'region', 'queue', {}, 'serviceAccount', '')).rejects.toThrow('Missing required parameters for Cloud Tasks setup');
|
|
42
|
+
});
|
|
43
|
+
it('should create a task and return task name', async () => {
|
|
44
|
+
const mockTaskName = 'projects/test-project/locations/us-central1/queues/test-queue/tasks/task-123';
|
|
45
|
+
mockCreateTask.mockResolvedValue([{ name: mockTaskName }]);
|
|
46
|
+
const result = await (0, task_1.createTask)('test-project', 'us-central1', 'test-queue', { test: 'data' }, 'test-sa@test.iam.gserviceaccount.com', 'https://run-url');
|
|
47
|
+
expect(result).toBe(mockTaskName);
|
|
48
|
+
expect(mockCreateTask).toHaveBeenCalledTimes(1);
|
|
49
|
+
});
|
|
50
|
+
it('should throw error if task name is missing', async () => {
|
|
51
|
+
mockCreateTask.mockResolvedValue([{}]); // Simulate missing name
|
|
52
|
+
await expect((0, task_1.createTask)('test-project', 'us-central1', 'test-queue', { foo: 'bar' }, 'test@project.iam.gserviceaccount.com', 'https://example.com')).rejects.toThrow('Failed to create task: no name returned');
|
|
53
|
+
});
|
|
54
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opticedge-cloud-utils",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "Common utilities for cloud functions",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@google-cloud/secret-manager": "^6.0.1",
|
|
19
|
+
"@google-cloud/tasks": "^6.1.0",
|
|
19
20
|
"google-auth-library": "^9.15.1",
|
|
20
21
|
"mongodb": "^6.16.0"
|
|
21
22
|
},
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// src/utils/env.test.ts
|
|
2
|
+
import { getEnv } from './env'
|
|
3
|
+
|
|
4
|
+
describe('getEnv', () => {
|
|
5
|
+
it('should return the value of an existing env var', () => {
|
|
6
|
+
process.env.TEST_KEY = 'test-value'
|
|
7
|
+
expect(getEnv('TEST_KEY')).toBe('test-value')
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
it('should throw an error if the env var is not set', () => {
|
|
11
|
+
delete process.env.MISSING_KEY
|
|
12
|
+
expect(() => getEnv('MISSING_KEY')).toThrow('Missing env var: MISSING_KEY')
|
|
13
|
+
})
|
|
14
|
+
})
|
package/src/utils/env.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const mockCreateTask = jest.fn()
|
|
2
|
+
const mockQueuePath = jest.fn(
|
|
3
|
+
(projectId, region, queueId) => `projects/${projectId}/locations/${region}/queues/${queueId}`
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
jest.mock('@google-cloud/tasks', () => {
|
|
7
|
+
return {
|
|
8
|
+
CloudTasksClient: jest.fn(() => ({
|
|
9
|
+
createTask: mockCreateTask,
|
|
10
|
+
queuePath: mockQueuePath
|
|
11
|
+
})),
|
|
12
|
+
protos: {
|
|
13
|
+
google: {
|
|
14
|
+
cloud: {
|
|
15
|
+
tasks: {
|
|
16
|
+
v2: {
|
|
17
|
+
HttpMethod: {
|
|
18
|
+
POST: 'POST'
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
import { createTask } from './task'
|
|
29
|
+
|
|
30
|
+
describe('createTask', () => {
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
mockCreateTask.mockReset()
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('throws error if any required parameter is missing', async () => {
|
|
36
|
+
// Missing projectId
|
|
37
|
+
await expect(
|
|
38
|
+
createTask('', 'region', 'queue', {}, 'serviceAccount', 'audience')
|
|
39
|
+
).rejects.toThrow('Missing required parameters for Cloud Tasks setup')
|
|
40
|
+
|
|
41
|
+
// Missing region
|
|
42
|
+
await expect(
|
|
43
|
+
createTask('project', '', 'queue', {}, 'serviceAccount', 'audience')
|
|
44
|
+
).rejects.toThrow('Missing required parameters for Cloud Tasks setup')
|
|
45
|
+
|
|
46
|
+
// Missing queueId
|
|
47
|
+
await expect(
|
|
48
|
+
createTask('project', 'region', '', {}, 'serviceAccount', 'audience')
|
|
49
|
+
).rejects.toThrow('Missing required parameters for Cloud Tasks setup')
|
|
50
|
+
|
|
51
|
+
// Missing serviceAccount
|
|
52
|
+
await expect(createTask('project', 'region', 'queue', {}, '', 'audience')).rejects.toThrow(
|
|
53
|
+
'Missing required parameters for Cloud Tasks setup'
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
// Missing audience
|
|
57
|
+
await expect(
|
|
58
|
+
createTask('project', 'region', 'queue', {}, 'serviceAccount', '')
|
|
59
|
+
).rejects.toThrow('Missing required parameters for Cloud Tasks setup')
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('should create a task and return task name', async () => {
|
|
63
|
+
const mockTaskName =
|
|
64
|
+
'projects/test-project/locations/us-central1/queues/test-queue/tasks/task-123'
|
|
65
|
+
mockCreateTask.mockResolvedValue([{ name: mockTaskName }])
|
|
66
|
+
|
|
67
|
+
const result = await createTask(
|
|
68
|
+
'test-project',
|
|
69
|
+
'us-central1',
|
|
70
|
+
'test-queue',
|
|
71
|
+
{ test: 'data' },
|
|
72
|
+
'test-sa@test.iam.gserviceaccount.com',
|
|
73
|
+
'https://run-url'
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
expect(result).toBe(mockTaskName)
|
|
77
|
+
expect(mockCreateTask).toHaveBeenCalledTimes(1)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it('should throw error if task name is missing', async () => {
|
|
81
|
+
mockCreateTask.mockResolvedValue([{}]) // Simulate missing name
|
|
82
|
+
|
|
83
|
+
await expect(
|
|
84
|
+
createTask(
|
|
85
|
+
'test-project',
|
|
86
|
+
'us-central1',
|
|
87
|
+
'test-queue',
|
|
88
|
+
{ foo: 'bar' },
|
|
89
|
+
'test@project.iam.gserviceaccount.com',
|
|
90
|
+
'https://example.com'
|
|
91
|
+
)
|
|
92
|
+
).rejects.toThrow('Failed to create task: no name returned')
|
|
93
|
+
})
|
|
94
|
+
})
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { CloudTasksClient, protos } from '@google-cloud/tasks'
|
|
2
|
+
|
|
3
|
+
const tasksClient = new CloudTasksClient()
|
|
4
|
+
|
|
5
|
+
export async function createTask(
|
|
6
|
+
projectId: string,
|
|
7
|
+
region: string,
|
|
8
|
+
queueId: string,
|
|
9
|
+
data: unknown,
|
|
10
|
+
serviceAccount: string,
|
|
11
|
+
audience: string
|
|
12
|
+
): Promise<string> {
|
|
13
|
+
if (!projectId || !region || !queueId || !serviceAccount || !audience) {
|
|
14
|
+
throw new Error('Missing required parameters for Cloud Tasks setup')
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const parent = tasksClient.queuePath(projectId, region, queueId)
|
|
18
|
+
|
|
19
|
+
const task: protos.google.cloud.tasks.v2.ITask = {
|
|
20
|
+
httpRequest: {
|
|
21
|
+
httpMethod: protos.google.cloud.tasks.v2.HttpMethod.POST,
|
|
22
|
+
url: audience,
|
|
23
|
+
headers: {
|
|
24
|
+
'Content-Type': 'application/json'
|
|
25
|
+
},
|
|
26
|
+
body: Buffer.from(JSON.stringify(data)).toString('base64'),
|
|
27
|
+
oidcToken: {
|
|
28
|
+
serviceAccountEmail: serviceAccount,
|
|
29
|
+
audience
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const [response] = await tasksClient.createTask({ parent, task })
|
|
35
|
+
if (!response.name) {
|
|
36
|
+
throw new Error('Failed to create task: no name returned')
|
|
37
|
+
}
|
|
38
|
+
return response.name
|
|
39
|
+
}
|