iobroker.javascript 10.0.0 → 10.1.1
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/README.md +48 -12
- package/admin/assets/AiChatPanel-C_WbKMGX.js +242 -0
- package/admin/assets/AiDiffView-BtXbDWZ8.js +1 -0
- package/admin/assets/Debugger-DAdJnEhw.js +15 -0
- package/admin/assets/Error-DQ1pzKcf.js +1 -0
- package/admin/assets/Import-BjMtH6Gk.js +1 -0
- package/admin/assets/RulesEditor-dDRPHw4X.js +1 -0
- package/admin/assets/RulesEditor-k-DMHotH.css +1 -0
- package/admin/assets/{ScriptEditor-BGIuoNei.js → ScriptEditor-CZSc7rwE.js} +2 -2
- package/admin/assets/ScriptEditorVanillaMonaco-DEKg14_A.js +3 -0
- package/admin/assets/_virtual_mf-localSharedImportMap___mfe_internal__iobroker_javascript__mf_owner__1-DPmwd_G2.js +1 -0
- package/admin/assets/_virtual_mf___mfe_internal__iobroker_javascript__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-C8inUeKt.js +1243 -0
- package/admin/assets/_virtual_mf___mfe_internal__iobroker_javascript__mf_owner__1__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-VcQjt7_9.js +9 -0
- package/admin/assets/aiPromptBuilder-D5FDo74i.js +1 -0
- package/admin/assets/blockly-DBw-ytY1.js +1047 -0
- package/admin/assets/blocks_action-BqfWEwpf.js +1 -0
- package/admin/assets/blocks_convert-CX0i-JfS.js +3 -0
- package/admin/assets/blocks_logic-D-QSzw95.js +1 -0
- package/admin/assets/blocks_number-D7JuNYsw.js +1 -0
- package/admin/assets/blocks_object-C9DzAlc7.js +1 -0
- package/admin/assets/blocks_procedures-BJMz6HWW.js +3 -0
- package/admin/assets/blocks_sendto-DRh7lk9o.js +5 -0
- package/admin/assets/blocks_switch-BfmboMex.js +2 -0
- package/admin/assets/blocks_system-B-78JfAc.js +1 -0
- package/admin/assets/blocks_text-CGbR0Ozw.js +1 -0
- package/admin/assets/blocks_time-5vS2geJg.js +1 -0
- package/admin/assets/blocks_timeout-BdaTywfN.js +1 -0
- package/admin/assets/blocks_trigger-D8kgHKbg.js +2 -0
- package/admin/assets/blocks_words-BhHIf_1o.js +1 -0
- package/admin/assets/{cronHoverProvider-pKJkSevo.js → cronHoverProvider-DpgESCox.js} +1 -1
- package/admin/assets/dist-CaOsN0XW.js +4 -0
- package/admin/assets/field_cron-B40zwSfJ.js +1 -0
- package/admin/assets/field_oid-KfoBnEM9.js +1 -0
- package/admin/assets/field_script-yXhe1iCp.js +1 -0
- package/admin/assets/helpers-B0ByElPJ.js +1 -0
- package/admin/assets/hostInit-9REPDUe7.js +1 -0
- package/admin/assets/index-07o_WKsX.js +726 -0
- package/admin/assets/index-Z8Hkv58g.css +1 -0
- package/admin/assets/{inlineChatWidget-ZaisTOLh.js → inlineChatWidget-B9y_gQcH.js} +2 -2
- package/admin/assets/{inlineDiffController-hTwHHqcc.js → inlineDiffController-C07CdIFo.js} +2 -2
- package/admin/assets/{mf-entry-bootstrap-0-d6052b31.js → mf-entry-bootstrap-0-efcb49d3.js} +7 -2
- package/admin/assets/stateHoverProvider-CqeoOjXs.js +9 -0
- package/admin/assets/{virtualExposes-Ed0lGq7k.js → virtualExposes-DgGB-18P.js} +1 -1
- package/admin/assets/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__iobroker_javascript__remoteEntry_js-BwSvIKEV.js +1 -0
- package/admin/assets/virtual_mf-exposes___mfe_internal__iobroker_javascript__remoteEntry_js-ChiJXsfH.js +1 -0
- package/admin/custom/assets/Components-BCQTjBgm.js +1 -0
- package/admin/custom/assets/_virtual_mf-localSharedImportMap___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1-BuAc8OyX.js +1 -0
- package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-BGJv4zZP.js +1 -0
- package/admin/custom/assets/{_virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare___mf_0_emotion_mf_1_styled__loadShare__.js-CGb5Cofy.js → _virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare___mf_0_emotion_mf_1_styled__loadShare__.js-B4E6MFJ4.js} +1 -1
- package/admin/custom/assets/{_virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-BVCIAgbo.js → _virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-aRlxyEhq.js} +78 -78
- package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-DQwzYx75.js +1494 -0
- package/admin/custom/assets/{_virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare__leaflet__loadShare__.js-h-rCw3iz.js → _virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare__leaflet__loadShare__.js-n2zIPi0L.js} +1 -1
- package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-xxszBNje.js +9 -0
- package/admin/custom/assets/{_virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__prebuild__date_mf_2_fns__prebuild__-Cb5TR7FB.js → _virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__prebuild__date_mf_2_fns__prebuild__-Tq7tesSS.js} +1 -1
- package/admin/custom/assets/{_virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__prebuild__leaflet__prebuild__-DARUoA03.js → _virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__prebuild__leaflet__prebuild__-BeF0jEWM.js} +1 -1
- package/admin/custom/assets/hostInit-CHwrowP4.js +1 -0
- package/admin/custom/assets/{index-uEKAoVT7.js → index-Cm6xl9K4.js} +1 -1
- package/admin/custom/assets/{lib-Yj8cfN0A.js → lib-bhrFL6jR.js} +1 -1
- package/admin/custom/assets/{mf-entry-bootstrap-0-77793feb.js → mf-entry-bootstrap-0-f08941e2.js} +7 -2
- package/admin/custom/assets/{setYear-DJ9FbdkO.js → setYear-DzTZ2h9A.js} +1 -1
- package/admin/custom/assets/virtualExposes-B5LJmnfO.js +1 -0
- package/admin/custom/assets/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__ConfigCustomJavascriptSet__customComponents_js-ML-chjs6.js +1 -0
- package/admin/custom/assets/virtual_mf-exposes___mfe_internal__ConfigCustomJavascriptSet__customComponents_js-C3ImybiM.js +2 -0
- package/admin/custom/customComponents.js +12 -1
- package/admin/custom/i18n/de.json +11 -1
- package/admin/custom/i18n/en.json +11 -1
- package/admin/custom/i18n/es.json +11 -1
- package/admin/custom/i18n/fr.json +11 -1
- package/admin/custom/i18n/it.json +11 -1
- package/admin/custom/i18n/nl.json +11 -1
- package/admin/custom/i18n/pl.json +11 -1
- package/admin/custom/i18n/pt.json +11 -1
- package/admin/custom/i18n/ru.json +11 -1
- package/admin/custom/i18n/uk.json +11 -1
- package/admin/custom/i18n/zh-cn.json +11 -1
- package/admin/google-blockly/VERSION +1 -0
- package/admin/google-blockly/media/drop.mp3 +0 -0
- package/admin/google-blockly/msg/js/de.js +332 -56
- package/admin/google-blockly/msg/js/en.js +319 -43
- package/admin/google-blockly/msg/js/es.js +319 -42
- package/admin/google-blockly/msg/js/fr.js +315 -39
- package/admin/google-blockly/msg/js/it.js +327 -51
- package/admin/google-blockly/msg/js/nl.js +376 -100
- package/admin/google-blockly/msg/js/pl.js +318 -42
- package/admin/google-blockly/msg/js/pt.js +318 -42
- package/admin/google-blockly/msg/js/ru.js +320 -44
- package/admin/google-blockly/msg/js/uk.js +326 -50
- package/admin/google-blockly/msg/js/zh-cn.js +322 -46
- package/admin/i18n/de.json +51 -26
- package/admin/i18n/en.json +50 -25
- package/admin/i18n/es.json +51 -18
- package/admin/i18n/fr.json +50 -17
- package/admin/i18n/it.json +50 -17
- package/admin/i18n/nl.json +50 -17
- package/admin/i18n/pl.json +51 -18
- package/admin/i18n/pt.json +50 -17
- package/admin/i18n/ru.json +50 -17
- package/admin/i18n/uk.json +50 -17
- package/admin/i18n/zh-cn.json +50 -17
- package/admin/jsonConfig.json +398 -0
- package/admin/mf-manifest.json +1 -1
- package/admin/mf-stats.json +1 -1
- package/admin/remoteEntry.js +12 -1
- package/admin/tab.html +6 -98
- package/build/lib/javascript.d.ts +48 -0
- package/build/lib/mirror.js +9 -0
- package/build/lib/mirror.js.map +1 -1
- package/build/lib/sandbox.js +37 -0
- package/build/lib/sandbox.js.map +1 -1
- package/build/lib/secrets.js +220 -0
- package/build/lib/secrets.js.map +1 -0
- package/build/lib/typescriptSettings.js +112 -2
- package/build/lib/typescriptSettings.js.map +1 -1
- package/build/lib/typescriptTools.js +168 -43
- package/build/lib/typescriptTools.js.map +1 -1
- package/build/main.js +61 -5
- package/build/main.js.map +1 -1
- package/build/types.d.ts +48 -0
- package/docs/en/blockly.md +29 -0
- package/docs/en/javascript.md +72 -0
- package/docs/en/upgrade-guide.md +3 -0
- package/io-package.json +59 -28
- package/package.json +8 -3
- package/admin/assets/AiChatPanel-p0KAg6Cs.js +0 -237
- package/admin/assets/AiDiffView-BPTLnNx1.js +0 -1
- package/admin/assets/AiScriptAnalyzer--BHML2rN.js +0 -9
- package/admin/assets/BlocklyEditor-CAjVMhYT.js +0 -81
- package/admin/assets/ContextWrapper-BVc8wTK_.css +0 -1
- package/admin/assets/ContextWrapper-D9CrnNKs.js +0 -127
- package/admin/assets/Debugger-SjROokFI.js +0 -15
- package/admin/assets/Error-DDfrxAt2.js +0 -1
- package/admin/assets/Import-DpTg1Jow.js +0 -1
- package/admin/assets/RulesEditor-BSRFWpEm.css +0 -1
- package/admin/assets/RulesEditor-D0hgrcBc.js +0 -1
- package/admin/assets/ScriptEditorVanillaMonaco-DyMQtoTQ.js +0 -3
- package/admin/assets/_virtual_mf-localSharedImportMap___mfe_internal__iobroker_javascript__mf_owner__1-DWJotR1B.js +0 -1
- package/admin/assets/_virtual_mf___mfe_internal__iobroker_javascript__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-CxICLr5Z.js +0 -1243
- package/admin/assets/_virtual_mf___mfe_internal__iobroker_javascript__mf_owner__1__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-BBAXJaqI.js +0 -9
- package/admin/assets/aiCodeLensProvider-hyAmut0e.js +0 -4
- package/admin/assets/aiPromptBuilder-Bs27qOHT.js +0 -7
- package/admin/assets/blocklyDarkTheme-DEiAX5DT.js +0 -1
- package/admin/assets/dist-uw5orDgd.js +0 -4
- package/admin/assets/hostInit-BFg5u9hY.js +0 -1
- package/admin/assets/index-B1gICjdq.js +0 -192
- package/admin/assets/index-BHhhebRG.css +0 -1
- package/admin/assets/mjs-DWqivHEk.js +0 -90
- package/admin/assets/stateHoverProvider-C7DawIs-.js +0 -9
- package/admin/assets/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__iobroker_javascript__remoteEntry_js-BYs71IQF.js +0 -1
- package/admin/assets/virtual_mf-exposes___mfe_internal__iobroker_javascript__remoteEntry_js-DnnXQRkG.js +0 -1
- package/admin/custom/assets/Components-BrDyDHXh.js +0 -1
- package/admin/custom/assets/_virtual_mf-localSharedImportMap___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1-CyYJM2-v.js +0 -1
- package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-BdzCssLn.js +0 -1
- package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-BkB0anQX.js +0 -1494
- package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-BotqDuw-.js +0 -9
- package/admin/custom/assets/hostInit-DJx2uXXy.js +0 -1
- package/admin/custom/assets/virtualExposes-CxDjLoYu.js +0 -1
- package/admin/custom/assets/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__ConfigCustomJavascriptSet__customComponents_js-BU-ugy_7.js +0 -1
- package/admin/custom/assets/virtual_mf-exposes-ssr___mfe_internal__ConfigCustomJavascriptSet__customComponents_js-BEfZbrf7.js +0 -2
- package/admin/custom/assets/virtual_mf-exposes___mfe_internal__ConfigCustomJavascriptSet__customComponents_js-CTeZ0Jpm.js +0 -2
- package/admin/google-blockly/blockly_compressed.js +0 -1679
- package/admin/google-blockly/blocks_compressed.js +0 -193
- package/admin/google-blockly/javascript_compressed.js +0 -264
- package/admin/google-blockly/msg/messages.js +0 -1630
- package/admin/google-blockly/own/blocks_action.js +0 -765
- package/admin/google-blockly/own/blocks_convert.js +0 -480
- package/admin/google-blockly/own/blocks_logic.js +0 -459
- package/admin/google-blockly/own/blocks_number.js +0 -30
- package/admin/google-blockly/own/blocks_object.js +0 -402
- package/admin/google-blockly/own/blocks_procedures.js +0 -688
- package/admin/google-blockly/own/blocks_sendto.js +0 -702
- package/admin/google-blockly/own/blocks_switch.js +0 -257
- package/admin/google-blockly/own/blocks_system.js +0 -1409
- package/admin/google-blockly/own/blocks_text.js +0 -104
- package/admin/google-blockly/own/blocks_time.js +0 -639
- package/admin/google-blockly/own/blocks_timeout.js +0 -551
- package/admin/google-blockly/own/blocks_trigger.js +0 -1791
- package/admin/google-blockly/own/blocks_words.js +0 -708
- package/admin/google-blockly/own/field_cron.js +0 -158
- package/admin/google-blockly/own/field_oid.js +0 -642
- package/admin/google-blockly/own/field_script.js +0 -159
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.SecretsManager = exports.SECRETS_PREFIX = void 0;
|
|
37
|
+
exports.isSecretId = isSecretId;
|
|
38
|
+
exports.getSecretName = getSecretName;
|
|
39
|
+
/**
|
|
40
|
+
* Access to the central ioBroker credential store (`system.credentials.*`) from scripts.
|
|
41
|
+
*
|
|
42
|
+
* The admin UI manages the credentials under "Basic settings" → "Credentials". Every credential
|
|
43
|
+
* has an ID like `system.credentials.CameraPassword` and holds either a single `key` (API keys)
|
|
44
|
+
* or a `login`/`password` pair. The secret fields are stored encrypted with the system secret.
|
|
45
|
+
*
|
|
46
|
+
* This manager keeps all credentials decrypted in memory and exposes them to the scripts as the
|
|
47
|
+
* global `SECRETS` object, so a script can simply write:
|
|
48
|
+
*
|
|
49
|
+
* ```js
|
|
50
|
+
* const password = SECRETS.CameraPassword.key;
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* The cache is kept up to date while the adapter is running, so editing a credential in the admin
|
|
54
|
+
* UI takes effect immediately - without restarting the adapter or the scripts.
|
|
55
|
+
*/
|
|
56
|
+
// Imported from its own entry point on purpose: the package index of `@iobroker/adapter-core`
|
|
57
|
+
// looks for js-controller while it is being loaded and terminates the process with exit code 10
|
|
58
|
+
// when it is missing. This module is required by the unit tests, which run without a controller,
|
|
59
|
+
// so it must stay clear of that side effect. `@iobroker/adapter-core/credentials` is free of it -
|
|
60
|
+
// it is written to be usable in browser builds as well.
|
|
61
|
+
const Credentials = __importStar(require("@iobroker/adapter-core/credentials"));
|
|
62
|
+
/** Prefix of all credential object IDs */
|
|
63
|
+
exports.SECRETS_PREFIX = 'system.credentials.';
|
|
64
|
+
/**
|
|
65
|
+
* Checks if the given object ID belongs to the central credential store.
|
|
66
|
+
*
|
|
67
|
+
* @param id Object ID, e.g. `system.credentials.CameraPassword`
|
|
68
|
+
*/
|
|
69
|
+
function isSecretId(id) {
|
|
70
|
+
return id.startsWith(exports.SECRETS_PREFIX) && id.length > exports.SECRETS_PREFIX.length;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Extracts the name a credential is exposed under in `SECRETS`.
|
|
74
|
+
*
|
|
75
|
+
* @param id Object ID, e.g. `system.credentials.CameraPassword`
|
|
76
|
+
*/
|
|
77
|
+
function getSecretName(id) {
|
|
78
|
+
return id.substring(exports.SECRETS_PREFIX.length);
|
|
79
|
+
}
|
|
80
|
+
class SecretsManager {
|
|
81
|
+
adapter;
|
|
82
|
+
/** Decrypted credentials, keyed by name (the credential ID without the `system.credentials.` prefix) */
|
|
83
|
+
cache = new Map();
|
|
84
|
+
/** If the scripts may read the credentials at all (adapter option `enableSecrets`) */
|
|
85
|
+
enabled = false;
|
|
86
|
+
/** Warn only once per script run that the feature is disabled */
|
|
87
|
+
disabledWarningShown = false;
|
|
88
|
+
/**
|
|
89
|
+
* The object handed to the scripts as the global `SECRETS`.
|
|
90
|
+
*
|
|
91
|
+
* It is a read-only view on the cache, so the values stay up to date without the scripts
|
|
92
|
+
* having to re-read anything, and a script cannot modify the credentials of another script.
|
|
93
|
+
*/
|
|
94
|
+
secrets;
|
|
95
|
+
constructor(adapter) {
|
|
96
|
+
this.adapter = adapter;
|
|
97
|
+
this.secrets = new Proxy(Object.create(null), {
|
|
98
|
+
get: (_target, prop) => typeof prop === 'string' ? this.get(prop) : undefined,
|
|
99
|
+
has: (_target, prop) => typeof prop === 'string' && this.cache.has(prop),
|
|
100
|
+
ownKeys: () => (this.enabled ? Array.from(this.cache.keys()) : []),
|
|
101
|
+
getOwnPropertyDescriptor: (_target, prop) => {
|
|
102
|
+
const value = typeof prop === 'string' ? this.get(prop) : undefined;
|
|
103
|
+
return value === undefined
|
|
104
|
+
? undefined
|
|
105
|
+
: { value, enumerable: true, configurable: true, writable: false };
|
|
106
|
+
},
|
|
107
|
+
// The credentials belong to the system - scripts may read them, but never change them
|
|
108
|
+
set: () => false,
|
|
109
|
+
defineProperty: () => false,
|
|
110
|
+
deleteProperty: () => false,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/** Reads one credential from the cache and warns if the whole feature is switched off */
|
|
114
|
+
get(name) {
|
|
115
|
+
if (!this.enabled) {
|
|
116
|
+
if (!this.disabledWarningShown) {
|
|
117
|
+
this.disabledWarningShown = true;
|
|
118
|
+
this.adapter.log.warn(`A script tried to read the secret "${name}", but the access to the credentials is disabled. Enable "Allow scripts to read the credentials" in the instance settings.`);
|
|
119
|
+
}
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
return this.cache.get(name);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Reads all credentials of the central store and decrypts them.
|
|
126
|
+
*
|
|
127
|
+
* @param enabled Value of the adapter option `enableSecrets`
|
|
128
|
+
*/
|
|
129
|
+
async load(enabled) {
|
|
130
|
+
this.cache.clear();
|
|
131
|
+
this.disabledWarningShown = false;
|
|
132
|
+
this.enabled = enabled;
|
|
133
|
+
if (!enabled) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (!Credentials?.listCredentials) {
|
|
137
|
+
this.adapter.log.warn('Cannot read the credentials for "SECRETS": the credentials API is only available with js-controller 7.2 or newer');
|
|
138
|
+
this.enabled = false;
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
const list = await Credentials.listCredentials(this.adapter);
|
|
143
|
+
for (const entry of list) {
|
|
144
|
+
await this.update(entry.id);
|
|
145
|
+
}
|
|
146
|
+
this.adapter.log.debug(`${this.cache.size} secret(s) available in the scripts as "SECRETS"`);
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
this.adapter.log.warn(`Cannot read the credentials: ${e instanceof Error ? e.message : String(e)}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Reads one credential and decrypts it. Called for every change of a `system.credentials.*`
|
|
154
|
+
* object, so edits in the admin UI are visible in the scripts immediately.
|
|
155
|
+
*
|
|
156
|
+
* @param id Object ID, e.g. `system.credentials.CameraPassword`
|
|
157
|
+
*/
|
|
158
|
+
async update(id) {
|
|
159
|
+
if (!this.enabled || !isSecretId(id)) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const name = getSecretName(id);
|
|
163
|
+
try {
|
|
164
|
+
const credentials = await Credentials.getCredentials(this.adapter, id);
|
|
165
|
+
this.cache.set(name, Object.freeze({ ...credentials.values }));
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
this.cache.delete(name);
|
|
169
|
+
this.adapter.log.warn(`Cannot read the secret "${name}": ${e instanceof Error ? e.message : String(e)}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Forgets one credential because its object was deleted.
|
|
174
|
+
*
|
|
175
|
+
* @param id Object ID, e.g. `system.credentials.CameraPassword`
|
|
176
|
+
*/
|
|
177
|
+
remove(id) {
|
|
178
|
+
if (isSecretId(id) && this.cache.delete(getSecretName(id))) {
|
|
179
|
+
this.adapter.log.debug(`Secret "${getSecretName(id)}" was deleted`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* The structure of the credential store without any secret value: which credentials exist and
|
|
184
|
+
* which fields each of them has. Used by the instance settings and the Blockly editor to show
|
|
185
|
+
* the user what `SECRETS.<name>.<field>` expressions are available.
|
|
186
|
+
*/
|
|
187
|
+
getStructure() {
|
|
188
|
+
return Array.from(this.cache.entries())
|
|
189
|
+
.map(([name, values]) => ({ name, fields: Object.keys(values).sort() }))
|
|
190
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Builds the ambient TypeScript declarations for the credentials that currently exist, so the
|
|
194
|
+
* editor can suggest their names after typing `SECRETS.` and their fields after the next dot.
|
|
195
|
+
* The names are merged into the `iobJS.Secrets` interface, which has an index signature for
|
|
196
|
+
* all other names.
|
|
197
|
+
*/
|
|
198
|
+
getDeclarations() {
|
|
199
|
+
const lines = [
|
|
200
|
+
'// Generated by ioBroker.javascript from the central credential store - do not edit',
|
|
201
|
+
'declare namespace iobJS {',
|
|
202
|
+
' interface Secrets {',
|
|
203
|
+
];
|
|
204
|
+
for (const { name, fields } of this.getStructure()) {
|
|
205
|
+
const values = this.cache.get(name);
|
|
206
|
+
// Declare the fields this credential really has, so the editor suggests exactly those
|
|
207
|
+
const members = fields.map(field => `${JSON.stringify(field)}: ${typeof values[field]}`).join('; ');
|
|
208
|
+
lines.push(` ${JSON.stringify(name)}: { ${members} };`);
|
|
209
|
+
}
|
|
210
|
+
lines.push(' }', '}', '');
|
|
211
|
+
return lines.join('\n');
|
|
212
|
+
}
|
|
213
|
+
/** Forgets all decrypted credentials */
|
|
214
|
+
destroy() {
|
|
215
|
+
this.cache.clear();
|
|
216
|
+
this.enabled = false;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
exports.SecretsManager = SecretsManager;
|
|
220
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/lib/secrets.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Access to the central ioBroker credential store (`system.credentials.*`) from scripts.\n *\n * The admin UI manages the credentials under \"Basic settings\" → \"Credentials\". Every credential\n * has an ID like `system.credentials.CameraPassword` and holds either a single `key` (API keys)\n * or a `login`/`password` pair. The secret fields are stored encrypted with the system secret.\n *\n * This manager keeps all credentials decrypted in memory and exposes them to the scripts as the\n * global `SECRETS` object, so a script can simply write:\n *\n * ```js\n * const password = SECRETS.CameraPassword.key;\n * ```\n *\n * The cache is kept up to date while the adapter is running, so editing a credential in the admin\n * UI takes effect immediately - without restarting the adapter or the scripts.\n */\n// Imported from its own entry point on purpose: the package index of `@iobroker/adapter-core`\n// looks for js-controller while it is being loaded and terminates the process with exit code 10\n// when it is missing. This module is required by the unit tests, which run without a controller,\n// so it must stay clear of that side effect. `@iobroker/adapter-core/credentials` is free of it -\n// it is written to be usable in browser builds as well.\nimport * as Credentials from '@iobroker/adapter-core/credentials';\n\n/** Prefix of all credential object IDs */\nexport const SECRETS_PREFIX = 'system.credentials.';\n\n/** Decrypted fields of one credential, e.g. `{ key: 'abc' }` or `{ login: 'user', password: 'pass' }` */\nexport type SecretValues = Record<string, string | number | boolean>;\n\n/** The global `SECRETS` object: credential name (ID without the prefix) => decrypted fields */\nexport type Secrets = Record<string, SecretValues>;\n\n/** One credential without its values: only the name and the names of its fields */\nexport interface SecretStructure {\n /** Credential name, i.e. the object ID without the `system.credentials.` prefix */\n name: string;\n /** Names of the fields this credential has, e.g. `['key']` or `['login', 'password']` */\n fields: string[];\n}\n\n/**\n * Checks if the given object ID belongs to the central credential store.\n *\n * @param id Object ID, e.g. `system.credentials.CameraPassword`\n */\nexport function isSecretId(id: string): boolean {\n return id.startsWith(SECRETS_PREFIX) && id.length > SECRETS_PREFIX.length;\n}\n\n/**\n * Extracts the name a credential is exposed under in `SECRETS`.\n *\n * @param id Object ID, e.g. `system.credentials.CameraPassword`\n */\nexport function getSecretName(id: string): string {\n return id.substring(SECRETS_PREFIX.length);\n}\n\nexport class SecretsManager {\n private readonly adapter: ioBroker.Adapter;\n\n /** Decrypted credentials, keyed by name (the credential ID without the `system.credentials.` prefix) */\n private readonly cache: Map<string, Readonly<SecretValues>> = new Map();\n\n /** If the scripts may read the credentials at all (adapter option `enableSecrets`) */\n private enabled = false;\n\n /** Warn only once per script run that the feature is disabled */\n private disabledWarningShown = false;\n\n /**\n * The object handed to the scripts as the global `SECRETS`.\n *\n * It is a read-only view on the cache, so the values stay up to date without the scripts\n * having to re-read anything, and a script cannot modify the credentials of another script.\n */\n public readonly secrets: Secrets;\n\n constructor(adapter: ioBroker.Adapter) {\n this.adapter = adapter;\n\n this.secrets = new Proxy(Object.create(null) as Secrets, {\n get: (_target: Secrets, prop: string | symbol): SecretValues | undefined =>\n typeof prop === 'string' ? this.get(prop) : undefined,\n has: (_target: Secrets, prop: string | symbol): boolean => typeof prop === 'string' && this.cache.has(prop),\n ownKeys: (): string[] => (this.enabled ? Array.from(this.cache.keys()) : []),\n getOwnPropertyDescriptor: (_target: Secrets, prop: string | symbol): PropertyDescriptor | undefined => {\n const value = typeof prop === 'string' ? this.get(prop) : undefined;\n return value === undefined\n ? undefined\n : { value, enumerable: true, configurable: true, writable: false };\n },\n // The credentials belong to the system - scripts may read them, but never change them\n set: (): boolean => false,\n defineProperty: (): boolean => false,\n deleteProperty: (): boolean => false,\n });\n }\n\n /** Reads one credential from the cache and warns if the whole feature is switched off */\n private get(name: string): SecretValues | undefined {\n if (!this.enabled) {\n if (!this.disabledWarningShown) {\n this.disabledWarningShown = true;\n this.adapter.log.warn(\n `A script tried to read the secret \"${name}\", but the access to the credentials is disabled. Enable \"Allow scripts to read the credentials\" in the instance settings.`,\n );\n }\n return undefined;\n }\n return this.cache.get(name);\n }\n\n /**\n * Reads all credentials of the central store and decrypts them.\n *\n * @param enabled Value of the adapter option `enableSecrets`\n */\n async load(enabled: boolean): Promise<void> {\n this.cache.clear();\n this.disabledWarningShown = false;\n this.enabled = enabled;\n\n if (!enabled) {\n return;\n }\n\n if (!Credentials?.listCredentials) {\n this.adapter.log.warn(\n 'Cannot read the credentials for \"SECRETS\": the credentials API is only available with js-controller 7.2 or newer',\n );\n this.enabled = false;\n return;\n }\n\n try {\n const list = await Credentials.listCredentials(this.adapter);\n for (const entry of list) {\n await this.update(entry.id);\n }\n this.adapter.log.debug(`${this.cache.size} secret(s) available in the scripts as \"SECRETS\"`);\n } catch (e: unknown) {\n this.adapter.log.warn(`Cannot read the credentials: ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n\n /**\n * Reads one credential and decrypts it. Called for every change of a `system.credentials.*`\n * object, so edits in the admin UI are visible in the scripts immediately.\n *\n * @param id Object ID, e.g. `system.credentials.CameraPassword`\n */\n async update(id: string): Promise<void> {\n if (!this.enabled || !isSecretId(id)) {\n return;\n }\n const name = getSecretName(id);\n\n try {\n const credentials = await Credentials.getCredentials(this.adapter, id);\n this.cache.set(name, Object.freeze({ ...credentials.values }));\n } catch (e: unknown) {\n this.cache.delete(name);\n this.adapter.log.warn(`Cannot read the secret \"${name}\": ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n\n /**\n * Forgets one credential because its object was deleted.\n *\n * @param id Object ID, e.g. `system.credentials.CameraPassword`\n */\n remove(id: string): void {\n if (isSecretId(id) && this.cache.delete(getSecretName(id))) {\n this.adapter.log.debug(`Secret \"${getSecretName(id)}\" was deleted`);\n }\n }\n\n /**\n * The structure of the credential store without any secret value: which credentials exist and\n * which fields each of them has. Used by the instance settings and the Blockly editor to show\n * the user what `SECRETS.<name>.<field>` expressions are available.\n */\n getStructure(): SecretStructure[] {\n return Array.from(this.cache.entries())\n .map(([name, values]) => ({ name, fields: Object.keys(values).sort() }))\n .sort((a, b) => a.name.localeCompare(b.name));\n }\n\n /**\n * Builds the ambient TypeScript declarations for the credentials that currently exist, so the\n * editor can suggest their names after typing `SECRETS.` and their fields after the next dot.\n * The names are merged into the `iobJS.Secrets` interface, which has an index signature for\n * all other names.\n */\n getDeclarations(): string {\n const lines = [\n '// Generated by ioBroker.javascript from the central credential store - do not edit',\n 'declare namespace iobJS {',\n ' interface Secrets {',\n ];\n for (const { name, fields } of this.getStructure()) {\n const values = this.cache.get(name)!;\n // Declare the fields this credential really has, so the editor suggests exactly those\n const members = fields.map(field => `${JSON.stringify(field)}: ${typeof values[field]}`).join('; ');\n lines.push(` ${JSON.stringify(name)}: { ${members} };`);\n }\n lines.push(' }', '}', '');\n return lines.join('\\n');\n }\n\n /** Forgets all decrypted credentials */\n destroy(): void {\n this.cache.clear();\n this.enabled = false;\n }\n}\n"]}
|
|
@@ -1,11 +1,29 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.jsDeclarationCompilerOptions = exports.tsCompilerOptions = exports.targetTsLib = void 0;
|
|
3
|
+
exports.jsDeclarationCompilerOptions = exports.tsCompilerOptions = exports.TS_TARGETS = exports.targetTsLib = void 0;
|
|
4
|
+
exports.getTargetTsLib = getTargetTsLib;
|
|
5
|
+
exports.getTsCompilerOptions = getTsCompilerOptions;
|
|
4
6
|
const typescript_1 = require("typescript");
|
|
5
7
|
// Node.js 18+ supports the features of ES2022
|
|
6
8
|
// consider changing this, so we get to support the newest features too
|
|
7
9
|
exports.targetTsLib = 'es2022';
|
|
10
|
+
/** All targets that may be selected in the instance configuration */
|
|
11
|
+
exports.TS_TARGETS = {
|
|
12
|
+
es2018: typescript_1.ScriptTarget.ES2018,
|
|
13
|
+
es2019: typescript_1.ScriptTarget.ES2019,
|
|
14
|
+
es2020: typescript_1.ScriptTarget.ES2020,
|
|
15
|
+
es2021: typescript_1.ScriptTarget.ES2021,
|
|
16
|
+
es2022: typescript_1.ScriptTarget.ES2022,
|
|
17
|
+
es2023: typescript_1.ScriptTarget.ES2023,
|
|
18
|
+
es2024: typescript_1.ScriptTarget.ES2024,
|
|
19
|
+
es2025: typescript_1.ScriptTarget.ES2025,
|
|
20
|
+
esnext: typescript_1.ScriptTarget.ESNext,
|
|
21
|
+
};
|
|
8
22
|
exports.tsCompilerOptions = {
|
|
23
|
+
// TypeScript 6 enables `strict` by default. That would break virtually every existing user
|
|
24
|
+
// script (implicit any parameters, strict null checks), so keep the pre-TS6 behavior.
|
|
25
|
+
// Can be re-enabled per instance in the "TypeScript" tab of the adapter settings.
|
|
26
|
+
strict: false,
|
|
9
27
|
// don't compile faulty scripts
|
|
10
28
|
noEmitOnError: true,
|
|
11
29
|
// emit declarations for global scripts
|
|
@@ -22,7 +40,7 @@ exports.tsCompilerOptions = {
|
|
|
22
40
|
// Node.js 18+ runs ES2022 natively, so nothing has to be downleveled. This also makes
|
|
23
41
|
// `downlevelIteration` obsolete - QueryResults stays iterable without it
|
|
24
42
|
// (https://github.com/ioBroker/ioBroker.javascript/pull/663#issuecomment-721645705).
|
|
25
|
-
target:
|
|
43
|
+
target: exports.TS_TARGETS[exports.targetTsLib],
|
|
26
44
|
// From ES2022 on, TypeScript would emit class fields as native declarations ([[Define]]
|
|
27
45
|
// semantics). Keep the previous assignment semantics (`this.x = ...` in the constructor),
|
|
28
46
|
// so existing user scripts behave unchanged.
|
|
@@ -42,4 +60,96 @@ exports.jsDeclarationCompilerOptions = {
|
|
|
42
60
|
noImplicitAny: false,
|
|
43
61
|
strict: false,
|
|
44
62
|
};
|
|
63
|
+
/**
|
|
64
|
+
* Applies a checkbox option from the instance configuration.
|
|
65
|
+
* An option that is missing (configuration of an older version) keeps the value the adapter ships with.
|
|
66
|
+
*
|
|
67
|
+
* @param options The compiler options to modify
|
|
68
|
+
* @param name Name of the compiler option
|
|
69
|
+
* @param value Value from the instance configuration
|
|
70
|
+
*/
|
|
71
|
+
function applyBoolean(options, name, value) {
|
|
72
|
+
if (value === undefined || value === null) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
options[name] = !!value;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Applies a tri-state option from the instance configuration.
|
|
79
|
+
* An empty selection removes the option, so it follows `strict` (resp. the TypeScript default).
|
|
80
|
+
* An option that is missing (configuration of an older version) keeps the value the adapter ships with.
|
|
81
|
+
*
|
|
82
|
+
* @param options The compiler options to modify
|
|
83
|
+
* @param name Name of the compiler option
|
|
84
|
+
* @param value Value from the instance configuration
|
|
85
|
+
*/
|
|
86
|
+
function applyTriState(options, name, value) {
|
|
87
|
+
if (value === undefined || value === null) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (value === '') {
|
|
91
|
+
delete options[name];
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
options[name] = value === 'true';
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Determines the ECMAScript version the user scripts are compiled for
|
|
98
|
+
*
|
|
99
|
+
* @param config The instance configuration
|
|
100
|
+
*/
|
|
101
|
+
function getTargetTsLib(config) {
|
|
102
|
+
const target = config?.tsTarget?.toLowerCase();
|
|
103
|
+
return target && exports.TS_TARGETS[target] !== undefined ? target : exports.targetTsLib;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Builds the compiler options for the user scripts out of the instance configuration.
|
|
107
|
+
* Everything that is not configured stays at the value the adapter ships with.
|
|
108
|
+
*
|
|
109
|
+
* @param config The instance configuration
|
|
110
|
+
*/
|
|
111
|
+
function getTsCompilerOptions(config) {
|
|
112
|
+
const tsLib = getTargetTsLib(config);
|
|
113
|
+
const options = {
|
|
114
|
+
...exports.tsCompilerOptions,
|
|
115
|
+
target: exports.TS_TARGETS[tsLib],
|
|
116
|
+
lib: [`lib.${tsLib}.d.ts`],
|
|
117
|
+
};
|
|
118
|
+
if (!config) {
|
|
119
|
+
return options;
|
|
120
|
+
}
|
|
121
|
+
// Strict type checking
|
|
122
|
+
applyBoolean(options, 'strict', config.tsStrict);
|
|
123
|
+
applyTriState(options, 'noImplicitAny', config.tsNoImplicitAny);
|
|
124
|
+
applyTriState(options, 'strictNullChecks', config.tsStrictNullChecks);
|
|
125
|
+
applyTriState(options, 'strictFunctionTypes', config.tsStrictFunctionTypes);
|
|
126
|
+
applyTriState(options, 'strictBindCallApply', config.tsStrictBindCallApply);
|
|
127
|
+
applyTriState(options, 'strictPropertyInitialization', config.tsStrictPropertyInitialization);
|
|
128
|
+
applyTriState(options, 'strictBuiltinIteratorReturn', config.tsStrictBuiltinIteratorReturn);
|
|
129
|
+
applyTriState(options, 'noImplicitThis', config.tsNoImplicitThis);
|
|
130
|
+
applyTriState(options, 'alwaysStrict', config.tsAlwaysStrict);
|
|
131
|
+
applyTriState(options, 'useUnknownInCatchVariables', config.tsUseUnknownInCatchVariables);
|
|
132
|
+
// Additional checks
|
|
133
|
+
applyBoolean(options, 'noUnusedLocals', config.tsNoUnusedLocals);
|
|
134
|
+
applyBoolean(options, 'noUnusedParameters', config.tsNoUnusedParameters);
|
|
135
|
+
applyBoolean(options, 'noImplicitReturns', config.tsNoImplicitReturns);
|
|
136
|
+
applyBoolean(options, 'noFallthroughCasesInSwitch', config.tsNoFallthroughCasesInSwitch);
|
|
137
|
+
applyBoolean(options, 'noImplicitOverride', config.tsNoImplicitOverride);
|
|
138
|
+
applyBoolean(options, 'noUncheckedIndexedAccess', config.tsNoUncheckedIndexedAccess);
|
|
139
|
+
applyBoolean(options, 'noPropertyAccessFromIndexSignature', config.tsNoPropertyAccessFromIndexSignature);
|
|
140
|
+
applyBoolean(options, 'exactOptionalPropertyTypes', config.tsExactOptionalPropertyTypes);
|
|
141
|
+
applyTriState(options, 'allowUnreachableCode', config.tsAllowUnreachableCode);
|
|
142
|
+
applyTriState(options, 'allowUnusedLabels', config.tsAllowUnusedLabels);
|
|
143
|
+
// Language and emit
|
|
144
|
+
applyBoolean(options, 'noEmitOnError', config.tsNoEmitOnError);
|
|
145
|
+
applyBoolean(options, 'esModuleInterop', config.tsEsModuleInterop);
|
|
146
|
+
applyBoolean(options, 'allowSyntheticDefaultImports', config.tsAllowSyntheticDefaultImports);
|
|
147
|
+
applyBoolean(options, 'useDefineForClassFields', config.tsUseDefineForClassFields);
|
|
148
|
+
applyBoolean(options, 'downlevelIteration', config.tsDownlevelIteration);
|
|
149
|
+
applyBoolean(options, 'experimentalDecorators', config.tsExperimentalDecorators);
|
|
150
|
+
applyBoolean(options, 'emitDecoratorMetadata', config.tsEmitDecoratorMetadata);
|
|
151
|
+
applyBoolean(options, 'removeComments', config.tsRemoveComments);
|
|
152
|
+
applyBoolean(options, 'skipLibCheck', config.tsSkipLibCheck);
|
|
153
|
+
return options;
|
|
154
|
+
}
|
|
45
155
|
//# sourceMappingURL=typescriptSettings.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typescriptSettings.js","sourceRoot":"","sources":["../../src/lib/typescriptSettings.ts"],"names":[],"mappings":";;;AAAA,2CAA4E;AAE5E,8CAA8C;AAC9C,uEAAuE;AAC1D,QAAA,WAAW,GAAG,QAAQ,CAAC;AAEvB,QAAA,iBAAiB,GAAoB;IAC9C,+BAA+B;IAC/B,aAAa,EAAE,IAAI;IACnB,uCAAuC;IACvC,WAAW,EAAE,IAAI;IACjB,wEAAwE;IACxE,eAAe,EAAE,IAAI;IACrB,2EAA2E;IAC3E,4BAA4B;IAC5B,0BAA0B,EAAE,KAAK;IACjC,8FAA8F;IAC9F,gGAAgG;IAChG,+FAA+F;IAC/F,MAAM,EAAE,uBAAU,CAAC,QAAQ;IAC3B,sFAAsF;IACtF,yEAAyE;IACzE,qFAAqF;IACrF,MAAM,EAAE,yBAAY,CAAC,MAAM;IAC3B,wFAAwF;IACxF,0FAA0F;IAC1F,6CAA6C;IAC7C,uBAAuB,EAAE,KAAK;IAC9B,6FAA6F;IAC7F,6FAA6F;IAC7F,gCAAgC;IAChC,kBAAkB,EAAE,KAAK;IACzB,GAAG,EAAE,CAAC,OAAO,mBAAW,OAAO,CAAC;CACnC,CAAC;AAEW,QAAA,4BAA4B,GAAoB;IACzD,GAAG,yBAAiB;IACpB,sCAAsC;IACtC,mBAAmB,EAAE,IAAI;IACzB,eAAe;IACf,aAAa,EAAE,KAAK;IACpB,aAAa,EAAE,KAAK;IACpB,MAAM,EAAE,KAAK;CAChB,CAAC","sourcesContent":["import { type CompilerOptions, ModuleKind, ScriptTarget } from 'typescript';\n\n// Node.js 18+ supports the features of ES2022\n// consider changing this, so we get to support the newest features too\nexport const targetTsLib = 'es2022';\n\nexport const tsCompilerOptions: CompilerOptions = {\n // don't compile faulty scripts\n noEmitOnError: true,\n // emit declarations for global scripts\n declaration: true,\n // This enables TS users to `import * as ... from` and `import ... from`\n esModuleInterop: true,\n // This flag was introduced in TS 4.4 and may break a lot of legacy scripts\n // Better keep it turned off\n useUnknownInCatchVariables: false,\n // Scripts are executed as a Node.js `vm.Script`, which does not support the `import` keyword,\n // so the emitted code must be CommonJS. This has to be set explicitly: TypeScript only defaults\n // `module` to CommonJS for the ES5/ES3 targets and would emit ES modules for the target below.\n module: ModuleKind.CommonJS,\n // Node.js 18+ runs ES2022 natively, so nothing has to be downleveled. This also makes\n // `downlevelIteration` obsolete - QueryResults stays iterable without it\n // (https://github.com/ioBroker/ioBroker.javascript/pull/663#issuecomment-721645705).\n target: ScriptTarget.ES2022,\n // From ES2022 on, TypeScript would emit class fields as native declarations ([[Define]]\n // semantics). Keep the previous assignment semantics (`this.x = ...` in the constructor),\n // so existing user scripts behave unchanged.\n useDefineForClassFields: false,\n // `virtual-tsc` overwrites `moduleResolution` with \"node10\", which TypeScript 6 reports as a\n // deprecation error. It cannot be configured from here, so deprecations have to be tolerated\n // until that is fixed upstream.\n ignoreDeprecations: '6.0',\n lib: [`lib.${targetTsLib}.d.ts`],\n};\n\nexport const jsDeclarationCompilerOptions: CompilerOptions = {\n ...tsCompilerOptions,\n // we only care about the declarations\n emitDeclarationOnly: true,\n // allow errors\n noEmitOnError: false,\n noImplicitAny: false,\n strict: false,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"typescriptSettings.js","sourceRoot":"","sources":["../../src/lib/typescriptSettings.ts"],"names":[],"mappings":"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","sourcesContent":["import { type CompilerOptions, ModuleKind, ScriptTarget } from 'typescript';\nimport type { JavaScriptAdapterConfig, TsTarget, TsTriState } from '../types';\n\n// Node.js 18+ supports the features of ES2022\n// consider changing this, so we get to support the newest features too\nexport const targetTsLib: TsTarget = 'es2022';\n\n/** All targets that may be selected in the instance configuration */\nexport const TS_TARGETS: Record<TsTarget, ScriptTarget> = {\n es2018: ScriptTarget.ES2018,\n es2019: ScriptTarget.ES2019,\n es2020: ScriptTarget.ES2020,\n es2021: ScriptTarget.ES2021,\n es2022: ScriptTarget.ES2022,\n es2023: ScriptTarget.ES2023,\n es2024: ScriptTarget.ES2024,\n es2025: ScriptTarget.ES2025,\n esnext: ScriptTarget.ESNext,\n};\n\nexport const tsCompilerOptions: CompilerOptions = {\n // TypeScript 6 enables `strict` by default. That would break virtually every existing user\n // script (implicit any parameters, strict null checks), so keep the pre-TS6 behavior.\n // Can be re-enabled per instance in the \"TypeScript\" tab of the adapter settings.\n strict: false,\n // don't compile faulty scripts\n noEmitOnError: true,\n // emit declarations for global scripts\n declaration: true,\n // This enables TS users to `import * as ... from` and `import ... from`\n esModuleInterop: true,\n // This flag was introduced in TS 4.4 and may break a lot of legacy scripts\n // Better keep it turned off\n useUnknownInCatchVariables: false,\n // Scripts are executed as a Node.js `vm.Script`, which does not support the `import` keyword,\n // so the emitted code must be CommonJS. This has to be set explicitly: TypeScript only defaults\n // `module` to CommonJS for the ES5/ES3 targets and would emit ES modules for the target below.\n module: ModuleKind.CommonJS,\n // Node.js 18+ runs ES2022 natively, so nothing has to be downleveled. This also makes\n // `downlevelIteration` obsolete - QueryResults stays iterable without it\n // (https://github.com/ioBroker/ioBroker.javascript/pull/663#issuecomment-721645705).\n target: TS_TARGETS[targetTsLib],\n // From ES2022 on, TypeScript would emit class fields as native declarations ([[Define]]\n // semantics). Keep the previous assignment semantics (`this.x = ...` in the constructor),\n // so existing user scripts behave unchanged.\n useDefineForClassFields: false,\n // `virtual-tsc` overwrites `moduleResolution` with \"node10\", which TypeScript 6 reports as a\n // deprecation error. It cannot be configured from here, so deprecations have to be tolerated\n // until that is fixed upstream.\n ignoreDeprecations: '6.0',\n lib: [`lib.${targetTsLib}.d.ts`],\n};\n\nexport const jsDeclarationCompilerOptions: CompilerOptions = {\n ...tsCompilerOptions,\n // we only care about the declarations\n emitDeclarationOnly: true,\n // allow errors\n noEmitOnError: false,\n noImplicitAny: false,\n strict: false,\n};\n\n/**\n * Applies a checkbox option from the instance configuration.\n * An option that is missing (configuration of an older version) keeps the value the adapter ships with.\n *\n * @param options The compiler options to modify\n * @param name Name of the compiler option\n * @param value Value from the instance configuration\n */\nfunction applyBoolean(options: CompilerOptions, name: keyof CompilerOptions, value: boolean | undefined): void {\n if (value === undefined || value === null) {\n return;\n }\n (options as Record<string, unknown>)[name] = !!value;\n}\n\n/**\n * Applies a tri-state option from the instance configuration.\n * An empty selection removes the option, so it follows `strict` (resp. the TypeScript default).\n * An option that is missing (configuration of an older version) keeps the value the adapter ships with.\n *\n * @param options The compiler options to modify\n * @param name Name of the compiler option\n * @param value Value from the instance configuration\n */\nfunction applyTriState(options: CompilerOptions, name: keyof CompilerOptions, value: TsTriState | undefined): void {\n if (value === undefined || value === null) {\n return;\n }\n if (value === '') {\n delete (options as Record<string, unknown>)[name];\n return;\n }\n (options as Record<string, unknown>)[name] = value === 'true';\n}\n\n/**\n * Determines the ECMAScript version the user scripts are compiled for\n *\n * @param config The instance configuration\n */\nexport function getTargetTsLib(config?: Partial<JavaScriptAdapterConfig>): TsTarget {\n const target = config?.tsTarget?.toLowerCase() as TsTarget;\n\n return target && TS_TARGETS[target] !== undefined ? target : targetTsLib;\n}\n\n/**\n * Builds the compiler options for the user scripts out of the instance configuration.\n * Everything that is not configured stays at the value the adapter ships with.\n *\n * @param config The instance configuration\n */\nexport function getTsCompilerOptions(config?: Partial<JavaScriptAdapterConfig>): CompilerOptions {\n const tsLib = getTargetTsLib(config);\n const options: CompilerOptions = {\n ...tsCompilerOptions,\n target: TS_TARGETS[tsLib],\n lib: [`lib.${tsLib}.d.ts`],\n };\n\n if (!config) {\n return options;\n }\n\n // Strict type checking\n applyBoolean(options, 'strict', config.tsStrict);\n applyTriState(options, 'noImplicitAny', config.tsNoImplicitAny);\n applyTriState(options, 'strictNullChecks', config.tsStrictNullChecks);\n applyTriState(options, 'strictFunctionTypes', config.tsStrictFunctionTypes);\n applyTriState(options, 'strictBindCallApply', config.tsStrictBindCallApply);\n applyTriState(options, 'strictPropertyInitialization', config.tsStrictPropertyInitialization);\n applyTriState(options, 'strictBuiltinIteratorReturn', config.tsStrictBuiltinIteratorReturn);\n applyTriState(options, 'noImplicitThis', config.tsNoImplicitThis);\n applyTriState(options, 'alwaysStrict', config.tsAlwaysStrict);\n applyTriState(options, 'useUnknownInCatchVariables', config.tsUseUnknownInCatchVariables);\n\n // Additional checks\n applyBoolean(options, 'noUnusedLocals', config.tsNoUnusedLocals);\n applyBoolean(options, 'noUnusedParameters', config.tsNoUnusedParameters);\n applyBoolean(options, 'noImplicitReturns', config.tsNoImplicitReturns);\n applyBoolean(options, 'noFallthroughCasesInSwitch', config.tsNoFallthroughCasesInSwitch);\n applyBoolean(options, 'noImplicitOverride', config.tsNoImplicitOverride);\n applyBoolean(options, 'noUncheckedIndexedAccess', config.tsNoUncheckedIndexedAccess);\n applyBoolean(options, 'noPropertyAccessFromIndexSignature', config.tsNoPropertyAccessFromIndexSignature);\n applyBoolean(options, 'exactOptionalPropertyTypes', config.tsExactOptionalPropertyTypes);\n applyTriState(options, 'allowUnreachableCode', config.tsAllowUnreachableCode);\n applyTriState(options, 'allowUnusedLabels', config.tsAllowUnusedLabels);\n\n // Language and emit\n applyBoolean(options, 'noEmitOnError', config.tsNoEmitOnError);\n applyBoolean(options, 'esModuleInterop', config.tsEsModuleInterop);\n applyBoolean(options, 'allowSyntheticDefaultImports', config.tsAllowSyntheticDefaultImports);\n applyBoolean(options, 'useDefineForClassFields', config.tsUseDefineForClassFields);\n applyBoolean(options, 'downlevelIteration', config.tsDownlevelIteration);\n applyBoolean(options, 'experimentalDecorators', config.tsExperimentalDecorators);\n applyBoolean(options, 'emitDecoratorMetadata', config.tsEmitDecoratorMetadata);\n applyBoolean(options, 'removeComments', config.tsRemoveComments);\n applyBoolean(options, 'skipLibCheck', config.tsSkipLibCheck);\n\n return options;\n}\n"]}
|