@ohos-ports/iobroker-adapter-dev 0.0.0-stage → 1.5.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +356 -2
- package/bin/build-adapter.js +2 -0
- package/bin/clean-dir.js +20 -0
- package/bin/translate-adapter.js +2 -0
- package/build/build-adapter-handlers.d.ts +17 -0
- package/build/build-adapter-handlers.js +247 -0
- package/build/build-adapter-handlers.js.map +1 -0
- package/build/build-adapter.d.ts +1 -0
- package/build/build-adapter.js +194 -0
- package/build/build-adapter.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.js +40 -0
- package/build/index.js.map +1 -0
- package/build/network.d.ts +11 -0
- package/build/network.js +42 -0
- package/build/network.js.map +1 -0
- package/build/translate-adapter-handlers.d.ts +63 -0
- package/build/translate-adapter-handlers.js +593 -0
- package/build/translate-adapter-handlers.js.map +1 -0
- package/build/translate-adapter.d.ts +1 -0
- package/build/translate-adapter.js +81 -0
- package/build/translate-adapter.js.map +1 -0
- package/build/translate.d.ts +47 -0
- package/build/translate.js +169 -0
- package/build/translate.js.map +1 -0
- package/build/translators/deepl-translator.d.ts +15 -0
- package/build/translators/deepl-translator.js +86 -0
- package/build/translators/deepl-translator.js.map +1 -0
- package/build/translators/google-v3-translator.d.ts +12 -0
- package/build/translators/google-v3-translator.js +49 -0
- package/build/translators/google-v3-translator.js.map +1 -0
- package/build/translators/index.d.ts +5 -0
- package/build/translators/index.js +12 -0
- package/build/translators/index.js.map +1 -0
- package/build/translators/legacy-translator.d.ts +9 -0
- package/build/translators/legacy-translator.js +32 -0
- package/build/translators/legacy-translator.js.map +1 -0
- package/build/translators/testing-translator.d.ts +8 -0
- package/build/translators/testing-translator.js +14 -0
- package/build/translators/testing-translator.js.map +1 -0
- package/build/translators/types.d.ts +6 -0
- package/build/translators/types.js +3 -0
- package/build/translators/types.js.map +1 -0
- package/build/util.d.ts +28 -0
- package/build/util.js +84 -0
- package/build/util.js.map +1 -0
- package/package.json +85 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021-2025 ioBroker developers
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,357 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ioBroker adapter-dev
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
All dependencies an ioBroker adapter developer needs.
|
|
4
|
+
|
|
5
|
+
[
|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
](https://www.npmjs.com/package/@iobroker/adapter-dev)
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
To use this library, add it to your dev dependencies:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install --save-dev @iobroker/adapter-dev
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Add the following to the `scripts` section of your `package.json`:
|
|
20
|
+
|
|
21
|
+
```json5
|
|
22
|
+
"scripts": {
|
|
23
|
+
// ... other scripts before this
|
|
24
|
+
"translate": "translate-adapter",
|
|
25
|
+
// If you need to compile React or TypeScript:
|
|
26
|
+
"build": "build-adapter",
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
If you don't have any i18n JSON files yet, call the following exactly once:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm run translate to-json
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## TL;DR
|
|
37
|
+
|
|
38
|
+
- You should only update i18n JSON files and you shouldn't touch words.js anymore.
|
|
39
|
+
- Add new strings only to the English JSON file.
|
|
40
|
+
- Call the following command whenever you add any text in JSON files (inside the admin i18n folder or in `io-package.json`).
|
|
41
|
+
- If you have an HTML/JavaScript admin UI: `npm run translate all`
|
|
42
|
+
- If you have a React admin UI: `npm run translate`
|
|
43
|
+
- Run the following commands to (re)compile your adapter:
|
|
44
|
+
- If you are using TypeScript: `npm run build-adapter typescript`
|
|
45
|
+
- If you have a React admin UI: `npm run build-adapter react`
|
|
46
|
+
- If you have both: `npm run build-adapter all`
|
|
47
|
+
|
|
48
|
+
## Manage Translations
|
|
49
|
+
|
|
50
|
+
With the above setup completed, you can use the different commands of `translate-adapter` simply by calling:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npm run translate <command>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The commands exist in three forms (all three will be shown as examples below):
|
|
57
|
+
|
|
58
|
+
- full name: a self-explaining name
|
|
59
|
+
- short code: a one-character command
|
|
60
|
+
- legacy name: the same name as previously used in gulp
|
|
61
|
+
|
|
62
|
+
In most cases, you don't need to specify any additional arguments as the defaults should match most adapters.
|
|
63
|
+
|
|
64
|
+
Note: if you need to provide arguments, you must add a double dash `--` before any arguments!
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm run translate <command> -- <args>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Global Command Line Arguments
|
|
71
|
+
|
|
72
|
+
The following command line arguments can be passed to all commands:
|
|
73
|
+
|
|
74
|
+
- `--io-package`: Path to the io-package.json file. Short: `-p`. Default: `./io-package.json`
|
|
75
|
+
- `--admin`: Path to the admin directory. Short: `-a`. Default: `./admin`
|
|
76
|
+
- `--words`: Path to the words.js file. Short: `-w`. Default: searches it in the admin directory, either `<admin-dir>/words.js` or `<admin-dir>/js/words.js`.
|
|
77
|
+
- `--base`: Path to the english i18n file, multiple files are possible. Short: `-b`. Default: searches it in the admin directory, it will be `<admin-dir>/i18n/en/translations.json` or/and `<admin-dir>/src/i18n/en.json`
|
|
78
|
+
- `--languages`: Specify a subset of languages to be translated. Short `-l`. Default: all languages.
|
|
79
|
+
|
|
80
|
+
### `translate` Command
|
|
81
|
+
|
|
82
|
+
This is the default command and does not need to be specified.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
npm run translate # (default)
|
|
86
|
+
npm run translate translate # full name/legacy
|
|
87
|
+
npm run translate t # short code
|
|
88
|
+
npm run translate t -- -l de fr it # Only translate into german, french and italian
|
|
89
|
+
npm run translate t -- --rebuild # Delete all translation files and rebuild from scratch
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Translates all not yet translated strings in `io-package.json` and the i18n JSON files to all supported languages using Google Translate.
|
|
93
|
+
|
|
94
|
+
#### Rebuild Option
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
npm run translate --rebuild # Delete all translation files and rebuild
|
|
98
|
+
npm run translate -r # Short form
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The `--rebuild` option deletes all existing translation files (except English base files) and regenerates everything new. This is useful when:
|
|
102
|
+
|
|
103
|
+
- English source text has changed and you want fresh translations
|
|
104
|
+
- You want to ensure structural consistency across all translation files
|
|
105
|
+
- You've modified the English keys and want to clean up old translations
|
|
106
|
+
|
|
107
|
+
Previously known as `gulp translate`.
|
|
108
|
+
|
|
109
|
+
### `to-json` Command
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
npm run translate to-json # full name
|
|
113
|
+
npm run translate j # short code
|
|
114
|
+
npm run translate adminWords2languages # legacy
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Converts `words.js` to the different i18n JSON files; this should be used exactly once when there are no JSON files yet.
|
|
118
|
+
|
|
119
|
+
Previously known as `gulp adminWords2languages`.
|
|
120
|
+
|
|
121
|
+
### `to-words` Command
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npm run translate to-words # full name
|
|
125
|
+
npm run translate w # short code
|
|
126
|
+
npm run translate adminLanguages2words # legacy
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Updates `words.js` from the different i18n JSON files; call this whenever you modify any of your JSON files manually. This is also automatically called by [Weblate](https://weblate.iobroker.net/) whenever translations are updated.
|
|
130
|
+
|
|
131
|
+
Previously known as `gulp adminLanguages2words`.
|
|
132
|
+
|
|
133
|
+
### `convert` Command
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npm run translate convert # full name
|
|
137
|
+
npm run translate c # short code
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Converts old structure of i18n files, like `i18n/LANG/translations.json` to new one `i18n/LANG.json`. The new structure is preferred.
|
|
141
|
+
|
|
142
|
+
Additionally, it will convert the indent to 4 spaces, line endings to LF and sort the keys.
|
|
143
|
+
|
|
144
|
+
### `all` Command
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npm run translate all # full name
|
|
148
|
+
npm run translate a # short code
|
|
149
|
+
npm run translate translateAndUpdateWordsJS # legacy
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Calls `translate` and afterwards updates `words.js` using `to-words` followed by `to-json`.
|
|
153
|
+
|
|
154
|
+
Previously known as `gulp translateAndUpdateWordsJS`.
|
|
155
|
+
|
|
156
|
+
### Environment Variables
|
|
157
|
+
|
|
158
|
+
#### Instead of Command Line Arguments
|
|
159
|
+
|
|
160
|
+
All command line arguments can also be provided as environment variables. Just prefix any argument with `IOBROKER_TRANSLATE_`:
|
|
161
|
+
|
|
162
|
+
- `--io-package` becomes `IOBROKER_TRANSLATE_IO_PACKAGE`
|
|
163
|
+
- `--admin` becomes `IOBROKER_TRANSLATE_ADMIN`
|
|
164
|
+
- `--words` becomes `IOBROKER_TRANSLATE_WORDS`
|
|
165
|
+
- `--base` becomes `IOBROKER_TRANSLATE_BASE`
|
|
166
|
+
- `--languages` becomes `IOBROKER_TRANSLATE_LANGUAGES`
|
|
167
|
+
|
|
168
|
+
#### Translate with Google Translate Credentials
|
|
169
|
+
|
|
170
|
+
If you wish to use the Google Translate V3 API, you can set the environment variable `GOOGLE_APPLICATION_CREDENTIALS` to point to a credentials file, so the translations can use larger quota for translations (which may result in costs).
|
|
171
|
+
|
|
172
|
+
The file can be generated on the Google Cloud Platform by creating a Service Account for Google Translate V3. See [here](https://cloud.google.com/translate/docs/setup) for additional information. The expected format looks something like this:
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"type": "service_account",
|
|
177
|
+
"project_id": "your-project-id-123456",
|
|
178
|
+
"private_key_id": "1234567890abcdef1234567890abcdef12345678",
|
|
179
|
+
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
|
|
180
|
+
"client_email": "your-app-name@your-project-id-123456.iam.gserviceaccount.com",
|
|
181
|
+
"client_id": "123456789012345678901",
|
|
182
|
+
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
|
183
|
+
"token_uri": "https://oauth2.googleapis.com/token",
|
|
184
|
+
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
|
185
|
+
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/your-app-name%40your-project-id-123456.iam.gserviceaccount.com"
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### Translate with DeepL API
|
|
190
|
+
|
|
191
|
+
**Recommended:** If you wish to use the DeepL API for higher quality translations, you can set the environment variable `DEEPL_API_KEY` to your DeepL API key. DeepL generally provides better translation quality than Google Translate and has a generous free tier.
|
|
192
|
+
|
|
193
|
+
To get a DeepL API key:
|
|
194
|
+
|
|
195
|
+
1. Visit [DeepL Pro Developer](https://www.deepl.com/pro#developer)
|
|
196
|
+
2. Sign up for a free DeepL API account
|
|
197
|
+
3. Get your API key from the account dashboard
|
|
198
|
+
4. Set the environment variable: `DEEPL_API_KEY=your-api-key-here`
|
|
199
|
+
|
|
200
|
+
Example usage:
|
|
201
|
+
```bash
|
|
202
|
+
# Use DeepL for translation
|
|
203
|
+
export DEEPL_API_KEY="your-deepl-api-key"
|
|
204
|
+
npm run translate
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
#### Translation Service Priority
|
|
208
|
+
|
|
209
|
+
When multiple translation services are configured, the system automatically selects the best available service using this priority order:
|
|
210
|
+
|
|
211
|
+
1. **DeepL API** (when `DEEPL_API_KEY` is set) - **Recommended for best quality**
|
|
212
|
+
2. **Google Translate V3** (when `GOOGLE_APPLICATION_CREDENTIALS` is set)
|
|
213
|
+
3. **Legacy Google Translate** (free, rate-limited)
|
|
214
|
+
|
|
215
|
+
Configure your preferred translation service using environment variables:
|
|
216
|
+
```bash
|
|
217
|
+
# For highest quality (recommended)
|
|
218
|
+
export DEEPL_API_KEY="your-deepl-api-key"
|
|
219
|
+
npm run translate
|
|
220
|
+
|
|
221
|
+
# For Google Translate V3
|
|
222
|
+
export GOOGLE_APPLICATION_CREDENTIALS="path/to/google-credentials.json"
|
|
223
|
+
npm run translate
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Compile adapter files
|
|
227
|
+
|
|
228
|
+
The `build-adapter` command uses esbuild under the hood for lightning fast compilation. It has an extensive set of options you can use to fine tune the compilation process, although the defaults should work out of the box when the adapter was created with `@iobroker/create-adapter`:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
npm run build typescript [options] # TypeScript, full name
|
|
232
|
+
npm run build ts [options] # TypeScript, short code
|
|
233
|
+
npm run build react [options] # React
|
|
234
|
+
npm run build all [options] # Everything (at the moment this is TypeScript and React)
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
These options are available for all commands:
|
|
238
|
+
|
|
239
|
+
- `--watch`, short `-w`: Watch for changes and recompile
|
|
240
|
+
|
|
241
|
+
These only have an effect for the `ts/typescript` and `all` commands:
|
|
242
|
+
|
|
243
|
+
- `--typescriptRootDir`: Directory where the TypeScript part of the adapter is located. Default: `.`
|
|
244
|
+
- `--typescriptOutDir`: Directory where the compiled TypeScript output will be placed, relative to `typescriptRootDir`. Default: `build`
|
|
245
|
+
- `--typescriptPattern`: Glob pattern for TypeScript source files, relative to typescriptRootDir. Should not be changed unless bundling is enabled. Each match will result in a separate bundle. Default: `src/**/*.ts`
|
|
246
|
+
- `--typescriptTsConfig`: Path to the tsconfig.json file used for building TypeScript, relative to `typescriptRootDir`. Default: `tsconfig.build.json`
|
|
247
|
+
- `--typescriptBundle`: Bundle compiled TypeScript output into one file per entry point. Default: `false`
|
|
248
|
+
- `--typescriptFormat`: [Format](https://esbuild.github.io/api/#format) of the output file(s). CommonJS (`cjs`) or ES modules (`esm`).
|
|
249
|
+
- `--typescriptCompileTarget`: [Compilation target](https://esbuild.github.io/api/#target) for TypeScript. Determines which JS features will be used in the output file. Should be in sync with the minimum Node.js version supported by the adapter/ioBroker. Default: `node12`
|
|
250
|
+
- `--typescriptRaw`: An object of raw [esbuild options](https://esbuild.github.io/api/#simple-options) that are passed to the build process for TypeScript. This has to be specified in a config file (see below). Default: (none)
|
|
251
|
+
|
|
252
|
+
These only have an effect for the `react` and `all` commands:
|
|
253
|
+
|
|
254
|
+
- `--reactRootDir`: Directory where the React part of the adapter is located. Default: `admin`
|
|
255
|
+
- `--reactOutDir`: Directory where the compiled React output will be placed, relative to `reactRootDir`. Default: `build`
|
|
256
|
+
- `--reactWatchDir`: Directory where the compiled React output will be placed in watch mode, relative to `reactRootDir`. Default: `.watch`
|
|
257
|
+
- `--reactPattern`: Glob pattern for React source files, relative to reactRootDir. Each match will result in a separate bundle. Default: `src/{index,tab}.{tsx,jsx}`
|
|
258
|
+
- `--reactTsConfig`: Path to the tsconfig.json file used for building React, relative to `reactRootDir`. Default: `tsconfig.json`
|
|
259
|
+
- `--reactBundle`: Bundle compiled React output into one file per entry point. Default: `true`
|
|
260
|
+
- `--reactFormat`: [Format](https://esbuild.github.io/api/#format) of the output file(s). Supports `iife` and `esm`, but ESM should only be selected when targeting modern browsers exclusively.
|
|
261
|
+
- `--reactSplitting`: Moves common code from multiple entry points into separate files, so they only have to be loaded once. Only relevant when `reactBundle` is `true`, `reactFormat` is `"esm"` and there are multiple entry points. If this is the case and there are [unexpected differences](https://esbuild.github.io/api/#splitting) between the watch mode and a normal build, try turning this off. Default: `true`
|
|
262
|
+
- `--reactCompileTarget`: [Compilation target](https://esbuild.github.io/api/#target) for React. Determines which JS features will be used in the output file. Default: `es2018`
|
|
263
|
+
- `--reactRaw`: An object of raw [esbuild options](https://esbuild.github.io/api/#simple-options) that are passed to the build process for React. This has to be specified in a config file (see below). Default: (none)
|
|
264
|
+
|
|
265
|
+
### Using a config file
|
|
266
|
+
|
|
267
|
+
By default, the build script looks for a `.buildconfig.json` file where the above options can be saved (without leading `--`), so they don't have to be specified on the command line. Example:
|
|
268
|
+
|
|
269
|
+
```json
|
|
270
|
+
{ "typescriptBundle": true, "typescriptCompileTarget": "node16" }
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
This path can be changed with the `--config` option, short `-c`.
|
|
274
|
+
|
|
275
|
+
When using a `.js` file instead, this can be used to specify additional [esbuild plugins](https://github.com/esbuild/community-plugins), for example:
|
|
276
|
+
|
|
277
|
+
```js
|
|
278
|
+
const { html } = require("@esbuilder/html");
|
|
279
|
+
|
|
280
|
+
module.exports = { reactRaw: { plugins: [html()] } };
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## clean-dir
|
|
284
|
+
This tool deletes a directory to be specified recursively.
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
npm run clean-dir <directory> # directory to remove
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
## Changelog
|
|
292
|
+
|
|
293
|
+
<!--
|
|
294
|
+
Placeholder for the next version (at the beginning of the line):
|
|
295
|
+
### **WORK IN PROGRESS**
|
|
296
|
+
-->
|
|
297
|
+
### 1.5.0 (2025-09-20)
|
|
298
|
+
- (@Apollon77/@copilot) Add DeepL API support for higher quality translations. Set `DEEPL_API_KEY` environment variable to use DeepL as the preferred translation service. DeepL is prioritized over Google Translate when available.
|
|
299
|
+
- (@Apollon77/@copilot) Add `remove-translations` (`rt`) and `remove-key` (`rk`) commands for translation management. New commands allow removing translation keys from language files efficiently
|
|
300
|
+
- (@Apollon77/@copilot) Enhanced translation error messages for empty string keys with clearer error context and actionable guidance
|
|
301
|
+
- (@Apollon77/@copilot) Add `--rebuild` option to translate command for complete regeneration of translation files
|
|
302
|
+
- (@Apollon77/@copilot) Detect and preserve original indentation in JSON files during translation. Files using tab indentation or different space amounts are now preserved correctly instead of being converted to 4-space indentation.
|
|
303
|
+
- (@Apollon77/@copilot) Sort JSON keys alphabetically in all generated translation files
|
|
304
|
+
- (@Apollon77/@copilot) ESM support for TypeScript build format option. The `--typescriptFormat` option now accepts both `cjs` (CommonJS) and `esm` (ES modules) formats
|
|
305
|
+
- (@Apollon77/@copilot) Enhanced handling of rate limits for translations and persist as much progress as possible.
|
|
306
|
+
|
|
307
|
+
### 1.4.0 (2025-02-22)
|
|
308
|
+
- (ticaki) rimraf replaced by by internal tool.
|
|
309
|
+
- (hombach) change year to 2025
|
|
310
|
+
- (hombach) Fix two vulnerabilities
|
|
311
|
+
- (hombach) Bump dev dependencies
|
|
312
|
+
- (hombach) add tests for node.js 22, remove node 16 tests
|
|
313
|
+
- (@GermanBluefox) Added `convert` command to convert old i18n structure to new one
|
|
314
|
+
- (@GermanBluefox) Packages were updated
|
|
315
|
+
- (@UncleSamSwiss) Change default path for translation JSON files to `admin/i18n/en.json`; the old path is still supported for existing repositories
|
|
316
|
+
|
|
317
|
+
### 1.3.0 (2024-02-18)
|
|
318
|
+
|
|
319
|
+
- (kleinOr/Apollon77) Detects and keeps space indentation of io-package
|
|
320
|
+
- (Steiger04) Fix handling of dot keys for esbuild
|
|
321
|
+
- (Steiger04) Update esbuild and adjust watch mode
|
|
322
|
+
- (Steiger04) process.env.NODE_ENV is now also available server side
|
|
323
|
+
|
|
324
|
+
### 1.2.0 (2022-10-23)
|
|
325
|
+
|
|
326
|
+
- (Grizzlebee) only translate linkText from messages if existent
|
|
327
|
+
- (Apollon77) Add ukrainian as language for translations
|
|
328
|
+
|
|
329
|
+
### 1.1.0 (2022-09-14)
|
|
330
|
+
|
|
331
|
+
- (Grizzelbee) Also translate admin messages in io-package.json
|
|
332
|
+
- (AlCalzone) support specifying raw esbuild options, like loaders/plugins
|
|
333
|
+
|
|
334
|
+
### 1.0.1 (2022-08-17)
|
|
335
|
+
|
|
336
|
+
- (Apollon77) make sure that also texts with multiple sentences are correctly translated via Google Translate
|
|
337
|
+
|
|
338
|
+
### 1.0.0 (2022-02-15)
|
|
339
|
+
|
|
340
|
+
- (AlCalzone) Add build script to compile TypeScript and React using the blazing fast esbuild
|
|
341
|
+
|
|
342
|
+
### 0.1.0 (2021-09-21)
|
|
343
|
+
|
|
344
|
+
- (UncleSamSwiss) Removed dependency on gulp
|
|
345
|
+
- (UncleSamSwiss) Rewrote translation management as a regular Node.js application
|
|
346
|
+
|
|
347
|
+
### 0.0.4 (2021-05-26)
|
|
348
|
+
|
|
349
|
+
- (UncleSamSwiss) Implemented gulp tasks very similar to the existing tasks
|
|
350
|
+
|
|
351
|
+
### 0.0.3 (2021-05-06)
|
|
352
|
+
|
|
353
|
+
- (UncleSamSwiss) Fixed npm publishing
|
|
354
|
+
|
|
355
|
+
### 0.0.2 (2021-05-06)
|
|
356
|
+
|
|
357
|
+
- (UncleSamSwiss) Initial repository setup
|
package/bin/clean-dir.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require("node:fs");
|
|
3
|
+
|
|
4
|
+
const dirPath = process.argv[2];
|
|
5
|
+
|
|
6
|
+
if (!dirPath) {
|
|
7
|
+
console.error("Please provide a directory to clean.");
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
if (fs.existsSync(dirPath)) {
|
|
11
|
+
fs.rm(dirPath, { recursive: true }, (err) => {
|
|
12
|
+
if (err) {
|
|
13
|
+
console.error(`Error while deleting ${dirPath}.`, err);
|
|
14
|
+
} else {
|
|
15
|
+
console.log(`${dirPath} has been deleted.`);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
} else {
|
|
19
|
+
console.log(`${dirPath} does not exist.`);
|
|
20
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Format } from "@ohos-ports/esbuild";
|
|
2
|
+
interface BuildOptions {
|
|
3
|
+
pattern: string;
|
|
4
|
+
tsConfig: string;
|
|
5
|
+
bundle: boolean;
|
|
6
|
+
splitting?: boolean;
|
|
7
|
+
format?: Format;
|
|
8
|
+
compileTarget: string;
|
|
9
|
+
rootDir: string;
|
|
10
|
+
outDir: string;
|
|
11
|
+
watchDir?: string;
|
|
12
|
+
raw?: Record<string, any>;
|
|
13
|
+
}
|
|
14
|
+
export declare function handleBuildReactCommand(watch: boolean, options: BuildOptions): Promise<void>;
|
|
15
|
+
export declare function handleBuildTypeScriptCommand(watch: boolean, options: BuildOptions): Promise<void>;
|
|
16
|
+
export declare function handleBuildAllCommand(watch: boolean, reactOptions: BuildOptions, typescriptOptions: BuildOptions): Promise<void>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.handleBuildReactCommand = handleBuildReactCommand;
|
|
7
|
+
exports.handleBuildTypeScriptCommand = handleBuildTypeScriptCommand;
|
|
8
|
+
exports.handleBuildAllCommand = handleBuildAllCommand;
|
|
9
|
+
/** The build script to use esbuild without specifying 1000 CLI options */
|
|
10
|
+
// @ts-expect-error esm2cjs/execa needs to be fixed to allow cjs import with types
|
|
11
|
+
const execa_1 = require("@esm2cjs/execa");
|
|
12
|
+
const ansi_colors_1 = require("ansi-colors");
|
|
13
|
+
const esbuild_1 = require("@ohos-ports/esbuild");
|
|
14
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
15
|
+
const tiny_glob_1 = __importDefault(require("tiny-glob"));
|
|
16
|
+
const util_1 = require("./util");
|
|
17
|
+
const fs_extra_1 = require("fs-extra");
|
|
18
|
+
async function findTsc() {
|
|
19
|
+
try {
|
|
20
|
+
const packageJsonPath = require.resolve("typescript/package.json");
|
|
21
|
+
const packageJson = await (0, fs_extra_1.readJson)(packageJsonPath);
|
|
22
|
+
const binPath = packageJson.bin.tsc;
|
|
23
|
+
return node_path_1.default.join(node_path_1.default.dirname(packageJsonPath), binPath);
|
|
24
|
+
}
|
|
25
|
+
catch (e) {
|
|
26
|
+
(0, util_1.die)(`Could not find tsc executable: ${e.message}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Helper function to determine file paths that serve as input for React builds
|
|
31
|
+
*
|
|
32
|
+
* @param reactOptions
|
|
33
|
+
*/
|
|
34
|
+
async function getReactFilePaths(reactOptions) {
|
|
35
|
+
let entryPoints = await (0, tiny_glob_1.default)(`${reactOptions.rootDir}/${reactOptions.pattern}`);
|
|
36
|
+
entryPoints = entryPoints.filter(ep => !ep.endsWith(".d.ts") &&
|
|
37
|
+
!ep.endsWith(".test.ts") &&
|
|
38
|
+
!ep.endsWith(".test.tsx"));
|
|
39
|
+
const tsConfigPath = `${reactOptions.rootDir}/${reactOptions.tsConfig}`;
|
|
40
|
+
return { entryPoints, tsConfigPath };
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Helper function to determine file paths that serve as input for TypeScript builds
|
|
44
|
+
*
|
|
45
|
+
* @param typescriptOptions
|
|
46
|
+
*/
|
|
47
|
+
async function getTypeScriptFilePaths(typescriptOptions) {
|
|
48
|
+
let entryPoints = await (0, tiny_glob_1.default)(`${typescriptOptions.rootDir}/${typescriptOptions.pattern}`);
|
|
49
|
+
entryPoints = entryPoints.filter(ep => !ep.endsWith(".d.ts") && !ep.endsWith(".test.ts"));
|
|
50
|
+
const tsConfigPath = `${typescriptOptions.rootDir}/${typescriptOptions.tsConfig}`;
|
|
51
|
+
return { entryPoints, tsConfigPath };
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Type-checks the project with the given tsconfig path
|
|
55
|
+
*
|
|
56
|
+
* @param tsConfigPath
|
|
57
|
+
*/
|
|
58
|
+
async function typeCheck(tsConfigPath) {
|
|
59
|
+
console.log();
|
|
60
|
+
console.log((0, ansi_colors_1.gray)(`Type-checking ${tsConfigPath} with tsc...`));
|
|
61
|
+
const tscPath = await findTsc();
|
|
62
|
+
try {
|
|
63
|
+
await (0, execa_1.execaNode)(tscPath, `-p ${tsConfigPath} --noEmit`.split(" "), {
|
|
64
|
+
stdout: "inherit",
|
|
65
|
+
stderr: "inherit",
|
|
66
|
+
});
|
|
67
|
+
console.error((0, ansi_colors_1.green)(`✔ Type-checking ${tsConfigPath} succeeded!`));
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
console.error((0, ansi_colors_1.red)(`❌ Type-checking ${tsConfigPath} failed!`));
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function typeCheckWatch(tsConfigPath) {
|
|
76
|
+
console.log();
|
|
77
|
+
console.log((0, ansi_colors_1.gray)(`Type-checking ${tsConfigPath} with tsc in watch mode...`));
|
|
78
|
+
const tscPath = await findTsc();
|
|
79
|
+
return (0, execa_1.execaNode)(tscPath, `-p ${tsConfigPath} --noEmit --watch --preserveWatchOutput`.split(" "), { stdout: "inherit", stderr: "inherit" });
|
|
80
|
+
}
|
|
81
|
+
function getReactBuildOptions(watch, reactOptions, entryPoints, tsConfigPath) {
|
|
82
|
+
return {
|
|
83
|
+
entryPoints,
|
|
84
|
+
tsconfig: tsConfigPath,
|
|
85
|
+
outdir: `${reactOptions.rootDir}/${(watch && reactOptions.watchDir) || reactOptions.outDir}`,
|
|
86
|
+
bundle: reactOptions.bundle,
|
|
87
|
+
format: reactOptions.format,
|
|
88
|
+
// Splitting moves common code from multiple entry points into separate files
|
|
89
|
+
// This is only relevant for React builds with output format ESM though
|
|
90
|
+
splitting: !watch &&
|
|
91
|
+
entryPoints.length > 1 &&
|
|
92
|
+
reactOptions.splitting &&
|
|
93
|
+
reactOptions.bundle &&
|
|
94
|
+
reactOptions.format === "esm",
|
|
95
|
+
target: reactOptions.compileTarget,
|
|
96
|
+
minify: !watch,
|
|
97
|
+
sourcemap: true,
|
|
98
|
+
logLevel: "info",
|
|
99
|
+
define: {
|
|
100
|
+
"process.env.NODE_ENV": watch ? '"development"' : '"production"',
|
|
101
|
+
},
|
|
102
|
+
...reactOptions.raw,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function getTypeScriptBuildOptions(watch, typescriptOptions, entryPoints, tsConfigPath) {
|
|
106
|
+
return {
|
|
107
|
+
entryPoints,
|
|
108
|
+
tsconfig: tsConfigPath,
|
|
109
|
+
outdir: `${typescriptOptions.rootDir}/${typescriptOptions.outDir}`,
|
|
110
|
+
bundle: typescriptOptions.bundle,
|
|
111
|
+
minify: false,
|
|
112
|
+
sourcemap: true,
|
|
113
|
+
logLevel: "info",
|
|
114
|
+
platform: "node",
|
|
115
|
+
format: typescriptOptions.format || "cjs",
|
|
116
|
+
target: typescriptOptions.compileTarget,
|
|
117
|
+
define: {
|
|
118
|
+
"process.env.NODE_ENV": watch ? '"development"' : '"production"',
|
|
119
|
+
},
|
|
120
|
+
...typescriptOptions.raw,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
async function buildReact(options) {
|
|
124
|
+
const { entryPoints, tsConfigPath } = await getReactFilePaths(options);
|
|
125
|
+
// Building React happens in one or two steps:
|
|
126
|
+
// 1. fast compile with ESBuild
|
|
127
|
+
console.log();
|
|
128
|
+
console.log((0, ansi_colors_1.gray)("Compiling React with ESBuild..."));
|
|
129
|
+
await (0, esbuild_1.build)(getReactBuildOptions(false, options, entryPoints, tsConfigPath));
|
|
130
|
+
// 2. type-check with TypeScript (if there are TSX entry points)
|
|
131
|
+
if (entryPoints.some(e => e.endsWith(".tsx"))) {
|
|
132
|
+
if (!(await typeCheck(tsConfigPath))) {
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async function buildTypeScript(options) {
|
|
138
|
+
const { entryPoints, tsConfigPath } = await getTypeScriptFilePaths(options);
|
|
139
|
+
// Building TS happens in two steps:
|
|
140
|
+
// 1. fast compile with ESBuild
|
|
141
|
+
console.log();
|
|
142
|
+
console.log((0, ansi_colors_1.gray)("Compiling TypeScript with ESBuild..."));
|
|
143
|
+
await (0, esbuild_1.build)(getTypeScriptBuildOptions(false, options, entryPoints, tsConfigPath));
|
|
144
|
+
// 2. type-check with TypeScript
|
|
145
|
+
if (!(await typeCheck(tsConfigPath))) {
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
async function buildAll(reactOptions, typescriptOptions) {
|
|
150
|
+
await Promise.all([
|
|
151
|
+
buildReact(reactOptions),
|
|
152
|
+
buildTypeScript(typescriptOptions),
|
|
153
|
+
]);
|
|
154
|
+
}
|
|
155
|
+
async function watchReact(options) {
|
|
156
|
+
const { entryPoints, tsConfigPath } = await getReactFilePaths(options);
|
|
157
|
+
// Building React happens in one or two steps:
|
|
158
|
+
// 1. fast compile with ESBuild
|
|
159
|
+
console.log();
|
|
160
|
+
console.log((0, ansi_colors_1.gray)("Compiling React with ESBuild in watch mode..."));
|
|
161
|
+
const buildCtx = await (0, esbuild_1.context)({
|
|
162
|
+
...getReactBuildOptions(true, options, entryPoints, tsConfigPath),
|
|
163
|
+
// We could run a separate type checking process after each successful
|
|
164
|
+
});
|
|
165
|
+
void buildCtx.watch();
|
|
166
|
+
// 2. type-check with TypeScript (if there are TSX entry points)
|
|
167
|
+
let checkProcess;
|
|
168
|
+
if (entryPoints.some(e => e.endsWith(".tsx"))) {
|
|
169
|
+
checkProcess = await typeCheckWatch(tsConfigPath);
|
|
170
|
+
}
|
|
171
|
+
return { ctx: buildCtx, check: checkProcess };
|
|
172
|
+
}
|
|
173
|
+
async function watchTypeScript(options) {
|
|
174
|
+
const { entryPoints, tsConfigPath } = await getTypeScriptFilePaths(options);
|
|
175
|
+
// Building TS happens in two steps:
|
|
176
|
+
// 1. fast compile with ESBuild
|
|
177
|
+
console.log();
|
|
178
|
+
console.log((0, ansi_colors_1.gray)("Compiling TypeScript with ESBuild..."));
|
|
179
|
+
const buildCtx = await (0, esbuild_1.context)({
|
|
180
|
+
...getTypeScriptBuildOptions(true, options, entryPoints, tsConfigPath),
|
|
181
|
+
// We could run a separate type checking process after each successful
|
|
182
|
+
});
|
|
183
|
+
void buildCtx.watch();
|
|
184
|
+
// 2. type-check with TypeScript
|
|
185
|
+
const checkProcess = await typeCheckWatch(tsConfigPath);
|
|
186
|
+
return { ctx: buildCtx, check: checkProcess };
|
|
187
|
+
}
|
|
188
|
+
// Entry points for the CLI
|
|
189
|
+
async function handleBuildReactCommand(watch, options) {
|
|
190
|
+
if (watch) {
|
|
191
|
+
// In watch mode, we start the ESBuild and TSC processes in parallel and wait until they end
|
|
192
|
+
const { ctx, check } = await watchReact(options);
|
|
193
|
+
return new Promise(resolve => {
|
|
194
|
+
check === null || check === void 0 ? void 0 : check.then(() => resolve()).catch(() => resolve());
|
|
195
|
+
process.on("SIGINT", () => {
|
|
196
|
+
console.log();
|
|
197
|
+
console.log((0, ansi_colors_1.gray)("SIGINT received, shutting down..."));
|
|
198
|
+
ctx.dispose();
|
|
199
|
+
if (check) {
|
|
200
|
+
check.kill("SIGINT");
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
resolve();
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
await buildReact(options);
|
|
209
|
+
}
|
|
210
|
+
async function handleBuildTypeScriptCommand(watch, options) {
|
|
211
|
+
if (watch) {
|
|
212
|
+
// In watch mode, we start the ESBuild and TSC processes in parallel and wait until they end
|
|
213
|
+
const { ctx, check } = await watchTypeScript(options);
|
|
214
|
+
return new Promise(resolve => {
|
|
215
|
+
check.then(() => resolve()).catch(() => resolve());
|
|
216
|
+
process.on("SIGINT", () => {
|
|
217
|
+
console.log();
|
|
218
|
+
console.log((0, ansi_colors_1.gray)("SIGINT received, shutting down..."));
|
|
219
|
+
ctx.dispose();
|
|
220
|
+
check.kill("SIGINT");
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
await buildTypeScript(options);
|
|
225
|
+
}
|
|
226
|
+
async function handleBuildAllCommand(watch, reactOptions, typescriptOptions) {
|
|
227
|
+
if (watch) {
|
|
228
|
+
// In watch mode, we start the ESBuild and TSC processes in parallel and wait until they end
|
|
229
|
+
const { ctx: ctxReact, check: checkReact } = await watchReact(reactOptions);
|
|
230
|
+
const { ctx: ctxTS, check: checkTS } = await watchTypeScript(typescriptOptions);
|
|
231
|
+
return new Promise(resolve => {
|
|
232
|
+
Promise.all([checkReact, checkTS].filter(Boolean))
|
|
233
|
+
.then(() => resolve())
|
|
234
|
+
.catch(() => resolve());
|
|
235
|
+
process.on("SIGINT", () => {
|
|
236
|
+
console.log();
|
|
237
|
+
console.log((0, ansi_colors_1.gray)("SIGINT received, shutting down..."));
|
|
238
|
+
ctxReact.dispose();
|
|
239
|
+
ctxTS.dispose();
|
|
240
|
+
checkReact === null || checkReact === void 0 ? void 0 : checkReact.kill("SIGINT");
|
|
241
|
+
checkTS.kill("SIGINT");
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
await buildAll(reactOptions, typescriptOptions);
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=build-adapter-handlers.js.map
|