Agent skill

Sasjs Adapter

by sasjs in sasjs/core

Frontend/Node integration with SAS backends using @sasjs/adapter - configuring the SASjs class, the exact request() inputs and response shape, authentication, file upload, and session management.

MITAuto-check passedBackend & APIs

Install Sasjs Adapter

skills CLI
$ npx skills add sasjs/core --skill sasjs-adapter -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install sasjs/core sasjs-adapter --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/sasjs/core.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/sasjs-adapter .claude/skills/sasjs-adapter && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
sasjs-adapter
GitHub stars
132
Token cost
~2.6k tokens
SKILL.md length
1,182 words
Files
1
Skills in repo
6
Repo updated
First seen
Licence
MIT

At a glance

Frontend/Node integration with SAS backends using @sasjs/adapter - configuring the SASjs class, the exact request() inputs and response shape, authentication, file upload, and session management.

  • Works in 2 steps: Param-based (default for Viya web /… → File-upload (SAS 9 always; Viya/SASjs…
  • Writing TypeScript/JavaScript that calls SAS services
  • SKILL.md covers Basic setup, request() - inputs (JS -> SAS), request() - outputs (SAS -> JS) and Authentication, plus 4 more sections
  • Calls npm

What it does

Sasjs Adapter is an agent skill from sasjs/core. Frontend/Node integration with SAS backends using @sasjs/adapter - configuring the SASjs class, the exact request() inputs and response shape, authentication, file upload, and session management. Use when writing TypeScript/JavaScript that calls SAS services or jobs.

Its SKILL.md is about 2.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Backend & APIs, covering Authentication and File uploads and storage. It works with TypeScript and JavaScript. The repository describes itself as: Macros for SAS® App Developers. The licence is MIT.

When your agent uses it

  • Writing TypeScript/JavaScript that calls SAS services
  • Tasks that involve Authentication
  • Tasks that involve File uploads and storage

Example prompts

  • “/sasjs-adapter”

Requirements

  • Node.js

Workflow steps

2 steps, taken from the first numbered list in SKILL.md.

  1. Param-based (default for Viya web / SASjs server, small payloads): each table's CSV is appended as a form field named sasjs{N}data (N = 1…
  2. File-upload (SAS 9 always; Viya/SASjs when JSON.stringify(data) exceeds 500000 chars or contains a ;): each table is appended as a CSV…

What it can do on your machine

Read from SKILL.md and the folder at commit b13a83f. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use npm, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Sasjs Adapter loads about 2.6k tokens when it runs. Until then it costs about 70 tokens; SKILL.md has 1,182 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~70
When it runs · the whole SKILL.md, loaded when a task matches
~2.6k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from sasjs/core at commit b13a83f, republished under its MIT licence (© sasjs). 1,182 words, ~2,624 tokens.

Download SKILL.mdSave it as .claude/skills/sasjs-adapter/SKILL.md (or your agent's skills folder).
name
sasjs-adapter
description
Frontend/Node integration with SAS backends using @sasjs/adapter - configuring the SASjs class, the exact request() inputs and response shape, authentication, file upload, and session management. Use when writing TypeScript/JavaScript that calls SAS services or jobs.

@sasjs/adapter

@sasjs/adapter is the TypeScript library for calling SAS services/jobs from browsers or Node, with a unified API across three server types: SAS9, SASVIYA, SASJS.

Basic setup

ts
import SASjs from '@sasjs/adapter'

const sasjs = new SASjs({
  serverUrl: 'https://sas.example.com',
  serverType: 'SASVIYA',      // SAS9 | SASVIYA | SASJS
  appLoc: '/Public/app/myapp', // root folder of deployed services
  contextName: 'SAS Job Execution compute context', // Viya only
  debug: false
})

request() - inputs (JS -> SAS)

Signature
ts
sasjs.request(
  sasJob: string,
  data: { [key: string]: any[] } | null,
  config?: { [key: string]: any },             // merged over SASjsConfig
  loginRequiredCallback?: () => any,
  authConfig?: AuthConfig,                      // Viya tokens for Node usage
  extraResponseAttributes?: ExtraResponseAttributes[]  // ['log'] | ['file'] | ['data']
)
  • sasJob: relative path (no leading slash) resolved against appLoc, or an absolute path. Becomes the SAS _program parameter.
  • data: an object whose keys become work datasets in SAS. Can be null if the service takes no input.
  • config: overrides merged on top of the constructor config for this call only.
The data object - tables, not arbitrary JSON

Every key in data must be an array of plain objects. Each key becomes a SAS work dataset named after the key; each object in the array is a row; each property is a column.

ts
const res = await sasjs.request('services/common/getdata', {
  customers: [
    { id: 1, name: 'Acme', active: true },
    { id: 2, name: 'Globex', active: false }
  ],
  config: [{ rootdir: '/tmp', retries: 3 }]  // even a single-row "config" table
})

On the SAS side these arrive as work.customers and work.config.

Input validation rules

Before sending, the adapter validates data (see validateInput). Violations reject the promise with an ErrorResponse:

  • data must be null or a plain object (not an array, not a primitive).
  • Every table key must start with a letter or underscore: /^[a-zA-Z_][a-zA-Z0-9_]*$/. Numbers at the start are rejected.
  • Table names cannot exceed 32 characters (SAS name limit).
  • Every value under a key must be an array of objects. Non-object rows are rejected.
  • No property in any row may be undefined (it must be null, a string, a number, or a boolean).
How tables are serialized to CSV

Each table is converted to CSV via convertToCSV. The conversion is type-aware:

  • String columns: quoted only if they contain commas, tabs, newlines, or quotes. Internal " is escaped as "".
  • Numeric columns: emitted unquoted.
  • Null / empty in a numeric column: becomes . (SAS missing).
  • Column type inference: the adapter scans all rows per column. If a column has both null/number values and special-missing strings (.a-.z, _), the column is typed as best.. Otherwise the first non-empty value determines chars vs number.
  • Column format header: the first CSV line is a space-delimited format spec, e.g. name:$char20. id:best. - the SAS side uses this to assign informats.
  • Byte-size length check: string values are measured in UTF-8 bytes. If any value exceeds 32765 bytes, the request throws The max length of a string value in SASjs is 32765 characters.
  • Formats tables: a key prefixed with $ (e.g. $customers) is treated as a formats definition for the customers table and is not sent as a separate dataset. Its formats property maps column names to SAS formats.
Two transport modes

The adapter picks the transport based on payload size and server type (see WebJobExecutor):

  1. Param-based (default for Viya web / SASjs server, small payloads): each table's CSV is appended as a form field named sasjs{N}data (N = 1, 2, ...). A sasjs_tables field lists the table names space-separated. If a single CSV exceeds 16000 chars it is split into chunks: sasjs{N}data0 holds the chunk count, sasjs{N}data1..N hold the pieces.
  2. File-upload (SAS 9 always; Viya/SASjs when JSON.stringify(data) exceeds 500000 chars or contains a ;): each table is appended as a CSV file ({tableName}.csv) in multipart form data.

In both cases the body is multipart/form-data with debug params (_debug=131, _omittextlog=false, _omitSessionResults=false) when debug: true.

request() - outputs (SAS -> JS)

Response shape depends on extraResponseAttributes

Default (no extraResponseAttributes): the resolved value is the parsed webout object directly - whatever JSON the SAS service wrote to _webout:

ts
// SAS service wrote: {"mydata":[{"COL1":"x","COL2":1}]}
const res = await sasjs.request('services/getdata', { in: [{ a: 1 }] })
// res === { mydata: [{ COL1: 'x', COL2: 1 }] }
// res.mydata[0].COL1  // note UPPERCASE column names

With extraResponseAttributes (e.g. ['log']): the result is wrapped:

ts
const res = await sasjs.request('services/getdata', { in: [{ a: 1 }] }, {}, undefined, undefined, ['log'])
// res === { result: { mydata: [...] }, log: '<sas log string>' }

ExtraResponseAttributes is 'file' | 'data' | 'log'. Only log is fully implemented in current releases.

Name casing
  • Table names in the response are lowercase - this is enforced by the %webout/mp_jsonout macro on the SAS side, not the adapter. The adapter passes the webout JSON through as-is.
  • Column names are UPPERCASE - SAS dataset variable names are uppercased by SAS itself, and the adapter does not re-case them.
What the SAS service must produce

The service must write valid JSON to _webout. Conventionally via %webout (from @sasjs/core), which wraps mp_jsonout. The JSON shape is an object whose keys are table names, each mapping to an array of row objects:

sas
%webout(OPEN)
%webout(OBJ, work.customers)   /* -> {"customers":[{...}]} */
%webout(CLOSE)
Debug mode

When config.debug is true:

  • SAS 9: the raw response is a string containing the log plus the webout, delimited by >>weboutBEGIN<< and >>weboutEND<<. The adapter extracts the JSON between the markers.
  • Viya (web/JES): the debug response is parsed via parseSasViyaDebugResponse / parseSasViyaLogDebugResponse, which split out the log and the webout JSON.
  • Viya (compute API): the log is fetched separately from the compute session.

In all cases, with debug on and extraResponseAttributes: ['log'], the SAS log is available in res.log.

Show full SKILL.md (449 more words)Show less
Request history

Every executed request is appended to an in-memory history (capped at requestHistoryLimit, default 10):

ts
sasjs.getSasRequests()
// SASjsRequest[]: { serviceLink, timestamp, sourceCode, generatedCode, logFile, SASWORK }

sourceCode and generatedCode are only populated when debug: true. The history is a ring buffer - oldest entries are dropped when the limit is exceeded.

Authentication

  • SAS 9: sasjs.logIn(username, password) (form-based against the stored process server). Session cookie is managed automatically.
  • Viya: OAuth client/secret (client credentials grant) or authorization code flow; tokens are refreshed automatically. Configure via CLI (sasjs add cred) for Node usage. For Node, pass authConfig (client/secret/access/refresh tokens) to request().
  • SASJS server: token-based auth against the sasjs/server API.

Key classes / modules

  • SASjs - main facade: request(), logIn()/logOut(), uploadFile(), executeScript(), startComputeJob(), deployServicePack()
  • RequestClient - HTTP layer; holds the request history (getRequests()), CSRF tokens, and auth headers
  • WebJobExecutor - SAS 9 STP, Viya web JES, and SASjs server web (multipart form POST)
  • ComputeJobExecutor - Viya compute API (direct code submission on a named context)
  • JesJobExecutor - Viya JES API (job submission via the jobs API, not the web app)
  • SasjsJobExecutor - SASjs server web execution
  • SessionManager - Viya compute session lifecycle
  • SASViyaApiClient / SAS9ApiClient / SASjsApiClient - low-level per-platform clients (rarely needed directly)
  • file/ utilities - file upload to SAS (binary content handling)

Tips

  • Set debug: true to surface the SAS log in responses while developing.
  • Always handle response.status / error responses - SAS-side errors (e.g. from %mp_abort) come back in the JSON, not necessarily as HTTP errors.
  • For large payloads prefer CSV upload or streamed files over JSON input tables.
  • Keep appLoc consistent with the appLoc in sasjsconfig.json used to deploy.
  • Column names come back UPPERCASE from SAS. If your frontend expects lowercase, map them in JS rather than trying to force SAS casing.
  • null in a numeric input column becomes SAS missing (.); empty string in a char column becomes empty string. Don't use undefined - validation rejects it.

Using the adapter without a bundler (zero-build / strict CSP frontends)

The package root index.js is a UMD bundle exposing a global SASjs. Pattern (from the minimal seed app):

  1. "prepare": "cp node_modules/@sasjs/adapter/index.js src/sasjs.js" in package.json (runs on npm i).
  2. <script src="sasjs.js"></script> before your app script.
  3. Configure via a hidden custom element: <sasjs serverType="SASJS" appLoc="/Public/app/myapp" debug="false"></sasjs> and read attributes with document.querySelector('sasjs'). When the app is streamed by SAS itself, omit serverUrl - same-origin requests just work (CSP default-src 'self' safe).

Limitations

This skill is a static reference for the @sasjs/adapter library - it provides guidance on the API, request/response shapes, authentication, and CSV serialization. It does not execute code, run shell commands, access the filesystem, connect to databases, or make network requests. All code examples are illustrative; the user must integrate them into their own application. References to authentication tokens describe what the adapter library manages at runtime - this skill does not read, write, or access those values itself.

© sasjs, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .agents/skills/sasjs-adapter of sasjs/core.

Open the folder on GitHubat commit b13a83f

Compare with similar skills

Sasjs Adapter next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Sasjs Adapter compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Sasjs Adapter this skillsasjs/core132—~2.6kAutomated safety check: PassMIT
Gemini Live API Devgoogle-gemini/gemini-skills4.3k—~4.6kAutomated safety check: PassApache-2.0
Azure Storage Blob TSmicrosoft/skills3.1k5 repos~3.3kAutomated safety check: PassMIT
Javascript SDKaiskillstore/marketplace4301 repos~3.3kAutomated safety check: PassNone
Security Sensitive Path InstrumenterArabelaTso/Skills-4-SE253—~1.1kAutomated safety check: PassApache-2.0
Gemini Live API DevJetBrains/skills366—~2.6kAutomated safety check: PassNone

Similar skills

  • Gemini Live API Dev

    google-gemini/gemini-skills

    Official

    A skill your agent uses when building real-time, bidirectional streaming applications with the Gemini Live API, or migrating legacy Live models (2.0/2.5/3.1) to Gemini 3.8 Live.

    4.3k GitHub stars~4.6k tokensUpdated 2 days ago
    Backend & APIsAuto-check passed
  • Azure Storage Blob TS

    microsoft/skills

    Official

    Azure Blob Storage JavaScript/TypeScript SDK (@azure/storage-blob) for blob operations.

    3.1k GitHub starsUsed in 5 repos~3.3k tokens
    Backend & APIsAuto-check passed
  • Javascript SDK

    aiskillstore/marketplace

    JavaScript/TypeScript SDK for inference.sh - run AI apps, build agents, integrate with all models.

    430 GitHub starsUsed in 1 repo~3.3k tokens
    Backend & APIsAuto-check passed
  • Instruments authentication, authorization, and input-handling code paths to monitor security-relevant events and states at runtime.

    253 GitHub stars~1.1k tokensUpdated 1 mo ago
    Backend & APIsAuto-check passed
  • Gemini Live API Dev

    JetBrains/skills

    Official

    A skill your agent uses when building real-time, bidirectional streaming applications with the Gemini Live API.

    366 GitHub stars~2.6k tokensUpdated 3 mo ago
    Backend & APIsAuto-check passed
  • Create Auth Skill

    deadlock-mod-manager/deadlock-mod-manager

    Scaffold and implement authentication in TypeScript/JavaScript apps using Better Auth.

    477 GitHub starsUsed in 4 repos~3.4k tokens
    DatabasesAuto-check passed

More from sasjs/core

  • Sas

    sasjs/core

    Expert guidance for the SAS programming language - DATA step, PROC SQL, macro language, formats, ODS, and common procedures.

    132 GitHub stars~3.1k tokensUpdated 4 days ago
    Auto-check passed
  • Sasjs CLI

    sasjs/core

    Using the SASjs CLI (@sasjs/cli) to create, compile, build, deploy, run, and test SASjs projects against SAS 9, Viya, and SASjs server targets.

    132 GitHub stars~3.6k tokensUpdated 4 days ago
    Auto-check: notes
  • Sasjs Core

    sasjs/core

    Standards and conventions for the @sasjs/core SAS macro library (mf, mp, mm, ms, mv macros).

    132 GitHub stars~1.2k tokensUpdated 4 days ago
    Auto-check passed
  • Sasjs Framework

    sasjs/core

    Building full SASjs applications - project structure, sasjsconfig.json, services/jobs/macros folders, multi-target (SAS 9 / Viya / SASjs server) configuration, streaming frontends, mocks and tests.

    132 GitHub stars~2.4k tokensUpdated 4 days ago
    Auto-check passed
  • Sasjs Server

    sasjs/core

    Installing, configuring, and running @sasjs/server - the open-source NodeJS wrapper around the SAS binary that provides a REST API, filesystem (SASjs Drive), Stored Program execution, and web app…

    132 GitHub stars~2.4k tokensUpdated 4 days ago
    Auto-check: notes

Categories

Questions about Sasjs Adapter

What does Sasjs Adapter do?

Frontend/Node integration with SAS backends using @sasjs/adapter - configuring the SASjs class, the exact request() inputs and response shape, authentication, file upload, and session management. Sasjs Adapter is an agent skill from sasjs/core. Frontend/Node integration with SAS backends using @sasjs/adapter - configuring the SASjs class, the exact request() inputs and response shape, authentication, file upload, and session management.

When should I use Sasjs Adapter?

Sasjs Adapter fits situations like: writing TypeScript/JavaScript that calls SAS services; tasks that involve Authentication; tasks that involve File uploads and storage.

How do I install Sasjs Adapter in Claude Code?

Run `npx skills add sasjs/core --skill sasjs-adapter -a claude-code`. Or copy the skill folder (.agents/skills/sasjs-adapter in sasjs/core) into .claude/skills/sasjs-adapter in your project. Claude Code loads it when a task matches its description.

How do I install Sasjs Adapter in Codex?

Run `npx skills add sasjs/core --skill sasjs-adapter -a codex`. Or copy the skill folder (.agents/skills/sasjs-adapter in sasjs/core) into .agents/skills/sasjs-adapter in your project. Codex loads it when a task matches its description.

Can I use Sasjs Adapter in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add sasjs/core --skill sasjs-adapter -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/sasjs-adapter, .gemini/skills/sasjs-adapter, .github/skills/sasjs-adapter and .opencode/skills/sasjs-adapter in your project.

What does Sasjs Adapter need to run?

Going by SKILL.md and its folder, Sasjs Adapter needs the command-line tools its instructions call (npm). Our summary lists: Node.js.

Does Sasjs Adapter access the network?

SKILL.md contains no URLs. Its commands use npm, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Sasjs Adapter safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Sasjs Adapter use?

Sasjs Adapter is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Sasjs Adapter use?

About 2.6k tokens (SKILL.md is roughly 10k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Sasjs Adapter?

Skills that share tags, products or a category with Sasjs Adapter: Gemini Live API Dev (google-gemini/gemini-skills, 4.3k stars), Azure Storage Blob TS (microsoft/skills, 3.1k stars), Javascript SDK (aiskillstore/marketplace, 430 stars) and Security Sensitive Path Instrumenter (ArabelaTso/Skills-4-SE, 253 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Sasjs Adapter?

sasjs (a GitHub organization) maintains it in sasjs/core, which has 132 GitHub stars. The repository holds 6 skills in this directory. The repository was last updated on October 5, 2026.

Source: sasjs/core on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.