@pbvision/cloud-run-service 0.0.10 → 0.0.11

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/.env CHANGED
@@ -1,5 +1,6 @@
1
+ CLOUD_TASKS_EMULATOR_PORT=8123
1
2
  FIRESTORE_EMULATOR_HOST=[::1]:8404
2
- GCLOUD_PROJECT=xyz-dev
3
+ GCLOUD_PROJECT=localhost-emulator
3
4
  K_REVISION=unittest
4
5
  LOCAL_SERVICE_PORT_MAP='{}'
5
6
  NODE_ENV=localhost
@@ -21,7 +21,7 @@ jobs:
21
21
  shell: bash
22
22
  - name: 'Setup Firestore Emulator'
23
23
  run: |
24
- echo '{ "projects": { "default": "xyz-dev" } }' > ./.firebaserc
24
+ echo '{ "projects": { "default": "localhost-emulator" } }' > ./.firebaserc
25
25
  echo '{ "firestore": {} }' > ./firebase.json
26
26
  npm install -g firebase-tools
27
27
  firebase setup:emulators:firestore
package/README.md CHANGED
@@ -30,12 +30,17 @@
30
30
  - When running it unit tests, it should be`unittest`
31
31
  - If this is `unittest` then `isUnitTesting` will be true.
32
32
  - `NODE_ENV`
33
- - If this is `localhost` then `isLocalhost` will be true.
33
+ - If this is `localhost` then `isLocalhost` will be true. This is always
34
+ the case when running locally, even if we're connecting to real cloud resources (like Firestore or Task Queue).
35
+ - `isCloud` is the opposite of `isLocalhost`.
34
36
  - If this is `dev` then `isDev` will be true.
35
37
  - If this is `prod` then `isProd` will be true.
36
38
  - `REGION` - the region this service's cloud run is located in
37
39
  - `SERVICE` - the name of this service
38
40
  - Optional:
41
+ - Emulation (must provide all or none of these) for GCP services:
42
+ - `CLOUD_TASKS_EMULATOR_PORT`
43
+ - `FIRESTORE_EMULATOR_HOST`
39
44
  - `CLOUD_RUN_HOSTNAME_SUFFIX` - the hostname of our cloud run instances in
40
45
  this region, excluding the `SERVICE` name portion at the beginning. Only
41
46
  required if using the `callServiceAPI()` function.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pbvision/cloud-run-service",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "description": "fastify-firestore-service Web Framework on Cloud Run",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
package/src/main.js CHANGED
@@ -5,7 +5,7 @@ import { API } from '@pbvision/fastify-firestore-service'
5
5
  import { makePBVService } from './app.js'
6
6
  import { callServiceAPI } from './call-service-api.js'
7
7
  import { port } from './port.js'
8
- import { isLocalhost } from './utils.js'
8
+ import { isCloud, isLocalhost } from './utils.js'
9
9
 
10
10
  API.prototype.callServiceAPI = callServiceAPI
11
11
 
@@ -17,7 +17,6 @@ function verifyEnvironmentVariables () {
17
17
  'GCLOUD_PROJECT', 'K_REVISION', 'NODE_ENV', 'REGION', 'SERVICE']
18
18
  // istanbul ignore else
19
19
  if (isLocalhost) {
20
- assert(process.env.FIRESTORE_EMULATOR_HOST, 'use emulator on localhost')
21
20
  assert(['localhost', 'unittest'].indexOf(process.env.K_REVISION) !== -1,
22
21
  'K_REVISION must be "localhost" or "unittest" in this environment')
23
22
  } else {
@@ -27,8 +26,6 @@ function verifyEnvironmentVariables () {
27
26
  for (const k of requiredEnvKeys) {
28
27
  assert(process.env[k], `${k} environment variable must be set`)
29
28
  }
30
- assert(['localhost', 'dev', 'prod'].indexOf(process.env.NODE_ENV) !== -1,
31
- `invalid NODE_ENV: ${process.env.NODE_ENV}`)
32
29
  }
33
30
 
34
31
  function makeCustomizeLoggingOptionsFunction () {
@@ -67,7 +64,7 @@ export async function makeService (components) {
67
64
 
68
65
  // istanbul ignore next
69
66
  export async function runService (components) {
70
- if (!isLocalhost) {
67
+ if (isCloud) {
71
68
  // if the instance tells us it will shutdown, try to shut down gracefully (for
72
69
  // example flushing logs)
73
70
  process.on('SIGTERM', () => {
package/src/tasks.js CHANGED
@@ -1,8 +1,19 @@
1
1
  import { CloudTasksClient } from '@google-cloud/tasks'
2
+ import { credentials } from '@grpc/grpc-js'
2
3
 
3
- import { getServiceProtocolAndHost } from './utils.js'
4
+ import { getServiceProtocolAndHost, usingEmulator } from './utils.js'
4
5
 
5
- const tasksClient = new CloudTasksClient()
6
+ const tasksClient = (() => {
7
+ if (usingEmulator) {
8
+ return new CloudTasksClient({
9
+ port: process.env.CLOUD_TASKS_EMULATOR_PORT,
10
+ servicePath: 'localhost',
11
+ sslCreds: credentials.createInsecure()
12
+ })
13
+ }
14
+ // istanbul ignore next
15
+ return new CloudTasksClient()
16
+ })()
6
17
 
7
18
  /**
8
19
  * Add a Task to a Cloud Tasks queue.
package/src/utils.js CHANGED
@@ -2,15 +2,25 @@ import assert from 'node:assert'
2
2
 
3
3
  import { port as portForThisService } from './port.js'
4
4
 
5
+ // this refers to where the code is running; the database and other services
6
+ // we are connected to depends on GCLOUD_PROJECT
5
7
  export const isLocalhost = process.env.NODE_ENV === 'localhost'
8
+ export const isCloud = !isLocalhost
6
9
  export const isDev = process.env.NODE_ENV === 'dev'
7
10
  export const isProd = process.env.NODE_ENV === 'prod'
8
11
  // istanbul ignore next
9
- assert(isLocalhost || isDev || isProd, 'must be on localhost, dev or prod')
12
+ assert(isLocalhost || isDev || isProd,
13
+ 'invalid NODE_ENV: must be on localhost, dev or prod')
10
14
 
11
15
  export const isUnitTesting = process.env.K_REVISION === 'unittest'
12
16
  assert(!isUnitTesting || isLocalhost, 'must be on localhost if unit testing')
13
17
 
18
+ export const usingEmulator = !!process.env.FIRESTORE_EMULATOR_HOST
19
+ assert(!usingEmulator || process.env.CLOUD_TASKS_EMULATOR_PORT,
20
+ 'both firestore and tasks need to be either emulated or not')
21
+ assert(usingEmulator === (process.env.GCLOUD_PROJECT === 'localhost-emulator'),
22
+ 'when using the emulator, GCLOUD_PROJECT should be set to localhost-emulator')
23
+
14
24
  export function getServiceProtocolAndHost (serviceName) {
15
25
  const host = getServiceHost(serviceName)
16
26
  // istanbul ignore next
@@ -38,16 +38,16 @@ class TestTasks extends BaseTest {
38
38
  await promise
39
39
  }
40
40
  expect(CloudTasksClient.prototype.createTask).toHaveBeenCalledWith({
41
- // assuming values for project (xyz-dev) and region (us-central1) and
41
+ // assuming values for project (localhost-emulator) and region (us-central1) and
42
42
  // service (tbd)
43
- parent: 'projects/xyz-dev/locations/us-central1/queues/test-queue',
43
+ parent: 'projects/localhost-emulator/locations/us-central1/queues/test-queue',
44
44
  task: {
45
45
  httpRequest: {
46
46
  body: Buffer.from(JSON.stringify(args.payload)).toString('base64'),
47
47
  headers: { 'Content-Type': 'application/json' },
48
48
  httpMethod: 'POST',
49
49
  oidcToken: {
50
- serviceAccountEmail: 'cr-tbd@xyz-dev.iam.gserviceaccount.com'
50
+ serviceAccountEmail: 'cr-tbd@localhost-emulator.iam.gserviceaccount.com'
51
51
  },
52
52
  url: 'http://localhost:8888/test_queue'
53
53
  },
@@ -63,7 +63,7 @@ class TestTasks extends BaseTest {
63
63
  async testEnqueueTaskWithName () {
64
64
  await this.check(
65
65
  { name: 'x', payload: { x: 3 } },
66
- { name: 'projects/xyz-dev/locations/us-central1/queues/test-queue/tasks/x' })
66
+ { name: 'projects/localhost-emulator/locations/us-central1/queues/test-queue/tasks/x' })
67
67
  }
68
68
 
69
69
  async testEnqueueTaskWithNameThatWasRecentlyUsedNOTOkay () {
@@ -74,7 +74,7 @@ class TestTasks extends BaseTest {
74
74
  })
75
75
  await this.check(
76
76
  { name: 'x', payload: { x: 3 }, ignoreNameAlreadyUsedError: true },
77
- { name: 'projects/xyz-dev/locations/us-central1/queues/test-queue/tasks/x' })
77
+ { name: 'projects/localhost-emulator/locations/us-central1/queues/test-queue/tasks/x' })
78
78
  }
79
79
 
80
80
  async testEnqueueTaskWithNameThatWasRecentlyUsedAndThatsOkay () {
@@ -85,7 +85,7 @@ class TestTasks extends BaseTest {
85
85
  })
86
86
  await this.check(
87
87
  { name: 'x', payload: { x: 3 } },
88
- { name: 'projects/xyz-dev/locations/us-central1/queues/test-queue/tasks/x' },
88
+ { name: 'projects/localhost-emulator/locations/us-central1/queues/test-queue/tasks/x' },
89
89
  'task name already used recently: x')
90
90
  }
91
91
 
@@ -96,7 +96,7 @@ class TestTasks extends BaseTest {
96
96
  })
97
97
  await this.check(
98
98
  { name: 'x', payload: { x: 3 } },
99
- { name: 'projects/xyz-dev/locations/us-central1/queues/test-queue/tasks/x' },
99
+ { name: 'projects/localhost-emulator/locations/us-central1/queues/test-queue/tasks/x' },
100
100
  'not in right format')
101
101
  }
102
102
  }
@@ -2,7 +2,7 @@ import { jest } from '@jest/globals'
2
2
 
3
3
  import { BaseTest, runTests } from '../node_modules/@pbvision/fastify-firestore-service/test/base-test.js'
4
4
  import { port } from '../src/port.js'
5
- import { getServiceHost, isDev, isLocalhost, isProd } from '../src/utils.js'
5
+ import { getServiceHost, isCloud, isDev, isLocalhost, isProd, usingEmulator } from '../src/utils.js'
6
6
 
7
7
  const ORIG_ENV = process.env
8
8
 
@@ -21,8 +21,10 @@ class TestUtils extends BaseTest {
21
21
  expect(process.env.K_REVISION).toBe('unittest')
22
22
  expect(process.env.NODE_ENV).toBe('localhost')
23
23
  expect(isLocalhost).toBe(true)
24
+ expect(isCloud).toBe(false)
24
25
  expect(isProd).toBe(false)
25
26
  expect(isDev).toBe(false)
27
+ expect(usingEmulator).toBe(true)
26
28
  }
27
29
 
28
30
  testGetServiceHost () {