@lakutata/cli 3.1.4 → 3.1.5

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 CHANGED
@@ -26,7 +26,7 @@ both the features and the confirmation).
26
26
  | `--path <directory>` | the directory in which the project directory is created, by default the current one |
27
27
  | `--init` | create the project in the `--path` directory itself, which must exist and may hold files: the files it already has are kept (a warning lists those that the template also has, to merge by hand), and only the files the tool writes are filled with the information of the project |
28
28
  | `--description`, `--author`, `--license` | information about the application |
29
- | `--with <features>` | the optional features of the template to enable, separated by commas (listed by `lakutata templates`): `i18n`, `installer`. In a terminal, without `--with` or `--yes`, you choose them from a list |
29
+ | `--with <features>` | the optional features of the template to enable, separated by commas (listed by `lakutata templates`): `i18n`, `installer`, `win7`. In a terminal, without `--with` or `--yes`, you choose them from a list |
30
30
  | `--package-manager <npm\|pnpm\|yarn\|none>` | the package manager that installs the dependencies (`none` installs nothing): npm by default, or pnpm or yarn when one of them started the tool |
31
31
  | `--no-git` | do not initialize a git repository |
32
32
  | `--yes` | create the project without asking for the features or for a confirmation |
@@ -38,11 +38,13 @@ lakutata create --name my-service --template service --with i18n --yes
38
38
 
39
39
  Every official template has the `i18n` feature: the messages of the application in several languages
40
40
  (`lakutata/com/i18n`), in `src/locales` (`en.json`, `zh-CN.json`) and bundled with the code. Each request is answered in
41
- its own language, including its validation errors (command line tools and Electron applications use the language of the
41
+ its own language, including its validation errors (command line tools and desktop applications use the language of the
42
42
  environment). The feature also adds the `i18n:check` and `i18n:types` scripts. The `cli`, `service` and `web-*`
43
43
  templates also have the `installer` feature: the `lakutata.installer` configuration of the application and the scripts
44
44
  that make its installers (on the machine, and for Linux in Docker), and, in the `service` and `web-*` templates, a
45
- system service.
45
+ system service. The `nwjs-*` templates have the `win7` feature: NW.js 0.72.0, the last release running on Windows 7, 8
46
+ and 8.1, instead of the release the template was published with, and the script that makes the installers of 32-bit
47
+ Windows.
46
48
 
47
49
  ### `lakutata templates`
48
50
 
@@ -408,12 +410,12 @@ platforms (the Linux ones can be made in a container). They are configured by th
408
410
  | `productName` | the name shown to users (in the installers, and in the list of programs on Windows), by default the `productName` of the `package.json`, else the name |
409
411
  | `description`, `maintainer`, `homepage`, `license` | by default those of the `package.json` (the maintainer is its author) |
410
412
  | `vendor` | its vendor, none by default (on Windows, the publisher is the vendor, else the maintainer) |
411
- | `runtime` | the runtime of the executable: `node` (the default) or `bun`; `electron` for an Electron application (below) |
412
- | `addToPath` | put the program in the PATH (`/usr/bin/<program>`, `/usr/local/bin/<program>` on macOS; on Windows, the PATH of the machine), `true` by default |
413
+ | `runtime` | the runtime of the executable: `node` (the default) or `bun`; `electron` for an Electron application, `nwjs` for an NW.js application (below) |
414
+ | `addToPath` | put the program in the PATH (`/usr/bin/<program>`, `/usr/local/bin/<program>` on macOS; on Windows, the PATH of the machine), `true` by default (`false` for an NW.js application) |
413
415
  | `service` | `true` or the options of the service (below), none by default |
414
416
  | `linux.targets` | `deb`, `rpm`, `archlinux`, `tar.gz` on glibc systems (`deb`, `rpm`, `tar.gz` by default); `apk`, `tar.gz` on Alpine (musl) |
415
417
  | `linux.depends`, `linux.recommends`, `linux.section`, `linux.priority` | the system packages it needs and recommends, its section and its priority (deb) |
416
- | `mac.targets` | `pkg`, `tar.gz` (both by default) |
418
+ | `mac.targets` | `pkg`, `tar.gz` (both by default); `dmg` for an NW.js application |
417
419
  | `win.targets` | `nsis`, `msi`, `zip` (all by default) |
418
420
  | `electron` | the electron-builder configuration of an Electron application, merged over the one made from these options |
419
421
 
@@ -527,11 +529,56 @@ one electron-builder downloads is built for x64. On Windows arm64, the NSIS inst
527
529
  the BCJ filter (`ELECTRON_BUILDER_7Z_FILTER`), because they cannot extract files compressed with the ARM64 filter,
528
530
  which 7-Zip would choose.
529
531
 
532
+ The installers of an NW.js application (`"runtime": "nwjs"`) hold the normal flavor of its NW.js (`lakutata nwjs use`,
533
+ below), named after the application, with the application in it: its bundle for the Node.js of that NW.js, its native
534
+ addons made to load in it, its resources and the manifest of NW.js. On Windows, the executable is `<name>.exe`, with
535
+ the icon and the version information of the application; on macOS, the bundle is `<productName>.app`, whose
536
+ `Info.plist` gives its name, its `appId`, its version and its icon (signed again ad hoc). Its installers are those of a
537
+ desktop application, by default `deb` on Linux, `dmg` on macOS and `nsis` on Windows: the Windows installers (`nsis`,
538
+ `msi`) add it to the start menu and to the desktop, the `dmg` disk image holds it beside a link to /Applications and
539
+ the `pkg` package installs it there, and the Linux packages (`deb`, `rpm`) add its desktop entry and its icons and
540
+ depend on the libraries of Chromium. `--arch` makes them for another architecture than the one of the machine (`ia32`:
541
+ 32-bit Windows). An NW.js application is not a service; its scripts run as for the other applications (on macOS, it is
542
+ removed by deleting it, without a removal script).
543
+
530
544
  | Command option | |
531
545
  |---|---|
532
546
  | `--target <targets...>` | the installers to make, by default those of the configuration |
533
547
  | `--outdir <directory>` | the directory of the installers, `dist/installer` by default |
534
548
  | `--entry`, `--no-minify`, `--external` | as for `lakutata package exe` |
549
+ | `--arch <arch>` | the architecture of an NW.js application (`x64`, `ia32`, `arm64`), the one of the machine by default |
550
+
551
+ ## NW.js
552
+
553
+ An NW.js application (the `nwjs-react` and `nwjs-vue` templates) runs in the version of NW.js of its `package.json`,
554
+ `"lakutata": {"nwjs": {"version": "0.119.2"}}`. The runtimes of NW.js are downloaded once into the cache of lakutata
555
+ (from `https://dl.nwjs.io`, or the mirror of `LAKUTATA_NWJS_MIRROR`) and checked against the checksums of their release.
556
+ lakutata runs on the releases whose Node.js is 18.10 or later.
557
+
558
+ ### `lakutata nwjs versions`
559
+
560
+ List the releases of NW.js lakutata runs on, newest first: their date, their Node.js, their Chromium and their builds,
561
+ the latest and the last one running on Windows 7 (`win7`, 0.72.0) marked. It lists the ten latest and the one of
562
+ Windows 7, every release with `--all`. The list of the releases (`https://nwjs.io/versions.json`, or the one of
563
+ `LAKUTATA_NWJS_VERSIONS`) is cached for a day.
564
+
565
+ ### `lakutata nwjs use <version>`
566
+
567
+ Give the application of the current directory its version of NW.js: a version (`0.119.2`), `latest` or `win7`, written
568
+ as a version into the `lakutata.nwjs` of its `package.json`. It writes `nwjs.json` too, the version with its Node.js and
569
+ its Chromium, which the templates' build of the user interface reads to target that Chromium, and tells the systems the
570
+ release runs on. `--download` downloads its sdk flavor for the machine at once.
571
+
572
+ ### `lakutata nwjs run [args...]`
573
+
574
+ Run the compiled application of the current directory in NW.js: it is bundled into `.nwjs/app` for the Node.js of its
575
+ NW.js, with its resources and its native addons made to load in it, then run with the arguments given after `--`
576
+ (`lakutata nwjs run -- --ui=http://localhost:5173`). The command ends with NW.js, and stops it when it is stopped.
577
+
578
+ | Option | |
579
+ |---|---|
580
+ | `--release <version>` | the release of NW.js run (a version, `latest`, `win7`), the one of `lakutata.nwjs` by default |
581
+ | `--flavor <sdk\|normal>` | `sdk` (the default: with the DevTools) or `normal` (the one the installers hold) |
535
582
 
536
583
  ## Migrations
537
584
 
@@ -604,6 +651,8 @@ matches. The names of the commands and options, and the other results and errors
604
651
  | `LAKUTATA_NPM_REGISTRY` | the npm registry of the templates (by default `npm_config_registry`, else `https://registry.npmjs.org`) |
605
652
  | `LAKUTATA_GITHUB_DOWNLOAD` | a GitHub mirror for the `github:` templates (`https://github.com` by default) |
606
653
  | `LAKUTATA_CACHE_DIR` | the cache directory (by default `$XDG_CACHE_HOME/lakutata`, else `~/.cache/lakutata`) |
654
+ | `LAKUTATA_NWJS_MIRROR` | where the runtimes of NW.js are downloaded from (`https://dl.nwjs.io` by default) |
655
+ | `LAKUTATA_NWJS_VERSIONS` | the list of the releases of NW.js (`https://nwjs.io/versions.json` by default) |
607
656
  | `LAKUTATA_LANG` | the language of the tool (`zh-CN`, `zh-TW`, `en`), by default that of the environment |
608
657
 
609
658
  The tool is itself a lakutata application: its commands are the CLI actions of its controllers, served by the
package/README.zh-CN.md CHANGED
@@ -24,7 +24,7 @@ lakutata create --name my-app
24
24
  | `--path <directory>` | 在哪个目录中创建项目目录,默认是当前目录 |
25
25
  | `--init` | 直接在 `--path` 目录中创建项目。这个目录必须已经存在,里面可以有文件:已有的文件会保留(模板中也有的那些会在警告中列出,需要手动合并),只有新写入的文件会填入项目的信息 |
26
26
  | `--description`、`--author`、`--license` | 应用的信息 |
27
- | `--with <features>` | 要启用的模板可选功能,用逗号分隔(`lakutata templates` 会列出):`i18n`、`installer`。在终端里,如果没有给出 `--with` 或 `--yes`,会让你从列表中选择 |
27
+ | `--with <features>` | 要启用的模板可选功能,用逗号分隔(`lakutata templates` 会列出):`i18n`、`installer`、`win7`。在终端里,如果没有给出 `--with` 或 `--yes`,会让你从列表中选择 |
28
28
  | `--package-manager <npm\|pnpm\|yarn\|none>` | 安装依赖所用的包管理器(`none` 表示不安装):默认是 npm,由 pnpm 或 yarn 启动工具时用对应的那个 |
29
29
  | `--no-git` | 不初始化 git 仓库 |
30
30
  | `--yes` | 直接创建项目,不询问可选功能,也不要求确认 |
@@ -34,7 +34,7 @@ lakutata create --name my-service --template service --package-manager pnpm --ye
34
34
  lakutata create --name my-service --template service --with i18n --yes
35
35
  ```
36
36
 
37
- 每个官方模板都有 `i18n` 功能:应用的多语言消息(`lakutata/com/i18n`),放在 `src/locales` 中(`en.json`、`zh-CN.json`),并随代码一起打包。应用按每个请求的语言回复,校验错误也一样(命令行工具和 Electron 应用使用运行环境的语言)。这个功能还会加上 `i18n:check` 和 `i18n:types` 脚本。`cli`、`service` 和 `web-*` 模板还有 `installer` 功能:应用的 `lakutata.installer` 配置,以及制作安装包的脚本(在本机制作,以及在 Docker 中制作 Linux 的安装包);在 `service` 和 `web-*` 模板中,这个功能还包括一个系统服务。
37
+ 每个官方模板都有 `i18n` 功能:应用的多语言消息(`lakutata/com/i18n`),放在 `src/locales` 中(`en.json`、`zh-CN.json`),并随代码一起打包。应用按每个请求的语言回复,校验错误也一样(命令行工具和桌面应用使用运行环境的语言)。这个功能还会加上 `i18n:check` 和 `i18n:types` 脚本。`cli`、`service` 和 `web-*` 模板还有 `installer` 功能:应用的 `lakutata.installer` 配置,以及制作安装包的脚本(在本机制作,以及在 Docker 中制作 Linux 的安装包);在 `service` 和 `web-*` 模板中,这个功能还包括一个系统服务。`nwjs-*` 模板有 `win7` 功能:用 NW.js 0.72.0(最后一个能在 Windows 7、8 和 8.1 上运行的版本)代替模板发布时的版本,并加上制作 32 位 Windows 安装包的脚本。
38
38
 
39
39
  ### `lakutata templates`
40
40
 
@@ -242,12 +242,12 @@ macOS 的可执行文件使用临时签名(ad hoc)。用 Node.js 制作的 W
242
242
  | `productName` | 显示给用户的名称(在安装程序中,以及 Windows 的程序列表中),默认取 `package.json` 的 `productName`,没有时取名称 |
243
243
  | `description`、`maintainer`、`homepage`、`license` | 默认取自 `package.json`(维护者是它的作者) |
244
244
  | `vendor` | 供应商,默认没有(在 Windows 上,发布者是供应商,没有时是维护者) |
245
- | `runtime` | 可执行文件的运行时:`node`(默认)或 `bun`;Electron 应用用 `electron`(见下文) |
246
- | `addToPath` | 把程序加入 PATH(`/usr/bin/<program>`,macOS 上是 `/usr/local/bin/<program>`;Windows 上是机器的 PATH),默认 `true` |
245
+ | `runtime` | 可执行文件的运行时:`node`(默认)或 `bun`;Electron 应用用 `electron`,NW.js 应用用 `nwjs`(见下文) |
246
+ | `addToPath` | 把程序加入 PATH(`/usr/bin/<program>`,macOS 上是 `/usr/local/bin/<program>`;Windows 上是机器的 PATH),默认 `true`(NW.js 应用默认 `false`) |
247
247
  | `service` | `true` 或服务的选项(见下文),默认没有 |
248
248
  | `linux.targets` | glibc 系统上可以是 `deb`、`rpm`、`archlinux`、`tar.gz`(默认 `deb`、`rpm`、`tar.gz`);Alpine(musl)上是 `apk`、`tar.gz` |
249
249
  | `linux.depends`、`linux.recommends`、`linux.section`、`linux.priority` | 依赖和推荐的系统软件包、分类和优先级(deb) |
250
- | `mac.targets` | `pkg`、`tar.gz`(默认两种都制作) |
250
+ | `mac.targets` | `pkg`、`tar.gz`(默认两种都制作);NW.js 应用还可以用 `dmg` |
251
251
  | `win.targets` | `nsis`、`msi`、`zip`(默认全部制作) |
252
252
  | `electron` | Electron 应用的 electron-builder 配置,合并到由这些选项生成的配置之上 |
253
253
 
@@ -313,11 +313,35 @@ Electron 应用(`"runtime": "electron"`)的安装包由 electron-builder 制
313
313
 
314
314
  在 Linux arm64 上,fpm 软件包需要系统中的 fpm(`gem install fpm`、`USE_SYSTEM_FPM=true`),因为 electron-builder 下载的那个是为 x64 构建的。在 Windows arm64 上,NSIS 安装程序用 BCJ 过滤器压缩可执行文件(`ELECTRON_BUILDER_7Z_FILTER`),因为 7-Zip 默认会选用 ARM64 过滤器,而 NSIS 安装程序无法解压用它压缩的文件。
315
315
 
316
+ NW.js 应用(`"runtime": "nwjs"`)的安装包里是它所用 NW.js(`lakutata nwjs use`,见下文)的 normal 版本,以应用的名字命名,应用放在其中:为这个 NW.js 的 Node.js 打包的代码、处理成能在其中加载的原生插件、资源和 NW.js 的清单。Windows 上的可执行文件是 `<name>.exe`,带有应用的图标和版本信息;macOS 上的应用包是 `<productName>.app`,它的 `Info.plist` 给出应用的名称、`appId`、版本和图标(并重新做临时签名)。它的安装包是桌面应用的安装包,默认 Linux 上是 `deb`,macOS 上是 `dmg`,Windows 上是 `nsis`:Windows 的安装程序(`nsis`、`msi`)把应用加到开始菜单和桌面,`dmg` 磁盘映像里是应用和一个指向 /Applications 的链接,`pkg` 安装包把应用装到那里,Linux 的软件包(`deb`、`rpm`)添加应用的桌面入口和图标,并依赖 Chromium 所需的库。`--arch` 为本机以外的架构制作安装包(`ia32`:32 位 Windows)。NW.js 应用不是服务;它的脚本和其他应用一样执行(macOS 上的应用是直接删除的,没有卸载脚本)。
317
+
316
318
  | 命令选项 | |
317
319
  |---|---|
318
320
  | `--target <targets...>` | 要制作的安装包,默认是配置中的那些 |
319
321
  | `--outdir <directory>` | 安装包的输出目录,默认 `dist/installer` |
320
322
  | `--entry`、`--no-minify`、`--external` | 与 `lakutata package exe` 相同 |
323
+ | `--arch <arch>` | NW.js 应用的架构(`x64`、`ia32`、`arm64`),默认是本机的架构 |
324
+
325
+ ## NW.js
326
+
327
+ NW.js 应用(`nwjs-react` 和 `nwjs-vue` 模板)运行在它 `package.json` 中指定的 NW.js 版本里:`"lakutata": {"nwjs": {"version": "0.119.2"}}`。NW.js 的运行时只下载一次到 lakutata 的缓存目录(从 `https://dl.nwjs.io` 下载,或者从 `LAKUTATA_NWJS_MIRROR` 指定的镜像下载),并按其发布版本的校验和核对。lakutata 支持内置 Node.js 为 18.10 或更高版本的 NW.js。
328
+
329
+ ### `lakutata nwjs versions`
330
+
331
+ 列出 lakutata 支持的 NW.js 版本,从新到旧:发布日期、内置的 Node.js 和 Chromium、提供的构建,并标出最新版本和最后一个能在 Windows 7 上运行的版本(`win7`,0.72.0)。默认列出最新的十个版本和 Windows 7 的那个版本,`--all` 列出全部。版本列表(`https://nwjs.io/versions.json`,或者 `LAKUTATA_NWJS_VERSIONS` 指定的列表)缓存一天。
332
+
333
+ ### `lakutata nwjs use <version>`
334
+
335
+ 为当前目录的应用设置 NW.js 版本:某个版本(`0.119.2`)、`latest` 或 `win7`,以具体的版本号写进 `package.json` 的 `lakutata.nwjs`。它同时写入 `nwjs.json`,即这个版本及其内置的 Node.js 和 Chromium,模板里用户界面的构建会读取它,以这个 Chromium 为目标;命令还会给出这个版本能运行的系统。`--download` 立即为本机下载它的 sdk 版本。
336
+
337
+ ### `lakutata nwjs run [args...]`
338
+
339
+ 在 NW.js 中运行当前目录下编译好的应用:应用先被打包到 `.nwjs/app`,以这个 NW.js 的 Node.js 为目标,带上资源和处理成能在其中加载的原生插件,然后带着 `--` 之后的参数运行(`lakutata nwjs run -- --ui=http://localhost:5173`)。NW.js 退出时命令结束;命令被终止时,NW.js 也会随之结束。
340
+
341
+ | 选项 | |
342
+ |---|---|
343
+ | `--release <version>` | 运行的 NW.js 版本(某个版本、`latest`、`win7`),默认是 `lakutata.nwjs` 中的版本 |
344
+ | `--flavor <sdk\|normal>` | `sdk`(默认:带 DevTools)或 `normal`(安装包中的版本) |
321
345
 
322
346
  ## 迁移
323
347
 
@@ -367,6 +391,8 @@ Electron 应用(`"runtime": "electron"`)的安装包由 electron-builder 制
367
391
  | `LAKUTATA_NPM_REGISTRY` | 下载模板的 npm 仓库(默认取 `npm_config_registry`,否则为 `https://registry.npmjs.org`) |
368
392
  | `LAKUTATA_GITHUB_DOWNLOAD` | 下载 `github:` 模板所用的 GitHub 镜像(默认 `https://github.com`) |
369
393
  | `LAKUTATA_CACHE_DIR` | 缓存目录(默认 `$XDG_CACHE_HOME/lakutata`,否则为 `~/.cache/lakutata`) |
394
+ | `LAKUTATA_NWJS_MIRROR` | NW.js 运行时的下载地址(默认 `https://dl.nwjs.io`) |
395
+ | `LAKUTATA_NWJS_VERSIONS` | NW.js 的发布版本列表(默认 `https://nwjs.io/versions.json`) |
370
396
  | `LAKUTATA_LANG` | 工具的语言(`zh-CN`、`zh-TW`、`en`),默认取环境的语言 |
371
397
 
372
398
  这个工具本身也是一个 lakutata 应用:它的命令就是其控制器的命令行动作,由入口的 commander 适配器提供。
@@ -1,21 +1,21 @@
1
+ import { readFileSync } from 'node:fs';
1
2
  import { buildEntrypoints } from 'lakutata/com/entrypoint';
2
3
  import { commanderCLIEntrypoint } from 'lakutata/adapter/commander';
3
4
  import { buildI18nOptions, commanderTranslator } from 'lakutata/com/i18n';
4
- import zhCN from './locales/zh-CN.json' with { type: 'json' };
5
- import zhTW from './locales/zh-TW.json' with { type: 'json' };
6
5
  import { CommandLineController } from './controllers/CommandLineController.js';
7
6
  import { WorkspaceController } from './controllers/WorkspaceController.js';
8
7
  import { PackController } from './controllers/PackController.js';
9
8
  import { MigrationController } from './controllers/MigrationController.js';
10
9
  import { NativeController } from './controllers/NativeController.js';
11
10
  import { FFIController } from './controllers/FFIController.js';
11
+ import { NwjsController } from './controllers/NwjsController.js';
12
12
  import { I18nController } from './controllers/I18nController.js';
13
13
  import { LANGUAGE_VARIABLE, LanguageMiddleware } from './lib/Language.js';
14
14
  import { toolPackage } from './lib/Versions.js';
15
15
  /**
16
16
  * The controllers of the commands of the tool
17
17
  */
18
- export const CONTROLLERS = [CommandLineController, WorkspaceController, PackController, MigrationController, NativeController, FFIController, I18nController];
18
+ export const CONTROLLERS = [CommandLineController, WorkspaceController, PackController, MigrationController, NativeController, FFIController, NwjsController, I18nController];
19
19
  /**
20
20
  * The messages of the tool in the languages besides English (its texts in the code): its help, its prompts
21
21
  */
@@ -24,9 +24,18 @@ export const CONTROLLERS = [CommandLineController, WorkspaceController, PackCont
24
24
  */
25
25
  export const COMMAND_GROUPS = {
26
26
  package: 'Package the compiled application: into one JavaScript file, an executable or its installers',
27
- ffi: 'Generate the classes of the native libraries of @lakutata/ffi from their C headers'
27
+ ffi: 'Generate the classes of the native libraries of @lakutata/ffi from their C headers',
28
+ nwjs: 'Give the application its version of NW.js, run it in NW.js, list the releases of NW.js'
28
29
  };
29
- export const MESSAGES = { 'zh-CN': zhCN, 'zh-TW': zhTW };
30
+ /**
31
+ * The messages of a language, read from its file of the locales (an import of JSON needs the import attributes, which
32
+ * Node.js 18.10 does not read)
33
+ * @param language
34
+ */
35
+ function messagesOf(language) {
36
+ return JSON.parse(readFileSync(new URL(`./locales/${language}.json`, import.meta.url), 'utf8'));
37
+ }
38
+ export const MESSAGES = { 'zh-CN': messagesOf('zh-CN'), 'zh-TW': messagesOf('zh-TW') };
30
39
  /**
31
40
  * The application of the tool
32
41
  */
@@ -0,0 +1,128 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { spawn } from 'node:child_process';
11
+ import { readFileSync, writeFileSync } from 'node:fs';
12
+ import path from 'node:path';
13
+ import { Controller } from 'lakutata/com/entrypoint';
14
+ import { CLIAction } from 'lakutata/decorator/ctrl';
15
+ import { NwjsRunDTO } from '../dtos/NwjsRunDTO.js';
16
+ import { NwjsUseDTO } from '../dtos/NwjsUseDTO.js';
17
+ import { NwjsVersionsDTO } from '../dtos/NwjsVersionsDTO.js';
18
+ import { loadBuilder } from '../lib/Builder.js';
19
+ import { done, step } from '../lib/Output.js';
20
+ /**
21
+ * The last release of NW.js running on Windows 7, 8 and 8.1 (Chromium 109)
22
+ */
23
+ const WINDOWS_7 = '0.72.0';
24
+ /**
25
+ * Whether a version of NW.js is at most another one
26
+ * @param version
27
+ * @param other
28
+ */
29
+ function atMost(version, other) {
30
+ const parts = (value) => value.split('.').map((part) => parseInt(part, 10) || 0);
31
+ const [a, b] = [parts(version), parts(other)];
32
+ for (let index = 0; index < 3; index++)
33
+ if (a[index] !== b[index])
34
+ return (a[index] ?? 0) < (b[index] ?? 0);
35
+ return true;
36
+ }
37
+ /**
38
+ * The systems a release of NW.js runs on, as its users see them
39
+ * @param release
40
+ */
41
+ function systemsOf(release) {
42
+ const windows = atMost(release.version, WINDOWS_7) ? 'Windows 7 or later' : 'Windows 10 or later';
43
+ const mac = release.platforms.includes('osx-arm64') ? 'macOS (Intel, Apple silicon)' : 'macOS (Intel; Apple silicon through Rosetta)';
44
+ const linux = `Linux (${release.platforms.filter((platform) => platform.startsWith('linux-')).map((platform) => platform.slice(6)).join(', ')})`;
45
+ return `${windows}, ${mac}, ${linux}`;
46
+ }
47
+ /**
48
+ * The commands of the applications of NW.js: its releases, the one of the application, the run of the development
49
+ */
50
+ export class NwjsController extends Controller {
51
+ async versions(input) {
52
+ const { nwjsReleases } = await loadBuilder(process.cwd());
53
+ const releases = (await nwjsReleases()).filter((release) => !atMost(release.node, '18.9.99'));
54
+ const shown = input.all ? releases : releases.filter((release, index) => index < 10 || release.version === WINDOWS_7);
55
+ for (const release of shown) {
56
+ const marks = [release === releases[0] ? 'latest' : '', release.version === WINDOWS_7 ? 'win7: the last one running on Windows 7, 8 and 8.1' : ''].filter(Boolean).join(', ');
57
+ step(`${release.version.padEnd(9)} ${release.date.padEnd(11)} Node.js ${release.node.padEnd(8)} Chromium ${release.chromium.split('.')[0]} ${release.platforms.join(' ')}${marks ? ` (${marks})` : ''}`);
58
+ }
59
+ return undefined;
60
+ }
61
+ async use(input) {
62
+ const { nwjsRelease, downloadNwjs } = await loadBuilder(process.cwd());
63
+ const release = await nwjsRelease(input.version);
64
+ const file = path.join(process.cwd(), 'package.json');
65
+ const manifest = JSON.parse(readFileSync(file, 'utf8'));
66
+ manifest.lakutata = { ...manifest.lakutata, nwjs: { ...manifest.lakutata?.nwjs, version: release.version } };
67
+ writeFileSync(file, `${JSON.stringify(manifest, null, 2)}\n`);
68
+ //What the builds of the user interface and of the application are made for
69
+ writeFileSync(path.join(process.cwd(), 'nwjs.json'), `${JSON.stringify({ version: release.version, node: release.node, chromium: release.chromium }, null, 2)}\n`);
70
+ done(`NW.js ${release.version}: Node.js ${release.node}, Chromium ${release.chromium}`);
71
+ step(`Runs on ${systemsOf(release)}`);
72
+ if (input.download) {
73
+ const runtime = await downloadNwjs({ version: release.version, flavor: 'sdk' });
74
+ done(`Downloaded NW.js ${runtime.version} (sdk, ${runtime.platform})`);
75
+ }
76
+ return undefined;
77
+ }
78
+ async run(input) {
79
+ const { stageNwjsApp, downloadNwjs } = await loadBuilder(process.cwd());
80
+ const stage = await stageNwjsApp({ project: process.cwd(), outdir: path.join('.nwjs', 'app'), version: input.release });
81
+ if (stage.addons.rebuilt.length)
82
+ step(`Native addons built for NW.js ${stage.release.version} (${stage.platform}): ${stage.addons.rebuilt.join(', ')}`);
83
+ if (stage.addons.renamed.length)
84
+ step(`Native addons loading the Node.js of NW.js (node.dll): ${stage.addons.renamed.join(', ')}`);
85
+ const runtime = await downloadNwjs({ version: stage.release.version, flavor: input.flavor });
86
+ step(`NW.js ${runtime.version} (${runtime.flavor}, ${runtime.platform}): Node.js ${runtime.node}, Chromium ${runtime.chromium.split('.')[0]}`);
87
+ const code = await new Promise((resolve, reject) => {
88
+ const child = spawn(runtime.executable, [stage.directory, ...input.args ?? []], { stdio: 'inherit' });
89
+ //NW.js ends with the command: at once when the command is stopped by a signal sent to it only (a runner of the
90
+ //scripts), the run then done
91
+ const stop = () => {
92
+ if (child.exitCode === null && child.signalCode === null)
93
+ child.kill();
94
+ };
95
+ const events = ['exit', 'SIGINT', 'SIGTERM', 'SIGHUP'];
96
+ for (const event of events)
97
+ process.once(event, stop);
98
+ child.once('error', reject);
99
+ //Stopped by a signal (Ctrl-C in the terminal): a normal end of the run
100
+ child.once('exit', (exitCode, signal) => {
101
+ for (const event of events)
102
+ process.off(event, stop);
103
+ resolve(signal ? 0 : exitCode ?? 1);
104
+ });
105
+ });
106
+ if (code !== 0)
107
+ throw new Error(`NW.js exited with ${code}`);
108
+ return undefined;
109
+ }
110
+ }
111
+ __decorate([
112
+ CLIAction('nwjs versions', NwjsVersionsDTO, { description: 'List the releases of NW.js lakutata runs on: their Node.js, their Chromium, their systems' }),
113
+ __metadata("design:type", Function),
114
+ __metadata("design:paramtypes", [NwjsVersionsDTO]),
115
+ __metadata("design:returntype", Promise)
116
+ ], NwjsController.prototype, "versions", null);
117
+ __decorate([
118
+ CLIAction('nwjs use <version>', NwjsUseDTO, { description: 'Give the application of the current directory its version of NW.js (lakutata.nwjs), and write its Node.js and its Chromium into nwjs.json' }),
119
+ __metadata("design:type", Function),
120
+ __metadata("design:paramtypes", [NwjsUseDTO]),
121
+ __metadata("design:returntype", Promise)
122
+ ], NwjsController.prototype, "use", null);
123
+ __decorate([
124
+ CLIAction('nwjs run [args...]', NwjsRunDTO, { description: 'Run the compiled application of the current directory in NW.js (the build with its developer tools, by default)' }),
125
+ __metadata("design:type", Function),
126
+ __metadata("design:paramtypes", [NwjsRunDTO]),
127
+ __metadata("design:returntype", Promise)
128
+ ], NwjsController.prototype, "run", null);
@@ -29,7 +29,7 @@ function megabytes(size) {
29
29
  export class PackController extends Controller {
30
30
  async bundle(input) {
31
31
  const { bundleProject } = await loadBuilder(process.cwd());
32
- const result = await bundleProject({ project: process.cwd(), entry: input.entry, outfile: input.outfile, minify: input.minify, external: input.external });
32
+ const result = await bundleProject({ project: process.cwd(), entry: input.entry, outfile: input.outfile, minify: input.minify, external: input.external, node: input.node });
33
33
  done(`${path.relative(process.cwd(), result.outfile)} (${megabytes(result.size)}): node ${path.relative(process.cwd(), result.outfile)}`);
34
34
  //The native addons and the scripts of the workers are next to the bundle, which is distributed with them
35
35
  if (result.nativeDirectory) {
@@ -49,7 +49,7 @@ export class PackController extends Controller {
49
49
  }
50
50
  async executable(input) {
51
51
  const { buildExecutable } = await loadBuilder(process.cwd());
52
- const result = await buildExecutable({ project: process.cwd(), entry: input.entry, outdir: input.outdir, minify: input.minify, external: input.external, runtime: input.runtime, layout: input.layout });
52
+ const result = await buildExecutable({ project: process.cwd(), entry: input.entry, outdir: input.outdir, minify: input.minify, external: input.external, runtime: input.runtime, layout: input.layout, nodeProgram: input.nodeProgram });
53
53
  step(`${result.runtime} embedded`);
54
54
  if (result.native.length)
55
55
  step(result.directory ? `Native addons next to the executable: ${result.native.join(', ')}` : `Native addons embedded, extracted at the first run: ${result.native.join(', ')}`);
@@ -68,12 +68,21 @@ export class PackController extends Controller {
68
68
  }
69
69
  async installer(input) {
70
70
  const { buildInstaller } = await loadBuilder(process.cwd());
71
- const result = await buildInstaller({ project: process.cwd(), targets: input.target, outdir: input.outdir, entry: input.entry, minify: input.minify, external: input.external });
72
- step(`${result.executable.runtime} embedded`);
73
- if (result.executable.native.length)
74
- step(`Native addons: ${result.executable.native.join(', ')}`);
75
- if (result.executable.resources.length)
76
- step(`Resources: ${result.executable.resources.join(', ')}`);
71
+ const result = await buildInstaller({ project: process.cwd(), targets: input.target, outdir: input.outdir, entry: input.entry, minify: input.minify, external: input.external, nodeProgram: input.nodeProgram, arch: input.arch });
72
+ if (result.nwjs) {
73
+ step(`NW.js ${result.nwjs.runtime.version} (${result.nwjs.runtime.platform}): ${path.basename(result.nwjs.directory)}`);
74
+ if (result.nwjs.stage.addons.rebuilt.length)
75
+ step(`Native addons built for NW.js: ${result.nwjs.stage.addons.rebuilt.join(', ')}`);
76
+ if (result.nwjs.stage.addons.renamed.length)
77
+ step(`Native addons loading the Node.js of NW.js (node.dll): ${result.nwjs.stage.addons.renamed.join(', ')}`);
78
+ }
79
+ if (result.executable) {
80
+ step(`${result.executable.runtime} embedded`);
81
+ if (result.executable.native.length)
82
+ step(`Native addons: ${result.executable.native.join(', ')}`);
83
+ if (result.executable.resources.length)
84
+ step(`Resources: ${result.executable.resources.join(', ')}`);
85
+ }
77
86
  for (const warning of result.warnings)
78
87
  warn(warning);
79
88
  for (const file of result.files)
@@ -27,3 +27,7 @@ __decorate([
27
27
  Expect(DTO.Array(DTO.String()).optional().description('The modules left out of the bundle, loaded at run time from a node_modules next to it (the native addons are handled)')),
28
28
  __metadata("design:type", Array)
29
29
  ], BundleDTO.prototype, "external", void 0);
30
+ __decorate([
31
+ Expect(DTO.String().pattern(/^v?\d+(\.\d+){0,2}$/).optional().description('The version of Node.js running the bundle, whose syntax it is written in (18.10 for NW.js 0.70; the version running the command by default)')),
32
+ __metadata("design:type", String)
33
+ ], BundleDTO.prototype, "node", void 0);
@@ -35,3 +35,7 @@ __decorate([
35
35
  Expect(DTO.String().valid('file', 'directory').optional().default('file').description('One file, its native addons and its resources embedded (file, by default), or a directory: the executable and its native addons and resources next to it (directory)')),
36
36
  __metadata("design:type", String)
37
37
  ], ExecutableDTO.prototype, "layout", void 0);
38
+ __decorate([
39
+ Expect(DTO.String().optional().description('The node program embedded in the executable (Node.js 20.12, 21.7 or later): another Node.js than the one running the command, to make the executable from an older Node.js (the bundle is written in the syntax of the node program)')),
40
+ __metadata("design:type", String)
41
+ ], ExecutableDTO.prototype, "nodeProgram", void 0);
@@ -12,7 +12,7 @@ import { Expect } from 'lakutata/decorator/dto';
12
12
  export class InstallerDTO extends DTO {
13
13
  }
14
14
  __decorate([
15
- Expect(DTO.Array(DTO.String()).optional().description('The installers made: deb, rpm, apk, archlinux, tar.gz on Linux, pkg, tar.gz on macOS, nsis, msi, zip on Windows (the lakutata.installer of the package.json by default)')),
15
+ Expect(DTO.Array(DTO.String()).optional().description('The installers made: deb, rpm, apk, archlinux, tar.gz on Linux, pkg, dmg (the applications of NW.js), tar.gz on macOS, nsis, msi, zip on Windows (the lakutata.installer of the package.json by default)')),
16
16
  __metadata("design:type", Array)
17
17
  ], InstallerDTO.prototype, "target", void 0);
18
18
  __decorate([
@@ -31,3 +31,11 @@ __decorate([
31
31
  Expect(DTO.Array(DTO.String()).optional().description('The modules left out of the bundle')),
32
32
  __metadata("design:type", Array)
33
33
  ], InstallerDTO.prototype, "external", void 0);
34
+ __decorate([
35
+ Expect(DTO.String().optional().description('The node program embedded in the executable (Node.js 20.12, 21.7 or later): another Node.js than the one running the command, to make the executable from an older Node.js (the bundle is written in the syntax of the node program)')),
36
+ __metadata("design:type", String)
37
+ ], InstallerDTO.prototype, "nodeProgram", void 0);
38
+ __decorate([
39
+ Expect(DTO.String().valid('x64', 'ia32', 'arm64').optional().description('The architecture of an application of NW.js (the one of this machine by default): ia32 for the 32-bit systems of Windows (Windows 7)')),
40
+ __metadata("design:type", String)
41
+ ], InstallerDTO.prototype, "arch", void 0);
@@ -0,0 +1,25 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { DTO } from 'lakutata';
11
+ import { Expect } from 'lakutata/decorator/dto';
12
+ export class NwjsRunDTO extends DTO {
13
+ }
14
+ __decorate([
15
+ Expect(DTO.Array(DTO.String()).optional().description('The arguments given to the application, after -- (lakutata nwjs run -- --ui=http://localhost:5173)')),
16
+ __metadata("design:type", Array)
17
+ ], NwjsRunDTO.prototype, "args", void 0);
18
+ __decorate([
19
+ Expect(DTO.String().optional().description('The release of NW.js run: a version, latest or win7 (the version of lakutata.nwjs by default)')),
20
+ __metadata("design:type", String)
21
+ ], NwjsRunDTO.prototype, "release", void 0);
22
+ __decorate([
23
+ Expect(DTO.String().valid('sdk', 'normal').optional().default('sdk').description('The flavor of NW.js: sdk (with its developer tools, by default) or normal (the one shipped to the users)')),
24
+ __metadata("design:type", String)
25
+ ], NwjsRunDTO.prototype, "flavor", void 0);
@@ -0,0 +1,21 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { DTO } from 'lakutata';
11
+ import { Expect } from 'lakutata/decorator/dto';
12
+ export class NwjsUseDTO extends DTO {
13
+ }
14
+ __decorate([
15
+ Expect(DTO.String().required().description('The version of NW.js: a version (0.119.2), latest, or win7 (0.72.0, the last one running on Windows 7, 8 and 8.1)')),
16
+ __metadata("design:type", String)
17
+ ], NwjsUseDTO.prototype, "version", void 0);
18
+ __decorate([
19
+ Expect(DTO.Boolean().optional().default(false).description('Download the development build of NW.js (with its developer tools) for this machine now')),
20
+ __metadata("design:type", Boolean)
21
+ ], NwjsUseDTO.prototype, "download", void 0);
@@ -0,0 +1,17 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { DTO } from 'lakutata';
11
+ import { Expect } from 'lakutata/decorator/dto';
12
+ export class NwjsVersionsDTO extends DTO {
13
+ }
14
+ __decorate([
15
+ Expect(DTO.Boolean().optional().default(false).description('List every release lakutata runs on (the latest ten and the one of Windows 7 by default)')),
16
+ __metadata("design:type", Boolean)
17
+ ], NwjsVersionsDTO.prototype, "all", void 0);
@@ -383,7 +383,9 @@ function nativeFiles(name, version, build, packageManager) {
383
383
  name: name,
384
384
  version: version,
385
385
  private: true,
386
- type: 'module',
386
+ //CommonJS: the bundles of the applications are CommonJS and require it, which loads an ES module only on
387
+ //Node.js 20.19, 22.12 and later
388
+ type: 'commonjs',
387
389
  main: 'dist/index.js',
388
390
  types: 'dist/index.d.ts',
389
391
  exports: { '.': { types: './dist/index.d.ts', default: './dist/index.js' } },
@@ -406,7 +408,6 @@ function nativeFiles(name, version, build, packageManager) {
406
408
  ...chosen.files,
407
409
  'src/index.ts': `import {createRequire} from 'node:module'
408
410
  import path from 'node:path'
409
- import {fileURLToPath} from 'node:url'
410
411
 
411
412
  /**
412
413
  * The functions of the addon
@@ -418,7 +419,7 @@ type Binding = {
418
419
  /**
419
420
  * The addon built into build/Release, loaded from the directory of the package
420
421
  */
421
- const binding: Binding = createRequire(import.meta.url)('node-gyp-build')(path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'))
422
+ const binding: Binding = createRequire(__filename)('node-gyp-build')(path.resolve(__dirname, '..'))
422
423
 
423
424
  /**
424
425
  * Greet someone, in ${build === 'rust' ? 'Rust' : 'C++'}
@@ -1,11 +1,20 @@
1
- import { styleText } from 'node:util';
1
+ import util from 'node:util';
2
+ /**
3
+ * The styles of the output, and their codes of the terminals (where util.styleText is missing: before Node.js 20.12)
4
+ */
5
+ const STYLES = { bold: [1, 22], red: [31, 39], green: [32, 39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39] };
2
6
  /**
3
7
  * A text in a style, when the output is a terminal
4
8
  * @param style
5
9
  * @param text
6
10
  */
7
11
  export function styled(style, text) {
8
- return process.stdout.isTTY && !process.env.NO_COLOR ? styleText(style, text) : text;
12
+ if (!process.stdout.isTTY || process.env.NO_COLOR)
13
+ return text;
14
+ //node-compat: util.styleText
15
+ if (typeof util.styleText === 'function')
16
+ return util.styleText(style, text);
17
+ return `\u001b[${STYLES[style][0]}m${text}\u001b[${STYLES[style][1]}m`;
9
18
  }
10
19
  /**
11
20
  * Print a step done
@@ -32,7 +32,9 @@ export const BUILTIN_TEMPLATES = [
32
32
  { name: 'web-vue', description: 'An HTTP API serving a Vue single-page application (Vite)', package: '@lakutata/template-web-vue', features: ['i18n', 'installer'] },
33
33
  { name: 'web-nuxt', description: 'An HTTP API serving a Nuxt application from the same process', package: '@lakutata/template-web-nuxt', features: ['i18n', 'installer'] },
34
34
  { name: 'electron-react', description: 'A desktop application: Electron, its main process serving a React renderer over IPC', package: '@lakutata/template-electron-react', features: ['i18n'] },
35
- { name: 'electron-vue', description: 'A desktop application: Electron, its main process serving a Vue renderer over IPC', package: '@lakutata/template-electron-vue', features: ['i18n'] }
35
+ { name: 'electron-vue', description: 'A desktop application: Electron, its main process serving a Vue renderer over IPC', package: '@lakutata/template-electron-vue', features: ['i18n'] },
36
+ { name: 'nwjs-react', description: 'A desktop application: NW.js, its background script serving a React user interface isolated in a webview', package: '@lakutata/template-nwjs-react', features: ['i18n', 'win7'] },
37
+ { name: 'nwjs-vue', description: 'A desktop application: NW.js, its background script serving a Vue user interface isolated in a webview', package: '@lakutata/template-nwjs-vue', features: ['i18n', 'win7'] }
36
38
  ];
37
39
  /**
38
40
  * How long the catalog is kept, 1 day
@@ -66,7 +66,8 @@ export async function runScript(workspace, script, options = {}) {
66
66
  dependencies.delete(name);
67
67
  return [pkg.name, dependencies];
68
68
  }));
69
- const concurrency = options.parallel ? Math.max(1, selected.length) : Math.max(1, options.concurrency ?? os.availableParallelism());
69
+ //node-compat: os.availableParallelism
70
+ const concurrency = options.parallel ? Math.max(1, selected.length) : Math.max(1, options.concurrency ?? (typeof os.availableParallelism === 'function' ? os.availableParallelism() : os.cpus().length));
70
71
  const width = Math.max(0, ...selected.map((pkg) => pkg.name.length));
71
72
  const done = new Set();
72
73
  //The packages depending on a failed package, not run
@@ -78,7 +78,8 @@
78
78
  "entry": "应用编译后的入口(默认是 package.json 的 main)",
79
79
  "outfile": "打包输出的文件(默认 dist/<名称>.cjs)",
80
80
  "minify": "压缩打包结果",
81
- "external": "不打进包里的模块,运行时从旁边的 node_modules 加载(原生插件会自动处理)"
81
+ "external": "不打进包里的模块,运行时从旁边的 node_modules 加载(原生插件会自动处理)",
82
+ "node": "运行打包结果的 Node.js 版本,打包结果用这个版本支持的语法生成(NW.js 0.70 是 18.10;默认是运行本命令的版本)"
82
83
  }
83
84
  },
84
85
  "exe": {
@@ -89,17 +90,20 @@
89
90
  "minify": "压缩嵌入可执行文件的包",
90
91
  "external": "不打进包里的模块(它们不在可执行文件中,而是从旁边的 node_modules 加载)",
91
92
  "runtime": "嵌入可执行文件的运行时:node(Node.js 的单可执行应用,默认)或 bun(Bun,安装在项目中或系统上)",
92
- "layout": "单个文件,原生插件和资源嵌入其中(file,默认);或一个目录:可执行文件及其旁边的原生插件和资源(directory)"
93
+ "layout": "单个文件,原生插件和资源嵌入其中(file,默认);或一个目录:可执行文件及其旁边的原生插件和资源(directory)",
94
+ "nodeProgram": "嵌入可执行文件的 node 程序(Node.js 20.12、21.7 或更高版本):用另一个 Node.js 代替运行本命令的那个,这样在较旧的 Node.js 上也能生成可执行文件"
93
95
  }
94
96
  },
95
97
  "installer": {
96
98
  "description": "为当前平台生成编译后应用的安装包:安装可执行文件、原生插件和资源,把程序加入 PATH,并注册系统服务",
97
99
  "options": {
98
- "target": "要生成的安装包:Linux 上为 deb、rpm、apk、archlinux、tar.gz,macOS 上为 pkg、tar.gz,Windows 上为 nsis、msi、zip(默认取 package.json 的 lakutata.installer)",
100
+ "target": "要生成的安装包:Linux 上为 deb、rpm、apk、archlinux、tar.gz,macOS 上为 pkg、dmg(NW.js 应用)、tar.gz,Windows 上为 nsis、msi、zip(默认取 package.json 的 lakutata.installer)",
99
101
  "outdir": "安装包所在的目录(默认 dist/installer)",
100
102
  "entry": "应用编译后的入口(默认是 package.json 的 main)",
101
103
  "minify": "压缩嵌入可执行文件的包",
102
- "external": "不打进包里的模块"
104
+ "external": "不打进包里的模块",
105
+ "nodeProgram": "嵌入可执行文件的 node 程序(Node.js 20.12、21.7 或更高版本):用另一个 Node.js 代替运行本命令的那个,这样在较旧的 Node.js 上也能生成可执行文件",
106
+ "arch": "NW.js 应用的架构(默认是本机的架构):32 位 Windows(Windows 7)用 ia32"
103
107
  }
104
108
  }
105
109
  },
@@ -152,6 +156,34 @@
152
156
  }
153
157
  }
154
158
  },
159
+ "nwjs": {
160
+ "description": "为应用指定 NW.js 版本、在 NW.js 里运行应用、列出 NW.js 的版本",
161
+ "versions": {
162
+ "description": "列出 lakutata 能运行的 NW.js 版本:各自的 Node.js、Chromium 和支持的系统",
163
+ "options": {
164
+ "all": "列出所有能运行 lakutata 的版本(默认只列最新的十个和支持 Windows 7 的那个)"
165
+ }
166
+ },
167
+ "use": {
168
+ "description": "给当前目录的应用指定 NW.js 版本(lakutata.nwjs),并把它的 Node.js 和 Chromium 版本写入 nwjs.json",
169
+ "arguments": {
170
+ "version": "NW.js 版本:具体的版本号(0.119.2)、latest,或 win7(0.72.0,最后一个能在 Windows 7、8、8.1 上运行的版本)"
171
+ },
172
+ "options": {
173
+ "download": "现在就为本机下载开发用的 NW.js(带开发者工具)"
174
+ }
175
+ },
176
+ "run": {
177
+ "description": "在 NW.js 里运行当前目录下编译好的应用(默认带开发者工具)",
178
+ "arguments": {
179
+ "args": "传给应用的参数,写在 -- 之后(lakutata nwjs run -- --ui=http://localhost:5173)"
180
+ },
181
+ "options": {
182
+ "release": "运行的 NW.js 版本:具体的版本号、latest 或 win7(默认是 lakutata.nwjs 里的版本)",
183
+ "flavor": "NW.js 的类型:sdk(带开发者工具,默认)或 normal(发布给用户的)"
184
+ }
185
+ }
186
+ },
155
187
  "i18n": {
156
188
  "description": "检查各语言的翻译、声明键名的类型,或添加一种语言",
157
189
  "arguments": {
@@ -78,7 +78,8 @@
78
78
  "entry": "應用程式編譯後的入口(預設是 package.json 的 main)",
79
79
  "outfile": "打包輸出的檔案(預設 dist/<名稱>.cjs)",
80
80
  "minify": "壓縮打包結果",
81
- "external": "不打包進去的模組,執行時從旁邊的 node_modules 載入(原生外掛會自動處理)"
81
+ "external": "不打包進去的模組,執行時從旁邊的 node_modules 載入(原生外掛會自動處理)",
82
+ "node": "執行打包結果的 Node.js 版本,打包結果用這個版本支援的語法產生(NW.js 0.70 是 18.10;預設是執行本命令的版本)"
82
83
  }
83
84
  },
84
85
  "exe": {
@@ -89,17 +90,20 @@
89
90
  "minify": "壓縮嵌入可執行檔的打包結果",
90
91
  "external": "不打包進去的模組(它們不在可執行檔中,而是從旁邊的 node_modules 載入)",
91
92
  "runtime": "嵌入可執行檔的執行環境:node(Node.js 的單一可執行應用程式,預設)或 bun(Bun,安裝在專案中或系統上)",
92
- "layout": "單一檔案,原生外掛程式和資源嵌入其中(file,預設);或一個目錄:可執行檔及其旁邊的原生外掛程式和資源(directory)"
93
+ "layout": "單一檔案,原生外掛程式和資源嵌入其中(file,預設);或一個目錄:可執行檔及其旁邊的原生外掛程式和資源(directory)",
94
+ "nodeProgram": "嵌入可執行檔的 node 程式(Node.js 20.12、21.7 或更新版本):用另一個 Node.js 代替執行本命令的那個,這樣在較舊的 Node.js 上也能產生可執行檔"
93
95
  }
94
96
  },
95
97
  "installer": {
96
98
  "description": "為目前平台產生編譯後應用程式的安裝套件:安裝可執行檔、原生外掛程式和資源,把程式加入 PATH,並註冊系統服務",
97
99
  "options": {
98
- "target": "要產生的安裝套件:Linux 上為 deb、rpm、apk、archlinux、tar.gz,macOS 上為 pkg、tar.gz,Windows 上為 nsis、msi、zip(預設取 package.json 的 lakutata.installer)",
100
+ "target": "要產生的安裝套件:Linux 上為 deb、rpm、apk、archlinux、tar.gz,macOS 上為 pkg、dmg(NW.js 應用程式)、tar.gz,Windows 上為 nsis、msi、zip(預設取 package.json 的 lakutata.installer)",
99
101
  "outdir": "安裝套件所在的目錄(預設 dist/installer)",
100
102
  "entry": "應用程式編譯後的入口(預設是 package.json 的 main)",
101
103
  "minify": "壓縮嵌入可執行檔的打包結果",
102
- "external": "不打包進去的模組"
104
+ "external": "不打包進去的模組",
105
+ "nodeProgram": "嵌入可執行檔的 node 程式(Node.js 20.12、21.7 或更新版本):用另一個 Node.js 代替執行本命令的那個,這樣在較舊的 Node.js 上也能產生可執行檔",
106
+ "arch": "NW.js 應用程式的架構(預設是本機的架構):32 位元 Windows(Windows 7)用 ia32"
103
107
  }
104
108
  }
105
109
  },
@@ -152,6 +156,34 @@
152
156
  }
153
157
  }
154
158
  },
159
+ "nwjs": {
160
+ "description": "為應用程式指定 NW.js 版本、在 NW.js 裡執行應用程式、列出 NW.js 的版本",
161
+ "versions": {
162
+ "description": "列出 lakutata 能執行的 NW.js 版本:各自的 Node.js、Chromium 和支援的系統",
163
+ "options": {
164
+ "all": "列出所有能執行 lakutata 的版本(預設只列最新的十個和支援 Windows 7 的那個)"
165
+ }
166
+ },
167
+ "use": {
168
+ "description": "為目前目錄的應用程式指定 NW.js 版本(lakutata.nwjs),並把它的 Node.js 和 Chromium 版本寫入 nwjs.json",
169
+ "arguments": {
170
+ "version": "NW.js 版本:具體的版本號(0.119.2)、latest,或 win7(0.72.0,最後一個能在 Windows 7、8、8.1 上執行的版本)"
171
+ },
172
+ "options": {
173
+ "download": "現在就為本機下載開發用的 NW.js(帶開發者工具)"
174
+ }
175
+ },
176
+ "run": {
177
+ "description": "在 NW.js 裡執行目前目錄下編譯好的應用程式(預設帶開發者工具)",
178
+ "arguments": {
179
+ "args": "傳給應用程式的參數,寫在 -- 之後(lakutata nwjs run -- --ui=http://localhost:5173)"
180
+ },
181
+ "options": {
182
+ "release": "執行的 NW.js 版本:具體的版本號、latest 或 win7(預設是 lakutata.nwjs 裡的版本)",
183
+ "flavor": "NW.js 的類型:sdk(帶開發者工具,預設)或 normal(發佈給使用者的)"
184
+ }
185
+ }
186
+ },
155
187
  "i18n": {
156
188
  "description": "檢查各語言的翻譯、宣告鍵名的型別,或新增一種語言",
157
189
  "arguments": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lakutata/cli",
3
- "version": "3.1.4",
3
+ "version": "3.1.5",
4
4
  "description": "The command line tool of the lakutata framework: create the projects from the templates, run and version the packages of the workspaces, bundle the applications and make their executables (with @lakutata/builder).",
5
5
  "keywords": [
6
6
  "lakutata",
@@ -37,13 +37,13 @@
37
37
  "test:unit": "npm run compile && node --import ./dist/esm/tests/support/English.js --test \"dist/esm/tests/*.spec.js\""
38
38
  },
39
39
  "dependencies": {
40
- "@inquirer/prompts": "^8.7.2",
41
- "commander": "^15.0.0",
42
- "lakutata": "3.1.4"
40
+ "@inquirer/prompts": "^7.10.1",
41
+ "commander": "^13.1.0",
42
+ "lakutata": "3.1.5"
43
43
  },
44
44
  "peerDependencies": {
45
- "@lakutata/builder": "~3.1.3",
46
- "@lakutata/ffi": "~3.1.2"
45
+ "@lakutata/builder": "~3.1.5",
46
+ "@lakutata/ffi": "~3.1.5"
47
47
  },
48
48
  "peerDependenciesMeta": {
49
49
  "@lakutata/builder": {
@@ -54,11 +54,11 @@
54
54
  }
55
55
  },
56
56
  "devDependencies": {
57
- "@lakutata/builder": "~3.1.3",
58
- "@lakutata/ffi": "~3.1.2"
57
+ "@lakutata/builder": "~3.1.5",
58
+ "@lakutata/ffi": "~3.1.5"
59
59
  },
60
60
  "engines": {
61
- "node": "^22.13.0 || >=24.11.0"
61
+ "node": ">=18.10.0"
62
62
  },
63
63
  "license": "MIT",
64
64
  "files": [