@omen.foundation/node-microservice-runtime 0.1.67 → 0.1.68

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omen.foundation/node-microservice-runtime",
3
- "version": "0.1.67",
3
+ "version": "0.1.68",
4
4
  "description": "Beamable microservice runtime for Node.js/TypeScript services.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -15,7 +15,8 @@
15
15
  "beamo-node": "./dist/cli/index.js"
16
16
  },
17
17
  "files": [
18
- "dist"
18
+ "dist",
19
+ "scripts"
19
20
  ],
20
21
  "scripts": {
21
22
  "clean": "rimraf dist dist-cjs",
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Script to deprecate all old versions that contain .env files
4
+ *
5
+ * Usage: node scripts/deprecate-all-versions.js
6
+ *
7
+ * This will deprecate all versions from 0.1.0 to 0.1.66
8
+ * You cannot unpublish packages older than 72 hours, so deprecation is the alternative
9
+ */
10
+
11
+ import { execSync } from 'child_process';
12
+
13
+ const PACKAGE_NAME = '@omen.foundation/node-microservice-runtime';
14
+ const DEPRECATE_MESSAGE = 'Security: This version contains exposed credentials. Use version 0.1.67 or later.';
15
+
16
+ // All versions that need to be deprecated
17
+ const VERSIONS = [
18
+ '0.1.0', '0.1.1', '0.1.2', '0.1.3', '0.1.4', '0.1.5', '0.1.6', '0.1.7', '0.1.8', '0.1.9',
19
+ '0.1.10', '0.1.11', '0.1.12', '0.1.13', '0.1.14', '0.1.15', '0.1.16', '0.1.17', '0.1.18', '0.1.19',
20
+ '0.1.20', '0.1.21', '0.1.22', '0.1.23', '0.1.24', '0.1.25', '0.1.26', '0.1.27', '0.1.28', '0.1.29',
21
+ '0.1.30', '0.1.31', '0.1.32', '0.1.33', '0.1.34', '0.1.35', '0.1.36', '0.1.37', '0.1.38', '0.1.39',
22
+ '0.1.40', '0.1.41', '0.1.42', '0.1.43', '0.1.44', '0.1.45', '0.1.46', '0.1.47', '0.1.48', '0.1.49',
23
+ '0.1.50', '0.1.51', '0.1.52', '0.1.53', '0.1.54', '0.1.55', '0.1.56', '0.1.57', '0.1.58', '0.1.59',
24
+ '0.1.60', '0.1.61', '0.1.62', '0.1.63', '0.1.64', '0.1.65', '0.1.66'
25
+ ];
26
+
27
+ console.log(`\n🚨 Deprecating ${VERSIONS.length} versions of ${PACKAGE_NAME}\n`);
28
+ console.log(`Message: "${DEPRECATE_MESSAGE}"\n`);
29
+
30
+ let successCount = 0;
31
+ let failCount = 0;
32
+ const failedVersions = [];
33
+
34
+ for (const version of VERSIONS) {
35
+ const fullPackageName = `${PACKAGE_NAME}@${version}`;
36
+
37
+ try {
38
+ console.log(`Deprecating ${fullPackageName}...`);
39
+
40
+ // Escape the message for shell
41
+ const escapedMessage = DEPRECATE_MESSAGE.replace(/'/g, "\\'").replace(/"/g, '\\"');
42
+ const command = `npm deprecate "${fullPackageName}" "${escapedMessage}"`;
43
+
44
+ execSync(command, { stdio: 'inherit' });
45
+
46
+ console.log(`āœ… Deprecated ${version}\n`);
47
+ successCount++;
48
+
49
+ // Small delay to avoid rate limiting
50
+ if (successCount % 10 === 0) {
51
+ console.log('Pausing for 2 seconds to avoid rate limiting...\n');
52
+ await new Promise(resolve => setTimeout(resolve, 2000));
53
+ }
54
+ } catch (error) {
55
+ console.error(`āŒ Failed to deprecate ${version}: ${error.message}\n`);
56
+ failCount++;
57
+ failedVersions.push(version);
58
+ }
59
+ }
60
+
61
+ console.log(`\n=== Summary ===`);
62
+ console.log(`āœ… Successfully deprecated: ${successCount} versions`);
63
+ console.log(`āŒ Failed: ${failCount} versions`);
64
+
65
+ if (failedVersions.length > 0) {
66
+ console.log(`\nFailed versions:`);
67
+ failedVersions.forEach(v => console.log(` - ${v}`));
68
+ console.log(`\nYou may need to deprecate these manually or they may already be deprecated.`);
69
+ }
70
+
71
+ console.log(`\nāš ļø Important: Rotate your Beamable SECRET immediately!`);
72
+ console.log(` All these versions contained exposed credentials.`);
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import { pathToFileURL, fileURLToPath } from 'node:url';
6
+ import dotenv from 'dotenv';
7
+
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+
10
+ function parseArgs(argv) {
11
+ const args = {
12
+ entry: 'dist/main.js',
13
+ output: 'beam_openApi.json',
14
+ envFile: undefined,
15
+ cid: undefined,
16
+ pid: undefined,
17
+ host: undefined,
18
+ namePrefix: undefined,
19
+ service: undefined,
20
+ };
21
+
22
+ const queue = [...argv];
23
+ while (queue.length > 0) {
24
+ const current = queue.shift();
25
+ switch (current) {
26
+ case '--entry':
27
+ args.entry = queue.shift();
28
+ break;
29
+ case '--output':
30
+ args.output = queue.shift();
31
+ break;
32
+ case '--env-file':
33
+ args.envFile = queue.shift();
34
+ break;
35
+ case '--cid':
36
+ args.cid = queue.shift();
37
+ break;
38
+ case '--pid':
39
+ args.pid = queue.shift();
40
+ break;
41
+ case '--host':
42
+ args.host = queue.shift();
43
+ break;
44
+ case '--routing-key':
45
+ case '--name-prefix':
46
+ args.namePrefix = queue.shift();
47
+ break;
48
+ case '--service':
49
+ args.service = queue.shift();
50
+ break;
51
+ default:
52
+ throw new Error(`Unknown argument: ${current}`);
53
+ }
54
+ }
55
+
56
+ return args;
57
+ }
58
+
59
+ async function main() {
60
+ const args = parseArgs(process.argv.slice(2));
61
+
62
+ if (args.envFile) {
63
+ const envPath = path.resolve(args.envFile);
64
+ dotenv.config({ path: envPath });
65
+ }
66
+
67
+ if (args.cid) {
68
+ process.env.CID = args.cid;
69
+ }
70
+ if (args.pid) {
71
+ process.env.PID = args.pid;
72
+ }
73
+ if (args.host) {
74
+ process.env.HOST = args.host;
75
+ }
76
+ if (args.namePrefix) {
77
+ process.env.NAME_PREFIX = args.namePrefix;
78
+ }
79
+
80
+ process.env.BEAMABLE_SKIP_RUNTIME = 'true';
81
+
82
+ const entryPath = path.resolve(args.entry);
83
+ const outputPath = path.resolve(args.output);
84
+
85
+ const runtimeEntry = path.resolve(__dirname, '../dist/runtime.js');
86
+ try {
87
+ await fs.access(runtimeEntry);
88
+ } catch (error) {
89
+ throw new Error('Runtime distribution not found. Run "npm run compile" in @omen.foundation/node-microservice-runtime.');
90
+ }
91
+
92
+ await import(pathToFileURL(entryPath).href);
93
+
94
+ const { generateOpenApiDocumentForRegisteredServices } = await import(pathToFileURL(runtimeEntry).href);
95
+
96
+ const document = generateOpenApiDocumentForRegisteredServices(
97
+ {
98
+ cid: process.env.CID,
99
+ pid: process.env.PID,
100
+ host: process.env.HOST,
101
+ routingKey: process.env.NAME_PREFIX,
102
+ },
103
+ { serviceName: args.service },
104
+ );
105
+
106
+ await fs.writeFile(outputPath, `${JSON.stringify(document, null, 2)}\n`, 'utf8');
107
+
108
+ console.log(`OpenAPI documentation generated at ${outputPath}`);
109
+ }
110
+
111
+ main().catch((error) => {
112
+ console.error(error instanceof Error ? error.message : error);
113
+ process.exit(1);
114
+ });
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawn } from 'node:child_process';
4
+
5
+ export function runCommand(
6
+ command,
7
+ args,
8
+ { cwd = process.cwd(), env = process.env, stdio = 'inherit', capture = false, shell, silent = false } = {},
9
+ ) {
10
+ return new Promise((resolve, reject) => {
11
+ const stdioOption = capture ? 'pipe' : (silent ? 'ignore' : stdio);
12
+ const child = spawn(command, args, {
13
+ cwd,
14
+ env,
15
+ stdio: stdioOption,
16
+ shell: shell ?? (process.platform === 'win32'),
17
+ });
18
+
19
+ const stdoutChunks = [];
20
+ const stderrChunks = [];
21
+
22
+ if (capture) {
23
+ child.stdout?.on('data', (chunk) => stdoutChunks.push(chunk));
24
+ child.stderr?.on('data', (chunk) => stderrChunks.push(chunk));
25
+ }
26
+
27
+ child.on('error', (error) => {
28
+ reject(error);
29
+ });
30
+
31
+ child.on('exit', (code, signal) => {
32
+ if (code === 0) {
33
+ resolve({
34
+ code,
35
+ signal,
36
+ stdout: capture ? Buffer.concat(stdoutChunks).toString('utf8').trim() : undefined,
37
+ stderr: capture ? Buffer.concat(stderrChunks).toString('utf8').trim() : undefined,
38
+ });
39
+ } else {
40
+ const error = new Error(`Command failed: ${command} ${args.join(' ')}`);
41
+ error.code = code;
42
+ error.signal = signal;
43
+ if (capture) {
44
+ error.stdout = Buffer.concat(stdoutChunks).toString('utf8');
45
+ error.stderr = Buffer.concat(stderrChunks).toString('utf8');
46
+ }
47
+ reject(error);
48
+ }
49
+ });
50
+ });
51
+ }
52
+
53
+ export function parseBooleanEnv(value, fallback = false) {
54
+ if (value === undefined) {
55
+ return fallback;
56
+ }
57
+ return ['1', 'true', 'yes', 'on'].includes(value.toString().trim().toLowerCase());
58
+ }
@@ -0,0 +1,44 @@
1
+ import { mkdir, readdir, readFile, rm, writeFile } from 'node:fs/promises';
2
+ import { dirname, join } from 'node:path';
3
+
4
+ async function ensureDir(path) {
5
+ await mkdir(path, { recursive: true });
6
+ }
7
+
8
+ async function copyCjsFiles() {
9
+ const srcRoot = join(process.cwd(), 'dist-cjs');
10
+ const dstRoot = join(process.cwd(), 'dist');
11
+
12
+ await ensureDir(dstRoot);
13
+
14
+ const stack = [''];
15
+ while (stack.length > 0) {
16
+ const current = stack.pop();
17
+ const srcDir = join(srcRoot, current);
18
+ const entries = await readdir(srcDir, { withFileTypes: true });
19
+ for (const entry of entries) {
20
+ const relativePath = join(current, entry.name);
21
+ if (entry.isDirectory()) {
22
+ stack.push(relativePath);
23
+ continue;
24
+ }
25
+
26
+ if (!entry.name.endsWith('.js')) {
27
+ continue;
28
+ }
29
+
30
+ const sourceFile = join(srcRoot, relativePath);
31
+ const destFile = join(dstRoot, current, entry.name.replace(/\.js$/, '.cjs'));
32
+ await ensureDir(dirname(destFile));
33
+ const contents = await readFile(sourceFile);
34
+ await writeFile(destFile, contents);
35
+ }
36
+ }
37
+
38
+ await rm(srcRoot, { recursive: true, force: true });
39
+ }
40
+
41
+ copyCjsFiles().catch((error) => {
42
+ console.error('Failed to prepare CommonJS artifacts:', error);
43
+ process.exitCode = 1;
44
+ });