chore: remove tracked artifacts
This commit is contained in:
parent
bcf83e3672
commit
4c4b890a23
87
2.txt
87
2.txt
@ -1,87 +0,0 @@
|
|||||||
收到,我先不再改代码。下面是根据本次对话记录整理出来的修改清单(仅基于聊天内容,不查看当前文件;如果某条在中途被回滚/覆盖,已在备注里说明)。
|
|
||||||
|
|
||||||
整体新增/变更汇总(按功能模块)
|
|
||||||
|
|
||||||
1. 底部状态栏 + 保留空行 ✓
|
|
||||||
|
|
||||||
- 新增“永久底部状态栏”概念:最底行显示提示信息,上一行留空;输入行位于其上方。
|
|
||||||
- 左侧文案在输入时为“输入/查看所有指令”,运行时变为“按下Esc停止”。
|
|
||||||
- 右侧显示“当前上下文 0/256k”,且数字>1000时显示 1.1k 格式。
|
|
||||||
- 需要窗口缩放时自适应,不增加新底层显示行。
|
|
||||||
|
|
||||||
2. ESC 取消行为与记录落盘时机
|
|
||||||
|
|
||||||
- 按 Esc 需要立即中断运行:
|
|
||||||
- 若模型思考中:显示“∙ 停止思考”,并在思考内容下方打印红色“已取消本次响应”,上下各留一行空行。
|
|
||||||
- 若工具执行中:立即停止工具执行,工具结果为红色“任务被用户取消”,且不再继续执行工具结果处理。
|
|
||||||
- 数据落盘更细:用户输入后、模型完整输出后(不含工具)、工具调用后、工具结果后都应写入内存+落盘。
|
|
||||||
- 取消时如果输出未完成,未完成内容不入记录。
|
|
||||||
|
|
||||||
3. 工具输出显示
|
|
||||||
|
|
||||||
- “任务被用户取消”不带“└”或“失败:”前缀;左侧对齐。
|
|
||||||
- 工具执行完后输出与下一行 prompt 之间空一行。
|
|
||||||
- “取消响应”也需红色且左侧对齐,上一行留空。
|
|
||||||
|
|
||||||
4. /new 与 /resume token 复位
|
|
||||||
|
|
||||||
- /new 需要把右下角“当前上下文”重置(逻辑同 /resume)。
|
|
||||||
- 修复了 /new 未被识别的问题(与命令菜单注入有关)。
|
|
||||||
|
|
||||||
5. 只读权限提示文案
|
|
||||||
|
|
||||||
- 只读模式提示文案最后一句改为“请告知当前无权限需要用户输入 /allow 切换权限”。
|
|
||||||
- 只读模式下工具结果文案也需更新。
|
|
||||||
|
|
||||||
6. /allow、/model 等“Update”提示清理
|
|
||||||
|
|
||||||
- /allow /model /thinking 等菜单里不显示“Update …”。
|
|
||||||
|
|
||||||
7. /model 交互逻辑
|
|
||||||
|
|
||||||
- 需求最终定为:
|
|
||||||
- 选择模型后,隔一行显示“模型已切换为: xxx”;
|
|
||||||
- 隔一行再显示思考模式选择;
|
|
||||||
- 选择思考模式后,在选项下面隔一行显示“思考模式: xxx”;
|
|
||||||
- 不再要求清除菜单残留(因为清理和状态栏冲突)。
|
|
||||||
|
|
||||||
8. 命令菜单 / 无效指令
|
|
||||||
|
|
||||||
- 当 / 输入无匹配结果:
|
|
||||||
- 菜单显示“无效的指令”(替换 No results found)。
|
|
||||||
- 按 Enter 后不发送给模型,只显示“无效的命令“/app””。
|
|
||||||
|
|
||||||
9. 多模态(图片/视频)
|
|
||||||
|
|
||||||
- 输入路径或拖拽可自动插入蓝色 token [图片 #1] / [视频 #1]。
|
|
||||||
- 删除时 token 作为整体删除。
|
|
||||||
- 最多 9 张图片、1 个视频。
|
|
||||||
- 发送时:文本里包含 [图片 #n] 显示;实际请求使用 image_url/video_url base64 发送。
|
|
||||||
- 识别单引号路径 '/path/to/file.png'。
|
|
||||||
- 修复“只发送文本而未发送真实图片”的问题,最终要求按示例把图片作为 content list 的一部分发送。
|
|
||||||
|
|
||||||
10. 文件编辑工具创建文件
|
|
||||||
|
|
||||||
- 编辑文件时自动创建不存在的文件与目录,不再报错 ENOENT。
|
|
||||||
|
|
||||||
11. 提示信息空行规范
|
|
||||||
|
|
||||||
- 所有提示信息(如“已创建新对话/权限切换/模型切换/思考模式切换”)上下各空一行。
|
|
||||||
- Banner 与 prompt 之间需保持空行。
|
|
||||||
|
|
||||||
12. 思考完成标记
|
|
||||||
|
|
||||||
- 思考完成行使用 ∙ 而不是 ○。
|
|
||||||
- ∙ 行与思考内容整体左移一个空格以对齐工具调用的 • 前缀。
|
|
||||||
|
|
||||||
13. /system.txt 增加模型变量
|
|
||||||
|
|
||||||
- system prompt 里加入当前使用模型(用请求模型名称)。
|
|
||||||
|
|
||||||
14. 取消时错误显示
|
|
||||||
|
|
||||||
- 在思考时按 Esc,不能重复显示思考内容;只显示“停止思考 + 已取消本次响应”。
|
|
||||||
|
|
||||||
15. 运行指令取消空行
|
|
||||||
|
|
||||||
- 工具取消输出行与后续 prompt 之间需空一行。
|
|
||||||
4094
edited_records.txt
4094
edited_records.txt
File diff suppressed because it is too large
Load Diff
423
node_modules/.package-lock.json
generated
vendored
423
node_modules/.package-lock.json
generated
vendored
@ -1,423 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "easyagent",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"lockfileVersion": 3,
|
|
||||||
"requires": true,
|
|
||||||
"packages": {
|
|
||||||
"node_modules/@inquirer/ansi": {
|
|
||||||
"version": "2.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.3.tgz",
|
|
||||||
"integrity": "sha512-g44zhR3NIKVs0zUesa4iMzExmZpLUdTLRMCStqX3GE5NT6VkPcxQGJ+uC8tDgBUC/vB1rUhUd55cOf++4NZcmw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@inquirer/core": {
|
|
||||||
"version": "11.1.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/core/-/core-11.1.5.tgz",
|
|
||||||
"integrity": "sha512-QQPAX+lka8GyLcZ7u7Nb1h6q72iZ/oy0blilC3IB2nSt1Qqxp7akt94Jqhi/DzARuN3Eo9QwJRvtl4tmVe4T5A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@inquirer/ansi": "^2.0.3",
|
|
||||||
"@inquirer/figures": "^2.0.3",
|
|
||||||
"@inquirer/type": "^4.0.3",
|
|
||||||
"cli-width": "^4.1.0",
|
|
||||||
"fast-wrap-ansi": "^0.2.0",
|
|
||||||
"mute-stream": "^3.0.0",
|
|
||||||
"signal-exit": "^4.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@types/node": ">=18"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@types/node": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@inquirer/figures": {
|
|
||||||
"version": "2.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-2.0.3.tgz",
|
|
||||||
"integrity": "sha512-y09iGt3JKoOCBQ3w4YrSJdokcD8ciSlMIWsD+auPu+OZpfxLuyz+gICAQ6GCBOmJJt4KEQGHuZSVff2jiNOy7g==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@inquirer/search": {
|
|
||||||
"version": "4.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/search/-/search-4.1.4.tgz",
|
|
||||||
"integrity": "sha512-9yPTxq7LPmYjrGn3DRuaPuPbmC6u3fiWcsE9ggfLcdgO/ICHYgxq7mEy1yJ39brVvgXhtOtvDVjDh9slJxE4LQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@inquirer/core": "^11.1.5",
|
|
||||||
"@inquirer/figures": "^2.0.3",
|
|
||||||
"@inquirer/type": "^4.0.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@types/node": ">=18"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@types/node": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@inquirer/select": {
|
|
||||||
"version": "5.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/select/-/select-5.1.0.tgz",
|
|
||||||
"integrity": "sha512-OyYbKnchS1u+zRe14LpYrN8S0wH1vD0p2yKISvSsJdH2TpI87fh4eZdWnpdbrGauCRWDph3NwxRmM4Pcm/hx1Q==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@inquirer/ansi": "^2.0.3",
|
|
||||||
"@inquirer/core": "^11.1.5",
|
|
||||||
"@inquirer/figures": "^2.0.3",
|
|
||||||
"@inquirer/type": "^4.0.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@types/node": ">=18"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@types/node": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@inquirer/type": {
|
|
||||||
"version": "4.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.0.3.tgz",
|
|
||||||
"integrity": "sha512-cKZN7qcXOpj1h+1eTTcGDVLaBIHNMT1Rz9JqJP5MnEJ0JhgVWllx7H/tahUp5YEK1qaByH2Itb8wLG/iScD5kw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@types/node": ">=18"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@types/node": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@nodelib/fs.scandir": {
|
|
||||||
"version": "2.1.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
|
||||||
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@nodelib/fs.stat": "2.0.5",
|
|
||||||
"run-parallel": "^1.1.9"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@nodelib/fs.stat": {
|
|
||||||
"version": "2.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
|
|
||||||
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@nodelib/fs.walk": {
|
|
||||||
"version": "1.2.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
|
|
||||||
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@nodelib/fs.scandir": "2.1.5",
|
|
||||||
"fastq": "^1.6.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/braces": {
|
|
||||||
"version": "3.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
|
||||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"fill-range": "^7.1.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/cli-width": {
|
|
||||||
"version": "4.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
|
|
||||||
"integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/diff": {
|
|
||||||
"version": "5.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz",
|
|
||||||
"integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.3.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fast-glob": {
|
|
||||||
"version": "3.3.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
|
|
||||||
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@nodelib/fs.stat": "^2.0.2",
|
|
||||||
"@nodelib/fs.walk": "^1.2.3",
|
|
||||||
"glob-parent": "^5.1.2",
|
|
||||||
"merge2": "^1.3.0",
|
|
||||||
"micromatch": "^4.0.8"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.6.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fast-string-truncated-width": {
|
|
||||||
"version": "3.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz",
|
|
||||||
"integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/fast-string-width": {
|
|
||||||
"version": "3.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz",
|
|
||||||
"integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"fast-string-truncated-width": "^3.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fast-wrap-ansi": {
|
|
||||||
"version": "0.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.0.tgz",
|
|
||||||
"integrity": "sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"fast-string-width": "^3.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fastq": {
|
|
||||||
"version": "1.20.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
|
|
||||||
"integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"reusify": "^1.0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fill-range": {
|
|
||||||
"version": "7.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
|
||||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"to-regex-range": "^5.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/glob-parent": {
|
|
||||||
"version": "5.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
|
||||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"is-glob": "^4.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-extglob": {
|
|
||||||
"version": "2.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
|
||||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-glob": {
|
|
||||||
"version": "4.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
|
||||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"is-extglob": "^2.1.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-number": {
|
|
||||||
"version": "7.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
|
||||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.12.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/merge2": {
|
|
||||||
"version": "1.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
|
||||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/micromatch": {
|
|
||||||
"version": "4.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
|
||||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"braces": "^3.0.3",
|
|
||||||
"picomatch": "^2.3.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mime-db": {
|
|
||||||
"version": "1.52.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
|
||||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mime-types": {
|
|
||||||
"version": "2.1.35",
|
|
||||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
|
||||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"mime-db": "1.52.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/mute-stream": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": "^20.17.0 || >=22.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/picomatch": {
|
|
||||||
"version": "2.3.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
|
||||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.6"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/queue-microtask": {
|
|
||||||
"version": "1.2.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
|
||||||
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "patreon",
|
|
||||||
"url": "https://www.patreon.com/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "consulting",
|
|
||||||
"url": "https://feross.org/support"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/reusify": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"iojs": ">=1.0.0",
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/run-parallel": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "patreon",
|
|
||||||
"url": "https://www.patreon.com/feross"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "consulting",
|
|
||||||
"url": "https://feross.org/support"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"queue-microtask": "^1.2.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/signal-exit": {
|
|
||||||
"version": "4.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
|
||||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/to-regex-range": {
|
|
||||||
"version": "5.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
|
||||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"is-number": "^7.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
22
node_modules/@inquirer/ansi/LICENSE
generated
vendored
22
node_modules/@inquirer/ansi/LICENSE
generated
vendored
@ -1,22 +0,0 @@
|
|||||||
Copyright (c) 2025 Simon Boudrias
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
|
||||||
obtaining a copy of this software and associated documentation
|
|
||||||
files (the "Software"), to deal in the Software without
|
|
||||||
restriction, including without limitation the rights to use,
|
|
||||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
89
node_modules/@inquirer/ansi/README.md
generated
vendored
89
node_modules/@inquirer/ansi/README.md
generated
vendored
@ -1,89 +0,0 @@
|
|||||||
# @inquirer/ansi
|
|
||||||
|
|
||||||
A lightweight package providing ANSI escape sequences for terminal cursor manipulation and screen clearing.
|
|
||||||
|
|
||||||
# Installation
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>npm</th>
|
|
||||||
<th>yarn</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm install @inquirer/ansi
|
|
||||||
```
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
```sh
|
|
||||||
yarn add @inquirer/ansi
|
|
||||||
```
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
import {
|
|
||||||
cursorUp,
|
|
||||||
cursorDown,
|
|
||||||
cursorTo,
|
|
||||||
cursorLeft,
|
|
||||||
cursorHide,
|
|
||||||
cursorShow,
|
|
||||||
eraseLines,
|
|
||||||
} from '@inquirer/ansi';
|
|
||||||
|
|
||||||
// Move cursor up 3 lines
|
|
||||||
process.stdout.write(cursorUp(3));
|
|
||||||
|
|
||||||
// Move cursor to specific position (x: 10, y: 5)
|
|
||||||
process.stdout.write(cursorTo(10, 5));
|
|
||||||
|
|
||||||
// Hide/show cursor
|
|
||||||
process.stdout.write(cursorHide);
|
|
||||||
process.stdout.write(cursorShow);
|
|
||||||
|
|
||||||
// Clear 5 lines
|
|
||||||
process.stdout.write(eraseLines(5));
|
|
||||||
```
|
|
||||||
|
|
||||||
Or when used inside an inquirer prompt:
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { cursorHide } from '@inquirer/ansi';
|
|
||||||
import { createPrompt } from '@inquirer/core';
|
|
||||||
|
|
||||||
export default createPrompt((config, done: (value: void) => void) => {
|
|
||||||
return `Choose an option${cursorHide}`;
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### Cursor Movement
|
|
||||||
|
|
||||||
- **`cursorUp(count?: number)`** - Move cursor up by `count` lines (default: 1)
|
|
||||||
- **`cursorDown(count?: number)`** - Move cursor down by `count` lines (default: 1)
|
|
||||||
- **`cursorTo(x: number, y?: number)`** - Move cursor to position (x, y). If y is omitted, only moves horizontally
|
|
||||||
- **`cursorLeft`** - Move cursor to beginning of line
|
|
||||||
|
|
||||||
### Cursor Visibility
|
|
||||||
|
|
||||||
- **`cursorHide`** - Hide the cursor
|
|
||||||
- **`cursorShow`** - Show the cursor
|
|
||||||
|
|
||||||
### Screen Manipulation
|
|
||||||
|
|
||||||
- **`eraseLines(count: number)`** - Clear `count` lines and position cursor at the beginning of the first cleared line
|
|
||||||
|
|
||||||
# License
|
|
||||||
|
|
||||||
Copyright (c) 2025 Simon Boudrias (twitter: [@vaxilart](https://twitter.com/Vaxilart))<br/>
|
|
||||||
Licensed under the MIT license.
|
|
||||||
14
node_modules/@inquirer/ansi/dist/index.d.ts
generated
vendored
14
node_modules/@inquirer/ansi/dist/index.d.ts
generated
vendored
@ -1,14 +0,0 @@
|
|||||||
/** Move cursor to first column */
|
|
||||||
export declare const cursorLeft: string;
|
|
||||||
/** Hide the cursor */
|
|
||||||
export declare const cursorHide: string;
|
|
||||||
/** Show the cursor */
|
|
||||||
export declare const cursorShow: string;
|
|
||||||
/** Move cursor up by count rows */
|
|
||||||
export declare const cursorUp: (rows?: number) => string;
|
|
||||||
/** Move cursor down by count rows */
|
|
||||||
export declare const cursorDown: (rows?: number) => string;
|
|
||||||
/** Move cursor to position (x, y) */
|
|
||||||
export declare const cursorTo: (x: number, y?: number) => string;
|
|
||||||
/** Erase the specified number of lines above the cursor */
|
|
||||||
export declare const eraseLines: (lines: number) => string;
|
|
||||||
21
node_modules/@inquirer/ansi/dist/index.js
generated
vendored
21
node_modules/@inquirer/ansi/dist/index.js
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
const ESC = '\u001B[';
|
|
||||||
/** Move cursor to first column */
|
|
||||||
export const cursorLeft = ESC + 'G';
|
|
||||||
/** Hide the cursor */
|
|
||||||
export const cursorHide = ESC + '?25l';
|
|
||||||
/** Show the cursor */
|
|
||||||
export const cursorShow = ESC + '?25h';
|
|
||||||
/** Move cursor up by count rows */
|
|
||||||
export const cursorUp = (rows = 1) => (rows > 0 ? `${ESC}${rows}A` : '');
|
|
||||||
/** Move cursor down by count rows */
|
|
||||||
export const cursorDown = (rows = 1) => rows > 0 ? `${ESC}${rows}B` : '';
|
|
||||||
/** Move cursor to position (x, y) */
|
|
||||||
export const cursorTo = (x, y) => {
|
|
||||||
if (typeof y === 'number' && !Number.isNaN(y)) {
|
|
||||||
return `${ESC}${y + 1};${x + 1}H`;
|
|
||||||
}
|
|
||||||
return `${ESC}${x + 1}G`;
|
|
||||||
};
|
|
||||||
const eraseLine = ESC + '2K';
|
|
||||||
/** Erase the specified number of lines above the cursor */
|
|
||||||
export const eraseLines = (lines) => lines > 0 ? (eraseLine + cursorUp(1)).repeat(lines - 1) + eraseLine + cursorLeft : '';
|
|
||||||
78
node_modules/@inquirer/ansi/package.json
generated
vendored
78
node_modules/@inquirer/ansi/package.json
generated
vendored
@ -1,78 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@inquirer/ansi",
|
|
||||||
"version": "2.0.3",
|
|
||||||
"keywords": [
|
|
||||||
"ansi",
|
|
||||||
"answer",
|
|
||||||
"answers",
|
|
||||||
"ask",
|
|
||||||
"base",
|
|
||||||
"cli",
|
|
||||||
"command",
|
|
||||||
"command-line",
|
|
||||||
"confirm",
|
|
||||||
"enquirer",
|
|
||||||
"generate",
|
|
||||||
"generator",
|
|
||||||
"hyper",
|
|
||||||
"input",
|
|
||||||
"inquire",
|
|
||||||
"inquirer",
|
|
||||||
"interface",
|
|
||||||
"iterm",
|
|
||||||
"javascript",
|
|
||||||
"menu",
|
|
||||||
"node",
|
|
||||||
"nodejs",
|
|
||||||
"prompt",
|
|
||||||
"promptly",
|
|
||||||
"prompts",
|
|
||||||
"question",
|
|
||||||
"readline",
|
|
||||||
"scaffold",
|
|
||||||
"scaffolder",
|
|
||||||
"scaffolding",
|
|
||||||
"stdin",
|
|
||||||
"stdout",
|
|
||||||
"terminal",
|
|
||||||
"tty",
|
|
||||||
"ui",
|
|
||||||
"yeoman",
|
|
||||||
"yo",
|
|
||||||
"zsh"
|
|
||||||
],
|
|
||||||
"homepage": "https://github.com/SBoudrias/Inquirer.js/blob/main/packages/ansi/README.md",
|
|
||||||
"license": "MIT",
|
|
||||||
"author": "Simon Boudrias <admin@simonboudrias.com>",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/SBoudrias/Inquirer.js.git"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"type": "module",
|
|
||||||
"sideEffects": false,
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"default": "./dist/index.js"
|
|
||||||
},
|
|
||||||
"./package.json": "./package.json"
|
|
||||||
},
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"tsc": "tsc"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"typescript": "^5.9.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
|
|
||||||
},
|
|
||||||
"main": "./dist/index.js",
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"gitHead": "99d00a9adc53be8b7edf5926b2ec4ba0b792f68f"
|
|
||||||
}
|
|
||||||
22
node_modules/@inquirer/core/LICENSE
generated
vendored
22
node_modules/@inquirer/core/LICENSE
generated
vendored
@ -1,22 +0,0 @@
|
|||||||
Copyright (c) 2025 Simon Boudrias
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
|
||||||
obtaining a copy of this software and associated documentation
|
|
||||||
files (the "Software"), to deal in the Software without
|
|
||||||
restriction, including without limitation the rights to use,
|
|
||||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
383
node_modules/@inquirer/core/README.md
generated
vendored
383
node_modules/@inquirer/core/README.md
generated
vendored
@ -1,383 +0,0 @@
|
|||||||
# `@inquirer/core`
|
|
||||||
|
|
||||||
The `@inquirer/core` package is the library enabling the creation of Inquirer prompts.
|
|
||||||
|
|
||||||
It aims to implements a lightweight API similar to React hooks - but without JSX.
|
|
||||||
|
|
||||||
# Installation
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>npm</th>
|
|
||||||
<th>yarn</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm install @inquirer/core
|
|
||||||
```
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
```sh
|
|
||||||
yarn add @inquirer/core
|
|
||||||
```
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
# Usage
|
|
||||||
|
|
||||||
## Basic concept
|
|
||||||
|
|
||||||
Visual terminal apps are at their core strings rendered onto the terminal.
|
|
||||||
|
|
||||||
The most basic prompt is a function returning a string that'll be rendered in the terminal. This function will run every time the prompt state change, and the new returned string will replace the previously rendered one. The prompt cursor appears after the string.
|
|
||||||
|
|
||||||
Wrapping the rendering function with `createPrompt()` will setup the rendering layer, inject the state management utilities, and wait until the `done` callback is called.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { createPrompt } from '@inquirer/core';
|
|
||||||
|
|
||||||
const input = createPrompt((config, done) => {
|
|
||||||
// Implement logic
|
|
||||||
|
|
||||||
return '? My question';
|
|
||||||
});
|
|
||||||
|
|
||||||
// And it is then called as
|
|
||||||
const answer = await input({
|
|
||||||
/* config */
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Hooks
|
|
||||||
|
|
||||||
State management and user interactions are handled through hooks. Hooks are common [within the React ecosystem](https://react.dev/reference/react/hooks), and Inquirer reimplement the common ones.
|
|
||||||
|
|
||||||
### State hook
|
|
||||||
|
|
||||||
State lets a component “remember” information like user input. For example, an input prompt can use state to store the input value, while a list prompt can use state to track the cursor index.
|
|
||||||
|
|
||||||
`useState` declares a state variable that you can update directly.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { createPrompt, useState } from '@inquirer/core';
|
|
||||||
|
|
||||||
const input = createPrompt((config, done) => {
|
|
||||||
const [index, setIndex] = useState(0);
|
|
||||||
|
|
||||||
// ...
|
|
||||||
```
|
|
||||||
|
|
||||||
### Keypress hook
|
|
||||||
|
|
||||||
Almost all prompts need to react to user actions. In a terminal, this is done through typing.
|
|
||||||
|
|
||||||
`useKeypress` allows you to react to keypress events, and access the prompt line.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const input = createPrompt((config, done) => {
|
|
||||||
useKeypress((key) => {
|
|
||||||
if (key.name === 'enter') {
|
|
||||||
done(answer);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// ...
|
|
||||||
```
|
|
||||||
|
|
||||||
Behind the scenes, Inquirer prompts are wrappers around [readlines](https://nodejs.org/api/readline.html). Aside the keypress event object, the hook also pass the active readline instance to the event handler.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const input = createPrompt((config, done) => {
|
|
||||||
useKeypress((key, readline) => {
|
|
||||||
setValue(readline.line);
|
|
||||||
});
|
|
||||||
|
|
||||||
// ...
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ref hook
|
|
||||||
|
|
||||||
Refs let a prompt hold some information that isn’t used for rendering, like a class instance or a timeout ID. Unlike with state, updating a ref does not re-render your prompt. Refs are an “escape hatch” from the rendering paradigm.
|
|
||||||
|
|
||||||
`useRef` declares a ref. You can hold any value in it, but most often it’s used to hold a timeout ID.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const input = createPrompt((config, done) => {
|
|
||||||
const timeout = useRef(null);
|
|
||||||
|
|
||||||
// ...
|
|
||||||
```
|
|
||||||
|
|
||||||
### Effect Hook
|
|
||||||
|
|
||||||
Effects let a prompt connect to and synchronize with external systems. This includes dealing with network or animations.
|
|
||||||
|
|
||||||
`useEffect` connects a component to an external system.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const chat = createPrompt((config, done) => {
|
|
||||||
useEffect(() => {
|
|
||||||
const connection = createConnection(roomId);
|
|
||||||
connection.connect();
|
|
||||||
return () => connection.disconnect();
|
|
||||||
}, [roomId]);
|
|
||||||
|
|
||||||
// ...
|
|
||||||
```
|
|
||||||
|
|
||||||
### Performance hook
|
|
||||||
|
|
||||||
A common way to optimize re-rendering performance is to skip unnecessary work. For example, you can tell Inquirer to reuse a cached calculation or to skip a re-render if the data has not changed since the previous render.
|
|
||||||
|
|
||||||
`useMemo` lets you cache the result of an expensive calculation.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const todoSelect = createPrompt((config, done) => {
|
|
||||||
const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
|
|
||||||
|
|
||||||
// ...
|
|
||||||
```
|
|
||||||
|
|
||||||
### Rendering hooks
|
|
||||||
|
|
||||||
#### Prefix / loading
|
|
||||||
|
|
||||||
All default prompts, and most custom ones, uses a prefix at the beginning of the prompt line. This helps visually delineate different questions, and provides a convenient area to render a loading spinner.
|
|
||||||
|
|
||||||
`usePrefix` is a built-in hook to do this.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const input = createPrompt((config, done) => {
|
|
||||||
const prefix = usePrefix({ status });
|
|
||||||
|
|
||||||
return `${prefix} My question`;
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Pagination
|
|
||||||
|
|
||||||
When looping through a long list of options (like in the `select` prompt), paginating the results appearing on the screen at once can be necessary. The `usePagination` hook is the utility used within the `select` and `checkbox` prompts to cycle through the list of options.
|
|
||||||
|
|
||||||
Pagination works by taking in the list of options and returning a subset of the rendered items that fit within the page. The hook takes in a few options. It needs a list of options (`items`), and a `pageSize` which is the number of lines to be rendered. The `active` index is the index of the currently selected/selectable item. The `loop` option is a boolean that indicates if the list should loop around when reaching the end: this is the default behavior. The pagination hook renders items only as necessary, so it takes a function that can render an item at an index, including an `active` state, called `renderItem`.
|
|
||||||
|
|
||||||
```js
|
|
||||||
export default createPrompt((config, done) => {
|
|
||||||
const [active, setActive] = useState(0);
|
|
||||||
|
|
||||||
const allChoices = config.choices.map((choice) => choice.name);
|
|
||||||
|
|
||||||
const page = usePagination({
|
|
||||||
items: allChoices,
|
|
||||||
active: active,
|
|
||||||
renderItem: ({ item, index, isActive }) => `${isActive ? ">" : " "}${index}. ${item.toString()}`
|
|
||||||
pageSize: config.pageSize,
|
|
||||||
loop: config.loop,
|
|
||||||
});
|
|
||||||
|
|
||||||
return `... ${page}`;
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## `createPrompt()` API
|
|
||||||
|
|
||||||
As we saw earlier, the rendering function should return a string, and eventually call `done` to close the prompt and return the answer.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const input = createPrompt((config, done) => {
|
|
||||||
const [value, setValue] = useState();
|
|
||||||
|
|
||||||
useKeypress((key, readline) => {
|
|
||||||
if (key.name === 'enter') {
|
|
||||||
done(answer);
|
|
||||||
} else {
|
|
||||||
setValue(readline.line);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return `? ${config.message} ${value}`;
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
The rendering function can also return a tuple of 2 string (`[string, string]`.) The first string represents the prompt. The second one is content to render under the prompt, like an error message. The text input cursor will appear after the first string.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const number = createPrompt((config, done) => {
|
|
||||||
// Add some logic here
|
|
||||||
|
|
||||||
return [`? My question ${input}`, `! The input must be a number`];
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
### Typescript
|
|
||||||
|
|
||||||
If using typescript, `createPrompt` takes 2 generic arguments.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
// createPrompt<Value, Config>
|
|
||||||
const input = createPrompt<string, { message: string }>(// ...
|
|
||||||
```
|
|
||||||
|
|
||||||
The first one is the type of the resolved value
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const answer: string = await input();
|
|
||||||
```
|
|
||||||
|
|
||||||
The second one is the type of the prompt config; in other words the interface the created prompt will provide to users.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const answer = await input({
|
|
||||||
message: 'My question',
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Key utilities
|
|
||||||
|
|
||||||
Listening for keypress events inside an inquirer prompt is a very common pattern. To ease this, we export a few utility functions taking in the keypress event object and return a boolean:
|
|
||||||
|
|
||||||
- `isEnterKey()`
|
|
||||||
- `isBackspaceKey()`
|
|
||||||
- `isSpaceKey()`
|
|
||||||
- `isUpKey()` - Note: this utility will handle vim and emacs keybindings (up, `k`, and `ctrl+p`)
|
|
||||||
- `isDownKey()` - Note: this utility will handle vim and emacs keybindings (down, `j`, and `ctrl+n`)
|
|
||||||
- `isNumberKey()` one of 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
|
|
||||||
|
|
||||||
## Theming
|
|
||||||
|
|
||||||
Theming utilities will allow you to expose customization of the prompt style. Inquirer also has a few standard theme values shared across all the official prompts.
|
|
||||||
|
|
||||||
To allow standard customization:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { createPrompt, usePrefix, makeTheme, type Theme } from '@inquirer/core';
|
|
||||||
import type { PartialDeep } from '@inquirer/type';
|
|
||||||
|
|
||||||
type PromptConfig = {
|
|
||||||
theme?: PartialDeep<Theme>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createPrompt<string, PromptConfig>((config, done) => {
|
|
||||||
const theme = makeTheme(config.theme);
|
|
||||||
|
|
||||||
const prefix = usePrefix({ status, theme });
|
|
||||||
|
|
||||||
return `${prefix} ${theme.style.highlight('hello')}`;
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
To setup a custom theme:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { createPrompt, makeTheme, type Theme } from '@inquirer/core';
|
|
||||||
import type { PartialDeep } from '@inquirer/type';
|
|
||||||
|
|
||||||
type PromptTheme = {};
|
|
||||||
|
|
||||||
const promptTheme: PromptTheme = {
|
|
||||||
icon: '!',
|
|
||||||
};
|
|
||||||
|
|
||||||
type PromptConfig = {
|
|
||||||
theme?: PartialDeep<Theme<PromptTheme>>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createPrompt<string, PromptConfig>((config, done) => {
|
|
||||||
const theme = makeTheme(promptTheme, config.theme);
|
|
||||||
|
|
||||||
const prefix = usePrefix({ status, theme });
|
|
||||||
|
|
||||||
return `${prefix} ${theme.icon}`;
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
The [default theme keys cover](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/core/src/lib/theme.ts):
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type DefaultTheme = {
|
|
||||||
prefix: string | { idle: string; done: string };
|
|
||||||
spinner: {
|
|
||||||
interval: number;
|
|
||||||
frames: string[];
|
|
||||||
};
|
|
||||||
style: {
|
|
||||||
answer: (text: string) => string;
|
|
||||||
message: (text: string, status: 'idle' | 'done' | 'loading') => string;
|
|
||||||
error: (text: string) => string;
|
|
||||||
defaultAnswer: (text: string) => string;
|
|
||||||
help: (text: string) => string;
|
|
||||||
highlight: (text: string) => string;
|
|
||||||
key: (text: string) => string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
# Examples
|
|
||||||
|
|
||||||
You can refer to any `@inquirer/prompts` prompts for real examples:
|
|
||||||
|
|
||||||
- [Confirm Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/confirm/src/index.ts)
|
|
||||||
- [Input Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/input/src/index.ts)
|
|
||||||
- [Password Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/password/src/index.ts)
|
|
||||||
- [Editor Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/editor/src/index.ts)
|
|
||||||
- [Select Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/select/src/index.ts)
|
|
||||||
- [Checkbox Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/checkbox/src/index.ts)
|
|
||||||
- [Rawlist Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/rawlist/src/index.ts)
|
|
||||||
- [Expand Prompt](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/expand/src/index.ts)
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import { styleText } from 'node:util';
|
|
||||||
import {
|
|
||||||
createPrompt,
|
|
||||||
useState,
|
|
||||||
useKeypress,
|
|
||||||
isEnterKey,
|
|
||||||
usePrefix,
|
|
||||||
type Status,
|
|
||||||
} from '@inquirer/core';
|
|
||||||
|
|
||||||
const confirm = createPrompt<boolean, { message: string; default?: boolean }>(
|
|
||||||
(config, done) => {
|
|
||||||
const [status, setStatus] = useState<Status>('idle');
|
|
||||||
const [value, setValue] = useState('');
|
|
||||||
const prefix = usePrefix({});
|
|
||||||
|
|
||||||
useKeypress((key, rl) => {
|
|
||||||
if (isEnterKey(key)) {
|
|
||||||
const answer = value ? /^y(es)?/i.test(value) : config.default !== false;
|
|
||||||
setValue(answer ? 'yes' : 'no');
|
|
||||||
setStatus('done');
|
|
||||||
done(answer);
|
|
||||||
} else {
|
|
||||||
setValue(rl.line);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let formattedValue = value;
|
|
||||||
let defaultValue = '';
|
|
||||||
if (status === 'done') {
|
|
||||||
formattedValue = styleText('cyan', value);
|
|
||||||
} else {
|
|
||||||
defaultValue = styleText('dim', config.default === false ? ' (y/N)' : ' (Y/n)');
|
|
||||||
}
|
|
||||||
|
|
||||||
const message = styleText('bold', config.message);
|
|
||||||
return `${prefix} ${message}${defaultValue} ${formattedValue}`;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Which then can be used like this:
|
|
||||||
*/
|
|
||||||
const answer = await confirm({ message: 'Do you want to continue?' });
|
|
||||||
```
|
|
||||||
|
|
||||||
# License
|
|
||||||
|
|
||||||
Copyright (c) 2023 Simon Boudrias (twitter: [@vaxilart](https://twitter.com/Vaxilart))<br/>
|
|
||||||
Licensed under the MIT license.
|
|
||||||
13
node_modules/@inquirer/core/dist/index.d.ts
generated
vendored
13
node_modules/@inquirer/core/dist/index.d.ts
generated
vendored
@ -1,13 +0,0 @@
|
|||||||
export { isUpKey, isDownKey, isSpaceKey, isBackspaceKey, isTabKey, isNumberKey, isEnterKey, isShiftKey, type KeypressEvent, type Keybinding, } from './lib/key.ts';
|
|
||||||
export * from './lib/errors.ts';
|
|
||||||
export { usePrefix } from './lib/use-prefix.ts';
|
|
||||||
export { useState } from './lib/use-state.ts';
|
|
||||||
export { useEffect } from './lib/use-effect.ts';
|
|
||||||
export { useMemo } from './lib/use-memo.ts';
|
|
||||||
export { useRef } from './lib/use-ref.ts';
|
|
||||||
export { useKeypress } from './lib/use-keypress.ts';
|
|
||||||
export { makeTheme } from './lib/make-theme.ts';
|
|
||||||
export type { Theme, Status } from './lib/theme.ts';
|
|
||||||
export { usePagination } from './lib/pagination/use-pagination.ts';
|
|
||||||
export { createPrompt } from './lib/create-prompt.ts';
|
|
||||||
export { Separator } from './lib/Separator.ts';
|
|
||||||
12
node_modules/@inquirer/core/dist/index.js
generated
vendored
12
node_modules/@inquirer/core/dist/index.js
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
export { isUpKey, isDownKey, isSpaceKey, isBackspaceKey, isTabKey, isNumberKey, isEnterKey, isShiftKey, } from "./lib/key.js";
|
|
||||||
export * from "./lib/errors.js";
|
|
||||||
export { usePrefix } from "./lib/use-prefix.js";
|
|
||||||
export { useState } from "./lib/use-state.js";
|
|
||||||
export { useEffect } from "./lib/use-effect.js";
|
|
||||||
export { useMemo } from "./lib/use-memo.js";
|
|
||||||
export { useRef } from "./lib/use-ref.js";
|
|
||||||
export { useKeypress } from "./lib/use-keypress.js";
|
|
||||||
export { makeTheme } from "./lib/make-theme.js";
|
|
||||||
export { usePagination } from "./lib/pagination/use-pagination.js";
|
|
||||||
export { createPrompt } from "./lib/create-prompt.js";
|
|
||||||
export { Separator } from "./lib/Separator.js";
|
|
||||||
10
node_modules/@inquirer/core/dist/lib/Separator.d.ts
generated
vendored
10
node_modules/@inquirer/core/dist/lib/Separator.d.ts
generated
vendored
@ -1,10 +0,0 @@
|
|||||||
/**
|
|
||||||
* Separator object
|
|
||||||
* Used to space/separate choices group
|
|
||||||
*/
|
|
||||||
export declare class Separator {
|
|
||||||
readonly separator: string;
|
|
||||||
readonly type: string;
|
|
||||||
constructor(separator?: string);
|
|
||||||
static isSeparator(choice: unknown): choice is Separator;
|
|
||||||
}
|
|
||||||
21
node_modules/@inquirer/core/dist/lib/Separator.js
generated
vendored
21
node_modules/@inquirer/core/dist/lib/Separator.js
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
import { styleText } from 'node:util';
|
|
||||||
import figures from '@inquirer/figures';
|
|
||||||
/**
|
|
||||||
* Separator object
|
|
||||||
* Used to space/separate choices group
|
|
||||||
*/
|
|
||||||
export class Separator {
|
|
||||||
separator = styleText('dim', Array.from({ length: 15 }).join(figures.line));
|
|
||||||
type = 'separator';
|
|
||||||
constructor(separator) {
|
|
||||||
if (separator) {
|
|
||||||
this.separator = separator;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static isSeparator(choice) {
|
|
||||||
return Boolean(choice &&
|
|
||||||
typeof choice === 'object' &&
|
|
||||||
'type' in choice &&
|
|
||||||
choice.type === 'separator');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
4
node_modules/@inquirer/core/dist/lib/create-prompt.d.ts
generated
vendored
4
node_modules/@inquirer/core/dist/lib/create-prompt.d.ts
generated
vendored
@ -1,4 +0,0 @@
|
|||||||
import { type Prompt, type Prettify } from '@inquirer/type';
|
|
||||||
type ViewFunction<Value, Config> = (config: Prettify<Config>, done: (value: Value) => void) => string | [string, string | undefined];
|
|
||||||
export declare function createPrompt<Value, Config>(view: ViewFunction<Value, Config>): Prompt<Value, Config>;
|
|
||||||
export {};
|
|
||||||
143
node_modules/@inquirer/core/dist/lib/create-prompt.js
generated
vendored
143
node_modules/@inquirer/core/dist/lib/create-prompt.js
generated
vendored
@ -1,143 +0,0 @@
|
|||||||
import * as readline from 'node:readline';
|
|
||||||
import { AsyncResource } from 'node:async_hooks';
|
|
||||||
import MuteStream from 'mute-stream';
|
|
||||||
import { onExit as onSignalExit } from 'signal-exit';
|
|
||||||
import ScreenManager from "./screen-manager.js";
|
|
||||||
import { PromisePolyfill } from "./promise-polyfill.js";
|
|
||||||
import { withHooks, effectScheduler } from "./hook-engine.js";
|
|
||||||
import { AbortPromptError, CancelPromptError, ExitPromptError } from "./errors.js";
|
|
||||||
// Capture the real setImmediate at module load time so it works even when test
|
|
||||||
// frameworks mock timers with vi.useFakeTimers() or similar.
|
|
||||||
const nativeSetImmediate = globalThis.setImmediate;
|
|
||||||
function getCallSites() {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
||||||
const _prepareStackTrace = Error.prepareStackTrace;
|
|
||||||
let result = [];
|
|
||||||
try {
|
|
||||||
Error.prepareStackTrace = (_, callSites) => {
|
|
||||||
const callSitesWithoutCurrent = callSites.slice(1);
|
|
||||||
result = callSitesWithoutCurrent;
|
|
||||||
return callSitesWithoutCurrent;
|
|
||||||
};
|
|
||||||
// oxlint-disable-next-line no-unused-expressions
|
|
||||||
new Error().stack;
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
// An error will occur if the Node flag --frozen-intrinsics is used.
|
|
||||||
// https://nodejs.org/api/cli.html#--frozen-intrinsics
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
Error.prepareStackTrace = _prepareStackTrace;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
export function createPrompt(view) {
|
|
||||||
const callSites = getCallSites();
|
|
||||||
const prompt = (config, context = {}) => {
|
|
||||||
// Default `input` to stdin
|
|
||||||
const { input = process.stdin, signal } = context;
|
|
||||||
const cleanups = new Set();
|
|
||||||
// Add mute capabilities to the output
|
|
||||||
const output = new MuteStream();
|
|
||||||
output.pipe(context.output ?? process.stdout);
|
|
||||||
// Pre-mute the output so that readline doesn't echo stale keystrokes
|
|
||||||
// to the terminal before the first render. ScreenManager will unmute/mute
|
|
||||||
// the output around each render call as needed.
|
|
||||||
output.mute();
|
|
||||||
const rl = readline.createInterface({
|
|
||||||
terminal: true,
|
|
||||||
input,
|
|
||||||
output,
|
|
||||||
});
|
|
||||||
const screen = new ScreenManager(rl);
|
|
||||||
const { promise, resolve, reject } = PromisePolyfill.withResolver();
|
|
||||||
const cancel = () => reject(new CancelPromptError());
|
|
||||||
if (signal) {
|
|
||||||
const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
|
|
||||||
if (signal.aborted) {
|
|
||||||
abort();
|
|
||||||
return Object.assign(promise, { cancel });
|
|
||||||
}
|
|
||||||
signal.addEventListener('abort', abort);
|
|
||||||
cleanups.add(() => signal.removeEventListener('abort', abort));
|
|
||||||
}
|
|
||||||
cleanups.add(onSignalExit((code, signal) => {
|
|
||||||
reject(new ExitPromptError(`User force closed the prompt with ${code} ${signal}`));
|
|
||||||
}));
|
|
||||||
// SIGINT must be explicitly handled by the prompt so the ExitPromptError can be handled.
|
|
||||||
// Otherwise, the prompt will stop and in some scenarios never resolve.
|
|
||||||
// Ref issue #1741
|
|
||||||
const sigint = () => reject(new ExitPromptError(`User force closed the prompt with SIGINT`));
|
|
||||||
rl.on('SIGINT', sigint);
|
|
||||||
cleanups.add(() => rl.removeListener('SIGINT', sigint));
|
|
||||||
return withHooks(rl, (cycle) => {
|
|
||||||
// The close event triggers immediately when the user press ctrl+c. SignalExit on the other hand
|
|
||||||
// triggers after the process is done (which happens after timeouts are done triggering.)
|
|
||||||
// We triggers the hooks cleanup phase on rl `close` so active timeouts can be cleared.
|
|
||||||
const hooksCleanup = AsyncResource.bind(() => effectScheduler.clearAll());
|
|
||||||
rl.on('close', hooksCleanup);
|
|
||||||
cleanups.add(() => rl.removeListener('close', hooksCleanup));
|
|
||||||
const startCycle = () => {
|
|
||||||
// Re-renders only happen when the state change; but the readline cursor could
|
|
||||||
// change position and that also requires a re-render (and a manual one because
|
|
||||||
// we mute the streams). We set the listener after the initial workLoop to avoid
|
|
||||||
// a double render if render triggered by a state change sets the cursor to the
|
|
||||||
// right position.
|
|
||||||
const checkCursorPos = () => screen.checkCursorPos();
|
|
||||||
rl.input.on('keypress', checkCursorPos);
|
|
||||||
cleanups.add(() => rl.input.removeListener('keypress', checkCursorPos));
|
|
||||||
cycle(() => {
|
|
||||||
try {
|
|
||||||
const nextView = view(config, (value) => {
|
|
||||||
setImmediate(() => resolve(value));
|
|
||||||
});
|
|
||||||
// Typescript won't allow this, but not all users rely on typescript.
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
||||||
if (nextView === undefined) {
|
|
||||||
const callerFilename = callSites[1]?.getFileName();
|
|
||||||
throw new Error(`Prompt functions must return a string.\n at ${callerFilename}`);
|
|
||||||
}
|
|
||||||
const [content, bottomContent] = typeof nextView === 'string' ? [nextView] : nextView;
|
|
||||||
screen.render(content, bottomContent);
|
|
||||||
effectScheduler.run();
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// Proper Readable streams (like process.stdin) may have OS-level buffered
|
|
||||||
// data that arrives in the poll phase when readline resumes the stream.
|
|
||||||
// Deferring the first render by one setImmediate tick (check phase, after
|
|
||||||
// poll) lets that stale data flow through readline harmlessly—no keypress
|
|
||||||
// handlers are registered yet and the output is muted, so the stale
|
|
||||||
// keystrokes are silently discarded.
|
|
||||||
// Old-style streams (like MuteStream) have no such buffering, so the
|
|
||||||
// render cycle starts immediately.
|
|
||||||
//
|
|
||||||
// @see https://github.com/SBoudrias/Inquirer.js/issues/1303
|
|
||||||
if ('readableFlowing' in input) {
|
|
||||||
nativeSetImmediate(startCycle);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
startCycle();
|
|
||||||
}
|
|
||||||
return Object.assign(promise
|
|
||||||
.then((answer) => {
|
|
||||||
effectScheduler.clearAll();
|
|
||||||
return answer;
|
|
||||||
}, (error) => {
|
|
||||||
effectScheduler.clearAll();
|
|
||||||
throw error;
|
|
||||||
})
|
|
||||||
// Wait for the promise to settle, then cleanup.
|
|
||||||
.finally(() => {
|
|
||||||
cleanups.forEach((cleanup) => cleanup());
|
|
||||||
screen.done({ clearContent: Boolean(context.clearPromptOnDone) });
|
|
||||||
output.end();
|
|
||||||
})
|
|
||||||
// Once cleanup is done, let the expose promise resolve/reject to the internal one.
|
|
||||||
.then(() => promise), { cancel });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
return prompt;
|
|
||||||
}
|
|
||||||
20
node_modules/@inquirer/core/dist/lib/errors.d.ts
generated
vendored
20
node_modules/@inquirer/core/dist/lib/errors.d.ts
generated
vendored
@ -1,20 +0,0 @@
|
|||||||
export declare class AbortPromptError extends Error {
|
|
||||||
name: string;
|
|
||||||
message: string;
|
|
||||||
constructor(options?: {
|
|
||||||
cause?: unknown;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
export declare class CancelPromptError extends Error {
|
|
||||||
name: string;
|
|
||||||
message: string;
|
|
||||||
}
|
|
||||||
export declare class ExitPromptError extends Error {
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
export declare class HookError extends Error {
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
export declare class ValidationError extends Error {
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
21
node_modules/@inquirer/core/dist/lib/errors.js
generated
vendored
21
node_modules/@inquirer/core/dist/lib/errors.js
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
export class AbortPromptError extends Error {
|
|
||||||
name = 'AbortPromptError';
|
|
||||||
message = 'Prompt was aborted';
|
|
||||||
constructor(options) {
|
|
||||||
super();
|
|
||||||
this.cause = options?.cause;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export class CancelPromptError extends Error {
|
|
||||||
name = 'CancelPromptError';
|
|
||||||
message = 'Prompt was canceled';
|
|
||||||
}
|
|
||||||
export class ExitPromptError extends Error {
|
|
||||||
name = 'ExitPromptError';
|
|
||||||
}
|
|
||||||
export class HookError extends Error {
|
|
||||||
name = 'HookError';
|
|
||||||
}
|
|
||||||
export class ValidationError extends Error {
|
|
||||||
name = 'ValidationError';
|
|
||||||
}
|
|
||||||
23
node_modules/@inquirer/core/dist/lib/hook-engine.d.ts
generated
vendored
23
node_modules/@inquirer/core/dist/lib/hook-engine.d.ts
generated
vendored
@ -1,23 +0,0 @@
|
|||||||
import type { InquirerReadline } from '@inquirer/type';
|
|
||||||
export declare function withHooks<T>(rl: InquirerReadline, cb: (cycle: (render: () => void) => void) => T): T;
|
|
||||||
export declare function readline(): InquirerReadline;
|
|
||||||
export declare function withUpdates<Args extends unknown[], R>(fn: (...args: Args) => R): (...args: Args) => R;
|
|
||||||
type SetPointer<Value> = {
|
|
||||||
get(): Value;
|
|
||||||
set(value: Value): void;
|
|
||||||
initialized: true;
|
|
||||||
};
|
|
||||||
type UnsetPointer<Value> = {
|
|
||||||
get(): void;
|
|
||||||
set(value: Value): void;
|
|
||||||
initialized: false;
|
|
||||||
};
|
|
||||||
type Pointer<Value> = SetPointer<Value> | UnsetPointer<Value>;
|
|
||||||
export declare function withPointer<Value, ReturnValue>(cb: (pointer: Pointer<Value>) => ReturnValue): ReturnValue;
|
|
||||||
export declare function handleChange(): void;
|
|
||||||
export declare const effectScheduler: {
|
|
||||||
queue(cb: (readline: InquirerReadline) => void | (() => void)): void;
|
|
||||||
run(): void;
|
|
||||||
clearAll(): void;
|
|
||||||
};
|
|
||||||
export {};
|
|
||||||
110
node_modules/@inquirer/core/dist/lib/hook-engine.js
generated
vendored
110
node_modules/@inquirer/core/dist/lib/hook-engine.js
generated
vendored
@ -1,110 +0,0 @@
|
|||||||
/* eslint @typescript-eslint/no-explicit-any: ["off"] */
|
|
||||||
import { AsyncLocalStorage, AsyncResource } from 'node:async_hooks';
|
|
||||||
import { HookError, ValidationError } from "./errors.js";
|
|
||||||
const hookStorage = new AsyncLocalStorage();
|
|
||||||
function createStore(rl) {
|
|
||||||
const store = {
|
|
||||||
rl,
|
|
||||||
hooks: [],
|
|
||||||
hooksCleanup: [],
|
|
||||||
hooksEffect: [],
|
|
||||||
index: 0,
|
|
||||||
handleChange() { },
|
|
||||||
};
|
|
||||||
return store;
|
|
||||||
}
|
|
||||||
// Run callback in with the hook engine setup.
|
|
||||||
export function withHooks(rl, cb) {
|
|
||||||
const store = createStore(rl);
|
|
||||||
return hookStorage.run(store, () => {
|
|
||||||
function cycle(render) {
|
|
||||||
store.handleChange = () => {
|
|
||||||
store.index = 0;
|
|
||||||
render();
|
|
||||||
};
|
|
||||||
store.handleChange();
|
|
||||||
}
|
|
||||||
return cb(cycle);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Safe getStore utility that'll return the store or throw if undefined.
|
|
||||||
function getStore() {
|
|
||||||
const store = hookStorage.getStore();
|
|
||||||
if (!store) {
|
|
||||||
throw new HookError('[Inquirer] Hook functions can only be called from within a prompt');
|
|
||||||
}
|
|
||||||
return store;
|
|
||||||
}
|
|
||||||
export function readline() {
|
|
||||||
return getStore().rl;
|
|
||||||
}
|
|
||||||
// Merge state updates happening within the callback function to avoid multiple renders.
|
|
||||||
export function withUpdates(fn) {
|
|
||||||
const wrapped = (...args) => {
|
|
||||||
const store = getStore();
|
|
||||||
let shouldUpdate = false;
|
|
||||||
const oldHandleChange = store.handleChange;
|
|
||||||
store.handleChange = () => {
|
|
||||||
shouldUpdate = true;
|
|
||||||
};
|
|
||||||
const returnValue = fn(...args);
|
|
||||||
if (shouldUpdate) {
|
|
||||||
oldHandleChange();
|
|
||||||
}
|
|
||||||
store.handleChange = oldHandleChange;
|
|
||||||
return returnValue;
|
|
||||||
};
|
|
||||||
return AsyncResource.bind(wrapped);
|
|
||||||
}
|
|
||||||
export function withPointer(cb) {
|
|
||||||
const store = getStore();
|
|
||||||
const { index } = store;
|
|
||||||
const pointer = {
|
|
||||||
get() {
|
|
||||||
return store.hooks[index];
|
|
||||||
},
|
|
||||||
set(value) {
|
|
||||||
store.hooks[index] = value;
|
|
||||||
},
|
|
||||||
initialized: index in store.hooks,
|
|
||||||
};
|
|
||||||
const returnValue = cb(pointer);
|
|
||||||
store.index++;
|
|
||||||
return returnValue;
|
|
||||||
}
|
|
||||||
export function handleChange() {
|
|
||||||
getStore().handleChange();
|
|
||||||
}
|
|
||||||
export const effectScheduler = {
|
|
||||||
queue(cb) {
|
|
||||||
const store = getStore();
|
|
||||||
const { index } = store;
|
|
||||||
store.hooksEffect.push(() => {
|
|
||||||
store.hooksCleanup[index]?.();
|
|
||||||
const cleanFn = cb(readline());
|
|
||||||
if (cleanFn != null && typeof cleanFn !== 'function') {
|
|
||||||
throw new ValidationError('useEffect return value must be a cleanup function or nothing.');
|
|
||||||
}
|
|
||||||
store.hooksCleanup[index] = cleanFn;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
run() {
|
|
||||||
const store = getStore();
|
|
||||||
withUpdates(() => {
|
|
||||||
store.hooksEffect.forEach((effect) => {
|
|
||||||
effect();
|
|
||||||
});
|
|
||||||
// Warning: Clean the hooks before exiting the `withUpdates` block.
|
|
||||||
// Failure to do so means an updates would hit the same effects again.
|
|
||||||
store.hooksEffect.length = 0;
|
|
||||||
})();
|
|
||||||
},
|
|
||||||
clearAll() {
|
|
||||||
const store = getStore();
|
|
||||||
store.hooksCleanup.forEach((cleanFn) => {
|
|
||||||
cleanFn?.();
|
|
||||||
});
|
|
||||||
store.hooksEffect.length = 0;
|
|
||||||
store.hooksCleanup.length = 0;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
14
node_modules/@inquirer/core/dist/lib/key.d.ts
generated
vendored
14
node_modules/@inquirer/core/dist/lib/key.d.ts
generated
vendored
@ -1,14 +0,0 @@
|
|||||||
export type KeypressEvent = {
|
|
||||||
name: string;
|
|
||||||
ctrl: boolean;
|
|
||||||
shift: boolean;
|
|
||||||
};
|
|
||||||
export type Keybinding = 'emacs' | 'vim';
|
|
||||||
export declare const isUpKey: (key: KeypressEvent, keybindings?: ReadonlyArray<Keybinding>) => boolean;
|
|
||||||
export declare const isDownKey: (key: KeypressEvent, keybindings?: ReadonlyArray<Keybinding>) => boolean;
|
|
||||||
export declare const isSpaceKey: (key: KeypressEvent) => boolean;
|
|
||||||
export declare const isBackspaceKey: (key: KeypressEvent) => boolean;
|
|
||||||
export declare const isTabKey: (key: KeypressEvent) => boolean;
|
|
||||||
export declare const isNumberKey: (key: KeypressEvent) => boolean;
|
|
||||||
export declare const isEnterKey: (key: KeypressEvent) => boolean;
|
|
||||||
export declare const isShiftKey: (key: KeypressEvent) => boolean;
|
|
||||||
20
node_modules/@inquirer/core/dist/lib/key.js
generated
vendored
20
node_modules/@inquirer/core/dist/lib/key.js
generated
vendored
@ -1,20 +0,0 @@
|
|||||||
export const isUpKey = (key, keybindings = []) =>
|
|
||||||
// The up key
|
|
||||||
key.name === 'up' ||
|
|
||||||
// Vim keybinding: hjkl keys map to left/down/up/right
|
|
||||||
(keybindings.includes('vim') && key.name === 'k') ||
|
|
||||||
// Emacs keybinding: Ctrl+P means "previous" in Emacs navigation conventions
|
|
||||||
(keybindings.includes('emacs') && key.ctrl && key.name === 'p');
|
|
||||||
export const isDownKey = (key, keybindings = []) =>
|
|
||||||
// The down key
|
|
||||||
key.name === 'down' ||
|
|
||||||
// Vim keybinding: hjkl keys map to left/down/up/right
|
|
||||||
(keybindings.includes('vim') && key.name === 'j') ||
|
|
||||||
// Emacs keybinding: Ctrl+N means "next" in Emacs navigation conventions
|
|
||||||
(keybindings.includes('emacs') && key.ctrl && key.name === 'n');
|
|
||||||
export const isSpaceKey = (key) => key.name === 'space';
|
|
||||||
export const isBackspaceKey = (key) => key.name === 'backspace';
|
|
||||||
export const isTabKey = (key) => key.name === 'tab';
|
|
||||||
export const isNumberKey = (key) => '1234567890'.includes(key.name);
|
|
||||||
export const isEnterKey = (key) => key.name === 'enter' || key.name === 'return';
|
|
||||||
export const isShiftKey = (key) => key.shift;
|
|
||||||
3
node_modules/@inquirer/core/dist/lib/make-theme.d.ts
generated
vendored
3
node_modules/@inquirer/core/dist/lib/make-theme.d.ts
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
import type { Prettify, PartialDeep } from '@inquirer/type';
|
|
||||||
import { type Theme } from './theme.ts';
|
|
||||||
export declare function makeTheme<SpecificTheme extends object>(...themes: ReadonlyArray<undefined | PartialDeep<Theme<SpecificTheme>>>): Prettify<Theme<SpecificTheme>>;
|
|
||||||
30
node_modules/@inquirer/core/dist/lib/make-theme.js
generated
vendored
30
node_modules/@inquirer/core/dist/lib/make-theme.js
generated
vendored
@ -1,30 +0,0 @@
|
|||||||
import { defaultTheme } from "./theme.js";
|
|
||||||
function isPlainObject(value) {
|
|
||||||
if (typeof value !== 'object' || value === null)
|
|
||||||
return false;
|
|
||||||
let proto = value;
|
|
||||||
while (Object.getPrototypeOf(proto) !== null) {
|
|
||||||
proto = Object.getPrototypeOf(proto);
|
|
||||||
}
|
|
||||||
return Object.getPrototypeOf(value) === proto;
|
|
||||||
}
|
|
||||||
function deepMerge(...objects) {
|
|
||||||
const output = {};
|
|
||||||
for (const obj of objects) {
|
|
||||||
for (const [key, value] of Object.entries(obj)) {
|
|
||||||
const prevValue = output[key];
|
|
||||||
output[key] =
|
|
||||||
isPlainObject(prevValue) && isPlainObject(value)
|
|
||||||
? deepMerge(prevValue, value)
|
|
||||||
: value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
export function makeTheme(...themes) {
|
|
||||||
const themesToMerge = [
|
|
||||||
defaultTheme,
|
|
||||||
...themes.filter((theme) => theme != null),
|
|
||||||
];
|
|
||||||
return deepMerge(...themesToMerge);
|
|
||||||
}
|
|
||||||
16
node_modules/@inquirer/core/dist/lib/pagination/use-pagination.d.ts
generated
vendored
16
node_modules/@inquirer/core/dist/lib/pagination/use-pagination.d.ts
generated
vendored
@ -1,16 +0,0 @@
|
|||||||
import type { Prettify } from '@inquirer/type';
|
|
||||||
export declare function usePagination<T>({ items, active, renderItem, pageSize, loop, }: {
|
|
||||||
items: ReadonlyArray<T>;
|
|
||||||
/** The index of the active item. */
|
|
||||||
active: number;
|
|
||||||
/** Renders an item as part of a page. */
|
|
||||||
renderItem: (layout: Prettify<{
|
|
||||||
item: T;
|
|
||||||
index: number;
|
|
||||||
isActive: boolean;
|
|
||||||
}>) => string;
|
|
||||||
/** The size of the page. */
|
|
||||||
pageSize: number;
|
|
||||||
/** Allows creating an infinitely looping list. `true` if unspecified. */
|
|
||||||
loop?: boolean;
|
|
||||||
}): string;
|
|
||||||
121
node_modules/@inquirer/core/dist/lib/pagination/use-pagination.js
generated
vendored
121
node_modules/@inquirer/core/dist/lib/pagination/use-pagination.js
generated
vendored
@ -1,121 +0,0 @@
|
|||||||
import { useRef } from "../use-ref.js";
|
|
||||||
import { readlineWidth, breakLines } from "../utils.js";
|
|
||||||
function usePointerPosition({ active, renderedItems, pageSize, loop, }) {
|
|
||||||
const state = useRef({
|
|
||||||
lastPointer: active,
|
|
||||||
lastActive: undefined,
|
|
||||||
});
|
|
||||||
const { lastPointer, lastActive } = state.current;
|
|
||||||
const middle = Math.floor(pageSize / 2);
|
|
||||||
const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
|
|
||||||
const defaultPointerPosition = renderedItems
|
|
||||||
.slice(0, active)
|
|
||||||
.reduce((acc, item) => acc + item.length, 0);
|
|
||||||
let pointer = defaultPointerPosition;
|
|
||||||
if (renderedLength > pageSize) {
|
|
||||||
if (loop) {
|
|
||||||
/**
|
|
||||||
* Creates the next position for the pointer considering an infinitely
|
|
||||||
* looping list of items to be rendered on the page.
|
|
||||||
*
|
|
||||||
* The goal is to progressively move the cursor to the middle position as the user move down, and then keep
|
|
||||||
* the cursor there. When the user move up, maintain the cursor position.
|
|
||||||
*/
|
|
||||||
// By default, keep the cursor position as-is.
|
|
||||||
pointer = lastPointer;
|
|
||||||
if (
|
|
||||||
// First render, skip this logic.
|
|
||||||
lastActive != null &&
|
|
||||||
// Only move the pointer down when the user moves down.
|
|
||||||
lastActive < active &&
|
|
||||||
// Check user didn't move up across page boundary.
|
|
||||||
active - lastActive < pageSize) {
|
|
||||||
pointer = Math.min(
|
|
||||||
// Furthest allowed position for the pointer is the middle of the list
|
|
||||||
middle, Math.abs(active - lastActive) === 1
|
|
||||||
? Math.min(
|
|
||||||
// Move the pointer at most the height of the last active item.
|
|
||||||
lastPointer + (renderedItems[lastActive]?.length ?? 0),
|
|
||||||
// If the user moved by one item, move the pointer to the natural position of the active item as
|
|
||||||
// long as it doesn't move the cursor up.
|
|
||||||
Math.max(defaultPointerPosition, lastPointer))
|
|
||||||
: // Otherwise, move the pointer down by the difference between the active and last active item.
|
|
||||||
lastPointer + active - lastActive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/**
|
|
||||||
* Creates the next position for the pointer considering a finite list of
|
|
||||||
* items to be rendered on a page.
|
|
||||||
*
|
|
||||||
* The goal is to keep the pointer in the middle of the page whenever possible, until
|
|
||||||
* we reach the bounds of the list (top or bottom). In which case, the cursor moves progressively
|
|
||||||
* to the bottom or top of the list.
|
|
||||||
*/
|
|
||||||
const spaceUnderActive = renderedItems
|
|
||||||
.slice(active)
|
|
||||||
.reduce((acc, item) => acc + item.length, 0);
|
|
||||||
pointer =
|
|
||||||
spaceUnderActive < pageSize - middle
|
|
||||||
? // If the active item is near the end of the list, progressively move the cursor towards the end.
|
|
||||||
pageSize - spaceUnderActive
|
|
||||||
: // Otherwise, progressively move the pointer to the middle of the list.
|
|
||||||
Math.min(defaultPointerPosition, middle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Save state for the next render
|
|
||||||
state.current.lastPointer = pointer;
|
|
||||||
state.current.lastActive = active;
|
|
||||||
return pointer;
|
|
||||||
}
|
|
||||||
export function usePagination({ items, active, renderItem, pageSize, loop = true, }) {
|
|
||||||
const width = readlineWidth();
|
|
||||||
const bound = (num) => ((num % items.length) + items.length) % items.length;
|
|
||||||
const renderedItems = items.map((item, index) => {
|
|
||||||
if (item == null)
|
|
||||||
return [];
|
|
||||||
return breakLines(renderItem({ item, index, isActive: index === active }), width).split('\n');
|
|
||||||
});
|
|
||||||
const renderedLength = renderedItems.reduce((acc, item) => acc + item.length, 0);
|
|
||||||
const renderItemAtIndex = (index) => renderedItems[index] ?? [];
|
|
||||||
const pointer = usePointerPosition({ active, renderedItems, pageSize, loop });
|
|
||||||
// Render the active item to decide the position.
|
|
||||||
// If the active item fits under the pointer, we render it there.
|
|
||||||
// Otherwise, we need to render it to fit at the bottom of the page; moving the pointer up.
|
|
||||||
const activeItem = renderItemAtIndex(active).slice(0, pageSize);
|
|
||||||
const activeItemPosition = pointer + activeItem.length <= pageSize ? pointer : pageSize - activeItem.length;
|
|
||||||
// Create an array of lines for the page, and add the lines of the active item into the page
|
|
||||||
const pageBuffer = Array.from({ length: pageSize });
|
|
||||||
pageBuffer.splice(activeItemPosition, activeItem.length, ...activeItem);
|
|
||||||
// Store to prevent rendering the same item twice
|
|
||||||
const itemVisited = new Set([active]);
|
|
||||||
// Fill the page under the active item
|
|
||||||
let bufferPointer = activeItemPosition + activeItem.length;
|
|
||||||
let itemPointer = bound(active + 1);
|
|
||||||
while (bufferPointer < pageSize &&
|
|
||||||
!itemVisited.has(itemPointer) &&
|
|
||||||
(loop && renderedLength > pageSize ? itemPointer !== active : itemPointer > active)) {
|
|
||||||
const lines = renderItemAtIndex(itemPointer);
|
|
||||||
const linesToAdd = lines.slice(0, pageSize - bufferPointer);
|
|
||||||
pageBuffer.splice(bufferPointer, linesToAdd.length, ...linesToAdd);
|
|
||||||
// Move pointers for next iteration
|
|
||||||
itemVisited.add(itemPointer);
|
|
||||||
bufferPointer += linesToAdd.length;
|
|
||||||
itemPointer = bound(itemPointer + 1);
|
|
||||||
}
|
|
||||||
// Fill the page over the active item
|
|
||||||
bufferPointer = activeItemPosition - 1;
|
|
||||||
itemPointer = bound(active - 1);
|
|
||||||
while (bufferPointer >= 0 &&
|
|
||||||
!itemVisited.has(itemPointer) &&
|
|
||||||
(loop && renderedLength > pageSize ? itemPointer !== active : itemPointer < active)) {
|
|
||||||
const lines = renderItemAtIndex(itemPointer);
|
|
||||||
const linesToAdd = lines.slice(Math.max(0, lines.length - bufferPointer - 1));
|
|
||||||
pageBuffer.splice(bufferPointer - linesToAdd.length + 1, linesToAdd.length, ...linesToAdd);
|
|
||||||
// Move pointers for next iteration
|
|
||||||
itemVisited.add(itemPointer);
|
|
||||||
bufferPointer -= linesToAdd.length;
|
|
||||||
itemPointer = bound(itemPointer - 1);
|
|
||||||
}
|
|
||||||
return pageBuffer.filter((line) => typeof line === 'string').join('\n');
|
|
||||||
}
|
|
||||||
7
node_modules/@inquirer/core/dist/lib/promise-polyfill.d.ts
generated
vendored
7
node_modules/@inquirer/core/dist/lib/promise-polyfill.d.ts
generated
vendored
@ -1,7 +0,0 @@
|
|||||||
export declare class PromisePolyfill<T> extends Promise<T> {
|
|
||||||
static withResolver<T>(): {
|
|
||||||
promise: Promise<T>;
|
|
||||||
resolve: (value: T) => void;
|
|
||||||
reject: (error: unknown) => void;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
14
node_modules/@inquirer/core/dist/lib/promise-polyfill.js
generated
vendored
14
node_modules/@inquirer/core/dist/lib/promise-polyfill.js
generated
vendored
@ -1,14 +0,0 @@
|
|||||||
// TODO: Remove this class once Node 22 becomes the minimum supported version.
|
|
||||||
export class PromisePolyfill extends Promise {
|
|
||||||
// Available starting from Node 22
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
|
|
||||||
static withResolver() {
|
|
||||||
let resolve;
|
|
||||||
let reject;
|
|
||||||
const promise = new Promise((res, rej) => {
|
|
||||||
resolve = res;
|
|
||||||
reject = rej;
|
|
||||||
});
|
|
||||||
return { promise, resolve: resolve, reject: reject };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
14
node_modules/@inquirer/core/dist/lib/screen-manager.d.ts
generated
vendored
14
node_modules/@inquirer/core/dist/lib/screen-manager.d.ts
generated
vendored
@ -1,14 +0,0 @@
|
|||||||
import type { InquirerReadline } from '@inquirer/type';
|
|
||||||
export default class ScreenManager {
|
|
||||||
private height;
|
|
||||||
private extraLinesUnderPrompt;
|
|
||||||
private cursorPos;
|
|
||||||
private readonly rl;
|
|
||||||
constructor(rl: InquirerReadline);
|
|
||||||
write(content: string): void;
|
|
||||||
render(content: string, bottomContent?: string): void;
|
|
||||||
checkCursorPos(): void;
|
|
||||||
done({ clearContent }: {
|
|
||||||
clearContent: boolean;
|
|
||||||
}): void;
|
|
||||||
}
|
|
||||||
79
node_modules/@inquirer/core/dist/lib/screen-manager.js
generated
vendored
79
node_modules/@inquirer/core/dist/lib/screen-manager.js
generated
vendored
@ -1,79 +0,0 @@
|
|||||||
import { stripVTControlCharacters } from 'node:util';
|
|
||||||
import { breakLines, readlineWidth } from "./utils.js";
|
|
||||||
import { cursorDown, cursorUp, cursorTo, cursorShow, eraseLines } from '@inquirer/ansi';
|
|
||||||
const height = (content) => content.split('\n').length;
|
|
||||||
const lastLine = (content) => content.split('\n').pop() ?? '';
|
|
||||||
export default class ScreenManager {
|
|
||||||
// These variables are keeping information to allow correct prompt re-rendering
|
|
||||||
height = 0;
|
|
||||||
extraLinesUnderPrompt = 0;
|
|
||||||
cursorPos;
|
|
||||||
rl;
|
|
||||||
constructor(rl) {
|
|
||||||
this.rl = rl;
|
|
||||||
this.cursorPos = rl.getCursorPos();
|
|
||||||
}
|
|
||||||
write(content) {
|
|
||||||
this.rl.output.unmute();
|
|
||||||
this.rl.output.write(content);
|
|
||||||
this.rl.output.mute();
|
|
||||||
}
|
|
||||||
render(content, bottomContent = '') {
|
|
||||||
// Write message to screen and setPrompt to control backspace
|
|
||||||
const promptLine = lastLine(content);
|
|
||||||
const rawPromptLine = stripVTControlCharacters(promptLine);
|
|
||||||
// Remove the rl.line from our prompt. We can't rely on the content of
|
|
||||||
// rl.line (mainly because of the password prompt), so just rely on it's
|
|
||||||
// length.
|
|
||||||
let prompt = rawPromptLine;
|
|
||||||
if (this.rl.line.length > 0) {
|
|
||||||
prompt = prompt.slice(0, -this.rl.line.length);
|
|
||||||
}
|
|
||||||
this.rl.setPrompt(prompt);
|
|
||||||
// SetPrompt will change cursor position, now we can get correct value
|
|
||||||
this.cursorPos = this.rl.getCursorPos();
|
|
||||||
const width = readlineWidth();
|
|
||||||
content = breakLines(content, width);
|
|
||||||
bottomContent = breakLines(bottomContent, width);
|
|
||||||
// Manually insert an extra line if we're at the end of the line.
|
|
||||||
// This prevent the cursor from appearing at the beginning of the
|
|
||||||
// current line.
|
|
||||||
if (rawPromptLine.length % width === 0) {
|
|
||||||
content += '\n';
|
|
||||||
}
|
|
||||||
let output = content + (bottomContent ? '\n' + bottomContent : '');
|
|
||||||
/**
|
|
||||||
* Re-adjust the cursor at the correct position.
|
|
||||||
*/
|
|
||||||
// We need to consider parts of the prompt under the cursor as part of the bottom
|
|
||||||
// content in order to correctly cleanup and re-render.
|
|
||||||
const promptLineUpDiff = Math.floor(rawPromptLine.length / width) - this.cursorPos.rows;
|
|
||||||
const bottomContentHeight = promptLineUpDiff + (bottomContent ? height(bottomContent) : 0);
|
|
||||||
// Return cursor to the input position (on top of the bottomContent)
|
|
||||||
if (bottomContentHeight > 0)
|
|
||||||
output += cursorUp(bottomContentHeight);
|
|
||||||
// Return cursor to the initial left offset.
|
|
||||||
output += cursorTo(this.cursorPos.cols);
|
|
||||||
/**
|
|
||||||
* Render and store state for future re-rendering
|
|
||||||
*/
|
|
||||||
this.write(cursorDown(this.extraLinesUnderPrompt) + eraseLines(this.height) + output);
|
|
||||||
this.extraLinesUnderPrompt = bottomContentHeight;
|
|
||||||
this.height = height(output);
|
|
||||||
}
|
|
||||||
checkCursorPos() {
|
|
||||||
const cursorPos = this.rl.getCursorPos();
|
|
||||||
if (cursorPos.cols !== this.cursorPos.cols) {
|
|
||||||
this.write(cursorTo(cursorPos.cols));
|
|
||||||
this.cursorPos = cursorPos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
done({ clearContent }) {
|
|
||||||
this.rl.setPrompt('');
|
|
||||||
let output = cursorDown(this.extraLinesUnderPrompt);
|
|
||||||
output += clearContent ? eraseLines(this.height) : '\n';
|
|
||||||
output += cursorShow;
|
|
||||||
this.write(output);
|
|
||||||
this.rl.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
155
node_modules/@inquirer/core/dist/lib/theme.d.ts
generated
vendored
155
node_modules/@inquirer/core/dist/lib/theme.d.ts
generated
vendored
@ -1,155 +0,0 @@
|
|||||||
import type { Prettify } from '@inquirer/type';
|
|
||||||
/**
|
|
||||||
* Union type representing the possible statuses of a prompt.
|
|
||||||
*
|
|
||||||
* - `'loading'`: The prompt is currently loading.
|
|
||||||
* - `'idle'`: The prompt is loaded and currently waiting for the user to
|
|
||||||
* submit an answer.
|
|
||||||
* - `'done'`: The user has submitted an answer and the prompt is finished.
|
|
||||||
* - `string`: Any other string: The prompt is in a custom state.
|
|
||||||
*/
|
|
||||||
export type Status = 'loading' | 'idle' | 'done' | (string & {});
|
|
||||||
type DefaultTheme = {
|
|
||||||
/**
|
|
||||||
* Prefix to prepend to the message. If a function is provided, it will be
|
|
||||||
* called with the current status of the prompt, and the return value will be
|
|
||||||
* used as the prefix.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* If `status === 'loading'`, this property is ignored and the spinner (styled
|
|
||||||
* by the `spinner` property) will be displayed instead.
|
|
||||||
*
|
|
||||||
* @defaultValue
|
|
||||||
* ```ts
|
|
||||||
* // import { styleText } from 'node:util';
|
|
||||||
* (status) => status === 'done' ? styleText('green', '✔') : styleText('blue', '?')
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
prefix: string | Prettify<Omit<Record<Status, string>, 'loading'>>;
|
|
||||||
/**
|
|
||||||
* Configuration for the spinner that is displayed when the prompt is in the
|
|
||||||
* `'loading'` state.
|
|
||||||
*
|
|
||||||
* We recommend the use of {@link https://github.com/sindresorhus/cli-spinners|cli-spinners} for a list of available spinners.
|
|
||||||
*/
|
|
||||||
spinner: {
|
|
||||||
/**
|
|
||||||
* The time interval between frames, in milliseconds.
|
|
||||||
*
|
|
||||||
* @defaultValue
|
|
||||||
* ```ts
|
|
||||||
* 80
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
interval: number;
|
|
||||||
/**
|
|
||||||
* A list of frames to show for the spinner.
|
|
||||||
*
|
|
||||||
* @defaultValue
|
|
||||||
* ```ts
|
|
||||||
* ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏']
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
frames: string[];
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Object containing functions to style different parts of the prompt.
|
|
||||||
*/
|
|
||||||
style: {
|
|
||||||
/**
|
|
||||||
* Style to apply to the user's answer once it has been submitted.
|
|
||||||
*
|
|
||||||
* @param text - The user's answer.
|
|
||||||
* @returns The styled answer.
|
|
||||||
*
|
|
||||||
* @defaultValue
|
|
||||||
* ```ts
|
|
||||||
* // import { styleText } from 'node:util';
|
|
||||||
* (text) => styleText('cyan', text)
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
answer: (text: string) => string;
|
|
||||||
/**
|
|
||||||
* Style to apply to the message displayed to the user.
|
|
||||||
*
|
|
||||||
* @param text - The message to style.
|
|
||||||
* @param status - The current status of the prompt.
|
|
||||||
* @returns The styled message.
|
|
||||||
*
|
|
||||||
* @defaultValue
|
|
||||||
* ```ts
|
|
||||||
* // import { styleText } from 'node:util';
|
|
||||||
* (text, status) => styleText('bold', text)
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
message: (text: string, status: Status) => string;
|
|
||||||
/**
|
|
||||||
* Style to apply to error messages.
|
|
||||||
*
|
|
||||||
* @param text - The error message.
|
|
||||||
* @returns The styled error message.
|
|
||||||
*
|
|
||||||
* @defaultValue
|
|
||||||
* ```ts
|
|
||||||
* // import { styleText } from 'node:util';
|
|
||||||
* (text) => styleText('red', `> ${text}`)
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
error: (text: string) => string;
|
|
||||||
/**
|
|
||||||
* Style to apply to the default answer when one is provided.
|
|
||||||
*
|
|
||||||
* @param text - The default answer.
|
|
||||||
* @returns The styled default answer.
|
|
||||||
*
|
|
||||||
* @defaultValue
|
|
||||||
* ```ts
|
|
||||||
* // import { styleText } from 'node:util';
|
|
||||||
* (text) => styleText('dim', `(${text})`)
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
defaultAnswer: (text: string) => string;
|
|
||||||
/**
|
|
||||||
* Style to apply to help text.
|
|
||||||
*
|
|
||||||
* @param text - The help text.
|
|
||||||
* @returns The styled help text.
|
|
||||||
*
|
|
||||||
* @defaultValue
|
|
||||||
* ```ts
|
|
||||||
* // import { styleText } from 'node:util';
|
|
||||||
* (text) => styleText('dim', text)
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
help: (text: string) => string;
|
|
||||||
/**
|
|
||||||
* Style to apply to highlighted text.
|
|
||||||
*
|
|
||||||
* @param text - The text to highlight.
|
|
||||||
* @returns The highlighted text.
|
|
||||||
*
|
|
||||||
* @defaultValue
|
|
||||||
* ```ts
|
|
||||||
* // import { styleText } from 'node:util';
|
|
||||||
* (text) => styleText('cyan', text)
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
highlight: (text: string) => string;
|
|
||||||
/**
|
|
||||||
* Style to apply to keyboard keys referred to in help texts.
|
|
||||||
*
|
|
||||||
* @param text - The key to style.
|
|
||||||
* @returns The styled key.
|
|
||||||
*
|
|
||||||
* @defaultValue
|
|
||||||
* ```ts
|
|
||||||
* // import { styleText } from 'node:util';
|
|
||||||
* (text) => styleText('cyan', styleText('bold', `<${text}>`))
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
key: (text: string) => string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
export type Theme<Extension extends object = object> = Prettify<Extension & DefaultTheme>;
|
|
||||||
export declare const defaultTheme: DefaultTheme;
|
|
||||||
export {};
|
|
||||||
21
node_modules/@inquirer/core/dist/lib/theme.js
generated
vendored
21
node_modules/@inquirer/core/dist/lib/theme.js
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
import { styleText } from 'node:util';
|
|
||||||
import figures from '@inquirer/figures';
|
|
||||||
export const defaultTheme = {
|
|
||||||
prefix: {
|
|
||||||
idle: styleText('blue', '?'),
|
|
||||||
done: styleText('green', figures.tick),
|
|
||||||
},
|
|
||||||
spinner: {
|
|
||||||
interval: 80,
|
|
||||||
frames: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'].map((frame) => styleText('yellow', frame)),
|
|
||||||
},
|
|
||||||
style: {
|
|
||||||
answer: (text) => styleText('cyan', text),
|
|
||||||
message: (text) => styleText('bold', text),
|
|
||||||
error: (text) => styleText('red', `> ${text}`),
|
|
||||||
defaultAnswer: (text) => styleText('dim', `(${text})`),
|
|
||||||
help: (text) => styleText('dim', text),
|
|
||||||
highlight: (text) => styleText('cyan', text),
|
|
||||||
key: (text) => styleText('cyan', styleText('bold', `<${text}>`)),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
2
node_modules/@inquirer/core/dist/lib/use-effect.d.ts
generated
vendored
2
node_modules/@inquirer/core/dist/lib/use-effect.d.ts
generated
vendored
@ -1,2 +0,0 @@
|
|||||||
import type { InquirerReadline } from '@inquirer/type';
|
|
||||||
export declare function useEffect(cb: (rl: InquirerReadline) => void | (() => void), depArray: ReadonlyArray<unknown>): void;
|
|
||||||
11
node_modules/@inquirer/core/dist/lib/use-effect.js
generated
vendored
11
node_modules/@inquirer/core/dist/lib/use-effect.js
generated
vendored
@ -1,11 +0,0 @@
|
|||||||
import { withPointer, effectScheduler } from "./hook-engine.js";
|
|
||||||
export function useEffect(cb, depArray) {
|
|
||||||
withPointer((pointer) => {
|
|
||||||
const oldDeps = pointer.get();
|
|
||||||
const hasChanged = !Array.isArray(oldDeps) || depArray.some((dep, i) => !Object.is(dep, oldDeps[i]));
|
|
||||||
if (hasChanged) {
|
|
||||||
effectScheduler.queue(cb);
|
|
||||||
}
|
|
||||||
pointer.set(depArray);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
3
node_modules/@inquirer/core/dist/lib/use-keypress.d.ts
generated
vendored
3
node_modules/@inquirer/core/dist/lib/use-keypress.d.ts
generated
vendored
@ -1,3 +0,0 @@
|
|||||||
import { type InquirerReadline } from '@inquirer/type';
|
|
||||||
import { type KeypressEvent } from './key.ts';
|
|
||||||
export declare function useKeypress(userHandler: (event: KeypressEvent, rl: InquirerReadline) => void | Promise<void>): void;
|
|
||||||
20
node_modules/@inquirer/core/dist/lib/use-keypress.js
generated
vendored
20
node_modules/@inquirer/core/dist/lib/use-keypress.js
generated
vendored
@ -1,20 +0,0 @@
|
|||||||
import { useRef } from "./use-ref.js";
|
|
||||||
import { useEffect } from "./use-effect.js";
|
|
||||||
import { withUpdates } from "./hook-engine.js";
|
|
||||||
export function useKeypress(userHandler) {
|
|
||||||
const signal = useRef(userHandler);
|
|
||||||
signal.current = userHandler;
|
|
||||||
useEffect((rl) => {
|
|
||||||
let ignore = false;
|
|
||||||
const handler = withUpdates((_input, event) => {
|
|
||||||
if (ignore)
|
|
||||||
return;
|
|
||||||
void signal.current(event, rl);
|
|
||||||
});
|
|
||||||
rl.input.on('keypress', handler);
|
|
||||||
return () => {
|
|
||||||
ignore = true;
|
|
||||||
rl.input.removeListener('keypress', handler);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
}
|
|
||||||
1
node_modules/@inquirer/core/dist/lib/use-memo.d.ts
generated
vendored
1
node_modules/@inquirer/core/dist/lib/use-memo.d.ts
generated
vendored
@ -1 +0,0 @@
|
|||||||
export declare function useMemo<Value>(fn: () => Value, dependencies: ReadonlyArray<unknown>): Value;
|
|
||||||
14
node_modules/@inquirer/core/dist/lib/use-memo.js
generated
vendored
14
node_modules/@inquirer/core/dist/lib/use-memo.js
generated
vendored
@ -1,14 +0,0 @@
|
|||||||
import { withPointer } from "./hook-engine.js";
|
|
||||||
export function useMemo(fn, dependencies) {
|
|
||||||
return withPointer((pointer) => {
|
|
||||||
const prev = pointer.get();
|
|
||||||
if (!prev ||
|
|
||||||
prev.dependencies.length !== dependencies.length ||
|
|
||||||
prev.dependencies.some((dep, i) => dep !== dependencies[i])) {
|
|
||||||
const value = fn();
|
|
||||||
pointer.set({ value, dependencies });
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
return prev.value;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
5
node_modules/@inquirer/core/dist/lib/use-prefix.d.ts
generated
vendored
5
node_modules/@inquirer/core/dist/lib/use-prefix.d.ts
generated
vendored
@ -1,5 +0,0 @@
|
|||||||
import type { Theme, Status } from './theme.ts';
|
|
||||||
export declare function usePrefix({ status, theme, }: {
|
|
||||||
status?: Status;
|
|
||||||
theme?: Theme;
|
|
||||||
}): string;
|
|
||||||
35
node_modules/@inquirer/core/dist/lib/use-prefix.js
generated
vendored
35
node_modules/@inquirer/core/dist/lib/use-prefix.js
generated
vendored
@ -1,35 +0,0 @@
|
|||||||
import { useState } from "./use-state.js";
|
|
||||||
import { useEffect } from "./use-effect.js";
|
|
||||||
import { makeTheme } from "./make-theme.js";
|
|
||||||
export function usePrefix({ status = 'idle', theme, }) {
|
|
||||||
const [showLoader, setShowLoader] = useState(false);
|
|
||||||
const [tick, setTick] = useState(0);
|
|
||||||
const { prefix, spinner } = makeTheme(theme);
|
|
||||||
useEffect(() => {
|
|
||||||
if (status === 'loading') {
|
|
||||||
let tickInterval;
|
|
||||||
let inc = -1;
|
|
||||||
// Delay displaying spinner by 300ms, to avoid flickering
|
|
||||||
const delayTimeout = setTimeout(() => {
|
|
||||||
setShowLoader(true);
|
|
||||||
tickInterval = setInterval(() => {
|
|
||||||
inc = inc + 1;
|
|
||||||
setTick(inc % spinner.frames.length);
|
|
||||||
}, spinner.interval);
|
|
||||||
}, 300);
|
|
||||||
return () => {
|
|
||||||
clearTimeout(delayTimeout);
|
|
||||||
clearInterval(tickInterval);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setShowLoader(false);
|
|
||||||
}
|
|
||||||
}, [status]);
|
|
||||||
if (showLoader) {
|
|
||||||
return spinner.frames[tick];
|
|
||||||
}
|
|
||||||
// There's a delay before we show the loader. So we want to ignore `loading` here, and pass idle instead.
|
|
||||||
const iconName = status === 'loading' ? 'idle' : status;
|
|
||||||
return typeof prefix === 'string' ? prefix : (prefix[iconName] ?? prefix['idle']);
|
|
||||||
}
|
|
||||||
6
node_modules/@inquirer/core/dist/lib/use-ref.d.ts
generated
vendored
6
node_modules/@inquirer/core/dist/lib/use-ref.d.ts
generated
vendored
@ -1,6 +0,0 @@
|
|||||||
export declare function useRef<Value>(val: Value): {
|
|
||||||
current: Value;
|
|
||||||
};
|
|
||||||
export declare function useRef<Value>(val?: Value): {
|
|
||||||
current: Value | undefined;
|
|
||||||
};
|
|
||||||
4
node_modules/@inquirer/core/dist/lib/use-ref.js
generated
vendored
4
node_modules/@inquirer/core/dist/lib/use-ref.js
generated
vendored
@ -1,4 +0,0 @@
|
|||||||
import { useState } from "./use-state.js";
|
|
||||||
export function useRef(val) {
|
|
||||||
return useState({ current: val })[0];
|
|
||||||
}
|
|
||||||
4
node_modules/@inquirer/core/dist/lib/use-state.d.ts
generated
vendored
4
node_modules/@inquirer/core/dist/lib/use-state.d.ts
generated
vendored
@ -1,4 +0,0 @@
|
|||||||
type NotFunction<T> = T extends (...args: never) => unknown ? never : T;
|
|
||||||
export declare function useState<Value>(defaultValue: NotFunction<Value> | (() => Value)): [Value, (newValue: Value) => void];
|
|
||||||
export declare function useState<Value>(defaultValue?: NotFunction<Value> | (() => Value)): [Value | undefined, (newValue?: Value) => void];
|
|
||||||
export {};
|
|
||||||
20
node_modules/@inquirer/core/dist/lib/use-state.js
generated
vendored
20
node_modules/@inquirer/core/dist/lib/use-state.js
generated
vendored
@ -1,20 +0,0 @@
|
|||||||
import { AsyncResource } from 'node:async_hooks';
|
|
||||||
import { withPointer, handleChange } from "./hook-engine.js";
|
|
||||||
export function useState(defaultValue) {
|
|
||||||
return withPointer((pointer) => {
|
|
||||||
const setState = AsyncResource.bind(function setState(newValue) {
|
|
||||||
// Noop if the value is still the same.
|
|
||||||
if (pointer.get() !== newValue) {
|
|
||||||
pointer.set(newValue);
|
|
||||||
// Trigger re-render
|
|
||||||
handleChange();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if (pointer.initialized) {
|
|
||||||
return [pointer.get(), setState];
|
|
||||||
}
|
|
||||||
const value = typeof defaultValue === 'function' ? defaultValue() : defaultValue;
|
|
||||||
pointer.set(value);
|
|
||||||
return [value, setState];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
13
node_modules/@inquirer/core/dist/lib/utils.d.ts
generated
vendored
13
node_modules/@inquirer/core/dist/lib/utils.d.ts
generated
vendored
@ -1,13 +0,0 @@
|
|||||||
/**
|
|
||||||
* Force line returns at specific width. This function is ANSI code friendly and it'll
|
|
||||||
* ignore invisible codes during width calculation.
|
|
||||||
* @param {string} content
|
|
||||||
* @param {number} width
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
export declare function breakLines(content: string, width: number): string;
|
|
||||||
/**
|
|
||||||
* Returns the width of the active readline, or 80 as default value.
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
export declare function readlineWidth(): number;
|
|
||||||
25
node_modules/@inquirer/core/dist/lib/utils.js
generated
vendored
25
node_modules/@inquirer/core/dist/lib/utils.js
generated
vendored
@ -1,25 +0,0 @@
|
|||||||
import cliWidth from 'cli-width';
|
|
||||||
import { wrapAnsi } from 'fast-wrap-ansi';
|
|
||||||
import { readline } from "./hook-engine.js";
|
|
||||||
/**
|
|
||||||
* Force line returns at specific width. This function is ANSI code friendly and it'll
|
|
||||||
* ignore invisible codes during width calculation.
|
|
||||||
* @param {string} content
|
|
||||||
* @param {number} width
|
|
||||||
* @return {string}
|
|
||||||
*/
|
|
||||||
export function breakLines(content, width) {
|
|
||||||
return content
|
|
||||||
.split('\n')
|
|
||||||
.flatMap((line) => wrapAnsi(line, width, { trim: false, hard: true })
|
|
||||||
.split('\n')
|
|
||||||
.map((str) => str.trimEnd()))
|
|
||||||
.join('\n');
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns the width of the active readline, or 80 as default value.
|
|
||||||
* @returns {number}
|
|
||||||
*/
|
|
||||||
export function readlineWidth() {
|
|
||||||
return cliWidth({ defaultWidth: 80, output: readline().output });
|
|
||||||
}
|
|
||||||
98
node_modules/@inquirer/core/package.json
generated
vendored
98
node_modules/@inquirer/core/package.json
generated
vendored
@ -1,98 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@inquirer/core",
|
|
||||||
"version": "11.1.5",
|
|
||||||
"description": "Core Inquirer prompt API",
|
|
||||||
"keywords": [
|
|
||||||
"answer",
|
|
||||||
"answers",
|
|
||||||
"ask",
|
|
||||||
"base",
|
|
||||||
"cli",
|
|
||||||
"command",
|
|
||||||
"command-line",
|
|
||||||
"confirm",
|
|
||||||
"enquirer",
|
|
||||||
"generate",
|
|
||||||
"generator",
|
|
||||||
"hyper",
|
|
||||||
"input",
|
|
||||||
"inquire",
|
|
||||||
"inquirer",
|
|
||||||
"interface",
|
|
||||||
"iterm",
|
|
||||||
"javascript",
|
|
||||||
"menu",
|
|
||||||
"node",
|
|
||||||
"nodejs",
|
|
||||||
"prompt",
|
|
||||||
"promptly",
|
|
||||||
"prompts",
|
|
||||||
"question",
|
|
||||||
"readline",
|
|
||||||
"scaffold",
|
|
||||||
"scaffolder",
|
|
||||||
"scaffolding",
|
|
||||||
"stdin",
|
|
||||||
"stdout",
|
|
||||||
"terminal",
|
|
||||||
"tty",
|
|
||||||
"ui",
|
|
||||||
"yeoman",
|
|
||||||
"yo",
|
|
||||||
"zsh"
|
|
||||||
],
|
|
||||||
"homepage": "https://github.com/SBoudrias/Inquirer.js/blob/main/packages/core/README.md",
|
|
||||||
"license": "MIT",
|
|
||||||
"author": "Simon Boudrias <admin@simonboudrias.com>",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/SBoudrias/Inquirer.js.git"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"type": "module",
|
|
||||||
"sideEffects": false,
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"default": "./dist/index.js"
|
|
||||||
},
|
|
||||||
"./package.json": "./package.json"
|
|
||||||
},
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"tsc": "tsc"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@inquirer/ansi": "^2.0.3",
|
|
||||||
"@inquirer/figures": "^2.0.3",
|
|
||||||
"@inquirer/type": "^4.0.3",
|
|
||||||
"cli-width": "^4.1.0",
|
|
||||||
"fast-wrap-ansi": "^0.2.0",
|
|
||||||
"mute-stream": "^3.0.0",
|
|
||||||
"signal-exit": "^4.1.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@inquirer/testing": "^3.3.0",
|
|
||||||
"@types/mute-stream": "^0.0.4",
|
|
||||||
"@types/node": "^25.0.2",
|
|
||||||
"typescript": "^5.9.3"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@types/node": ">=18"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@types/node": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
|
|
||||||
},
|
|
||||||
"main": "./dist/index.js",
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"gitHead": "526eca2e64853510821ffd457561840ec0cbfb93"
|
|
||||||
}
|
|
||||||
22
node_modules/@inquirer/figures/LICENSE
generated
vendored
22
node_modules/@inquirer/figures/LICENSE
generated
vendored
@ -1,22 +0,0 @@
|
|||||||
Copyright (c) 2025 Simon Boudrias
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
|
||||||
obtaining a copy of this software and associated documentation
|
|
||||||
files (the "Software"), to deal in the Software without
|
|
||||||
restriction, including without limitation the rights to use,
|
|
||||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
275
node_modules/@inquirer/figures/dist/index.d.ts
generated
vendored
275
node_modules/@inquirer/figures/dist/index.d.ts
generated
vendored
@ -1,275 +0,0 @@
|
|||||||
declare const common: {
|
|
||||||
circleQuestionMark: string;
|
|
||||||
questionMarkPrefix: string;
|
|
||||||
square: string;
|
|
||||||
squareDarkShade: string;
|
|
||||||
squareMediumShade: string;
|
|
||||||
squareLightShade: string;
|
|
||||||
squareTop: string;
|
|
||||||
squareBottom: string;
|
|
||||||
squareLeft: string;
|
|
||||||
squareRight: string;
|
|
||||||
squareCenter: string;
|
|
||||||
bullet: string;
|
|
||||||
dot: string;
|
|
||||||
ellipsis: string;
|
|
||||||
pointerSmall: string;
|
|
||||||
triangleUp: string;
|
|
||||||
triangleUpSmall: string;
|
|
||||||
triangleDown: string;
|
|
||||||
triangleDownSmall: string;
|
|
||||||
triangleLeftSmall: string;
|
|
||||||
triangleRightSmall: string;
|
|
||||||
home: string;
|
|
||||||
heart: string;
|
|
||||||
musicNote: string;
|
|
||||||
musicNoteBeamed: string;
|
|
||||||
arrowUp: string;
|
|
||||||
arrowDown: string;
|
|
||||||
arrowLeft: string;
|
|
||||||
arrowRight: string;
|
|
||||||
arrowLeftRight: string;
|
|
||||||
arrowUpDown: string;
|
|
||||||
almostEqual: string;
|
|
||||||
notEqual: string;
|
|
||||||
lessOrEqual: string;
|
|
||||||
greaterOrEqual: string;
|
|
||||||
identical: string;
|
|
||||||
infinity: string;
|
|
||||||
subscriptZero: string;
|
|
||||||
subscriptOne: string;
|
|
||||||
subscriptTwo: string;
|
|
||||||
subscriptThree: string;
|
|
||||||
subscriptFour: string;
|
|
||||||
subscriptFive: string;
|
|
||||||
subscriptSix: string;
|
|
||||||
subscriptSeven: string;
|
|
||||||
subscriptEight: string;
|
|
||||||
subscriptNine: string;
|
|
||||||
oneHalf: string;
|
|
||||||
oneThird: string;
|
|
||||||
oneQuarter: string;
|
|
||||||
oneFifth: string;
|
|
||||||
oneSixth: string;
|
|
||||||
oneEighth: string;
|
|
||||||
twoThirds: string;
|
|
||||||
twoFifths: string;
|
|
||||||
threeQuarters: string;
|
|
||||||
threeFifths: string;
|
|
||||||
threeEighths: string;
|
|
||||||
fourFifths: string;
|
|
||||||
fiveSixths: string;
|
|
||||||
fiveEighths: string;
|
|
||||||
sevenEighths: string;
|
|
||||||
line: string;
|
|
||||||
lineBold: string;
|
|
||||||
lineDouble: string;
|
|
||||||
lineDashed0: string;
|
|
||||||
lineDashed1: string;
|
|
||||||
lineDashed2: string;
|
|
||||||
lineDashed3: string;
|
|
||||||
lineDashed4: string;
|
|
||||||
lineDashed5: string;
|
|
||||||
lineDashed6: string;
|
|
||||||
lineDashed7: string;
|
|
||||||
lineDashed8: string;
|
|
||||||
lineDashed9: string;
|
|
||||||
lineDashed10: string;
|
|
||||||
lineDashed11: string;
|
|
||||||
lineDashed12: string;
|
|
||||||
lineDashed13: string;
|
|
||||||
lineDashed14: string;
|
|
||||||
lineDashed15: string;
|
|
||||||
lineVertical: string;
|
|
||||||
lineVerticalBold: string;
|
|
||||||
lineVerticalDouble: string;
|
|
||||||
lineVerticalDashed0: string;
|
|
||||||
lineVerticalDashed1: string;
|
|
||||||
lineVerticalDashed2: string;
|
|
||||||
lineVerticalDashed3: string;
|
|
||||||
lineVerticalDashed4: string;
|
|
||||||
lineVerticalDashed5: string;
|
|
||||||
lineVerticalDashed6: string;
|
|
||||||
lineVerticalDashed7: string;
|
|
||||||
lineVerticalDashed8: string;
|
|
||||||
lineVerticalDashed9: string;
|
|
||||||
lineVerticalDashed10: string;
|
|
||||||
lineVerticalDashed11: string;
|
|
||||||
lineDownLeft: string;
|
|
||||||
lineDownLeftArc: string;
|
|
||||||
lineDownBoldLeftBold: string;
|
|
||||||
lineDownBoldLeft: string;
|
|
||||||
lineDownLeftBold: string;
|
|
||||||
lineDownDoubleLeftDouble: string;
|
|
||||||
lineDownDoubleLeft: string;
|
|
||||||
lineDownLeftDouble: string;
|
|
||||||
lineDownRight: string;
|
|
||||||
lineDownRightArc: string;
|
|
||||||
lineDownBoldRightBold: string;
|
|
||||||
lineDownBoldRight: string;
|
|
||||||
lineDownRightBold: string;
|
|
||||||
lineDownDoubleRightDouble: string;
|
|
||||||
lineDownDoubleRight: string;
|
|
||||||
lineDownRightDouble: string;
|
|
||||||
lineUpLeft: string;
|
|
||||||
lineUpLeftArc: string;
|
|
||||||
lineUpBoldLeftBold: string;
|
|
||||||
lineUpBoldLeft: string;
|
|
||||||
lineUpLeftBold: string;
|
|
||||||
lineUpDoubleLeftDouble: string;
|
|
||||||
lineUpDoubleLeft: string;
|
|
||||||
lineUpLeftDouble: string;
|
|
||||||
lineUpRight: string;
|
|
||||||
lineUpRightArc: string;
|
|
||||||
lineUpBoldRightBold: string;
|
|
||||||
lineUpBoldRight: string;
|
|
||||||
lineUpRightBold: string;
|
|
||||||
lineUpDoubleRightDouble: string;
|
|
||||||
lineUpDoubleRight: string;
|
|
||||||
lineUpRightDouble: string;
|
|
||||||
lineUpDownLeft: string;
|
|
||||||
lineUpBoldDownBoldLeftBold: string;
|
|
||||||
lineUpBoldDownBoldLeft: string;
|
|
||||||
lineUpDownLeftBold: string;
|
|
||||||
lineUpBoldDownLeftBold: string;
|
|
||||||
lineUpDownBoldLeftBold: string;
|
|
||||||
lineUpDownBoldLeft: string;
|
|
||||||
lineUpBoldDownLeft: string;
|
|
||||||
lineUpDoubleDownDoubleLeftDouble: string;
|
|
||||||
lineUpDoubleDownDoubleLeft: string;
|
|
||||||
lineUpDownLeftDouble: string;
|
|
||||||
lineUpDownRight: string;
|
|
||||||
lineUpBoldDownBoldRightBold: string;
|
|
||||||
lineUpBoldDownBoldRight: string;
|
|
||||||
lineUpDownRightBold: string;
|
|
||||||
lineUpBoldDownRightBold: string;
|
|
||||||
lineUpDownBoldRightBold: string;
|
|
||||||
lineUpDownBoldRight: string;
|
|
||||||
lineUpBoldDownRight: string;
|
|
||||||
lineUpDoubleDownDoubleRightDouble: string;
|
|
||||||
lineUpDoubleDownDoubleRight: string;
|
|
||||||
lineUpDownRightDouble: string;
|
|
||||||
lineDownLeftRight: string;
|
|
||||||
lineDownBoldLeftBoldRightBold: string;
|
|
||||||
lineDownLeftBoldRightBold: string;
|
|
||||||
lineDownBoldLeftRight: string;
|
|
||||||
lineDownBoldLeftBoldRight: string;
|
|
||||||
lineDownBoldLeftRightBold: string;
|
|
||||||
lineDownLeftRightBold: string;
|
|
||||||
lineDownLeftBoldRight: string;
|
|
||||||
lineDownDoubleLeftDoubleRightDouble: string;
|
|
||||||
lineDownDoubleLeftRight: string;
|
|
||||||
lineDownLeftDoubleRightDouble: string;
|
|
||||||
lineUpLeftRight: string;
|
|
||||||
lineUpBoldLeftBoldRightBold: string;
|
|
||||||
lineUpLeftBoldRightBold: string;
|
|
||||||
lineUpBoldLeftRight: string;
|
|
||||||
lineUpBoldLeftBoldRight: string;
|
|
||||||
lineUpBoldLeftRightBold: string;
|
|
||||||
lineUpLeftRightBold: string;
|
|
||||||
lineUpLeftBoldRight: string;
|
|
||||||
lineUpDoubleLeftDoubleRightDouble: string;
|
|
||||||
lineUpDoubleLeftRight: string;
|
|
||||||
lineUpLeftDoubleRightDouble: string;
|
|
||||||
lineUpDownLeftRight: string;
|
|
||||||
lineUpBoldDownBoldLeftBoldRightBold: string;
|
|
||||||
lineUpDownBoldLeftBoldRightBold: string;
|
|
||||||
lineUpBoldDownLeftBoldRightBold: string;
|
|
||||||
lineUpBoldDownBoldLeftRightBold: string;
|
|
||||||
lineUpBoldDownBoldLeftBoldRight: string;
|
|
||||||
lineUpBoldDownLeftRight: string;
|
|
||||||
lineUpDownBoldLeftRight: string;
|
|
||||||
lineUpDownLeftBoldRight: string;
|
|
||||||
lineUpDownLeftRightBold: string;
|
|
||||||
lineUpBoldDownBoldLeftRight: string;
|
|
||||||
lineUpDownLeftBoldRightBold: string;
|
|
||||||
lineUpBoldDownLeftBoldRight: string;
|
|
||||||
lineUpBoldDownLeftRightBold: string;
|
|
||||||
lineUpDownBoldLeftBoldRight: string;
|
|
||||||
lineUpDownBoldLeftRightBold: string;
|
|
||||||
lineUpDoubleDownDoubleLeftDoubleRightDouble: string;
|
|
||||||
lineUpDoubleDownDoubleLeftRight: string;
|
|
||||||
lineUpDownLeftDoubleRightDouble: string;
|
|
||||||
lineCross: string;
|
|
||||||
lineBackslash: string;
|
|
||||||
lineSlash: string;
|
|
||||||
};
|
|
||||||
declare const specialMainSymbols: {
|
|
||||||
tick: string;
|
|
||||||
info: string;
|
|
||||||
warning: string;
|
|
||||||
cross: string;
|
|
||||||
squareSmall: string;
|
|
||||||
squareSmallFilled: string;
|
|
||||||
circle: string;
|
|
||||||
circleFilled: string;
|
|
||||||
circleDotted: string;
|
|
||||||
circleDouble: string;
|
|
||||||
circleCircle: string;
|
|
||||||
circleCross: string;
|
|
||||||
circlePipe: string;
|
|
||||||
radioOn: string;
|
|
||||||
radioOff: string;
|
|
||||||
checkboxOn: string;
|
|
||||||
checkboxOff: string;
|
|
||||||
checkboxCircleOn: string;
|
|
||||||
checkboxCircleOff: string;
|
|
||||||
pointer: string;
|
|
||||||
triangleUpOutline: string;
|
|
||||||
triangleLeft: string;
|
|
||||||
triangleRight: string;
|
|
||||||
lozenge: string;
|
|
||||||
lozengeOutline: string;
|
|
||||||
hamburger: string;
|
|
||||||
smiley: string;
|
|
||||||
mustache: string;
|
|
||||||
star: string;
|
|
||||||
play: string;
|
|
||||||
nodejs: string;
|
|
||||||
oneSeventh: string;
|
|
||||||
oneNinth: string;
|
|
||||||
oneTenth: string;
|
|
||||||
};
|
|
||||||
declare const specialFallbackSymbols: {
|
|
||||||
tick: string;
|
|
||||||
info: string;
|
|
||||||
warning: string;
|
|
||||||
cross: string;
|
|
||||||
squareSmall: string;
|
|
||||||
squareSmallFilled: string;
|
|
||||||
circle: string;
|
|
||||||
circleFilled: string;
|
|
||||||
circleDotted: string;
|
|
||||||
circleDouble: string;
|
|
||||||
circleCircle: string;
|
|
||||||
circleCross: string;
|
|
||||||
circlePipe: string;
|
|
||||||
radioOn: string;
|
|
||||||
radioOff: string;
|
|
||||||
checkboxOn: string;
|
|
||||||
checkboxOff: string;
|
|
||||||
checkboxCircleOn: string;
|
|
||||||
checkboxCircleOff: string;
|
|
||||||
pointer: string;
|
|
||||||
triangleUpOutline: string;
|
|
||||||
triangleLeft: string;
|
|
||||||
triangleRight: string;
|
|
||||||
lozenge: string;
|
|
||||||
lozengeOutline: string;
|
|
||||||
hamburger: string;
|
|
||||||
smiley: string;
|
|
||||||
mustache: string;
|
|
||||||
star: string;
|
|
||||||
play: string;
|
|
||||||
nodejs: string;
|
|
||||||
oneSeventh: string;
|
|
||||||
oneNinth: string;
|
|
||||||
oneTenth: string;
|
|
||||||
};
|
|
||||||
export declare const mainSymbols: typeof common & typeof specialMainSymbols;
|
|
||||||
export declare const fallbackSymbols: (typeof common & typeof specialFallbackSymbols) & Record<string, string>;
|
|
||||||
declare const figures: typeof mainSymbols | typeof fallbackSymbols;
|
|
||||||
export default figures;
|
|
||||||
export declare const replaceSymbols: (string: string, { useFallback }?: {
|
|
||||||
useFallback?: boolean;
|
|
||||||
}) => string;
|
|
||||||
314
node_modules/@inquirer/figures/dist/index.js
generated
vendored
314
node_modules/@inquirer/figures/dist/index.js
generated
vendored
@ -1,314 +0,0 @@
|
|||||||
// process.env dot-notation access prints:
|
|
||||||
// Property 'TERM' comes from an index signature, so it must be accessed with ['TERM'].ts(4111)
|
|
||||||
/* eslint dot-notation: ["off"] */
|
|
||||||
import process from 'node:process';
|
|
||||||
// Ported from is-unicode-supported
|
|
||||||
function isUnicodeSupported() {
|
|
||||||
if (process.platform !== 'win32') {
|
|
||||||
return process.env['TERM'] !== 'linux'; // Linux console (kernel)
|
|
||||||
}
|
|
||||||
return (Boolean(process.env['WT_SESSION']) || // Windows Terminal
|
|
||||||
Boolean(process.env['TERMINUS_SUBLIME']) || // Terminus (<0.2.27)
|
|
||||||
process.env['ConEmuTask'] === '{cmd::Cmder}' || // ConEmu and cmder
|
|
||||||
process.env['TERM_PROGRAM'] === 'Terminus-Sublime' ||
|
|
||||||
process.env['TERM_PROGRAM'] === 'vscode' ||
|
|
||||||
process.env['TERM'] === 'xterm-256color' ||
|
|
||||||
process.env['TERM'] === 'alacritty' ||
|
|
||||||
process.env['TERMINAL_EMULATOR'] === 'JetBrains-JediTerm');
|
|
||||||
}
|
|
||||||
// Ported from figures
|
|
||||||
const common = {
|
|
||||||
circleQuestionMark: '(?)',
|
|
||||||
questionMarkPrefix: '(?)',
|
|
||||||
square: '█',
|
|
||||||
squareDarkShade: '▓',
|
|
||||||
squareMediumShade: '▒',
|
|
||||||
squareLightShade: '░',
|
|
||||||
squareTop: '▀',
|
|
||||||
squareBottom: '▄',
|
|
||||||
squareLeft: '▌',
|
|
||||||
squareRight: '▐',
|
|
||||||
squareCenter: '■',
|
|
||||||
bullet: '●',
|
|
||||||
dot: '․',
|
|
||||||
ellipsis: '…',
|
|
||||||
pointerSmall: '›',
|
|
||||||
triangleUp: '▲',
|
|
||||||
triangleUpSmall: '▴',
|
|
||||||
triangleDown: '▼',
|
|
||||||
triangleDownSmall: '▾',
|
|
||||||
triangleLeftSmall: '◂',
|
|
||||||
triangleRightSmall: '▸',
|
|
||||||
home: '⌂',
|
|
||||||
heart: '♥',
|
|
||||||
musicNote: '♪',
|
|
||||||
musicNoteBeamed: '♫',
|
|
||||||
arrowUp: '↑',
|
|
||||||
arrowDown: '↓',
|
|
||||||
arrowLeft: '←',
|
|
||||||
arrowRight: '→',
|
|
||||||
arrowLeftRight: '↔',
|
|
||||||
arrowUpDown: '↕',
|
|
||||||
almostEqual: '≈',
|
|
||||||
notEqual: '≠',
|
|
||||||
lessOrEqual: '≤',
|
|
||||||
greaterOrEqual: '≥',
|
|
||||||
identical: '≡',
|
|
||||||
infinity: '∞',
|
|
||||||
subscriptZero: '₀',
|
|
||||||
subscriptOne: '₁',
|
|
||||||
subscriptTwo: '₂',
|
|
||||||
subscriptThree: '₃',
|
|
||||||
subscriptFour: '₄',
|
|
||||||
subscriptFive: '₅',
|
|
||||||
subscriptSix: '₆',
|
|
||||||
subscriptSeven: '₇',
|
|
||||||
subscriptEight: '₈',
|
|
||||||
subscriptNine: '₉',
|
|
||||||
oneHalf: '½',
|
|
||||||
oneThird: '⅓',
|
|
||||||
oneQuarter: '¼',
|
|
||||||
oneFifth: '⅕',
|
|
||||||
oneSixth: '⅙',
|
|
||||||
oneEighth: '⅛',
|
|
||||||
twoThirds: '⅔',
|
|
||||||
twoFifths: '⅖',
|
|
||||||
threeQuarters: '¾',
|
|
||||||
threeFifths: '⅗',
|
|
||||||
threeEighths: '⅜',
|
|
||||||
fourFifths: '⅘',
|
|
||||||
fiveSixths: '⅚',
|
|
||||||
fiveEighths: '⅝',
|
|
||||||
sevenEighths: '⅞',
|
|
||||||
line: '─',
|
|
||||||
lineBold: '━',
|
|
||||||
lineDouble: '═',
|
|
||||||
lineDashed0: '┄',
|
|
||||||
lineDashed1: '┅',
|
|
||||||
lineDashed2: '┈',
|
|
||||||
lineDashed3: '┉',
|
|
||||||
lineDashed4: '╌',
|
|
||||||
lineDashed5: '╍',
|
|
||||||
lineDashed6: '╴',
|
|
||||||
lineDashed7: '╶',
|
|
||||||
lineDashed8: '╸',
|
|
||||||
lineDashed9: '╺',
|
|
||||||
lineDashed10: '╼',
|
|
||||||
lineDashed11: '╾',
|
|
||||||
lineDashed12: '−',
|
|
||||||
lineDashed13: '–',
|
|
||||||
lineDashed14: '‐',
|
|
||||||
lineDashed15: '⁃',
|
|
||||||
lineVertical: '│',
|
|
||||||
lineVerticalBold: '┃',
|
|
||||||
lineVerticalDouble: '║',
|
|
||||||
lineVerticalDashed0: '┆',
|
|
||||||
lineVerticalDashed1: '┇',
|
|
||||||
lineVerticalDashed2: '┊',
|
|
||||||
lineVerticalDashed3: '┋',
|
|
||||||
lineVerticalDashed4: '╎',
|
|
||||||
lineVerticalDashed5: '╏',
|
|
||||||
lineVerticalDashed6: '╵',
|
|
||||||
lineVerticalDashed7: '╷',
|
|
||||||
lineVerticalDashed8: '╹',
|
|
||||||
lineVerticalDashed9: '╻',
|
|
||||||
lineVerticalDashed10: '╽',
|
|
||||||
lineVerticalDashed11: '╿',
|
|
||||||
lineDownLeft: '┐',
|
|
||||||
lineDownLeftArc: '╮',
|
|
||||||
lineDownBoldLeftBold: '┓',
|
|
||||||
lineDownBoldLeft: '┒',
|
|
||||||
lineDownLeftBold: '┑',
|
|
||||||
lineDownDoubleLeftDouble: '╗',
|
|
||||||
lineDownDoubleLeft: '╖',
|
|
||||||
lineDownLeftDouble: '╕',
|
|
||||||
lineDownRight: '┌',
|
|
||||||
lineDownRightArc: '╭',
|
|
||||||
lineDownBoldRightBold: '┏',
|
|
||||||
lineDownBoldRight: '┎',
|
|
||||||
lineDownRightBold: '┍',
|
|
||||||
lineDownDoubleRightDouble: '╔',
|
|
||||||
lineDownDoubleRight: '╓',
|
|
||||||
lineDownRightDouble: '╒',
|
|
||||||
lineUpLeft: '┘',
|
|
||||||
lineUpLeftArc: '╯',
|
|
||||||
lineUpBoldLeftBold: '┛',
|
|
||||||
lineUpBoldLeft: '┚',
|
|
||||||
lineUpLeftBold: '┙',
|
|
||||||
lineUpDoubleLeftDouble: '╝',
|
|
||||||
lineUpDoubleLeft: '╜',
|
|
||||||
lineUpLeftDouble: '╛',
|
|
||||||
lineUpRight: '└',
|
|
||||||
lineUpRightArc: '╰',
|
|
||||||
lineUpBoldRightBold: '┗',
|
|
||||||
lineUpBoldRight: '┖',
|
|
||||||
lineUpRightBold: '┕',
|
|
||||||
lineUpDoubleRightDouble: '╚',
|
|
||||||
lineUpDoubleRight: '╙',
|
|
||||||
lineUpRightDouble: '╘',
|
|
||||||
lineUpDownLeft: '┤',
|
|
||||||
lineUpBoldDownBoldLeftBold: '┫',
|
|
||||||
lineUpBoldDownBoldLeft: '┨',
|
|
||||||
lineUpDownLeftBold: '┥',
|
|
||||||
lineUpBoldDownLeftBold: '┩',
|
|
||||||
lineUpDownBoldLeftBold: '┪',
|
|
||||||
lineUpDownBoldLeft: '┧',
|
|
||||||
lineUpBoldDownLeft: '┦',
|
|
||||||
lineUpDoubleDownDoubleLeftDouble: '╣',
|
|
||||||
lineUpDoubleDownDoubleLeft: '╢',
|
|
||||||
lineUpDownLeftDouble: '╡',
|
|
||||||
lineUpDownRight: '├',
|
|
||||||
lineUpBoldDownBoldRightBold: '┣',
|
|
||||||
lineUpBoldDownBoldRight: '┠',
|
|
||||||
lineUpDownRightBold: '┝',
|
|
||||||
lineUpBoldDownRightBold: '┡',
|
|
||||||
lineUpDownBoldRightBold: '┢',
|
|
||||||
lineUpDownBoldRight: '┟',
|
|
||||||
lineUpBoldDownRight: '┞',
|
|
||||||
lineUpDoubleDownDoubleRightDouble: '╠',
|
|
||||||
lineUpDoubleDownDoubleRight: '╟',
|
|
||||||
lineUpDownRightDouble: '╞',
|
|
||||||
lineDownLeftRight: '┬',
|
|
||||||
lineDownBoldLeftBoldRightBold: '┳',
|
|
||||||
lineDownLeftBoldRightBold: '┯',
|
|
||||||
lineDownBoldLeftRight: '┰',
|
|
||||||
lineDownBoldLeftBoldRight: '┱',
|
|
||||||
lineDownBoldLeftRightBold: '┲',
|
|
||||||
lineDownLeftRightBold: '┮',
|
|
||||||
lineDownLeftBoldRight: '┭',
|
|
||||||
lineDownDoubleLeftDoubleRightDouble: '╦',
|
|
||||||
lineDownDoubleLeftRight: '╥',
|
|
||||||
lineDownLeftDoubleRightDouble: '╤',
|
|
||||||
lineUpLeftRight: '┴',
|
|
||||||
lineUpBoldLeftBoldRightBold: '┻',
|
|
||||||
lineUpLeftBoldRightBold: '┷',
|
|
||||||
lineUpBoldLeftRight: '┸',
|
|
||||||
lineUpBoldLeftBoldRight: '┹',
|
|
||||||
lineUpBoldLeftRightBold: '┺',
|
|
||||||
lineUpLeftRightBold: '┶',
|
|
||||||
lineUpLeftBoldRight: '┵',
|
|
||||||
lineUpDoubleLeftDoubleRightDouble: '╩',
|
|
||||||
lineUpDoubleLeftRight: '╨',
|
|
||||||
lineUpLeftDoubleRightDouble: '╧',
|
|
||||||
lineUpDownLeftRight: '┼',
|
|
||||||
lineUpBoldDownBoldLeftBoldRightBold: '╋',
|
|
||||||
lineUpDownBoldLeftBoldRightBold: '╈',
|
|
||||||
lineUpBoldDownLeftBoldRightBold: '╇',
|
|
||||||
lineUpBoldDownBoldLeftRightBold: '╊',
|
|
||||||
lineUpBoldDownBoldLeftBoldRight: '╉',
|
|
||||||
lineUpBoldDownLeftRight: '╀',
|
|
||||||
lineUpDownBoldLeftRight: '╁',
|
|
||||||
lineUpDownLeftBoldRight: '┽',
|
|
||||||
lineUpDownLeftRightBold: '┾',
|
|
||||||
lineUpBoldDownBoldLeftRight: '╂',
|
|
||||||
lineUpDownLeftBoldRightBold: '┿',
|
|
||||||
lineUpBoldDownLeftBoldRight: '╃',
|
|
||||||
lineUpBoldDownLeftRightBold: '╄',
|
|
||||||
lineUpDownBoldLeftBoldRight: '╅',
|
|
||||||
lineUpDownBoldLeftRightBold: '╆',
|
|
||||||
lineUpDoubleDownDoubleLeftDoubleRightDouble: '╬',
|
|
||||||
lineUpDoubleDownDoubleLeftRight: '╫',
|
|
||||||
lineUpDownLeftDoubleRightDouble: '╪',
|
|
||||||
lineCross: '╳',
|
|
||||||
lineBackslash: '╲',
|
|
||||||
lineSlash: '╱',
|
|
||||||
};
|
|
||||||
const specialMainSymbols = {
|
|
||||||
tick: '✔',
|
|
||||||
info: 'ℹ',
|
|
||||||
warning: '⚠',
|
|
||||||
cross: '✘',
|
|
||||||
squareSmall: '◻',
|
|
||||||
squareSmallFilled: '◼',
|
|
||||||
circle: '◯',
|
|
||||||
circleFilled: '◉',
|
|
||||||
circleDotted: '◌',
|
|
||||||
circleDouble: '◎',
|
|
||||||
circleCircle: 'ⓞ',
|
|
||||||
circleCross: 'ⓧ',
|
|
||||||
circlePipe: 'Ⓘ',
|
|
||||||
radioOn: '◉',
|
|
||||||
radioOff: '◯',
|
|
||||||
checkboxOn: '☒',
|
|
||||||
checkboxOff: '☐',
|
|
||||||
checkboxCircleOn: 'ⓧ',
|
|
||||||
checkboxCircleOff: 'Ⓘ',
|
|
||||||
pointer: '❯',
|
|
||||||
triangleUpOutline: '△',
|
|
||||||
triangleLeft: '◀',
|
|
||||||
triangleRight: '▶',
|
|
||||||
lozenge: '◆',
|
|
||||||
lozengeOutline: '◇',
|
|
||||||
hamburger: '☰',
|
|
||||||
smiley: '㋡',
|
|
||||||
mustache: '෴',
|
|
||||||
star: '★',
|
|
||||||
play: '▶',
|
|
||||||
nodejs: '⬢',
|
|
||||||
oneSeventh: '⅐',
|
|
||||||
oneNinth: '⅑',
|
|
||||||
oneTenth: '⅒',
|
|
||||||
};
|
|
||||||
const specialFallbackSymbols = {
|
|
||||||
tick: '√',
|
|
||||||
info: 'i',
|
|
||||||
warning: '‼',
|
|
||||||
cross: '×',
|
|
||||||
squareSmall: '□',
|
|
||||||
squareSmallFilled: '■',
|
|
||||||
circle: '( )',
|
|
||||||
circleFilled: '(*)',
|
|
||||||
circleDotted: '( )',
|
|
||||||
circleDouble: '( )',
|
|
||||||
circleCircle: '(○)',
|
|
||||||
circleCross: '(×)',
|
|
||||||
circlePipe: '(│)',
|
|
||||||
radioOn: '(*)',
|
|
||||||
radioOff: '( )',
|
|
||||||
checkboxOn: '[×]',
|
|
||||||
checkboxOff: '[ ]',
|
|
||||||
checkboxCircleOn: '(×)',
|
|
||||||
checkboxCircleOff: '( )',
|
|
||||||
pointer: '>',
|
|
||||||
triangleUpOutline: '∆',
|
|
||||||
triangleLeft: '◄',
|
|
||||||
triangleRight: '►',
|
|
||||||
lozenge: '♦',
|
|
||||||
lozengeOutline: '◊',
|
|
||||||
hamburger: '≡',
|
|
||||||
smiley: '☺',
|
|
||||||
mustache: '┌─┐',
|
|
||||||
star: '✶',
|
|
||||||
play: '►',
|
|
||||||
nodejs: '♦',
|
|
||||||
oneSeventh: '1/7',
|
|
||||||
oneNinth: '1/9',
|
|
||||||
oneTenth: '1/10',
|
|
||||||
};
|
|
||||||
export const mainSymbols = {
|
|
||||||
...common,
|
|
||||||
...specialMainSymbols,
|
|
||||||
};
|
|
||||||
export const fallbackSymbols = {
|
|
||||||
...common,
|
|
||||||
...specialFallbackSymbols,
|
|
||||||
};
|
|
||||||
const shouldUseMain = isUnicodeSupported();
|
|
||||||
const figures = shouldUseMain
|
|
||||||
? mainSymbols
|
|
||||||
: fallbackSymbols;
|
|
||||||
export default figures;
|
|
||||||
const replacements = Object.entries(specialMainSymbols);
|
|
||||||
// On terminals which do not support Unicode symbols, substitute them to other symbols
|
|
||||||
export const replaceSymbols = (string, { useFallback = !shouldUseMain } = {}) => {
|
|
||||||
if (useFallback) {
|
|
||||||
for (const [key, mainSymbol] of replacements) {
|
|
||||||
const fallbackSymbol = fallbackSymbols[key];
|
|
||||||
if (!fallbackSymbol) {
|
|
||||||
throw new Error(`Unable to find fallback for ${key}`);
|
|
||||||
}
|
|
||||||
string = string.replaceAll(mainSymbol, fallbackSymbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return string;
|
|
||||||
};
|
|
||||||
79
node_modules/@inquirer/figures/package.json
generated
vendored
79
node_modules/@inquirer/figures/package.json
generated
vendored
@ -1,79 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@inquirer/figures",
|
|
||||||
"version": "2.0.3",
|
|
||||||
"description": "Vendored version of figures, for CJS compatibility",
|
|
||||||
"keywords": [
|
|
||||||
"answer",
|
|
||||||
"answers",
|
|
||||||
"ask",
|
|
||||||
"base",
|
|
||||||
"cli",
|
|
||||||
"command",
|
|
||||||
"command-line",
|
|
||||||
"confirm",
|
|
||||||
"enquirer",
|
|
||||||
"generate",
|
|
||||||
"generator",
|
|
||||||
"hyper",
|
|
||||||
"input",
|
|
||||||
"inquire",
|
|
||||||
"inquirer",
|
|
||||||
"interface",
|
|
||||||
"iterm",
|
|
||||||
"javascript",
|
|
||||||
"menu",
|
|
||||||
"node",
|
|
||||||
"nodejs",
|
|
||||||
"prompt",
|
|
||||||
"promptly",
|
|
||||||
"prompts",
|
|
||||||
"question",
|
|
||||||
"readline",
|
|
||||||
"scaffold",
|
|
||||||
"scaffolder",
|
|
||||||
"scaffolding",
|
|
||||||
"stdin",
|
|
||||||
"stdout",
|
|
||||||
"terminal",
|
|
||||||
"tty",
|
|
||||||
"types",
|
|
||||||
"typescript",
|
|
||||||
"ui",
|
|
||||||
"yeoman",
|
|
||||||
"yo",
|
|
||||||
"zsh"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"author": "Simon Boudrias <admin@simonboudrias.com>",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/SBoudrias/Inquirer.js.git"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"type": "module",
|
|
||||||
"sideEffects": false,
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"default": "./dist/index.js"
|
|
||||||
},
|
|
||||||
"./package.json": "./package.json"
|
|
||||||
},
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"tsc": "tsc"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"typescript": "^5.9.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
|
|
||||||
},
|
|
||||||
"main": "./dist/index.js",
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"gitHead": "99d00a9adc53be8b7edf5926b2ec4ba0b792f68f"
|
|
||||||
}
|
|
||||||
22
node_modules/@inquirer/search/LICENSE
generated
vendored
22
node_modules/@inquirer/search/LICENSE
generated
vendored
@ -1,22 +0,0 @@
|
|||||||
Copyright (c) 2025 Simon Boudrias
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
|
||||||
obtaining a copy of this software and associated documentation
|
|
||||||
files (the "Software"), to deal in the Software without
|
|
||||||
restriction, including without limitation the rights to use,
|
|
||||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
213
node_modules/@inquirer/search/README.md
generated
vendored
213
node_modules/@inquirer/search/README.md
generated
vendored
@ -1,213 +0,0 @@
|
|||||||
# `@inquirer/search`
|
|
||||||
|
|
||||||
Interactive search prompt component for command line interfaces.
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
# Installation
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>npm</th>
|
|
||||||
<th>yarn</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm install @inquirer/prompts
|
|
||||||
```
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
```sh
|
|
||||||
yarn add @inquirer/prompts
|
|
||||||
```
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm install @inquirer/search
|
|
||||||
```
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
```sh
|
|
||||||
yarn add @inquirer/search
|
|
||||||
```
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
# Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { search, Separator } from '@inquirer/prompts';
|
|
||||||
// Or
|
|
||||||
// import search, { Separator } from '@inquirer/search';
|
|
||||||
|
|
||||||
const answer = await search({
|
|
||||||
message: 'Select an npm package',
|
|
||||||
source: async (input, { signal }) => {
|
|
||||||
if (!input) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetch(
|
|
||||||
`https://registry.npmjs.org/-/v1/search?text=${encodeURIComponent(input)}&size=20`,
|
|
||||||
{ signal },
|
|
||||||
);
|
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
return data.objects.map((pkg) => ({
|
|
||||||
name: pkg.package.name,
|
|
||||||
value: pkg.package.name,
|
|
||||||
description: pkg.package.description,
|
|
||||||
}));
|
|
||||||
},
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Options
|
|
||||||
|
|
||||||
| Property | Type | Required | Description |
|
|
||||||
| -------- | ---------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
||||||
| message | `string` | yes | The question to ask |
|
|
||||||
| source | `(term: string \| void) => Promise<Choice[]>` | yes | This function returns the choices relevant to the search term. |
|
|
||||||
| pageSize | `number` | no | By default, lists of choice longer than 7 will be paginated. Use this option to control how many choices will appear on the screen at once. |
|
|
||||||
| default | `Value` | no | Defines in front of which item the cursor will initially appear. When omitted, the cursor will appear on the first selectable item. |
|
|
||||||
| validate | `Value => boolean \| string \| Promise<boolean \| string>` | no | On submit, validate the answer. When returning a string, it'll be used as the error message displayed to the user. Note: returning a rejected promise, we'll assume a code error happened and crash. |
|
|
||||||
| theme | [See Theming](#Theming) | no | Customize look of the prompt. |
|
|
||||||
|
|
||||||
### `source` function
|
|
||||||
|
|
||||||
The full signature type of `source` is as follow:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
function(
|
|
||||||
term: string | void,
|
|
||||||
opt: { signal: AbortSignal },
|
|
||||||
): Promise<ReadonlyArray<Choice<Value> | Separator>>;
|
|
||||||
```
|
|
||||||
|
|
||||||
When `term` is `undefined`, it means the search term input is empty. You can use this to return default choices, or return an empty array.
|
|
||||||
|
|
||||||
Aside from returning the choices:
|
|
||||||
|
|
||||||
1. An `AbortSignal` is passed in to cancel ongoing network calls when the search term change.
|
|
||||||
2. `Separator`s can be used to organize the list.
|
|
||||||
|
|
||||||
### `Choice` object
|
|
||||||
|
|
||||||
The `Choice` object is typed as
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type Choice<Value> = {
|
|
||||||
value: Value;
|
|
||||||
name?: string;
|
|
||||||
description?: string;
|
|
||||||
short?: string;
|
|
||||||
disabled?: boolean | string;
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
Here's each property:
|
|
||||||
|
|
||||||
- `value`: The value is what will be returned by `await search()`.
|
|
||||||
- `name`: This is the string displayed in the choice list.
|
|
||||||
- `description`: Option for a longer description string that'll appear under the list when the cursor highlight a given choice.
|
|
||||||
- `short`: Once the prompt is done (press enter), we'll use `short` if defined to render next to the question. By default we'll use `name`.
|
|
||||||
- `disabled`: Disallow the option from being selected. If `disabled` is a string, it'll be used as a help tip explaining why the choice isn't available.
|
|
||||||
|
|
||||||
Choices can also be an array of string, in which case the string will be used both as the `value` and the `name`.
|
|
||||||
|
|
||||||
### Validation & autocomplete interaction
|
|
||||||
|
|
||||||
The validation within the search prompt acts as a signal for the autocomplete feature.
|
|
||||||
|
|
||||||
When a list value is submitted and fail validation, the prompt will compare it to the search term. If they're the same, the prompt display the error. If they're not the same, we'll autocomplete the search term to match the value. Doing this will trigger a new search.
|
|
||||||
|
|
||||||
You can rely on this behavior to implement progressive autocomplete searches. Where you want the user to narrow the search in a progressive manner.
|
|
||||||
|
|
||||||
Pressing `tab` also triggers the term autocomplete.
|
|
||||||
|
|
||||||
You can see this behavior in action in [our search demo](https://github.com/SBoudrias/Inquirer.js/blob/main/packages/demo/src/demos/search.ts).
|
|
||||||
|
|
||||||
## Theming
|
|
||||||
|
|
||||||
You can theme a prompt by passing a `theme` object option. The theme object only need to includes the keys you wish to modify, we'll fallback on the defaults for the rest.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type Theme = {
|
|
||||||
prefix: string | { idle: string; done: string };
|
|
||||||
spinner: {
|
|
||||||
interval: number;
|
|
||||||
frames: string[];
|
|
||||||
};
|
|
||||||
style: {
|
|
||||||
answer: (text: string) => string;
|
|
||||||
message: (text: string, status: 'idle' | 'done' | 'loading') => string;
|
|
||||||
error: (text: string) => string;
|
|
||||||
help: (text: string) => string;
|
|
||||||
highlight: (text: string) => string;
|
|
||||||
description: (text: string) => string;
|
|
||||||
disabled: (text: string) => string;
|
|
||||||
searchTerm: (text: string) => string;
|
|
||||||
keysHelpTip: (keys: [key: string, action: string][]) => string | undefined;
|
|
||||||
};
|
|
||||||
icon: {
|
|
||||||
cursor: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
### `theme.style.keysHelpTip`
|
|
||||||
|
|
||||||
This function allows you to customize the keyboard shortcuts help tip displayed below the prompt. It receives an array of key-action pairs and should return a formatted string. You can also hook here to localize the labels to different languages.
|
|
||||||
|
|
||||||
It can also returns `undefined` to hide the help tip entirely.
|
|
||||||
|
|
||||||
```js
|
|
||||||
theme: {
|
|
||||||
style: {
|
|
||||||
keysHelpTip: (keys) => {
|
|
||||||
// Return undefined to hide the help tip completely.
|
|
||||||
return undefined;
|
|
||||||
|
|
||||||
// Or customize the formatting. Or localize the labels.
|
|
||||||
return keys.map(([key, action]) => `${key}: ${action}`).join(' | ');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Recipes
|
|
||||||
|
|
||||||
### Debounce search
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { setTimeout } from 'node:timers/promises';
|
|
||||||
import { search } from '@inquirer/prompts';
|
|
||||||
|
|
||||||
const answer = await search({
|
|
||||||
message: 'Select an npm package',
|
|
||||||
source: async (input, { signal }) => {
|
|
||||||
await setTimeout(300);
|
|
||||||
if (signal.aborted) return [];
|
|
||||||
|
|
||||||
// Do the search
|
|
||||||
fetch(...)
|
|
||||||
},
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
# License
|
|
||||||
|
|
||||||
Copyright (c) 2024 Simon Boudrias (twitter: [@vaxilart](https://twitter.com/Vaxilart))<br/>
|
|
||||||
Licensed under the MIT license.
|
|
||||||
33
node_modules/@inquirer/search/dist/index.d.ts
generated
vendored
33
node_modules/@inquirer/search/dist/index.d.ts
generated
vendored
@ -1,33 +0,0 @@
|
|||||||
import { Separator, type Theme } from '@inquirer/core';
|
|
||||||
import type { PartialDeep } from '@inquirer/type';
|
|
||||||
type SearchTheme = {
|
|
||||||
icon: {
|
|
||||||
cursor: string;
|
|
||||||
};
|
|
||||||
style: {
|
|
||||||
disabled: (text: string) => string;
|
|
||||||
searchTerm: (text: string) => string;
|
|
||||||
description: (text: string) => string;
|
|
||||||
keysHelpTip: (keys: [key: string, action: string][]) => string | undefined;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
type Choice<Value> = {
|
|
||||||
value: Value;
|
|
||||||
name?: string;
|
|
||||||
description?: string;
|
|
||||||
short?: string;
|
|
||||||
disabled?: boolean | string;
|
|
||||||
type?: never;
|
|
||||||
};
|
|
||||||
declare const _default: <Value>(config: {
|
|
||||||
message: string;
|
|
||||||
source: (term: string | undefined, opt: {
|
|
||||||
signal: AbortSignal;
|
|
||||||
}) => readonly (string | Separator)[] | readonly (Separator | Choice<Value>)[] | Promise<readonly (string | Separator)[]> | Promise<readonly (Separator | Choice<Value>)[]>;
|
|
||||||
validate?: ((value: Value) => boolean | string | Promise<string | boolean>) | undefined;
|
|
||||||
pageSize?: number | undefined;
|
|
||||||
default?: NoInfer<Value> | undefined;
|
|
||||||
theme?: PartialDeep<Theme<SearchTheme>> | undefined;
|
|
||||||
}, context?: import("@inquirer/type").Context) => Promise<Value>;
|
|
||||||
export default _default;
|
|
||||||
export { Separator } from '@inquirer/core';
|
|
||||||
193
node_modules/@inquirer/search/dist/index.js
generated
vendored
193
node_modules/@inquirer/search/dist/index.js
generated
vendored
@ -1,193 +0,0 @@
|
|||||||
import { createPrompt, useState, useKeypress, usePrefix, usePagination, useEffect, useMemo, useRef, isDownKey, isEnterKey, isTabKey, isUpKey, Separator, makeTheme, } from '@inquirer/core';
|
|
||||||
import { styleText } from 'node:util';
|
|
||||||
import figures from '@inquirer/figures';
|
|
||||||
const searchTheme = {
|
|
||||||
icon: { cursor: figures.pointer },
|
|
||||||
style: {
|
|
||||||
disabled: (text) => styleText('dim', `- ${text}`),
|
|
||||||
searchTerm: (text) => styleText('cyan', text),
|
|
||||||
description: (text) => styleText('cyan', text),
|
|
||||||
keysHelpTip: (keys) => keys
|
|
||||||
.map(([key, action]) => `${styleText('bold', key)} ${styleText('dim', action)}`)
|
|
||||||
.join(styleText('dim', ' • ')),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
function isSelectable(item) {
|
|
||||||
return !Separator.isSeparator(item) && !item.disabled;
|
|
||||||
}
|
|
||||||
function normalizeChoices(choices) {
|
|
||||||
return choices.map((choice) => {
|
|
||||||
if (Separator.isSeparator(choice))
|
|
||||||
return choice;
|
|
||||||
if (typeof choice === 'string') {
|
|
||||||
return {
|
|
||||||
value: choice,
|
|
||||||
name: choice,
|
|
||||||
short: choice,
|
|
||||||
disabled: false,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const name = choice.name ?? String(choice.value);
|
|
||||||
const normalizedChoice = {
|
|
||||||
value: choice.value,
|
|
||||||
name,
|
|
||||||
short: choice.short ?? name,
|
|
||||||
disabled: choice.disabled ?? false,
|
|
||||||
};
|
|
||||||
if (choice.description) {
|
|
||||||
normalizedChoice.description = choice.description;
|
|
||||||
}
|
|
||||||
return normalizedChoice;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
export default createPrompt((config, done) => {
|
|
||||||
const { pageSize = 7, validate = () => true } = config;
|
|
||||||
const theme = makeTheme(searchTheme, config.theme);
|
|
||||||
const [status, setStatus] = useState('loading');
|
|
||||||
const [searchTerm, setSearchTerm] = useState('');
|
|
||||||
const [searchResults, setSearchResults] = useState([]);
|
|
||||||
const [searchError, setSearchError] = useState();
|
|
||||||
const defaultApplied = useRef(false);
|
|
||||||
const prefix = usePrefix({ status, theme });
|
|
||||||
const bounds = useMemo(() => {
|
|
||||||
const first = searchResults.findIndex(isSelectable);
|
|
||||||
const last = searchResults.findLastIndex(isSelectable);
|
|
||||||
return { first, last };
|
|
||||||
}, [searchResults]);
|
|
||||||
const [active = bounds.first, setActive] = useState();
|
|
||||||
useEffect(() => {
|
|
||||||
const controller = new AbortController();
|
|
||||||
setStatus('loading');
|
|
||||||
setSearchError(undefined);
|
|
||||||
const fetchResults = async () => {
|
|
||||||
try {
|
|
||||||
const results = await config.source(searchTerm || undefined, {
|
|
||||||
signal: controller.signal,
|
|
||||||
});
|
|
||||||
if (!controller.signal.aborted) {
|
|
||||||
const normalized = normalizeChoices(results);
|
|
||||||
let initialActive;
|
|
||||||
if (!defaultApplied.current && 'default' in config) {
|
|
||||||
const defaultIndex = normalized.findIndex((item) => isSelectable(item) && item.value === config.default);
|
|
||||||
initialActive = defaultIndex === -1 ? undefined : defaultIndex;
|
|
||||||
defaultApplied.current = true;
|
|
||||||
}
|
|
||||||
setActive(initialActive);
|
|
||||||
setSearchError(undefined);
|
|
||||||
setSearchResults(normalized);
|
|
||||||
setStatus('idle');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
if (!controller.signal.aborted && error instanceof Error) {
|
|
||||||
setSearchError(error.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
void fetchResults();
|
|
||||||
return () => {
|
|
||||||
controller.abort();
|
|
||||||
};
|
|
||||||
}, [searchTerm]);
|
|
||||||
// Safe to assume the cursor position never points to a Separator.
|
|
||||||
const selectedChoice = searchResults[active];
|
|
||||||
useKeypress(async (key, rl) => {
|
|
||||||
if (isEnterKey(key)) {
|
|
||||||
if (selectedChoice) {
|
|
||||||
setStatus('loading');
|
|
||||||
const isValid = await validate(selectedChoice.value);
|
|
||||||
setStatus('idle');
|
|
||||||
if (isValid === true) {
|
|
||||||
setStatus('done');
|
|
||||||
done(selectedChoice.value);
|
|
||||||
}
|
|
||||||
else if (selectedChoice.name === searchTerm) {
|
|
||||||
setSearchError(isValid || 'You must provide a valid value');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Reset line with new search term
|
|
||||||
rl.write(selectedChoice.name);
|
|
||||||
setSearchTerm(selectedChoice.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Reset the readline line value to the previous value. On line event, the value
|
|
||||||
// get cleared, forcing the user to re-enter the value instead of fixing it.
|
|
||||||
rl.write(searchTerm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (isTabKey(key) && selectedChoice) {
|
|
||||||
rl.clearLine(0); // Remove the tab character.
|
|
||||||
rl.write(selectedChoice.name);
|
|
||||||
setSearchTerm(selectedChoice.name);
|
|
||||||
}
|
|
||||||
else if (status !== 'loading' && (isUpKey(key) || isDownKey(key))) {
|
|
||||||
rl.clearLine(0);
|
|
||||||
if ((isUpKey(key) && active !== bounds.first) ||
|
|
||||||
(isDownKey(key) && active !== bounds.last)) {
|
|
||||||
const offset = isUpKey(key) ? -1 : 1;
|
|
||||||
let next = active;
|
|
||||||
do {
|
|
||||||
next = (next + offset + searchResults.length) % searchResults.length;
|
|
||||||
} while (!isSelectable(searchResults[next]));
|
|
||||||
setActive(next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setSearchTerm(rl.line);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const message = theme.style.message(config.message, status);
|
|
||||||
const helpLine = theme.style.keysHelpTip([
|
|
||||||
['↑↓', 'navigate'],
|
|
||||||
['⏎', 'select'],
|
|
||||||
]);
|
|
||||||
const page = usePagination({
|
|
||||||
items: searchResults,
|
|
||||||
active,
|
|
||||||
renderItem({ item, isActive }) {
|
|
||||||
if (Separator.isSeparator(item)) {
|
|
||||||
return ` ${item.separator}`;
|
|
||||||
}
|
|
||||||
if (item.disabled) {
|
|
||||||
const disabledLabel = typeof item.disabled === 'string' ? item.disabled : '(disabled)';
|
|
||||||
return theme.style.disabled(`${item.name} ${disabledLabel}`);
|
|
||||||
}
|
|
||||||
const color = isActive ? theme.style.highlight : (x) => x;
|
|
||||||
const cursor = isActive ? theme.icon.cursor : ` `;
|
|
||||||
return color(`${cursor} ${item.name}`);
|
|
||||||
},
|
|
||||||
pageSize,
|
|
||||||
loop: false,
|
|
||||||
});
|
|
||||||
let error;
|
|
||||||
if (searchError) {
|
|
||||||
error = theme.style.error(searchError);
|
|
||||||
}
|
|
||||||
else if (searchResults.length === 0 && searchTerm !== '' && status === 'idle') {
|
|
||||||
error = theme.style.error('No results found');
|
|
||||||
}
|
|
||||||
let searchStr;
|
|
||||||
if (status === 'done' && selectedChoice) {
|
|
||||||
return [prefix, message, theme.style.answer(selectedChoice.short)]
|
|
||||||
.filter(Boolean)
|
|
||||||
.join(' ')
|
|
||||||
.trimEnd();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
searchStr = theme.style.searchTerm(searchTerm);
|
|
||||||
}
|
|
||||||
const description = selectedChoice?.description;
|
|
||||||
const header = [prefix, message, searchStr].filter(Boolean).join(' ').trimEnd();
|
|
||||||
const body = [
|
|
||||||
error ?? page,
|
|
||||||
' ',
|
|
||||||
description ? theme.style.description(description) : '',
|
|
||||||
helpLine,
|
|
||||||
]
|
|
||||||
.filter(Boolean)
|
|
||||||
.join('\n')
|
|
||||||
.trimEnd();
|
|
||||||
return [header, body];
|
|
||||||
});
|
|
||||||
export { Separator } from '@inquirer/core';
|
|
||||||
92
node_modules/@inquirer/search/package.json
generated
vendored
92
node_modules/@inquirer/search/package.json
generated
vendored
@ -1,92 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@inquirer/search",
|
|
||||||
"version": "4.1.4",
|
|
||||||
"description": "Inquirer search prompt",
|
|
||||||
"keywords": [
|
|
||||||
"answer",
|
|
||||||
"answers",
|
|
||||||
"ask",
|
|
||||||
"base",
|
|
||||||
"cli",
|
|
||||||
"command",
|
|
||||||
"command-line",
|
|
||||||
"confirm",
|
|
||||||
"enquirer",
|
|
||||||
"generate",
|
|
||||||
"generator",
|
|
||||||
"hyper",
|
|
||||||
"input",
|
|
||||||
"inquire",
|
|
||||||
"inquirer",
|
|
||||||
"interface",
|
|
||||||
"iterm",
|
|
||||||
"javascript",
|
|
||||||
"menu",
|
|
||||||
"node",
|
|
||||||
"nodejs",
|
|
||||||
"prompt",
|
|
||||||
"promptly",
|
|
||||||
"prompts",
|
|
||||||
"question",
|
|
||||||
"readline",
|
|
||||||
"scaffold",
|
|
||||||
"scaffolder",
|
|
||||||
"scaffolding",
|
|
||||||
"stdin",
|
|
||||||
"stdout",
|
|
||||||
"terminal",
|
|
||||||
"tty",
|
|
||||||
"ui",
|
|
||||||
"yeoman",
|
|
||||||
"yo",
|
|
||||||
"zsh"
|
|
||||||
],
|
|
||||||
"homepage": "https://github.com/SBoudrias/Inquirer.js/blob/main/packages/search/README.md",
|
|
||||||
"license": "MIT",
|
|
||||||
"author": "Simon Boudrias <admin@simonboudrias.com>",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/SBoudrias/Inquirer.js.git"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"type": "module",
|
|
||||||
"sideEffects": false,
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"default": "./dist/index.js"
|
|
||||||
},
|
|
||||||
"./package.json": "./package.json"
|
|
||||||
},
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"tsc": "tsc"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@inquirer/core": "^11.1.5",
|
|
||||||
"@inquirer/figures": "^2.0.3",
|
|
||||||
"@inquirer/type": "^4.0.3"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@inquirer/testing": "^3.3.0",
|
|
||||||
"typescript": "^5.9.3"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@types/node": ">=18"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@types/node": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
|
|
||||||
},
|
|
||||||
"main": "./dist/index.js",
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"gitHead": "526eca2e64853510821ffd457561840ec0cbfb93"
|
|
||||||
}
|
|
||||||
22
node_modules/@inquirer/select/LICENSE
generated
vendored
22
node_modules/@inquirer/select/LICENSE
generated
vendored
@ -1,22 +0,0 @@
|
|||||||
Copyright (c) 2025 Simon Boudrias
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
|
||||||
obtaining a copy of this software and associated documentation
|
|
||||||
files (the "Software"), to deal in the Software without
|
|
||||||
restriction, including without limitation the rights to use,
|
|
||||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
181
node_modules/@inquirer/select/README.md
generated
vendored
181
node_modules/@inquirer/select/README.md
generated
vendored
@ -1,181 +0,0 @@
|
|||||||
# `@inquirer/select`
|
|
||||||
|
|
||||||
Simple interactive command line prompt to display a list of choices (single select.)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
# Installation
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<th>npm</th>
|
|
||||||
<th>yarn</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm install @inquirer/prompts
|
|
||||||
```
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
```sh
|
|
||||||
yarn add @inquirer/prompts
|
|
||||||
```
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colSpan="2" align="center">Or</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm install @inquirer/select
|
|
||||||
```
|
|
||||||
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
|
|
||||||
```sh
|
|
||||||
yarn add @inquirer/select
|
|
||||||
```
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
# Usage
|
|
||||||
|
|
||||||
```js
|
|
||||||
import { select, Separator } from '@inquirer/prompts';
|
|
||||||
// Or
|
|
||||||
// import select, { Separator } from '@inquirer/select';
|
|
||||||
|
|
||||||
const answer = await select({
|
|
||||||
message: 'Select a package manager',
|
|
||||||
choices: [
|
|
||||||
{
|
|
||||||
name: 'npm',
|
|
||||||
value: 'npm',
|
|
||||||
description: 'npm is the most popular package manager',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'yarn',
|
|
||||||
value: 'yarn',
|
|
||||||
description: 'yarn is an awesome package manager',
|
|
||||||
},
|
|
||||||
new Separator(),
|
|
||||||
{
|
|
||||||
name: 'jspm',
|
|
||||||
value: 'jspm',
|
|
||||||
disabled: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'pnpm',
|
|
||||||
value: 'pnpm',
|
|
||||||
disabled: '(pnpm is not available)',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Options
|
|
||||||
|
|
||||||
| Property | Type | Required | Description |
|
|
||||||
| -------- | ----------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
||||||
| message | `string` | yes | The question to ask |
|
|
||||||
| choices | `Choice[]` | yes | List of the available choices. |
|
|
||||||
| default | `string` | no | Defines in front of which item the cursor will initially appear. When omitted, the cursor will appear on the first selectable item. |
|
|
||||||
| pageSize | `number` | no | By default, lists of choice longer than 7 will be paginated. Use this option to control how many choices will appear on the screen at once. |
|
|
||||||
| loop | `boolean` | no | Defaults to `true`. When set to `false`, the cursor will be constrained to the top and bottom of the choice list without looping. |
|
|
||||||
| theme | [See Theming](#Theming) | no | Customize look of the prompt. |
|
|
||||||
|
|
||||||
`Separator` objects can be used in the `choices` array to render non-selectable lines in the choice list. By default it'll render a line, but you can provide the text as argument (`new Separator('-- Dependencies --')`). This option is often used to add labels to groups within long list of options.
|
|
||||||
|
|
||||||
### `Choice` object
|
|
||||||
|
|
||||||
The `Choice` object is typed as
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type Choice<Value> = {
|
|
||||||
value: Value;
|
|
||||||
name?: string;
|
|
||||||
description?: string;
|
|
||||||
short?: string;
|
|
||||||
disabled?: boolean | string;
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
Here's each property:
|
|
||||||
|
|
||||||
- `value`: The value is what will be returned by `await select()`.
|
|
||||||
- `name`: This is the string displayed in the choice list.
|
|
||||||
- `description`: Option for a longer description string that'll appear under the list when the cursor highlight a given choice.
|
|
||||||
- `short`: Once the prompt is done (press enter), we'll use `short` if defined to render next to the question. By default we'll use `name`.
|
|
||||||
- `disabled`: Disallow the option from being selected. If `disabled` is a string, it'll be used as a help tip explaining why the choice isn't available.
|
|
||||||
|
|
||||||
`choices` can also be an array of string, in which case the string will be used both as the `value` and the `name`.
|
|
||||||
|
|
||||||
## Theming
|
|
||||||
|
|
||||||
You can theme a prompt by passing a `theme` object option. The theme object only need to includes the keys you wish to modify, we'll fallback on the defaults for the rest.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
type Theme = {
|
|
||||||
prefix: string | { idle: string; done: string };
|
|
||||||
spinner: {
|
|
||||||
interval: number;
|
|
||||||
frames: string[];
|
|
||||||
};
|
|
||||||
style: {
|
|
||||||
answer: (text: string) => string;
|
|
||||||
message: (text: string, status: 'idle' | 'done' | 'loading') => string;
|
|
||||||
error: (text: string) => string;
|
|
||||||
help: (text: string) => string;
|
|
||||||
highlight: (text: string) => string;
|
|
||||||
description: (text: string) => string;
|
|
||||||
disabled: (text: string) => string;
|
|
||||||
keysHelpTip: (keys: [key: string, action: string][]) => string | undefined;
|
|
||||||
};
|
|
||||||
icon: {
|
|
||||||
cursor: string;
|
|
||||||
};
|
|
||||||
indexMode: 'hidden' | 'number';
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
### `theme.style.keysHelpTip`
|
|
||||||
|
|
||||||
This function allows you to customize the keyboard shortcuts help tip displayed below the prompt. It receives an array of key-action pairs and should return a formatted string. You can also hook here to localize the labels to different languages.
|
|
||||||
|
|
||||||
It can also returns `undefined` to hide the help tip entirely.
|
|
||||||
|
|
||||||
```js
|
|
||||||
theme: {
|
|
||||||
style: {
|
|
||||||
keysHelpTip: (keys) => {
|
|
||||||
// Return undefined to hide the help tip completely.
|
|
||||||
return undefined;
|
|
||||||
|
|
||||||
// Or customize the formatting. Or localize the labels.
|
|
||||||
return keys.map(([key, action]) => `${key}: ${action}`).join(' | ');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### `theme.indexMode`
|
|
||||||
|
|
||||||
Controls how indices are displayed before each choice:
|
|
||||||
|
|
||||||
- `hidden` (default): No indices are shown
|
|
||||||
- `number`: Display a number before each choice (e.g. "1. Option A")
|
|
||||||
|
|
||||||
# License
|
|
||||||
|
|
||||||
Copyright (c) 2023 Simon Boudrias (twitter: [@vaxilart](https://twitter.com/Vaxilart))<br/>
|
|
||||||
Licensed under the MIT license.
|
|
||||||
35
node_modules/@inquirer/select/dist/index.d.ts
generated
vendored
35
node_modules/@inquirer/select/dist/index.d.ts
generated
vendored
@ -1,35 +0,0 @@
|
|||||||
import { Separator, type Theme, type Keybinding } from '@inquirer/core';
|
|
||||||
import type { PartialDeep } from '@inquirer/type';
|
|
||||||
type SelectTheme = {
|
|
||||||
icon: {
|
|
||||||
cursor: string;
|
|
||||||
};
|
|
||||||
style: {
|
|
||||||
disabled: (text: string) => string;
|
|
||||||
description: (text: string) => string;
|
|
||||||
keysHelpTip: (keys: [key: string, action: string][]) => string | undefined;
|
|
||||||
};
|
|
||||||
i18n: {
|
|
||||||
disabledError: string;
|
|
||||||
};
|
|
||||||
indexMode: 'hidden' | 'number';
|
|
||||||
keybindings: ReadonlyArray<Keybinding>;
|
|
||||||
};
|
|
||||||
type Choice<Value> = {
|
|
||||||
value: Value;
|
|
||||||
name?: string;
|
|
||||||
description?: string;
|
|
||||||
short?: string;
|
|
||||||
disabled?: boolean | string;
|
|
||||||
type?: never;
|
|
||||||
};
|
|
||||||
declare const _default: <Value>(config: {
|
|
||||||
message: string;
|
|
||||||
choices: readonly (Separator | Value | Choice<Value>)[];
|
|
||||||
pageSize?: number | undefined;
|
|
||||||
loop?: boolean | undefined;
|
|
||||||
default?: NoInfer<Value> | undefined;
|
|
||||||
theme?: PartialDeep<Theme<SelectTheme>> | undefined;
|
|
||||||
}, context?: import("@inquirer/type").Context) => Promise<Value>;
|
|
||||||
export default _default;
|
|
||||||
export { Separator } from '@inquirer/core';
|
|
||||||
191
node_modules/@inquirer/select/dist/index.js
generated
vendored
191
node_modules/@inquirer/select/dist/index.js
generated
vendored
@ -1,191 +0,0 @@
|
|||||||
import { createPrompt, useState, useKeypress, usePrefix, usePagination, useRef, useMemo, useEffect, isBackspaceKey, isEnterKey, isUpKey, isDownKey, isNumberKey, Separator, ValidationError, makeTheme, } from '@inquirer/core';
|
|
||||||
import { cursorHide } from '@inquirer/ansi';
|
|
||||||
import { styleText } from 'node:util';
|
|
||||||
import figures from '@inquirer/figures';
|
|
||||||
const selectTheme = {
|
|
||||||
icon: { cursor: figures.pointer },
|
|
||||||
style: {
|
|
||||||
disabled: (text) => styleText('dim', text),
|
|
||||||
description: (text) => styleText('cyan', text),
|
|
||||||
keysHelpTip: (keys) => keys
|
|
||||||
.map(([key, action]) => `${styleText('bold', key)} ${styleText('dim', action)}`)
|
|
||||||
.join(styleText('dim', ' • ')),
|
|
||||||
},
|
|
||||||
i18n: { disabledError: 'This option is disabled and cannot be selected.' },
|
|
||||||
indexMode: 'hidden',
|
|
||||||
keybindings: [],
|
|
||||||
};
|
|
||||||
function isSelectable(item) {
|
|
||||||
return !Separator.isSeparator(item) && !item.disabled;
|
|
||||||
}
|
|
||||||
function isNavigable(item) {
|
|
||||||
return !Separator.isSeparator(item);
|
|
||||||
}
|
|
||||||
function normalizeChoices(choices) {
|
|
||||||
return choices.map((choice) => {
|
|
||||||
if (Separator.isSeparator(choice))
|
|
||||||
return choice;
|
|
||||||
if (typeof choice !== 'object' || choice === null || !('value' in choice)) {
|
|
||||||
// It's a raw value (string, number, etc.)
|
|
||||||
const name = String(choice);
|
|
||||||
return {
|
|
||||||
value: choice,
|
|
||||||
name,
|
|
||||||
short: name,
|
|
||||||
disabled: false,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const name = choice.name ?? String(choice.value);
|
|
||||||
const normalizedChoice = {
|
|
||||||
value: choice.value,
|
|
||||||
name,
|
|
||||||
short: choice.short ?? name,
|
|
||||||
disabled: choice.disabled ?? false,
|
|
||||||
};
|
|
||||||
if (choice.description) {
|
|
||||||
normalizedChoice.description = choice.description;
|
|
||||||
}
|
|
||||||
return normalizedChoice;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
export default createPrompt((config, done) => {
|
|
||||||
const { loop = true, pageSize = 7 } = config;
|
|
||||||
const theme = makeTheme(selectTheme, config.theme);
|
|
||||||
const { keybindings } = theme;
|
|
||||||
const [status, setStatus] = useState('idle');
|
|
||||||
const prefix = usePrefix({ status, theme });
|
|
||||||
const searchTimeoutRef = useRef();
|
|
||||||
// Vim keybindings (j/k) conflict with typing those letters in search,
|
|
||||||
// so search must be disabled when vim bindings are enabled
|
|
||||||
const searchEnabled = !keybindings.includes('vim');
|
|
||||||
const items = useMemo(() => normalizeChoices(config.choices), [config.choices]);
|
|
||||||
const bounds = useMemo(() => {
|
|
||||||
const first = items.findIndex(isNavigable);
|
|
||||||
const last = items.findLastIndex(isNavigable);
|
|
||||||
if (first === -1) {
|
|
||||||
throw new ValidationError('[select prompt] No selectable choices. All choices are disabled.');
|
|
||||||
}
|
|
||||||
return { first, last };
|
|
||||||
}, [items]);
|
|
||||||
const defaultItemIndex = useMemo(() => {
|
|
||||||
if (!('default' in config))
|
|
||||||
return -1;
|
|
||||||
return items.findIndex((item) => isSelectable(item) && item.value === config.default);
|
|
||||||
}, [config.default, items]);
|
|
||||||
const [active, setActive] = useState(defaultItemIndex === -1 ? bounds.first : defaultItemIndex);
|
|
||||||
// Safe to assume the cursor position always point to a Choice.
|
|
||||||
const selectedChoice = items[active];
|
|
||||||
const [errorMsg, setError] = useState();
|
|
||||||
useKeypress((key, rl) => {
|
|
||||||
clearTimeout(searchTimeoutRef.current);
|
|
||||||
if (errorMsg) {
|
|
||||||
setError(undefined);
|
|
||||||
}
|
|
||||||
if (isEnterKey(key)) {
|
|
||||||
if (selectedChoice.disabled) {
|
|
||||||
setError(theme.i18n.disabledError);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
setStatus('done');
|
|
||||||
done(selectedChoice.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (isUpKey(key, keybindings) || isDownKey(key, keybindings)) {
|
|
||||||
rl.clearLine(0);
|
|
||||||
if (loop ||
|
|
||||||
(isUpKey(key, keybindings) && active !== bounds.first) ||
|
|
||||||
(isDownKey(key, keybindings) && active !== bounds.last)) {
|
|
||||||
const offset = isUpKey(key, keybindings) ? -1 : 1;
|
|
||||||
let next = active;
|
|
||||||
do {
|
|
||||||
next = (next + offset + items.length) % items.length;
|
|
||||||
} while (!isNavigable(items[next]));
|
|
||||||
setActive(next);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (isNumberKey(key) && !Number.isNaN(Number(rl.line))) {
|
|
||||||
const selectedIndex = Number(rl.line) - 1;
|
|
||||||
// Find the nth item (ignoring separators)
|
|
||||||
let selectableIndex = -1;
|
|
||||||
const position = items.findIndex((item) => {
|
|
||||||
if (Separator.isSeparator(item))
|
|
||||||
return false;
|
|
||||||
selectableIndex++;
|
|
||||||
return selectableIndex === selectedIndex;
|
|
||||||
});
|
|
||||||
const item = items[position];
|
|
||||||
if (item != null && isSelectable(item)) {
|
|
||||||
setActive(position);
|
|
||||||
}
|
|
||||||
searchTimeoutRef.current = setTimeout(() => {
|
|
||||||
rl.clearLine(0);
|
|
||||||
}, 700);
|
|
||||||
}
|
|
||||||
else if (isBackspaceKey(key)) {
|
|
||||||
rl.clearLine(0);
|
|
||||||
}
|
|
||||||
else if (searchEnabled) {
|
|
||||||
const searchTerm = rl.line.toLowerCase();
|
|
||||||
const matchIndex = items.findIndex((item) => {
|
|
||||||
if (Separator.isSeparator(item) || !isSelectable(item))
|
|
||||||
return false;
|
|
||||||
return item.name.toLowerCase().startsWith(searchTerm);
|
|
||||||
});
|
|
||||||
if (matchIndex !== -1) {
|
|
||||||
setActive(matchIndex);
|
|
||||||
}
|
|
||||||
searchTimeoutRef.current = setTimeout(() => {
|
|
||||||
rl.clearLine(0);
|
|
||||||
}, 700);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
useEffect(() => () => {
|
|
||||||
clearTimeout(searchTimeoutRef.current);
|
|
||||||
}, []);
|
|
||||||
const message = theme.style.message(config.message, status);
|
|
||||||
const helpLine = theme.style.keysHelpTip([
|
|
||||||
['↑↓', 'navigate'],
|
|
||||||
['⏎', 'select'],
|
|
||||||
]);
|
|
||||||
let separatorCount = 0;
|
|
||||||
const page = usePagination({
|
|
||||||
items,
|
|
||||||
active,
|
|
||||||
renderItem({ item, isActive, index }) {
|
|
||||||
if (Separator.isSeparator(item)) {
|
|
||||||
separatorCount++;
|
|
||||||
return ` ${item.separator}`;
|
|
||||||
}
|
|
||||||
const cursor = isActive ? theme.icon.cursor : ' ';
|
|
||||||
const indexLabel = theme.indexMode === 'number' ? `${index + 1 - separatorCount}. ` : '';
|
|
||||||
if (item.disabled) {
|
|
||||||
const disabledLabel = typeof item.disabled === 'string' ? item.disabled : '(disabled)';
|
|
||||||
const disabledCursor = isActive ? theme.icon.cursor : '-';
|
|
||||||
return theme.style.disabled(`${disabledCursor} ${indexLabel}${item.name} ${disabledLabel}`);
|
|
||||||
}
|
|
||||||
const color = isActive ? theme.style.highlight : (x) => x;
|
|
||||||
return color(`${cursor} ${indexLabel}${item.name}`);
|
|
||||||
},
|
|
||||||
pageSize,
|
|
||||||
loop,
|
|
||||||
});
|
|
||||||
if (status === 'done') {
|
|
||||||
return [prefix, message, theme.style.answer(selectedChoice.short)]
|
|
||||||
.filter(Boolean)
|
|
||||||
.join(' ');
|
|
||||||
}
|
|
||||||
const { description } = selectedChoice;
|
|
||||||
const lines = [
|
|
||||||
[prefix, message].filter(Boolean).join(' '),
|
|
||||||
page,
|
|
||||||
' ',
|
|
||||||
description ? theme.style.description(description) : '',
|
|
||||||
errorMsg ? theme.style.error(errorMsg) : '',
|
|
||||||
helpLine,
|
|
||||||
]
|
|
||||||
.filter(Boolean)
|
|
||||||
.join('\n')
|
|
||||||
.trimEnd();
|
|
||||||
return `${lines}${cursorHide}`;
|
|
||||||
});
|
|
||||||
export { Separator } from '@inquirer/core';
|
|
||||||
93
node_modules/@inquirer/select/package.json
generated
vendored
93
node_modules/@inquirer/select/package.json
generated
vendored
@ -1,93 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@inquirer/select",
|
|
||||||
"version": "5.1.0",
|
|
||||||
"description": "Inquirer select/list prompt",
|
|
||||||
"keywords": [
|
|
||||||
"answer",
|
|
||||||
"answers",
|
|
||||||
"ask",
|
|
||||||
"base",
|
|
||||||
"cli",
|
|
||||||
"command",
|
|
||||||
"command-line",
|
|
||||||
"confirm",
|
|
||||||
"enquirer",
|
|
||||||
"generate",
|
|
||||||
"generator",
|
|
||||||
"hyper",
|
|
||||||
"input",
|
|
||||||
"inquire",
|
|
||||||
"inquirer",
|
|
||||||
"interface",
|
|
||||||
"iterm",
|
|
||||||
"javascript",
|
|
||||||
"menu",
|
|
||||||
"node",
|
|
||||||
"nodejs",
|
|
||||||
"prompt",
|
|
||||||
"promptly",
|
|
||||||
"prompts",
|
|
||||||
"question",
|
|
||||||
"readline",
|
|
||||||
"scaffold",
|
|
||||||
"scaffolder",
|
|
||||||
"scaffolding",
|
|
||||||
"stdin",
|
|
||||||
"stdout",
|
|
||||||
"terminal",
|
|
||||||
"tty",
|
|
||||||
"ui",
|
|
||||||
"yeoman",
|
|
||||||
"yo",
|
|
||||||
"zsh"
|
|
||||||
],
|
|
||||||
"homepage": "https://github.com/SBoudrias/Inquirer.js/blob/main/packages/select/README.md",
|
|
||||||
"license": "MIT",
|
|
||||||
"author": "Simon Boudrias <admin@simonboudrias.com>",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/SBoudrias/Inquirer.js.git"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"type": "module",
|
|
||||||
"sideEffects": false,
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"default": "./dist/index.js"
|
|
||||||
},
|
|
||||||
"./package.json": "./package.json"
|
|
||||||
},
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"tsc": "tsc"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@inquirer/ansi": "^2.0.3",
|
|
||||||
"@inquirer/core": "^11.1.5",
|
|
||||||
"@inquirer/figures": "^2.0.3",
|
|
||||||
"@inquirer/type": "^4.0.3"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@inquirer/testing": "^3.3.0",
|
|
||||||
"typescript": "^5.9.3"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@types/node": ">=18"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@types/node": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
|
|
||||||
},
|
|
||||||
"main": "./dist/index.js",
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"gitHead": "526eca2e64853510821ffd457561840ec0cbfb93"
|
|
||||||
}
|
|
||||||
22
node_modules/@inquirer/type/LICENSE
generated
vendored
22
node_modules/@inquirer/type/LICENSE
generated
vendored
@ -1,22 +0,0 @@
|
|||||||
Copyright (c) 2025 Simon Boudrias
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person
|
|
||||||
obtaining a copy of this software and associated documentation
|
|
||||||
files (the "Software"), to deal in the Software without
|
|
||||||
restriction, including without limitation the rights to use,
|
|
||||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the
|
|
||||||
Software is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
||||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
||||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
||||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
2
node_modules/@inquirer/type/dist/index.d.ts
generated
vendored
2
node_modules/@inquirer/type/dist/index.d.ts
generated
vendored
@ -1,2 +0,0 @@
|
|||||||
export * from './inquirer.ts';
|
|
||||||
export * from './utils.ts';
|
|
||||||
2
node_modules/@inquirer/type/dist/index.js
generated
vendored
2
node_modules/@inquirer/type/dist/index.js
generated
vendored
@ -1,2 +0,0 @@
|
|||||||
export * from "./inquirer.js";
|
|
||||||
export * from "./utils.js";
|
|
||||||
35
node_modules/@inquirer/type/dist/inquirer.d.ts
generated
vendored
35
node_modules/@inquirer/type/dist/inquirer.d.ts
generated
vendored
@ -1,35 +0,0 @@
|
|||||||
import { Duplex } from 'node:stream';
|
|
||||||
/**
|
|
||||||
* `InquirerReadline` is a re-implementation of `readline.Interface` from Node.js.
|
|
||||||
* We're reimplementing it because of 3 reasons:
|
|
||||||
* 1. The `readline.Interface` API is not complete; it's missing for example `clearLine`.
|
|
||||||
* 2. The input/output streams are not generics, meaning they're inexact.
|
|
||||||
* 3. Since ReadLine isn't built-in Typescript Global NodeJS type, it'd force us to ship `@types/node` as a dependency to all users.
|
|
||||||
*/
|
|
||||||
export type InquirerReadline = {
|
|
||||||
output: Duplex & {
|
|
||||||
mute: () => void;
|
|
||||||
unmute: () => void;
|
|
||||||
};
|
|
||||||
input: NodeJS.ReadableStream;
|
|
||||||
clearLine: (dir: 0 | 1 | -1) => void;
|
|
||||||
getCursorPos: () => {
|
|
||||||
rows: number;
|
|
||||||
cols: number;
|
|
||||||
};
|
|
||||||
setPrompt: (prompt: string) => void;
|
|
||||||
line: string;
|
|
||||||
write: (data: string) => void;
|
|
||||||
on: (event: string, listener: (...args: unknown[]) => void) => void;
|
|
||||||
removeListener: (event: string, listener: (...args: unknown[]) => void) => void;
|
|
||||||
pause: () => void;
|
|
||||||
resume: () => void;
|
|
||||||
close: () => void;
|
|
||||||
};
|
|
||||||
export type Context = {
|
|
||||||
input?: NodeJS.ReadableStream;
|
|
||||||
output?: NodeJS.WritableStream;
|
|
||||||
clearPromptOnDone?: boolean;
|
|
||||||
signal?: AbortSignal;
|
|
||||||
};
|
|
||||||
export type Prompt<Value, Config> = (config: Config, context?: Context) => Promise<Value>;
|
|
||||||
1
node_modules/@inquirer/type/dist/inquirer.js
generated
vendored
1
node_modules/@inquirer/type/dist/inquirer.js
generated
vendored
@ -1 +0,0 @@
|
|||||||
export {};
|
|
||||||
29
node_modules/@inquirer/type/dist/utils.d.ts
generated
vendored
29
node_modules/@inquirer/type/dist/utils.d.ts
generated
vendored
@ -1,29 +0,0 @@
|
|||||||
type Key = string | number | symbol;
|
|
||||||
export type Prettify<T> = {
|
|
||||||
[K in keyof T]: T[K];
|
|
||||||
} & {};
|
|
||||||
export type PartialDeep<T> = T extends object ? {
|
|
||||||
[P in keyof T]?: PartialDeep<T[P]>;
|
|
||||||
} : T;
|
|
||||||
export type LiteralUnion<T extends F, F = string> = T | (F & {});
|
|
||||||
export type KeyUnion<T> = LiteralUnion<Extract<keyof T, string>>;
|
|
||||||
export type DistributiveMerge<A, B> = A extends any ? Prettify<Omit<A, keyof B> & B> : never;
|
|
||||||
export type UnionToIntersection<T> = (T extends any ? (input: T) => void : never) extends (input: infer Intersection) => void ? Intersection : never;
|
|
||||||
/**
|
|
||||||
* @hidden
|
|
||||||
*/
|
|
||||||
type __Pick<O extends object, K extends keyof O> = {
|
|
||||||
[P in K]: O[P];
|
|
||||||
} & {};
|
|
||||||
/**
|
|
||||||
* @hidden
|
|
||||||
*/
|
|
||||||
export type _Pick<O extends object, K extends Key> = __Pick<O, keyof O & K>;
|
|
||||||
/**
|
|
||||||
* Extract out of `O` the fields of key `K`
|
|
||||||
* @param O to extract from
|
|
||||||
* @param K to chose fields
|
|
||||||
* @returns [[Object]]
|
|
||||||
*/
|
|
||||||
export type Pick<O extends object, K extends Key> = O extends unknown ? _Pick<O, K> : never;
|
|
||||||
export {};
|
|
||||||
2
node_modules/@inquirer/type/dist/utils.js
generated
vendored
2
node_modules/@inquirer/type/dist/utils.js
generated
vendored
@ -1,2 +0,0 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
||||||
export {};
|
|
||||||
87
node_modules/@inquirer/type/package.json
generated
vendored
87
node_modules/@inquirer/type/package.json
generated
vendored
@ -1,87 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@inquirer/type",
|
|
||||||
"version": "4.0.3",
|
|
||||||
"description": "Inquirer core TS types",
|
|
||||||
"keywords": [
|
|
||||||
"answer",
|
|
||||||
"answers",
|
|
||||||
"ask",
|
|
||||||
"base",
|
|
||||||
"cli",
|
|
||||||
"command",
|
|
||||||
"command-line",
|
|
||||||
"confirm",
|
|
||||||
"enquirer",
|
|
||||||
"generate",
|
|
||||||
"generator",
|
|
||||||
"hyper",
|
|
||||||
"input",
|
|
||||||
"inquire",
|
|
||||||
"inquirer",
|
|
||||||
"interface",
|
|
||||||
"iterm",
|
|
||||||
"javascript",
|
|
||||||
"menu",
|
|
||||||
"node",
|
|
||||||
"nodejs",
|
|
||||||
"prompt",
|
|
||||||
"promptly",
|
|
||||||
"prompts",
|
|
||||||
"question",
|
|
||||||
"readline",
|
|
||||||
"scaffold",
|
|
||||||
"scaffolder",
|
|
||||||
"scaffolding",
|
|
||||||
"stdin",
|
|
||||||
"stdout",
|
|
||||||
"terminal",
|
|
||||||
"tty",
|
|
||||||
"types",
|
|
||||||
"typescript",
|
|
||||||
"ui",
|
|
||||||
"yeoman",
|
|
||||||
"yo",
|
|
||||||
"zsh"
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"author": "Simon Boudrias <admin@simonboudrias.com>",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/SBoudrias/Inquirer.js.git"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"type": "module",
|
|
||||||
"sideEffects": false,
|
|
||||||
"exports": {
|
|
||||||
".": {
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"default": "./dist/index.js"
|
|
||||||
},
|
|
||||||
"./package.json": "./package.json"
|
|
||||||
},
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"tsc": "tsc"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"typescript": "^5.9.3"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@types/node": ">=18"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@types/node": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0"
|
|
||||||
},
|
|
||||||
"main": "./dist/index.js",
|
|
||||||
"types": "./dist/index.d.ts",
|
|
||||||
"gitHead": "99d00a9adc53be8b7edf5926b2ec4ba0b792f68f"
|
|
||||||
}
|
|
||||||
21
node_modules/@nodelib/fs.scandir/LICENSE
generated
vendored
21
node_modules/@nodelib/fs.scandir/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) Denis Malinochkin
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
171
node_modules/@nodelib/fs.scandir/README.md
generated
vendored
171
node_modules/@nodelib/fs.scandir/README.md
generated
vendored
@ -1,171 +0,0 @@
|
|||||||
# @nodelib/fs.scandir
|
|
||||||
|
|
||||||
> List files and directories inside the specified directory.
|
|
||||||
|
|
||||||
## :bulb: Highlights
|
|
||||||
|
|
||||||
The package is aimed at obtaining information about entries in the directory.
|
|
||||||
|
|
||||||
* :moneybag: Returns useful information: `name`, `path`, `dirent` and `stats` (optional).
|
|
||||||
* :gear: On Node.js 10.10+ uses the mechanism without additional calls to determine the entry type. See [`old` and `modern` mode](#old-and-modern-mode).
|
|
||||||
* :link: Can safely work with broken symbolic links.
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
```console
|
|
||||||
npm install @nodelib/fs.scandir
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import * as fsScandir from '@nodelib/fs.scandir';
|
|
||||||
|
|
||||||
fsScandir.scandir('path', (error, stats) => { /* … */ });
|
|
||||||
```
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### .scandir(path, [optionsOrSettings], callback)
|
|
||||||
|
|
||||||
Returns an array of plain objects ([`Entry`](#entry)) with information about entry for provided path with standard callback-style.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
fsScandir.scandir('path', (error, entries) => { /* … */ });
|
|
||||||
fsScandir.scandir('path', {}, (error, entries) => { /* … */ });
|
|
||||||
fsScandir.scandir('path', new fsScandir.Settings(), (error, entries) => { /* … */ });
|
|
||||||
```
|
|
||||||
|
|
||||||
### .scandirSync(path, [optionsOrSettings])
|
|
||||||
|
|
||||||
Returns an array of plain objects ([`Entry`](#entry)) with information about entry for provided path.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const entries = fsScandir.scandirSync('path');
|
|
||||||
const entries = fsScandir.scandirSync('path', {});
|
|
||||||
const entries = fsScandir.scandirSync(('path', new fsScandir.Settings());
|
|
||||||
```
|
|
||||||
|
|
||||||
#### path
|
|
||||||
|
|
||||||
* Required: `true`
|
|
||||||
* Type: `string | Buffer | URL`
|
|
||||||
|
|
||||||
A path to a file. If a URL is provided, it must use the `file:` protocol.
|
|
||||||
|
|
||||||
#### optionsOrSettings
|
|
||||||
|
|
||||||
* Required: `false`
|
|
||||||
* Type: `Options | Settings`
|
|
||||||
* Default: An instance of `Settings` class
|
|
||||||
|
|
||||||
An [`Options`](#options) object or an instance of [`Settings`](#settingsoptions) class.
|
|
||||||
|
|
||||||
> :book: When you pass a plain object, an instance of the `Settings` class will be created automatically. If you plan to call the method frequently, use a pre-created instance of the `Settings` class.
|
|
||||||
|
|
||||||
### Settings([options])
|
|
||||||
|
|
||||||
A class of full settings of the package.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const settings = new fsScandir.Settings({ followSymbolicLinks: false });
|
|
||||||
|
|
||||||
const entries = fsScandir.scandirSync('path', settings);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Entry
|
|
||||||
|
|
||||||
* `name` — The name of the entry (`unknown.txt`).
|
|
||||||
* `path` — The path of the entry relative to call directory (`root/unknown.txt`).
|
|
||||||
* `dirent` — An instance of [`fs.Dirent`](./src/types/index.ts) class. On Node.js below 10.10 will be emulated by [`DirentFromStats`](./src/utils/fs.ts) class.
|
|
||||||
* `stats` (optional) — An instance of `fs.Stats` class.
|
|
||||||
|
|
||||||
For example, the `scandir` call for `tools` directory with one directory inside:
|
|
||||||
|
|
||||||
```ts
|
|
||||||
{
|
|
||||||
dirent: Dirent { name: 'typedoc', /* … */ },
|
|
||||||
name: 'typedoc',
|
|
||||||
path: 'tools/typedoc'
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Options
|
|
||||||
|
|
||||||
### stats
|
|
||||||
|
|
||||||
* Type: `boolean`
|
|
||||||
* Default: `false`
|
|
||||||
|
|
||||||
Adds an instance of `fs.Stats` class to the [`Entry`](#entry).
|
|
||||||
|
|
||||||
> :book: Always use `fs.readdir` without the `withFileTypes` option. ??TODO??
|
|
||||||
|
|
||||||
### followSymbolicLinks
|
|
||||||
|
|
||||||
* Type: `boolean`
|
|
||||||
* Default: `false`
|
|
||||||
|
|
||||||
Follow symbolic links or not. Call `fs.stat` on symbolic link if `true`.
|
|
||||||
|
|
||||||
### `throwErrorOnBrokenSymbolicLink`
|
|
||||||
|
|
||||||
* Type: `boolean`
|
|
||||||
* Default: `true`
|
|
||||||
|
|
||||||
Throw an error when symbolic link is broken if `true` or safely use `lstat` call if `false`.
|
|
||||||
|
|
||||||
### `pathSegmentSeparator`
|
|
||||||
|
|
||||||
* Type: `string`
|
|
||||||
* Default: `path.sep`
|
|
||||||
|
|
||||||
By default, this package uses the correct path separator for your OS (`\` on Windows, `/` on Unix-like systems). But you can set this option to any separator character(s) that you want to use instead.
|
|
||||||
|
|
||||||
### `fs`
|
|
||||||
|
|
||||||
* Type: [`FileSystemAdapter`](./src/adapters/fs.ts)
|
|
||||||
* Default: A default FS methods
|
|
||||||
|
|
||||||
By default, the built-in Node.js module (`fs`) is used to work with the file system. You can replace any method with your own.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
interface FileSystemAdapter {
|
|
||||||
lstat?: typeof fs.lstat;
|
|
||||||
stat?: typeof fs.stat;
|
|
||||||
lstatSync?: typeof fs.lstatSync;
|
|
||||||
statSync?: typeof fs.statSync;
|
|
||||||
readdir?: typeof fs.readdir;
|
|
||||||
readdirSync?: typeof fs.readdirSync;
|
|
||||||
}
|
|
||||||
|
|
||||||
const settings = new fsScandir.Settings({
|
|
||||||
fs: { lstat: fakeLstat }
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## `old` and `modern` mode
|
|
||||||
|
|
||||||
This package has two modes that are used depending on the environment and parameters of use.
|
|
||||||
|
|
||||||
### old
|
|
||||||
|
|
||||||
* Node.js below `10.10` or when the `stats` option is enabled
|
|
||||||
|
|
||||||
When working in the old mode, the directory is read first (`fs.readdir`), then the type of entries is determined (`fs.lstat` and/or `fs.stat` for symbolic links).
|
|
||||||
|
|
||||||
### modern
|
|
||||||
|
|
||||||
* Node.js 10.10+ and the `stats` option is disabled
|
|
||||||
|
|
||||||
In the modern mode, reading the directory (`fs.readdir` with the `withFileTypes` option) is combined with obtaining information about its entries. An additional call for symbolic links (`fs.stat`) is still present.
|
|
||||||
|
|
||||||
This mode makes fewer calls to the file system. It's faster.
|
|
||||||
|
|
||||||
## Changelog
|
|
||||||
|
|
||||||
See the [Releases section of our GitHub project](https://github.com/nodelib/nodelib/releases) for changelog for each release version.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This software is released under the terms of the MIT license.
|
|
||||||
20
node_modules/@nodelib/fs.scandir/out/adapters/fs.d.ts
generated
vendored
20
node_modules/@nodelib/fs.scandir/out/adapters/fs.d.ts
generated
vendored
@ -1,20 +0,0 @@
|
|||||||
import type * as fsStat from '@nodelib/fs.stat';
|
|
||||||
import type { Dirent, ErrnoException } from '../types';
|
|
||||||
export interface ReaddirAsynchronousMethod {
|
|
||||||
(filepath: string, options: {
|
|
||||||
withFileTypes: true;
|
|
||||||
}, callback: (error: ErrnoException | null, files: Dirent[]) => void): void;
|
|
||||||
(filepath: string, callback: (error: ErrnoException | null, files: string[]) => void): void;
|
|
||||||
}
|
|
||||||
export interface ReaddirSynchronousMethod {
|
|
||||||
(filepath: string, options: {
|
|
||||||
withFileTypes: true;
|
|
||||||
}): Dirent[];
|
|
||||||
(filepath: string): string[];
|
|
||||||
}
|
|
||||||
export declare type FileSystemAdapter = fsStat.FileSystemAdapter & {
|
|
||||||
readdir: ReaddirAsynchronousMethod;
|
|
||||||
readdirSync: ReaddirSynchronousMethod;
|
|
||||||
};
|
|
||||||
export declare const FILE_SYSTEM_ADAPTER: FileSystemAdapter;
|
|
||||||
export declare function createFileSystemAdapter(fsMethods?: Partial<FileSystemAdapter>): FileSystemAdapter;
|
|
||||||
19
node_modules/@nodelib/fs.scandir/out/adapters/fs.js
generated
vendored
19
node_modules/@nodelib/fs.scandir/out/adapters/fs.js
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0;
|
|
||||||
const fs = require("fs");
|
|
||||||
exports.FILE_SYSTEM_ADAPTER = {
|
|
||||||
lstat: fs.lstat,
|
|
||||||
stat: fs.stat,
|
|
||||||
lstatSync: fs.lstatSync,
|
|
||||||
statSync: fs.statSync,
|
|
||||||
readdir: fs.readdir,
|
|
||||||
readdirSync: fs.readdirSync
|
|
||||||
};
|
|
||||||
function createFileSystemAdapter(fsMethods) {
|
|
||||||
if (fsMethods === undefined) {
|
|
||||||
return exports.FILE_SYSTEM_ADAPTER;
|
|
||||||
}
|
|
||||||
return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods);
|
|
||||||
}
|
|
||||||
exports.createFileSystemAdapter = createFileSystemAdapter;
|
|
||||||
4
node_modules/@nodelib/fs.scandir/out/constants.d.ts
generated
vendored
4
node_modules/@nodelib/fs.scandir/out/constants.d.ts
generated
vendored
@ -1,4 +0,0 @@
|
|||||||
/**
|
|
||||||
* IS `true` for Node.js 10.10 and greater.
|
|
||||||
*/
|
|
||||||
export declare const IS_SUPPORT_READDIR_WITH_FILE_TYPES: boolean;
|
|
||||||
17
node_modules/@nodelib/fs.scandir/out/constants.js
generated
vendored
17
node_modules/@nodelib/fs.scandir/out/constants.js
generated
vendored
@ -1,17 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = void 0;
|
|
||||||
const NODE_PROCESS_VERSION_PARTS = process.versions.node.split('.');
|
|
||||||
if (NODE_PROCESS_VERSION_PARTS[0] === undefined || NODE_PROCESS_VERSION_PARTS[1] === undefined) {
|
|
||||||
throw new Error(`Unexpected behavior. The 'process.versions.node' variable has invalid value: ${process.versions.node}`);
|
|
||||||
}
|
|
||||||
const MAJOR_VERSION = Number.parseInt(NODE_PROCESS_VERSION_PARTS[0], 10);
|
|
||||||
const MINOR_VERSION = Number.parseInt(NODE_PROCESS_VERSION_PARTS[1], 10);
|
|
||||||
const SUPPORTED_MAJOR_VERSION = 10;
|
|
||||||
const SUPPORTED_MINOR_VERSION = 10;
|
|
||||||
const IS_MATCHED_BY_MAJOR = MAJOR_VERSION > SUPPORTED_MAJOR_VERSION;
|
|
||||||
const IS_MATCHED_BY_MAJOR_AND_MINOR = MAJOR_VERSION === SUPPORTED_MAJOR_VERSION && MINOR_VERSION >= SUPPORTED_MINOR_VERSION;
|
|
||||||
/**
|
|
||||||
* IS `true` for Node.js 10.10 and greater.
|
|
||||||
*/
|
|
||||||
exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_BY_MAJOR_AND_MINOR;
|
|
||||||
12
node_modules/@nodelib/fs.scandir/out/index.d.ts
generated
vendored
12
node_modules/@nodelib/fs.scandir/out/index.d.ts
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
import type { FileSystemAdapter, ReaddirAsynchronousMethod, ReaddirSynchronousMethod } from './adapters/fs';
|
|
||||||
import * as async from './providers/async';
|
|
||||||
import Settings, { Options } from './settings';
|
|
||||||
import type { Dirent, Entry } from './types';
|
|
||||||
declare type AsyncCallback = async.AsyncCallback;
|
|
||||||
declare function scandir(path: string, callback: AsyncCallback): void;
|
|
||||||
declare function scandir(path: string, optionsOrSettings: Options | Settings, callback: AsyncCallback): void;
|
|
||||||
declare namespace scandir {
|
|
||||||
function __promisify__(path: string, optionsOrSettings?: Options | Settings): Promise<Entry[]>;
|
|
||||||
}
|
|
||||||
declare function scandirSync(path: string, optionsOrSettings?: Options | Settings): Entry[];
|
|
||||||
export { scandir, scandirSync, Settings, AsyncCallback, Dirent, Entry, FileSystemAdapter, ReaddirAsynchronousMethod, ReaddirSynchronousMethod, Options };
|
|
||||||
26
node_modules/@nodelib/fs.scandir/out/index.js
generated
vendored
26
node_modules/@nodelib/fs.scandir/out/index.js
generated
vendored
@ -1,26 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.Settings = exports.scandirSync = exports.scandir = void 0;
|
|
||||||
const async = require("./providers/async");
|
|
||||||
const sync = require("./providers/sync");
|
|
||||||
const settings_1 = require("./settings");
|
|
||||||
exports.Settings = settings_1.default;
|
|
||||||
function scandir(path, optionsOrSettingsOrCallback, callback) {
|
|
||||||
if (typeof optionsOrSettingsOrCallback === 'function') {
|
|
||||||
async.read(path, getSettings(), optionsOrSettingsOrCallback);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
async.read(path, getSettings(optionsOrSettingsOrCallback), callback);
|
|
||||||
}
|
|
||||||
exports.scandir = scandir;
|
|
||||||
function scandirSync(path, optionsOrSettings) {
|
|
||||||
const settings = getSettings(optionsOrSettings);
|
|
||||||
return sync.read(path, settings);
|
|
||||||
}
|
|
||||||
exports.scandirSync = scandirSync;
|
|
||||||
function getSettings(settingsOrOptions = {}) {
|
|
||||||
if (settingsOrOptions instanceof settings_1.default) {
|
|
||||||
return settingsOrOptions;
|
|
||||||
}
|
|
||||||
return new settings_1.default(settingsOrOptions);
|
|
||||||
}
|
|
||||||
7
node_modules/@nodelib/fs.scandir/out/providers/async.d.ts
generated
vendored
7
node_modules/@nodelib/fs.scandir/out/providers/async.d.ts
generated
vendored
@ -1,7 +0,0 @@
|
|||||||
/// <reference types="node" />
|
|
||||||
import type Settings from '../settings';
|
|
||||||
import type { Entry } from '../types';
|
|
||||||
export declare type AsyncCallback = (error: NodeJS.ErrnoException, entries: Entry[]) => void;
|
|
||||||
export declare function read(directory: string, settings: Settings, callback: AsyncCallback): void;
|
|
||||||
export declare function readdirWithFileTypes(directory: string, settings: Settings, callback: AsyncCallback): void;
|
|
||||||
export declare function readdir(directory: string, settings: Settings, callback: AsyncCallback): void;
|
|
||||||
104
node_modules/@nodelib/fs.scandir/out/providers/async.js
generated
vendored
104
node_modules/@nodelib/fs.scandir/out/providers/async.js
generated
vendored
@ -1,104 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.readdir = exports.readdirWithFileTypes = exports.read = void 0;
|
|
||||||
const fsStat = require("@nodelib/fs.stat");
|
|
||||||
const rpl = require("run-parallel");
|
|
||||||
const constants_1 = require("../constants");
|
|
||||||
const utils = require("../utils");
|
|
||||||
const common = require("./common");
|
|
||||||
function read(directory, settings, callback) {
|
|
||||||
if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
|
|
||||||
readdirWithFileTypes(directory, settings, callback);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
readdir(directory, settings, callback);
|
|
||||||
}
|
|
||||||
exports.read = read;
|
|
||||||
function readdirWithFileTypes(directory, settings, callback) {
|
|
||||||
settings.fs.readdir(directory, { withFileTypes: true }, (readdirError, dirents) => {
|
|
||||||
if (readdirError !== null) {
|
|
||||||
callFailureCallback(callback, readdirError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const entries = dirents.map((dirent) => ({
|
|
||||||
dirent,
|
|
||||||
name: dirent.name,
|
|
||||||
path: common.joinPathSegments(directory, dirent.name, settings.pathSegmentSeparator)
|
|
||||||
}));
|
|
||||||
if (!settings.followSymbolicLinks) {
|
|
||||||
callSuccessCallback(callback, entries);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const tasks = entries.map((entry) => makeRplTaskEntry(entry, settings));
|
|
||||||
rpl(tasks, (rplError, rplEntries) => {
|
|
||||||
if (rplError !== null) {
|
|
||||||
callFailureCallback(callback, rplError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callSuccessCallback(callback, rplEntries);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.readdirWithFileTypes = readdirWithFileTypes;
|
|
||||||
function makeRplTaskEntry(entry, settings) {
|
|
||||||
return (done) => {
|
|
||||||
if (!entry.dirent.isSymbolicLink()) {
|
|
||||||
done(null, entry);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
settings.fs.stat(entry.path, (statError, stats) => {
|
|
||||||
if (statError !== null) {
|
|
||||||
if (settings.throwErrorOnBrokenSymbolicLink) {
|
|
||||||
done(statError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
done(null, entry);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
entry.dirent = utils.fs.createDirentFromStats(entry.name, stats);
|
|
||||||
done(null, entry);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
function readdir(directory, settings, callback) {
|
|
||||||
settings.fs.readdir(directory, (readdirError, names) => {
|
|
||||||
if (readdirError !== null) {
|
|
||||||
callFailureCallback(callback, readdirError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const tasks = names.map((name) => {
|
|
||||||
const path = common.joinPathSegments(directory, name, settings.pathSegmentSeparator);
|
|
||||||
return (done) => {
|
|
||||||
fsStat.stat(path, settings.fsStatSettings, (error, stats) => {
|
|
||||||
if (error !== null) {
|
|
||||||
done(error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const entry = {
|
|
||||||
name,
|
|
||||||
path,
|
|
||||||
dirent: utils.fs.createDirentFromStats(name, stats)
|
|
||||||
};
|
|
||||||
if (settings.stats) {
|
|
||||||
entry.stats = stats;
|
|
||||||
}
|
|
||||||
done(null, entry);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
});
|
|
||||||
rpl(tasks, (rplError, entries) => {
|
|
||||||
if (rplError !== null) {
|
|
||||||
callFailureCallback(callback, rplError);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callSuccessCallback(callback, entries);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.readdir = readdir;
|
|
||||||
function callFailureCallback(callback, error) {
|
|
||||||
callback(error);
|
|
||||||
}
|
|
||||||
function callSuccessCallback(callback, result) {
|
|
||||||
callback(null, result);
|
|
||||||
}
|
|
||||||
1
node_modules/@nodelib/fs.scandir/out/providers/common.d.ts
generated
vendored
1
node_modules/@nodelib/fs.scandir/out/providers/common.d.ts
generated
vendored
@ -1 +0,0 @@
|
|||||||
export declare function joinPathSegments(a: string, b: string, separator: string): string;
|
|
||||||
13
node_modules/@nodelib/fs.scandir/out/providers/common.js
generated
vendored
13
node_modules/@nodelib/fs.scandir/out/providers/common.js
generated
vendored
@ -1,13 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.joinPathSegments = void 0;
|
|
||||||
function joinPathSegments(a, b, separator) {
|
|
||||||
/**
|
|
||||||
* The correct handling of cases when the first segment is a root (`/`, `C:/`) or UNC path (`//?/C:/`).
|
|
||||||
*/
|
|
||||||
if (a.endsWith(separator)) {
|
|
||||||
return a + b;
|
|
||||||
}
|
|
||||||
return a + separator + b;
|
|
||||||
}
|
|
||||||
exports.joinPathSegments = joinPathSegments;
|
|
||||||
5
node_modules/@nodelib/fs.scandir/out/providers/sync.d.ts
generated
vendored
5
node_modules/@nodelib/fs.scandir/out/providers/sync.d.ts
generated
vendored
@ -1,5 +0,0 @@
|
|||||||
import type Settings from '../settings';
|
|
||||||
import type { Entry } from '../types';
|
|
||||||
export declare function read(directory: string, settings: Settings): Entry[];
|
|
||||||
export declare function readdirWithFileTypes(directory: string, settings: Settings): Entry[];
|
|
||||||
export declare function readdir(directory: string, settings: Settings): Entry[];
|
|
||||||
54
node_modules/@nodelib/fs.scandir/out/providers/sync.js
generated
vendored
54
node_modules/@nodelib/fs.scandir/out/providers/sync.js
generated
vendored
@ -1,54 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.readdir = exports.readdirWithFileTypes = exports.read = void 0;
|
|
||||||
const fsStat = require("@nodelib/fs.stat");
|
|
||||||
const constants_1 = require("../constants");
|
|
||||||
const utils = require("../utils");
|
|
||||||
const common = require("./common");
|
|
||||||
function read(directory, settings) {
|
|
||||||
if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) {
|
|
||||||
return readdirWithFileTypes(directory, settings);
|
|
||||||
}
|
|
||||||
return readdir(directory, settings);
|
|
||||||
}
|
|
||||||
exports.read = read;
|
|
||||||
function readdirWithFileTypes(directory, settings) {
|
|
||||||
const dirents = settings.fs.readdirSync(directory, { withFileTypes: true });
|
|
||||||
return dirents.map((dirent) => {
|
|
||||||
const entry = {
|
|
||||||
dirent,
|
|
||||||
name: dirent.name,
|
|
||||||
path: common.joinPathSegments(directory, dirent.name, settings.pathSegmentSeparator)
|
|
||||||
};
|
|
||||||
if (entry.dirent.isSymbolicLink() && settings.followSymbolicLinks) {
|
|
||||||
try {
|
|
||||||
const stats = settings.fs.statSync(entry.path);
|
|
||||||
entry.dirent = utils.fs.createDirentFromStats(entry.name, stats);
|
|
||||||
}
|
|
||||||
catch (error) {
|
|
||||||
if (settings.throwErrorOnBrokenSymbolicLink) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return entry;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.readdirWithFileTypes = readdirWithFileTypes;
|
|
||||||
function readdir(directory, settings) {
|
|
||||||
const names = settings.fs.readdirSync(directory);
|
|
||||||
return names.map((name) => {
|
|
||||||
const entryPath = common.joinPathSegments(directory, name, settings.pathSegmentSeparator);
|
|
||||||
const stats = fsStat.statSync(entryPath, settings.fsStatSettings);
|
|
||||||
const entry = {
|
|
||||||
name,
|
|
||||||
path: entryPath,
|
|
||||||
dirent: utils.fs.createDirentFromStats(name, stats)
|
|
||||||
};
|
|
||||||
if (settings.stats) {
|
|
||||||
entry.stats = stats;
|
|
||||||
}
|
|
||||||
return entry;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
exports.readdir = readdir;
|
|
||||||
20
node_modules/@nodelib/fs.scandir/out/settings.d.ts
generated
vendored
20
node_modules/@nodelib/fs.scandir/out/settings.d.ts
generated
vendored
@ -1,20 +0,0 @@
|
|||||||
import * as fsStat from '@nodelib/fs.stat';
|
|
||||||
import * as fs from './adapters/fs';
|
|
||||||
export interface Options {
|
|
||||||
followSymbolicLinks?: boolean;
|
|
||||||
fs?: Partial<fs.FileSystemAdapter>;
|
|
||||||
pathSegmentSeparator?: string;
|
|
||||||
stats?: boolean;
|
|
||||||
throwErrorOnBrokenSymbolicLink?: boolean;
|
|
||||||
}
|
|
||||||
export default class Settings {
|
|
||||||
private readonly _options;
|
|
||||||
readonly followSymbolicLinks: boolean;
|
|
||||||
readonly fs: fs.FileSystemAdapter;
|
|
||||||
readonly pathSegmentSeparator: string;
|
|
||||||
readonly stats: boolean;
|
|
||||||
readonly throwErrorOnBrokenSymbolicLink: boolean;
|
|
||||||
readonly fsStatSettings: fsStat.Settings;
|
|
||||||
constructor(_options?: Options);
|
|
||||||
private _getValue;
|
|
||||||
}
|
|
||||||
24
node_modules/@nodelib/fs.scandir/out/settings.js
generated
vendored
24
node_modules/@nodelib/fs.scandir/out/settings.js
generated
vendored
@ -1,24 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
const path = require("path");
|
|
||||||
const fsStat = require("@nodelib/fs.stat");
|
|
||||||
const fs = require("./adapters/fs");
|
|
||||||
class Settings {
|
|
||||||
constructor(_options = {}) {
|
|
||||||
this._options = _options;
|
|
||||||
this.followSymbolicLinks = this._getValue(this._options.followSymbolicLinks, false);
|
|
||||||
this.fs = fs.createFileSystemAdapter(this._options.fs);
|
|
||||||
this.pathSegmentSeparator = this._getValue(this._options.pathSegmentSeparator, path.sep);
|
|
||||||
this.stats = this._getValue(this._options.stats, false);
|
|
||||||
this.throwErrorOnBrokenSymbolicLink = this._getValue(this._options.throwErrorOnBrokenSymbolicLink, true);
|
|
||||||
this.fsStatSettings = new fsStat.Settings({
|
|
||||||
followSymbolicLink: this.followSymbolicLinks,
|
|
||||||
fs: this.fs,
|
|
||||||
throwErrorOnBrokenSymbolicLink: this.throwErrorOnBrokenSymbolicLink
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_getValue(option, value) {
|
|
||||||
return option !== null && option !== void 0 ? option : value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.default = Settings;
|
|
||||||
20
node_modules/@nodelib/fs.scandir/out/types/index.d.ts
generated
vendored
20
node_modules/@nodelib/fs.scandir/out/types/index.d.ts
generated
vendored
@ -1,20 +0,0 @@
|
|||||||
/// <reference types="node" />
|
|
||||||
import type * as fs from 'fs';
|
|
||||||
export interface Entry {
|
|
||||||
dirent: Dirent;
|
|
||||||
name: string;
|
|
||||||
path: string;
|
|
||||||
stats?: Stats;
|
|
||||||
}
|
|
||||||
export declare type Stats = fs.Stats;
|
|
||||||
export declare type ErrnoException = NodeJS.ErrnoException;
|
|
||||||
export interface Dirent {
|
|
||||||
isBlockDevice: () => boolean;
|
|
||||||
isCharacterDevice: () => boolean;
|
|
||||||
isDirectory: () => boolean;
|
|
||||||
isFIFO: () => boolean;
|
|
||||||
isFile: () => boolean;
|
|
||||||
isSocket: () => boolean;
|
|
||||||
isSymbolicLink: () => boolean;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
2
node_modules/@nodelib/fs.scandir/out/types/index.js
generated
vendored
2
node_modules/@nodelib/fs.scandir/out/types/index.js
generated
vendored
@ -1,2 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
2
node_modules/@nodelib/fs.scandir/out/utils/fs.d.ts
generated
vendored
2
node_modules/@nodelib/fs.scandir/out/utils/fs.d.ts
generated
vendored
@ -1,2 +0,0 @@
|
|||||||
import type { Dirent, Stats } from '../types';
|
|
||||||
export declare function createDirentFromStats(name: string, stats: Stats): Dirent;
|
|
||||||
19
node_modules/@nodelib/fs.scandir/out/utils/fs.js
generated
vendored
19
node_modules/@nodelib/fs.scandir/out/utils/fs.js
generated
vendored
@ -1,19 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.createDirentFromStats = void 0;
|
|
||||||
class DirentFromStats {
|
|
||||||
constructor(name, stats) {
|
|
||||||
this.name = name;
|
|
||||||
this.isBlockDevice = stats.isBlockDevice.bind(stats);
|
|
||||||
this.isCharacterDevice = stats.isCharacterDevice.bind(stats);
|
|
||||||
this.isDirectory = stats.isDirectory.bind(stats);
|
|
||||||
this.isFIFO = stats.isFIFO.bind(stats);
|
|
||||||
this.isFile = stats.isFile.bind(stats);
|
|
||||||
this.isSocket = stats.isSocket.bind(stats);
|
|
||||||
this.isSymbolicLink = stats.isSymbolicLink.bind(stats);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function createDirentFromStats(name, stats) {
|
|
||||||
return new DirentFromStats(name, stats);
|
|
||||||
}
|
|
||||||
exports.createDirentFromStats = createDirentFromStats;
|
|
||||||
2
node_modules/@nodelib/fs.scandir/out/utils/index.d.ts
generated
vendored
2
node_modules/@nodelib/fs.scandir/out/utils/index.d.ts
generated
vendored
@ -1,2 +0,0 @@
|
|||||||
import * as fs from './fs';
|
|
||||||
export { fs };
|
|
||||||
5
node_modules/@nodelib/fs.scandir/out/utils/index.js
generated
vendored
5
node_modules/@nodelib/fs.scandir/out/utils/index.js
generated
vendored
@ -1,5 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.fs = void 0;
|
|
||||||
const fs = require("./fs");
|
|
||||||
exports.fs = fs;
|
|
||||||
44
node_modules/@nodelib/fs.scandir/package.json
generated
vendored
44
node_modules/@nodelib/fs.scandir/package.json
generated
vendored
@ -1,44 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@nodelib/fs.scandir",
|
|
||||||
"version": "2.1.5",
|
|
||||||
"description": "List files and directories inside the specified directory",
|
|
||||||
"license": "MIT",
|
|
||||||
"repository": "https://github.com/nodelib/nodelib/tree/master/packages/fs/fs.scandir",
|
|
||||||
"keywords": [
|
|
||||||
"NodeLib",
|
|
||||||
"fs",
|
|
||||||
"FileSystem",
|
|
||||||
"file system",
|
|
||||||
"scandir",
|
|
||||||
"readdir",
|
|
||||||
"dirent"
|
|
||||||
],
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 8"
|
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"out/**",
|
|
||||||
"!out/**/*.map",
|
|
||||||
"!out/**/*.spec.*"
|
|
||||||
],
|
|
||||||
"main": "out/index.js",
|
|
||||||
"typings": "out/index.d.ts",
|
|
||||||
"scripts": {
|
|
||||||
"clean": "rimraf {tsconfig.tsbuildinfo,out}",
|
|
||||||
"lint": "eslint \"src/**/*.ts\" --cache",
|
|
||||||
"compile": "tsc -b .",
|
|
||||||
"compile:watch": "tsc -p . --watch --sourceMap",
|
|
||||||
"test": "mocha \"out/**/*.spec.js\" -s 0",
|
|
||||||
"build": "npm run clean && npm run compile && npm run lint && npm test",
|
|
||||||
"watch": "npm run clean && npm run compile:watch"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@nodelib/fs.stat": "2.0.5",
|
|
||||||
"run-parallel": "^1.1.9"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@nodelib/fs.macchiato": "1.0.4",
|
|
||||||
"@types/run-parallel": "^1.1.0"
|
|
||||||
},
|
|
||||||
"gitHead": "d6a7960d5281d3dd5f8e2efba49bb552d090f562"
|
|
||||||
}
|
|
||||||
21
node_modules/@nodelib/fs.stat/LICENSE
generated
vendored
21
node_modules/@nodelib/fs.stat/LICENSE
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) Denis Malinochkin
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
126
node_modules/@nodelib/fs.stat/README.md
generated
vendored
126
node_modules/@nodelib/fs.stat/README.md
generated
vendored
@ -1,126 +0,0 @@
|
|||||||
# @nodelib/fs.stat
|
|
||||||
|
|
||||||
> Get the status of a file with some features.
|
|
||||||
|
|
||||||
## :bulb: Highlights
|
|
||||||
|
|
||||||
Wrapper around standard method `fs.lstat` and `fs.stat` with some features.
|
|
||||||
|
|
||||||
* :beginner: Normally follows symbolic link.
|
|
||||||
* :gear: Can safely work with broken symbolic link.
|
|
||||||
|
|
||||||
## Install
|
|
||||||
|
|
||||||
```console
|
|
||||||
npm install @nodelib/fs.stat
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import * as fsStat from '@nodelib/fs.stat';
|
|
||||||
|
|
||||||
fsStat.stat('path', (error, stats) => { /* … */ });
|
|
||||||
```
|
|
||||||
|
|
||||||
## API
|
|
||||||
|
|
||||||
### .stat(path, [optionsOrSettings], callback)
|
|
||||||
|
|
||||||
Returns an instance of `fs.Stats` class for provided path with standard callback-style.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
fsStat.stat('path', (error, stats) => { /* … */ });
|
|
||||||
fsStat.stat('path', {}, (error, stats) => { /* … */ });
|
|
||||||
fsStat.stat('path', new fsStat.Settings(), (error, stats) => { /* … */ });
|
|
||||||
```
|
|
||||||
|
|
||||||
### .statSync(path, [optionsOrSettings])
|
|
||||||
|
|
||||||
Returns an instance of `fs.Stats` class for provided path.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const stats = fsStat.stat('path');
|
|
||||||
const stats = fsStat.stat('path', {});
|
|
||||||
const stats = fsStat.stat('path', new fsStat.Settings());
|
|
||||||
```
|
|
||||||
|
|
||||||
#### path
|
|
||||||
|
|
||||||
* Required: `true`
|
|
||||||
* Type: `string | Buffer | URL`
|
|
||||||
|
|
||||||
A path to a file. If a URL is provided, it must use the `file:` protocol.
|
|
||||||
|
|
||||||
#### optionsOrSettings
|
|
||||||
|
|
||||||
* Required: `false`
|
|
||||||
* Type: `Options | Settings`
|
|
||||||
* Default: An instance of `Settings` class
|
|
||||||
|
|
||||||
An [`Options`](#options) object or an instance of [`Settings`](#settings) class.
|
|
||||||
|
|
||||||
> :book: When you pass a plain object, an instance of the `Settings` class will be created automatically. If you plan to call the method frequently, use a pre-created instance of the `Settings` class.
|
|
||||||
|
|
||||||
### Settings([options])
|
|
||||||
|
|
||||||
A class of full settings of the package.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
const settings = new fsStat.Settings({ followSymbolicLink: false });
|
|
||||||
|
|
||||||
const stats = fsStat.stat('path', settings);
|
|
||||||
```
|
|
||||||
|
|
||||||
## Options
|
|
||||||
|
|
||||||
### `followSymbolicLink`
|
|
||||||
|
|
||||||
* Type: `boolean`
|
|
||||||
* Default: `true`
|
|
||||||
|
|
||||||
Follow symbolic link or not. Call `fs.stat` on symbolic link if `true`.
|
|
||||||
|
|
||||||
### `markSymbolicLink`
|
|
||||||
|
|
||||||
* Type: `boolean`
|
|
||||||
* Default: `false`
|
|
||||||
|
|
||||||
Mark symbolic link by setting the return value of `isSymbolicLink` function to always `true` (even after `fs.stat`).
|
|
||||||
|
|
||||||
> :book: Can be used if you want to know what is hidden behind a symbolic link, but still continue to know that it is a symbolic link.
|
|
||||||
|
|
||||||
### `throwErrorOnBrokenSymbolicLink`
|
|
||||||
|
|
||||||
* Type: `boolean`
|
|
||||||
* Default: `true`
|
|
||||||
|
|
||||||
Throw an error when symbolic link is broken if `true` or safely return `lstat` call if `false`.
|
|
||||||
|
|
||||||
### `fs`
|
|
||||||
|
|
||||||
* Type: [`FileSystemAdapter`](./src/adapters/fs.ts)
|
|
||||||
* Default: A default FS methods
|
|
||||||
|
|
||||||
By default, the built-in Node.js module (`fs`) is used to work with the file system. You can replace any method with your own.
|
|
||||||
|
|
||||||
```ts
|
|
||||||
interface FileSystemAdapter {
|
|
||||||
lstat?: typeof fs.lstat;
|
|
||||||
stat?: typeof fs.stat;
|
|
||||||
lstatSync?: typeof fs.lstatSync;
|
|
||||||
statSync?: typeof fs.statSync;
|
|
||||||
}
|
|
||||||
|
|
||||||
const settings = new fsStat.Settings({
|
|
||||||
fs: { lstat: fakeLstat }
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Changelog
|
|
||||||
|
|
||||||
See the [Releases section of our GitHub project](https://github.com/nodelib/nodelib/releases) for changelog for each release version.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This software is released under the terms of the MIT license.
|
|
||||||
13
node_modules/@nodelib/fs.stat/out/adapters/fs.d.ts
generated
vendored
13
node_modules/@nodelib/fs.stat/out/adapters/fs.d.ts
generated
vendored
@ -1,13 +0,0 @@
|
|||||||
/// <reference types="node" />
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import type { ErrnoException } from '../types';
|
|
||||||
export declare type StatAsynchronousMethod = (path: string, callback: (error: ErrnoException | null, stats: fs.Stats) => void) => void;
|
|
||||||
export declare type StatSynchronousMethod = (path: string) => fs.Stats;
|
|
||||||
export interface FileSystemAdapter {
|
|
||||||
lstat: StatAsynchronousMethod;
|
|
||||||
stat: StatAsynchronousMethod;
|
|
||||||
lstatSync: StatSynchronousMethod;
|
|
||||||
statSync: StatSynchronousMethod;
|
|
||||||
}
|
|
||||||
export declare const FILE_SYSTEM_ADAPTER: FileSystemAdapter;
|
|
||||||
export declare function createFileSystemAdapter(fsMethods?: Partial<FileSystemAdapter>): FileSystemAdapter;
|
|
||||||
17
node_modules/@nodelib/fs.stat/out/adapters/fs.js
generated
vendored
17
node_modules/@nodelib/fs.stat/out/adapters/fs.js
generated
vendored
@ -1,17 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.createFileSystemAdapter = exports.FILE_SYSTEM_ADAPTER = void 0;
|
|
||||||
const fs = require("fs");
|
|
||||||
exports.FILE_SYSTEM_ADAPTER = {
|
|
||||||
lstat: fs.lstat,
|
|
||||||
stat: fs.stat,
|
|
||||||
lstatSync: fs.lstatSync,
|
|
||||||
statSync: fs.statSync
|
|
||||||
};
|
|
||||||
function createFileSystemAdapter(fsMethods) {
|
|
||||||
if (fsMethods === undefined) {
|
|
||||||
return exports.FILE_SYSTEM_ADAPTER;
|
|
||||||
}
|
|
||||||
return Object.assign(Object.assign({}, exports.FILE_SYSTEM_ADAPTER), fsMethods);
|
|
||||||
}
|
|
||||||
exports.createFileSystemAdapter = createFileSystemAdapter;
|
|
||||||
12
node_modules/@nodelib/fs.stat/out/index.d.ts
generated
vendored
12
node_modules/@nodelib/fs.stat/out/index.d.ts
generated
vendored
@ -1,12 +0,0 @@
|
|||||||
import type { FileSystemAdapter, StatAsynchronousMethod, StatSynchronousMethod } from './adapters/fs';
|
|
||||||
import * as async from './providers/async';
|
|
||||||
import Settings, { Options } from './settings';
|
|
||||||
import type { Stats } from './types';
|
|
||||||
declare type AsyncCallback = async.AsyncCallback;
|
|
||||||
declare function stat(path: string, callback: AsyncCallback): void;
|
|
||||||
declare function stat(path: string, optionsOrSettings: Options | Settings, callback: AsyncCallback): void;
|
|
||||||
declare namespace stat {
|
|
||||||
function __promisify__(path: string, optionsOrSettings?: Options | Settings): Promise<Stats>;
|
|
||||||
}
|
|
||||||
declare function statSync(path: string, optionsOrSettings?: Options | Settings): Stats;
|
|
||||||
export { Settings, stat, statSync, AsyncCallback, FileSystemAdapter, StatAsynchronousMethod, StatSynchronousMethod, Options, Stats };
|
|
||||||
26
node_modules/@nodelib/fs.stat/out/index.js
generated
vendored
26
node_modules/@nodelib/fs.stat/out/index.js
generated
vendored
@ -1,26 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.statSync = exports.stat = exports.Settings = void 0;
|
|
||||||
const async = require("./providers/async");
|
|
||||||
const sync = require("./providers/sync");
|
|
||||||
const settings_1 = require("./settings");
|
|
||||||
exports.Settings = settings_1.default;
|
|
||||||
function stat(path, optionsOrSettingsOrCallback, callback) {
|
|
||||||
if (typeof optionsOrSettingsOrCallback === 'function') {
|
|
||||||
async.read(path, getSettings(), optionsOrSettingsOrCallback);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
async.read(path, getSettings(optionsOrSettingsOrCallback), callback);
|
|
||||||
}
|
|
||||||
exports.stat = stat;
|
|
||||||
function statSync(path, optionsOrSettings) {
|
|
||||||
const settings = getSettings(optionsOrSettings);
|
|
||||||
return sync.read(path, settings);
|
|
||||||
}
|
|
||||||
exports.statSync = statSync;
|
|
||||||
function getSettings(settingsOrOptions = {}) {
|
|
||||||
if (settingsOrOptions instanceof settings_1.default) {
|
|
||||||
return settingsOrOptions;
|
|
||||||
}
|
|
||||||
return new settings_1.default(settingsOrOptions);
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user