@balena/compose-parser 0.0.9 → 0.0.10

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/dist/compose.js CHANGED
@@ -20,8 +20,8 @@ async function parse(composeFilePaths) {
20
20
  const projectName = (0, crypto_1.randomUUID)();
21
21
  const fileFlags = filePaths.map((filePath) => `-f ${filePath}`).join(' ');
22
22
  const binaryName = process.platform === 'win32'
23
- ? 'balena_compose_parser.exe'
24
- : 'balena_compose_parser';
23
+ ? 'balena-compose-parser.exe'
24
+ : 'balena-compose-parser';
25
25
  const binaryPath = path.join(__dirname, '..', 'bin', binaryName);
26
26
  const result = await exec(`${binaryPath} ${fileFlags} ${projectName}`, {
27
27
  env: process.env,
package/lib/go.mod CHANGED
@@ -1,4 +1,4 @@
1
- module balena-compose-go
1
+ module balena-compose-parser
2
2
 
3
3
  go 1.24.4
4
4
 
package/lib/main.go CHANGED
@@ -21,7 +21,7 @@ type ErrorResponse struct {
21
21
 
22
22
  // Usage message
23
23
  const usage = `
24
- Usage: balena_compose_parser -f <compose-file> [-f <compose-file>...] <project-name>
24
+ Usage: balena-compose-parser -f <compose-file> [-f <compose-file>...] <project-name>
25
25
 
26
26
  Parses one or more docker-compose files and outputs a structured response.
27
27
 
@@ -31,7 +31,7 @@ Arguments:
31
31
  the project name need to be removed for normalization into a compose acceptable by balena.
32
32
 
33
33
  Example:
34
- balena_compose_parser -f docker-compose.yml -f docker-compose.override.yml my-project-name
34
+ balena-compose-parser -f docker-compose.yml -f docker-compose.override.yml my-project-name
35
35
  `
36
36
 
37
37
  func main() {
package/package.json CHANGED
@@ -1,28 +1,27 @@
1
1
  {
2
2
  "name": "@balena/compose-parser",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "description": "Wraps compose-go to parse balena-compatible docker-compose.yml files",
5
5
  "scripts": {
6
6
  "clean": "rimraf dist",
7
7
  "lint": "balena-lint lib/ test/ && tsc --noEmit",
8
8
  "lint-fix": "balena-lint --fix lib/ test/",
9
9
  "build": "npm run clean && tsc --project tsconfig.release.json",
10
- "build:go": "CGO_ENABLED=0 go build -C lib -ldflags='-s -w' -o \"../bin/balena_compose_parser$(go env GOEXE)\"",
10
+ "build:go": "echo 'Building Go binary from source...' && CGO_ENABLED=0 go build -C lib -ldflags='-s -w' -o \"../bin/balena-compose-parser$(go env GOEXE)\"",
11
11
  "test": "npm run lint && npm run test:unit",
12
12
  "test:unit": "ts-mocha 'test/**/*unit.spec.ts'",
13
13
  "test:integration": "ts-mocha 'test/**/*.spec.ts'",
14
14
  "test:compose": "(docker compose -f docker-compose.test.yml run --build --rm sut || docker compose logs); npm run compose:down",
15
15
  "compose:down": "docker compose -f docker-compose.test.yml down --volumes",
16
16
  "prepack": "npm run build",
17
- "install": "node-pre-gyp install --fallback-to-build=false || npm run build:go",
18
- "postinstall": "node scripts/rename-binary.js"
17
+ "postinstall": "node scripts/fetch-binary.js || npm run build:go"
19
18
  },
20
19
  "files": [
21
20
  "dist/",
22
21
  "lib/go.mod",
23
22
  "lib/go.sum",
24
23
  "lib/main.go",
25
- "scripts/rename-binary.js"
24
+ "scripts/fetch-binary.js"
26
25
  ],
27
26
  "repository": {
28
27
  "type": "git",
@@ -39,36 +38,33 @@
39
38
  "main": "dist/index.js",
40
39
  "types": "dist/index.d.ts",
41
40
  "binary": {
42
- "module_name": "balena_compose_parser",
43
- "module_path": "bin/",
44
- "remote_path": "v{version}",
45
- "package_name": "balena-compose-go-{platform}-{arch}.tar.gz",
46
- "host": "https://github.com/balena-io-experimental/balena-compose-parser/releases/download/"
41
+ "moduleName": "balena-compose-parser",
42
+ "modulePath": "bin/",
43
+ "packageName": "balena-compose-parser-{platform}-{arch}.tar.gz",
44
+ "remotePath": "https://github.com/balena-io-experimental/balena-compose-parser/releases/download/v{version}/"
47
45
  },
48
46
  "devDependencies": {
49
47
  "@balena/lint": "^9.3.3",
50
48
  "@types/chai": "^5.2.2",
51
- "@types/js-yaml": "^4.0.9",
52
49
  "@types/mocha": "^10.0.10",
53
50
  "@types/node": "^24.3.1",
54
51
  "@types/semver": "^7.7.1",
55
52
  "@types/sinon": "^17.0.4",
56
53
  "chai": "^6.0.1",
57
- "js-yaml": "^4.1.0",
58
54
  "mocha": "^11.7.2",
59
55
  "rimraf": "^6.0.1",
60
56
  "sinon": "^21.0.0",
57
+ "tar": "^7.4.3",
61
58
  "ts-mocha": "^11.1.0",
62
59
  "ts-node": "^10.9.2",
63
60
  "tsconfig-paths": "^4.2.0",
64
61
  "typescript": "^5.9.2"
65
62
  },
66
63
  "dependencies": {
67
- "@mapbox/node-pre-gyp": "^2.0.0",
68
64
  "semver": "^7.7.2",
69
65
  "typed-error": "^3.2.2"
70
66
  },
71
67
  "versionist": {
72
- "publishedAt": "2025-09-17T00:58:08.207Z"
68
+ "publishedAt": "2025-09-17T18:50:38.541Z"
73
69
  }
74
70
  }
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env node
2
+
3
+ const https = require('https');
4
+ const { promises: fs } = require('fs');
5
+ const path = require('path');
6
+ const { pipeline } = require('stream');
7
+ const { promisify } = require('util');
8
+ const zlib = require('zlib');
9
+ const tar = require('tar');
10
+ const packageJson = require('../package.json');
11
+
12
+ const streamPipeline = promisify(pipeline);
13
+
14
+
15
+ (async () => {
16
+ console.log('Fetching prebuilt Go binary...');
17
+ await fetchBinary();
18
+ })();
19
+
20
+ function getPlatform() {
21
+ const platform = process.platform;
22
+ switch (platform) {
23
+ case 'darwin':
24
+ return 'darwin';
25
+ case 'linux':
26
+ return 'linux';
27
+ case 'win32':
28
+ return 'windows';
29
+ default:
30
+ throw new Error(`Unsupported platform: ${platform}`);
31
+ }
32
+ }
33
+
34
+ function getArch() {
35
+ const arch = process.arch;
36
+ switch (arch) {
37
+ case 'x64':
38
+ return 'amd64';
39
+ case 'arm64':
40
+ return 'arm64';
41
+ default:
42
+ throw new Error(`Unsupported architecture: ${arch}`);
43
+ }
44
+ }
45
+
46
+ function getBinaryUrl() {
47
+ const config = packageJson.binary;
48
+ if (!config) {
49
+ throw new Error('No binary configuration found in package.json');
50
+ }
51
+
52
+ const platform = getPlatform();
53
+ const arch = getArch();
54
+ const version = packageJson.version;
55
+
56
+ const packageName = config.packageName
57
+ .replace('{platform}', platform)
58
+ .replace('{arch}', arch);
59
+
60
+ const url = config.remotePath
61
+ .replace('{version}', version) + packageName;
62
+
63
+ return url;
64
+ }
65
+
66
+ function downloadFile(url) {
67
+ return new Promise((resolve, reject) => {
68
+ console.log(`Downloading binary from: ${url}`);
69
+
70
+ https.get(url, (response) => {
71
+ if (response.statusCode === 302 || response.statusCode === 301) {
72
+ // Follow redirect
73
+ return downloadFile(response.headers.location).then(resolve).catch(reject);
74
+ }
75
+
76
+ if (response.statusCode !== 200) {
77
+ reject(new Error(`Failed to download: HTTP ${response.statusCode}`));
78
+ return;
79
+ }
80
+
81
+ resolve(response);
82
+ }).on('error', reject);
83
+ });
84
+ }
85
+
86
+ async function extractTarGz(stream, targetDir) {
87
+ await streamPipeline(
88
+ stream,
89
+ zlib.createGunzip(),
90
+ tar.extract({
91
+ cwd: targetDir,
92
+ strip: 0
93
+ })
94
+ );
95
+ }
96
+
97
+ async function fetchBinary() {
98
+ try {
99
+ const config = packageJson.binary;
100
+ const binDir = path.join(__dirname, '..', config.modulePath);
101
+ const binaryName = `${config.moduleName}${process.platform === 'win32' ? '.exe' : ''}`;
102
+ const binaryPath = path.join(binDir, binaryName);
103
+
104
+ // Check if binary already exists
105
+ if (await fs.exists(binaryPath)) {
106
+ console.log(`Binary already exists at ${binaryPath}`);
107
+ return;
108
+ }
109
+
110
+ // Create bin directory if it doesn't exist
111
+ if (!(await fs.exists(binDir))) {
112
+ await fs.mkdir(binDir, { recursive: true });
113
+ }
114
+
115
+ // Download binary
116
+ const url = getBinaryUrl();
117
+ const response = await downloadFile(url);
118
+
119
+ // Extract tar.gz to bin directory
120
+ console.log(`Extracting binary to ${binDir}`);
121
+ await extractTarGz(response, binDir);
122
+
123
+ // Make binary executable on Unix systems
124
+ if (process.platform !== 'win32') {
125
+ await fs.chmod(binaryPath, 0o755);
126
+ }
127
+
128
+ console.log(`Binary successfully installed at ${binaryPath}`);
129
+ process.exit(0);
130
+ } catch (error) {
131
+ console.error(`Failed to fetch binary: ${error.message}`);
132
+ process.exit(1);
133
+ }
134
+ }
@@ -1,31 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('fs');
4
- const path = require('path');
5
-
6
- const binDir = path.join(__dirname, '..', 'bin');
7
-
8
- if (!fs.existsSync(binDir)) {
9
- console.debug('Binary directory does not exist, skipping rename');
10
- process.exit(0);
11
- }
12
-
13
- // Find file matching balena_compose_parser.node
14
- const files = fs.readdirSync(binDir).filter(f => f.match(/^balena_compose_parser\.node$/));
15
-
16
- if (files.length === 0) {
17
- console.debug('No binary file found, skipping rename');
18
- process.exit(0);
19
- }
20
-
21
- const sourceFile = path.join(binDir, files[0]);
22
- const targetFile = path.join(binDir, `balena_compose_parser${process.platform === 'win32' ? '.exe' : ''}`);
23
-
24
- // Rename the file
25
- try {
26
- fs.renameSync(sourceFile, targetFile);
27
- console.debug('Binary file renamed successfully');
28
- } catch (err) {
29
- console.error(`Failed to rename binary file: ${err.message}`);
30
- process.exit(1);
31
- }