@alwaysai/device-agent 1.3.1 → 1.5.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.
- package/lib/application-control/config.js +2 -2
- package/lib/application-control/config.js.map +1 -1
- package/lib/application-control/environment-variables.d.ts.map +1 -1
- package/lib/application-control/environment-variables.js +9 -4
- package/lib/application-control/environment-variables.js.map +1 -1
- package/lib/application-control/environment-variables.test.js +1 -1
- package/lib/application-control/environment-variables.test.js.map +1 -1
- package/lib/application-control/install.d.ts.map +1 -1
- package/lib/application-control/install.js +7 -2
- package/lib/application-control/install.js.map +1 -1
- package/lib/application-control/models.d.ts +5 -0
- package/lib/application-control/models.d.ts.map +1 -1
- package/lib/application-control/models.js +28 -14
- package/lib/application-control/models.js.map +1 -1
- package/lib/application-control/status.d.ts.map +1 -1
- package/lib/application-control/status.js +14 -17
- package/lib/application-control/status.js.map +1 -1
- package/lib/application-control/utils.js +2 -2
- package/lib/application-control/utils.js.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts +5 -5
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.js +140 -105
- package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.d.ts +4 -2
- package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
- package/lib/cloud-connection/live-updates-handler.js +46 -25
- package/lib/cloud-connection/live-updates-handler.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.test.js +132 -16
- package/lib/cloud-connection/live-updates-handler.test.js.map +1 -1
- package/lib/cloud-connection/messages.d.ts.map +1 -1
- package/lib/cloud-connection/messages.js +3 -4
- package/lib/cloud-connection/messages.js.map +1 -1
- package/lib/cloud-connection/passthrough-handler.d.ts +5 -3
- package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
- package/lib/cloud-connection/passthrough-handler.js +76 -62
- package/lib/cloud-connection/passthrough-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.d.ts +16 -21
- package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
- package/lib/cloud-connection/shadow-handler.js +162 -108
- package/lib/cloud-connection/shadow-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.test.js +100 -83
- package/lib/cloud-connection/shadow-handler.test.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.d.ts +3 -0
- package/lib/cloud-connection/transaction-manager.d.ts.map +1 -1
- package/lib/cloud-connection/transaction-manager.js +11 -0
- package/lib/cloud-connection/transaction-manager.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.test.js +102 -0
- package/lib/cloud-connection/transaction-manager.test.js.map +1 -1
- package/lib/device-control/device-control.d.ts +16 -15
- package/lib/device-control/device-control.d.ts.map +1 -1
- package/lib/device-control/device-control.js +117 -18
- package/lib/device-control/device-control.js.map +1 -1
- package/lib/docker/docker-compose.d.ts +14 -0
- package/lib/docker/docker-compose.d.ts.map +1 -0
- package/lib/docker/docker-compose.js +56 -0
- package/lib/docker/docker-compose.js.map +1 -0
- package/lib/index.js +2 -5
- package/lib/index.js.map +1 -1
- package/lib/infrastructure/agent-config.d.ts +45 -14
- package/lib/infrastructure/agent-config.d.ts.map +1 -1
- package/lib/infrastructure/agent-config.js +30 -15
- package/lib/infrastructure/agent-config.js.map +1 -1
- package/lib/infrastructure/agent-config.test.js +3 -0
- package/lib/infrastructure/agent-config.test.js.map +1 -1
- package/lib/local-connection/rabbitmq-connection.js +11 -11
- package/lib/local-connection/rabbitmq-connection.js.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.d.ts +97 -0
- package/lib/secure-tunneling/secure-tunneling.d.ts.map +1 -0
- package/lib/secure-tunneling/secure-tunneling.js +435 -0
- package/lib/secure-tunneling/secure-tunneling.js.map +1 -0
- package/lib/secure-tunneling/secure-tunneling.test.d.ts +2 -0
- package/lib/secure-tunneling/secure-tunneling.test.d.ts.map +1 -0
- package/lib/secure-tunneling/secure-tunneling.test.js +1070 -0
- package/lib/secure-tunneling/secure-tunneling.test.js.map +1 -0
- package/lib/secure-tunneling/spawner-detached.d.ts +6 -0
- package/lib/secure-tunneling/spawner-detached.d.ts.map +1 -0
- package/lib/secure-tunneling/spawner-detached.js +107 -0
- package/lib/secure-tunneling/spawner-detached.js.map +1 -0
- package/lib/subcommands/app/analytics.d.ts.map +1 -1
- package/lib/subcommands/app/analytics.js +9 -13
- package/lib/subcommands/app/analytics.js.map +1 -1
- package/lib/subcommands/app/env-vars.d.ts.map +1 -1
- package/lib/subcommands/app/env-vars.js +11 -16
- package/lib/subcommands/app/env-vars.js.map +1 -1
- package/lib/subcommands/app/models.d.ts.map +1 -1
- package/lib/subcommands/app/models.js +12 -16
- package/lib/subcommands/app/models.js.map +1 -1
- package/lib/subcommands/device/clean.d.ts.map +1 -1
- package/lib/subcommands/device/clean.js +8 -6
- package/lib/subcommands/device/clean.js.map +1 -1
- package/lib/subcommands/device/get-info.d.ts +2 -0
- package/lib/subcommands/device/get-info.d.ts.map +1 -0
- package/lib/subcommands/device/get-info.js +36 -0
- package/lib/subcommands/device/get-info.js.map +1 -0
- package/lib/subcommands/device/index.d.ts.map +1 -1
- package/lib/subcommands/device/index.js +11 -2
- package/lib/subcommands/device/index.js.map +1 -1
- package/lib/subcommands/device/init.d.ts +5 -0
- package/lib/subcommands/device/init.d.ts.map +1 -0
- package/lib/subcommands/device/{device.js → init.js} +5 -36
- package/lib/subcommands/device/init.js.map +1 -0
- package/lib/subcommands/device/refresh.d.ts +2 -0
- package/lib/subcommands/device/refresh.d.ts.map +1 -0
- package/lib/subcommands/device/refresh.js +24 -0
- package/lib/subcommands/device/refresh.js.map +1 -0
- package/lib/subcommands/device/restart.d.ts +2 -0
- package/lib/subcommands/device/restart.d.ts.map +1 -0
- package/lib/subcommands/device/restart.js +14 -0
- package/lib/subcommands/device/restart.js.map +1 -0
- package/lib/util/check-for-updates.d.ts +3 -0
- package/lib/util/check-for-updates.d.ts.map +1 -0
- package/lib/util/check-for-updates.js +69 -0
- package/lib/util/check-for-updates.js.map +1 -0
- package/lib/util/cloud-mode-ready.d.ts +1 -0
- package/lib/util/cloud-mode-ready.d.ts.map +1 -1
- package/lib/util/cloud-mode-ready.js +36 -1
- package/lib/util/cloud-mode-ready.js.map +1 -1
- package/lib/util/file.d.ts +7 -0
- package/lib/util/file.d.ts.map +1 -0
- package/lib/util/file.js +66 -0
- package/lib/util/file.js.map +1 -0
- package/lib/util/file.test.d.ts +2 -0
- package/lib/util/file.test.d.ts.map +1 -0
- package/lib/util/file.test.js +87 -0
- package/lib/util/file.test.js.map +1 -0
- package/package.json +8 -7
- package/readme.md +3 -3
- package/src/application-control/config.ts +1 -1
- package/src/application-control/environment-variables.test.ts +1 -1
- package/src/application-control/environment-variables.ts +9 -6
- package/src/application-control/install.ts +8 -3
- package/src/application-control/models.ts +47 -19
- package/src/application-control/status.ts +16 -14
- package/src/application-control/utils.ts +1 -1
- package/src/cloud-connection/device-agent-cloud-connection.ts +202 -148
- package/src/cloud-connection/live-updates-handler.test.ts +161 -20
- package/src/cloud-connection/live-updates-handler.ts +63 -31
- package/src/cloud-connection/messages.ts +3 -4
- package/src/cloud-connection/passthrough-handler.ts +98 -76
- package/src/cloud-connection/shadow-handler.test.ts +101 -84
- package/src/cloud-connection/shadow-handler.ts +287 -133
- package/src/cloud-connection/transaction-manager.test.ts +124 -0
- package/src/cloud-connection/transaction-manager.ts +15 -0
- package/src/device-control/device-control.ts +125 -23
- package/src/docker/docker-compose.ts +60 -0
- package/src/index.ts +2 -6
- package/src/infrastructure/agent-config.test.ts +3 -0
- package/src/infrastructure/agent-config.ts +38 -40
- package/src/local-connection/rabbitmq-connection.ts +8 -8
- package/src/secure-tunneling/secure-tunneling.test.ts +1239 -0
- package/src/secure-tunneling/secure-tunneling.ts +599 -0
- package/src/secure-tunneling/spawner-detached.ts +123 -0
- package/src/subcommands/app/analytics.ts +16 -13
- package/src/subcommands/app/env-vars.ts +18 -16
- package/src/subcommands/app/models.ts +20 -16
- package/src/subcommands/device/clean.ts +5 -2
- package/src/subcommands/device/get-info.ts +49 -0
- package/src/subcommands/device/index.ts +11 -2
- package/src/subcommands/device/{device.ts → init.ts} +5 -47
- package/src/subcommands/device/refresh.ts +22 -0
- package/src/subcommands/device/restart.ts +11 -0
- package/src/util/check-for-updates.ts +69 -0
- package/src/util/cloud-mode-ready.ts +36 -0
- package/src/util/file.test.ts +90 -0
- package/src/util/file.ts +76 -0
- package/lib/docker/docker-compose-cmd.d.ts +0 -5
- package/lib/docker/docker-compose-cmd.d.ts.map +0 -1
- package/lib/docker/docker-compose-cmd.js +0 -16
- package/lib/docker/docker-compose-cmd.js.map +0 -1
- package/lib/secure-tunneling/index.d.ts +0 -5
- package/lib/secure-tunneling/index.d.ts.map +0 -1
- package/lib/secure-tunneling/index.js +0 -64
- package/lib/secure-tunneling/index.js.map +0 -1
- package/lib/subcommands/device/device.d.ts +0 -7
- package/lib/subcommands/device/device.d.ts.map +0 -1
- package/lib/subcommands/device/device.js.map +0 -1
- package/lib/util/safe-rimraf.d.ts +0 -2
- package/lib/util/safe-rimraf.d.ts.map +0 -1
- package/lib/util/safe-rimraf.js +0 -16
- package/lib/util/safe-rimraf.js.map +0 -1
- package/src/docker/docker-compose-cmd.ts +0 -15
- package/src/secure-tunneling/index.ts +0 -74
- package/src/util/safe-rimraf.ts +0 -14
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.initCliLeaf = void 0;
|
|
4
4
|
const alwayscli_1 = require("@alwaysai/alwayscli");
|
|
5
5
|
const app_1 = require("alwaysai/lib/core/app");
|
|
6
6
|
const uuid_1 = require("uuid");
|
|
@@ -9,7 +9,6 @@ const fs_1 = require("fs");
|
|
|
9
9
|
const http_client_1 = require("../../util/http-client");
|
|
10
10
|
const directories_1 = require("../../util/directories");
|
|
11
11
|
const util_1 = require("alwaysai/lib/util");
|
|
12
|
-
const device_control_1 = require("../../device-control/device-control");
|
|
13
12
|
const tokens_and_device_cfg_1 = require("../../infrastructure/tokens-and-device-cfg");
|
|
14
13
|
const logger_1 = require("../../util/logger");
|
|
15
14
|
const device_1 = require("alwaysai/lib/core/device");
|
|
@@ -61,42 +60,12 @@ exports.initCliLeaf = (0, alwayscli_1.CliLeaf)({
|
|
|
61
60
|
const certSpawner = (0, util_1.JsSpawner)({
|
|
62
61
|
path: (0, directories_1.BOOTSTRAP_CERTIFICATES_DIR_PATH)()
|
|
63
62
|
});
|
|
63
|
+
const writeCertFilePromises = [];
|
|
64
64
|
for (const key in response.claimCertificate) {
|
|
65
|
-
|
|
65
|
+
writeCertFilePromises.push(certSpawner.writeFile(key, response.claimCertificate[key]));
|
|
66
66
|
}
|
|
67
|
+
await Promise.all(writeCertFilePromises);
|
|
67
68
|
logger_1.logger.info(`Initialized device ${name}: UUID=${response.deviceUuid}`);
|
|
68
69
|
}
|
|
69
70
|
});
|
|
70
|
-
|
|
71
|
-
name: 'get-info',
|
|
72
|
-
description: 'Get device info',
|
|
73
|
-
namedInputs: {},
|
|
74
|
-
async action(_, opts) {
|
|
75
|
-
var _a;
|
|
76
|
-
const cpuDetails = await (0, device_control_1.getCpuDetails)();
|
|
77
|
-
const diskDetails = await (0, device_control_1.getDiskDetails)();
|
|
78
|
-
const memDetails = await (0, device_control_1.getMemDetails)();
|
|
79
|
-
const out = {
|
|
80
|
-
'CPU Utilization': `Used ${cpuDetails.usedPerc.toFixed(2)}%, Temperature ${cpuDetails.temperature} °C`,
|
|
81
|
-
'Disk Utilization': `${diskDetails.usedGb} GB / ${diskDetails.usedGb + diskDetails.freeGb} GB`,
|
|
82
|
-
'Memory Utilization': `${memDetails.usedMb} MB / ${memDetails.usedMb + memDetails.freeMb} MB`
|
|
83
|
-
};
|
|
84
|
-
console.table(out);
|
|
85
|
-
const systemInfo = await (0, device_control_1.getSystemInformation)();
|
|
86
|
-
console.table(systemInfo.os);
|
|
87
|
-
console.table(systemInfo.cpu);
|
|
88
|
-
console.table((_a = systemInfo.disk) === null || _a === void 0 ? void 0 : _a.drives);
|
|
89
|
-
console.table(systemInfo.device);
|
|
90
|
-
console.table(systemInfo.network);
|
|
91
|
-
console.table(systemInfo.versions);
|
|
92
|
-
}
|
|
93
|
-
});
|
|
94
|
-
exports.restartCliLeaf = (0, alwayscli_1.CliLeaf)({
|
|
95
|
-
name: 'restart',
|
|
96
|
-
description: 'Restart the device',
|
|
97
|
-
namedInputs: {},
|
|
98
|
-
async action(_, opts) {
|
|
99
|
-
await (0, device_control_1.reboot)();
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
//# sourceMappingURL=device.js.map
|
|
71
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/subcommands/device/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../../src/subcommands/device/refresh.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,cAAc,yKAgBzB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.refreshCliLeaf = void 0;
|
|
4
|
+
const alwayscli_1 = require("@alwaysai/alwayscli");
|
|
5
|
+
const tokens_and_device_cfg_1 = require("../../infrastructure/tokens-and-device-cfg");
|
|
6
|
+
const logger_1 = require("../../util/logger");
|
|
7
|
+
const device_1 = require("alwaysai/lib/core/device");
|
|
8
|
+
exports.refreshCliLeaf = (0, alwayscli_1.CliLeaf)({
|
|
9
|
+
name: 'refresh',
|
|
10
|
+
description: 'Refresh the device tokens',
|
|
11
|
+
namedInputs: {},
|
|
12
|
+
async action(_, opts) {
|
|
13
|
+
logger_1.logger.info(`Refreshing device tokens`);
|
|
14
|
+
const cfg = (0, device_1.DeviceConfigFile)().readIfExists();
|
|
15
|
+
if (cfg === undefined) {
|
|
16
|
+
throw new alwayscli_1.CliTerseError('Configuration not found on current device!');
|
|
17
|
+
}
|
|
18
|
+
const deviceUuid = cfg.deviceUuid;
|
|
19
|
+
await (0, tokens_and_device_cfg_1.writeTokenAndDeviceCfg)({
|
|
20
|
+
deviceUuid
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=refresh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../../src/subcommands/device/refresh.ts"],"names":[],"mappings":";;;AAAA,mDAA6D;AAC7D,sFAAoF;AACpF,8CAA2C;AAC3C,qDAA4D;AAE/C,QAAA,cAAc,GAAG,IAAA,mBAAO,EAAC;IACpC,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,2BAA2B;IACxC,WAAW,EAAE,EAAE;IACf,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI;QAClB,eAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,IAAA,yBAAgB,GAAE,CAAC,YAAY,EAAE,CAAC;QAC9C,IAAI,GAAG,KAAK,SAAS,EAAE;YACrB,MAAM,IAAI,yBAAa,CAAC,4CAA4C,CAAC,CAAC;SACvE;QACD,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;QAElC,MAAM,IAAA,8CAAsB,EAAC;YAC3B,UAAU;SACX,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restart.d.ts","sourceRoot":"","sources":["../../../src/subcommands/device/restart.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,cAAc,yKAOzB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.restartCliLeaf = void 0;
|
|
4
|
+
const alwayscli_1 = require("@alwaysai/alwayscli");
|
|
5
|
+
const device_control_1 = require("../../device-control/device-control");
|
|
6
|
+
exports.restartCliLeaf = (0, alwayscli_1.CliLeaf)({
|
|
7
|
+
name: 'restart',
|
|
8
|
+
description: 'Restart the device',
|
|
9
|
+
namedInputs: {},
|
|
10
|
+
async action(_, opts) {
|
|
11
|
+
await (0, device_control_1.reboot)();
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
//# sourceMappingURL=restart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restart.js","sourceRoot":"","sources":["../../../src/subcommands/device/restart.ts"],"names":[],"mappings":";;;AAAA,mDAA8C;AAC9C,wEAA6D;AAEhD,QAAA,cAAc,GAAG,IAAA,mBAAO,EAAC;IACpC,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,oBAAoB;IACjC,WAAW,EAAE,EAAE;IACf,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI;QAClB,MAAM,IAAA,uBAAM,GAAE,CAAC;IACjB,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-for-updates.d.ts","sourceRoot":"","sources":["../../src/util/check-for-updates.ts"],"names":[],"mappings":"AAgCA,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,CAAC,CAY7D;AAQD,wBAAsB,wBAAwB,kBAgB7C"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkForUpdatesAndPrompt = exports.getDeviceAgentVersion = void 0;
|
|
4
|
+
const logger_1 = require("../util/logger");
|
|
5
|
+
const util_1 = require("alwaysai/lib/util");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const https_1 = require("https");
|
|
8
|
+
const appPrompt = 'Please restart the Device Agent or reboot the device to update. ';
|
|
9
|
+
const updatePrompt = `A new version of the Device Agent is available! \n\n`;
|
|
10
|
+
function getLatestVersion(packageName) {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
const url = `https://registry.npmjs.org/${packageName}/latest`;
|
|
13
|
+
(0, https_1.get)(url, (res) => {
|
|
14
|
+
let data = '';
|
|
15
|
+
res.on('data', (chunk) => {
|
|
16
|
+
data += chunk;
|
|
17
|
+
});
|
|
18
|
+
res.on('end', () => {
|
|
19
|
+
try {
|
|
20
|
+
const latestPackage = JSON.parse(data);
|
|
21
|
+
resolve(latestPackage.version);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
reject(error);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}).on('error', (error) => {
|
|
28
|
+
reject(error);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
async function getDeviceAgentVersion() {
|
|
33
|
+
let daVersion = '';
|
|
34
|
+
try {
|
|
35
|
+
const packagePath = path.join(__dirname, '../../');
|
|
36
|
+
const spawner = (0, util_1.JsSpawner)({ path: packagePath });
|
|
37
|
+
const output = await spawner.readFile('package.json');
|
|
38
|
+
const parsed = JSON.parse(output);
|
|
39
|
+
daVersion = parsed.version;
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
logger_1.logger.error(`Could not retrieve the Device Agent version: $ {e}`);
|
|
43
|
+
}
|
|
44
|
+
return daVersion;
|
|
45
|
+
}
|
|
46
|
+
exports.getDeviceAgentVersion = getDeviceAgentVersion;
|
|
47
|
+
function constructPrompt(props) {
|
|
48
|
+
const { currentVer, latestVer } = props;
|
|
49
|
+
const prompt = `${updatePrompt}${appPrompt}\nYour version: ${currentVer}. Newest version: ${latestVer}`;
|
|
50
|
+
return prompt;
|
|
51
|
+
}
|
|
52
|
+
async function checkForUpdatesAndPrompt() {
|
|
53
|
+
try {
|
|
54
|
+
logger_1.logger.debug('Checking for updates...');
|
|
55
|
+
const latestVersion = await getLatestVersion('@alwaysai/device-agent');
|
|
56
|
+
const version = await getDeviceAgentVersion();
|
|
57
|
+
if (version !== latestVersion) {
|
|
58
|
+
logger_1.logger.warn(constructPrompt({
|
|
59
|
+
currentVer: version,
|
|
60
|
+
latestVer: latestVersion
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
logger_1.logger.error(`Could not check for updates: ${error}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.checkForUpdatesAndPrompt = checkForUpdatesAndPrompt;
|
|
69
|
+
//# sourceMappingURL=check-for-updates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-for-updates.js","sourceRoot":"","sources":["../../src/util/check-for-updates.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AACxC,4CAA8C;AAC9C,6BAA6B;AAC7B,iCAA4B;AAE5B,MAAM,SAAS,GACb,kEAAkE,CAAC;AACrE,MAAM,YAAY,GAAG,sDAAsD,CAAC;AAE5E,SAAS,gBAAgB,CAAC,WAAmB;IAC3C,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC7C,MAAM,GAAG,GAAG,8BAA8B,WAAW,SAAS,CAAC;QAE/D,IAAA,WAAG,EAAC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE;YACf,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBACvB,IAAI,IAAI,KAAK,CAAC;YAChB,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACjB,IAAI;oBACF,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACvC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;iBAChC;gBAAC,OAAO,KAAK,EAAE;oBACd,MAAM,CAAC,KAAK,CAAC,CAAC;iBACf;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACvB,MAAM,CAAC,KAAK,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,qBAAqB;IACzC,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,IAAI;QACF,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,IAAA,gBAAS,EAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAClC,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC;KAC5B;IAAC,OAAO,CAAC,EAAE;QACV,eAAM,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;KACpE;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAZD,sDAYC;AAED,SAAS,eAAe,CAAC,KAAgD;IACvE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IACxC,MAAM,MAAM,GAAG,GAAG,YAAY,GAAG,SAAS,mBAAmB,UAAU,qBAAqB,SAAS,EAAE,CAAC;IACxG,OAAO,MAAM,CAAC;AAChB,CAAC;AAEM,KAAK,UAAU,wBAAwB;IAC5C,IAAI;QACF,eAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACxC,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;QACvE,MAAM,OAAO,GAAG,MAAM,qBAAqB,EAAE,CAAC;QAC9C,IAAI,OAAO,KAAK,aAAa,EAAE;YAC7B,eAAM,CAAC,IAAI,CACT,eAAe,CAAC;gBACd,UAAU,EAAE,OAAO;gBACnB,SAAS,EAAE,aAAa;aACzB,CAAC,CACH,CAAC;SACH;KACF;IAAC,OAAO,KAAK,EAAE;QACd,eAAM,CAAC,KAAK,CAAC,gCAAgC,KAAK,EAAE,CAAC,CAAC;KACvD;AACH,CAAC;AAhBD,4DAgBC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-mode-ready.d.ts","sourceRoot":"","sources":["../../src/util/cloud-mode-ready.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cloud-mode-ready.d.ts","sourceRoot":"","sources":["../../src/util/cloud-mode-ready.ts"],"names":[],"mappings":"AAuCA,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,cAAc,YAe7B"}
|
|
@@ -1,8 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.cloudModeReady = void 0;
|
|
3
|
+
exports.cloudModeReady = exports.isValidAwsRegion = void 0;
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
5
|
const directories_1 = require("../util/directories");
|
|
6
|
+
const VALID_AWS_REGIONS = [
|
|
7
|
+
// 'af-south-1', // Africa (Cape Town)
|
|
8
|
+
// 'ap-east-1', // Asia Pacific (Hong Kong)
|
|
9
|
+
// 'ap-south-2', // Asia Pacific (Hyderabad)
|
|
10
|
+
// 'ap-northeast-1', // Asia Pacific (Tokyo)
|
|
11
|
+
// 'ap-northeast-2', // Asia Pacific (Seoul)
|
|
12
|
+
// 'ap-northeast-3', // Asia Pacific (Osaka)
|
|
13
|
+
// 'ap-south-1', // Asia Pacific (Mumbai)
|
|
14
|
+
// 'ap-southeast-1', // Asia Pacific (Singapore)
|
|
15
|
+
// 'ap-southeast-2', // Asia Pacific (Sydney)
|
|
16
|
+
// 'ap-southeast-3', // Asia Pacific (Jakarta)
|
|
17
|
+
// 'ap-southeast-4', // Asia Pacific (Melbourne)
|
|
18
|
+
// 'ca-central-1', // Canada (Central)
|
|
19
|
+
// 'ca-west-1', // Canada West (Calgary)
|
|
20
|
+
// 'eu-west-2', // Europe (London)
|
|
21
|
+
// 'eu-west-3', // Europe (Paris)
|
|
22
|
+
// 'eu-central-1', // Europe (Frankfurt)
|
|
23
|
+
// 'eu-central-2', // Europe (Zurich)
|
|
24
|
+
// 'eu-north-1', // Europe (Stockholm)
|
|
25
|
+
// 'eu-south-1', // Europe (Milan)
|
|
26
|
+
// 'eu-south-2', // Europe (Spain)
|
|
27
|
+
// 'eu-west-1', // Europe (Ireland)
|
|
28
|
+
// 'il-central-1', // Israel (Tel Aviv)
|
|
29
|
+
// 'me-south-1', // Middle East (Bahrain)
|
|
30
|
+
// 'me-central-1', // Middle East (UAE)
|
|
31
|
+
// 'sa-east-1' // South America (São Paulo)
|
|
32
|
+
// 'us-east-2', // US East (Ohio)
|
|
33
|
+
// 'us-east-1', // US East (Virginia)
|
|
34
|
+
// 'us-west-1', // US West (N. California)
|
|
35
|
+
'us-west-2' // US West (Oregon)
|
|
36
|
+
];
|
|
37
|
+
function isValidAwsRegion(region) {
|
|
38
|
+
return VALID_AWS_REGIONS.includes(region);
|
|
39
|
+
}
|
|
40
|
+
exports.isValidAwsRegion = isValidAwsRegion;
|
|
6
41
|
function cloudModeReady() {
|
|
7
42
|
let ready = true;
|
|
8
43
|
const requiredFiles = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-mode-ready.js","sourceRoot":"","sources":["../../src/util/cloud-mode-ready.ts"],"names":[],"mappings":";;;AAAA,2BAAgC;AAChC,qDAI6B;AAE7B,SAAgB,cAAc;IAC5B,IAAI,KAAK,GAAG,IAAI,CAAC;IACjB,MAAM,aAAa,GAAG;QACpB,0CAA4B;QAC5B,0CAA4B;QAC5B,4CAA8B;KAC/B,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE;QAChC,IAAI,CAAC,IAAA,eAAU,EAAC,IAAI,CAAC,EAAE;YACrB,KAAK,GAAG,KAAK,CAAC;YACd,MAAM;SACP;KACF;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAfD,wCAeC"}
|
|
1
|
+
{"version":3,"file":"cloud-mode-ready.js","sourceRoot":"","sources":["../../src/util/cloud-mode-ready.ts"],"names":[],"mappings":";;;AAAA,2BAAgC;AAChC,qDAI6B;AAE7B,MAAM,iBAAiB,GAAG;IACxB,sCAAsC;IACtC,2CAA2C;IAC3C,4CAA4C;IAC5C,4CAA4C;IAC5C,4CAA4C;IAC5C,4CAA4C;IAC5C,yCAAyC;IACzC,gDAAgD;IAChD,6CAA6C;IAC7C,8CAA8C;IAC9C,gDAAgD;IAChD,sCAAsC;IACtC,wCAAwC;IACxC,kCAAkC;IAClC,iCAAiC;IACjC,wCAAwC;IACxC,qCAAqC;IACrC,sCAAsC;IACtC,kCAAkC;IAClC,kCAAkC;IAClC,mCAAmC;IACnC,uCAAuC;IACvC,yCAAyC;IACzC,uCAAuC;IACvC,2CAA2C;IAC3C,iCAAiC;IACjC,qCAAqC;IACrC,0CAA0C;IAC1C,WAAW,CAAC,mBAAmB;CAChC,CAAC;AAEF,SAAgB,gBAAgB,CAAC,MAAc;IAC7C,OAAO,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC5C,CAAC;AAFD,4CAEC;AAED,SAAgB,cAAc;IAC5B,IAAI,KAAK,GAAG,IAAI,CAAC;IACjB,MAAM,aAAa,GAAG;QACpB,0CAA4B;QAC5B,0CAA4B;QAC5B,4CAA8B;KAC/B,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE;QAChC,IAAI,CAAC,IAAA,eAAU,EAAC,IAAI,CAAC,EAAE;YACrB,KAAK,GAAG,KAAK,CAAC;YACd,MAAM;SACP;KACF;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAfD,wCAeC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/util/file.ts"],"names":[],"mappings":"AAKA,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,iBAU5C;AAED,wBAAsB,QAAQ,CAAC,EAC7B,IAAI,EACJ,OAAO,EACP,OAAO,EACR,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,oBAkDA"}
|
package/lib/util/file.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pruneDir = exports.safeRimraf = void 0;
|
|
4
|
+
const rimraf_1 = require("rimraf");
|
|
5
|
+
const logger_1 = require("../util/logger");
|
|
6
|
+
const promises_1 = require("fs/promises");
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
async function safeRimraf(path) {
|
|
9
|
+
logger_1.logger.debug(`Removing ${path}`);
|
|
10
|
+
try {
|
|
11
|
+
await (0, rimraf_1.rimraf)(path);
|
|
12
|
+
}
|
|
13
|
+
catch (e) {
|
|
14
|
+
logger_1.logger.error(`Failed to remove ${path}. Please manually delete the file or directory.`);
|
|
15
|
+
logger_1.logger.debug(`Error removing ${path}: ${e}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.safeRimraf = safeRimraf;
|
|
19
|
+
async function pruneDir({ path, exclude, recurse }) {
|
|
20
|
+
/**
|
|
21
|
+
* Deletes all files and directories in a given directory path, excluding specific paths.
|
|
22
|
+
* Will not delete top-level directory
|
|
23
|
+
* @param {string} path path of directory to prune.
|
|
24
|
+
* @param {string[]} exclude list of paths to exclude when pruning
|
|
25
|
+
* @param {boolean} recurse flag to prune recursively into directories
|
|
26
|
+
*/
|
|
27
|
+
try {
|
|
28
|
+
const files = await (0, promises_1.readdir)(path);
|
|
29
|
+
let canPruneParent = true;
|
|
30
|
+
for (const file of files) {
|
|
31
|
+
const filePath = (0, path_1.join)(path, file);
|
|
32
|
+
const isExcluded = exclude === null || exclude === void 0 ? void 0 : exclude.some((excludePath) => filePath.endsWith(excludePath));
|
|
33
|
+
if (isExcluded) {
|
|
34
|
+
logger_1.logger.debug(`Excluding file ${filePath} during pruning.`);
|
|
35
|
+
canPruneParent = false;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
const fileStats = await (0, promises_1.stat)(filePath);
|
|
39
|
+
if (fileStats.isDirectory()) {
|
|
40
|
+
if (recurse) {
|
|
41
|
+
const dirIsEmpty = await pruneDir({
|
|
42
|
+
path: filePath,
|
|
43
|
+
exclude,
|
|
44
|
+
recurse
|
|
45
|
+
});
|
|
46
|
+
if (dirIsEmpty) {
|
|
47
|
+
await (0, promises_1.rmdir)(filePath);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
canPruneParent = false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
await (0, promises_1.unlink)(filePath);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return canPruneParent;
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
logger_1.logger.error(`Error pruning directory ${path}: ${JSON.stringify(error)}`);
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.pruneDir = pruneDir;
|
|
66
|
+
//# sourceMappingURL=file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/util/file.ts"],"names":[],"mappings":";;;AAAA,mCAAgC;AAChC,2CAAwC;AACxC,0CAA2D;AAC3D,+BAA4B;AAErB,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,eAAM,CAAC,KAAK,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IACjC,IAAI;QACF,MAAM,IAAA,eAAM,EAAC,IAAI,CAAC,CAAC;KACpB;IAAC,OAAO,CAAC,EAAE;QACV,eAAM,CAAC,KAAK,CACV,oBAAoB,IAAI,iDAAiD,CAC1E,CAAC;QACF,eAAM,CAAC,KAAK,CAAC,kBAAkB,IAAI,KAAK,CAAC,EAAE,CAAC,CAAC;KAC9C;AACH,CAAC;AAVD,gCAUC;AAEM,KAAK,UAAU,QAAQ,CAAC,EAC7B,IAAI,EACJ,OAAO,EACP,OAAO,EAKR;IACC;;;;;;OAMG;IACH,IAAI;QACF,MAAM,KAAK,GAAG,MAAM,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;QAElC,IAAI,cAAc,GAAG,IAAI,CAAC;QAE1B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAElC,MAAM,UAAU,GAAG,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAC/C,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAC/B,CAAC;YAEF,IAAI,UAAU,EAAE;gBACd,eAAM,CAAC,KAAK,CAAC,kBAAkB,QAAQ,kBAAkB,CAAC,CAAC;gBAC3D,cAAc,GAAG,KAAK,CAAC;gBACvB,SAAS;aACV;YAED,MAAM,SAAS,GAAG,MAAM,IAAA,eAAI,EAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,SAAS,CAAC,WAAW,EAAE,EAAE;gBAC3B,IAAI,OAAO,EAAE;oBACX,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC;wBAChC,IAAI,EAAE,QAAQ;wBACd,OAAO;wBACP,OAAO;qBACR,CAAC,CAAC;oBAEH,IAAI,UAAU,EAAE;wBACd,MAAM,IAAA,gBAAK,EAAC,QAAQ,CAAC,CAAC;qBACvB;yBAAM;wBACL,cAAc,GAAG,KAAK,CAAC;qBACxB;iBACF;aACF;iBAAM;gBACL,MAAM,IAAA,iBAAM,EAAC,QAAQ,CAAC,CAAC;aACxB;SACF;QACD,OAAO,cAAc,CAAC;KACvB;IAAC,OAAO,KAAK,EAAE;QACd,eAAM,CAAC,KAAK,CAAC,2BAA2B,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1E,OAAO,KAAK,CAAC;KACd;AACH,CAAC;AA1DD,4BA0DC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.test.d.ts","sourceRoot":"","sources":["../../src/util/file.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const file_1 = require("../../src/util/file");
|
|
4
|
+
const promises_1 = require("fs/promises");
|
|
5
|
+
jest.mock('fs/promises');
|
|
6
|
+
describe('pruneDir function', () => {
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
jest.clearAllMocks();
|
|
9
|
+
});
|
|
10
|
+
it('should return true if directory is successfully pruned', async () => {
|
|
11
|
+
const path = '/path/to/directory';
|
|
12
|
+
const files = ['file1.txt', 'file2.txt'];
|
|
13
|
+
promises_1.readdir.mockResolvedValue(files);
|
|
14
|
+
promises_1.stat.mockResolvedValue({ isDirectory: () => false });
|
|
15
|
+
const result = await (0, file_1.pruneDir)({ path });
|
|
16
|
+
expect(result).toBe(true);
|
|
17
|
+
expect(promises_1.readdir).toHaveBeenCalledWith(path);
|
|
18
|
+
expect(promises_1.stat).toHaveBeenCalledTimes(2); // Called for each file
|
|
19
|
+
expect(promises_1.unlink).toHaveBeenCalledTimes(2); // Called for each file
|
|
20
|
+
});
|
|
21
|
+
it('should exclude specified files from pruning', async () => {
|
|
22
|
+
const path = '/path/to/directory';
|
|
23
|
+
const files = ['file1.txt', 'file2.txt'];
|
|
24
|
+
const exclude = ['file1.txt']; // Exclude file1.txt
|
|
25
|
+
promises_1.readdir.mockResolvedValue(files);
|
|
26
|
+
promises_1.stat.mockResolvedValue({ isDirectory: () => false });
|
|
27
|
+
const result = await (0, file_1.pruneDir)({ path, exclude });
|
|
28
|
+
expect(result).toBe(false);
|
|
29
|
+
expect(promises_1.readdir).toHaveBeenCalledWith(path);
|
|
30
|
+
expect(promises_1.stat).toHaveBeenCalledTimes(1); // Called only for file2.txt
|
|
31
|
+
expect(promises_1.unlink).toHaveBeenCalledTimes(1); // Called only for file2.txt
|
|
32
|
+
});
|
|
33
|
+
it('should recursively prune directories if recurse option is true', async () => {
|
|
34
|
+
const rootPath = '/path/to/directory';
|
|
35
|
+
const subDirPath = '/path/to/directory/subdir';
|
|
36
|
+
const files = ['file1.txt', 'subdir'];
|
|
37
|
+
const subDirFiles = ['file2.txt'];
|
|
38
|
+
promises_1.readdir.mockImplementation((path) => {
|
|
39
|
+
if (path === rootPath)
|
|
40
|
+
return files;
|
|
41
|
+
if (path === subDirPath)
|
|
42
|
+
return subDirFiles;
|
|
43
|
+
});
|
|
44
|
+
promises_1.stat.mockImplementation((path) => {
|
|
45
|
+
if (path === `${rootPath}/file1.txt`)
|
|
46
|
+
return { isDirectory: () => false };
|
|
47
|
+
if (path === subDirPath)
|
|
48
|
+
return { isDirectory: () => true };
|
|
49
|
+
if (path === `${subDirPath}/file2.txt`)
|
|
50
|
+
return { isDirectory: () => false };
|
|
51
|
+
});
|
|
52
|
+
const result = await (0, file_1.pruneDir)({ path: rootPath, recurse: true });
|
|
53
|
+
expect(result).toBe(true);
|
|
54
|
+
expect(promises_1.readdir).toHaveBeenCalledWith(rootPath);
|
|
55
|
+
expect(promises_1.readdir).toHaveBeenCalledWith(subDirPath);
|
|
56
|
+
expect(promises_1.stat).toHaveBeenCalledTimes(3); // Called for file1.txt, subdir, and file2.txt
|
|
57
|
+
expect(promises_1.unlink).toHaveBeenCalledWith(`${rootPath}/file1.txt`);
|
|
58
|
+
expect(promises_1.unlink).toHaveBeenCalledWith(`${subDirPath}/file2.txt`);
|
|
59
|
+
expect(promises_1.rmdir).toHaveBeenCalledWith(subDirPath);
|
|
60
|
+
});
|
|
61
|
+
it('should not recurse into directories if recurse option is false', async () => {
|
|
62
|
+
const rootPath = '/path/to/directory';
|
|
63
|
+
const subDirPath = '/path/to/directory/subdir';
|
|
64
|
+
const files = ['file1.txt', 'subdir'];
|
|
65
|
+
const subDirFiles = ['file2.txt'];
|
|
66
|
+
promises_1.readdir.mockImplementation((path) => {
|
|
67
|
+
if (path === rootPath)
|
|
68
|
+
return files;
|
|
69
|
+
if (path === subDirPath)
|
|
70
|
+
return subDirFiles;
|
|
71
|
+
});
|
|
72
|
+
promises_1.stat.mockImplementation((path) => {
|
|
73
|
+
if (path === `${rootPath}/file1.txt`)
|
|
74
|
+
return { isDirectory: () => false };
|
|
75
|
+
if (path === subDirPath)
|
|
76
|
+
return { isDirectory: () => true };
|
|
77
|
+
});
|
|
78
|
+
const result = await (0, file_1.pruneDir)({ path: rootPath, recurse: false });
|
|
79
|
+
expect(result).toBe(true);
|
|
80
|
+
expect(promises_1.readdir).toHaveBeenCalledWith(rootPath);
|
|
81
|
+
expect(promises_1.stat).toHaveBeenCalledTimes(2); // Called for file1.txt and subdir
|
|
82
|
+
expect(promises_1.unlink).toHaveBeenCalledWith(`${rootPath}/file1.txt`);
|
|
83
|
+
expect(promises_1.unlink).not.toHaveBeenCalledWith(`${subDirPath}/file2.txt`);
|
|
84
|
+
expect(promises_1.rmdir).not.toHaveBeenCalled();
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=file.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.test.js","sourceRoot":"","sources":["../../src/util/file.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alwaysai/device-agent",
|
|
3
3
|
"description": "The alwaysAI Device Agent",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.0",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
7
7
|
"publishConfig": {
|
|
@@ -37,26 +37,27 @@
|
|
|
37
37
|
"@alwaysai/alwayscli": "0.3.2",
|
|
38
38
|
"@alwaysai/app-configuration-schemas": "0.1.0",
|
|
39
39
|
"@alwaysai/config-nodejs": "0.3.0",
|
|
40
|
-
"@alwaysai/device-agent-schemas": "2.
|
|
40
|
+
"@alwaysai/device-agent-schemas": "2.3.3",
|
|
41
41
|
"@carnesen/coded-error": "0.4.0",
|
|
42
42
|
"ajv": "8.11.0",
|
|
43
|
-
"alwaysai": "2.
|
|
43
|
+
"alwaysai": "2.5.3",
|
|
44
44
|
"amqplib": "0.10.3",
|
|
45
45
|
"aws-iot-device-sdk": "2.2.12",
|
|
46
|
-
"docker-compose": "0.
|
|
46
|
+
"docker-compose": "0.24.3",
|
|
47
47
|
"lodash": "4.17.21",
|
|
48
48
|
"node-fetch": "2.6.1",
|
|
49
49
|
"node-os-utils": "1.3.7",
|
|
50
50
|
"rimraf": "4.4.0",
|
|
51
51
|
"systeminformation": "5.21.13",
|
|
52
52
|
"uuid": "9.0.0",
|
|
53
|
-
"winston": "3.
|
|
54
|
-
"winston-daily-rotate-file": "
|
|
53
|
+
"winston": "3.13.0",
|
|
54
|
+
"winston-daily-rotate-file": "5.0.0",
|
|
55
55
|
"yaml": "2.2.1"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@alwaysai/tsconfig": "0.0.1",
|
|
59
58
|
"@alwaysai/eslint-config": "0.1.0",
|
|
59
|
+
"@alwaysai/tsconfig": "0.0.1",
|
|
60
|
+
"@types/amqplib": "0.10.5",
|
|
60
61
|
"@types/destroy": "1.0.0",
|
|
61
62
|
"@types/jest": "28.1.2",
|
|
62
63
|
"@types/node": "16.11.12",
|
package/readme.md
CHANGED
|
@@ -42,13 +42,13 @@ change.
|
|
|
42
42
|
|
|
43
43
|
* Supported OS:
|
|
44
44
|
* Debian Bookworm, Bullseye
|
|
45
|
-
* Ubuntu 23.10, 22.04, 20.04
|
|
46
|
-
* NVIDIA
|
|
45
|
+
* Ubuntu 24.04, 23.10, 22.04, 20.04
|
|
46
|
+
* NVIDIA JetPack 5.1.1, 5.1
|
|
47
47
|
* Supported target architecture
|
|
48
48
|
* amd64
|
|
49
49
|
* aarch64
|
|
50
50
|
* `docker` >= 19.03
|
|
51
|
-
* `docker-compose` >= 1.29.0
|
|
51
|
+
* `docker-compose` >= 1.29.0
|
|
52
52
|
* `curl` installed (required to download provisioning scripts)
|
|
53
53
|
* Passwordless `sudo` for `npm` if using `pm2`
|
|
54
54
|
* Passwordless `sudo` for `/sbin/shutdown` for device restart functionality
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
requireAppReady
|
|
8
8
|
} from './utils';
|
|
9
9
|
import { JsSpawner } from 'alwaysai/lib/util';
|
|
10
|
-
import compose from 'docker-compose';
|
|
10
|
+
import { compose } from '../docker/docker-compose';
|
|
11
11
|
import { assign, merge } from 'lodash';
|
|
12
12
|
import { AppJsonFile } from 'alwaysai/lib/core/app';
|
|
13
13
|
import { AppConfig } from '@alwaysai/app-configuration-schemas';
|
|
@@ -41,24 +41,27 @@ export async function setEnv(props: { projectId: string; envVars: EnvVars }) {
|
|
|
41
41
|
|
|
42
42
|
const service = composeParsed['services'][s];
|
|
43
43
|
const oldEnv: string[] | undefined = service['environment'];
|
|
44
|
+
const envVarsForService = envVars[s];
|
|
44
45
|
|
|
45
46
|
const newEnvVarsObj = {};
|
|
46
47
|
oldEnv?.forEach((envVarStr: string) => {
|
|
47
48
|
const envVarSplit = envVarStr.split('=');
|
|
48
49
|
const key = envVarSplit[0];
|
|
49
50
|
const value = envVarSplit[1];
|
|
50
|
-
|
|
51
|
+
if (envVarsForService[key] !== null) {
|
|
52
|
+
newEnvVarsObj[key] = value;
|
|
53
|
+
}
|
|
51
54
|
});
|
|
52
55
|
|
|
53
|
-
for (const envVar of Object.keys(
|
|
54
|
-
|
|
56
|
+
for (const envVar of Object.keys(envVarsForService)) {
|
|
57
|
+
if (envVarsForService[envVar] !== null) {
|
|
58
|
+
newEnvVarsObj[envVar] = envVarsForService[envVar];
|
|
59
|
+
}
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
const envVarList: string[] = [];
|
|
58
63
|
for (const envVar of Object.keys(newEnvVarsObj)) {
|
|
59
|
-
envVarList.push(
|
|
60
|
-
`${envVar}=${newEnvVarsObj[envVar] ? newEnvVarsObj[envVar] : ''}`
|
|
61
|
-
);
|
|
64
|
+
envVarList.push(`${envVar}=${newEnvVarsObj[envVar]}`);
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
service['environment'] = envVarList;
|
|
@@ -113,12 +113,18 @@ export async function installApp(props: {
|
|
|
113
113
|
const DACfg = await createAppCfgDeviceAgentConnection();
|
|
114
114
|
await updateAppCfgFile({ projectId, newAppCfg: DACfg });
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
// Clean up original dependency files (models, virtual env)
|
|
117
|
+
const targetJsonFile = TargetJsonFile(appDir);
|
|
118
|
+
const hostSpawner = targetJsonFile.readHostSpawner();
|
|
119
|
+
await appCleanDocker({ targetHostSpawner: hostSpawner });
|
|
120
|
+
|
|
121
|
+
// Download model files
|
|
117
122
|
await installModelsWithPresignedURLs(
|
|
118
123
|
signedUrlsPayload.modelsInstallPayload,
|
|
119
124
|
path.join(appDir, 'models')
|
|
120
125
|
);
|
|
121
126
|
|
|
127
|
+
await installAppBuildReqs({ appDir });
|
|
122
128
|
await buildApp({ appDir });
|
|
123
129
|
|
|
124
130
|
await AgentConfigFile().setAppInstalled({
|
|
@@ -153,8 +159,6 @@ async function installAppBuildReqs(props: { appDir: string }) {
|
|
|
153
159
|
async () => {
|
|
154
160
|
const hostSpawner = targetJsonFile.readHostSpawner();
|
|
155
161
|
|
|
156
|
-
await appCleanDocker({ targetHostSpawner: hostSpawner });
|
|
157
|
-
|
|
158
162
|
const dockerImageId = await buildDockerImage({
|
|
159
163
|
targetHostSpawner: hostSpawner,
|
|
160
164
|
targetHardware: targetCfg.targetHardware,
|
|
@@ -227,6 +231,7 @@ export async function uninstallApp(props: {
|
|
|
227
231
|
logger.info(`Application ${projectId} not installed`);
|
|
228
232
|
return;
|
|
229
233
|
}
|
|
234
|
+
await AgentConfigFile().setAppUninstalling({ projectId });
|
|
230
235
|
try {
|
|
231
236
|
await stopApp({ projectId });
|
|
232
237
|
} catch (e) {
|