@bopen-io/messagebox-server 1.1.5 → 1.2.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.
Files changed (113) hide show
  1. package/.dockerignore +11 -0
  2. package/.env.example +11 -0
  3. package/.eslintignore +2 -0
  4. package/.gcloudignore +17 -0
  5. package/.gitattributes +2 -0
  6. package/.github/workflows/build-and-push.yml +51 -0
  7. package/.github/workflows/deploy.yaml.example +64 -0
  8. package/.github/workflows/image.yaml +66 -0
  9. package/.vscode/launch.json +67 -0
  10. package/AGENTS.md +92 -0
  11. package/BASELINE.md +55 -0
  12. package/DEPLOYING.md +120 -0
  13. package/Dockerfile +63 -0
  14. package/docker-compose.yml +64 -0
  15. package/jest.config.integration.ts +26 -0
  16. package/jest.config.mjs +42 -0
  17. package/jest.config.ts +35 -0
  18. package/jest.setup.mjs +18 -0
  19. package/nginx.conf +36 -0
  20. package/package.json +65 -51
  21. package/scripts/build.js +19 -0
  22. package/scripts/mkenv.sh +31 -0
  23. package/scripts/start.sh +16 -0
  24. package/src/__tests/compose.test.ts +30 -0
  25. package/src/app.ts +210 -0
  26. package/src/compose.ts +286 -0
  27. package/src/config/firebase.ts +183 -0
  28. package/src/context.ts +49 -0
  29. package/src/index.ts +375 -0
  30. package/src/routes/__tests/acknowledgeMessage.test.ts +158 -0
  31. package/src/routes/__tests/listMessages.test.ts +240 -0
  32. package/src/routes/__tests/sendMessage.test.ts +362 -0
  33. package/src/routes/acknowledgeMessage.ts +153 -0
  34. package/src/routes/index.ts +17 -0
  35. package/src/routes/listDevices.ts +80 -0
  36. package/src/routes/listMessages.ts +195 -0
  37. package/src/routes/permissions/getPermission.ts +152 -0
  38. package/src/routes/permissions/getQuote.ts +192 -0
  39. package/src/routes/permissions/index.ts +12 -0
  40. package/src/routes/permissions/listPermissions.ts +202 -0
  41. package/src/routes/permissions/setPermission.ts +155 -0
  42. package/src/routes/registerDevice.ts +155 -0
  43. package/src/routes/sendMessage.ts +531 -0
  44. package/src/runtimeDeps.ts +29 -0
  45. package/src/swagger.ts +54 -0
  46. package/src/telemetry.ts +158 -0
  47. package/src/types/messagePermissions.ts +18 -0
  48. package/src/types/mock-knex.d.ts +18 -0
  49. package/src/types/notifications.ts +27 -0
  50. package/src/utils/logger.ts +92 -0
  51. package/src/utils/messagePermissions.ts +148 -0
  52. package/src/utils/sendFCMNotification.ts +143 -0
  53. package/tsconfig.json +36 -0
  54. package/tsconfig.types.json +11 -0
  55. package/out/knexfile.js +0 -25
  56. package/out/knexfile.js.map +0 -1
  57. package/out/src/app.js +0 -160
  58. package/out/src/app.js.map +0 -1
  59. package/out/src/config/firebase.js +0 -150
  60. package/out/src/config/firebase.js.map +0 -1
  61. package/out/src/index.js +0 -295
  62. package/out/src/index.js.map +0 -1
  63. package/out/src/migrations/2022-12-28-001-initial-migration.js +0 -28
  64. package/out/src/migrations/2022-12-28-001-initial-migration.js.map +0 -1
  65. package/out/src/migrations/2023-01-17-messages-update.js +0 -11
  66. package/out/src/migrations/2023-01-17-messages-update.js.map +0 -1
  67. package/out/src/migrations/2024-03-05-001-messageID-upgrade.js +0 -21
  68. package/out/src/migrations/2024-03-05-001-messageID-upgrade.js.map +0 -1
  69. package/out/src/migrations/2025-01-31-001-notification-permissions.js +0 -59
  70. package/out/src/migrations/2025-01-31-001-notification-permissions.js.map +0 -1
  71. package/out/src/migrations/2025-01-31-002-device-registrations.js +0 -24
  72. package/out/src/migrations/2025-01-31-002-device-registrations.js.map +0 -1
  73. package/out/src/routes/__tests/acknowledgeMessage.test.js +0 -129
  74. package/out/src/routes/__tests/acknowledgeMessage.test.js.map +0 -1
  75. package/out/src/routes/__tests/listMessages.test.js +0 -211
  76. package/out/src/routes/__tests/listMessages.test.js.map +0 -1
  77. package/out/src/routes/__tests/sendMessage.test.js +0 -307
  78. package/out/src/routes/__tests/sendMessage.test.js.map +0 -1
  79. package/out/src/routes/acknowledgeMessage.js +0 -144
  80. package/out/src/routes/acknowledgeMessage.js.map +0 -1
  81. package/out/src/routes/index.js +0 -17
  82. package/out/src/routes/index.js.map +0 -1
  83. package/out/src/routes/listDevices.js +0 -74
  84. package/out/src/routes/listDevices.js.map +0 -1
  85. package/out/src/routes/listMessages.js +0 -186
  86. package/out/src/routes/listMessages.js.map +0 -1
  87. package/out/src/routes/permissions/getPermission.js +0 -149
  88. package/out/src/routes/permissions/getPermission.js.map +0 -1
  89. package/out/src/routes/permissions/getQuote.js +0 -165
  90. package/out/src/routes/permissions/getQuote.js.map +0 -1
  91. package/out/src/routes/permissions/index.js +0 -12
  92. package/out/src/routes/permissions/index.js.map +0 -1
  93. package/out/src/routes/permissions/listPermissions.js +0 -190
  94. package/out/src/routes/permissions/listPermissions.js.map +0 -1
  95. package/out/src/routes/permissions/setPermission.js +0 -137
  96. package/out/src/routes/permissions/setPermission.js.map +0 -1
  97. package/out/src/routes/registerDevice.js +0 -150
  98. package/out/src/routes/registerDevice.js.map +0 -1
  99. package/out/src/routes/sendMessage.js +0 -451
  100. package/out/src/routes/sendMessage.js.map +0 -1
  101. package/out/src/swagger.js +0 -49
  102. package/out/src/swagger.js.map +0 -1
  103. package/out/src/types/messagePermissions.js +0 -2
  104. package/out/src/types/messagePermissions.js.map +0 -1
  105. package/out/src/types/notifications.js +0 -2
  106. package/out/src/types/notifications.js.map +0 -1
  107. package/out/src/utils/logger.js +0 -24
  108. package/out/src/utils/logger.js.map +0 -1
  109. package/out/src/utils/messagePermissions.js +0 -126
  110. package/out/src/utils/messagePermissions.js.map +0 -1
  111. package/out/src/utils/sendFCMNotification.js +0 -121
  112. package/out/src/utils/sendFCMNotification.js.map +0 -1
  113. package/out/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,64 @@
1
+ version: '3.8'
2
+ services:
3
+ ## Backend API
4
+ backend:
5
+ build:
6
+ context: .
7
+ dockerfile: Dockerfile
8
+ restart: always
9
+ ports:
10
+ - "8080:8080"
11
+ - 9229:9229
12
+ command: node --inspect=0.0.0.0 --import ./out/src/telemetry.js ./out/src/index.js
13
+ environment:
14
+ HOSTING_DOMAIN: 'http://localhost:8080'
15
+ PORT: 8080
16
+ SERVER_PRIVATE_KEY: 'f8b4b466417e3fede5f95cb0651fb6371c3c9c0753a3e15c1c30155461d03c18' # EXAMPLE TEST KEY
17
+ KNEX_DB_CLIENT: mysql
18
+ KNEX_DB_CONNECTION: '{"port":3306,"host":"backend-mysql","user":"root","password":"test","database":"messagebox-backend"}'
19
+ NODE_ENV: development
20
+ WALLET_STORAGE_URL: 'https://storage.babbage.systems'
21
+ # OpenTelemetry — point at any OTLP/HTTP collector. Unset => console exporters.
22
+ OTEL_EXPORTER_OTLP_ENDPOINT: ${OTEL_EXPORTER_OTLP_ENDPOINT:-}
23
+ OTEL_EXPORTER_OTLP_HEADERS: ${OTEL_EXPORTER_OTLP_HEADERS:-}
24
+ OTEL_SERVICE_NAME: ${OTEL_SERVICE_NAME:-message-box-server}
25
+ OTEL_RESOURCE_ATTRIBUTES: ${OTEL_RESOURCE_ATTRIBUTES:-}
26
+ DEPLOY_ENV: ${DEPLOY_ENV:-development}
27
+ depends_on:
28
+ backend-mysql:
29
+ condition: service_healthy
30
+
31
+ ## Backend database
32
+ backend-mysql:
33
+ image: "mysql:8.0"
34
+ platform: linux/amd64
35
+ hostname: 'backend-mysql'
36
+ command: 'mysqld --default-authentication-plugin=mysql_native_password --sync_binlog=0 --innodb_doublewrite=OFF --innodb-flush-log-at-trx-commit=0 --innodb-flush-method=nosync'
37
+ restart: always
38
+ volumes:
39
+ - './data/backend-mysql-data:/var/lib/mysql'
40
+ environment:
41
+ MYSQL_HOST: "127.0.0.1"
42
+ MYSQL_TCP_PORT: 3306
43
+ MYSQL_ROOT_PASSWORD: "test"
44
+ MYSQL_DATABASE: "messagebox-backend"
45
+ ports:
46
+ - "3306:3306"
47
+ healthcheck:
48
+ test: ["CMD-SHELL", 'mysqladmin ping']
49
+ interval: 10s
50
+ timeout: 2s
51
+ retries: 10
52
+
53
+ # Optional: PHPMyAdmin for DB browsing
54
+ phpmyadmin:
55
+ image: phpmyadmin/phpmyadmin
56
+ links:
57
+ - backend-mysql
58
+ environment:
59
+ PMA_HOST: backend-mysql
60
+ PMA_PORT: 3306
61
+ PMA_ARBITRARY: 1
62
+ restart: always
63
+ ports:
64
+ - 3003:80
@@ -0,0 +1,26 @@
1
+ /** @type {import('ts-jest').JestConfigWithTsJest} */
2
+ import type { JestConfigWithTsJest } from 'ts-jest'
3
+
4
+ const config: JestConfigWithTsJest = {
5
+ preset: 'ts-jest',
6
+ testEnvironment: 'node',
7
+ extensionsToTreatAsEsm: ['.ts'],
8
+ testPathIgnorePatterns: ['dist/'],
9
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
10
+ transform: {
11
+ '^.+\\.ts?$': ['ts-jest', {
12
+ useESM: true,
13
+ tsconfig: {
14
+ module: 'ESNext',
15
+ moduleResolution: 'bundler',
16
+ isolatedModules: true
17
+ }
18
+ }]
19
+ },
20
+ testMatch: ['**/test/integration/**/*.test.ts'], // Only run integration tests
21
+ verbose: true,
22
+ setupFilesAfterEnv: ['./jest.setup.ts'], // Ensures the test server/db start correctly
23
+ testTimeout: 30000 // Longer timeout for integration tests
24
+ }
25
+
26
+ export default config
@@ -0,0 +1,42 @@
1
+ // jest.config.mjs - ES Module version of Jest config
2
+ export default {
3
+ // Setup file to provide globals and env vars
4
+ setupFilesAfterEnv: ['./jest.setup.mjs'],
5
+ // Use Node environment
6
+ testEnvironment: 'node',
7
+ // Force exit after tests complete (module-level knex pools stay open)
8
+ forceExit: true,
9
+
10
+ // Transform TypeScript files
11
+ transform: {
12
+ '^.+\\.tsx?$': [
13
+ 'ts-jest',
14
+ {
15
+ useESM: true,
16
+ tsconfig: {
17
+ module: 'ESNext',
18
+ moduleResolution: 'bundler',
19
+ },
20
+ },
21
+ ],
22
+ },
23
+
24
+ // Tell Jest these extensions should be treated as ESM
25
+ extensionsToTreatAsEsm: ['.ts', '.tsx'],
26
+
27
+ // Handle .js extensions in import statements for TypeScript files
28
+ moduleNameMapper: {
29
+ '^(\\.{1,2}/.*)\\.js$': '$1',
30
+ },
31
+
32
+ // Ignore compiled output
33
+ testPathIgnorePatterns: ['/node_modules/', '/out/'],
34
+
35
+ // Important for ES modules
36
+ transformIgnorePatterns: [
37
+ '/node_modules/(?!.*\\.mjs$)'
38
+ ],
39
+
40
+ // Use .mjs extension for Jest config to indicate ESM
41
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node', 'mjs'],
42
+ };
package/jest.config.ts ADDED
@@ -0,0 +1,35 @@
1
+ // jest.config.ts
2
+ import type { JestConfigWithTsJest } from 'ts-jest'
3
+
4
+ const config: JestConfigWithTsJest = {
5
+ // Use the preset specifically designed for ESM
6
+ preset: 'ts-jest/presets/default-esm',
7
+
8
+ // Use the Node environment for testing
9
+ testEnvironment: 'node',
10
+
11
+ // Ignore compiled output
12
+ testPathIgnorePatterns: ['dist/'],
13
+
14
+ // These globals configure ts-jest to output ESM
15
+ globals: {
16
+ 'ts-jest': {
17
+ useESM: true,
18
+ tsconfig: {
19
+ module: 'ESNext',
20
+ moduleResolution: 'bundler'
21
+ }
22
+ }
23
+ },
24
+
25
+ // Tell Jest that files ending in .ts should be treated as ESM modules
26
+ extensionsToTreatAsEsm: ['.ts'],
27
+
28
+ // Optionally, if you have imports with a .js extension in your source (or tests)
29
+ // but your source files are actually TypeScript, this mapper will remove the extension.
30
+ moduleNameMapper: {
31
+ '^(\\.{1,2}/.*)\\.js$': '$1'
32
+ }
33
+ }
34
+
35
+ export default config
package/jest.setup.mjs ADDED
@@ -0,0 +1,18 @@
1
+ // Import Jest types from the jest package
2
+ import { jest } from '@jest/globals';
3
+
4
+ // Make Jest available globally
5
+ global.jest = jest;
6
+ global.expect = expect;
7
+ global.test = test;
8
+ global.describe = describe;
9
+ global.beforeEach = beforeEach;
10
+ global.afterEach = afterEach;
11
+ global.beforeAll = beforeAll;
12
+ global.afterAll = afterAll;
13
+
14
+ // Add mock environment variables needed for tests
15
+ process.env.SERVER_PRIVATE_KEY = 'test_private_key_for_jest_environment';
16
+ process.env.NODE_ENV = 'test';
17
+ process.env.KNEX_DB_CLIENT = 'better-sqlite3';
18
+ process.env.KNEX_DB_CONNECTION = '{"filename":":memory:"}';
package/nginx.conf ADDED
@@ -0,0 +1,36 @@
1
+ user nginx;
2
+ worker_processes auto;
3
+ daemon off;
4
+ error_log stderr info;
5
+ pid /var/run/nginx.pid;
6
+ events {
7
+ worker_connections 1024;
8
+ }
9
+ http {
10
+ access_log stdout;
11
+ include /etc/nginx/mime.types;
12
+ default_type application/octet-stream;
13
+ log_format main '$remote_addr - $remote_user [$time_local] "$request" '
14
+ '$status $body_bytes_sent "$http_referer" '
15
+ '"$http_user_agent" "$http_x_forwarded_for"';
16
+ sendfile on;
17
+ keepalive_timeout 3540;
18
+ gzip on;
19
+ server {
20
+ listen 8080 http2;
21
+ listen [::]:8080 http2;
22
+ server_name localhost;
23
+
24
+ # Set maximum allowed request size
25
+ client_max_body_size 1g;
26
+
27
+ location / {
28
+ proxy_set_header X-Real-IP $remote_addr;
29
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
30
+ proxy_set_header Host $host;
31
+ proxy_set_header X-NginX-Proxy true;
32
+ proxy_pass http://localhost:3000;
33
+ proxy_redirect off;
34
+ }
35
+ }
36
+ }
package/package.json CHANGED
@@ -1,15 +1,18 @@
1
1
  {
2
2
  "name": "@bopen-io/messagebox-server",
3
- "version": "1.1.5",
4
- "main": "./out/src/index.js",
3
+ "version": "1.2.0",
4
+ "main": "./out/src/compose.js",
5
+ "exports": {
6
+ ".": {
7
+ "import": "./out/src/compose.js",
8
+ "default": "./out/src/compose.js"
9
+ },
10
+ "./server": {
11
+ "import": "./out/src/index.js",
12
+ "default": "./out/src/index.js"
13
+ }
14
+ },
5
15
  "type": "module",
6
- "files": [
7
- "out/",
8
- "src/migrations/",
9
- "src/templates/",
10
- "knexfile.ts",
11
- "knexfile.d.ts"
12
- ],
13
16
  "scripts": {
14
17
  "start": "node out/src/index.js",
15
18
  "dev": "nodemon --inspect --watch .env --watch src --exec tsx src/index.ts",
@@ -20,68 +23,79 @@
20
23
  "test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config=jest.config.mjs --watch",
21
24
  "lint": "ts-standard --fix .",
22
25
  "clean": "rimraf dist node_modules && npm install",
23
- "prebuild": "rimraf dist",
24
- "prepublishOnly": "bun run build"
26
+ "prebuild": "rimraf dist"
25
27
  },
26
28
  "keywords": [],
27
29
  "author": "",
28
30
  "license": "ISC",
29
- "description": "",
31
+ "description": "BSV message-box server with composable mount API (build from ts-stack main)",
30
32
  "devDependencies": {
31
- "@eslint/js": "^9.20.0",
32
33
  "@types/better-sqlite3": "^7.6.13",
33
- "@types/body-parser": "^1.19.5",
34
- "@types/dotenv": "^6.1.1",
35
- "@types/express": "^5.0.0",
36
- "@types/jest": "^29.5.14",
37
- "@types/knex": "^0.15.2",
34
+ "@types/body-parser": "^1.19.6",
35
+ "@types/dotenv": "^8.2.3",
36
+ "@types/express": "^5.0.6",
37
+ "@types/jest": "^30.0.0",
38
+ "@types/knex": "^0.16.1",
38
39
  "@types/mock-knex": "^0.4.8",
39
- "@types/node": "^22.13.1",
40
+ "@types/node": "^26.0.0",
40
41
  "@types/prettyjson": "^0.0.33",
41
- "@types/superagent": "^8.1.9",
42
- "@types/supertest": "^6.0.2",
42
+ "@types/superagent": "^8.1.10",
43
+ "@types/supertest": "^7.2.0",
43
44
  "@types/swagger-jsdoc": "^6.0.4",
44
45
  "@types/swagger-ui-express": "^4.1.8",
45
46
  "@types/web-push": "^3.6.4",
46
- "@typescript-eslint/eslint-plugin": "^8.24.0",
47
- "@typescript-eslint/parser": "^8.24.0",
48
- "axios": "^1.8.4",
47
+ "axios": "^1.17.0",
49
48
  "axios-mock-adapter": "^2.1.0",
50
- "better-sqlite3": "^12.6.2",
51
- "ejs": "^3.1.10",
52
- "eslint": "^8.57.1",
53
- "eslint-plugin-react": "^7.37.4",
54
- "globals": "^15.14.0",
55
- "jest": "^29.7.0",
49
+ "better-sqlite3": "^12.10.0",
50
+ "ejs": "^6.0.1",
51
+ "jest": "^30.3.0",
56
52
  "mock-knex": "^0.4.13",
57
- "rimraf": "^6.0.1",
58
- "superagent": "^10.2.1",
59
- "supertest": "^7.1.1",
60
- "ts-jest": "^29.2.5",
53
+ "rimraf": "^6.1.3",
54
+ "superagent": "^10.3.0",
55
+ "supertest": "^7.2.2",
56
+ "ts-jest": "^29.4.9",
61
57
  "ts-node": "^10.9.2",
62
58
  "ts-standard": "^12.0.2",
63
- "tsx": "^4.19.3",
64
- "typescript": "^5.7.3",
65
- "typescript-eslint": "^8.24.0"
59
+ "tsx": "^4.22.4",
60
+ "typescript": "^6.0.3"
66
61
  },
67
62
  "overrides": {
68
- "@tootallnate/once": "3.0.1"
63
+ "@tootallnate/once": "3.0.1",
64
+ "tar": ">=7.5.11",
65
+ "minimatch": ">=9.0.7",
66
+ "cross-spawn": ">=7.0.6",
67
+ "glob": ">=10.5.0"
69
68
  },
70
69
  "dependencies": {
71
- "@bsv/auth-express-middleware": "^2.0.4",
72
- "@bsv/authsocket": "^2.0.1",
73
- "@bsv/payment-express-middleware": "^2.0.1",
74
- "@bsv/sdk": "^2.0.7",
75
- "@bsv/wallet-toolbox": "^2.1.5",
76
- "body-parser": "^1.20.3",
77
- "dotenv": "^8.6.0",
78
- "express": "^4.21.2",
79
- "firebase-admin": "^13.7.0",
80
- "knex": "^2.5.1",
81
- "mongodb": "^6.15.0",
82
- "mysql2": "^3.12.0",
70
+ "@bsv/auth-express-middleware": "^2.1.0",
71
+ "@bsv/authsocket": "^2.1.0",
72
+ "@bsv/payment-express-middleware": "^2.1.0",
73
+ "@bsv/sdk": "^2.1.6",
74
+ "@bsv/wallet-toolbox": "^2.3.3",
75
+ "@opentelemetry/api": "^1.9.1",
76
+ "@opentelemetry/api-logs": "^0.219.0",
77
+ "@opentelemetry/auto-instrumentations-node": "^0.77.0",
78
+ "@opentelemetry/exporter-logs-otlp-http": "^0.219.0",
79
+ "@opentelemetry/exporter-metrics-otlp-http": "^0.219.0",
80
+ "@opentelemetry/exporter-trace-otlp-http": "^0.219.0",
81
+ "@opentelemetry/instrumentation": "^0.219.0",
82
+ "@opentelemetry/instrumentation-runtime-node": "^0.32.0",
83
+ "@opentelemetry/resources": "^2.8.0",
84
+ "@opentelemetry/sdk-logs": "^0.219.0",
85
+ "@opentelemetry/sdk-metrics": "^2.8.0",
86
+ "@opentelemetry/sdk-node": "^0.219.0",
87
+ "@opentelemetry/sdk-trace-base": "^2.8.0",
88
+ "@opentelemetry/semantic-conventions": "^1.41.1",
89
+ "body-parser": "^2.2.2",
90
+ "dotenv": "^17.4.2",
91
+ "express": "^5.2.1",
92
+ "firebase-admin": "^14.0.0",
93
+ "knex": "^3.2.10",
94
+ "mongodb": "^7.2.0",
95
+ "mysql2": "^3.22.5",
96
+ "pino": "^10.3.1",
83
97
  "prettyjson": "^1.2.5",
84
- "swagger-jsdoc": "^6.2.8",
98
+ "swagger-jsdoc": "^6.3.0",
85
99
  "swagger-ui-express": "^5.0.1",
86
100
  "web-push": "^3.6.7"
87
101
  }
@@ -0,0 +1,19 @@
1
+ const ejs = require('ejs')
2
+ const fs = require('fs')
3
+ require('dotenv').config()
4
+
5
+ ejs.renderFile(
6
+ 'src/templates/documentation.ejs',
7
+ {
8
+ ...process.env,
9
+ routes: require('../src/routes').postAuthrite
10
+ },
11
+ {},
12
+ (err, res) => {
13
+ if (err) {
14
+ throw err
15
+ }
16
+ console.log('Generating API Documentation...')
17
+ fs.writeFileSync('public/index.html', res)
18
+ }
19
+ )
@@ -0,0 +1,31 @@
1
+ #!/bin/bash
2
+
3
+ echo "Creating $1"
4
+ echo "apiVersion: serving.knative.dev/v1
5
+ kind: Service
6
+ metadata:
7
+ name: $SERVICE
8
+ spec:
9
+ template:
10
+ spec:
11
+ timeoutSeconds: 3540
12
+ containers:
13
+ - image: $IMAGE
14
+ ports:
15
+ - name: h2c
16
+ containerPort: 8080
17
+ env:" > $1
18
+
19
+ echo "Appending environment variables to $1"
20
+ perl -E'
21
+ say " - name: $_
22
+ value: \x27$ENV{$_}\x27" for @ARGV;
23
+ ' NODE_ENV \
24
+ KNEX_DB_CONNECTION \
25
+ BSV_NETWORK \
26
+ WALLET_STORAGE_URL \
27
+ LOGGING_ENABLED \
28
+ SERVER_PRIVATE_KEY >> $1
29
+
30
+ echo "Built! Contents of $1:"
31
+ cat $1
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+
3
+ if [[ $NODE_ENV = 'production' ]] || [[ $NODE_ENV = 'staging' ]]
4
+ then
5
+ npm run build
6
+ node src/index.js
7
+ exit
8
+ fi
9
+
10
+ until nc -z -v -w30 messagebox-backend-mysql 3001
11
+ do
12
+ echo "Waiting for database connection..."
13
+ sleep 1
14
+ done
15
+ knex migrate:latest
16
+ npm run start
@@ -0,0 +1,30 @@
1
+ /* eslint-env jest */
2
+ import knexLib from 'knex'
3
+ import {
4
+ createMessageBoxContext,
5
+ createMessageBoxApp,
6
+ mountMessageBoxRoutes
7
+ } from '../compose.js'
8
+
9
+ describe('compose API', () => {
10
+ it('createMessageBoxContext requires wallet and knex', () => {
11
+ expect(() => createMessageBoxContext({} as any)).toThrow(/wallet/)
12
+ })
13
+
14
+ it('mountMessageBoxRoutes attaches without throwing', () => {
15
+ const knexConfig = { client: 'mysql2', connection: {}, useNullAsDefault: true }
16
+ const knex = (knexLib as any).default?.(knexConfig) ?? (knexLib as any)(knexConfig)
17
+ const wallet = {
18
+ getPublicKey: async () => ({ publicKey: '02' + '11'.repeat(32) })
19
+ } as any
20
+ const app = createMessageBoxApp()
21
+ const ctx = createMessageBoxContext({
22
+ wallet,
23
+ knex,
24
+ enableSwagger: false,
25
+ enableWebSockets: false
26
+ })
27
+ expect(() => { mountMessageBoxRoutes(app, ctx) }).not.toThrow()
28
+ expect(typeof app.use).toBe('function')
29
+ })
30
+ })