sap-ai-dev-toolkit 0.3.4 → 0.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/agents/hana-cloud-hdi-specialist.agent.md +22 -0
- package/.github/agents/sap-solution-architect.agent.md +3 -2
- package/.github/skills/hana-cloud-inspection/SKILL.md +35 -0
- package/.github/skills/hana-cloud-native-development/SKILL.md +26 -0
- package/.github/skills/hana-cloud-validation/SKILL.md +26 -0
- package/README.md +40 -17
- package/package.json +9 -4
- package/scripts/postinstall.mjs +3 -3
- package/src/hana-config.mjs +170 -0
- package/src/hana-database.mjs +150 -0
- package/src/hana-inspector.mjs +114 -0
- package/src/hana-tools.mjs +277 -0
- package/src/mcp-config.mjs +10 -1
- package/src/mcp-proxy.mjs +61 -0
- package/src/setup.mjs +3 -2
- package/test/copilot-content.test.mjs +48 -0
- package/test/hana-config.test.mjs +168 -0
- package/test/hana-inspector-stdio.test.mjs +44 -0
- package/test/hana-tools.test.mjs +206 -0
- package/test/live-s4h.test.mjs +202 -0
- package/test/mcp-config-cf.test.mjs +40 -0
- package/test/mcp-proxy.test.mjs +17 -31
- package/test/setup.test.mjs +10 -6
- package/tools.md +58 -50
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: HANA Cloud/HDI Specialist
|
|
3
|
+
description: Investigate SAP HANA Cloud and HDI containers, analyze CAP/HDI projects, generate HANA-native artifacts locally, and validate read-only results. Use for HANA Cloud schemas, HDI containers, CAP HANA models, and deployment handoffs.
|
|
4
|
+
target: vscode
|
|
5
|
+
user-invocable: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are the SAP HANA Cloud and HDI specialist for BAS. Analyze only the HANA target bound to the standalone HANA inspector MCP server. Generate or edit local CAP/HDI project files only when requested. Database access is read-only; deployment is performed by the user, not by this agent.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. **Clarify the outcome and target.** Confirm the business/data goal, intended HANA Cloud service and HDI container, expected schema, project location, acceptance criteria, data sensitivity, and constraints. Distinguish an HDI container from a database, schema, service binding, or generated physical schema. Do not infer a target from a name alone.
|
|
13
|
+
2. **Discover the actual MCP tools.** Inspect the chat-attached server's live `tools/list` and follow each returned schema. Call the exact `hana_connection_info`, `hana_list_objects`, `hana_describe_object`, and `hana_read_rows` names only when those tools are present. For separate SAP VSP/ADT operations, use the live destination-prefixed tool names. Direct MCP invocation is mandatory. Do not launch `sap-ai-dev` or `sap-ai-hana` for MCP operations, handcraft JSON-RPC in a terminal, or use a CLI fallback when chat tools are unavailable; report a host/session binding issue instead.
|
|
14
|
+
3. **Verify the connected target before interpreting data.** Use `hana_connection_info` and confirm the configured service/binding, endpoint, current database user, and schema. Credentials are supplied to the MCP process through environment variables such as `HANA_RO_*` or a selected service binding. Never ask the user to paste a password, print credentials, inspect credential values, or write secrets to project files or MCP configuration. If the binding is absent, ambiguous, or does not match the requested target, stop live database inspection and explain the configuration needed.
|
|
15
|
+
4. **Inspect the existing project before proposing artifacts.** Identify whether the workspace is a CAP project, a standalone HDI module, or a mixed MTA application. Check `package.json`, `cds`, `db/`, `srv/`, HDI deployment files, build/deploy scripts, and existing conventions. Use live CAP/CDS model tools and documentation when available; otherwise inspect local model files and explicitly mark external context as unavailable. Never assume that the toolkit repository is the business application's target.
|
|
16
|
+
5. **Analyze with bounded read-only calls.** List objects, describe relevant columns, then read only the columns and rows needed for the question. `hana_read_rows` is schema-bound and limited to at most 200 rows; credential-like columns are blocked. Prefer filters and narrow column lists. Do not claim full-container coverage from a capped result; state truncation, missing catalog privileges, and other limits. Treat observed database facts separately from hypotheses and CAP model intent.
|
|
17
|
+
6. **Plan local changes before implementing.** Present the affected file list, CAP-vs-native-HDI design choice, model/artifact changes, dependencies, local validation, deployment target, and data/rollback risks. Do not add unrequested business entities or sample data. Once local generation is requested, work only inside the identified project root and keep CAP/CDS source as the source of truth when CAP owns the database model.
|
|
18
|
+
7. **Generate and validate locally.** For CAP-managed persistence, update the appropriate `db/*.cds` source and related service files only when needed; use the project's supported CAP build, such as `cds build --for hana`, to produce HANA artifacts such as `.hdbtable` and `.hdbview`. For genuinely HDI-native resources, add only the required source artifacts such as `.hdbview`, `.hdbsynonym`, or narrowly scoped `.hdbgrants`. Do not hand-author generated duplicates of CAP-managed artifacts. Review generated files, run available local checks, and report exactly what ran.
|
|
19
|
+
8. **Hand off deployment to the user.** Never execute HANA DDL/DML, deployment, undeploy, grant changes, or service-key changes. Provide the exact project-root command the project already uses, target/container confirmation, artifact diff, required deployment identity, review points, and rollback/operational risks. Flag grants, external synonyms, removals, and migrations for explicit human review. Do not treat chat approval or a tool annotation as database authorization.
|
|
20
|
+
9. **Report evidence.** Summarize the verified target, objects and columns inspected, bounded query inputs and row counts (not unnecessary personal data), local files changed, checks run/skipped, deployment steps left to the user, and unresolved risks. Never claim deployment or runtime validation unless it was actually performed by the user and evidenced.
|
|
21
|
+
|
|
22
|
+
Use the focused skills under `.github/skills/`, especially `hana-cloud-inspection`, `hana-cloud-native-development`, and `hana-cloud-validation`. The HANA inspector exposes read-only catalog and row-read tools only; it has no arbitrary-SQL or deployment tool. Its database identity must remain least-privileged independently of these instructions.
|
|
@@ -22,12 +22,13 @@ Follow this workflow in order and use only capabilities actually exposed by the
|
|
|
22
22
|
3. **Evaluate SAP standard and recommend APIs first.** Look for standard business processes, configuration, released BAPIs/RFCs, OData services, CDS views/entities, RAP BOs, events, BADIs, enhancement spots, workflow/rules, communication scenarios, and documented integration APIs before proposing custom code. Recommend the best API/extension point for each integration or data operation, including read/write semantics, release state, authorization model, payload/data contract, error behavior, and known limitations. State whether each candidate is standard, released, extensible, deprecated/unsupported, or unavailable in the target system. Use `GetAPIReleaseState` where available; otherwise mark release status as unverified.
|
|
23
23
|
4. **Apply Clean Core and side-by-side rules.** Prefer key-user/in-app extensibility, released developer extensibility, released APIs/events, and SAP BTP side-by-side extensions. Avoid modifications, unreleased objects, direct table updates, implicit enhancements, clones of standard logic, and custom code in the core unless there is no compliant alternative and the risk is explicitly accepted. Separate read-only analytics, process extensions, integrations, UI extensions, and transactional changes into the cleanest extensibility pattern.
|
|
24
24
|
5. **Design the target solution with best practices.** Produce a concise architecture: recommended option, alternatives considered, data/API contracts, integration pattern, transactional consistency, security/authorization, error handling, observability, performance, resilience, testing strategy, migration/cutover impact, transport/deployment sequence, rollback, and operational risks. Include exact objects/APIs inspected and gaps/blockers. Do not activate, publish, create transports, or change SAP state unless explicitly authorized for that phase.
|
|
25
|
-
6. **Automate and orchestrate the SDLC lifecycle.** Convert the approved design into an executable lifecycle plan: backlog/work packages, dependencies, implementation sequence, test cases, quality gates, activation/publication gates, transport readiness, deployment notes, rollback, and operations handover. Require a planning phase before implementation for every work package: each package starts with a presented plan of objects, tests, and validation steps, and no SAP state-changing package proceeds before the user approves it. Include a local quality gate in every implementation package: sources are authored locally as abapGit-style workspace files (`object.type.extension`) and must pass `LintABAP` plus LSP checks before they are sent to the SAP system. Automate every safe step exposed by the live MCP tools: inspect, analyze, delegate, validate, collect evidence, iterate on findings, and prepare release readiness. Keep all state-changing gates explicit and authorized.
|
|
25
|
+
6. **Automate and orchestrate the SDLC lifecycle.** Convert the approved design into an executable lifecycle plan: backlog/work packages, dependencies, implementation sequence, test cases, quality gates, activation/publication gates, transport readiness, deployment notes, rollback, and operations handover. Require a planning phase before implementation for every work package: each package starts with a presented plan of objects, tests, and validation steps, and no SAP state-changing package proceeds before the user approves it. Include a local quality gate in every implementation package: ABAP/RAP sources are authored locally as abapGit-style workspace files (`object.type.extension`) and must pass `LintABAP` plus LSP checks before they are sent to the SAP system; CAP/HANA work follows the HANA specialist's local build and user-run deployment handoff, including `cds build --for hana` when applicable. Automate every safe step exposed by the live MCP tools: inspect, analyze, delegate, validate, collect evidence, iterate on findings, and prepare release readiness. Keep all state-changing gates explicit and authorized.
|
|
26
26
|
7. **Plan delegation to implementation agents.** When implementation is requested, break the work into safe, ordered work packages. If the Copilot client supports subagents/delegation, hand off implementation packages to the specialized agents; otherwise provide ready-to-paste briefs for:
|
|
27
27
|
- **ABAP Developer** for ABAP classes, reports, interfaces, tests, quality checks, and transport preparation.
|
|
28
28
|
- **RAP Service Developer** for RAP BOs, CDS/projections, behavior, service definitions, bindings, and OData validation.
|
|
29
29
|
- **ABAP Runtime Debugger** for dumps, logs, traces, reproductions, performance symptoms, and runtime root cause analysis.
|
|
30
|
-
|
|
30
|
+
- **HANA Cloud/HDI Specialist** for bound-container inspection, CAP/HDI artifact design, local HANA builds, and a user-run deployment handoff. Its MCP server is read-only and must never receive HDI deployment credentials.
|
|
31
|
+
Each brief must include the target, scope, objects, acceptance criteria, state-changing permissions, required validations, and security constraints, and must mandate a planning step before implementation. ABAP/RAP briefs require local `LintABAP`/LSP checks before SAP transfer; HANA briefs use the HANA skills and never deploy through MCP.
|
|
31
32
|
8. **Report decision and SDLC evidence.** Finish with the chosen approach, recommended APIs/extension points, why SAP standard/released APIs were or were not sufficient, Clean Core and side-by-side compliance status, required implementation packages, actual MCP evidence gathered, validation gates passed/skipped, release readiness, and open questions/blockers. Report every check not run and why.
|
|
32
33
|
|
|
33
34
|
Use the focused skills under `.github/skills/`, especially `sap-standard-api-analysis`, `clean-core-extensibility`, and `sap-sdlc-orchestration`. Their task-specific guidance supplements this workflow.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hana-cloud-inspection
|
|
3
|
+
description: Inspect SAP HANA Cloud HDI containers and schemas using the read-only HANA MCP server. Use for connection verification, catalog inventory, table/view metadata, and bounded data investigation.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# HANA Cloud inspection
|
|
7
|
+
|
|
8
|
+
## Tool shortlist
|
|
9
|
+
|
|
10
|
+
Use the live MCP `tools/list` result as authoritative. Call only the exact schemas exposed by the HANA inspector:
|
|
11
|
+
|
|
12
|
+
- `hana_connection_info` verifies the configured endpoint, bound schema, current user, and TLS state without returning a password.
|
|
13
|
+
- `hana_list_objects` lists tables and views in the bound HDI schema.
|
|
14
|
+
- `hana_describe_object` returns columns for an object in that schema.
|
|
15
|
+
- `hana_read_rows` reads selected catalog-verified columns with parameterized filters and a hard 200-row limit.
|
|
16
|
+
|
|
17
|
+
For the ABAP destination server, `RunQuery` is ABAP SQL—not HANA SQL. Use destination-prefixed tools only when that separate server exposes them.
|
|
18
|
+
|
|
19
|
+
## Procedure
|
|
20
|
+
|
|
21
|
+
1. Confirm the user’s requested system/container and expected schema. Do not assume a binding name uniquely identifies a database.
|
|
22
|
+
2. Query live `tools/list`, use the returned tool names and schemas exactly, and invoke the chat-attached tools directly. Direct MCP invocation is mandatory. Do not launch `sap-ai-dev` or `sap-ai-hana` for MCP operations, handcraft JSON-RPC in a terminal, or fall back to a CLI when chat tools are missing; report a host/session binding issue.
|
|
23
|
+
3. Call `hana_connection_info` first. Compare endpoint, binding, schema, and current user against the request. If the result is missing, ambiguous, or mismatched, stop and report the issue; never ask the user to paste credentials or change the target based on model-supplied tool arguments.
|
|
24
|
+
4. Inventory only relevant objects using `hana_list_objects`. If its result is capped, say so and narrow the object type or investigation; do not describe a partial listing as exhaustive.
|
|
25
|
+
5. Call `hana_describe_object` before reading values. Select only required columns. Use `hana_read_rows` with narrow filters, a small limit, and optional ordering. Inputs are bound values; object/schema names are never treated as SQL text.
|
|
26
|
+
6. Report actual endpoint/schema evidence, object/column names, filters, returned row count, caps, and access errors. Minimize returned personal or sensitive data; summarize or aggregate only with tools/queries the live schema actually permits.
|
|
27
|
+
|
|
28
|
+
## Safety boundaries
|
|
29
|
+
|
|
30
|
+
- The configured target/schema is schema-bound server-side. Do not try to select another host, database, tenant, or schema.
|
|
31
|
+
- The server does not accept arbitrary SQL and offers no DDL, DML, procedure-call, deployment, undeploy, grant, or service-key tools. Do not invent such tools or use the ABAP `RunQuery` as a substitute.
|
|
32
|
+
- The row-read tool rejects credential-like columns (password, secret, token, API-key, private-key, and credential names), including when used as filters or sort keys.
|
|
33
|
+
- The process must receive a dedicated HANA read-only identity via `HANA_RO_*` or an unambiguous `VCAP_SERVICES` binding. Never use `hdi_user`/`hdi_password` as a fallback or expose binding contents.
|
|
34
|
+
- Tool annotations and agent instructions are not authorization controls. Database grants remain the write barrier.
|
|
35
|
+
- If no HANA MCP server is attached, limit work to local project inspection and clearly state that no live HANA inspection occurred.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hana-cloud-native-development
|
|
3
|
+
description: Develop SAP HANA Cloud CAP and HDI database components locally, including CDS models, HANA build outputs, synonyms, and grants. Use when creating or changing HANA-native project artifacts.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# HANA Cloud native development
|
|
7
|
+
|
|
8
|
+
## Tool shortlist
|
|
9
|
+
|
|
10
|
+
Inspect the active workspace and its CAP/HDI tooling first. Query `tools/list` for live MCP availability and use exact destination-prefixed names for any SAP VSP tools. Use the CDS/CAP MCP model and documentation tools when available; otherwise inspect the project's local `.cds`, package, MTA, and HDI files and mark missing context. Direct MCP invocation is mandatory. Do not launch `sap-ai-dev` or `sap-ai-hana` for MCP operations, handcraft JSON-RPC in a terminal, or use a CLI fallback when chat tools are unavailable; report a host/session binding issue.
|
|
11
|
+
|
|
12
|
+
## Procedure
|
|
13
|
+
|
|
14
|
+
1. Identify the application root under `/home/user/projects` and establish whether it is a CAP application, an HDI-only module, or an existing MTA project. Read its scripts, `cds` configuration, `db/`, `srv/`, `.hdiconfig`, `.hdinamespace`, synonyms, grants, MTA descriptor, and established naming conventions before proposing edits.
|
|
15
|
+
2. For CAP-owned database models, prefer CDS in `db/` as the source of truth and add or modify `srv/` only when the requested application behavior needs a CAP service. Consult available CDS MCP docs/model tools before CAP model/API changes. Do not duplicate generated `.hdbtable`/`.hdbview` definitions as hand-authored HDI files.
|
|
16
|
+
3. For HDI-native objects not represented by the existing CAP model, add only the required design-time artifacts and follow existing HDI namespace/build conventions. Treat `.hdbsynonym`, `.hdbgrants`, external-object access, and user/role changes as security-sensitive; require the minimal named object and privilege set and present them for review. Never generate broad schema grants or a deployer credential into source/config.
|
|
17
|
+
4. If MTA packaging or deployment metadata is required, extend the existing project structure and module/service references instead of creating a second deployment topology. Do not scaffold sample entities, CSV data, or unrelated CAP services unless explicitly requested.
|
|
18
|
+
5. Before file changes, present a concise local plan containing the exact paths and design choice. Keep edits within the confirmed application root. Generate only requested or technically required components; do not write business application artifacts into this toolkit's repository.
|
|
19
|
+
6. Validate source locally with the project’s available CAP/CDS tooling. `cds build --for hana` can generate the deployable HDI artifacts from a CAP model; inspect existing scripts and target CAP version before using it. Review generated `gen/db` output and do not mistake a generated artifact for the maintained source model.
|
|
20
|
+
7. Report changed model/source files, generated artifacts, dependencies, local checks, and any deployment/permission effects. HANA deployment is not part of this skill; hand it to `hana-cloud-validation` for review and user-run deployment instructions.
|
|
21
|
+
|
|
22
|
+
## Constraints
|
|
23
|
+
|
|
24
|
+
- Never execute `cds deploy` against HANA, `cf deploy`, HDI deployment, HANA DDL/DML SQL, undeploy, grant changes, or user/service-key administration.
|
|
25
|
+
- Do not store host passwords, `VCAP_SERVICES`, service keys, or HDI deployment credentials in project source, MCP configuration, generated artifacts, or logs.
|
|
26
|
+
- Do not claim that compilation or generated artifacts prove a live database deployment succeeded.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hana-cloud-validation
|
|
3
|
+
description: Validate HANA Cloud CAP and HDI changes locally, inspect deployment plans and diffs, and prepare a safe user-run deployment handoff. Use before deploying database artifacts or assessing a HANA change.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# HANA Cloud validation and deployment handoff
|
|
7
|
+
|
|
8
|
+
## Tool shortlist
|
|
9
|
+
|
|
10
|
+
Use live `tools/list` for HANA and SAP tool availability. HANA inspection is limited to `hana_connection_info`, `hana_list_objects`, `hana_describe_object`, and bounded `hana_read_rows`; SAP VSP tools use their live destination-prefixed names. Use CAP/CDS documentation and model tools where available. Do not use ABAP `RunQuery`, ABAP Unit, or `LintABAP` as HANA validation. Direct MCP invocation is mandatory. Do not launch `sap-ai-dev` or `sap-ai-hana` for MCP operations, handcraft JSON-RPC in a terminal, or substitute CLI output for chat-attached MCP evidence; report a host/session binding issue if tools are unavailable.
|
|
11
|
+
|
|
12
|
+
## Procedure
|
|
13
|
+
|
|
14
|
+
1. **Reconfirm scope and target.** Identify the CAP/HDI project root, HANA endpoint, service/binding, HDI container/schema, intended environment, and deployment identity. Use `hana_connection_info` only if its live tool is attached. Never ask for or print credentials; if no bound target is available, stop live inspection and report that.
|
|
15
|
+
2. **Review the exact source and build diff.** Inspect tracked/untracked files, CAP model changes, `gen/db` outputs, MTA/service wiring, grants, synonyms, migrations, and undeploy implications. Call out drops, field narrowing/type changes, external-object privileges, and generated artifacts that imply data loss or authorization changes.
|
|
16
|
+
3. **Run local-only validation.** Inspect the project scripts and CAP version, then run the supported compile/build/tests. For a CAP HANA project, `cds build --for hana` builds deployable HDI artifacts locally; it does not prove deployment or runtime behavior. Ensure test configuration cannot redirect validation to the live HANA instance. Never run a production HANA deployment as a test.
|
|
17
|
+
4. **Inspect the target read-only.** If connected, use the bounded catalog tools to confirm only the relevant object names and columns, then use a minimal `hana_read_rows` call when data evidence is necessary. Never pass free-form SQL, exceed the tool’s 200-row cap, select a different schema, or attempt a write to “check” permissions.
|
|
18
|
+
5. **Prepare the user-run deployment plan.** Present exact project-root command(s) already defined by the project, target/environment, source/build diff, HDI deployer identity required by the pipeline, ordering/dependencies, expected generated objects, data migration or removal risks, rollback strategy, and post-deployment read-only checks. Ask the user to review/approve before proceeding with any deployment-related action; the MCP server has no deploy path and this agent does not execute deployment.
|
|
19
|
+
6. **Report evidence and gaps.** Separate local compile/test/build results, live read-only inspection, and user-run deployment evidence. State skipped tests, absent credentials/tools, target uncertainty, truncation, and remaining risks. Never claim HANA activation/deployment or runtime validation unless the user has supplied evidence that it occurred.
|
|
20
|
+
|
|
21
|
+
## Safety boundaries
|
|
22
|
+
|
|
23
|
+
- HANA tools are metadata and bounded read-only inspection only. There is no arbitrary SQL, write, deployment, undeploy, migration execution, grant, or credential-management tool.
|
|
24
|
+
- `HANA_RO_*`/VCAP credentials must represent a dedicated read-only identity. The user’s deployment identity stays out of the MCP host environment.
|
|
25
|
+
- A chat confirmation, `readOnlyHint`, successful build, or prompt instruction is not an authorization gate for database changes.
|
|
26
|
+
- Deployment, destructive schema changes, grants, and removals remain explicit user-run operations with independent review and authorization.
|
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ Then connect a destination in SAP Business Application Studio:
|
|
|
62
62
|
1. Open the Command Palette.
|
|
63
63
|
2. Run **MCP: List Servers**.
|
|
64
64
|
3. Start the server named after your selected BAS destination.
|
|
65
|
-
4. In GitHub Copilot Chat, choose the best-fit bundled agent from the agent picker: **SAP Solution Architect**, **ABAP Developer**, **ABAP Runtime Debugger**,
|
|
65
|
+
4. In GitHub Copilot Chat, choose the best-fit bundled agent from the agent picker: **SAP Solution Architect**, **ABAP Developer**, **ABAP Runtime Debugger**, **RAP Service Developer**, or **HANA Cloud/HDI Specialist**.
|
|
66
66
|
5. In the Chat tools picker, enable the server for that BAS destination.
|
|
67
67
|
6. Ask Copilot to inspect, build, test, or verify something in your SAP landscape.
|
|
68
68
|
|
|
@@ -72,7 +72,7 @@ Use the attached destination-prefixed tools directly in chat. Do not launch `sap
|
|
|
72
72
|
|
|
73
73
|
## 🤖 Available agents and skills
|
|
74
74
|
|
|
75
|
-
**Agents:**
|
|
75
|
+
**Agents:** Five user-invocable custom agents are included. Select the best fit from the agent picker in GitHub Copilot Chat, as shown in Quick start.
|
|
76
76
|
|
|
77
77
|
| | Agent | Best for |
|
|
78
78
|
| --- | --- | --- |
|
|
@@ -80,8 +80,9 @@ Use the attached destination-prefixed tools directly in chat. Do not launch `sap
|
|
|
80
80
|
| 🧑💻 | **ABAP Developer** | General ABAP, CDS, and RAP implementation, validation, and transport-preparation tasks |
|
|
81
81
|
| 🐞 | **ABAP Runtime Debugger** | Runtime incidents, dumps, logs, traces, debugger sessions, call graphs, and performance symptoms |
|
|
82
82
|
| 🚀 | **RAP Service Developer** | RAP business objects, behavior implementations, projections, service definitions, service bindings, and OData validation |
|
|
83
|
+
| 🗃️ | **HANA Cloud/HDI Specialist** | Read-only HANA Cloud container inspection, CAP/HDI artifact generation, local validation, and user-run deployment handoffs |
|
|
83
84
|
|
|
84
|
-
**Included skills:** `abap-development` · `abap-testing-quality` · `cds-development` · `rap-development` · `abap-debugging` · `abap-runtime-analysis` · `rap-service-delivery` · `sap-standard-api-analysis` · `clean-core-extensibility` · `sap-sdlc-orchestration` · `sap-transport-release`
|
|
85
|
+
**Included skills:** `abap-development` · `abap-testing-quality` · `cds-development` · `rap-development` · `abap-debugging` · `abap-runtime-analysis` · `rap-service-delivery` · `sap-standard-api-analysis` · `clean-core-extensibility` · `sap-sdlc-orchestration` · `sap-transport-release` · `hana-cloud-inspection` · `hana-cloud-native-development` · `hana-cloud-validation`
|
|
85
86
|
|
|
86
87
|
If the agents are not listed, install the optional agents and skills under `$HOME/.copilot` when prompted during an interactive global install, then reload BAS if needed. Repository-scoped installation instructions appear below.
|
|
87
88
|
|
|
@@ -102,7 +103,8 @@ The workflow covers ABAP, CDS, RAP, repository analysis, table and query access,
|
|
|
102
103
|
| 🔎 | **Understand before editing** | Trace source, callers, definitions, package contents, dependencies, and CDS impact in one workflow. |
|
|
103
104
|
| 🧩 | **CDS + RAP development** | Explore models and dependencies, then build RAP business objects and services with system context. |
|
|
104
105
|
| 🗃️ | **Ground decisions in SAP data** | Inspect DDIC structures, read table contents, and run controlled ABAP SQL queries. |
|
|
105
|
-
|
|
|
106
|
+
| ☁️ | **Read-only HANA Cloud inspection** | Inspect an environment-bound HDI schema, object metadata, and capped query results without exposing deployment credentials. |
|
|
107
|
+
| ✍️ | **Edit ABAP safely** | Update supported source, stage reviewed change sets, create transport requests, and run syntax checks before requested activation. |
|
|
106
108
|
| ✅ | **Quality built into the flow** | Pair local ABAP linting with SAP syntax checks, ABAP Unit, ATC, editor diagnostics, and formatting. |
|
|
107
109
|
| 🐞 | **Debug with system context** | Investigate dumps, traces, application logs, runtime failures, capabilities, and installed components. |
|
|
108
110
|
| 🚚 | **Transport-aware workflows** | Check request and lock context before preparing a change; create transports only when authorized. |
|
|
@@ -152,9 +154,9 @@ The catalog below covers source inspection, data, editing, quality, transports,
|
|
|
152
154
|
- Read SLG1 application logs
|
|
153
155
|
- Review and create transport requests
|
|
154
156
|
|
|
155
|
-
## 🧠
|
|
157
|
+
## 🧠 Five agents, fourteen focused skills
|
|
156
158
|
|
|
157
|
-
The package ships with
|
|
159
|
+
The package ships with five custom agents plus fourteen task-focused Copilot Agent Skills:
|
|
158
160
|
|
|
159
161
|
| | Skill | Best for |
|
|
160
162
|
| --- | --- | --- |
|
|
@@ -169,6 +171,9 @@ The package ships with four custom agents plus eleven task-focused Copilot Agent
|
|
|
169
171
|
| 🔬 | `abap-runtime-analysis` | Incident triage, traces, debugger state, call graphs, and performance analysis |
|
|
170
172
|
| 🚀 | `rap-service-delivery` | RAP service activation, publication, OData validation, and end-to-end runtime checks |
|
|
171
173
|
| 🚚 | `sap-transport-release` | Dependency checks and transport preparation; release itself is intentionally unavailable here |
|
|
174
|
+
| 🔎 | `hana-cloud-inspection` | Verify the selected HANA Cloud binding and inspect bounded HDI catalog/data results |
|
|
175
|
+
| 🧱 | `hana-cloud-native-development` | Generate CAP-owned CDS models or required native HDI artifacts without duplicating generated sources |
|
|
176
|
+
| ✅ | `hana-cloud-validation` | Run local CAP/HANA builds and prepare a reviewed, user-run deployment handoff |
|
|
172
177
|
|
|
173
178
|
## 🗺️ How it fits together
|
|
174
179
|
|
|
@@ -176,13 +181,13 @@ Each selected BAS destination becomes its own isolated MCP server identity. The
|
|
|
176
181
|
|
|
177
182
|
## 🧰 Optional full-stack companion MCP servers
|
|
178
183
|
|
|
179
|
-
ABAP/RAP backend access is provided by this add-on's BAS/VSP proxy. For end-to-end SAP development, setup can also add managed companion MCP entries for frontend, CAP,
|
|
184
|
+
ABAP/RAP backend access is provided by this add-on's BAS/VSP proxy. For end-to-end SAP development, setup can also add managed companion MCP entries for frontend, CAP, browser validation, and read-only HANA inspection:
|
|
180
185
|
|
|
181
186
|
```sh
|
|
182
187
|
sap-ai-dev --setup --tools
|
|
183
188
|
```
|
|
184
189
|
|
|
185
|
-
The companion entries are optional and are launched through `npx` only when the MCP client starts them. They are marked as managed by `sap-ai-dev-toolkit`, so rerunning setup can update or remove them without touching unrelated MCP servers.
|
|
190
|
+
The companion entries are optional and are launched through `npx` only when the MCP client starts them. They are marked as managed by `sap-ai-dev-toolkit`, so rerunning setup can update or remove them without touching unrelated MCP servers. The HANA companion uses `--ignore-scripts` so the toolkit postinstall wizard cannot run during MCP startup.
|
|
186
191
|
|
|
187
192
|
| MCP entry | Package | Launches | Use when the agent needs to |
|
|
188
193
|
| --- | --- | --- | --- |
|
|
@@ -190,13 +195,26 @@ The companion entries are optional and are launched through `npx` only when the
|
|
|
190
195
|
| `ui5-tools` | `@ui5/mcp-server` | `ui5mcp` | Inspect SAPUI5/OpenUI5 projects, manifests, routing, views, controllers, and UI5-specific issues |
|
|
191
196
|
| `cap-tools` | `@cap-js/mcp-server` | `cds-mcp` | Inspect CAP CDS models, services, entities, actions, and local CAP application structure |
|
|
192
197
|
| `browser-validation` | `@playwright/mcp` | `playwright-mcp` | Open BAS previews, smoke-test Fiori/UI flows, collect screenshots, and verify browser runtime behavior |
|
|
198
|
+
| `hana-cloud-inspector` | `sap-ai-dev-toolkit` | `sap-ai-hana` | Inspect a bound HANA Cloud HDI schema using read-only catalog tools and capped row reads |
|
|
193
199
|
|
|
194
200
|
Recommended profiles:
|
|
195
201
|
|
|
196
202
|
- **RAP + Fiori:** select your BAS destination plus `sap-fiori-tools`, `ui5-tools`, and `browser-validation`.
|
|
197
203
|
- **CAP on BTP:** select `cap-tools`, `sap-fiori-tools`, `ui5-tools`, and `browser-validation`.
|
|
204
|
+
- **CAP + HANA Cloud:** select `cap-tools` and `hana-cloud-inspector`; provide the inspector's read-only connection through MCP-host environment variables.
|
|
198
205
|
- **UI-only:** select `sap-fiori-tools`, `ui5-tools`, and optionally `browser-validation`.
|
|
199
206
|
|
|
207
|
+
### HANA Cloud/HDI inspector
|
|
208
|
+
|
|
209
|
+
Select `hana-cloud-inspector` in the optional companion-server setup, then start it from **MCP: List Servers**. The process reads its connection from the MCP host's environment; setup never copies HANA credentials into `mcp.json`. Make sure variables are available to the BAS/VS Code MCP host process (not only to a later terminal session), then reload/restart the MCP host if needed.
|
|
210
|
+
|
|
211
|
+
Use either:
|
|
212
|
+
|
|
213
|
+
- A dedicated read-only VCAP binding with `credentials.host`, `port`, `user`, `password`, and `schema` in `VCAP_SERVICES`; optionally set `HANA_RO_VCAP_SERVICE` to the exact VCAP service key and `HANA_RO_BINDING` to the binding/instance name when selection is ambiguous.
|
|
214
|
+
- Explicit `HANA_RO_HOST`, `HANA_RO_PORT`, `HANA_RO_USER`, `HANA_RO_PASSWORD`, and `HANA_RO_SCHEMA` variables. `HANA_RO_TRUST_STORE` is optional; TLS and certificate verification are always enabled.
|
|
215
|
+
|
|
216
|
+
The configured identity must be a separate least-privileged read-only HANA user. The server rejects bindings that offer only HDI deployment credentials and never falls back to `hdi_user`/`hdi_password`. Its tools are limited to connection identity, object listing/descriptions, and parameterized row reads capped at 200 rows; credential-like columns are blocked, and there is no arbitrary SQL, DDL/DML, grant, deployment, or undeploy tool. Use the existing project deployment workflow yourself after reviewing the exact generated artifact diff and target. The SAP HANA Node.js driver is provided under the SAP Developer License Agreement.
|
|
217
|
+
|
|
200
218
|
## 💡 Example requests
|
|
201
219
|
|
|
202
220
|
Once the destination server is enabled in Copilot Chat, ask for outcomes instead of manually orchestrating individual SAP operations:
|
|
@@ -209,6 +227,8 @@ Once the destination server is enabled in Copilot Chat, ask for outcomes instead
|
|
|
209
227
|
|
|
210
228
|
> Read company codes from `T001` for this destination and return `BUKRS`, `BUTXT`, `WAERS`, and `LAND1`.
|
|
211
229
|
|
|
230
|
+
> Inspect the HANA HDI container attached to this workspace, describe the relevant tables, and show at most 20 rows for the columns needed to explain the issue. Do not change database state.
|
|
231
|
+
|
|
212
232
|
> Check the current object's transport context, prepare the change for transport, but do not release anything.
|
|
213
233
|
|
|
214
234
|
## 🔐 Enterprise-friendly safety model
|
|
@@ -219,7 +239,7 @@ Once the destination server is enabled in Copilot Chat, ask for outcomes instead
|
|
|
219
239
|
| 🚦 **Explicit state change** | Activation, service publication, and transport creation happen only when requested and authorized. |
|
|
220
240
|
| 🧪 **Verification first** | The agent uses available lint, syntax, unit-test, ATC, and diagnostics workflows and reports what actually ran. |
|
|
221
241
|
| 🔒 **SAP authorization remains authoritative** | The add-on does not bypass backend SAP permissions. |
|
|
222
|
-
| 🚚 **
|
|
242
|
+
| 🚚 **Curated VSP tool surface** | The proxy exposes a cherry-picked developer-lifecycle set from VSP plus local workflow tools, keeping one destination below 60 tools; SAP authorizations and VSP safety checks still apply. |
|
|
223
243
|
| 🧱 **Per-destination isolation** | Generated MCP entries are scoped to a single `SAP_AI_DEV_TOOLKIT_DESTINATION`. |
|
|
224
244
|
| 🔑 **No credentials in `mcp.json`** | Authentication material stays in BAS destination configuration rather than MCP config. |
|
|
225
245
|
|
|
@@ -294,7 +314,7 @@ At the end of a global install, the color-coded summary shows the MCP config pat
|
|
|
294
314
|
|
|
295
315
|
## 🤖 GitHub Copilot ABAP agents and skills
|
|
296
316
|
|
|
297
|
-
The package includes
|
|
317
|
+
The package includes five user-invocable custom agents (**SAP Solution Architect**, **ABAP Developer**, **ABAP Runtime Debugger**, **RAP Service Developer**, and **HANA Cloud/HDI Specialist**) and fourteen task-focused Agent Skills for GitHub Copilot in BAS.
|
|
298
318
|
|
|
299
319
|
### 🧠 How the SAP Solution Architect and ABAP Developer agents work
|
|
300
320
|
|
|
@@ -322,10 +342,13 @@ The package includes four user-invocable custom agents (**SAP Solution Architect
|
|
|
322
342
|
| 🔬 | `abap-runtime-analysis` | Analyze incidents, traces, debugger state, call graphs, and performance symptoms. |
|
|
323
343
|
| 🚀 | `rap-service-delivery` | Validate RAP service bindings, activation, publication, and end-to-end OData behavior. |
|
|
324
344
|
| 🚚 | `sap-transport-release` | Check dependencies and prepare changes for transport; release is not available here. |
|
|
345
|
+
| 🔎 | `hana-cloud-inspection` | Verify the attached HANA target and inspect bounded HDI metadata and rows. |
|
|
346
|
+
| 🧱 | `hana-cloud-native-development` | Create CAP CDS or required native HDI source artifacts while avoiding duplicate models. |
|
|
347
|
+
| ✅ | `hana-cloud-validation` | Build locally, review deployment risks, and hand off deployment to the user. |
|
|
325
348
|
|
|
326
349
|
### 📥 Install for your BAS user
|
|
327
350
|
|
|
328
|
-
After destination setup, the installer prints a 🤖 notice that it is waiting for confirmation, then offers to install
|
|
351
|
+
After destination setup, the installer prints a 🤖 notice that it is waiting for confirmation, then offers to install all bundled agents and skills under `$HOME/.copilot`. Press **Enter** to install; type **n** then **Enter** to skip. Declining leaves those files unchanged.
|
|
329
352
|
|
|
330
353
|
These user-level customizations are available across workspaces opened by the same BAS user in the same dev space. Copilot must be available in BAS and may need a window reload to discover new files. A non-interactive install skips the optional prompt; `npm install --ignore-scripts` skips the postinstall wizard entirely.
|
|
331
354
|
|
|
@@ -457,7 +480,7 @@ The file must be strict JSON with an object-valued `servers` property. Existing
|
|
|
457
480
|
|
|
458
481
|
With `H2O_URL` set, the normal command starts the MCP proxy. Each generated entry supplies one `SAP_AI_DEV_TOOLKIT_DESTINATION`, so each server stays in its own lane and exposes only its selected SAP system.
|
|
459
482
|
|
|
460
|
-
The proxy exposes
|
|
483
|
+
The proxy exposes a curated subset of VSP tools, plus local `LintABAP`, destination-scoped workflow tools, and the convenience `GetApplicationLog` mapping when the VSP SAP router is available. Hidden VSP tools remain available only behind local workflow chaining where required; they are not advertised or directly callable through the proxy. Direct VSP invocation remains unchanged.
|
|
461
484
|
|
|
462
485
|
Without `H2O_URL`, the command passes arguments directly to the installed VSP binary—no BAS proxy detour.
|
|
463
486
|
|
|
@@ -588,8 +611,8 @@ The write, create, and activation tools change SAP state. Confirm the target, pa
|
|
|
588
611
|
| `GetTransport` | Read a transport request's details, objects, and tasks. |
|
|
589
612
|
| `GetTransportInfo` | Find eligible transports and lock status for an ABAP object or package. |
|
|
590
613
|
| `CreateTransport` | Create a transport request. |
|
|
591
|
-
| `ReleaseTransport` |
|
|
592
|
-
| `DeleteTransport` |
|
|
614
|
+
| `ReleaseTransport` | Not exposed by the curated proxy surface; release transports outside this add-on after review. |
|
|
615
|
+
| `DeleteTransport` | Not exposed by the curated proxy surface; delete transports outside this add-on after review. |
|
|
593
616
|
|
|
594
617
|
The proxy starts VSP with `--enable-transports` and omits `--transport-read-only`. Generated MCP entries set `SAP_ALLOW_TRANSPORTABLE_EDITS=true` so source edits in transportable packages are permitted. VSP safety checks and SAP authorizations still apply.
|
|
595
618
|
|
|
@@ -602,9 +625,9 @@ The proxy starts VSP with `--enable-transports` and omits `--transport-read-only
|
|
|
602
625
|
- Filter by program, user, object, subobject, from, and to.
|
|
603
626
|
- `max_results` defaults to 100. Date-only `to` values include the full day.
|
|
604
627
|
- `messages: true` adds BALDAT details and T100 message text; otherwise, the tool returns log headers only.
|
|
605
|
-
- The proxy maps this convenience tool to the single `SAP(action="analyze", type="application_log")` operation. The general-purpose `SAP` router is
|
|
628
|
+
- The proxy maps this convenience tool to the single upstream `SAP(action="analyze", type="application_log")` operation. The general-purpose `SAP` router itself is hidden from direct calls.
|
|
606
629
|
|
|
607
|
-
The proxy
|
|
630
|
+
The proxy intentionally does not expose the full child VSP process. Object deletion, debugger, trace, general-purpose SAP router, and transport release/delete tools are hidden from direct MCP calls. Direct VSP invocation without `H2O_URL` retains the VSP binary's own tool surface.
|
|
608
631
|
|
|
609
632
|
### 🚀 Ready to put the tools to work from chat?
|
|
610
633
|
|
|
@@ -700,7 +723,7 @@ The response contains a `tools` array. A `RunQuery` entry resembles this excerpt
|
|
|
700
723
|
| --- | --- |
|
|
701
724
|
| `H2O_URL` | BAS endpoint used to discover destinations. Required for BAS discovery. |
|
|
702
725
|
| `SAP_AI_DEV_TOOLKIT_DESTINATION` | Comma-separated destination allowlist for normal runtime discovery. Setup clears this temporarily so it can display all eligible systems. |
|
|
703
|
-
| `SAP_AI_DEV_TOOLKIT_MODE` | VSP child mode (`expert` by default; `focused` omits `ActivateMultiple`, `GetUserTransports`, and `GetTransportInfo`). The proxy exposes its curated
|
|
726
|
+
| `SAP_AI_DEV_TOOLKIT_MODE` | VSP child mode (`expert` by default; `focused` omits `ActivateMultiple`, `GetUserTransports`, and `GetTransportInfo`). The proxy exposes its curated tool subset and local workflow tools, including `LintABAP`. |
|
|
704
727
|
| `SAP_ALLOW_TRANSPORTABLE_EDITS` | Generated MCP entries set this to `true` to permit source edits in transportable packages; VSP safety checks and SAP authorizations still apply. |
|
|
705
728
|
| `SAP_AI_DEV_TOOLKIT_DISABLE_BAS_RELAY=true` | Disable the built-in BAS destination relay. By default the add-on self-heals `.dest` destinations through a local relay that keeps all access destination-based while handling ADT CSRF fetch/retry behavior before VSP calls SAP. |
|
|
706
729
|
| `SAP_AI_DEV_TOOLKIT_HTTP_PROXY` | Egress proxy for relay and discovery traffic (falls back to `HTTP_PROXY`/`http_proxy`; unset means the default BAS proxy for `.dest` hosts, empty means direct except for OnPremise credential overrides, which require a BAS proxy tunnel). |
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sap-ai-dev-toolkit",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"description": "SAP AI development toolkit for BAS, ABAP, RAP, CAP, Fiori, UI5, and MCP",
|
|
3
|
+
"version": "0.3.7",
|
|
4
|
+
"description": "SAP AI development toolkit for BAS, ABAP, RAP, CAP, HANA Cloud, Fiori, UI5, and MCP",
|
|
5
5
|
"author": "Gurkan Yilmaz",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
@@ -9,16 +9,21 @@
|
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@abaplint/core": "2.119.0",
|
|
12
|
+
"@modelcontextprotocol/sdk": "1.30.1",
|
|
13
|
+
"@sap/hana-client": "2.30.27",
|
|
12
14
|
"terminal-kit": "^3.1.4",
|
|
13
|
-
"undici": "^6.21.3"
|
|
15
|
+
"undici": "^6.21.3",
|
|
16
|
+
"zod": "4.6.5"
|
|
14
17
|
},
|
|
15
18
|
"bin": {
|
|
16
|
-
"sap-ai-dev": "src/launcher.mjs"
|
|
19
|
+
"sap-ai-dev": "src/launcher.mjs",
|
|
20
|
+
"sap-ai-hana": "src/hana-inspector.mjs"
|
|
17
21
|
},
|
|
18
22
|
"scripts": {
|
|
19
23
|
"postinstall": "node scripts/postinstall.mjs",
|
|
20
24
|
"install:local": "node scripts/install-local.mjs",
|
|
21
25
|
"test": "node --test test/*.test.mjs",
|
|
26
|
+
"test:live:s4h": "SAP_AI_DEV_LIVE_S4H=1 node --test test/live-s4h.test.mjs",
|
|
22
27
|
"test:visibility": "node --test test/setup.test.mjs test/terminal-ui.test.mjs",
|
|
23
28
|
"test:mutation": "node scripts/mutation-terminal-ui.mjs",
|
|
24
29
|
"publish:npm": "node scripts/publish-npm.mjs",
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -76,9 +76,9 @@ async function runCopilotAssetInstall() {
|
|
|
76
76
|
await announce([
|
|
77
77
|
'Optional Copilot setup is waiting for your choice.',
|
|
78
78
|
'',
|
|
79
|
-
'Press Enter to install the bundled agents and
|
|
79
|
+
'Press Enter to install the bundled agents and all skills in the path shown below; type n then press Enter to skip.',
|
|
80
80
|
'',
|
|
81
|
-
`${colorText('✅ Press Enter', 'green', true)} to install the bundled agents and
|
|
81
|
+
`${colorText('✅ Press Enter', 'green', true)} to install the bundled agents and all skills.`,
|
|
82
82
|
`${colorText('⏭️ Type n then Enter', 'yellow', true)} to skip this optional step.`,
|
|
83
83
|
'',
|
|
84
84
|
`${colorText('📁 Target folder:', 'cyan', true)}`,
|
|
@@ -88,7 +88,7 @@ async function runCopilotAssetInstall() {
|
|
|
88
88
|
const prompt = createInterface({ input: terminal.input, output: terminal.output });
|
|
89
89
|
let answer;
|
|
90
90
|
try {
|
|
91
|
-
answer = await prompt.question(`${colorText('🤖 Install the bundled agents and
|
|
91
|
+
answer = await prompt.question(`${colorText('🤖 Install the bundled agents and all skills?', 'magenta', terminal.output)} ${colorText('[Y/n]', 'yellow', terminal.output)} `);
|
|
92
92
|
} finally {
|
|
93
93
|
prompt.close();
|
|
94
94
|
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
const EXPLICIT_CONNECTION_KEYS = [
|
|
2
|
+
'HANA_RO_HOST',
|
|
3
|
+
'HANA_RO_PORT',
|
|
4
|
+
'HANA_RO_USER',
|
|
5
|
+
'HANA_RO_PASSWORD',
|
|
6
|
+
'HANA_RO_SCHEMA'
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
const DEFAULT_SERVICE_TYPES = new Set(['hana', 'hana-cloud', 'hana-cloud-db', 'hanacloud', 'sap-hana-cloud']);
|
|
10
|
+
|
|
11
|
+
function fail(message) {
|
|
12
|
+
throw new Error(message);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function normalizeServiceType(value) {
|
|
16
|
+
return String(value || '').trim().toLowerCase().replaceAll('_', '-');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function requiredText(value, label) {
|
|
20
|
+
if (typeof value !== 'string' || !value.trim()) fail(`HANA read-only connection is missing ${label}.`);
|
|
21
|
+
return value.trim();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function validateHost(value) {
|
|
25
|
+
const host = requiredText(value, 'host');
|
|
26
|
+
if (/[\s/@?#\\]/.test(host) || host.includes('://') || host.includes(':')) {
|
|
27
|
+
fail('HANA_RO_HOST must contain only a hostname; provide the port separately.');
|
|
28
|
+
}
|
|
29
|
+
return host;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function validatePort(value) {
|
|
33
|
+
const portText = requiredText(String(value ?? ''), 'port');
|
|
34
|
+
if (!/^\d{1,5}$/.test(portText)) fail('HANA_RO_PORT must be an integer between 1 and 65535.');
|
|
35
|
+
const port = Number(portText);
|
|
36
|
+
if (port < 1 || port > 65535) fail('HANA_RO_PORT must be an integer between 1 and 65535.');
|
|
37
|
+
return port;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function validateSchema(value) {
|
|
41
|
+
const schema = requiredText(value, 'schema');
|
|
42
|
+
if (schema.length > 127 || /[\u0000-\u001f\u007f]/.test(schema)) {
|
|
43
|
+
fail('The configured HANA schema name is invalid.');
|
|
44
|
+
}
|
|
45
|
+
return schema;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function hasExplicitConnection(env) {
|
|
49
|
+
return EXPLICIT_CONNECTION_KEYS.some(key => env[key] !== undefined && env[key] !== '');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function explicitConfig(env) {
|
|
53
|
+
const host = validateHost(env.HANA_RO_HOST);
|
|
54
|
+
const port = validatePort(env.HANA_RO_PORT);
|
|
55
|
+
const user = requiredText(env.HANA_RO_USER, 'read-only user');
|
|
56
|
+
const password = requiredText(env.HANA_RO_PASSWORD, 'read-only password');
|
|
57
|
+
const schema = validateSchema(env.HANA_RO_SCHEMA);
|
|
58
|
+
return {
|
|
59
|
+
source: 'environment',
|
|
60
|
+
bindingName: undefined,
|
|
61
|
+
serviceName: undefined,
|
|
62
|
+
host,
|
|
63
|
+
port,
|
|
64
|
+
user,
|
|
65
|
+
password,
|
|
66
|
+
schema,
|
|
67
|
+
trustStore: optionalTrustStore(env.HANA_RO_TRUST_STORE)
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function optionalTrustStore(value) {
|
|
72
|
+
if (value === undefined || value === '') return undefined;
|
|
73
|
+
const trustStore = requiredText(value, 'TLS trust-store path');
|
|
74
|
+
if (/[\u0000-\u001f\u007f]/.test(trustStore)) fail('The configured HANA TLS trust-store path is invalid.');
|
|
75
|
+
return trustStore;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function parseVcapServices(raw) {
|
|
79
|
+
if (!raw) fail('Set HANA_RO_* read-only credentials or bind a selected HANA service in VCAP_SERVICES.');
|
|
80
|
+
let services;
|
|
81
|
+
try {
|
|
82
|
+
services = typeof raw === 'string' ? JSON.parse(raw) : raw;
|
|
83
|
+
} catch {
|
|
84
|
+
fail('VCAP_SERVICES is not valid JSON.');
|
|
85
|
+
}
|
|
86
|
+
if (!services || typeof services !== 'object' || Array.isArray(services)) {
|
|
87
|
+
fail('VCAP_SERVICES must contain a JSON object.');
|
|
88
|
+
}
|
|
89
|
+
return services;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function vcapCandidates(env) {
|
|
93
|
+
const services = parseVcapServices(env.VCAP_SERVICES);
|
|
94
|
+
const selectedType = env.HANA_RO_VCAP_SERVICE?.trim();
|
|
95
|
+
const bindingName = env.HANA_RO_BINDING?.trim();
|
|
96
|
+
const entries = Object.entries(services).filter(([serviceType]) => {
|
|
97
|
+
return selectedType
|
|
98
|
+
? serviceType === selectedType
|
|
99
|
+
: DEFAULT_SERVICE_TYPES.has(normalizeServiceType(serviceType));
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
if (selectedType && !entries.length) fail('The selected HANA VCAP service type was not found.');
|
|
103
|
+
|
|
104
|
+
let candidates = entries.flatMap(([serviceName, instances]) => {
|
|
105
|
+
if (!Array.isArray(instances)) return [];
|
|
106
|
+
return instances
|
|
107
|
+
.filter(instance => instance && typeof instance === 'object' && !Array.isArray(instance))
|
|
108
|
+
.map(instance => ({ serviceName, instance }));
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
if (bindingName) {
|
|
112
|
+
candidates = candidates.filter(({ instance }) => {
|
|
113
|
+
return instance.name === bindingName || instance.binding_name === bindingName;
|
|
114
|
+
});
|
|
115
|
+
if (!candidates.length) fail('The selected HANA binding was not found in VCAP_SERVICES.');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (candidates.length !== 1) {
|
|
119
|
+
fail(candidates.length === 0
|
|
120
|
+
? 'No HANA VCAP binding was found; set HANA_RO_VCAP_SERVICE or explicit HANA_RO_* credentials.'
|
|
121
|
+
: 'Multiple HANA VCAP bindings were found; set HANA_RO_BINDING to select exactly one.');
|
|
122
|
+
}
|
|
123
|
+
return candidates[0];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function vcapConfig(env) {
|
|
127
|
+
const { serviceName, instance } = vcapCandidates(env);
|
|
128
|
+
const credentials = instance.credentials;
|
|
129
|
+
if (!credentials || typeof credentials !== 'object' || Array.isArray(credentials)) {
|
|
130
|
+
fail('The selected HANA binding has no usable credentials object.');
|
|
131
|
+
}
|
|
132
|
+
if ((!credentials.user || !credentials.password) && (credentials.hdi_user || credentials.hdi_password)) {
|
|
133
|
+
fail('The selected HANA binding only exposes HDI deployment credentials; configure a separate read-only binding.');
|
|
134
|
+
}
|
|
135
|
+
if (credentials.user && credentials.hdi_user && credentials.user === credentials.hdi_user) {
|
|
136
|
+
fail('The selected HANA binding aliases its read-only and HDI deployment users; configure separate identities.');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
source: 'vcap-services',
|
|
141
|
+
bindingName: typeof instance.binding_name === 'string' ? instance.binding_name : instance.name,
|
|
142
|
+
serviceName,
|
|
143
|
+
host: validateHost(credentials.host),
|
|
144
|
+
port: validatePort(credentials.port),
|
|
145
|
+
user: requiredText(credentials.user, 'read-only user'),
|
|
146
|
+
password: requiredText(credentials.password, 'read-only password'),
|
|
147
|
+
schema: validateSchema(credentials.schema),
|
|
148
|
+
trustStore: optionalTrustStore(env.HANA_RO_TRUST_STORE)
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Resolve only a read-only HANA identity; HDI deployment credentials are never a fallback. */
|
|
153
|
+
export function resolveHanaReadOnlyConfig(env = process.env) {
|
|
154
|
+
if (!env || typeof env !== 'object') fail('HANA environment configuration is unavailable.');
|
|
155
|
+
const hasExplicit = hasExplicitConnection(env);
|
|
156
|
+
if (hasExplicit) {
|
|
157
|
+
const missing = EXPLICIT_CONNECTION_KEYS.filter(key => typeof env[key] !== 'string' || !env[key].trim());
|
|
158
|
+
if (missing.length) fail(`Explicit HANA read-only configuration is incomplete: ${missing.join(', ')}.`);
|
|
159
|
+
return Object.freeze(explicitConfig(env));
|
|
160
|
+
}
|
|
161
|
+
return Object.freeze(vcapConfig(env));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function quoteHanaIdentifier(value) {
|
|
165
|
+
const identifier = requiredText(value, 'identifier');
|
|
166
|
+
if (identifier.length > 127 || /[\u0000-\u001f\u007f]/.test(identifier)) {
|
|
167
|
+
fail('The HANA identifier is invalid.');
|
|
168
|
+
}
|
|
169
|
+
return `"${identifier.replaceAll('"', '""')}"`;
|
|
170
|
+
}
|