iobroker.javascript 10.0.0 → 10.1.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.
Files changed (157) hide show
  1. package/README.md +41 -6
  2. package/admin/assets/AiChatPanel-C4kuqP2U.js +237 -0
  3. package/admin/assets/AiDiffView-zJTEnv05.js +1 -0
  4. package/admin/assets/BlocklyEditor-BB77aFJI.js +84 -0
  5. package/admin/assets/ContextWrapper-C2yvd2Tn.css +1 -0
  6. package/admin/assets/ContextWrapper-W2H0z6zD.js +136 -0
  7. package/admin/assets/Debugger-DCMWjeGm.js +15 -0
  8. package/admin/assets/Error-CBC2oZzb.js +1 -0
  9. package/admin/assets/Import-B-F9IhZ-.js +1 -0
  10. package/admin/assets/RulesEditor-ByjgEaVo.js +1 -0
  11. package/admin/assets/RulesEditor-k-DMHotH.css +1 -0
  12. package/admin/assets/{ScriptEditor-BGIuoNei.js → ScriptEditor-CMYUt5S4.js} +2 -2
  13. package/admin/assets/{ScriptEditorVanillaMonaco-DyMQtoTQ.js → ScriptEditorVanillaMonaco-v12-gORS.js} +3 -3
  14. package/admin/assets/Send-CChqR5Oy.js +1 -0
  15. package/admin/assets/_virtual_mf-localSharedImportMap___mfe_internal__iobroker_javascript__mf_owner__1-7EPUlgCk.js +1 -0
  16. package/admin/assets/_virtual_mf___mfe_internal__iobroker_javascript__mf_owner__1__loadShare___mf_0_iobroker_mf_1_gui_mf_2_components__loadShare__.js-DuplUOZN.js +1243 -0
  17. package/admin/assets/{_virtual_mf___mfe_internal__iobroker_javascript__mf_owner__1__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-BBAXJaqI.js → _virtual_mf___mfe_internal__iobroker_javascript__mf_owner__1__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-JkwfVf8d.js} +1 -1
  18. package/admin/assets/{aiCodeLensProvider-hyAmut0e.js → aiCodeLensProvider-BGvIu6hH.js} +1 -1
  19. package/admin/assets/blockly-C4zJerWL.js +1047 -0
  20. package/admin/assets/blocks_action-CvnOHXwt.js +1 -0
  21. package/admin/assets/blocks_convert-BZlKcd02.js +3 -0
  22. package/admin/assets/blocks_logic-B33Pypxr.js +1 -0
  23. package/admin/assets/blocks_number-k2IjE7OH.js +1 -0
  24. package/admin/assets/blocks_object-B64vSfel.js +1 -0
  25. package/admin/assets/blocks_procedures-BpvNI5dO.js +3 -0
  26. package/admin/assets/blocks_sendto-pwZchfe0.js +5 -0
  27. package/admin/assets/blocks_switch-DViYCmQd.js +2 -0
  28. package/admin/assets/blocks_system-BZZcGqTJ.js +1 -0
  29. package/admin/assets/blocks_text-BOvtHN2r.js +1 -0
  30. package/admin/assets/blocks_time-BH2F-ylT.js +1 -0
  31. package/admin/assets/blocks_timeout-C3BoW4XJ.js +1 -0
  32. package/admin/assets/blocks_trigger-gwXvuAHV.js +2 -0
  33. package/admin/assets/blocks_words-D8PL_nSE.js +1 -0
  34. package/admin/assets/{cronHoverProvider-pKJkSevo.js → cronHoverProvider-DjY3jLvQ.js} +1 -1
  35. package/admin/assets/dist-D6o4h8Pd.js +4 -0
  36. package/admin/assets/field_cron-BMQWPb61.js +1 -0
  37. package/admin/assets/field_oid-BGIMv9gw.js +1 -0
  38. package/admin/assets/field_script-CdzYBCe6.js +1 -0
  39. package/admin/assets/helpers-Crmcgphg.js +1 -0
  40. package/admin/assets/hostInit-DBlZi_Kt.js +1 -0
  41. package/admin/assets/index-BvPVHv3P.js +192 -0
  42. package/admin/assets/{inlineChatWidget-ZaisTOLh.js → inlineChatWidget-SDoyVtOR.js} +2 -2
  43. package/admin/assets/{inlineDiffController-hTwHHqcc.js → inlineDiffController-CnHE3Rwd.js} +2 -2
  44. package/admin/assets/javascript-DVIhlTDr.js +218 -0
  45. package/admin/assets/{mf-entry-bootstrap-0-d6052b31.js → mf-entry-bootstrap-0-a03ecebd.js} +6 -2
  46. package/admin/assets/{mjs-DWqivHEk.js → mjs-Bh7xFIpd.js} +2 -2
  47. package/admin/assets/{stateHoverProvider-C7DawIs-.js → stateHoverProvider-D0iXo6YF.js} +3 -3
  48. package/admin/assets/{virtualExposes-Ed0lGq7k.js → virtualExposes-DgGB-18P.js} +1 -1
  49. package/admin/assets/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__iobroker_javascript__remoteEntry_js-DYEYnOkt.js +1 -0
  50. package/admin/assets/virtual_mf-exposes___mfe_internal__iobroker_javascript__remoteEntry_js-ChiJXsfH.js +1 -0
  51. package/admin/custom/assets/Components-CuFt9lAY.js +1 -0
  52. package/admin/custom/assets/_virtual_mf-localSharedImportMap___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1-DljJyQQg.js +1 -0
  53. package/admin/custom/assets/_virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-D0M1SjIE.js +1 -0
  54. 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-BD2OkSge.js} +1 -1
  55. 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-pM642JFd.js} +91 -91
  56. 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 → _virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__.js-BLelmJ7Y.js} +74 -74
  57. package/admin/custom/assets/{_virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-BotqDuw-.js → _virtual_mf___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1__loadShare__react_mf_2_dom_mf_1_client__loadShare__.js-BGiB1l5e.js} +1 -1
  58. 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__-D5hqXJXI.js} +1 -1
  59. package/admin/custom/assets/hostInit-0DGPuZTB.js +1 -0
  60. package/admin/custom/assets/{index-uEKAoVT7.js → index-DcFI5r-g.js} +1 -1
  61. package/admin/custom/assets/{lib-Yj8cfN0A.js → lib-BlUjuGH7.js} +1 -1
  62. package/admin/custom/assets/{mf-entry-bootstrap-0-77793feb.js → mf-entry-bootstrap-0-efd847a6.js} +6 -2
  63. package/admin/custom/assets/{setYear-DJ9FbdkO.js → setYear-BaCcPbbI.js} +1 -1
  64. package/admin/custom/assets/virtualExposes-DGxNcyb6.js +1 -0
  65. package/admin/custom/assets/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__ConfigCustomJavascriptSet__customComponents_js-DVNwFcUr.js +1 -0
  66. package/admin/custom/assets/virtual_mf-exposes___mfe_internal__ConfigCustomJavascriptSet__customComponents_js-DPck7zEs.js +2 -0
  67. package/admin/custom/customComponents.js +1 -1
  68. package/admin/google-blockly/VERSION +1 -0
  69. package/admin/google-blockly/media/drop.mp3 +0 -0
  70. package/admin/google-blockly/msg/js/de.js +332 -56
  71. package/admin/google-blockly/msg/js/en.js +319 -43
  72. package/admin/google-blockly/msg/js/es.js +319 -42
  73. package/admin/google-blockly/msg/js/fr.js +315 -39
  74. package/admin/google-blockly/msg/js/it.js +327 -51
  75. package/admin/google-blockly/msg/js/nl.js +376 -100
  76. package/admin/google-blockly/msg/js/pl.js +318 -42
  77. package/admin/google-blockly/msg/js/pt.js +318 -42
  78. package/admin/google-blockly/msg/js/ru.js +320 -44
  79. package/admin/google-blockly/msg/js/uk.js +326 -50
  80. package/admin/google-blockly/msg/js/zh-cn.js +322 -46
  81. package/admin/i18n/de.json +48 -26
  82. package/admin/i18n/en.json +47 -25
  83. package/admin/i18n/es.json +48 -18
  84. package/admin/i18n/fr.json +47 -17
  85. package/admin/i18n/it.json +47 -17
  86. package/admin/i18n/nl.json +47 -17
  87. package/admin/i18n/pl.json +48 -18
  88. package/admin/i18n/pt.json +47 -17
  89. package/admin/i18n/ru.json +47 -17
  90. package/admin/i18n/uk.json +47 -17
  91. package/admin/i18n/zh-cn.json +47 -17
  92. package/admin/jsonConfig.json +367 -0
  93. package/admin/mf-manifest.json +1 -1
  94. package/admin/mf-stats.json +1 -1
  95. package/admin/remoteEntry.js +1 -1
  96. package/admin/tab.html +12 -95
  97. package/build/lib/mirror.js +9 -0
  98. package/build/lib/mirror.js.map +1 -1
  99. package/build/lib/sandbox.js +35 -0
  100. package/build/lib/sandbox.js.map +1 -1
  101. package/build/lib/typescriptSettings.js +112 -2
  102. package/build/lib/typescriptSettings.js.map +1 -1
  103. package/build/lib/typescriptTools.js +168 -43
  104. package/build/lib/typescriptTools.js.map +1 -1
  105. package/build/main.js +10 -5
  106. package/build/main.js.map +1 -1
  107. package/build/types.d.ts +41 -0
  108. package/docs/en/javascript.md +16 -0
  109. package/docs/en/upgrade-guide.md +3 -0
  110. package/io-package.json +45 -15
  111. package/package.json +8 -3
  112. package/admin/assets/AiChatPanel-p0KAg6Cs.js +0 -237
  113. package/admin/assets/AiDiffView-BPTLnNx1.js +0 -1
  114. package/admin/assets/BlocklyEditor-CAjVMhYT.js +0 -81
  115. package/admin/assets/ContextWrapper-BVc8wTK_.css +0 -1
  116. package/admin/assets/ContextWrapper-D9CrnNKs.js +0 -127
  117. package/admin/assets/Debugger-SjROokFI.js +0 -15
  118. package/admin/assets/Error-DDfrxAt2.js +0 -1
  119. package/admin/assets/Import-DpTg1Jow.js +0 -1
  120. package/admin/assets/RulesEditor-BSRFWpEm.css +0 -1
  121. package/admin/assets/RulesEditor-D0hgrcBc.js +0 -1
  122. package/admin/assets/_virtual_mf-localSharedImportMap___mfe_internal__iobroker_javascript__mf_owner__1-DWJotR1B.js +0 -1
  123. 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
  124. package/admin/assets/dist-uw5orDgd.js +0 -4
  125. package/admin/assets/hostInit-BFg5u9hY.js +0 -1
  126. package/admin/assets/index-B1gICjdq.js +0 -192
  127. package/admin/assets/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__iobroker_javascript__remoteEntry_js-BYs71IQF.js +0 -1
  128. package/admin/assets/virtual_mf-exposes___mfe_internal__iobroker_javascript__remoteEntry_js-DnnXQRkG.js +0 -1
  129. package/admin/custom/assets/Components-BrDyDHXh.js +0 -1
  130. package/admin/custom/assets/_virtual_mf-localSharedImportMap___mfe_internal__ConfigCustomJavascriptSet__mf_owner__1-CyYJM2-v.js +0 -1
  131. 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
  132. package/admin/custom/assets/hostInit-DJx2uXXy.js +0 -1
  133. package/admin/custom/assets/virtualExposes-CxDjLoYu.js +0 -1
  134. package/admin/custom/assets/virtual_mf-REMOTE_ENTRY_ID___mfe_internal__ConfigCustomJavascriptSet__customComponents_js-BU-ugy_7.js +0 -1
  135. package/admin/custom/assets/virtual_mf-exposes-ssr___mfe_internal__ConfigCustomJavascriptSet__customComponents_js-BEfZbrf7.js +0 -2
  136. package/admin/custom/assets/virtual_mf-exposes___mfe_internal__ConfigCustomJavascriptSet__customComponents_js-CTeZ0Jpm.js +0 -2
  137. package/admin/google-blockly/blockly_compressed.js +0 -1679
  138. package/admin/google-blockly/blocks_compressed.js +0 -193
  139. package/admin/google-blockly/javascript_compressed.js +0 -264
  140. package/admin/google-blockly/msg/messages.js +0 -1630
  141. package/admin/google-blockly/own/blocks_action.js +0 -765
  142. package/admin/google-blockly/own/blocks_convert.js +0 -480
  143. package/admin/google-blockly/own/blocks_logic.js +0 -459
  144. package/admin/google-blockly/own/blocks_number.js +0 -30
  145. package/admin/google-blockly/own/blocks_object.js +0 -402
  146. package/admin/google-blockly/own/blocks_procedures.js +0 -688
  147. package/admin/google-blockly/own/blocks_sendto.js +0 -702
  148. package/admin/google-blockly/own/blocks_switch.js +0 -257
  149. package/admin/google-blockly/own/blocks_system.js +0 -1409
  150. package/admin/google-blockly/own/blocks_text.js +0 -104
  151. package/admin/google-blockly/own/blocks_time.js +0 -639
  152. package/admin/google-blockly/own/blocks_timeout.js +0 -551
  153. package/admin/google-blockly/own/blocks_trigger.js +0 -1791
  154. package/admin/google-blockly/own/blocks_words.js +0 -708
  155. package/admin/google-blockly/own/field_cron.js +0 -158
  156. package/admin/google-blockly/own/field_oid.js +0 -642
  157. package/admin/google-blockly/own/field_script.js +0 -159
@@ -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: typescript_1.ScriptTarget.ES2022,
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"]}
@@ -9,6 +9,12 @@ const node_fs_1 = require("node:fs");
9
9
  const node_path_1 = require("node:path");
10
10
  const typescript_1 = require("typescript");
11
11
  const tools_1 = require("./tools");
12
+ /**
13
+ * The transformed sources are stored in the ioBroker database and mirrored to disk, so they must
14
+ * not depend on the platform or on a TypeScript default. TypeScript 5 printed CRLF here and
15
+ * TypeScript 6 prints LF - pinning it keeps a compiler update from silently rewriting every script.
16
+ */
17
+ const PRINTER_OPTIONS = { newLine: typescript_1.NewLineKind.LineFeed };
12
18
  /**
13
19
  * Resolves all TypeScript lib files for the editor
14
20
  *
@@ -49,41 +55,117 @@ function normalizeDTSImport(filename) {
49
55
  return (0, node_path_1.join)(filename, 'index.d.ts');
50
56
  }
51
57
  /**
52
- * Resolves the type declarations of a 3rd party package for the editor
58
+ * Wraps a package's root declarations in `declare module "<pkg>"` if - and only if - they are not a
59
+ * module themselves.
60
+ *
61
+ * This used to be applied to every package. That broke all of them that ship real typings: inside an
62
+ * ambient module declaration TypeScript does not resolve the relative paths a barrel file re-exports
63
+ * from, so every name the package exported became `any` - which is why type inference never worked
64
+ * for e.g. rxjs (https://github.com/ioBroker/ioBroker.javascript/issues/2341). Such a file is now
65
+ * left alone and found through ordinary module resolution.
66
+ *
67
+ * A declaration file without any top-level `import`/`export` is a script, not a module, and
68
+ * `import ... from "<pkg>"` would not accept it. Those still need the wrapper - and having no
69
+ * imports, they cannot suffer from the problem above.
70
+ *
71
+ * A file that only points at other files (`@types/node` is nothing but `/// <reference path>` lines)
72
+ * is left alone as well: the wrapper would cut those references off from the global scope they are
73
+ * meant to populate.
74
+ *
75
+ * @param pkg The package the declarations belong to
76
+ * @param content The content of the root declaration file
77
+ */
78
+ function wrapRootTypingsIfNeeded(pkg, content) {
79
+ const isModule = /^\s*(?:import|export)\b/m.test(content);
80
+ const isAmbientDeclaration = /^\s*declare module/m.test(content);
81
+ const referencesOtherFiles = /\/\/\/\s*<reference path=/.test(content);
82
+ return isModule || isAmbientDeclaration || referencesOtherFiles
83
+ ? content
84
+ : `declare module "${pkg}" { ${content} }`;
85
+ }
86
+ /**
87
+ * Finds the package.json of a package on disk.
88
+ *
89
+ * `require.resolve("<pkg>/package.json")` goes through Node's module resolution, and a package with
90
+ * an `exports` map that does not list `./package.json` makes that throw - which is common enough
91
+ * among modern packages to matter. The directories Node would have searched are then looked at
92
+ * directly, which no `exports` map can hide.
93
+ *
94
+ * @param pkg The package to look for
95
+ */
96
+ function findPackageJson(pkg) {
97
+ try {
98
+ return require.resolve(`${pkg}/package.json`);
99
+ }
100
+ catch {
101
+ // the package may be there but refuse to hand out its manifest
102
+ }
103
+ return (require.resolve.paths(pkg) || [])
104
+ .map(dir => (0, node_path_1.join)(dir, pkg, 'package.json'))
105
+ .find(candidate => (0, node_fs_1.existsSync)(candidate));
106
+ }
107
+ /**
108
+ * Finds the declaration entry point of a package.
109
+ *
110
+ * A package that ships an `exports` map often keeps the legacy `types` field only as a stub - rxjs 7
111
+ * declares `"types": "index.d.ts"` although no such file exists and the real declarations sit in
112
+ * `./dist/types/`. A candidate therefore only counts if the file is really there
113
+ * (https://github.com/ioBroker/ioBroker.javascript/issues/928).
114
+ *
115
+ * @param packageJson The parsed package.json
116
+ * @param packageRoot The directory that package.json lives in
117
+ */
118
+ function findRootTypings(packageJson, packageRoot) {
119
+ const mainExport = packageJson.exports?.['.'];
120
+ const fromExports = mainExport && typeof mainExport === 'object'
121
+ ? (mainExport.types ??
122
+ mainExport.require?.types ??
123
+ mainExport.import?.types ??
124
+ mainExport.default?.types)
125
+ : undefined;
126
+ // the legacy fields come first: they are what a package without an `exports` map has, and where
127
+ // both exist they agree
128
+ return [packageJson.types, packageJson.typings, fromExports].find(candidate => typeof candidate === 'string' && (0, node_fs_1.existsSync)(normalizeDTSImport((0, node_path_1.join)(packageRoot, candidate))));
129
+ }
130
+ /**
131
+ * Resolves the type declarations of a 3rd party package for the editor and the compiler
132
+ *
133
+ * The declarations are handed to TypeScript as a virtual file system. They are placed under the name
134
+ * the *scripts* import - `node_modules/rxjs/...` - not under the name the package has on disk: the
135
+ * js-controller installs script libraries under an adapter-scoped alias, and TypeScript has to
136
+ * resolve `import ... from "rxjs"` against these files.
53
137
  *
54
138
  * @param pkg The package whose typings we're interested in
55
139
  * @param adapterScopedPackageName the package name on the system
56
- * @param wrapInDeclareModule Whether the root file should be wrapped in `declare module "<pkg>" { ... }`
57
140
  * @returns The found declarations or undefined if none were found
58
141
  */
59
- function resolveTypings(pkg, adapterScopedPackageName, wrapInDeclareModule) {
142
+ function resolveTypings(pkg, adapterScopedPackageName) {
60
143
  let packageJsonPath;
61
144
  let packageJson;
62
145
  let rootTypings;
63
146
  let pkgIncludesTypings = true;
64
- function tryToLoadPackage(path) {
147
+ function tryToLoadPackage(name) {
148
+ const found = findPackageJson(name);
149
+ if (!found) {
150
+ return;
151
+ }
65
152
  try {
66
- packageJsonPath = require.resolve(path);
67
- packageJson = require(packageJsonPath);
68
- rootTypings =
69
- typeof packageJson.types === 'string'
70
- ? packageJson.types
71
- : typeof packageJson.typings === 'string'
72
- ? packageJson.typings
73
- : undefined;
153
+ packageJsonPath = found;
154
+ packageJson = require(found);
155
+ rootTypings = findRootTypings(packageJson, (0, node_path_1.dirname)(found));
74
156
  }
75
157
  catch {
76
158
  /* ignore */
77
159
  }
78
160
  }
79
161
  // First, try to resolve the package itself in case it brings its own typings
80
- tryToLoadPackage(`${adapterScopedPackageName}/package.json`);
162
+ tryToLoadPackage(adapterScopedPackageName);
81
163
  if (!rootTypings) {
82
- tryToLoadPackage(`${pkg}/package.json`);
164
+ tryToLoadPackage(pkg);
83
165
  }
84
166
  // If that didn't work, try again with the @types version of the package
85
167
  if (!rootTypings) {
86
- tryToLoadPackage(`@types/${pkg}/package.json`);
168
+ tryToLoadPackage(`@types/${pkg}`);
87
169
  pkgIncludesTypings = false;
88
170
  }
89
171
  // TODO: If that didn't work, download @types/<packagename> and retry the previous step
@@ -95,56 +177,99 @@ function resolveTypings(pkg, adapterScopedPackageName, wrapInDeclareModule) {
95
177
  return undefined;
96
178
  }
97
179
  const packageRoot = (0, node_path_1.dirname)(packageJsonPath);
98
- const normalizeImportPath = (filename) => (0, node_path_1.normalize)(`node_modules/${pkgIncludesTypings ? adapterScopedPackageName : `@types/${pkg}`}/${(0, node_path_1.relative)(packageRoot, filename)}`).replace(/\\/g, '/');
99
- const ret = {};
100
- // We need to look at `import/export ... from 'modulename'` and `/// <reference path='...' />`
101
- const importDtsRegex = /^\s*(?:import|export) .+ from ["'](\.+\/[^"']+)["']/g;
180
+ /**
181
+ * The directory the declarations get in the virtual file system. It has to be the one the
182
+ * `package.json` below is written to, otherwise TypeScript reads that file, follows its `types`
183
+ * entry and finds nothing - which used to leave every import from the package typed as `any`.
184
+ */
185
+ const virtualPackageDir = `node_modules/${pkgIncludesTypings ? '' : '@types/'}${pkg}`;
186
+ // We need to look at everything that names another file of the package: `import ... from "./x"`,
187
+ // `export ... from "./x"`, the side effect import `import "./x"`, `import x = require("./x")`,
188
+ // and `/// <reference path='...' />`.
189
+ //
190
+ // The `m` flag is what makes `^` match every line instead of only the start of the file. Without
191
+ // it, exactly one import per file was followed - and only if it happened to be the first thing in
192
+ // it. For rxjs 6 that collected 6 of its ~800 declaration files.
193
+ //
194
+ // Everything between the keyword and the path is skipped, so the shape of the import does not
195
+ // matter and it may span several lines. `[^;]` stops that at the statement's semicolon, so a
196
+ // match can never run into the next statement.
197
+ const importDtsRegex = /^\s*(?:import|export)\s[^;]*?["'](\.+\/[^"']+)["']/gm;
102
198
  const pathReferenceRegex = /\/\/\/ <reference path=["']([^"']+)["'] \/>/g;
103
199
  const matchAllImports = (str) => [...(0, tools_1.matchAll)(importDtsRegex, str), ...(0, tools_1.matchAll)(pathReferenceRegex, str)].map(groups => groups[0]);
104
200
  // the paths are relative to the package.json - we need an absolute path to read the files
105
201
  rootTypings = (0, node_path_1.join)(packageRoot, rootTypings);
106
202
  // some @types packages specify `index` as their typings file instead of `index.d.ts`
107
203
  rootTypings = normalizeDTSImport(rootTypings);
108
- // include package.json in typings, so TypeScript can look up the correct entry point
109
- const relativePath = `node_modules/${pkgIncludesTypings ? '' : '@types/'}${pkg}/package.json`.replace(/\\/g, '/');
110
- ret[relativePath] = JSON.stringify(packageJson);
111
- // Used to test whether a .d.ts file already uses "declare module" or not
112
- const declareModuleRegex = /^\s*declare module/gm;
113
- // recursively load all typings
204
+ // recursively load all typings, keyed by their location on disk
205
+ const collected = new Map();
114
206
  const definitionQueue = [rootTypings];
115
207
  while (definitionQueue.length > 0) {
116
208
  const filename = definitionQueue.shift();
117
- const dirName = (0, node_path_1.dirname)(filename);
118
- // Read the file and remember it in the return dictionary
209
+ if (collected.has(filename)) {
210
+ continue;
211
+ }
119
212
  let fileContent;
120
213
  try {
121
214
  fileContent = (0, node_fs_1.readFileSync)(filename, 'utf8');
122
215
  }
123
216
  catch (e) {
124
- // The typings are malformed
125
- console.error(`Failed to load definitions for ${pkg}: ${e.toString()}`);
126
- // Since we cannot use them, return undefined
127
- return undefined;
217
+ // Without the entry point there is nothing to hand to TypeScript
218
+ if (filename === rootTypings) {
219
+ console.error(`Failed to load definitions for ${pkg}: ${e.toString()}`);
220
+ return undefined;
221
+ }
222
+ // A referenced file was there a moment ago but cannot be read now. Dropping every
223
+ // declaration of the package over one unreadable file would be out of proportion.
224
+ console.warn(`Skipped a definition file of ${pkg}: ${e.toString()}`);
225
+ continue;
128
226
  }
129
- // We need to store the filename relative to the base dir
130
- const relativePath = normalizeImportPath(filename);
131
- // If necessary, wrap the root typings (only those!)
132
- ret[relativePath] =
133
- wrapInDeclareModule && filename === rootTypings && !declareModuleRegex.test(fileContent)
134
- ? `declare module "${pkg}" { ${fileContent} }`
135
- : fileContent;
227
+ collected.set(filename, fileContent);
136
228
  // If this file references another .d.ts file, we need to load that too
137
229
  matchAllImports(fileContent)
138
230
  // resolve the file relative to the current directory
139
- .map(file => (0, node_path_1.join)(dirName, file))
231
+ .map(file => (0, node_path_1.join)((0, node_path_1.dirname)(filename), file))
140
232
  // find out the correct path of the file we want to import
141
233
  .map(normalizeDTSImport)
234
+ // A package may import something it does not ship declarations for, and the matcher
235
+ // above may pick up a string that only looks like a path
236
+ .filter(file => (0, node_fs_1.existsSync)(file))
142
237
  // Find all libs we have not loaded yet
143
- .filter(file => !(normalizeImportPath(file) in ret))
238
+ .filter(file => !collected.has(file))
144
239
  .forEach(file => definitionQueue.push(file));
145
240
  }
241
+ /**
242
+ * The directory that becomes `node_modules/<pkg>` in the virtual file system.
243
+ *
244
+ * `virtual-tsc` resolves with `moduleResolution: node10`, which looks the entry point up next to
245
+ * the package - so laying the files out around the entry point rather than around the
246
+ * package.json is what makes a package work whose declarations sit in a subdirectory. For a
247
+ * package whose entry point is at its root - the usual case - this is the package root and
248
+ * nothing changes.
249
+ */
250
+ let virtualRoot = (0, node_path_1.dirname)(rootTypings);
251
+ if ([...collected.keys()].some(file => (0, node_path_1.relative)(virtualRoot, file).startsWith('..'))) {
252
+ // Declarations reach above the entry point. Moving them would break the relative imports
253
+ // between them, so the layout of the package is kept as it is.
254
+ virtualRoot = packageRoot;
255
+ }
256
+ const toVirtualPath = (filename) => (0, node_path_1.normalize)(`${virtualPackageDir}/${(0, node_path_1.relative)(virtualRoot, filename)}`).replace(/\\/g, '/');
257
+ const ret = {};
258
+ for (const [filename, fileContent] of collected) {
259
+ ret[toVirtualPath(filename)] =
260
+ filename === rootTypings ? wrapRootTypingsIfNeeded(pkg, fileContent) : fileContent;
261
+ }
262
+ // Include a package.json, so TypeScript can look up the entry point. It describes the layout
263
+ // above, not the one the package has on disk - and it is deliberately minimal: the original
264
+ // `exports` map refers to paths that do not exist here, and TypeScript refuses to resolve the
265
+ // package at all when it finds one it cannot follow under `moduleResolution: node10`.
266
+ ret[`${virtualPackageDir}/package.json`] = JSON.stringify({
267
+ name: pkg,
268
+ version: packageJson?.version,
269
+ types: `./${(0, node_path_1.relative)(virtualRoot, rootTypings).replace(/\\/g, '/')}`,
270
+ });
146
271
  // Avoid returning empty declarations
147
- if (Object.keys(ret).length === 0) {
272
+ if (!collected.size) {
148
273
  return undefined;
149
274
  }
150
275
  return ret;
@@ -386,7 +511,7 @@ function transformScriptBeforeCompilation(source, isGlobal) {
386
511
  };
387
512
  const sourceFile = (0, typescript_1.createSourceFile)('index.ts', source, typescript_1.ScriptTarget.ESNext, /* setParentNodes */ true);
388
513
  const result = (0, typescript_1.transform)(sourceFile, [transformer]);
389
- return (0, typescript_1.createPrinter)().printNode(typescript_1.EmitHint.Unspecified, result.transformed[0], sourceFile);
514
+ return (0, typescript_1.createPrinter)(PRINTER_OPTIONS).printNode(typescript_1.EmitHint.Unspecified, result.transformed[0], sourceFile);
390
515
  }
391
516
  /**
392
517
  * Takes the global declarations for a TypeScript and wraps export statements in `declare global`
@@ -422,7 +547,7 @@ function transformGlobalDeclarations(decl) {
422
547
  };
423
548
  const sourceFile = (0, typescript_1.createSourceFile)('index.d.ts', decl, typescript_1.ScriptTarget.ESNext, /* setParentNodes */ true);
424
549
  const result = (0, typescript_1.transform)(sourceFile, [transformer]);
425
- return (0, typescript_1.createPrinter)().printNode(typescript_1.EmitHint.Unspecified, result.transformed[0], sourceFile);
550
+ return (0, typescript_1.createPrinter)(PRINTER_OPTIONS).printNode(typescript_1.EmitHint.Unspecified, result.transformed[0], sourceFile);
426
551
  }
427
552
  /**
428
553
  * Translates a script ID to a filename for the compiler