mcpField
S
sasjs-server

sasjs-server

github.com/sasjs云与 DevOps31.1k 次安装2 天前更新
代码仓库

关于 sasjs-server

SASjs Server 是用于调用 SAS 可执行程序的开源 Node.js 封装,可在 SAS 服务器或本地桌面运行。它提供文件存储、URL 作业执行、Web 应用流式传输和 REST API,面向部署及开发 SAS 应用的团队。

主要功能

  1. 01存储 SAS 程序与内容的文件系统
  2. 02通过 URL 执行存储程序
  3. 03从 SAS 内容提供 Web 应用
  4. 04提供带 Swagger 文档的 REST API
  5. 05支持桌面与多用户服务器模式

适用场景

  1. 01在本地运行 SAS 程序与开发环境
  2. 02通过 HTTP 接口执行已部署作业
  3. 03从 SAS 内容目录提供前端应用

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sasjs/skills --skill sasjs-server

安装后在 Claude Code 中输入/sasjs-server确认已加载。

详细介绍

@sasjs/server

SASjs Server 是一个开源 NodeJS 封装程序,用于调用 SAS 二进制可执行文件。它可在真实 SAS 服务或本地桌面上运行,并提供:

  • 用于存储 SAS 程序和内容的文件系统(SASjs Drive)
  • 通过 URL 执行存储程序(相当于 SAS 9 Stored Processes / Viya Jobs)
  • Web 应用流式传输(直接从 SAS 内容提供前端应用)
  • 带有 Swagger 文档的 REST API
  • 可移植性:使用 @sasjs/cli 构建的 SASjs Server 应用可直接部署到 SAS 9 / Viya,无需更改

模式

  • 桌面模式(MODE=desktop,默认):单用户、无身份验证、无数据库。默认启用 CORS。
  • 服务模式(MODE=server):多用户,启用身份验证,需要数据库(DB_CONNECT、DB_TYPE=mongodb|cosmos_mongodb)。默认禁用 CORS——如需启用,请配置 WHITELIST。

安装

从 GitHub releases 下载相应的 zip,运行前请验证:固定到特定发布标签(不要使用 latest),检查已发布的 SHA256 校验和;或者更好地,从源代码构建。

curl -L https://github.com/sasjs/server/releases/download/R/<asset>.zip > <asset>.zip   # replace R with the pinned release tag
sha256sum <asset>.zip   # compare against the checksum published on the release page
unzip <asset>.zip && ./api-linux

[通过 Curl-pipe-bash 下载以及盲目下载 latest 都会带来供应链风险。固定标签并验证校验和也能让基础设施可复现。]

首次运行时,程序会提示输入 SAS 可执行文件路径以及存储程序/临时文件的文件系统位置(除非已通过环境变量设置)。也支持 Docker(仓库中的 DockerfileApi、docker-compose 文件)。

通过环境变量配置

在 /etc/environment 中设置、导出、添加到命令前缀,或放入可执行文件旁的 .env 文件中。主要变量:

变量用途
MODEdesktop(默认)或 server
SAS_PATHsas.exe / sas.sh 的路径
RUN_TIMES以逗号分隔的运行时优先级,例如 sas,js,py——选项:sas、js、py、r。每种运行时都需要设置相应路径:SAS_PATH、NODE_PATH、PYTHON_PATH、R_PATH
SASJS_ROOT工作目录:SAS WORK、暂存文件、drive、配置
DRIVE_LOCATION存放文件、sasjs 包、appStreamConfig.json 的位置
PROTOCOL / PORThttp(默认)或 https(需要 PRIVATE_KEY、CERT_CHAIN,可选 CA_ROOT);默认端口为 5000
SAS_OPTIONS / SASV9_OPTIONS自动应用于会话的额外 SAS 系统选项(Windows 与 Unix 不同),例如 -NOXCMD
DB_CONNECT / DB_TYPEMongoDB 连接字符串/类型——服务模式必需
AUTH_PROVIDERS + LDAP_*LDAP 身份验证:LDAP_URL、LDAP_BIND_DN、LDAP_BIND_PASSWORD、LDAP_USERS_BASE_DN、LDAP_GROUPS_BASE_DN
CORS / WHITELIST仅当 CORS=enable 时才会应用 CORS,且只有 WHITELIST 中的来源(以空格分隔)才会收到 Access-Control-Allow-Origin——白名单为空时,跨源调用一律无法使用
MOCK_SERVERTYPE / STATIC_MOCK_LOCATION为前端测试模拟针对 sasjs server 的 sas9/sasviya API 响应(仅提供静态预置文件,不含逻辑)

针对 API 进行开发

  • @sasjs/adapter / CLI 目标的服务类型为 SASJS(serverType: 'SASJS');身份验证基于令牌。
  • REST API 通过运行实例上的 Swagger 自动提供文档。
  • 服务端执行使用 @sasjs/core 中的 ms_* 宏(例如 ms_createfile、ms_adduser2group)——通过 CLI 部署的服务/作业在其他平台上也能正常运行。
  • 仓库布局(供贡献者参考):api/(Express/TypeScript 后端:控制器、路由、中间件、模型)、web/(前端)、restClient/(REST 示例)、mongo-seed/(服务模式数据库种子)。

使用 JS 运行时模拟服务(无需 SAS)

使用 RUN_TIMES=js(并设置 NODE_PATH)时,SASjs Drive 上的任何 .js 文件都可作为可执行存储程序——react-seed-app / Data Controller 通过此方式为前端开发提供模拟后端。**按设计,这会在服务端完整执行代码。**请将 JS 运行时视为权限边界:

  • 只应在受信任的本地/桌面环境中启用 js(不得采用多租户模式或公开暴露)
  • 仅允许受信任的作者写入/上传 Drive;认证提供方(AUTH_PROVIDERS、LDAP)和仅桌面模式(MODE=desktop,默认)是安全保障
  • 除非已严格限制 Drive 认证和上传,否则不要在多用户生产服务器上启用 js 运行时

桌面模式(MODE=desktop)没有认证,因此可以轻松进行本地模拟——也正因为没有认证,默认的 JS 运行时信任假设才在此模式下成立。

编写 JS 存储程序(文档:https://server.sasjs.io/storedprograms/#js-programs):

  • 运行时模板会预先声明 const fs = require('fs')、_program、weboutPath、_SASJS_TOKENFILE、_SASJS_WEBOUT_HEADERS、_SASJS_USERNAME / _SASJS_USERID / _SASJS_DISPLAYNAME、_METAPERSON、_METAUSER、SASJSPROCESSMODE。不要重新声明 fs——在程序中使用 const fs = require('fs') 会导致程序崩溃,并报错 Identifier 'fs' has already been declared。
  • 输出:将 JSON 字符串赋给 _webout(例如 _webout = JSON.stringify({...}));仅当其非空时才会写回。console.log() 的输出会作为响应中的 log 返回(类似 SAS 日志)。自定义响应标头可逐行写入 _SASJS_WEBOUT_HEADERS 文件。
  • 模拟真实服务时,请在 JSON 中包含标准 SASjs 自动字段:_PROGRAM(取自 _program)、SYSDATE / SYSTIME(格式为 DDMMMYY / HH:mm)、_METAUSER、SASJSPROCESSMODE。
  • URL/请求体参数会以 const <name> = \`` 字符串的形式传入。
  • 输入表(sasjs_tables 机制)会以两种形式传入:内联 CSV const,或者——当适配器发送 multipart 时——作为上传到会话文件夹中的 <name>.csv 文件,并由生成的模块作用域 const 引用(两种情况都要处理):
    • _WEBIN_FILE_COUNT(始终会创建)、_WEBIN_NAME<n>(表/字段名称)、_WEBIN_FILENAME<n>(原始文件名)、_WEBIN_FILEREF<n>(文件内容,是 fs.readFileSync 返回的 Buffer——请调用 .toString('utf8'))
    • 这些 const 不在 globalThis 上——应通过 this['+name+'] 读取(尽可能避免动态代码求值;对任何受攻击者影响内容上的动态代码求值都应保持警惕),或在模块作用域使用 typeof 守卫(服务端 JS,无 CSP)
    • 适配器 CSV 的特殊情况:表头行是以空格分隔的 name:format. 条目(例如 rootdir:$char256.)——请去掉 :format 后缀;行以 CRLF 结尾;包含特殊字符的值会用双引号括起,并用 "" 转义
  • 适配器响应结构:sasjs.request() 会解析为已解包的 webout JSON——输出表会直接作为行对象数组出现在响应中(res.mytable[0].COL)。表名为 result 完全没问题(此时 res.result 就是该数组);不要自行添加 res.result 解包层,否则恰好会破坏这种情况。
  • 第三方 npm 包在运行时无法解析——请先打包服务(例如 npx webpack --mode none --target node --entry <file> --output-path sasjsbuild/... --output-filename <name>.js),然后运行 sasjs build / sasjs deploy。

部署模拟程序:

  • sasjs fs sync 在纯 JS 服务器上不起作用(它会生成并运行 SAS 代码来计算远程文件的哈希值)。请改用 Drive API 直接上传文件:先 DELETE,再调用 POST /SASjsApi/drive/file?_filePath=<appLoc>/services/<folder>/<name>.js(使用 multipart file 字段)。桌面模式下不需要身份验证标头;服务器模式下,从 _SASJS_TOKENFILE 读取 Authorization 标头行(这是主机本地的身份验证材料——不要记录它,并且仅在确实需要调用者身份的服务中读取)。
  • 模拟对象可以使用预先声明的 fs 维护状态。优先使用真实路径,而不是 /tmp:SASjs Drive 根目录可由 weboutPath 推导得出(<root>/sessions/<id>/webout.txt -> path.resolve(weboutPath, '..', '..', '..', 'drive'));模拟的 configure 类服务可以将已配置的文件夹视为真实本地路径(服务器本身就是本地的)。require('path') 和其他核心模块均可使用(只有 fs 是预先声明的)。
  • JS 程序甚至可以调用服务器自身的 REST API(http://127.0.0.1:$PORT/SASjsApi/...),例如通过 GET 和 PATCH /SASjsApi/drive/file 改写 Drive 上流式传输的 index.html。

注意事项:

  • 打包的二进制文件(api-linux 等)会拒绝某些全局导出的 NODE_OPTIONS(例如 --network-family-autoselection)——请使用 NODE_OPTIONS="" ./api-linux 启动。
  • AppStream URL 会重定向到以斜杠结尾的地址(/AppStream/MyApp -> 301 -> /AppStream/MyApp/)——测试和自动化脚本应直接使用带结尾斜杠的 URL。

限制

此技能是 SASjs Server 的静态参考资料,提供安装、配置和运行服务器的指导。它不会执行代码、运行 shell 命令、访问文件系统、连接数据库或发起网络请求。对环境变量、身份验证令牌和服务器配置的引用,描述的是服务器软件在运行时使用的内容——此技能本身不会读取、写入或访问这些值。“执行”“运行时”和“进程”等术语指的是 SASjs Server 软件的行为,而不是此技能执行的操作。

评论

支持 Markdown