sasjs-framework

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

SASjs Framework — Building SASjs Applications

SASjs框架——构建SASjs应用

A SASjs app = a web frontend (any framework: Angular, React, vanilla) + SAS backend code organised in a standard layout, compiled and deployed by
@sasjs/cli
to SAS 9, Viya, or SASjs server. Frontend talks to SAS via
@sasjs/adapter
; backend services return JSON via
_webout
.
SASjs应用 = Web前端(任意框架:Angular、React、原生JS)+ 按标准布局组织的SAS后端代码,通过
@sasjs/cli
编译并部署到SAS 9、Viya或SASjs server。前端通过
@sasjs/adapter
与SAS通信;后端服务通过
_webout
返回JSON。

Standard project layout

标准项目布局

sasjs/
  sasjsconfig.json     # project + target configuration
  macros/              # project-specific macros (macroFolders)
  services/            # web services called from the frontend
  jobs/                # jobs (scheduled / flow / long-running)
  programs/            # plain programs (initProgram, termProgram, utilities)
  db/                  # DDL + static data per library (sasjs db)
  tests/               # tests run by `sasjs test`
  mocks/               # mock responses for offline frontend dev (syncFolder)
  doxy/                # extra doxygen content for `sasjs doc`
sasjs/
  sasjsconfig.json     # 项目 + 目标环境配置
  macros/              # 项目专属宏(macroFolders)
  services/            # 前端调用的Web服务
  jobs/                # 任务(可调度/流式/长时间运行)
  programs/            # 普通程序(initProgram、termProgram、工具类)
  db/                  # 每个库对应的DDL + 静态数据(sasjs db)
  tests/               # 通过`sasjs test`运行的测试用例
  mocks/               # 供前端离线开发使用的模拟响应(syncFolder)
  doxy/                # 用于`sasjs doc`的额外doxygen内容

sasjsconfig.json

sasjsconfig.json

Root config holds defaults; each entry in
targets[]
can override them. Key sections:
  • macroFolders
    ,
    binaryFolders
    — where the CLI finds macros/binaries
  • serviceConfig.serviceFolders
    — service source folders;
    initProgram
    runs before every service (set up libnames, options)
  • jobConfig.jobFolders
    — job source folders
  • programFolders
    — programs compiled/deployed with the app
  • streamConfig
    streamWeb: true
    streams the built frontend into SAS so it is served by the platform itself (no separate web server needed);
    webSourcePath
    points at the frontend build output
  • syncFolder
    — folder synced to the server (e.g. mocks)
  • testConfig
    — init/term programs for
    sasjs test
  • targets[]
    — per-environment overrides:
    serverUrl
    ,
    serverType
    (
    SAS9
    /
    SASVIYA
    /
    SASJS
    ),
    appLoc
    (deploy root, e.g.
    /Public/app/myapp
    ), target-specific macroFolders (e.g.
    targets/viya/macros_viya
    for platform shims),
    httpsAgentOptions
    ,
    deployConfig
The full JSON schema is bundled at
sasjsconfig-schema.json
next to this file — validate config changes against it. Reference it with
"$schema": "https://cli.sasjs.io/sasjsconfig-schema.json"
.
根配置文件保存默认设置;
targets[]
中的每个条目可覆盖默认值。核心配置部分:
  • macroFolders
    binaryFolders
    —— CLI查找宏/二进制文件的路径
  • serviceConfig.serviceFolders
    —— 服务源码文件夹;
    initProgram
    会在每个服务运行前执行(用于设置库名、选项)
  • jobConfig.jobFolders
    —— 任务源码文件夹
  • programFolders
    —— 随应用一起编译/部署的程序
  • streamConfig
    ——
    streamWeb: true
    会将构建好的前端流式传输到SAS中,由平台自身提供服务(无需独立Web服务器);
    webSourcePath
    指向前端构建输出目录
  • syncFolder
    —— 同步到服务器的文件夹(例如mocks)
  • testConfig
    —— 用于
    sasjs test
    的初始化/终止程序
  • targets[]
    —— 按环境区分的覆盖配置:
    serverUrl
    serverType
    SAS9
    /
    SASVIYA
    /
    SASJS
    )、
    appLoc
    (部署根路径,例如
    /Public/app/myapp
    )、目标环境专属的macroFolders(例如用于平台适配的
    targets/viya/macros_viya
    )、
    httpsAgentOptions
    deployConfig
完整的JSON schema随此文件捆绑在
sasjsconfig-schema.json
中——配置变更需以此为基准进行验证。可通过
"$schema": "https://cli.sasjs.io/sasjsconfig-schema.json"
引用该schema。

Service contract (frontend ↔ SAS)

服务契约(前端 ↔ SAS)

  1. Adapter POSTs to
    services/<folder>/<name>
    with input tables (arrays of objects) → work datasets named after the JS keys.
  2. Service SAS code runs after
    initProgram
    ; it reads inputs, does work, and writes output JSON to
    _webout
    .
  3. Conventional pattern using @sasjs/core macros:
sas
/**
  @file
  @brief Example service returning data
  <h4> SAS Macros </h4>
  @li mp_jsonout.sas
  @li mp_abort.sas
**/

/* validation / logic here */

%mp_jsonout(OPEN)
%mp_jsonout(OBJ,results,dslabel=results)
%mp_jsonout(CLOSE)
  1. On error, abort cleanly with
    %mp_abort(...)
    (
    mf_abort
    is deprecated) so the adapter receives a structured error in the JSON, not a half-written response. Do not call
    %mp_abort
    inside an
    %if/%else
    block — the macro processor may keep executing beyond the abort. Use the conditional
    iftrue=
    parameter instead, e.g.:
sas
%mp_abort(iftrue= (%mf_existds(work.results)=0)
  ,mac=&_program
  ,msg=%str(No results found)
)
If the abort happens inside a
%include
block, SAS cannot exit to
_webout
cleanly — after the include, call
%mp_abort(mode=INCLUDE)
(outside any macro wrapper), which checks
work.mp_abort_errds
for an abort status.
  1. Adapter向
    services/<folder>/<name>
    发送POST请求,传入输入表(对象数组)→ 生成以JS键命名的工作数据集。
  2. 服务SAS代码在
    initProgram
    之后运行;读取输入数据、执行处理逻辑,并将输出JSON写入
    _webout
  3. 使用@sasjs/core宏的常规模式:
sas
/**
  @file
  @brief 返回数据的示例服务
  <h4> SAS宏 </h4>
  @li mp_jsonout.sas
  @li mp_abort.sas
**/

/* 验证/逻辑代码写在这里 */

%mp_jsonout(OPEN)
%mp_jsonout(OBJ,results,dslabel=results)
%mp_jsonout(CLOSE)
  1. 发生错误时,通过
    %mp_abort(...)
    mf_abort
    已废弃)干净地终止程序,确保Adapter能收到JSON格式的结构化错误响应,而非不完整的输出。请勿
    %if/%else
    块内调用
    %mp_abort
    ——宏处理器可能会在终止后继续执行代码。请改用条件参数
    iftrue=
    ,例如:
sas
%mp_abort(iftrue= (%mf_existds(work.results)=0)
  ,mac=&_program
  ,msg=%str(未找到结果)
)
如果终止发生在
%include
块内,SAS无法干净地退出到
_webout
——在include之后,调用
%mp_abort(mode=INCLUDE)
(在任何宏包装器之外),该宏会检查
work.mp_abort_errds
中的终止状态。

Multi-target discipline

多目标规范

  • Keep backend code platform-neutral in shared folders; put platform-specific shims in
    targets/<name>/macros_*
    folders and register them only on that target.
  • Platform capability macros exist in @sasjs/core (
    mm_*
    metadata,
    mv_*
    Viya,
    ms_*
    server) — don't branch on server type by hand.
  • 在共享文件夹中保持后端代码的平台中立性;将平台专属的适配代码放在
    targets/<name>/macros_*
    文件夹中,并仅在对应目标环境中注册。
  • @sasjs/core中提供了平台能力宏(
    mm_*
    元数据、
    mv_*
    Viya、
    ms_*
    server)——请勿手动根据服务器类型分支代码。

Quality gates (follow the conventions of mature apps like Data Controller)

质量管控(遵循Data Controller等成熟应用的规范)

  • Run
    sasjs lint
    after touching any
    .sas
    file; fix all warnings in files you touched.
  • The linter enforces 2-space indentation everywhere, including continuation lines inside
    /* ... */
    block comments — never align comment text with 3+ spaces.
  • Add tests under
    sasjs/tests
    and run
    sasjs test
    for backend logic changes.
  • Provide mocks in
    sasjs/mocks
    so the frontend can be developed without a live SAS server.
  • Never auto-commit or bump versions; releases are pipeline-driven (conventional commits).
  • Markdown files: no hard wrapping — one paragraph per line.
  • Apps must work offline/on-prem: no external CDN assets in the frontend bundle.
  • 修改任何
    .sas
    文件后运行
    sasjs lint
    ;修复你修改的文件中的所有警告。
  • 代码检查器强制要求所有地方使用2空格缩进,包括
    /* ... */
    块注释内的换行——切勿用3个及以上空格对齐注释文本。
  • sasjs/tests
    下添加测试用例,后端逻辑变更时运行
    sasjs test
  • sasjs/mocks
    中提供模拟数据,以便前端无需连接SAS服务器即可开发。
  • 切勿自动提交或升级版本;版本发布由流水线驱动(遵循约定式提交规范)。
  • Markdown文件:禁止硬换行——每段文字占一行。
  • 应用必须支持离线/本地部署:前端包中不得包含外部CDN资源。

Reference implementations

参考实现

Look at existing apps for patterns: folder layouts,
sasjsconfig.json
multi-target setups, service structure, streaming builds, and test/mock conventions (e.g. Data Controller
dc
,
dwp_frs
,
plato
).
可参考现有应用的模式:文件夹布局、
sasjsconfig.json
多目标配置、服务结构、流式构建、测试/模拟规范(例如Data Controller
dc
dwp_frs
plato
)。