mcpField
S
sasjs-adapter

sasjs-adapter

github.com/sasjs開発31.1k 回インストール2 日前に更新
リポジトリ

sasjs-adapter について

ブラウザーや Node.js から SAS のサービスやジョブを呼び出す TypeScript ライブラリです。SAS9、SASVIYA、SASJS に共通する API を使い、JavaScript アプリへの SAS 実行機能の組み込みを支援します。

主な機能

  1. 013 種類の SAS サーバーへの共通呼び出し
  2. 02入力テーブルの CSV シリアライズ
  3. 03パラメーター送信とファイルアップロード
  4. 04認証とセッションの管理
  5. 05リクエスト履歴の保存とログ取得

活用シーン

  1. 01ブラウザーからテーブルを送って SAS ジョブを実行
  2. 02Node.js から Viya にジョブを送信
  3. 03リクエストをデバッグして SAS ログを確認

インストール

コマンドをコピーしてターミナルで実行します。

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

インストール後、Claude Code で/sasjs-adapterを入力して読み込まれたか確認します。

詳細

@sasjs/adapter

@sasjs/adapter は、ブラウザーまたは Node から SAS サービス/ジョブを呼び出すための TypeScript ライブラリです。SAS9、SASVIYA、SASJS の 3 種類のサーバーで共通の API を提供します。

基本設定

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() - 入力(JS -> SAS)

シグネチャ
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:appLoc を基準に解決される相対パス(先頭にスラッシュは付けません)、または絶対パスです。SAS の _program パラメーターになります。
  • data:キーが SAS の work データセットになるオブジェクトです。サービスに入力が不要な場合は null にできます。
  • config:この呼び出しに限り、コンストラクターの設定にマージして上書きする設定です。
data オブジェクト - 任意の JSON ではなくテーブル

data の各キーの値は、すべてプレーンオブジェクトの 配列 でなければなりません。各キーはその名前を持つ SAS work データセットになり、配列内の各オブジェクトは行、各プロパティは列になります。

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
})

SAS 側では、これらは work.customers および work.config として受け取られます。

入力検証ルール

送信前に、アダプターは data を検証します(validateInput を参照)。違反があると、ErrorResponse を伴ってプロミスが拒否されます。

  • data は null またはプレーンオブジェクトでなければなりません(配列やプリミティブ値は不可)。
  • テーブルキーはすべて、英字またはアンダースコアで始まる必要があります:/^[a-zA-Z_][a-zA-Z0-9_]*$/。数字で始まる名前は拒否されます。
  • テーブル名は 32 文字 を超えてはなりません(SAS の名前の上限)。
  • キーの下にある値はすべてオブジェクトの配列でなければなりません。オブジェクト以外の行は拒否されます。
  • いずれの行のプロパティも undefined であってはなりません(null、文字列、数値、またはブール値である必要があります)。
テーブルを CSV にシリアライズする方法

各テーブルは convertToCSV を使って CSV に変換されます。変換では型が考慮されます。

  • 文字列列:カンマ、タブ、改行、または引用符を含む場合にのみ引用符で囲みます。内部の " は "" にエスケープされます。
  • 数値列:引用符で囲まずに出力されます。
  • 数値列の null/空値:.(SAS の欠損値)になります。
  • 列の型推論:アダプターは列ごとにすべての行をスキャンします。列に null/数値と特殊欠損値を表す文字列(.a-.z、_)の両方がある場合、その列の型は best. になります。それ以外の場合は、最初の空でない値によって chars と number のどちらかが決まります。
  • 列フォーマットヘッダー:最初の CSV 行は、スペース区切りのフォーマット指定です(例:name:$char20. id:best.)。SAS 側ではこれを使ってインフォーマットを割り当てます。
  • バイトサイズの長さチェック:文字列の値は UTF-8 のバイト数で計測されます。いずれかの値が 32765 バイト を超えると、リクエストは The max length of a string value in SASjs is 32765 characters. をスローします。
  • フォーマットテーブル:$ を先頭に付けたキー(例:$customers)は、customers テーブルのフォーマット定義として扱われ、個別のデータセットとしては送信されません。その formats プロパティで、列名と SAS フォーマットを対応付けます。
2 つの転送方式

アダプターは、ペイロードのサイズとサーバーの種類に応じて転送方式を選択します(WebJobExecutor を参照)。

  1. パラメーター方式(Viya Web/SASjs サーバーのデフォルト、小さなペイロードの場合):各テーブルの CSV は、sasjs{N}data(N = 1, 2, ...)という名前のフォームフィールドとして追加されます。sasjs_tables フィールドには、テーブル名がスペース区切りで列挙されます。単一の CSV が 16000 文字を超える場合はチャンクに分割されます。sasjs{N}data0 にチャンク数が入り、sasjs{N}data1..N に各チャンクが入ります。
  2. ファイルアップロード方式(常に SAS 9 で使用。JSON.stringify(data) が 500000 文字を超える、または ; を含む場合は Viya/SASjs でも使用):各テーブルは {tableName}.csv という CSV ファイルとして、マルチパートフォームデータに追加されます。

どちらの場合も、debug: true の場合、本文はデバッグパラメーター(_debug=131、_omittextlog=false、_omitSessionResults=false)を含む multipart/form-data です。

request() - 出力(SAS -> JS)

レスポンスの形式は extraResponseAttributes によって異なります

デフォルト(extraResponseAttributes なし):解決された値は、パース済みの webout オブジェクトそのものです。つまり、SAS サービスが _webout に書き込んだ JSON が返されます。

// 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

extraResponseAttributes を指定した場合(例:['log']):結果はラップされます。

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

ExtraResponseAttributes は 'file' | 'data' | 'log' です。現行リリースで完全に実装されているのは log のみです。

名前の大文字・小文字
  • 応答内のテーブル名は小文字です。これはアダプターではなく、SAS 側の %webout/mp_jsonout マクロによって適用されます。アダプターは webout の JSON をそのまま渡します。
  • 列名は大文字です。SAS データセットの変数名は SAS 自体によって大文字に変換され、アダプターでは大文字・小文字を変換しません。
SAS サービスが出力する必要があるもの

サービスは _webout に有効な JSON を書き込む必要があります。通常は %webout(@sasjs/core 提供)を使用し、これは mp_jsonout をラップします。JSON の形式は、キーがテーブル名で、それぞれの値が行オブジェクトの配列であるオブジェクトです。

%webout(OPEN)
%webout(OBJ, work.customers)   /* -> {"customers":[{...}]} */
%webout(CLOSE)
デバッグモード

config.debug が true の場合:

  • SAS 9:生の応答は、ログと webout を含む文字列で、>>weboutBEGIN<< と >>weboutEND<< で区切られます。アダプターはマーカー間の JSON を抽出します。
  • Viya(web/JES):デバッグ応答は parseSasViyaDebugResponse/parseSasViyaLogDebugResponse で解析され、ログと webout JSON が分離されます。
  • Viya(compute API):ログは compute セッションから個別に取得されます。

いずれの場合も、デバッグを有効にして extraResponseAttributes: ['log'] を指定すると、SAS ログを res.log で参照できます。

リクエスト履歴

実行されたすべてのリクエストは、メモリ内の履歴に追加されます(上限は requestHistoryLimit。既定値は 10 です)。

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

sourceCode と generatedCode が設定されるのは、debug: true の場合のみです。履歴はリングバッファーで、上限を超えると最も古いエントリーが削除されます。

認証

  • SAS 9:sasjs.logIn(username, password)(Stored Process サーバーに対するフォームベースの認証)。セッション Cookie は自動的に管理されます。
  • Viya:OAuth クライアント/シークレット(クライアントクレデンシャル付与)または認可コードフローを使用します。トークンは自動的に更新されます。Node での使用時は CLI(sasjs add cred)で設定します。Node では、authConfig(クライアント/シークレット/アクセストークン/リフレッシュトークン)を request() に渡します。
  • SASJS サーバー:sasjs/server API に対するトークンベースの認証です。

主なクラス/モジュール

  • SASjs - メインのファサード:request()、logIn()/logOut()、uploadFile()、executeScript()、startComputeJob()、deployServicePack()
  • RequestClient - HTTP レイヤー。リクエスト履歴(getRequests())、CSRF トークン、認証ヘッダーを保持します。
  • WebJobExecutor - SAS 9 STP、Viya web JES、SASjs サーバーの web(マルチパートフォーム POST)
  • ComputeJobExecutor - Viya compute API(名前付きコンテキストへのコードの直接送信)
  • JesJobExecutor - Viya JES API(web アプリではなく、jobs API を介したジョブ送信)
  • SasjsJobExecutor - SASjs サーバーの web 実行
  • SessionManager - Viya compute セッションのライフサイクル
  • SASViyaApiClient/SAS9ApiClient/SASjsApiClient - プラットフォームごとの低レベルクライアント(直接使用することはほとんどありません)
  • file/ ユーティリティ - SAS へのファイルアップロード(バイナリーコンテンツの処理)

ヒント

  • 開発中は debug: true を設定すると、応答に SAS ログが表示されます。
  • response.status/エラー応答は必ず処理してください。SAS 側のエラー(例:%mp_abort によるエラー)は JSON 内に返され、必ずしも HTTP エラーになるとは限りません。
  • 大きなペイロードには、JSON 入力テーブルよりも CSV アップロードまたはストリームファイルを使用してください。
  • デプロイに使用した sasjsconfig.json の appLoc と一致するように appLoc を設定してください。
  • SAS から返される列名は大文字です。フロントエンドで小文字が必要な場合は、SAS の大文字・小文字を無理に変更しようとせず、JS でマッピングしてください。
  • 数値入力列の null は SAS の欠損値(.)になります。文字列列の空文字列は空文字列になります。undefined は使用しないでください。検証で拒否されます。

バンドラーを使わずにアダプターを使用する(ゼロビルド/厳格な CSP のフロントエンド)

パッケージのルートにある index.js は、グローバル変数 SASjs を公開する UMD バンドルです。最小構成のシードアプリに基づく手順は次のとおりです。

  1. package.json に "prepare": "cp node_modules/@sasjs/adapter/index.js src/sasjs.js" を記述します(npm i の実行時に処理されます)。
  2. アプリのスクリプトより前に <script src="sasjs.js"></script> を配置します。
  3. 非表示のカスタム要素で設定します:<sasjs serverType="SASJS" appLoc="/Public/app/myapp" debug="false"></sasjs>。属性は document.querySelector('sasjs') で読み取ります。SAS 自体がアプリをストリーミングする場合は、serverUrl を省略してください。同一オリジンへのリクエストはそのまま動作します(CSP default-src 'self' に対応)。

制限事項

このスキルは、@sasjs/adapter ライブラリの静的リファレンスです。API、リクエスト/レスポンスの形式、認証、CSV のシリアル化に関するガイダンスを提供します。コードの実行、シェルコマンドの実行、ファイルシステムへのアクセス、データベースへの接続、ネットワークリクエストの実行は行いません。すべてのコード例は説明用です。ユーザー自身がアプリケーションに統合する必要があります。認証トークンへの言及は、アダプターライブラリが実行時に管理する値について説明したものです。このスキル自体がその値を読み取り、書き込み、またはアクセスすることはありません。

コメント