@file-viewer/cli 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.en.md CHANGED
@@ -22,7 +22,9 @@ npx file-viewer-cli@latest add .
22
22
 
23
23
  `file-viewer-cli` is the single-bin `npx` carrier and pins this scoped package at the same version. If `@file-viewer/cli` is already installed locally, run `file-viewer add .` instead.
24
24
 
25
- The wizard selects a framework and validated version, File Viewer release, profile, formats, package manager, and asset directory. It supports Vanilla/Web Component, Vue 3, Vue 2.7, Vue 2.6, React, React Legacy, Svelte, and jQuery.
25
+ The wizard selects a framework and validated version, File Viewer release, profile, formats, package manager, and asset directory. Interactive runs present checkbox-style renderer/format-family rows, preselect and retain everything supplied by the chosen profile, and let users toggle optional capabilities by number or range instead of typing extensions. It supports Vanilla/Web Component, Vue 3, Vue 2.7, Vue 2.6, React, React Legacy, Svelte, and jQuery.
26
+
27
+ New projects use Vite 8. The generated `package.json` declares Node `^20.19.0 || >=22.12.0`, and `dev`/`build` run a version preflight. Unsupported runtimes therefore fail with an actionable upgrade-and-reinstall message instead of an indirect `CustomEvent` exception.
26
28
 
27
29
  ```bash
28
30
  npx file-viewer-cli create my-viewer \
@@ -40,7 +42,7 @@ npx file-viewer-cli create my-viewer \
40
42
 
41
43
  `standard` is the recommended common-format baseline for new projects. The eight existing `@file-viewer/*-full` packages keep their published `preset-all`, API, asset, and format behavior; they are not silently changed to `standard`.
42
44
 
43
- Installing a Full package directly does not automatically add future specialist capabilities. Explicit CLI `--profile full` keeps the matching Full package and adds later opt-ins in the catalog. The current extra opt-ins are DICOM and digital-signature/evidence containers, so the CLI shows their weight and licenses before confirmation. DICOM covers one local DICOM Part 10 file, including multi-frame navigation. It does not provide series assembly, PACS/DICOMweb, MPR, segmentation, diagnosis, or an embedded OHIF application. The signature renderer reports bounded container inspection and cryptographic verification separately from certificate trust, policy, and legal-validity decisions.
45
+ Installing a Full package directly does not automatically add future specialist capabilities. Explicit CLI `--profile full` keeps the matching Full package and adds the later opt-ins marked as Full defaults in the catalog. The current default additions are DICOM and digital-signature/evidence containers, so the CLI shows their weight and licenses before confirmation. The Adobe design renderer remains explicit: add `--formats pat`, `--formats psd`, or `--capabilities design` to install `@file-viewer/renderer-design` and its independent asset pack without changing the frozen 221-extension, 32-pipeline `preset-all` baseline. DICOM covers one local DICOM Part 10 file, including multi-frame navigation. It does not provide series assembly, PACS/DICOMweb, MPR, segmentation, diagnosis, or an embedded OHIF application. The signature renderer reports bounded container inspection and cryptographic verification separately from certificate trust, policy, and legal-validity decisions.
44
46
 
45
47
  ## Configuration, assets, and legacy compatibility
46
48
 
package/README.md CHANGED
@@ -22,7 +22,9 @@ npx file-viewer-cli@latest add .
22
22
 
23
23
  `file-viewer-cli` 是便于 `npx` 自动选择命令的单 bin 入口,并严格依赖同版本的本 scoped 包。项目已经安装 `@file-viewer/cli` 时,直接运行 `file-viewer add .`。
24
24
 
25
- 向导可选择框架及其已校验版本、File Viewer 版本、profile、格式、包管理器和资源目录。支持 Vanilla/Web Component、Vue 3、Vue 2.7、Vue 2.6、React、React Legacy、Svelte 和 jQuery。
25
+ 向导可选择框架及其已校验版本、File Viewer 版本、profile、格式、包管理器和资源目录。交互模式会按 renderer/格式族列出复选项,profile 已包含的能力预先打勾并保持启用;额外能力可用单个编号或范围切换,无需手写扩展名。支持 Vanilla/Web Component、Vue 3、Vue 2.7、Vue 2.6、React、React Legacy、Svelte 和 jQuery。
26
+
27
+ 新建项目使用 Vite 8。生成的 `package.json` 会声明 Node `^20.19.0 || >=22.12.0`,并在 `dev`/`build` 前执行版本检查;不兼容环境会直接给出升级和重新安装依赖的操作提示,而不是以间接的 `CustomEvent` 异常失败。
26
28
 
27
29
  ```bash
28
30
  npx file-viewer-cli create my-viewer \
@@ -40,7 +42,7 @@ npx file-viewer-cli create my-viewer \
40
42
 
41
43
  `standard` 是新项目推荐的常用格式基线。现有八个 `@file-viewer/*-full` 包继续保持已发布的 `preset-all`、API、资产和格式行为,不会被静默改成 `standard`。
42
44
 
43
- 直接安装 Full 包不会自动带入以后新增的专业能力;通过 CLI 明确选择 `--profile full` 时,CLI 会保留对应 Full 包并加入目录中的后续可选能力。当前额外能力是 DICOM 和数字签名/证据容器,因此确认前会显示体积和许可证信息。DICOM 仅预览本地单个 DICOM Part 10 文件及其多帧,不包含 series、PACS/DICOMweb、MPR、分割、诊断或内嵌 OHIF。签名 renderer 仅声明有界容器检查和密码学验证结果,不代替证书信任、政策或法律效力判定。
45
+ 直接安装 Full 包不会自动带入以后新增的专业能力;通过 CLI 明确选择 `--profile full` 时,CLI 会保留对应 Full 包,并加入目录中标记为 Full 默认追加的后续可选能力。当前默认额外能力是 DICOM 和数字签名/证据容器,因此确认前会显示体积和许可证信息。Adobe 设计 renderer 仍需显式选择,例如追加 `--formats pat`、`--formats psd` 或 `--capabilities design`;显式选择会安装 `@file-viewer/renderer-design` 及其独立资产包,但不会改变 `preset-all` 的 221 个扩展名、32 条链路冻结基线。DICOM 仅预览本地单个 DICOM Part 10 文件及其多帧,不包含 series、PACS/DICOMweb、MPR、分割、诊断或内嵌 OHIF。签名 renderer 仅声明有界容器检查和密码学验证结果,不代替证书信任、政策或法律效力判定。
44
46
 
45
47
  ## 配置、资产与旧命令兼容
46
48
 
@@ -2,75 +2,75 @@
2
2
  "schemaVersion": 1,
3
3
  "core": {
4
4
  "packageName": "@file-viewer/core",
5
- "version": "3.0.0"
5
+ "version": "3.0.1"
6
6
  },
7
7
  "frameworks": {
8
8
  "web": {
9
9
  "packageName": "@file-viewer/web",
10
- "version": "3.0.0"
10
+ "version": "3.0.1"
11
11
  },
12
12
  "vue3": {
13
13
  "packageName": "@file-viewer/vue3",
14
- "version": "3.0.0"
14
+ "version": "3.0.1"
15
15
  },
16
16
  "vue2.7": {
17
17
  "packageName": "@file-viewer/vue2.7",
18
- "version": "3.0.0"
18
+ "version": "3.0.1"
19
19
  },
20
20
  "vue2.6": {
21
21
  "packageName": "@file-viewer/vue2.6",
22
- "version": "3.0.0"
22
+ "version": "3.0.1"
23
23
  },
24
24
  "react": {
25
25
  "packageName": "@file-viewer/react",
26
- "version": "3.0.0"
26
+ "version": "3.0.1"
27
27
  },
28
28
  "react-legacy": {
29
29
  "packageName": "@file-viewer/react-legacy",
30
- "version": "3.0.0"
30
+ "version": "3.0.1"
31
31
  },
32
32
  "svelte": {
33
33
  "packageName": "@file-viewer/svelte",
34
- "version": "3.0.0"
34
+ "version": "3.0.1"
35
35
  },
36
36
  "jquery": {
37
37
  "packageName": "@file-viewer/jquery",
38
- "version": "3.0.0"
38
+ "version": "3.0.1"
39
39
  }
40
40
  },
41
41
  "frameworkOverrides": {
42
42
  "full": {
43
43
  "web": {
44
44
  "packageName": "@file-viewer/web-full",
45
- "version": "3.0.0"
45
+ "version": "3.0.1"
46
46
  },
47
47
  "vue3": {
48
48
  "packageName": "@file-viewer/vue3-full",
49
- "version": "3.0.0"
49
+ "version": "3.0.1"
50
50
  },
51
51
  "vue2.7": {
52
52
  "packageName": "@file-viewer/vue2.7-full",
53
- "version": "3.0.0"
53
+ "version": "3.0.1"
54
54
  },
55
55
  "vue2.6": {
56
56
  "packageName": "@file-viewer/vue2.6-full",
57
- "version": "3.0.0"
57
+ "version": "3.0.1"
58
58
  },
59
59
  "react": {
60
60
  "packageName": "@file-viewer/react-full",
61
- "version": "3.0.0"
61
+ "version": "3.0.1"
62
62
  },
63
63
  "react-legacy": {
64
64
  "packageName": "@file-viewer/react-legacy-full",
65
- "version": "3.0.0"
65
+ "version": "3.0.1"
66
66
  },
67
67
  "svelte": {
68
68
  "packageName": "@file-viewer/svelte-full",
69
- "version": "3.0.0"
69
+ "version": "3.0.1"
70
70
  },
71
71
  "jquery": {
72
72
  "packageName": "@file-viewer/jquery-full",
73
- "version": "3.0.0"
73
+ "version": "3.0.1"
74
74
  }
75
75
  }
76
76
  },
@@ -228,7 +228,7 @@
228
228
  {
229
229
  "id": "all",
230
230
  "packageName": "@file-viewer/preset-all",
231
- "version": "3.0.0",
231
+ "version": "3.0.1",
232
232
  "capabilityPackages": [
233
233
  "@file-viewer/renderer-word",
234
234
  "@file-viewer/renderer-ppt",
@@ -241,6 +241,7 @@
241
241
  "@file-viewer/renderer-hangul",
242
242
  "@file-viewer/renderer-typst",
243
243
  "@file-viewer/renderer-archive",
244
+ "@file-viewer/renderer-chm",
244
245
  "@file-viewer/renderer-email",
245
246
  "@file-viewer/renderer-eda",
246
247
  "@file-viewer/renderer-cad",
@@ -266,7 +267,7 @@
266
267
  {
267
268
  "id": "lite",
268
269
  "packageName": "@file-viewer/preset-lite",
269
- "version": "3.0.0",
270
+ "version": "3.0.1",
270
271
  "capabilityPackages": [
271
272
  "@file-viewer/renderer-image",
272
273
  "@file-viewer/renderer-text",
@@ -276,7 +277,7 @@
276
277
  {
277
278
  "id": "standard",
278
279
  "packageName": "@file-viewer/preset-standard",
279
- "version": "3.0.0",
280
+ "version": "3.0.1",
280
281
  "capabilityPackages": [
281
282
  "@file-viewer/capability-pdf-identity-repair",
282
283
  "@file-viewer/capability-pptx-charts",
@@ -294,15 +295,15 @@
294
295
  "assetPackageName": "@file-viewer/assets-standard",
295
296
  "profileManifestSha256": "aa60cba3fc4bb663516fc3be23881aeb3bfaf7039aa4fad9687bc21f8687caec",
296
297
  "estimates": {
297
- "packedClosureBytes": 30408704,
298
- "unpackedClosureBytes": 101711872,
299
- "staticAssetBytes": 24117248
298
+ "packedClosureBytes": 31457280,
299
+ "unpackedClosureBytes": 104857600,
300
+ "staticAssetBytes": 25165824
300
301
  }
301
302
  },
302
303
  {
303
304
  "id": "office",
304
305
  "packageName": "@file-viewer/preset-office",
305
- "version": "3.0.0",
306
+ "version": "3.0.1",
306
307
  "capabilityPackages": [
307
308
  "@file-viewer/renderer-word",
308
309
  "@file-viewer/renderer-ppt",
@@ -318,7 +319,7 @@
318
319
  {
319
320
  "id": "engineering",
320
321
  "packageName": "@file-viewer/preset-engineering",
321
- "version": "3.0.0",
322
+ "version": "3.0.1",
322
323
  "capabilityPackages": [
323
324
  "@file-viewer/renderer-eda",
324
325
  "@file-viewer/renderer-cad",
@@ -331,7 +332,7 @@
331
332
  "legacyFull": {
332
333
  "release": "2.4.0",
333
334
  "policy": "legacy-compatible-frozen",
334
- "baselineSha256": "76e444bfe7ecb2b0689729934d40c7ed741ed4ceff5f7a85e055128709372904",
335
+ "baselineSha256": "1ec679529f081000fedae3f3dda89ba4e25b610a6136a9f7d54556cbc926c566",
335
336
  "excludedFutureCapabilities": [
336
337
  "dicom",
337
338
  "signature"
@@ -406,8 +407,8 @@
406
407
  "copyMode": "capability-pack",
407
408
  "receiptFilename": "file-viewer-assets-model.receipt.json",
408
409
  "notice": "Independent model capability asset pack.",
409
- "packageVersion": "3.0.0",
410
- "installerPackageVersion": "3.0.0"
410
+ "packageVersion": "3.0.1",
411
+ "installerPackageVersion": "3.0.1"
411
412
  },
412
413
  "license": {
413
414
  "spdx": "Apache-2.0",
@@ -418,7 +419,7 @@
418
419
  "engineering",
419
420
  "all"
420
421
  ],
421
- "version": "3.0.0",
422
+ "version": "3.0.1",
422
423
  "activation": {
423
424
  "kind": "renderer-export",
424
425
  "import": "@file-viewer/renderer-3d",
@@ -479,9 +480,9 @@
479
480
  "copyMode": "profile-pack",
480
481
  "receiptFilename": "file-viewer-assets-standard.receipt.json",
481
482
  "notice": "Self-hosted libarchive Worker and WASM.",
482
- "packageVersion": "3.0.0",
483
+ "packageVersion": "3.0.1",
483
484
  "installerPackageName": "@file-viewer/assets-standard",
484
- "installerPackageVersion": "3.0.0"
485
+ "installerPackageVersion": "3.0.1"
485
486
  },
486
487
  "license": {
487
488
  "spdx": "Apache-2.0",
@@ -493,7 +494,7 @@
493
494
  "engineering",
494
495
  "all"
495
496
  ],
496
- "version": "3.0.0",
497
+ "version": "3.0.1",
497
498
  "activation": {
498
499
  "kind": "renderer-export",
499
500
  "import": "@file-viewer/renderer-archive",
@@ -529,8 +530,8 @@
529
530
  "copyMode": "capability-pack",
530
531
  "receiptFilename": "file-viewer-assets-cad.receipt.json",
531
532
  "notice": "Independent cad capability asset pack.",
532
- "packageVersion": "3.0.0",
533
- "installerPackageVersion": "3.0.0"
533
+ "packageVersion": "3.0.1",
534
+ "installerPackageVersion": "3.0.1"
534
535
  },
535
536
  "license": {
536
537
  "spdx": "Apache-2.0",
@@ -541,13 +542,69 @@
541
542
  "engineering",
542
543
  "all"
543
544
  ],
544
- "version": "3.0.0",
545
+ "version": "3.0.1",
545
546
  "activation": {
546
547
  "kind": "renderer-export",
547
548
  "import": "@file-viewer/renderer-cad",
548
549
  "export": "cadRenderer"
549
550
  }
550
551
  },
552
+ {
553
+ "$schema": "../../../ecosystem/capability-manifest.schema.json",
554
+ "schemaVersion": 1,
555
+ "id": "chm",
556
+ "packageName": "@file-viewer/renderer-chm",
557
+ "rendererIds": [
558
+ "chm"
559
+ ],
560
+ "formats": [
561
+ "chm"
562
+ ],
563
+ "assets": {
564
+ "rendererIds": [
565
+ "chm"
566
+ ],
567
+ "packageName": "@file-viewer/assets-chm",
568
+ "installerPackageName": "@file-viewer/assets-chm",
569
+ "bin": "file-viewer-assets-chm",
570
+ "apiExport": "installFileViewerCapabilityAssetPack",
571
+ "target": "public/file-viewer",
572
+ "copyGroups": [
573
+ "chm"
574
+ ],
575
+ "copyMode": "capability-pack",
576
+ "receiptFilename": "file-viewer-assets-chm.receipt.json",
577
+ "notice": "Self-hosted CHM module Worker and Rust/WebAssembly parser runtime.",
578
+ "packageVersion": "3.0.1",
579
+ "installerPackageVersion": "3.0.1"
580
+ },
581
+ "license": {
582
+ "spdx": "Apache-2.0",
583
+ "policy": "permissive",
584
+ "notices": [
585
+ {
586
+ "packageName": "RustChm",
587
+ "spdx": "MIT",
588
+ "notice": "Permissively licensed CHM parser reference; exact source provenance is recorded in THIRD_PARTY_NOTICES.md and rust/NOTICE.md."
589
+ },
590
+ {
591
+ "packageName": "FastChm",
592
+ "spdx": "MIT",
593
+ "notice": "Permissively licensed CHM and LZX reference; exact source provenance is recorded in THIRD_PARTY_NOTICES.md and rust/NOTICE.md."
594
+ }
595
+ ]
596
+ },
597
+ "weight": "heavy",
598
+ "profiles": [
599
+ "all"
600
+ ],
601
+ "version": "3.0.1",
602
+ "activation": {
603
+ "kind": "renderer-export",
604
+ "import": "@file-viewer/renderer-chm",
605
+ "export": "chmRenderer"
606
+ }
607
+ },
551
608
  {
552
609
  "schemaVersion": 1,
553
610
  "id": "data-asset",
@@ -584,8 +641,8 @@
584
641
  "copyMode": "capability-pack",
585
642
  "receiptFilename": "file-viewer-assets-data.receipt.json",
586
643
  "notice": "Independent data capability asset pack.",
587
- "packageVersion": "3.0.0",
588
- "installerPackageVersion": "3.0.0"
644
+ "packageVersion": "3.0.1",
645
+ "installerPackageVersion": "3.0.1"
589
646
  },
590
647
  "license": {
591
648
  "spdx": "Apache-2.0",
@@ -595,13 +652,104 @@
595
652
  "profiles": [
596
653
  "all"
597
654
  ],
598
- "version": "3.0.0",
655
+ "version": "3.0.1",
599
656
  "activation": {
600
657
  "kind": "renderer-export",
601
658
  "import": "@file-viewer/renderer-data",
602
659
  "export": "dataRenderer"
603
660
  }
604
661
  },
662
+ {
663
+ "schemaVersion": 1,
664
+ "id": "design",
665
+ "packageName": "@file-viewer/renderer-design",
666
+ "rendererIds": [
667
+ "photoshop-design",
668
+ "illustrator-pdf-design",
669
+ "indesign-idml-design",
670
+ "indesign-exchange-design",
671
+ "adobe-animate-xfl-design",
672
+ "adobe-xd-design",
673
+ "indesign-native-design",
674
+ "postscript-design",
675
+ "adobe-palette-design",
676
+ "photoshop-resource-design"
677
+ ],
678
+ "formats": [
679
+ "psb",
680
+ "pdd",
681
+ "psdt",
682
+ "psd",
683
+ "ait",
684
+ "ai",
685
+ "idml",
686
+ "icml",
687
+ "idms",
688
+ "inx",
689
+ "fla",
690
+ "xfl",
691
+ "xd",
692
+ "indd",
693
+ "indt",
694
+ "ps",
695
+ "eps",
696
+ "ase",
697
+ "aco",
698
+ "abr",
699
+ "csh",
700
+ "pat",
701
+ "grd",
702
+ "asl"
703
+ ],
704
+ "assets": {
705
+ "rendererIds": [
706
+ "adobe-animate-xfl-design",
707
+ "adobe-palette-design",
708
+ "adobe-xd-design",
709
+ "illustrator-pdf-design",
710
+ "indesign-exchange-design",
711
+ "indesign-idml-design",
712
+ "indesign-native-design",
713
+ "photoshop-design",
714
+ "photoshop-resource-design",
715
+ "postscript-design"
716
+ ],
717
+ "packageName": "@file-viewer/assets-design",
718
+ "installerPackageName": "@file-viewer/assets-design",
719
+ "bin": "file-viewer-assets-design",
720
+ "apiExport": "installFileViewerCapabilityAssetPack",
721
+ "target": "public/file-viewer",
722
+ "copyGroups": [
723
+ "adobe-animate-xfl-design",
724
+ "adobe-palette-design",
725
+ "adobe-xd-design",
726
+ "illustrator-pdf-design",
727
+ "indesign-exchange-design",
728
+ "indesign-idml-design",
729
+ "indesign-native-design",
730
+ "photoshop-design",
731
+ "photoshop-resource-design",
732
+ "postscript-design"
733
+ ],
734
+ "copyMode": "capability-pack",
735
+ "receiptFilename": "file-viewer-assets-design.receipt.json",
736
+ "notice": "Independent design capability asset pack.",
737
+ "packageVersion": "3.0.1",
738
+ "installerPackageVersion": "3.0.1"
739
+ },
740
+ "license": {
741
+ "spdx": "Apache-2.0",
742
+ "policy": "review-required"
743
+ },
744
+ "weight": "heavy",
745
+ "profiles": [],
746
+ "version": "3.0.1",
747
+ "activation": {
748
+ "kind": "renderer-export",
749
+ "import": "@file-viewer/renderer-design",
750
+ "export": "designRenderer"
751
+ }
752
+ },
605
753
  {
606
754
  "$schema": "../../../ecosystem/capability-manifest.schema.json",
607
755
  "schemaVersion": 1,
@@ -695,7 +843,7 @@
695
843
  },
696
844
  "weight": "heavy",
697
845
  "profiles": [],
698
- "version": "3.0.0"
846
+ "version": "3.0.1"
699
847
  },
700
848
  {
701
849
  "$schema": "../../../ecosystem/capability-manifest.schema.json",
@@ -725,7 +873,7 @@
725
873
  "profiles": [
726
874
  "all"
727
875
  ],
728
- "version": "3.0.0",
876
+ "version": "3.0.1",
729
877
  "activation": {
730
878
  "kind": "renderer-export",
731
879
  "import": "@file-viewer/renderer-drawing",
@@ -758,7 +906,7 @@
758
906
  "engineering",
759
907
  "all"
760
908
  ],
761
- "version": "3.0.0",
909
+ "version": "3.0.1",
762
910
  "activation": {
763
911
  "kind": "renderer-export",
764
912
  "import": "@file-viewer/renderer-eda",
@@ -790,7 +938,7 @@
790
938
  "standard",
791
939
  "all"
792
940
  ],
793
- "version": "3.0.0",
941
+ "version": "3.0.1",
794
942
  "activation": {
795
943
  "kind": "renderer-export",
796
944
  "import": "@file-viewer/renderer-email",
@@ -822,7 +970,7 @@
822
970
  "profiles": [
823
971
  "all"
824
972
  ],
825
- "version": "3.0.0",
973
+ "version": "3.0.1",
826
974
  "activation": {
827
975
  "kind": "renderer-export",
828
976
  "import": "@file-viewer/renderer-epub",
@@ -854,7 +1002,7 @@
854
1002
  "engineering",
855
1003
  "all"
856
1004
  ],
857
- "version": "3.0.0",
1005
+ "version": "3.0.1",
858
1006
  "activation": {
859
1007
  "kind": "renderer-export",
860
1008
  "import": "@file-viewer/renderer-geo",
@@ -887,8 +1035,8 @@
887
1035
  "copyMode": "capability-pack",
888
1036
  "receiptFilename": "file-viewer-assets-hangul.receipt.json",
889
1037
  "notice": "Independent hangul capability asset pack.",
890
- "packageVersion": "3.0.0",
891
- "installerPackageVersion": "3.0.0"
1038
+ "packageVersion": "3.0.1",
1039
+ "installerPackageVersion": "3.0.1"
892
1040
  },
893
1041
  "license": {
894
1042
  "spdx": "Apache-2.0",
@@ -899,7 +1047,7 @@
899
1047
  "office",
900
1048
  "all"
901
1049
  ],
902
- "version": "3.0.0",
1050
+ "version": "3.0.1",
903
1051
  "activation": {
904
1052
  "kind": "renderer-export",
905
1053
  "import": "@file-viewer/renderer-hangul",
@@ -943,7 +1091,7 @@
943
1091
  "standard",
944
1092
  "all"
945
1093
  ],
946
- "version": "3.0.0",
1094
+ "version": "3.0.1",
947
1095
  "activation": {
948
1096
  "kind": "renderer-export",
949
1097
  "import": "@file-viewer/renderer-image",
@@ -983,8 +1131,8 @@
983
1131
  "copyMode": "capability-pack",
984
1132
  "receiptFilename": "file-viewer-assets-iwork.receipt.json",
985
1133
  "notice": "Independent iwork capability asset pack.",
986
- "packageVersion": "3.0.0",
987
- "installerPackageVersion": "3.0.0"
1134
+ "packageVersion": "3.0.1",
1135
+ "installerPackageVersion": "3.0.1"
988
1136
  },
989
1137
  "license": {
990
1138
  "spdx": "Apache-2.0",
@@ -995,7 +1143,7 @@
995
1143
  "office",
996
1144
  "all"
997
1145
  ],
998
- "version": "3.0.0",
1146
+ "version": "3.0.1",
999
1147
  "activation": {
1000
1148
  "kind": "renderer-export",
1001
1149
  "import": "@file-viewer/renderer-iwork",
@@ -1038,7 +1186,7 @@
1038
1186
  "standard",
1039
1187
  "all"
1040
1188
  ],
1041
- "version": "3.0.0",
1189
+ "version": "3.0.1",
1042
1190
  "activation": {
1043
1191
  "kind": "renderer-export",
1044
1192
  "import": "@file-viewer/renderer-media",
@@ -1066,7 +1214,7 @@
1066
1214
  "profiles": [
1067
1215
  "all"
1068
1216
  ],
1069
- "version": "3.0.0",
1217
+ "version": "3.0.1",
1070
1218
  "activation": {
1071
1219
  "kind": "renderer-export",
1072
1220
  "import": "@file-viewer/renderer-mindmap",
@@ -1097,7 +1245,7 @@
1097
1245
  "office",
1098
1246
  "all"
1099
1247
  ],
1100
- "version": "3.0.0",
1248
+ "version": "3.0.1",
1101
1249
  "activation": {
1102
1250
  "kind": "renderer-export",
1103
1251
  "import": "@file-viewer/renderer-ofd",
@@ -1129,9 +1277,9 @@
1129
1277
  "copyMode": "profile-pack",
1130
1278
  "receiptFilename": "file-viewer-assets-standard.receipt.json",
1131
1279
  "notice": "PDF.js Worker, CMaps, WASM, standard fonts, and CJK fallback fonts.",
1132
- "packageVersion": "3.0.0",
1280
+ "packageVersion": "3.0.1",
1133
1281
  "installerPackageName": "@file-viewer/assets-standard",
1134
- "installerPackageVersion": "3.0.0"
1282
+ "installerPackageVersion": "3.0.1"
1135
1283
  },
1136
1284
  "license": {
1137
1285
  "spdx": "Apache-2.0",
@@ -1153,7 +1301,7 @@
1153
1301
  "office",
1154
1302
  "all"
1155
1303
  ],
1156
- "version": "3.0.0",
1304
+ "version": "3.0.1",
1157
1305
  "activation": {
1158
1306
  "kind": "renderer-export",
1159
1307
  "import": "@file-viewer/renderer-pdf",
@@ -1187,8 +1335,8 @@
1187
1335
  "copyMode": "capability-pack",
1188
1336
  "receiptFilename": "file-viewer-assets-ppt.receipt.json",
1189
1337
  "notice": "Legacy PPT Worker/WASM runtime with the existing watermark and license boundary.",
1190
- "packageVersion": "3.0.0",
1191
- "installerPackageVersion": "3.0.0"
1338
+ "packageVersion": "3.0.1",
1339
+ "installerPackageVersion": "3.0.1"
1192
1340
  },
1193
1341
  "license": {
1194
1342
  "spdx": "Apache-2.0",
@@ -1199,7 +1347,7 @@
1199
1347
  "office",
1200
1348
  "all"
1201
1349
  ],
1202
- "version": "3.0.0",
1350
+ "version": "3.0.1",
1203
1351
  "activation": {
1204
1352
  "kind": "renderer-export",
1205
1353
  "import": "@file-viewer/renderer-ppt",
@@ -1236,9 +1384,9 @@
1236
1384
  "copyMode": "profile-pack",
1237
1385
  "receiptFilename": "file-viewer-assets-standard.receipt.json",
1238
1386
  "notice": "Native PPTX parsing Worker.",
1239
- "packageVersion": "3.0.0",
1387
+ "packageVersion": "3.0.1",
1240
1388
  "installerPackageName": "@file-viewer/assets-standard",
1241
- "installerPackageVersion": "3.0.0"
1389
+ "installerPackageVersion": "3.0.1"
1242
1390
  },
1243
1391
  "license": {
1244
1392
  "spdx": "Apache-2.0",
@@ -1250,7 +1398,7 @@
1250
1398
  "office",
1251
1399
  "all"
1252
1400
  ],
1253
- "version": "3.0.0",
1401
+ "version": "3.0.1",
1254
1402
  "activation": {
1255
1403
  "kind": "renderer-export",
1256
1404
  "import": "@file-viewer/renderer-pptx",
@@ -1314,7 +1462,7 @@
1314
1462
  },
1315
1463
  "weight": "heavy",
1316
1464
  "profiles": [],
1317
- "version": "3.0.0"
1465
+ "version": "3.0.1"
1318
1466
  },
1319
1467
  {
1320
1468
  "$schema": "../../../ecosystem/capability-manifest.schema.json",
@@ -1355,9 +1503,9 @@
1355
1503
  "copyMode": "profile-pack",
1356
1504
  "receiptFilename": "file-viewer-assets-standard.receipt.json",
1357
1505
  "notice": "Spreadsheet parsing Worker.",
1358
- "packageVersion": "3.0.0",
1506
+ "packageVersion": "3.0.1",
1359
1507
  "installerPackageName": "@file-viewer/assets-standard",
1360
- "installerPackageVersion": "3.0.0"
1508
+ "installerPackageVersion": "3.0.1"
1361
1509
  },
1362
1510
  "license": {
1363
1511
  "spdx": "Apache-2.0",
@@ -1369,7 +1517,7 @@
1369
1517
  "office",
1370
1518
  "all"
1371
1519
  ],
1372
- "version": "3.0.0",
1520
+ "version": "3.0.1",
1373
1521
  "activation": {
1374
1522
  "kind": "renderer-export",
1375
1523
  "import": "@file-viewer/renderer-spreadsheet",
@@ -1446,7 +1594,7 @@
1446
1594
  "standard",
1447
1595
  "all"
1448
1596
  ],
1449
- "version": "3.0.0",
1597
+ "version": "3.0.1",
1450
1598
  "activation": {
1451
1599
  "kind": "renderer-export",
1452
1600
  "import": "@file-viewer/renderer-text",
@@ -1479,8 +1627,8 @@
1479
1627
  "copyMode": "capability-pack",
1480
1628
  "receiptFilename": "file-viewer-assets-typst.receipt.json",
1481
1629
  "notice": "Independent typst capability asset pack.",
1482
- "packageVersion": "3.0.0",
1483
- "installerPackageVersion": "3.0.0"
1630
+ "packageVersion": "3.0.1",
1631
+ "installerPackageVersion": "3.0.1"
1484
1632
  },
1485
1633
  "license": {
1486
1634
  "spdx": "Apache-2.0",
@@ -1490,7 +1638,7 @@
1490
1638
  "profiles": [
1491
1639
  "all"
1492
1640
  ],
1493
- "version": "3.0.0",
1641
+ "version": "3.0.1",
1494
1642
  "activation": {
1495
1643
  "kind": "renderer-export",
1496
1644
  "import": "@file-viewer/renderer-typst",
@@ -1531,9 +1679,9 @@
1531
1679
  "copyMode": "profile-pack",
1532
1680
  "receiptFilename": "file-viewer-assets-standard.receipt.json",
1533
1681
  "notice": "DOCX Worker and its offline ZIP runtime.",
1534
- "packageVersion": "3.0.0",
1682
+ "packageVersion": "3.0.1",
1535
1683
  "installerPackageName": "@file-viewer/assets-standard",
1536
- "installerPackageVersion": "3.0.0"
1684
+ "installerPackageVersion": "3.0.1"
1537
1685
  },
1538
1686
  "license": {
1539
1687
  "spdx": "Apache-2.0",
@@ -1545,7 +1693,7 @@
1545
1693
  "office",
1546
1694
  "all"
1547
1695
  ],
1548
- "version": "3.0.0",
1696
+ "version": "3.0.1",
1549
1697
  "activation": {
1550
1698
  "kind": "renderer-export",
1551
1699
  "import": "@file-viewer/renderer-word",
@@ -1580,8 +1728,8 @@
1580
1728
  "copyMode": "capability-pack",
1581
1729
  "receiptFilename": "file-viewer-assets-wordperfect.receipt.json",
1582
1730
  "notice": "Independent wordperfect capability asset pack.",
1583
- "packageVersion": "3.0.0",
1584
- "installerPackageVersion": "3.0.0"
1731
+ "packageVersion": "3.0.1",
1732
+ "installerPackageVersion": "3.0.1"
1585
1733
  },
1586
1734
  "license": {
1587
1735
  "spdx": "Apache-2.0",
@@ -1592,7 +1740,7 @@
1592
1740
  "office",
1593
1741
  "all"
1594
1742
  ],
1595
- "version": "3.0.0",
1743
+ "version": "3.0.1",
1596
1744
  "activation": {
1597
1745
  "kind": "renderer-export",
1598
1746
  "import": "@file-viewer/renderer-wordperfect",
@@ -1632,7 +1780,7 @@
1632
1780
  "standard",
1633
1781
  "all"
1634
1782
  ],
1635
- "version": "3.0.0"
1783
+ "version": "3.0.1"
1636
1784
  },
1637
1785
  {
1638
1786
  "$schema": "../../../ecosystem/capability-manifest.schema.json",
@@ -1671,7 +1819,7 @@
1671
1819
  "standard",
1672
1820
  "all"
1673
1821
  ],
1674
- "version": "3.0.0"
1822
+ "version": "3.0.1"
1675
1823
  },
1676
1824
  {
1677
1825
  "$schema": "../../../ecosystem/capability-manifest.schema.json",
@@ -1705,7 +1853,7 @@
1705
1853
  "profiles": [
1706
1854
  "all"
1707
1855
  ],
1708
- "version": "3.0.0"
1856
+ "version": "3.0.1"
1709
1857
  },
1710
1858
  {
1711
1859
  "$schema": "../../../ecosystem/capability-manifest.schema.json",
@@ -1742,7 +1890,7 @@
1742
1890
  "profiles": [
1743
1891
  "all"
1744
1892
  ],
1745
- "version": "3.0.0"
1893
+ "version": "3.0.1"
1746
1894
  },
1747
1895
  {
1748
1896
  "$schema": "../../../ecosystem/capability-manifest.schema.json",
@@ -1778,7 +1926,7 @@
1778
1926
  "profiles": [
1779
1927
  "all"
1780
1928
  ],
1781
- "version": "3.0.0"
1929
+ "version": "3.0.1"
1782
1930
  },
1783
1931
  {
1784
1932
  "$schema": "../../../ecosystem/capability-manifest.schema.json",
@@ -1814,7 +1962,7 @@
1814
1962
  "profiles": [
1815
1963
  "all"
1816
1964
  ],
1817
- "version": "3.0.0"
1965
+ "version": "3.0.1"
1818
1966
  },
1819
1967
  {
1820
1968
  "$schema": "../../../ecosystem/capability-manifest.schema.json",
@@ -1857,7 +2005,7 @@
1857
2005
  "profiles": [
1858
2006
  "all"
1859
2007
  ],
1860
- "version": "3.0.0"
2008
+ "version": "3.0.1"
1861
2009
  },
1862
2010
  {
1863
2011
  "$schema": "../../../ecosystem/capability-manifest.schema.json",
@@ -1892,8 +2040,8 @@
1892
2040
  "copyMode": "capability-pack",
1893
2041
  "receiptFilename": "file-viewer-assets-drawing.receipt.json",
1894
2042
  "notice": "Large official diagrams.net runtime; the safe local SVG fallback remains the default without this capability.",
1895
- "packageVersion": "3.0.0",
1896
- "installerPackageVersion": "3.0.0"
2043
+ "packageVersion": "3.0.1",
2044
+ "installerPackageVersion": "3.0.1"
1897
2045
  },
1898
2046
  "license": {
1899
2047
  "spdx": "Apache-2.0",
@@ -1909,11 +2057,11 @@
1909
2057
  "profiles": [
1910
2058
  "all"
1911
2059
  ],
1912
- "version": "3.0.0"
2060
+ "version": "3.0.1"
1913
2061
  }
1914
2062
  ],
1915
2063
  "assetTool": {
1916
2064
  "packageName": "@file-viewer/assets-standard",
1917
- "version": "3.0.0"
2065
+ "version": "3.0.1"
1918
2066
  }
1919
2067
  }
package/dist/cli.js CHANGED
@@ -9,6 +9,7 @@ import { pathToFileURL } from 'node:url';
9
9
  import { spawnSync } from 'node:child_process';
10
10
  import { assertFileViewerProjectAdapterCanWrite, inspectFileViewerProjectAdapter } from './project-adapters.js';
11
11
  import { createFileViewerCarrierCommand, createFileViewerRegistryEnvironment, detectYarnGeneration } from './carrier-command.js';
12
+ import { promptFileViewerCapabilitySelection } from './interactive-selection.js';
12
13
  import { DEFAULT_FILE_VIEWER_CONFIG, createFileViewerInstallPlan, doctorFileViewerProject, detectPackageManager, executeFileViewerPlanStep, initializeFileViewerProject, inferFileViewerLocalAssetBaseUrl, normalizeFileViewerConfig, readFileViewerProjectConfig, updateFileViewerProjectSelection, generateFileViewerIntegrationModule, listFileViewerCapabilities, renderFileViewerCapabilityList, reconcileFileViewerAssetOwners, reconcileFileViewerManagedDependencies, scaffoldFileViewerQuickstart, patchFileViewerApplicationEntry, listFileViewerApplicationEntries, loadFileViewerCliCatalog, normalizeFileViewerRegistryUrl, prepareFileViewerOfflineDirectory, resolveFileViewerOfflinePackages } from './index.js';
13
14
  const primaryHelpCommands = [
14
15
  'create',
@@ -1214,7 +1215,7 @@ async function promptQuickstart(args, existing, inspection) {
1214
1215
  'jquery'
1215
1216
  ];
1216
1217
  const profiles = ['standard', 'lite', 'office', 'engineering', 'all', 'full', 'custom'];
1217
- const fullCatalog = JSON.parse(await readFile(new URL('../catalog/catalog.json', import.meta.url), 'utf8'));
1218
+ const fullCatalog = (await loadFileViewerCliCatalog());
1218
1219
  let framework = args.framework ?? inspection?.framework ?? 'web';
1219
1220
  let profile = args.profile ?? inspection?.detectedProfile ?? 'standard';
1220
1221
  let frameworkVersion = args.frameworkVersion ??
@@ -1313,25 +1314,30 @@ async function promptQuickstart(args, existing, inspection) {
1313
1314
  packageManagerVersion = value;
1314
1315
  }
1315
1316
  else if (step === 6) {
1316
- const value = await askText(messages[args.locale].formats, formats);
1317
+ const value = await promptFileViewerCapabilitySelection({
1318
+ catalog: fullCatalog,
1319
+ profile,
1320
+ locale: args.locale,
1321
+ formats: formats ? [formats] : [],
1322
+ capabilities: capabilities ? [capabilities] : [],
1323
+ question: (prompt) => io.question(prompt),
1324
+ write: (output) => process.stdout.write(output)
1325
+ });
1317
1326
  if (value === null) {
1318
- step -= 1;
1327
+ step = packageManager === 'yarn' ? 5 : 4;
1319
1328
  continue;
1320
1329
  }
1321
- formats = value === '-' ? '' : value;
1330
+ formats = value.formats.join(',');
1331
+ capabilities = value.capabilities.join(',');
1322
1332
  }
1323
1333
  else if (step === 7) {
1324
- const value = await askText(messages[args.locale].capabilities, capabilities);
1325
- if (value === null) {
1326
- step -= 1;
1327
- continue;
1328
- }
1329
- capabilities = value === '-' ? '' : value;
1334
+ step += 1;
1335
+ continue;
1330
1336
  }
1331
1337
  else if (step === 8) {
1332
1338
  const value = await askText(messages[args.locale].assetTarget, assetTarget, false);
1333
1339
  if (value === null) {
1334
- step -= 1;
1340
+ step = 6;
1335
1341
  continue;
1336
1342
  }
1337
1343
  assetTarget = value;
package/dist/index.js CHANGED
@@ -217,10 +217,23 @@ function capabilityForToken(token, catalog) {
217
217
  return exactId;
218
218
  const matches = catalog.capabilities.filter((capability) => capability.rendererIds.includes(token) || capability.formats.includes(token));
219
219
  if (matches.length > 1) {
220
+ const explicitOptIns = matches.filter((capability) => capability.profiles.length === 0);
221
+ if (explicitOptIns.length === 1)
222
+ return explicitOptIns[0];
220
223
  throw new Error(`"${token}" matches multiple capabilities: ${matches.map((item) => item.id).join(', ')}.`);
221
224
  }
222
225
  return matches[0] ?? null;
223
226
  }
227
+ const isLegacyFullCapability = (capability) => capability.profiles.includes('all');
228
+ function selectFullExtraCapabilities(catalog, explicitlySelectedCapabilities) {
229
+ const defaultOptInIds = new Set(catalog.legacyFull?.excludedFutureCapabilities ?? []);
230
+ return [
231
+ ...new Map([
232
+ ...catalog.capabilities.filter((capability) => defaultOptInIds.has(capability.id)),
233
+ ...explicitlySelectedCapabilities.filter((capability) => !isLegacyFullCapability(capability))
234
+ ].map((capability) => [capability.packageName, capability])).values()
235
+ ];
236
+ }
224
237
  export function detectPackageManager(projectRoot) {
225
238
  try {
226
239
  const packageJson = JSON.parse(readFileSync(join(projectRoot, 'package.json'), 'utf8'));
@@ -592,12 +605,7 @@ export async function createFileViewerInstallPlan(configInput, options = {}) {
592
605
  return capability;
593
606
  });
594
607
  const selectedCapabilities = config.profile === 'full'
595
- ? [
596
- ...new Map([
597
- ...catalog.capabilities.filter((capability) => (catalog.legacyFull?.excludedFutureCapabilities ?? []).includes(capability.id)),
598
- ...explicitlySelectedCapabilities.filter((capability) => (catalog.legacyFull?.excludedFutureCapabilities ?? []).includes(capability.id))
599
- ].map((capability) => [capability.packageName, capability])).values()
600
- ]
608
+ ? selectFullExtraCapabilities(catalog, explicitlySelectedCapabilities)
601
609
  : explicitlySelectedCapabilities;
602
610
  const profilePackages = new Set(profile?.capabilityPackages ?? []);
603
611
  const capabilityPackages = [
@@ -620,7 +628,7 @@ export async function createFileViewerInstallPlan(configInput, options = {}) {
620
628
  ])).values()
621
629
  ];
622
630
  const legacyFullCapabilities = config.profile === 'full'
623
- ? catalog.capabilities.filter((capability) => !(catalog.legacyFull?.excludedFutureCapabilities ?? []).includes(capability.id))
631
+ ? catalog.capabilities.filter(isLegacyFullCapability)
624
632
  : [];
625
633
  const reportingCapabilities = [
626
634
  ...new Map([...legacyFullCapabilities, ...activeCapabilities].map((capability) => [
@@ -758,7 +766,12 @@ export async function createFileViewerInstallPlan(configInput, options = {}) {
758
766
  ].sort(),
759
767
  licenseNotices: [...licenseNotices.values()].sort((left, right) => left.packageName.localeCompare(right.packageName)),
760
768
  assetPackages: config.profile === 'full'
761
- ? [config.framework === 'web' ? frameworkEntry.packageName : 'file-viewer-copy-assets']
769
+ ? [
770
+ ...new Set([
771
+ config.framework === 'web' ? frameworkEntry.packageName : 'file-viewer-copy-assets',
772
+ ...assetPackages
773
+ ])
774
+ ]
762
775
  : assetPackages,
763
776
  assetRendererIds,
764
777
  missingAssetRendererIds: [...new Set(missingAssetRendererIds)].sort(),
@@ -1072,6 +1085,21 @@ function selectQuickstartSample(config, catalog) {
1072
1085
  }
1073
1086
  };
1074
1087
  }
1088
+ const quickstartNodeEngine = '^20.19.0 || >=22.12.0';
1089
+ const quickstartNodeGuard = `const [major, minor] = process.versions.node.split('.').map(Number)
1090
+ const supported =
1091
+ (major === 20 && minor >= 19) ||
1092
+ (major === 22 && minor >= 12) ||
1093
+ major > 22
1094
+ if (!supported) {
1095
+ console.error(
1096
+ 'File Viewer quickstart uses Vite 8 and requires Node ${quickstartNodeEngine}; current ' +
1097
+ process.version +
1098
+ '. Upgrade Node, remove node_modules, and reinstall dependencies.'
1099
+ )
1100
+ process.exit(1)
1101
+ }
1102
+ `;
1075
1103
  export async function scaffoldFileViewerQuickstart(projectRoot, input, options = {}) {
1076
1104
  const config = normalizeFileViewerConfig(input);
1077
1105
  const catalog = await loadFileViewerCliCatalog();
@@ -1133,11 +1161,16 @@ export async function scaffoldFileViewerQuickstart(projectRoot, input, options =
1133
1161
  ...(config.packageManager && config.packageManagerVersion
1134
1162
  ? { packageManager: `${config.packageManager}@${config.packageManagerVersion}` }
1135
1163
  : {}),
1136
- scripts: { dev: 'vite', build: 'vite build' },
1164
+ scripts: {
1165
+ dev: 'node ./scripts/check-node.mjs && vite',
1166
+ build: 'node ./scripts/check-node.mjs && vite build'
1167
+ },
1168
+ engines: { node: quickstartNodeEngine },
1137
1169
  dependencies: selectedTemplate.runtimeDependencies,
1138
1170
  devDependencies
1139
1171
  }, null, 2)}\n`
1140
1172
  ],
1173
+ ['scripts/check-node.mjs', quickstartNodeGuard],
1141
1174
  [
1142
1175
  'index.html',
1143
1176
  '<!doctype html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>File Viewer</title></head><body style="margin:0"><div id="app" style="height:100vh"></div><script type="module" src="/src/main.mjs"></script></body></html>\n'
@@ -1329,10 +1362,7 @@ export async function generateFileViewerIntegrationModule(projectRoot, input, op
1329
1362
  return capability;
1330
1363
  });
1331
1364
  const selectedSource = config.profile === 'full'
1332
- ? [
1333
- ...catalog.capabilities.filter((capability) => (catalog.legacyFull?.excludedFutureCapabilities ?? []).includes(capability.id)),
1334
- ...explicit.filter((capability) => (catalog.legacyFull?.excludedFutureCapabilities ?? []).includes(capability.id))
1335
- ]
1365
+ ? selectFullExtraCapabilities(catalog, explicit)
1336
1366
  : explicit;
1337
1367
  const selected = [
1338
1368
  ...new Map(selectedSource.map((capability) => [capability.packageName, capability])).values()
@@ -1440,8 +1470,7 @@ export async function updateFileViewerProjectSelection(projectRoot, tokenInput,
1440
1470
  const field = isCapabilityId ? 'capabilities' : 'formats';
1441
1471
  const values = new Set(config[field]);
1442
1472
  const providedByProfile = Boolean(profile?.capabilityPackages.includes(capability.packageName) ||
1443
- (config.profile === 'full' &&
1444
- !(catalog.legacyFull?.excludedFutureCapabilities ?? []).includes(capability.id)));
1473
+ (config.profile === 'full' && isLegacyFullCapability(capability)));
1445
1474
  if (action === 'remove' && !values.has(token) && providedByProfile) {
1446
1475
  throw new Error(`Cannot remove "${token}" from the fixed ${config.profile} profile; choose custom or another profile.`);
1447
1476
  }
@@ -0,0 +1,55 @@
1
+ import type { FileViewerCapabilityCatalogEntry, FileViewerCliCatalog, FileViewerCliLocale, FileViewerProfile } from './types.js';
2
+ export type FileViewerSelectionGroup = 'formats' | 'enhancements';
3
+ export type FileViewerCapabilitySelectionState = {
4
+ catalog: FileViewerCliCatalog;
5
+ profile: FileViewerProfile;
6
+ selectedCapabilityIds: Set<string>;
7
+ inheritedCapabilityIds: Set<string>;
8
+ unknownFormats: string[];
9
+ unknownCapabilities: string[];
10
+ };
11
+ export declare function createFileViewerCapabilitySelection(input: {
12
+ catalog: FileViewerCliCatalog;
13
+ profile: FileViewerProfile;
14
+ formats?: readonly string[];
15
+ capabilities?: readonly string[];
16
+ }): FileViewerCapabilitySelectionState;
17
+ export type FileViewerCapabilitySelectionRow = {
18
+ index: number;
19
+ capability: FileViewerCapabilityCatalogEntry;
20
+ selected: boolean;
21
+ locked: boolean;
22
+ };
23
+ export declare function listFileViewerCapabilitySelectionRows(state: FileViewerCapabilitySelectionState, group: FileViewerSelectionGroup): FileViewerCapabilitySelectionRow[];
24
+ export declare function renderFileViewerSelectionGroup(state: FileViewerCapabilitySelectionState, group: FileViewerSelectionGroup, locale: FileViewerCliLocale): string;
25
+ type SelectionCommandResult = {
26
+ action: 'confirm' | 'back' | 'cancel';
27
+ changed: false;
28
+ locked: false;
29
+ } | {
30
+ action: 'changed';
31
+ changed: true;
32
+ locked: boolean;
33
+ } | {
34
+ action: 'invalid';
35
+ changed: false;
36
+ locked: false;
37
+ };
38
+ export declare function applyFileViewerSelectionCommand(state: FileViewerCapabilitySelectionState, group: FileViewerSelectionGroup, answer: string): SelectionCommandResult;
39
+ export declare function finalizeFileViewerCapabilitySelection(state: FileViewerCapabilitySelectionState): {
40
+ formats: string[];
41
+ capabilities: string[];
42
+ };
43
+ export declare function promptFileViewerCapabilitySelection(input: {
44
+ catalog: FileViewerCliCatalog;
45
+ profile: FileViewerProfile;
46
+ locale: FileViewerCliLocale;
47
+ formats?: readonly string[];
48
+ capabilities?: readonly string[];
49
+ question: (prompt: string) => Promise<string>;
50
+ write: (output: string) => void;
51
+ }): Promise<{
52
+ formats: string[];
53
+ capabilities: string[];
54
+ } | null>;
55
+ export {};
@@ -0,0 +1,255 @@
1
+ const selectionCopy = {
2
+ en: {
3
+ formats: 'File format families',
4
+ enhancements: 'Optional capabilities without a file extension',
5
+ profile: 'profile',
6
+ heavy: 'heavy',
7
+ review: 'license review',
8
+ noFormats: 'no extension',
9
+ summary: (selected, total, inherited) => `${selected}/${total} enabled; ${inherited} provided by the selected profile`,
10
+ prompt: 'Toggle numbers/ranges (for example 2,5-7); a=all, n=clear extras, b=back, 0=cancel, Enter=confirm: ',
11
+ invalid: 'Enter listed numbers, ranges, a, n, b, 0, or press Enter.',
12
+ locked: 'Profile-provided capabilities stay enabled; only optional rows were changed.',
13
+ cancelled: 'Cancelled without changes.',
14
+ },
15
+ 'zh-CN': {
16
+ formats: '文件格式族',
17
+ enhancements: '无扩展名的可选增强能力',
18
+ profile: '方案内置',
19
+ heavy: '重型',
20
+ review: '需关注许可证',
21
+ noFormats: '无扩展名',
22
+ summary: (selected, total, inherited) => `已启用 ${selected}/${total} 项,其中 ${inherited} 项由当前方案提供`,
23
+ prompt: '输入编号/范围切换(如 2,5-7);a=全选,n=清空额外项,b=返回,0=取消,回车=确认:',
24
+ invalid: '请输入列表中的编号、范围、a、n、b、0,或直接回车确认。',
25
+ locked: '方案内置能力会保持启用,仅切换了可选项。',
26
+ cancelled: '已取消,未修改文件。',
27
+ },
28
+ 'ja-JP': {
29
+ formats: 'ファイル形式ファミリー',
30
+ enhancements: '拡張子を持たないオプション機能',
31
+ profile: 'プロファイル',
32
+ heavy: '重量',
33
+ review: 'ライセンス確認',
34
+ noFormats: '拡張子なし',
35
+ summary: (selected, total, inherited) => `${selected}/${total} 件を有効化(${inherited} 件はプロファイルに含まれます)`,
36
+ prompt: '番号/範囲を切替(例: 2,5-7);a=すべて、n=追加分を解除、b=戻る、0=中止、Enter=確定: ',
37
+ invalid: '表示された番号、範囲、a、n、b、0 を入力するか、Enter で確定してください。',
38
+ locked: 'プロファイルに含まれる機能は有効のままです。オプション項目だけを切り替えました。',
39
+ cancelled: '変更せずにキャンセルしました。',
40
+ },
41
+ 'de-DE': {
42
+ formats: 'Dateiformat-Familien',
43
+ enhancements: 'Optionale Funktionen ohne Dateiendung',
44
+ profile: 'Profil',
45
+ heavy: 'umfangreich',
46
+ review: 'Lizenz prüfen',
47
+ noFormats: 'keine Endung',
48
+ summary: (selected, total, inherited) => `${selected}/${total} aktiviert; ${inherited} durch das Profil bereitgestellt`,
49
+ prompt: 'Nummern/Bereiche umschalten (z. B. 2,5-7); a=alle, n=Extras leeren, b=zurück, 0=abbrechen, Enter=bestätigen: ',
50
+ invalid: 'Geben Sie Nummern, Bereiche, a, n, b oder 0 ein, oder bestätigen Sie mit Enter.',
51
+ locked: 'Profil-Funktionen bleiben aktiviert; nur optionale Einträge wurden geändert.',
52
+ cancelled: 'Ohne Änderungen abgebrochen.',
53
+ },
54
+ };
55
+ const normalizeTokens = (values) => [
56
+ ...new Set(values
57
+ .flatMap((value) => value.split(','))
58
+ .map((value) => value.trim().toLowerCase().replace(/^\./, ''))
59
+ .filter(Boolean)),
60
+ ];
61
+ const capabilityForToken = (token, catalog) => catalog.capabilities.find((capability) => capability.id.toLowerCase() === token ||
62
+ capability.formats.some((format) => format.toLowerCase() === token) ||
63
+ capability.rendererIds.some((rendererId) => rendererId.toLowerCase() === token));
64
+ const profileCapabilityIds = (profile, catalog) => {
65
+ if (profile === 'custom')
66
+ return new Set();
67
+ if (profile === 'full') {
68
+ const excluded = new Set(catalog.legacyFull?.excludedFutureCapabilities ?? []);
69
+ return new Set(catalog.capabilities
70
+ .filter((capability) => !excluded.has(capability.id))
71
+ .map((capability) => capability.id));
72
+ }
73
+ const selectedProfile = catalog.profiles.find((candidate) => candidate.id === profile);
74
+ const packages = new Set(selectedProfile?.capabilityPackages ?? []);
75
+ return new Set(catalog.capabilities
76
+ .filter((capability) => packages.has(capability.packageName))
77
+ .map((capability) => capability.id));
78
+ };
79
+ export function createFileViewerCapabilitySelection(input) {
80
+ const formats = normalizeTokens(input.formats ?? []);
81
+ const capabilities = normalizeTokens(input.capabilities ?? []);
82
+ const inheritedCapabilityIds = profileCapabilityIds(input.profile, input.catalog);
83
+ const selectedCapabilityIds = new Set();
84
+ const unknownFormats = [];
85
+ const unknownCapabilities = [];
86
+ for (const token of formats) {
87
+ const capability = capabilityForToken(token, input.catalog);
88
+ if (capability)
89
+ selectedCapabilityIds.add(capability.id);
90
+ else
91
+ unknownFormats.push(token);
92
+ }
93
+ for (const token of capabilities) {
94
+ const capability = capabilityForToken(token, input.catalog);
95
+ if (capability)
96
+ selectedCapabilityIds.add(capability.id);
97
+ else
98
+ unknownCapabilities.push(token);
99
+ }
100
+ for (const capabilityId of inheritedCapabilityIds)
101
+ selectedCapabilityIds.delete(capabilityId);
102
+ return {
103
+ catalog: input.catalog,
104
+ profile: input.profile,
105
+ selectedCapabilityIds,
106
+ inheritedCapabilityIds,
107
+ unknownFormats,
108
+ unknownCapabilities,
109
+ };
110
+ }
111
+ export function listFileViewerCapabilitySelectionRows(state, group) {
112
+ return state.catalog.capabilities
113
+ .filter((capability) => group === 'formats' ? capability.formats.length > 0 : capability.formats.length === 0)
114
+ .map((capability, index) => ({
115
+ index: index + 1,
116
+ capability,
117
+ selected: state.inheritedCapabilityIds.has(capability.id) ||
118
+ state.selectedCapabilityIds.has(capability.id),
119
+ locked: state.inheritedCapabilityIds.has(capability.id),
120
+ }));
121
+ }
122
+ const acronyms = new Map([
123
+ ['cad', 'CAD'],
124
+ ['dicom', 'DICOM'],
125
+ ['eda', 'EDA'],
126
+ ['epub', 'EPUB'],
127
+ ['html', 'HTML'],
128
+ ['iwork', 'iWork'],
129
+ ['ofd', 'OFD'],
130
+ ['openxml', 'OpenXML'],
131
+ ['pdf', 'PDF'],
132
+ ['ppt', 'PPT'],
133
+ ['pptx', 'PPTX'],
134
+ ['rtf', 'RTF'],
135
+ ['wasm', 'WASM'],
136
+ ['xmind', 'XMind'],
137
+ ['xml', 'XML'],
138
+ ]);
139
+ const capabilityLabel = (id) => id
140
+ .split('-')
141
+ .map((word) => acronyms.get(word) ?? `${word.slice(0, 1).toUpperCase()}${word.slice(1)}`)
142
+ .join(' ');
143
+ const formatSummary = (capability, copy) => {
144
+ if (!capability.formats.length)
145
+ return copy.noFormats;
146
+ const visible = capability.formats.slice(0, 7).map((format) => `.${format}`);
147
+ const remainder = capability.formats.length - visible.length;
148
+ return `${visible.join(' ')}${remainder > 0 ? ` +${remainder}` : ''}`;
149
+ };
150
+ export function renderFileViewerSelectionGroup(state, group, locale) {
151
+ const copy = selectionCopy[locale];
152
+ const rows = listFileViewerCapabilitySelectionRows(state, group);
153
+ const inherited = rows.filter((row) => row.locked).length;
154
+ const selected = rows.filter((row) => row.selected).length;
155
+ const labelWidth = Math.min(34, Math.max(18, ...rows.map((row) => capabilityLabel(row.capability.id).length)));
156
+ const lines = rows.map((row) => {
157
+ const marker = row.locked ? '[✓]' : row.selected ? '[x]' : '[ ]';
158
+ const index = String(row.index).padStart(2, ' ');
159
+ const label = capabilityLabel(row.capability.id).padEnd(labelWidth, ' ');
160
+ const tags = [
161
+ row.locked ? copy.profile : '',
162
+ row.capability.weight === 'heavy' ? copy.heavy : '',
163
+ row.capability.license.policy !== 'permissive' ? copy.review : '',
164
+ ].filter(Boolean);
165
+ return ` ${marker} ${index}. ${label} ${formatSummary(row.capability, copy)}${tags.length ? ` (${tags.join(', ')})` : ''}`;
166
+ });
167
+ return `\n${group === 'formats' ? copy.formats : copy.enhancements}:\n${lines.join('\n')}\n ${copy.summary(selected, rows.length, inherited)}\n`;
168
+ }
169
+ export function applyFileViewerSelectionCommand(state, group, answer) {
170
+ const normalized = answer.trim().toLowerCase();
171
+ if (!normalized)
172
+ return { action: 'confirm', changed: false, locked: false };
173
+ if (normalized === 'b')
174
+ return { action: 'back', changed: false, locked: false };
175
+ if (normalized === '0')
176
+ return { action: 'cancel', changed: false, locked: false };
177
+ const rows = listFileViewerCapabilitySelectionRows(state, group);
178
+ const editable = rows.filter((row) => !row.locked);
179
+ if (normalized === 'a') {
180
+ for (const row of editable)
181
+ state.selectedCapabilityIds.add(row.capability.id);
182
+ return { action: 'changed', changed: true, locked: false };
183
+ }
184
+ if (normalized === 'n') {
185
+ for (const row of editable)
186
+ state.selectedCapabilityIds.delete(row.capability.id);
187
+ return { action: 'changed', changed: true, locked: false };
188
+ }
189
+ const indexes = new Set();
190
+ for (const token of normalized.split(/[\s,]+/).filter(Boolean)) {
191
+ const match = token.match(/^(\d+)(?:-(\d+))?$/);
192
+ if (!match)
193
+ return { action: 'invalid', changed: false, locked: false };
194
+ const start = Number(match[1]);
195
+ const end = Number(match[2] ?? match[1]);
196
+ if (start < 1 || end < start || end > rows.length)
197
+ return { action: 'invalid', changed: false, locked: false };
198
+ for (let index = start; index <= end; index += 1)
199
+ indexes.add(index);
200
+ }
201
+ if (!indexes.size)
202
+ return { action: 'invalid', changed: false, locked: false };
203
+ let locked = false;
204
+ for (const index of indexes) {
205
+ const row = rows[index - 1];
206
+ if (row.locked) {
207
+ locked = true;
208
+ continue;
209
+ }
210
+ if (state.selectedCapabilityIds.has(row.capability.id))
211
+ state.selectedCapabilityIds.delete(row.capability.id);
212
+ else
213
+ state.selectedCapabilityIds.add(row.capability.id);
214
+ }
215
+ return { action: 'changed', changed: true, locked };
216
+ }
217
+ export function finalizeFileViewerCapabilitySelection(state) {
218
+ const selected = state.catalog.capabilities
219
+ .filter((capability) => state.selectedCapabilityIds.has(capability.id))
220
+ .map((capability) => capability.id);
221
+ return {
222
+ formats: [...state.unknownFormats],
223
+ capabilities: [...selected, ...state.unknownCapabilities],
224
+ };
225
+ }
226
+ export async function promptFileViewerCapabilitySelection(input) {
227
+ const copy = selectionCopy[input.locale];
228
+ const state = createFileViewerCapabilitySelection(input);
229
+ const groups = ['formats', 'enhancements'].filter((group) => listFileViewerCapabilitySelectionRows(state, group).length > 0);
230
+ let groupIndex = 0;
231
+ while (groupIndex < groups.length) {
232
+ const group = groups[groupIndex];
233
+ input.write(renderFileViewerSelectionGroup(state, group, input.locale));
234
+ const result = applyFileViewerSelectionCommand(state, group, await input.question(copy.prompt));
235
+ if (result.action === 'cancel')
236
+ throw new Error(copy.cancelled);
237
+ if (result.action === 'back') {
238
+ if (groupIndex === 0)
239
+ return null;
240
+ groupIndex -= 1;
241
+ continue;
242
+ }
243
+ if (result.action === 'invalid') {
244
+ input.write(` ${copy.invalid}\n`);
245
+ continue;
246
+ }
247
+ if (result.action === 'changed') {
248
+ if (result.locked)
249
+ input.write(` ${copy.locked}\n`);
250
+ continue;
251
+ }
252
+ groupIndex += 1;
253
+ }
254
+ return finalizeFileViewerCapabilitySelection(state);
255
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@file-viewer/cli",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Create or integrate a File Viewer project with framework detection, selectable formats, offline packages, and self-hosted assets.",
@@ -58,11 +58,11 @@
58
58
  "LICENSE"
59
59
  ],
60
60
  "dependencies": {
61
- "@file-viewer/asset-installer": "3.0.0"
61
+ "@file-viewer/asset-installer": "3.0.1"
62
62
  },
63
63
  "devDependencies": {
64
- "@file-viewer/assets-standard": "3.0.0",
65
- "@types/node": "^25.9.2",
64
+ "@file-viewer/assets-standard": "3.0.1",
65
+ "@types/node": "^26.4.0",
66
66
  "typescript": "^6.0.3"
67
67
  },
68
68
  "engines": {
@@ -72,7 +72,7 @@
72
72
  "scripts": {
73
73
  "stage-catalog": "node scripts/stage-catalog.mjs",
74
74
  "verify-catalog": "node scripts/stage-catalog.mjs --check",
75
- "build": "node scripts/stage-catalog.mjs && tsc -b tsconfig.json && node ../../../scripts/ensure-node-bin.mjs packages/tools/cli/dist/cli.js packages/tools/cli/dist/copy-assets.js && node --test test/*.test.mjs",
75
+ "build": "node scripts/stage-catalog.mjs && tsc -b tsconfig.json && node ../../build-support/ensure-node-bin.mjs packages/tools/cli/dist/cli.js packages/tools/cli/dist/copy-assets.js && node --test test/*.test.mjs",
76
76
  "type-check": "tsc -b tsconfig.json"
77
77
  }
78
78
  }