@nasl/cli
v0.4.0
Published
NASL (Next Application Specific Language) CLI tool for checking, compiling and developing NASL code
Readme
@nasl/cli
NASL 语言的命令行工具,提供编译、检查、开发服务等功能。
目前只支持 NaturalTS 表示的 NASL 代码,编译为 Vue 和 JS。
安装
npm install -g @nasl/cli使用
初始化配置(nasl init)
nasl init会在当前目录创建 nasl.config.json 配置文件。
{
"serverBaseURL": "https://nasl.lcap.163yun.com", // NASL 编译服务的基础 URL
"representation": "NaturalTS", // NASL 语言的表示
"namespaceResolution": "filename-as-namespace", // 命名空间解析策略
"ideVersion": "4.4", // IDE 版本
"srcDir": "src", // 源代码目录
"outDir": "out", // 输出目录
"ignoreEmptyDir": false // 为 true 时,若 src 目录不存在或为空(忽略点开头文件),加载配置后直接以退出码 0 结束,不执行后续命令逻辑(便于 CI 在无源码时跳过)
}入口文件说明
下面的命令中均支持 [entry] 参数,表示入口文件:
- 入口文件可选,不填则表示处理整个 src 目录
- 入口文件路径相对于项目目录,但必须在 src 目录下
- 支持具体文件和 glob 模式(注意要用引号包裹)
- src/app.enums.Status.ts 支持具体文件
- "src/app.enums.*.ts" 表示所有枚举
- "src/app.{.entities..ts,structures..ts,enums..ts}" 表示所有实体、数据结构和枚举,即全部用户自定义类型
- "src/app.logics.*.ts" 表示所有逻辑文件
- "src/*.tsx" 表示所有页面文件
- 会自动进行依赖分析,收集所有依赖的文件
- 依赖的页面文件(.tsx)不会继续进行依赖分析,而是直接提取签名,以提高性能
编译 NASL 代码(nasl compile 或 naslc)
# 编译整个 src 目录
nasl compile
# 编译指定入口文件及其依赖(自动进行依赖分析)
nasl compile src/app.frontendTypes.pc.frontends.pc.views.dashboard.tsx
# 或使用简写
naslc src/app.frontendTypes.pc.frontends.pc.views.dashboard.tsx
naslc "src/app.enums.*.ts"
naslc "src/app.{*.entities.*.ts,structures.*.ts,enums.*.ts}"
naslc "src/app.logics.*.ts"
naslc "src/*.tsx"检查 NASL 代码(nasl check)
# 检查整个 src 目录
nasl check
# 检查指定入口文件及其依赖(自动进行依赖分析)
nasl check src/app.frontendTypes.pc.frontends.pc.views.dashboard.tsx
nasl check "src/app.enums.*.ts"
nasl check "src/app.{*.entities.*.ts,structures.*.ts,enums.*.ts}"
nasl check "src/app.logics.*.ts"
nasl check "src/*.tsx"--ignore-destination:检查时不校验页面中的destination属性,即依赖其他页面的情况,但会保留父页面等依赖分析。
解析 NASL 代码(nasl parse)
将 NASL 源码解析为 JSON(NASL AST),输出到 stdout。
# 解析单个文件,返回该实体/枚举/结构/逻辑/页面的 JSON
nasl parse src/app.dataSources.defaultDS.entities.FactoryArea.ts
nasl parse src/app.enums.StatusEnum.ts
nasl parse src/app.structures.CourseSelectionRule.ts
nasl parse src/app.logics.loadData.ts
nasl parse src/app.frontendTypes.pc.frontends.pc.views.dashboard.tsx
# 使用通配符时,返回完整的 app JSON
nasl parse "src/{app.dataSources,app.enums}.*.ts"
# 不指定文件时,解析整个 src 目录,返回完整的 app JSON
nasl parse
# 仅做解析/语法检查,不输出 JSON(成功时提示检查通过,失败时输出带源文件行号的错误信息)
# 相比于 nasl check 更轻量,不做 Language Server 的语义检查
nasl parse --check
nasl parse src/app.logics.loadData.ts --check--check:检查模式,不向 stdout 打印 app JSON;解析失败时,错误会尽量映射回原始源文件与行号。
单文件模式目前支持的类型:entity, enum, structure, logic, view;其他类型(如 variables、extensions)暂不支持。
检查 plan 文档中的 NaturalTS(nasl-doc / nasld)
用于检查 plan 目录下 markdown 里 naturalts 代码块的语法(与 nasl check 面向 src 的 NASL 源码检查不同)。
安装 @nasl/cli 后,可使用 nasl-doc 或 nasld(同一命令的短名):
nasl-doc check path/to/plan.md
# 或
nasld check path/to/plan.md支持的文档类型包括:enums.md、entity-*.md、structure-*.md、logic-*.md、view-*.md 等(详见命令帮助:nasl-doc check --help)。
解析 plan 文档中的 NaturalTS(nasl-doc parse / nasld parse)
与 nasld check 类似,但返回解析后的 JSON 而非仅校验语法。不支持通配符和多文件,只支持单个文档。
# 解析单个文档,返回该实体/枚举/结构/逻辑/页面的 JSON
nasld parse specs/plan/data-model/entity-FactoryArea.md
nasld parse specs/plan/data-model/structure-CourseSelectionRule.md
# enums.md 包含多个枚举,返回完整的 app JSON
nasld parse specs/plan/data-model/enums.md
# 只校验 naturalts 能否解析,不输出 JSON
# 相比于 nasld check 更轻量,不做 Language Server 的语义检查
nasld parse specs/plan/data-model/entity-FactoryArea.md --check依赖分析(nasl dep)
建议指定入口文件,否则会扫描整个 src 目录,输出量较大。
nasl dep "src/app.enums.*.ts"
nasl dep "src/app.{*.entities.*.ts,structures.*.ts,enums.*.ts}"
nasl dep "src/app.logics.loadStudentList.ts"
nasl dep "src/*.tsx"
nasl dep安装依赖(nasl install)
安装 uilib、extension、api 或 connector 依赖,会调用远程服务生成对应的类型声明文件并写入 src 目录。
# 按类型安装,name@version 格式
nasl install uilib [email protected]
nasl install extension [email protected] [email protected]
nasl install connector [email protected]
# 安装 API 依赖,service:api1,api2 格式
nasl install api some_service:api1,api2
# 通过 JSON 字符串一次性安装多种类型的依赖
nasl install by-json '{"uilibs": {"some_component": "0.1.0"}, "extensions": {"some_encryption": "0.1.0"}}'
# 不指定参数时,按照 src/app.dependencies.json 中的声明安装所有依赖
nasl install
# --save-potential:将本次安装的依赖增量合并到 src/potential.dependencies.json
nasl install --save-potential extension [email protected]
nasl install --save-potential by-json '{"uilibs": {"some_component": "0.1.0"}, "extensions": {"some_encryption": "0.1.0"}}启动开发服务(nasl dev)
nasl dev启动开发服务后,默认访问 http://localhost:3100 查看预览效果。
可以用 --port 和 --host 更换端口号和主机名。
nasl dev --port 4900 --host 0.0.0.0dev 进程始终保持运行,规则如下:
- 启动:
- 有 src: 初始编译生成 out,然后启动 webpack
- 无 src: 1. 有 out:直接启动 webpack,等待 src 目录创建 2. 无 out:启动 webpack,等待 src 目录创建
- 运行中
- out 被删除:如果有 src,自动重新编译恢复 out
- src 被创建:自动编译生成 out 目录
- src 被删除: 使用缓存的 out 目录
构建项目(nasl build)
与 nasl dev 对应,构建成最终用于浏览器的 dist 产物。
# 使用生产模式构建(默认)
nasl build
# 使用开发模式构建
nasl build --mode development
# 构建指定入口文件及其依赖
nasl build src/app.frontendTypes.pc.frontends.pc.views.dashboard.tsx转换文件格式(nasl transform)
# files2full: 将 src 中的文件组合成 fullNaturalTS
nasl transform files2full [entry] --output [outputPath]
# 默认输出到 ./full-natural.ts
# json2files: 将 JSON 文件转换成 src 的 files
nasl transform json2files [jsonFile] --output [outputPath]
# 如果不指定 jsonFile,将按照默认 IDE 版本的基础模板转换
# files2json: 将 src 中的文件转换成一个 JSON(待实现)
nasl transform files2json [entry] --output [outputPath]
# 默认输出到 ./files.json在 IDE 中创建 / 更新应用
注意:create-app-in-ide 与 update-app-in-ide 只能在测试环境使用。
两个命令都会先按 入口文件说明 解析本地 NASL(可选 [entry],不传则处理整个 src),将源码组合为 fullNaturalTS(含依赖)后调用远程服务。均支持 --quiet 跳过确认、--verbose 输出依赖分析等详细信息。
在 IDE 中创建应用(nasl create-app-in-ide)
# 会询问确认(默认)
nasl create-app-in-ide [entry]
# 跳过确认,直接执行
nasl create-app-in-ide [entry] --quiet
# 显示详细信息
nasl create-app-in-ide [entry] --verbose执行前会展示即将使用的应用名称、包名、IDE 版本与租户。应用名与包名由项目目录推导:若存在 specs/ 目录,则取其中第一个子文件夹名作为基础名;否则使用项目根目录名。基础名经清洗(仅保留字母数字、去掉开头数字、最长 12 字符)后,再拼接时间后缀生成最终名称。
在 IDE 中更新已有应用(nasl update-app-in-ide)
第一个参数为远程应用的 appId(必填),其余与创建命令一致。
# 会询问确认(默认)
nasl update-app-in-ide <appId> [entry]
# 跳过确认
nasl update-app-in-ide <appId> [entry] --quiet
# 显示详细信息
nasl update-app-in-ide <appId> [entry] --verbose将当前本地 NASL 同步到指定应用,用于在 IDE 中更新已有应用而非新建。
从 IDE 下载应用到本地(nasl download-app-from-ide)
通过远程应用 appId 拉取应用数据并写成本地源文件,使用与 create-app-in-ide / update-app-in-ide 相同的服务与鉴权(serverBaseURL、OpenAPI 等,见上文环境变量)。若 src 下已有非隐藏文件,命令会提示选择:覆盖并清空当前 srcDir,或在项目根下新建 src_<appId> 再写入。
# 将指定应用拉取到本地(需有效网络与鉴权配置)
nasl download-app-from-ide <appId>
# 输出依赖分析等详细日志
nasl download-app-from-ide <appId> --verbose诊断页面视图拓扑(nasl doctor view)
分析项目中页面的拓扑结构,生成包含页面树、跳转引用关系、角色可访问性等信息的诊断报告。
# 默认输出:页面树 + 反向引用 + 未被引用页面分析
nasl doctor view
# 只输出页面树
nasl doctor view --view-tree
# 只输出反向引用
nasl doctor view --reverse-refs
# 只输出未被引用的页面
nasl doctor view --unref-views
# 分析指定角色的可访问页面树
nasl doctor view --role-access Administrator,SalesPerson
# 不输出相关代码片段(精简输出)
nasl doctor view --hide-code
# 在未被引用分析中包含根页面
nasl doctor view --unref-views --include-roots
# 以 JSON 格式输出完整的 ViewGraph 结构
nasl doctor view --json
# 组合使用
nasl doctor view --view-tree --unref-views --hide-code
# 快速输出全量页面路由列表(JSON)
nasl doctor routes --json选项说明:
| 选项 | 说明 |
|------|------|
| --view-tree | 输出页面树结构,展示所有页面层级及跳转关系 |
| --reverse-refs | 输出反向引用,展示每个页面被哪些页面跳转引用 |
| --unref-views | 输出没有默认跳转且没有被引用的页面列表 |
| --role-access <roles> | 输出指定角色的可访问页面树(多个角色用逗号分隔)。角色名必须存在于 src/app.roles.json 中 |
| --hide-code | 不输出相关代码片段,减少报告长度 |
| --include-roots | 在未被引用分析中包含根页面(默认忽略根页面) |
| --json | 以 JSON 格式输出完整的 ViewGraph 结构 |
nasl doctor routes 选项:
| 选项 | 说明 |
|------|------|
| --json | 以 JSON 格式输出全量页面路由列表(默认行为) |
默认行为:
- 不指定任何选项时,输出页面树 + 反向引用 + 未被引用页面分析
- 指定了
--view-tree、--reverse-refs、--unref-views、--role-access中的任一选项时,只输出明确指定的部分
环境变量配置
除了在 nasl.config.json 中配置外,也可以通过环境变量来配置部分选项。
环境变量的优先级高于配置文件,如果同时设置了环境变量和配置文件,将使用环境变量的值。
支持的环境变量
服务与版本
NASL_IDE_VERSION: IDE 版本号,对应配置ideVersion字段export NASL_IDE_VERSION=4.4NASL_SERVER_BASE_URL: NASL 编译服务的基础 URL,对应配置serverBaseURL字段export NASL_SERVER_BASE_URL=https://nasl.lcap.163yun.comNASL_IGNORE_EMPTY_DIR: 是否在无源码时跳过整个命令。设为'true'时,若srcDir不存在或除点开头文件外为空,加载项目配置后即以退出码 0 直接结束(不执行具体子命令逻辑),对应配置ignoreEmptyDir字段export NASL_IGNORE_EMPTY_DIR=trueNASL_USE_LOCAL_SDK: 是否使用本地 SDK(值为'true'时启用),对应配置useLocalSDK字段export NASL_USE_LOCAL_SDK=true
OpenAPI 鉴权
USE_LCAP_OPENAPI: 是否使用 OpenAPI 方式调用(值为'true'时启用),对应配置useOPENAPI字段export USE_LCAP_OPENAPI=trueLCAP_OPENAPI_AK: LCAP OpenAPI Access Key(使用 OpenAPI 时必需),对应配置OPENAPI_AK字段export LCAP_OPENAPI_AK=your_access_keyLCAP_OPENAPI_SK: LCAP OpenAPI Secret Key(使用 OpenAPI 时必需),对应配置OPENAPI_SK字段export LCAP_OPENAPI_SK=your_secret_keyLCAP_TENANT_NAME: LCAP 租户名称,对应配置tenantName字段export LCAP_TENANT_NAME=your_tenantLCAP_USER_NAME: LCAP 用户名称,对应配置userName字段。优先级高于LCAP_ACCOUNT_IDexport LCAP_USER_NAME=your_usernameLCAP_ACCOUNT_ID: 用户标识的备选环境变量,当LCAP_USER_NAME未设置时生效,同样对应userName字段export LCAP_ACCOUNT_ID=your_account_id
调试与日志
DEBUG: 启用调试输出。设置后,logger.debug()的内容会打印到控制台,依赖分析也会输出详细日志export DEBUG=1NO_AI_CACHE: 禁用 AI 响应缓存。设置后,所有带缓存的函数调用都会跳过缓存、直接执行export NO_AI_CACHE=1NASL_CLI_LOG_DIR: 指定日志输出目录。设置后,check等命令的详细结果会写入该目录下的日志文件export NASL_CLI_LOG_DIR=.nasl/some-taskNASL_USE_LOCAL_SDK: 是否优先使用本地 SDK(值为'true'时启用),对应配置useLocalSDK字段。启用后,ideVersion >= 4.4时走本地nasl-server-sdk零网络传输;版本不满足时自动降级到远程serverBaseURLexport NASL_USE_LOCAL_SDK=trueNASL_CALL_LOCAL_SDK_MODE: 本地 SDK 的调用方式,仅在useLocalSDK: true时生效,对应配置callLocalSDKMode字段daemon(默认):通过后台子进程 daemon socket 调用,复用内存缓存,第二次调用速度更快direct:跳过 daemon,每次直接调用 SDK,不启动子进程;适合单次执行或不希望后台进程常驻的场景
export NASL_CALL_LOCAL_SDK_MODE=directSBX_LOG_DIR: daemon 子进程的日志输出目录;未设置时默认写到当前执行目录的.nasl/文件夹下(.nasl/nasl-sdk-daemon.log)export SBX_LOG_DIR=/var/log/nasl
配置文件示例(包含 OpenAPI 配置)
{
"serverBaseURL": "https://sometenant.codewave.163.com",
"representation": "NaturalTS",
"namespaceResolution": "filename-as-namespace",
"ideVersion": "4.4",
"srcDir": "src",
"outDir": "out",
"ignoreEmptyDir": false,
"useOPENAPI": true,
"OPENAPI_AK": "your_access_key",
"OPENAPI_SK": "your_secret_key",
"tenantName": "your_tenant",
"userName": "your_username"
}注意:如果配置了 useOPENAPI: true,则必须同时配置 OPENAPI_AK 和 OPENAPI_SK(可在配置文件中配置,或通过环境变量 LCAP_OPENAPI_AK 和 LCAP_OPENAPI_SK 配置)。
DEVELOPMENT
# 安装依赖
pnpm install
# 构建
pnpm run build
# 开发模式(监听文件变化)
pnpm run dev
# 代码检查
pnpm run lint
# 代码修复
pnpm run lint:fix
# 代码格式化
pnpm run format