@saptools/cf-hana 0.1.0

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/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 - 2026-05-22
4
+
5
+ - Initial release: run SQL directly against SAP HANA Cloud databases bound to a Cloud Foundry app, addressed by a `region/org/space/app` selector (or a bare app name).
6
+ - Credentials are resolved cache-first via `@saptools/cf-sync`, with an on-demand live Cloud Foundry fetch fallback.
7
+ - Includes a `HanaClient` with pooled connections, parameterized queries, transactions, table introspection, query-builder shorthands, a read-only/destructive-statement safety guard, and a `cf-hana` CLI.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dongtran
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,159 @@
1
+ # @saptools/cf-hana
2
+
3
+ > Run SQL directly against SAP HANA Cloud databases bound to a Cloud Foundry app — addressed by a `region/org/space/app` selector.
4
+
5
+ `@saptools/cf-hana` closes the last gap in the `saptools` chain: `@saptools/cf-sync`
6
+ already discovers Cloud Foundry topology and HANA service bindings, but nothing
7
+ actually executes SQL. This package does. Pass a selector, get a connected,
8
+ pooled client, and run `SELECT` / `INSERT` / `UPDATE` / `DELETE` / DDL.
9
+
10
+ It is fast because credentials come from `cf-sync`'s on-disk cache (no 5–15s CF
11
+ login on the hot path) and connections are pooled and reused within a process.
12
+
13
+ ## Features
14
+
15
+ - **Selector-based connect** — `region/org/space/app` or a bare app name.
16
+ - **Credentials, handled for you** — cache-first via `@saptools/cf-sync`, with an
17
+ on-demand live Cloud Foundry fetch as a fallback.
18
+ - **Parameterized queries** — values always travel as bound `?` parameters, never
19
+ string-concatenated.
20
+ - **Connection pooling** — pooled, reused connections; opt out with `pool: false`.
21
+ - **Transactions** — `transaction(work)` commits on success, rolls back on throw.
22
+ - **Query-builder shorthands** — `selectFrom`, `count`, `insertInto`, `update`,
23
+ `deleteFrom` — query a table by name without writing SQL.
24
+ - **Schema introspection** — list schemas, tables, and columns.
25
+ - **Safety guard** — opt-in read-only mode and a destructive-statement guard
26
+ (blocks `DROP`/`TRUNCATE`/`ALTER` and unscoped `UPDATE`/`DELETE`).
27
+ - **Typed results** — `query<TRow>()` returns typed rows.
28
+ - **CLI + API** — a `cf-hana` CLI and an ergonomic TypeScript API.
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ npm install @saptools/cf-hana
34
+ # or, for the CLI
35
+ npm install -g @saptools/cf-hana
36
+ ```
37
+
38
+ Requires Node.js >= 20. The pure-JavaScript [`hdb`](https://github.com/SAP/node-hdb)
39
+ driver is bundled as a dependency — there is no native build step.
40
+
41
+ ## Quick start
42
+
43
+ ```ts
44
+ import { connect, query } from "@saptools/cf-hana";
45
+
46
+ // Open a reusable, pooled client for one CF app's HANA database.
47
+ const db = await connect("eu10/acme/dev/orders-srv");
48
+
49
+ const open = await db.query("SELECT ID, STATUS FROM ORDERS WHERE STATUS = ?", ["OPEN"]);
50
+ console.log(open.rows);
51
+
52
+ const total = await db.count({ schema: "ORDERS_APP", table: "ORDERS", where: { STATUS: "OPEN" } });
53
+
54
+ await db.transaction(async (tx) => {
55
+ await tx.execute("UPDATE ORDERS SET STATUS = ? WHERE ID = ?", ["SHIPPED", 42]);
56
+ });
57
+
58
+ await db.close();
59
+
60
+ // One-shot: connect, run one query, close.
61
+ const rows = await query("orders-srv", "SELECT COUNT(*) AS N FROM ORDERS");
62
+ ```
63
+
64
+ ## The selector
65
+
66
+ Every entry point takes a selector as its first argument:
67
+
68
+ - **Explicit** — `region/org/space/app` (e.g. `eu10/acme/dev/orders-srv`). Works
69
+ without any cached topology.
70
+ - **Bare app name** — `orders-srv`. Resolved against the topology cached by
71
+ `cf-sync sync`; throws if the name is ambiguous across spaces.
72
+
73
+ ## CLI
74
+
75
+ ```
76
+ cf-hana query <selector> <sql> Run a single SQL statement
77
+ cf-hana tables <selector> [schema] List tables in a schema
78
+ cf-hana columns <selector> <schema.table> List the columns of a table
79
+ cf-hana count <selector> <schema.table> Count rows in a table
80
+ cf-hana ping <selector> Connect and measure round-trip latency
81
+ cf-hana info <selector> Print the resolved connection metadata
82
+ ```
83
+
84
+ Common options: `--format <table|json|csv>`, `--refresh`, `--role <runtime|hdi>`,
85
+ `--binding <name>` / `--binding-index <n>`, `--timeout <ms>`, `--read-only`,
86
+ `--allow-destructive`, `--limit <n>`, `--no-auto-limit`. The `query` command also
87
+ accepts `--param <value>` (repeatable) to bind `?` placeholders.
88
+
89
+ ```bash
90
+ cf-hana query eu10/acme/dev/orders-srv "SELECT ID, STATUS FROM ORDERS WHERE STATUS = ?" \
91
+ --param OPEN --format json
92
+ cf-hana tables orders-srv
93
+ cf-hana columns orders-srv ORDERS_APP.ORDERS
94
+ cf-hana ping eu10/acme/dev/orders-srv
95
+ ```
96
+
97
+ ## Programmatic API
98
+
99
+ | Export | Purpose |
100
+ | --- | --- |
101
+ | `connect(selector, options?)` | Open a reusable, pooled `HanaClient`. |
102
+ | `query(selector, sql, params?, options?)` | One-shot: connect, query, close. |
103
+ | `withConnection(selector, work, options?)` | Run `work` with a client that auto-closes. |
104
+ | `HanaClient` | `query`, `execute`, `selectFrom`, `count`, `insertInto`, `update`, `deleteFrom`, `transaction`, `listSchemas`, `listTables`, `listColumns`, `explain`, `close`. |
105
+ | `createDriver`, `formatResult`, `build*` | Lower-level building blocks. |
106
+
107
+ `ConnectOptions` highlights: `role` (`runtime` | `hdi`), `bindingName` /
108
+ `bindingIndex`, `readOnly`, `allowDestructive`, `autoLimit`, `queryTimeoutMs`,
109
+ `connectTimeoutMs`, `refresh`, `pool`.
110
+
111
+ ## Credentials
112
+
113
+ Credentials are resolved **cache-first**:
114
+
115
+ 1. Read what `cf-sync db-sync` cached in `~/.saptools/cf-db-bindings.json`.
116
+ 2. On a cache miss (or when `refresh: true` / `--refresh` is passed), fetch them
117
+ live from Cloud Foundry. The live fetch needs `SAP_EMAIL` and `SAP_PASSWORD`
118
+ (or the `email` / `password` options) and never persists anything to disk.
119
+
120
+ `cf-hana` itself writes nothing under `~/.saptools/` — it only reads what
121
+ `cf-sync` cached. The connection pool is in-process and in-memory only, so it is
122
+ safe to run many `cf-hana` processes in parallel and alongside any `cf-sync`
123
+ command.
124
+
125
+ ## Safety
126
+
127
+ - **Read-only mode** (`readOnly` / `--read-only`) rejects every DML and DDL statement.
128
+ - **Destructive guard** blocks `DROP` / `TRUNCATE` / `ALTER` and `UPDATE` / `DELETE`
129
+ without a `WHERE` clause unless `allowDestructive` / `--allow-destructive` is set.
130
+ - **Auto-limit** appends a `LIMIT` to bare `SELECT` statements (default 1000);
131
+ `QueryResult.truncated` reports when it clipped the result. Disable with
132
+ `autoLimit: false` / `--no-auto-limit`.
133
+
134
+ The guard is a convenience, not a security control: always pass values as bound
135
+ parameters.
136
+
137
+ ## Requirements
138
+
139
+ - Node.js >= 20.
140
+ - A HANA binding reachable from your network. Resolving a bare app name, or a
141
+ live credential fetch, additionally needs the Cloud Foundry CLI and
142
+ `SAP_EMAIL` / `SAP_PASSWORD`.
143
+
144
+ ## Development
145
+
146
+ ```bash
147
+ pnpm --filter @saptools/cf-hana build
148
+ pnpm --filter @saptools/cf-hana lint
149
+ pnpm --filter @saptools/cf-hana typecheck
150
+ pnpm --filter @saptools/cf-hana test:unit
151
+ pnpm --filter @saptools/cf-hana test:e2e:fake
152
+ ```
153
+
154
+ The live e2e suite (`test:e2e:live`) needs real `SAP_EMAIL` / `SAP_PASSWORD` and
155
+ a `CF_HANA_E2E_TARGET` selector pointing at a HANA-bound app.
156
+
157
+ ## License
158
+
159
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+
2
+ export { }