Compare commits

...

1 Commits

Author SHA1 Message Date
507c54f37c Update balena-sdk to v22
Bump balena-sdk from 21.3.0 to 22.0.0

Change-type: patch
2025-06-18 11:48:30 -03:00
26 changed files with 696 additions and 384 deletions

572
npm-shrinkwrap.json generated
View File

@ -21,7 +21,7 @@
"balena-errors": "^4.7.3",
"balena-image-fs": "^7.5.2",
"balena-preload": "^18.0.4",
"balena-sdk": "^21.3.0",
"balena-sdk": "22.0.0-build-bump-pinejs-client-core-v2-49804ae555361fbb1685b6a6a727892b801f0bcc-3",
"balena-semver": "^2.3.0",
"balena-settings-client": "^5.0.2",
"balena-settings-storage": "^8.1.0",
@ -1341,48 +1341,33 @@
}
},
"node_modules/@balena/abstract-sql-compiler": {
"version": "9.2.0",
"resolved": "https://registry.npmjs.org/@balena/abstract-sql-compiler/-/abstract-sql-compiler-9.2.0.tgz",
"integrity": "sha512-sKSbGNcL19QvqUrslms/k8GsVWjq75g0b8uVh/jpZEUWHniixWq402b+OKs0wRIhtRMsWSVA3CLuC33tYj6KCA==",
"dependencies": {
"@balena/sbvr-types": "^7.0.1",
"lodash": "^4.17.21"
},
"version": "10.3.2",
"resolved": "https://registry.npmjs.org/@balena/abstract-sql-compiler/-/abstract-sql-compiler-10.3.2.tgz",
"integrity": "sha512-5gtvMhK4VZ4bKA1AtNjx+BQ8P4x1l0+NuNvylXCxMfhjbwqUoe8acTyZQP55sZOpm3Zc7fugln/5jaHlBpTtZA==",
"engines": {
"node": ">=16.13.0",
"npm": ">=8.1.0"
}
},
"node_modules/@balena/abstract-sql-compiler/node_modules/@balena/sbvr-types": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@balena/sbvr-types/-/sbvr-types-7.1.3.tgz",
"integrity": "sha512-kizk+ClfYJVJidMx69BiFSFqtDE97R4JXRYrn1Ff/vK+ycN7Mj3HVObFk5DvckresiBI9S2mvZsysW+RVNmJsg==",
"engines": {
"node": ">=16.13.0",
"npm": ">=8.1.0"
"node": ">=20.14.0",
"npm": ">=10.7.0"
},
"optionalDependencies": {
"bcrypt": "^5.1.1",
"bcryptjs": "^2.4.3",
"sha.js": "^2.4.11"
"peerDependencies": {
"@balena/sbvr-types": "^7.1.0 || ^8.0.0 || ^9.0.2"
}
},
"node_modules/@balena/abstract-sql-to-typescript": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/@balena/abstract-sql-to-typescript/-/abstract-sql-to-typescript-4.0.6.tgz",
"integrity": "sha512-OPfXbrM08VB7Uywr3QtlaJLIelsW55mgb9hYTgjlwW+mA3ZgvxBtr9DbKcAGujB2xNxwHBXCqwafP4X3CzGJ+Q==",
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/@balena/abstract-sql-to-typescript/-/abstract-sql-to-typescript-5.1.1.tgz",
"integrity": "sha512-4DSh2b1ORYyJ+9kd71mXApsHPztAzgv6zJQqSD+V251Zl+QCdxlmDJhl29R/PhGIp5rDvkoV+v/WAs/aQU/ubA==",
"dependencies": {
"@balena/abstract-sql-compiler": "^9.2.0",
"@balena/odata-to-abstract-sql": "^6.3.0",
"@balena/abstract-sql-compiler": "^10.0.1",
"@balena/odata-to-abstract-sql": "^7.0.0",
"@types/node": "^20.16.5",
"common-tags": "^1.8.2"
},
"engines": {
"node": ">=16.13.0",
"npm": ">=8.1.0"
"node": ">=20.14.0",
"npm": ">=10.7.0"
},
"peerDependencies": {
"@balena/sbvr-types": "^7.1.0, ^8.0.0, ^9.0.0"
"@balena/sbvr-types": "^7.1.0 || ^8.0.0 || ^9.0.0"
}
},
"node_modules/@balena/apple-plist": {
@ -1566,9 +1551,9 @@
}
},
"node_modules/@balena/lint/node_modules/@eslint/js": {
"version": "9.28.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.28.0.tgz",
"integrity": "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==",
"version": "9.29.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.29.0.tgz",
"integrity": "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==",
"dev": true,
"license": "MIT",
"engines": {
@ -1592,15 +1577,6 @@
"url": "https://github.com/sponsors/nzakas"
}
},
"node_modules/@balena/lint/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/@balena/lint/node_modules/cliui": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
@ -1642,19 +1618,19 @@
}
},
"node_modules/@balena/lint/node_modules/eslint": {
"version": "9.28.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.28.0.tgz",
"integrity": "sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==",
"version": "9.29.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.29.0.tgz",
"integrity": "sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.12.1",
"@eslint/config-array": "^0.20.0",
"@eslint/config-array": "^0.20.1",
"@eslint/config-helpers": "^0.2.1",
"@eslint/core": "^0.14.0",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "9.28.0",
"@eslint/js": "9.29.0",
"@eslint/plugin-kit": "^0.3.1",
"@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
@ -1666,9 +1642,9 @@
"cross-spawn": "^7.0.6",
"debug": "^4.3.2",
"escape-string-regexp": "^4.0.0",
"eslint-scope": "^8.3.0",
"eslint-visitor-keys": "^4.2.0",
"espree": "^10.3.0",
"eslint-scope": "^8.4.0",
"eslint-visitor-keys": "^4.2.1",
"espree": "^10.4.0",
"esquery": "^1.5.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
@ -1703,9 +1679,9 @@
}
},
"node_modules/@balena/lint/node_modules/eslint-scope": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz",
"integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==",
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
"integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@ -1720,9 +1696,9 @@
}
},
"node_modules/@balena/lint/node_modules/eslint-visitor-keys": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
"integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@ -1733,15 +1709,15 @@
}
},
"node_modules/@balena/lint/node_modules/espree": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
"integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"acorn": "^8.14.0",
"acorn": "^8.15.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^4.2.0"
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -1776,15 +1752,15 @@
}
},
"node_modules/@balena/lint/node_modules/glob": {
"version": "11.0.2",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.2.tgz",
"integrity": "sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==",
"version": "11.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz",
"integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==",
"dev": true,
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^4.0.1",
"minimatch": "^10.0.0",
"foreground-child": "^3.3.1",
"jackspeak": "^4.1.1",
"minimatch": "^10.0.3",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^2.0.0"
@ -1812,12 +1788,13 @@
}
},
"node_modules/@balena/lint/node_modules/glob/node_modules/minimatch": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
"integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz",
"integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
"@isaacs/brace-expansion": "^5.0.0"
},
"engines": {
"node": "20 || >=22"
@ -1978,27 +1955,30 @@
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/@balena/node-web-streams/-/node-web-streams-0.2.4.tgz",
"integrity": "sha512-Q9By3GPzANMZuf1i5i7Agyh6BUe6tTa+VCCZzsFzU32iXMcuDRXYHbNIKESrcjVXxiZScPB4u++WPw4LRyK1Gg==",
"license": "Apache-2.0",
"dependencies": {
"is-stream": "^1.1.0",
"web-streams-polyfill": "^3.1.0"
}
},
"node_modules/@balena/odata-parser": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@balena/odata-parser/-/odata-parser-3.1.2.tgz",
"integrity": "sha512-RBLqz1u945NgQ+Ds2YS1VXnk1ViFHoNIuRyROHGDmmp6LrczBq8fSZAs+cxb7URZptOryLBhQKwf3m23xUa11Q==",
"version": "4.2.6",
"resolved": "https://registry.npmjs.org/@balena/odata-parser/-/odata-parser-4.2.6.tgz",
"integrity": "sha512-gcEZg3P0mJeS2j01ktJT6lCqnpm2L+VayGcqLldqtq5MMu8CL1TSURl0RoYOxP6E1Ffpjget6vMI9k1ITerVlQ==",
"license": "BSD",
"engines": {
"node": ">=16.13.0",
"npm": ">=8.1.0"
}
},
"node_modules/@balena/odata-to-abstract-sql": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/@balena/odata-to-abstract-sql/-/odata-to-abstract-sql-6.4.0.tgz",
"integrity": "sha512-GMC8AP0HAS1Di5jM+JEjVEque4cQxLK77MQLVXgGI8dJK/UGwUDt/ThwOeqPTUKBHjUGPhiQgY6WedCHyM3zqw==",
"version": "7.2.5",
"resolved": "https://registry.npmjs.org/@balena/odata-to-abstract-sql/-/odata-to-abstract-sql-7.2.5.tgz",
"integrity": "sha512-nue2BxnYuJSb8E4PsMmUPGW3IjE84Jo1k23AR/ofhCj3XYv6BdzfKFLjOz3dg7cXjl8OzRYwBcjE3Xt/kibmiA==",
"license": "BSD",
"dependencies": {
"@balena/abstract-sql-compiler": "^9.2.0",
"@balena/odata-parser": "^3.1.0",
"@balena/abstract-sql-compiler": "^10.2.0",
"@balena/odata-parser": "^4.2.1",
"@types/lodash": "^4.17.10",
"@types/memoizee": "^0.4.11",
"@types/string-hash": "^1.1.3",
@ -2007,14 +1987,14 @@
"string-hash": "^1.1.3"
},
"engines": {
"node": ">=16.13.0",
"npm": ">=8.1.0"
"node": ">=20.14.0",
"npm": ">=10.7.0"
}
},
"node_modules/@balena/sbvr-types": {
"version": "9.2.4",
"resolved": "https://registry.npmjs.org/@balena/sbvr-types/-/sbvr-types-9.2.4.tgz",
"integrity": "sha512-qiyys96H3x3atw0PNJ9y69a8sFzDGWBtDUVxE6BDerrabnypJr5u3spH9Z3hvcnGHTX9HhGHk5UKW9LgTPWt9Q==",
"version": "9.2.6",
"resolved": "https://registry.npmjs.org/@balena/sbvr-types/-/sbvr-types-9.2.6.tgz",
"integrity": "sha512-QjvmhN/3ZNZBOml49Z0RXobcWJcFYT4vXVr2rNDhSuy75AKMxplBB53w4TkRm/uaeapvfNOE1aolEXqMWRVdVg==",
"license": "BSD",
"peer": true,
"engines": {
@ -2023,10 +2003,21 @@
},
"optionalDependencies": {
"bcrypt": "^5.1.1",
"bcryptjs": "^2.4.3",
"bcryptjs": "^3.0.0",
"sha.js": "^2.4.11"
}
},
"node_modules/@balena/sbvr-types/node_modules/bcryptjs": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.2.tgz",
"integrity": "sha512-k38b3XOZKv60C4E2hVsXTolJWfkGRMbILBIe2IBITXciy5bOsTKot5kDrf3ZfufQtQOUN5mXceUEpU1rTl9Uog==",
"license": "BSD-3-Clause",
"optional": true,
"peer": true,
"bin": {
"bcrypt": "bin/bcrypt"
}
},
"node_modules/@balena/udif": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@balena/udif/-/udif-1.1.2.tgz",
@ -2136,9 +2127,9 @@
}
},
"node_modules/@eslint/config-array": {
"version": "0.20.0",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.0.tgz",
"integrity": "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==",
"version": "0.20.1",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.1.tgz",
"integrity": "sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@ -2596,9 +2587,9 @@
}
},
"node_modules/@inquirer/core/node_modules/@types/node": {
"version": "22.15.30",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.30.tgz",
"integrity": "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA==",
"version": "22.15.32",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.32.tgz",
"integrity": "sha512-3jigKqgSjsH6gYZv2nEsqdXfZqIFGAV36XYYjf9KGZ3PSG+IhLecqPnI310RvjutyMwifE2hhhNEklOUrvx/wA==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -3809,6 +3800,29 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/@isaacs/balanced-match": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
"integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "20 || >=22"
}
},
"node_modules/@isaacs/brace-expansion": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
"integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@isaacs/balanced-match": "^4.0.1"
},
"engines": {
"node": "20 || >=22"
}
},
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@ -4161,9 +4175,10 @@
}
},
"node_modules/@oclif/core/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
@ -5046,9 +5061,9 @@
}
},
"node_modules/@sentry/node/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@ -6212,9 +6227,10 @@
"integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg=="
},
"node_modules/@types/memoizee": {
"version": "0.4.11",
"resolved": "https://registry.npmjs.org/@types/memoizee/-/memoizee-0.4.11.tgz",
"integrity": "sha512-2gyorIBZu8GoDr9pYjROkxWWcFtHCquF7TVbN2I+/OvgZhnIGQS0vX5KJz4lXNKb8XOSfxFOSG5OLru1ESqLUg=="
"version": "0.4.12",
"resolved": "https://registry.npmjs.org/@types/memoizee/-/memoizee-0.4.12.tgz",
"integrity": "sha512-EdtpwNYNhe3kZ+4TlXj/++pvBoU0KdrAICMzgI7vjWgu9sIvvUhu9XR8Ks4L6Wh3sxpZ22wkZR7yCLAqUjnZuQ==",
"license": "MIT"
},
"node_modules/@types/mime": {
"version": "3.0.4",
@ -6281,9 +6297,9 @@
}
},
"node_modules/@types/node": {
"version": "20.19.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.0.tgz",
"integrity": "sha512-hfrc+1tud1xcdVTABC2JiomZJEklMcXYNTVtZLAeqTVWD+qL5jkHKT+1lOtqDdGxt+mB53DTtiz673vfjU8D1Q==",
"version": "20.19.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.1.tgz",
"integrity": "sha512-jJD50LtlD2dodAEO653i3YF04NWak6jN3ky+Ri3Em3mGR39/glWiboM/IePaRbgwSfqM1TpGXfAg8ohn/4dTgA==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
@ -6374,9 +6390,10 @@
}
},
"node_modules/@types/semver": {
"version": "7.5.3",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz",
"integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw=="
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.0.tgz",
"integrity": "sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==",
"license": "MIT"
},
"node_modules/@types/serve-static": {
"version": "1.13.10",
@ -6460,7 +6477,8 @@
"node_modules/@types/string-hash": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@types/string-hash/-/string-hash-1.1.3.tgz",
"integrity": "sha512-p6skq756fJWiA59g2Uss+cMl6tpoDGuCBuxG0SI1t0NwJmYOU66LAMS6QiCgu7cUh3/hYCaMl5phcCW1JP5wOA=="
"integrity": "sha512-p6skq756fJWiA59g2Uss+cMl6tpoDGuCBuxG0SI1t0NwJmYOU66LAMS6QiCgu7cUh3/hYCaMl5phcCW1JP5wOA==",
"license": "MIT"
},
"node_modules/@types/tar-stream": {
"version": "2.2.2",
@ -6684,9 +6702,9 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -6752,9 +6770,9 @@
}
},
"node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
"integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
@ -6855,9 +6873,10 @@
}
},
"node_modules/acorn": {
"version": "8.14.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
"version": "8.15.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
@ -7477,6 +7496,74 @@
"node": "^20.12.0 || >=22.0.0"
}
},
"node_modules/balena-preload/node_modules/balena-sdk": {
"version": "21.6.1",
"resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-21.6.1.tgz",
"integrity": "sha512-fQrRc/My28dPYYm/kzroJmjtHtpYizP769guIwYwLBPcLXLFI5/PEC4XrjZFVPbQ2x6xRLxJxcZY3y4uVA2SeQ==",
"license": "Apache-2.0",
"dependencies": {
"@balena/es-version": "^1.0.0",
"@types/json-schema": "^7.0.9",
"@types/node": "^20.17.8",
"abortcontroller-polyfill": "^1.7.1",
"balena-auth": "^6.0.1",
"balena-errors": "^4.9.0",
"balena-hup-action-utils": "~6.2.0",
"balena-register-device": "^9.0.4",
"balena-request": "^14.0.8",
"balena-semver": "^3.0.0",
"balena-settings-client": "^5.0.0",
"date-fns": "^3.0.5",
"handlebars": "^4.7.7",
"lodash": "^4.17.21",
"memoizee": "^0.4.15",
"mime": "^3.0.0",
"ndjson": "^2.0.0",
"p-throttle": "^4.1.1",
"pinejs-client-core": "^7.0.0",
"tslib": "^2.1.0"
},
"engines": {
"node": "^20.12.0 || >= 22.0.0"
}
},
"node_modules/balena-preload/node_modules/balena-semver": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/balena-semver/-/balena-semver-3.0.7.tgz",
"integrity": "sha512-PkYs+04bINIGxSciPJ4zDn/Wa6ocy/XzooSYEE4yGUe/TcIAANDpihK71ryH6dsMlG8hzanCrdsjFkT2KobbIw==",
"license": "Apache-2.0",
"dependencies": {
"@types/lodash": "^4.14.200",
"@types/semver": "^7.5.4",
"lodash": "^4.17.21",
"semver": "^7.5.4"
},
"engines": {
"node": ">=16"
}
},
"node_modules/balena-preload/node_modules/date-fns": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz",
"integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/kossnocorp"
}
},
"node_modules/balena-preload/node_modules/mime": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
"integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==",
"license": "MIT",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/balena-register-device": {
"version": "9.0.4",
"resolved": "https://registry.npmjs.org/balena-register-device/-/balena-register-device-9.0.4.tgz",
@ -7496,9 +7583,10 @@
}
},
"node_modules/balena-request": {
"version": "14.0.1",
"resolved": "https://registry.npmjs.org/balena-request/-/balena-request-14.0.1.tgz",
"integrity": "sha512-D6sQyeOZNoR736WVBD5F0AL/XsiGTioD9vaDpiqQJZvhShTDVzbNXkW7Sd+QCGrSP3gpdqorGN7hyEZsv5WZlA==",
"version": "14.0.6",
"resolved": "https://registry.npmjs.org/balena-request/-/balena-request-14.0.6.tgz",
"integrity": "sha512-SRl4kr2AhQVQB2kgmq3sArn0uaumja0fj9Wy7r3hMLI+wJGyJqnKyePzzLsWtxImOxnGTkhWLcy/oYzR2buuXg==",
"license": "Apache-2.0",
"dependencies": {
"@balena/node-web-streams": "^0.2.3",
"balena-errors": "^4.9.0",
@ -7519,11 +7607,12 @@
}
},
"node_modules/balena-sdk": {
"version": "21.3.0",
"resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-21.3.0.tgz",
"integrity": "sha512-3Ub2doNsXwBPoRNr/feoMY18tXCUOTkclq6/Qe3lEiQA40/Q/pBfglveVXuOV6P2ljyC6jayJ8aR/3r5Kov/2w==",
"version": "22.0.0-build-bump-pinejs-client-core-v2-49804ae555361fbb1685b6a6a727892b801f0bcc-3",
"resolved": "https://registry.npmjs.org/balena-sdk/-/balena-sdk-22.0.0-build-bump-pinejs-client-core-v2-49804ae555361fbb1685b6a6a727892b801f0bcc-3.tgz",
"integrity": "sha512-ySdLK739ksmtwgEsrGL4I5pkXqCyBcxCmFNMd5zBEbgfMKscrTIHr3aJnpbUf3UiHpzWfkHAXfOn921xsp4Vzw==",
"license": "Apache-2.0",
"dependencies": {
"@balena/abstract-sql-to-typescript": "^5.1.1",
"@balena/es-version": "^1.0.0",
"@types/json-schema": "^7.0.9",
"@types/node": "^20.17.8",
@ -7532,8 +7621,8 @@
"balena-errors": "^4.9.0",
"balena-hup-action-utils": "~6.2.0",
"balena-register-device": "^9.0.4",
"balena-request": "^14.0.0",
"balena-semver": "^2.3.0",
"balena-request": "^14.0.8",
"balena-semver": "^3.0.0",
"balena-settings-client": "^5.0.0",
"date-fns": "^3.0.5",
"handlebars": "^4.7.7",
@ -7542,13 +7631,28 @@
"mime": "^3.0.0",
"ndjson": "^2.0.0",
"p-throttle": "^4.1.1",
"pinejs-client-core": "^7.0.0",
"pinejs-client-core": "^8.2.0",
"tslib": "^2.1.0"
},
"engines": {
"node": "^20.12.0 || >= 22.0.0"
}
},
"node_modules/balena-sdk/node_modules/balena-semver": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/balena-semver/-/balena-semver-3.0.7.tgz",
"integrity": "sha512-PkYs+04bINIGxSciPJ4zDn/Wa6ocy/XzooSYEE4yGUe/TcIAANDpihK71ryH6dsMlG8hzanCrdsjFkT2KobbIw==",
"license": "Apache-2.0",
"dependencies": {
"@types/lodash": "^4.14.200",
"@types/semver": "^7.5.4",
"lodash": "^4.17.21",
"semver": "^7.5.4"
},
"engines": {
"node": ">=16"
}
},
"node_modules/balena-sdk/node_modules/date-fns": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz",
@ -7571,6 +7675,19 @@
"node": ">=10.0.0"
}
},
"node_modules/balena-sdk/node_modules/pinejs-client-core": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/pinejs-client-core/-/pinejs-client-core-8.2.0.tgz",
"integrity": "sha512-Q6Q64LOiJvWtqEVkJd8w3wmHBzbqS5nsBs8DwCtxvEHP5y5fDWQtXvlOuRX5Km/TVhbN0tO70K9cfVX30/bJ6A==",
"license": "MIT",
"dependencies": {
"@balena/abstract-sql-to-typescript": "^5.0.0"
},
"engines": {
"node": ">=10.0.0",
"npm": ">=6.0.0"
}
},
"node_modules/balena-semver": {
"version": "2.3.5",
"resolved": "https://registry.npmjs.org/balena-semver/-/balena-semver-2.3.5.tgz",
@ -7877,9 +7994,10 @@
}
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -9194,10 +9312,11 @@
}
},
"node_modules/depcheck/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
@ -9540,9 +9659,9 @@
}
},
"node_modules/drivelist/node_modules/node-addon-api": {
"version": "8.3.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.1.tgz",
"integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==",
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.4.0.tgz",
"integrity": "sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==",
"license": "MIT",
"engines": {
"node": "^18 || ^20 || >= 21"
@ -9665,9 +9784,10 @@
}
},
"node_modules/end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
"integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
"license": "MIT",
"dependencies": {
"once": "^1.4.0"
}
@ -10063,10 +10183,11 @@
}
},
"node_modules/eslint-plugin-jsdoc/node_modules/eslint-visitor-keys": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
"integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
@ -10075,14 +10196,15 @@
}
},
"node_modules/eslint-plugin-jsdoc/node_modules/espree": {
"version": "10.3.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
"integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"acorn": "^8.14.0",
"acorn": "^8.15.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^4.2.0"
"eslint-visitor-keys": "^4.2.1"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -10459,9 +10581,9 @@
}
},
"node_modules/etcher-sdk/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@ -10855,10 +10977,31 @@
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-7.1.0.tgz",
"integrity": "sha512-FhbbL55dj/qdVO3YNK7ZEkshvj3eQ7EuIGV2I6ic/2YiocvyWv+7jg2s4AyS0wdRU75s3tA8ZxI/xPigb0v5Aw==",
"license": "MIT",
"dependencies": {
"node-fetch": "~2.6.1"
}
},
"node_modules/fetch-ponyfill/node_modules/node-fetch": {
"version": "2.6.13",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz",
"integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==",
"license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/fetch-readablestream": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/fetch-readablestream/-/fetch-readablestream-0.2.0.tgz",
@ -10931,9 +11074,10 @@
}
},
"node_modules/filelist/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
@ -11119,11 +11263,12 @@
}
},
"node_modules/foreground-child": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
"integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
"integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
"license": "ISC",
"dependencies": {
"cross-spawn": "^7.0.0",
"cross-spawn": "^7.0.6",
"signal-exit": "^4.0.1"
},
"engines": {
@ -14304,10 +14449,11 @@
}
},
"node_modules/mocha/node_modules/brace-expansion": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
@ -14703,9 +14849,11 @@
}
},
"node_modules/node-fetch": {
"version": "2.6.13",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz",
"integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==",
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"license": "MIT",
"optional": true,
"dependencies": {
"whatwg-url": "^5.0.0"
},
@ -15152,10 +15300,11 @@
}
},
"node_modules/oclif/node_modules/normalize-url": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz",
"integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==",
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.2.tgz",
"integrity": "sha512-Ee/R3SyN4BuynXcnTaekmaVdbDAEiNrHqjQIA37mHU8G9pf7aaAD4ZX3XjBLo6rsdcxA/gtkcNYZLt30ACgynw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14.16"
},
@ -15976,6 +16125,7 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/pinejs-client-core/-/pinejs-client-core-7.2.0.tgz",
"integrity": "sha512-47ZWj2HbhKKLUbvnutohzh75972esGM+CO+a331/ldIgNhLZ5DYfIBrHlR4C9RBiEXC2Us9qD0twyi4qnZJ2xg==",
"license": "MIT",
"dependencies": {
"@balena/abstract-sql-to-typescript": "^4.0.0",
"@balena/es-version": "^1.0.3"
@ -15985,6 +16135,82 @@
"npm": ">=6.0.0"
}
},
"node_modules/pinejs-client-core/node_modules/@balena/abstract-sql-compiler": {
"version": "9.2.0",
"resolved": "https://registry.npmjs.org/@balena/abstract-sql-compiler/-/abstract-sql-compiler-9.2.0.tgz",
"integrity": "sha512-sKSbGNcL19QvqUrslms/k8GsVWjq75g0b8uVh/jpZEUWHniixWq402b+OKs0wRIhtRMsWSVA3CLuC33tYj6KCA==",
"dependencies": {
"@balena/sbvr-types": "^7.0.1",
"lodash": "^4.17.21"
},
"engines": {
"node": ">=16.13.0",
"npm": ">=8.1.0"
}
},
"node_modules/pinejs-client-core/node_modules/@balena/abstract-sql-compiler/node_modules/@balena/sbvr-types": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@balena/sbvr-types/-/sbvr-types-7.1.3.tgz",
"integrity": "sha512-kizk+ClfYJVJidMx69BiFSFqtDE97R4JXRYrn1Ff/vK+ycN7Mj3HVObFk5DvckresiBI9S2mvZsysW+RVNmJsg==",
"license": "BSD",
"engines": {
"node": ">=16.13.0",
"npm": ">=8.1.0"
},
"optionalDependencies": {
"bcrypt": "^5.1.1",
"bcryptjs": "^2.4.3",
"sha.js": "^2.4.11"
}
},
"node_modules/pinejs-client-core/node_modules/@balena/abstract-sql-to-typescript": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/@balena/abstract-sql-to-typescript/-/abstract-sql-to-typescript-4.0.6.tgz",
"integrity": "sha512-OPfXbrM08VB7Uywr3QtlaJLIelsW55mgb9hYTgjlwW+mA3ZgvxBtr9DbKcAGujB2xNxwHBXCqwafP4X3CzGJ+Q==",
"dependencies": {
"@balena/abstract-sql-compiler": "^9.2.0",
"@balena/odata-to-abstract-sql": "^6.3.0",
"@types/node": "^20.16.5",
"common-tags": "^1.8.2"
},
"engines": {
"node": ">=16.13.0",
"npm": ">=8.1.0"
},
"peerDependencies": {
"@balena/sbvr-types": "^7.1.0, ^8.0.0, ^9.0.0"
}
},
"node_modules/pinejs-client-core/node_modules/@balena/odata-parser": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@balena/odata-parser/-/odata-parser-3.1.2.tgz",
"integrity": "sha512-RBLqz1u945NgQ+Ds2YS1VXnk1ViFHoNIuRyROHGDmmp6LrczBq8fSZAs+cxb7URZptOryLBhQKwf3m23xUa11Q==",
"license": "BSD",
"engines": {
"node": ">=16.13.0",
"npm": ">=8.1.0"
}
},
"node_modules/pinejs-client-core/node_modules/@balena/odata-to-abstract-sql": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/@balena/odata-to-abstract-sql/-/odata-to-abstract-sql-6.4.0.tgz",
"integrity": "sha512-GMC8AP0HAS1Di5jM+JEjVEque4cQxLK77MQLVXgGI8dJK/UGwUDt/ThwOeqPTUKBHjUGPhiQgY6WedCHyM3zqw==",
"license": "BSD",
"dependencies": {
"@balena/abstract-sql-compiler": "^9.2.0",
"@balena/odata-parser": "^3.1.0",
"@types/lodash": "^4.17.10",
"@types/memoizee": "^0.4.11",
"@types/string-hash": "^1.1.3",
"lodash": "^4.17.21",
"memoizee": "^0.4.17",
"string-hash": "^1.1.3"
},
"engines": {
"node": ">=16.13.0",
"npm": ">=8.1.0"
}
},
"node_modules/pinkie": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
@ -16321,9 +16547,10 @@
"integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
},
"node_modules/pump": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
"integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
"integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
"license": "MIT",
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
@ -17870,7 +18097,8 @@
"node_modules/string-hash": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz",
"integrity": "sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A=="
"integrity": "sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==",
"license": "CC0-1.0"
},
"node_modules/string-to-stream": {
"version": "3.0.1",
@ -19057,9 +19285,9 @@
}
},
"node_modules/usb/node_modules/node-addon-api": {
"version": "8.3.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.3.1.tgz",
"integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==",
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.4.0.tgz",
"integrity": "sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg==",
"license": "MIT",
"engines": {
"node": "^18 || ^20 || >= 21"

View File

@ -174,7 +174,7 @@
"balena-errors": "^4.7.3",
"balena-image-fs": "^7.5.2",
"balena-preload": "^18.0.4",
"balena-sdk": "^21.3.0",
"balena-sdk": "22.0.0-build-bump-pinejs-client-core-v2-49804ae555361fbb1685b6a6a727892b801f0bcc-3",
"balena-semver": "^2.3.0",
"balena-settings-client": "^5.0.2",
"balena-settings-storage": "^8.1.0",
@ -245,7 +245,8 @@
"overrides": {
"inline-source-cli": {
"inline-source": "^8.0.3"
}
},
"balena-request": "14.0.6"
},
"versionist": {
"publishedAt": "2025-06-09T20:05:10.116Z"

View File

@ -67,7 +67,7 @@ export default class APIKeyListCmd extends Command {
}
: {}),
},
$orderby: 'name asc',
$orderby: { name: 'asc' },
},
});
const fields = ['id', 'name', 'created_at', 'description', 'expiry_date'];

View File

@ -19,13 +19,7 @@ import { Args, Flags, Command } from '@oclif/core';
import { getBalenaSdk } from '../../utils/lazy';
import * as cf from '../../utils/common-flags';
import * as compose from '../../utils/compose';
import type {
ApplicationType,
BalenaSDK,
DeviceType,
PineOptions,
PineTypedResult,
} from 'balena-sdk';
import type { ApplicationType, BalenaSDK, DeviceType, Pine } from 'balena-sdk';
import {
buildArgDeprecation,
dockerignoreHelp,
@ -186,18 +180,24 @@ ${dockerignoreHelp}
if (opts.deviceType != null && opts.arch == null) {
try {
const deviceTypeOpts = {
$select: 'is_of__cpu_architecture',
$select: 'id',
$expand: {
is_of__cpu_architecture: {
$select: 'slug',
},
},
} satisfies PineOptions<DeviceType>;
} as const;
opts.arch = (
(await sdk.models.deviceType.get(
opts.deviceType,
deviceTypeOpts,
)) as PineTypedResult<DeviceType, typeof deviceTypeOpts>
)) as NonNullable<
Pine.OptionsToResponse<
DeviceType['Read'],
typeof deviceTypeOpts,
NonNullable<typeof opts.deviceType>
>
>
).is_of__cpu_architecture[0].slug;
} catch (err) {
const { ExpectedError } = await import('../../errors');
@ -257,7 +257,7 @@ ${dockerignoreHelp}
logger: import('../../utils/logger'),
composeOpts: ComposeOpts,
opts: {
appType?: Pick<ApplicationType, 'supports_multicontainer'>;
appType?: Pick<ApplicationType['Read'], 'supports_multicontainer'>;
arch: string;
deviceType: string;
buildEmulated: boolean;

View File

@ -24,6 +24,7 @@ import {
registrySecretsHelp,
buildArgDeprecation,
} from '../../utils/messages';
import type { getAppWithArch } from '../../utils/helpers';
import * as ca from '../../utils/common-args';
import * as compose from '../../utils/compose';
import type {
@ -41,14 +42,7 @@ import {
parseReleaseTagKeysAndValues,
} from '../../utils/compose_ts';
import { dockerCliFlags } from '../../utils/docker';
import type { ApplicationType, DeviceType, Release } from 'balena-sdk';
interface ApplicationWithArch {
id: number;
arch: string;
is_for__device_type: [Pick<DeviceType, 'slug'>];
application_type: [Pick<ApplicationType, 'slug' | 'supports_multicontainer'>];
}
import type { Release } from 'balena-sdk';
// TODO: For this special one we can't use Interfaces.InferredFlags/InferredArgs
// because of the 'registry-secrets' type which is defined in the actual code
@ -229,7 +223,7 @@ ${dockerignoreHelp}
logger: import('../../utils/logger'),
composeOpts: ComposeOpts,
opts: {
app: ApplicationWithArch; // the application instance to deploy to
app: Awaited<ReturnType<typeof getAppWithArch>>; // the application instance to deploy to
appName: string;
image?: string;
dockerfilePath?: string; // alternative Dockerfile
@ -324,7 +318,7 @@ ${dockerignoreHelp}
},
);
let release: Release | ComposeReleaseInfo['release'];
let release: Release['Read'] | ComposeReleaseInfo['release'];
if (appType.slug === 'legacy-v1' || appType.slug === 'legacy-v2') {
const { deployLegacy } = require('../../utils/deploy-legacy');

View File

@ -66,13 +66,15 @@ export default class DeviceTypeListCmd extends Command {
$orderby: { is_referenced_by__alias: 'asc' },
},
},
} satisfies BalenaSdk.PineOptions<BalenaSdk.DeviceType>;
} as const;
const dts = (
options.all
? await getBalenaSdk().models.deviceType.getAll(pineOptions)
: await getBalenaSdk().models.deviceType.getAllSupported(pineOptions)
) as Array<
BalenaSdk.PineTypedResult<BalenaSdk.DeviceType, typeof pineOptions>
) as BalenaSdk.Pine.OptionsToResponse<
BalenaSdk.DeviceType['Read'],
typeof pineOptions,
undefined
>;
interface DT {
slug: string;

View File

@ -21,7 +21,7 @@ import { expandForAppName } from '../../utils/helpers';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
import { jsonInfo } from '../../utils/messages';
import type { Application, Release } from 'balena-sdk';
import type { Application, Device, Pine, Release } from 'balena-sdk';
interface ExtendedDevice extends DeviceWithDeviceType {
dashboard_url?: string;
@ -77,24 +77,75 @@ export default class DeviceCmd extends Command {
const balena = getBalenaSdk();
const jsonExpand = {
$expand: {
device_tag: {
$select: ['tag_key', 'value'],
},
...expandForAppName.$expand,
},
} as const;
const jsonComputedFieldsSelect = {
$select: [
'overall_status',
'overall_progress',
'should_be_running__release',
],
} as const;
const tableParams = {
$select: [
'device_name',
'id',
'overall_status',
'is_online',
'ip_address',
'mac_address',
'last_connectivity_event',
'uuid',
'supervisor_version',
'is_web_accessible',
'note',
'os_version',
'memory_usage',
'memory_total',
'public_address',
'storage_block_device',
'storage_usage',
'storage_total',
'cpu_usage',
'cpu_temp',
'cpu_id',
'is_undervolted',
],
...expandForAppName,
} as const;
let device: ExtendedDevice;
if (options.json) {
const [deviceBase, deviceComputed] = await Promise.all([
balena.models.device.get(params.uuid, {
$expand: {
device_tag: {
$select: ['tag_key', 'value'],
},
...expandForAppName.$expand,
},
}),
balena.models.device.get(params.uuid, {
$select: [
'overall_status',
'overall_progress',
'should_be_running__release',
],
}),
balena.models.device.get(params.uuid, jsonExpand) as Promise<
NonNullable<
Pine.OptionsToResponse<
Device['Read'],
typeof jsonExpand,
typeof params.uuid
>
>
>,
balena.models.device.get(
params.uuid,
jsonComputedFieldsSelect,
) as Promise<
NonNullable<
Pine.OptionsToResponse<
Device['Read'],
typeof jsonComputedFieldsSelect,
typeof params.uuid
>
>
>,
]);
device = {
@ -102,33 +153,16 @@ export default class DeviceCmd extends Command {
...deviceComputed,
} as ExtendedDevice;
} else {
device = (await balena.models.device.get(params.uuid, {
$select: [
'device_name',
'id',
'overall_status',
'is_online',
'ip_address',
'mac_address',
'last_connectivity_event',
'uuid',
'supervisor_version',
'is_web_accessible',
'note',
'os_version',
'memory_usage',
'memory_total',
'public_address',
'storage_block_device',
'storage_usage',
'storage_total',
'cpu_usage',
'cpu_temp',
'cpu_id',
'is_undervolted',
],
...expandForAppName,
})) as ExtendedDevice;
device = (await balena.models.device.get(
params.uuid,
tableParams,
)) as NonNullable<
Pine.OptionsToResponse<
Device['Read'],
typeof tableParams,
typeof params.uuid
>
> as ExtendedDevice;
}
if (options.view) {
@ -142,15 +176,16 @@ export default class DeviceCmd extends Command {
device.dashboard_url = balena.models.device.getDashboardUrl(device.uuid);
const belongsToApplication =
device.belongs_to__application as Application[];
const belongsToApplication = device.belongs_to__application as [
Application['Read'],
];
device.fleet = belongsToApplication?.[0]
? belongsToApplication[0].slug
: 'N/a';
device.device_type = device.is_of__device_type[0].slug;
const isRunningRelease = device.is_running__release as Release[];
const isRunningRelease = device.is_running__release as [Release['Read']];
device.commit = isRunningRelease?.[0] ? isRunningRelease[0].commit : 'N/a';
device.last_seen = device.last_connectivity_event ?? undefined;

View File

@ -21,8 +21,6 @@ import { expandForAppName } from '../../utils/helpers';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
import { applicationIdInfo, jsonInfo } from '../../utils/messages';
import type { Device, PineOptions } from 'balena-sdk';
const devicesSelectFields = {
$select: [
'id',
@ -33,7 +31,7 @@ const devicesSelectFields = {
'supervisor_version',
'os_version',
],
} satisfies PineOptions<Device>;
} as const;
export default class DeviceListCmd extends Command {
public static aliases = ['devices'];
@ -73,7 +71,7 @@ export default class DeviceListCmd extends Command {
...devicesSelectFields,
...expandForAppName,
$orderby: { device_name: 'asc' },
} satisfies PineOptions<Device>;
} as const;
const devices = (
await (async () => {

View File

@ -16,12 +16,7 @@
*/
import { Args, Command } from '@oclif/core';
import type {
BalenaSDK,
Device,
PineOptions,
PineTypedResult,
} from 'balena-sdk';
import type { BalenaSDK, Device, Pine } from 'balena-sdk';
import * as cf from '../../utils/common-flags';
import { ExpectedError } from '../../errors';
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
@ -64,7 +59,7 @@ export default class DeviceMoveCmd extends Command {
$select: 'belongs_to__application',
$expand: {
is_of__device_type: {
$select: 'is_of__cpu_architecture',
$select: 'id',
$expand: {
is_of__cpu_architecture: {
$select: 'slug',
@ -72,14 +67,20 @@ export default class DeviceMoveCmd extends Command {
},
},
},
} satisfies PineOptions<Device>;
} as const;
// TODO: Refacor once `device.get()` accepts an array of uuids`
const devices = await Promise.all(
deviceUuids.map(
(uuid) =>
balena.models.device.get(uuid, deviceOptions) as Promise<
PineTypedResult<Device, typeof deviceOptions>
NonNullable<
Pine.OptionsToResponse<
Device['Read'],
typeof deviceOptions,
typeof uuid
>
>
>,
),
);

View File

@ -83,7 +83,7 @@ export default class DeviceOsUpdateCmd extends Command {
const currentOsVersion = sdk.models.device.getOsVersion({
os_version,
os_variant,
} as Device);
} as Device['Read']);
if (!currentOsVersion) {
throw new ExpectedError(
'The current os version of the device is not available',

View File

@ -240,7 +240,9 @@ async function getAppVars(
fillInInfoFields(vars, fleetSlug);
appVars.push(...vars);
if (!options.config) {
const pineOpts: SDK.PineOptions<SDK.ServiceEnvironmentVariable> = {
const pineOpts: SDK.Pine.ODataOptionsWithoutCount<
SDK.ServiceEnvironmentVariable['Read']
> = {
$expand: {
service: {},
},
@ -248,7 +250,14 @@ async function getAppVars(
if (options.service) {
pineOpts.$filter = {
service: {
service_name: options.service,
$any: {
$alias: 's',
$expr: {
s: {
service_name: options.service,
},
},
},
},
};
}
@ -280,20 +289,38 @@ async function getDeviceVars(
fillInInfoFields(deviceConfigVars, fleetSlug, printedUUID);
deviceVars.push(...deviceConfigVars);
} else {
const pineOpts: SDK.PineOptions<SDK.DeviceServiceEnvironmentVariable> = {
const pineOpts: SDK.Pine.ODataOptionsWithoutCount<
SDK.DeviceServiceEnvironmentVariable['Read']
> = {
$expand: {
service_install: {
$expand: 'installs__service',
},
},
};
if (options.service) {
pineOpts.$filter = {
service_install: {
installs__service: { service_name: options.service },
$any: {
$alias: 'si',
$expr: {
si: {
installs__service: {
$any: {
$alias: 's',
$expr: {
s: { service_name: options.service },
},
},
},
},
},
},
},
};
}
const deviceServiceVars = await sdk.models.device.serviceVar.getAllByDevice(
fullUUID,
pineOpts,
@ -325,12 +352,14 @@ function fillInInfoFields(
for (const envVar of varArray) {
if ('service' in envVar) {
// envVar is of type ServiceEnvironmentVariableInfo
envVar.serviceName = (envVar.service as SDK.Service[])[0]?.service_name;
envVar.serviceName = (
envVar.service as Array<SDK.Service['Read']>
)[0]?.service_name;
} else if ('service_install' in envVar) {
// envVar is of type DeviceServiceEnvironmentVariableInfo
envVar.serviceName = (
(envVar.service_install as SDK.ServiceInstall[])[0]
?.installs__service as SDK.Service[]
(envVar.service_install as Array<SDK.ServiceInstall['Read']>)[0]
?.installs__service as Array<SDK.Service['Read']>
)[0]?.service_name;
}
envVar.fleet = fleetSlug;

View File

@ -15,17 +15,10 @@
* limitations under the License.
*/
import type * as BalenaSdk from 'balena-sdk';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
import { Command } from '@oclif/core';
interface ExtendedApplication extends ApplicationWithDeviceTypeSlug {
device_count: number;
online_devices: number;
device_type?: string;
}
export default class FleetListCmd extends Command {
public static aliases = ['fleets'];
public static deprecateAliases = true;
@ -52,31 +45,26 @@ export default class FleetListCmd extends Command {
const { flags: options } = await this.parse(FleetListCmd);
const balena = getBalenaSdk();
const pineOptions = {
$select: ['id', 'app_name', 'slug'],
$expand: {
is_for__device_type: { $select: 'slug' },
owns__device: { $select: 'is_online' },
},
} satisfies BalenaSdk.PineOptions<BalenaSdk.Application>;
// Get applications
const applications =
(await balena.models.application.getAllDirectlyAccessible(
pineOptions,
)) as Array<
BalenaSdk.PineTypedResult<BalenaSdk.Application, typeof pineOptions>
> as ExtendedApplication[];
(await balena.models.application.getAllDirectlyAccessible({
$select: ['id', 'app_name', 'slug'],
$expand: {
is_for__device_type: { $select: 'slug' },
owns__device: { $select: 'is_online' },
},
})) as ApplicationWithDeviceTypeSlug[];
// Add extended properties
applications.forEach((application) => {
application.device_count = application.owns__device?.length ?? 0;
application.online_devices =
application.owns__device?.filter((d) => d.is_online).length || 0;
application.device_type = application.is_for__device_type[0].slug;
});
const extendedApplications = applications.map((application) => ({
...application,
device_count: application.owns__device?.length ?? 0,
online_devices:
application.owns__device?.filter((d) => d.is_online).length || 0,
device_type: application.is_for__device_type[0].slug,
}));
const applicationsToDisplay = applications.map((application) => ({
const applicationsToDisplay = extendedApplications.map((application) => ({
id: application.id,
app_name: application.app_name,
slug: application.slug,

View File

@ -356,7 +356,7 @@ async function getOsVersionFromImage(
async function checkDeviceTypeCompatibility(
options: FlagsDef,
app: {
is_for__device_type: [Pick<BalenaSdk.DeviceType, 'slug'>];
is_for__device_type: Array<Pick<BalenaSdk.DeviceType['Read'], 'slug'>>;
},
) {
if (options['device-type']) {

View File

@ -28,14 +28,7 @@ import { dockerConnectionCliFlags } from '../../utils/docker';
import { parseAsInteger } from '../../utils/validation';
import { Flags, Args, Command } from '@oclif/core';
import * as _ from 'lodash';
import type {
Application,
BalenaSDK,
PineExpand,
PineOptions,
PineTypedResult,
Release,
} from 'balena-sdk';
import type { Application, BalenaSDK, Pine, Release } from 'balena-sdk';
import type { Preloader } from 'balena-preload';
import type * as Fs from 'fs';
@ -333,7 +326,7 @@ Can be repeated to add multiple certificates.\
$select: ['id', 'commit', 'end_timestamp', 'composition'],
$expand: {
release_image: {
$select: ['image'],
$select: ['id'],
$expand: {
image: {
$select: ['image_size', 'is_stored_at__image_location'],
@ -349,7 +342,9 @@ Can be repeated to add multiple certificates.\
should_be_running__release: {
$select: 'commit',
},
} satisfies PineExpand<Application>;
} as const satisfies Pine.ODataOptionsWithoutCount<
Application['Read']
>['$expand'];
isCurrentCommit(commit: string) {
return commit === 'latest' || commit === 'current';
@ -407,11 +402,16 @@ Can be repeated to add multiple certificates.\
},
},
},
$orderby: 'slug asc',
} satisfies PineOptions<Application>;
$orderby: { slug: 'asc' },
} as const satisfies Pine.ODataOptionsWithoutCount<Application['Read']>;
return (await balena.models.application.getAllDirectlyAccessible(
options,
)) as Array<PineTypedResult<Application, typeof options>>;
)) as Pine.OptionsToResponse<
Application['Read'],
typeof options,
undefined
>;
}
async selectApplication(deviceTypeSlug: string) {
@ -440,7 +440,7 @@ Can be repeated to add multiple certificates.\
});
}
selectApplicationCommit(releases: Release[]) {
selectApplicationCommit(releases: Array<Release['Read']>) {
if (releases.length === 0) {
throw new ExpectedError('This fleet has no successful releases.');
}
@ -462,7 +462,10 @@ Can be repeated to add multiple certificates.\
}
async offerToDisableAutomaticUpdates(
application: Pick<Application, 'id' | 'should_track_latest_release'>,
application: Pick<
Application['Read'],
'id' | 'should_track_latest_release'
>,
commit: string,
pinDevice: boolean | undefined,
) {
@ -503,7 +506,7 @@ Would you like to disable automatic updates for this fleet now?\
if (!update) {
return;
}
return await balena.pine.patch({
await balena.pine.patch({
resource: 'application',
id: application.id,
body: {
@ -563,7 +566,7 @@ Would you like to disable automatic updates for this fleet now?\
} else {
// this could have the value 'current'
commit = await this.selectApplicationCommit(
application.owns__release as Release[],
application.owns__release as Array<Release['Read']>,
);
}

View File

@ -96,7 +96,7 @@ export default class ReleaseCmd extends Command {
'build_log',
'start_timestamp',
'end_timestamp',
] satisfies BalenaSdk.PineOptions<BalenaSdk.Release>['$select'];
] as const;
const release = await balena.models.release.get(commitOrId, {
...(!options.json && { $select: fields }),

View File

@ -19,7 +19,6 @@ import { Args, Command } from '@oclif/core';
import * as cf from '../../utils/common-flags';
import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
import { applicationNameNote } from '../../utils/messages';
import type * as BalenaSdk from 'balena-sdk';
import { jsonInfo } from '../../utils/messages';
export default class ReleaseListCmd extends Command {
@ -63,7 +62,7 @@ export default class ReleaseListCmd extends Command {
'status',
'semver',
'is_final',
] satisfies BalenaSdk.PineOptions<BalenaSdk.Release>['$select'];
] as const;
const balena = getBalenaSdk();
const { getFleetSlug } = await import('../../utils/sdk');

View File

@ -26,7 +26,7 @@ export const serviceIdToName = _.memoize(
sdk: SDK.BalenaSDK,
serviceId: number,
): Promise<string | undefined> => {
const serviceName = await sdk.pine.get<SDK.Service>({
const serviceName = await sdk.pine.get({
resource: 'service',
id: serviceId,
options: {
@ -53,9 +53,9 @@ export const getDeviceAndAppFromUUID = _.memoize(
async (
sdk: SDK.BalenaSDK,
deviceUUID: string,
selectDeviceFields?: Array<keyof SDK.Device>,
selectAppFields?: Array<keyof SDK.Application>,
): Promise<[SDK.Device, SDK.Application]> => {
selectDeviceFields?: Array<keyof SDK.Device['Read']>,
selectAppFields?: Array<keyof SDK.Application['Read']>,
): Promise<[SDK.Device['Read'], SDK.Application['Read']]> => {
const [device, app] = await getDeviceAndMaybeAppFromUUID(
sdk,
deviceUUID,
@ -85,19 +85,21 @@ export const getDeviceAndMaybeAppFromUUID = _.memoize(
async (
sdk: SDK.BalenaSDK,
deviceUUID: string,
selectDeviceFields?: Array<keyof SDK.Device>,
selectAppFields?: Array<keyof SDK.Application>,
): Promise<[SDK.Device, SDK.Application | undefined]> => {
selectDeviceFields?: Array<keyof SDK.Device['Read']>,
selectAppFields?: Array<keyof SDK.Application['Read']>,
): Promise<[SDK.Device['Read'], SDK.Application['Read'] | undefined]> => {
const pineOpts = {
$expand: selectAppFields
? { belongs_to__application: { $select: selectAppFields } }
: 'belongs_to__application',
} as SDK.PineOptions<SDK.Device>;
} as SDK.Pine.ODataOptionsWithoutCount<SDK.Device['Read']>;
if (selectDeviceFields) {
pineOpts.$select = selectDeviceFields as any;
}
const device = await sdk.models.device.get(deviceUUID, pineOpts);
const apps = device.belongs_to__application as SDK.Application[];
const apps = device.belongs_to__application as Array<
SDK.Application['Read']
>;
if (_.isEmpty(apps) || _.isEmpty(apps[0])) {
return [device, undefined];
}

View File

@ -233,7 +233,7 @@ export const getPreviousRepos = (
appID: number,
): Promise<string[]> =>
sdk.pine
.get<SDK.Release>({
.get({
resource: 'release',
options: {
$select: 'id',
@ -243,20 +243,18 @@ export const getPreviousRepos = (
},
$expand: {
release_image: {
$select: 'image',
$select: 'id',
$expand: { image: { $select: 'is_stored_at__image_location' } },
},
},
$orderby: 'id desc',
$orderby: { id: 'desc' },
$top: 1,
},
})
.then(function (release) {
// grab all images from the latest release, return all image locations in the registry
if (release.length > 0) {
const images = release[0].release_image as Array<{
image: [SDK.Image];
}>;
const images = release[0].release_image;
const { getRegistryAndName } =
require('@balena/compose/dist/multibuild') as typeof import('@balena/compose/dist/multibuild');
return Promise.all(

View File

@ -58,7 +58,7 @@ export interface ImgConfig {
}
export async function generateApplicationConfig(
application: Pick<BalenaSdk.Application, 'slug'>,
application: Pick<BalenaSdk.Application['Read'], 'slug'>,
options: {
version: string;
appUpdatePollInterval?: number;
@ -202,6 +202,7 @@ export async function validateSecureBootOptionAndWarn(
}
if (
// @ts-expect-error - parsed contract will be a Contract
osRelease.contract?.provides.some((entry: Dictionary<string>) => {
return entry.type === 'sw.feature' && entry.slug === 'secureboot';
})

View File

@ -80,7 +80,7 @@ export function getVarResourceName(
isConfig: boolean,
isDevice: boolean,
isService: boolean,
): string {
) {
return isDevice
? isConfig
? 'device_config_variable'

View File

@ -156,18 +156,24 @@ export const areDeviceTypesCompatible = async (
}
const sdk = getBalenaSdk();
const pineOptions = {
$select: 'is_of__cpu_architecture',
$select: 'id',
$expand: {
is_of__cpu_architecture: {
$select: 'slug',
},
},
} satisfies BalenaSdk.PineOptions<BalenaSdk.DeviceType>;
} as const;
const [appDeviceType, osDeviceType] = await Promise.all(
[appDeviceTypeSlug, osDeviceTypeSlug].map(
(dtSlug) =>
sdk.models.deviceType.get(dtSlug, pineOptions) as Promise<
BalenaSdk.PineTypedResult<BalenaSdk.DeviceType, typeof pineOptions>
NonNullable<
BalenaSdk.Pine.OptionsToResponse<
BalenaSdk.DeviceType['Read'],
typeof pineOptions,
typeof dtSlug
>
>
>,
),
);
@ -409,7 +415,7 @@ export const expandForAppName = {
is_of__device_type: { $select: 'slug' },
is_running__release: { $select: 'commit' },
},
} satisfies BalenaSdk.PineOptions<BalenaSdk.Device>;
} as const;
/**
* Use the `readline` library on Windows to install SIGINT handlers.

View File

@ -19,9 +19,7 @@ import type {
BalenaSDK,
Device,
Organization,
PineFilter,
PineOptions,
PineTypedResult,
Pine,
} from 'balena-sdk';
import {
@ -210,24 +208,25 @@ const selectApplicationPineOptions = {
$select: 'slug',
},
},
} satisfies PineOptions<Application>;
} as const;
type SelectApplicationResult = PineTypedResult<
Application,
typeof selectApplicationPineOptions
type SelectApplicationResult = Pine.OptionsToResponse<
Application['Read'],
typeof selectApplicationPineOptions,
undefined
>;
export async function selectApplication(
filter?:
| PineFilter<Application>
| ((app: SelectApplicationResult) => boolean),
export async function selectApplication<
T extends Pine.Filter<Application['Read']>,
>(
filter?: T | ((app: SelectApplicationResult[number]) => boolean),
errorOnEmptySelection = false,
) {
const balena = getBalenaSdk();
let apps = (await balena.models.application.getAllDirectlyAccessible({
...selectApplicationPineOptions,
...(filter != null && typeof filter === 'object' && { $filter: filter }),
})) as SelectApplicationResult[];
})) as SelectApplicationResult;
if (!apps.length) {
throw new ExpectedError('No fleets found');
@ -251,7 +250,7 @@ export async function selectApplication(
}
export async function selectOrganization(
organizations?: Array<Pick<Organization, 'handle' | 'name'>>,
organizations?: Array<Pick<Organization['Read'], 'handle' | 'name'>>,
) {
// Use either provided orgs (if e.g. already loaded) or load from cloud
organizations ??= await getBalenaSdk().models.organization.getAll({
@ -302,7 +301,7 @@ export async function getOnlineTargetDeviceUuid(
// If looks like UUID, probably device
if (validation.validateUuid(fleetOrDevice)) {
let device: Device;
let device: Device['Read'];
try {
logger.logDebug(
`Trying to fetch device by UUID ${fleetOrDevice} (${typeof fleetOrDevice})`,

View File

@ -14,13 +14,16 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import type { OptionalNavigationResource } from 'balena-sdk';
import type { Pine, OptionalNavigationResource } from 'balena-sdk';
export const getExpanded = <T extends object>(
export const getExpanded = <T extends Pine.Resource['Read']>(
obj: OptionalNavigationResource<T>,
) => (Array.isArray(obj) && obj[0]) || undefined;
export const getExpandedProp = <T extends object, K extends keyof T>(
export const getExpandedProp = <
T extends Pine.Resource['Read'],
K extends keyof T,
>(
obj: OptionalNavigationResource<T>,
key: K,
) => (Array.isArray(obj) && obj[0] && obj[0][key]) || undefined;
) => (Array.isArray(obj) && obj[0]?.[key]) || undefined;

View File

@ -255,11 +255,17 @@ async function getOrSelectApplication(
$select: 'slug',
},
},
} satisfies BalenaSdk.PineOptions<BalenaSdk.DeviceType>;
} as const;
const deviceType = (await sdk.models.deviceType.get(
deviceTypeSlug,
pineOptions,
)) as BalenaSdk.PineTypedResult<BalenaSdk.DeviceType, typeof pineOptions>;
)) as NonNullable<
BalenaSdk.Pine.OptionsToResponse<
BalenaSdk.DeviceType['Read'],
typeof pineOptions,
typeof deviceTypeSlug
>
>;
const allCpuArches = await sdk.pine.get({
resource: 'cpu_architecture',
options: {
@ -299,21 +305,31 @@ async function getOrSelectApplication(
$expand: {
is_for__device_type: { $select: ['slug', 'is_of__cpu_architecture'] },
},
} satisfies BalenaSdk.PineOptions<BalenaSdk.Application>;
} satisfies BalenaSdk.Pine.ODataOptionsWithoutCount<
BalenaSdk.Application['Read']
>;
// Check for a fleet slug of the form `user/fleet` and update the API query.
let name: string;
const match = appName.split('/');
if (match.length > 1) {
// These will match at most one fleet
(options as BalenaSdk.PineOptions<BalenaSdk.Application>).$filter = {
(
options as BalenaSdk.Pine.ODataOptionsWithoutCount<
BalenaSdk.Application['Read']
>
).$filter = {
slug: appName.toLowerCase(),
};
name = match[1];
} else {
// We're given an application; resolve it if it's ambiguous and also validate
// it's of appropriate device type.
(options as BalenaSdk.PineOptions<BalenaSdk.Application>).$filter = {
(
options as BalenaSdk.Pine.ODataOptionsWithoutCount<
BalenaSdk.Application['Read']
>
).$filter = {
app_name: appName,
};
name = appName;
@ -321,7 +337,11 @@ async function getOrSelectApplication(
const applications = (await sdk.models.application.getAllDirectlyAccessible(
options,
)) as Array<BalenaSdk.PineTypedResult<BalenaSdk.Application, typeof options>>;
)) as BalenaSdk.Pine.OptionsToResponse<
BalenaSdk.Application['Read'],
typeof options,
undefined
>;
if (applications.length === 0) {
await confirm(
@ -356,7 +376,9 @@ async function getOrSelectApplication(
async function createOrSelectApp(
sdk: BalenaSdk.BalenaSDK,
compatibleDeviceTypesFilter: BalenaSdk.PineFilter<BalenaSdk.Application>,
compatibleDeviceTypesFilter: BalenaSdk.Pine.Filter<
BalenaSdk.Application['Read']
>,
deviceType: string,
): Promise<ApplicationWithDeviceTypeSlug> {
// No fleet specified, show a list to select one.

View File

@ -15,23 +15,23 @@
* limitations under the License.
*/
import type {
Application,
BalenaSDK,
Organization,
PineOptions,
PineTypedResult,
} from 'balena-sdk';
import type { Application, BalenaSDK, Organization, Pine } from 'balena-sdk';
export async function getApplication(
sdk: BalenaSDK,
nameOrSlugOrId: string | number,
): Promise<Application>;
export async function getApplication<TP extends PineOptions<Application>>(
): Promise<Application['Read']>;
export async function getApplication<
TP extends Pine.ODataOptionsWithoutCount<Application['Read']>,
>(
sdk: BalenaSDK,
nameOrSlugOrId: string | number,
options?: TP,
): Promise<PineTypedResult<Application, TP>>;
options: TP,
): Promise<
NonNullable<
Pine.OptionsToResponse<Application['Read'], TP, typeof nameOrSlugOrId>
>
>;
/**
* Get a fleet object, disambiguating the fleet identifier which may be a
* a fleet slug or name.
@ -40,8 +40,8 @@ export async function getApplication<TP extends PineOptions<Application>>(
export async function getApplication(
sdk: BalenaSDK,
nameOrSlugOrId: string | number,
options?: PineOptions<Application>,
): Promise<Application> {
options?: Pine.ODataOptionsWithoutCount<Application['Read']>,
): Promise<Application['Read']> {
const { looksLikeFleetSlug } = await import('./validation');
const whoamiResult = await sdk.auth.whoami();
const isDeviceActor = whoamiResult?.actorType === 'device';
@ -108,19 +108,22 @@ export async function getFleetSlug(
export async function getOwnOrganizations(
sdk: BalenaSDK,
): Promise<Organization[]>;
export async function getOwnOrganizations<TP extends PineOptions<Organization>>(
): Promise<Array<Organization['Read']>>;
export async function getOwnOrganizations<
TP extends Pine.ODataOptionsWithoutCount<Organization['Read']>,
>(
sdk: BalenaSDK,
options: TP,
): Promise<Array<PineTypedResult<Organization, TP>>>;
): Promise<Pine.OptionsToResponse<Organization['Read'], TP, undefined>>;
/**
* Wraps the sdk organization.getAll method,
* restricting to those orgs user is a member of
*/
export async function getOwnOrganizations(
sdk: BalenaSDK,
options?: PineOptions<Organization>,
): Promise<Organization[]> {
options?: Pine.ODataOptionsWithoutCount<Organization['Read']>,
): Promise<Array<Organization['Read']>> {
return await sdk.models.organization.getAll(
sdk.utils.mergePineOptions(
{
@ -136,9 +139,9 @@ export async function getOwnOrganizations(
},
},
},
$orderby: 'name asc',
$orderby: { name: 'asc' },
},
options,
options ?? {},
),
);
}

8
typings/global.d.ts vendored
View File

@ -2,12 +2,12 @@ import type { Application, DeviceType, Device } from 'balena-sdk';
declare global {
type ApplicationWithDeviceTypeSlug = Omit<
Application,
Application['Read'],
'is_for__device_type'
> & {
is_for__device_type: [Pick<DeviceType, 'slug'>];
is_for__device_type: Array<Pick<DeviceType['Read'], 'slug'>>;
};
type DeviceWithDeviceType = Device & {
is_of__device_type: [DeviceType];
type DeviceWithDeviceType = Omit<Device['Read'], 'is_of__device_type'> & {
is_of__device_type: [DeviceType['Read']];
};
}