@saptools/cf-hana 0.3.5 → 0.4.1
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 +15 -0
- package/README.md +97 -17
- package/dist/cli.js +3932 -3184
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +23 -8
- package/dist/index.js +922 -315
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- cspell:words VARCHAR -->
|
|
4
4
|
|
|
5
|
+
## 0.4.0 - 2026-07-14
|
|
6
|
+
|
|
7
|
+
- Back up `REPLACE` and matched `MERGE INTO` pre-images, cap backup size, and
|
|
8
|
+
refuse those statements when their target or safe pre-image cannot be derived.
|
|
9
|
+
- Confirm every resolved CLI target on stderr, distinguish ambient from explicit
|
|
10
|
+
selectors, and verify direct `cf env` identity against the ambient target.
|
|
11
|
+
- Add actionable insufficient-privilege guidance with schema, technical user,
|
|
12
|
+
current binding, and sibling binding names without automatic retries.
|
|
13
|
+
- Auto-save exact rows only when compact CSV shortens cells, add
|
|
14
|
+
`--no-auto-save`, and make implicit storage failures non-fatal.
|
|
15
|
+
- Add lossless `query --format table|json|json-compact|csv`, flat catalog name
|
|
16
|
+
output, and exact per-command JSON schemas in help while preserving defaults.
|
|
17
|
+
- Scope metadata suggestions by binding identity and document the existing
|
|
18
|
+
bounded CF retries and 60-second timeout defaults.
|
|
19
|
+
|
|
5
20
|
## 0.3.5 - 2026-07-06
|
|
6
21
|
|
|
7
22
|
- Normalize HANA `BOOLEAN` result columns that arrive from the driver as `1`/`0`
|
package/README.md
CHANGED
|
@@ -11,6 +11,8 @@ password re-authentication.
|
|
|
11
11
|
## Features
|
|
12
12
|
|
|
13
13
|
- **Selector-based connect** — `region/org/space/app` or a bare app name.
|
|
14
|
+
- **Visible target provenance** — every connecting CLI command confirms the
|
|
15
|
+
resolved selector on stderr and labels ambient versus explicit targeting.
|
|
14
16
|
- **Credentials, handled for you** — HANA bindings are read live from Cloud Foundry.
|
|
15
17
|
Bare app names use the current CF session first; explicit selectors use isolated live authentication.
|
|
16
18
|
- **Parameterized queries** — values always travel as bound `?` parameters, never
|
|
@@ -21,14 +23,18 @@ password re-authentication.
|
|
|
21
23
|
`deleteFrom` — query a table by name without writing SQL.
|
|
22
24
|
- **Schema introspection** — list schemas, tables, and columns.
|
|
23
25
|
- **Table-name recovery** — failed CLI queries for missing tables/views show nearby schema-local suggestions on stderr.
|
|
26
|
+
- **Privilege recovery** — HANA error 258 identifies the active schema,
|
|
27
|
+
technical user, binding, and any sibling bindings worth trying explicitly.
|
|
24
28
|
- **Local SQL history** — direct SQL calls are appended to dated JSONL files
|
|
25
29
|
under `~/.saptools/cf-hana/histories/` with five-day retention.
|
|
26
|
-
- **Write backups** — CLI `UPDATE`, `UPSERT`,
|
|
27
|
-
|
|
30
|
+
- **Write backups** — CLI `UPDATE`, `UPSERT`, `REPLACE`, matched `MERGE`, and
|
|
31
|
+
`DELETE` statements preserve pre-image rows before the write runs.
|
|
28
32
|
- **Compact CLI results** — CLI `SELECT`/`WITH` output is compact CSV with
|
|
29
|
-
bounded cells
|
|
33
|
+
bounded cells; truncated exact values are retained automatically for follow-up inspection.
|
|
34
|
+
- **Lossless CLI formats** — `query --format table|json|json-compact|csv`
|
|
35
|
+
provides exact cell values without changing the compact-CSV default.
|
|
30
36
|
- **Safety guard** — opt-in read-only mode and a destructive-statement guard
|
|
31
|
-
(blocks
|
|
37
|
+
(blocks destructive DDL, unscoped `UPDATE`/`DELETE`, and unconditional matched deletes).
|
|
32
38
|
- **Typed results** — `query<TRow>()` returns typed rows.
|
|
33
39
|
- **CLI + API** — a `cf-hana` CLI and an ergonomic TypeScript API.
|
|
34
40
|
|
|
@@ -76,6 +82,15 @@ Every entry point takes a selector as its first argument:
|
|
|
76
82
|
(current org/space/API endpoint) and fetched with `cf env app-demo` using your
|
|
77
83
|
existing CF session before any isolated re-auth fallback.
|
|
78
84
|
|
|
85
|
+
Every connecting CLI command prints the resolved selector to stderr. A bare
|
|
86
|
+
selector is labeled as inherited from ambient `cf target`; an explicit selector
|
|
87
|
+
is labeled as pinned. For the direct bare-app path, cf-hana verifies the app,
|
|
88
|
+
API, org, and space embedded in the same `VCAP_APPLICATION` payload as the
|
|
89
|
+
bindings, then reads `cf target` again. Missing or mismatched identity, including
|
|
90
|
+
an A-to-B-to-A target race, is refused before a database connection is opened.
|
|
91
|
+
If the ambient API cannot be mapped to a supported region, the notice says the
|
|
92
|
+
region is unconfirmed instead of presenting `current/...` as a usable pin.
|
|
93
|
+
|
|
79
94
|
## CLI
|
|
80
95
|
|
|
81
96
|
```
|
|
@@ -91,10 +106,11 @@ cf-hana result <command> Inspect saved query refs
|
|
|
91
106
|
Common options: `--refresh` (deprecated compatibility flag; binding discovery is already live), `--role <runtime|hdi>`, `--binding <name>` /
|
|
92
107
|
`--binding-index <n>`, `--timeout <ms>`, `--read-only`, `--allow-destructive`,
|
|
93
108
|
`--limit <n>`, `--no-auto-limit`. The `query` command also accepts
|
|
94
|
-
`--param <value>` (repeatable), `--cell-limit <n>`, `--save`,
|
|
95
|
-
`--result-ttl-minutes <n>`, and
|
|
96
|
-
`--
|
|
97
|
-
|
|
109
|
+
`--param <value>` (repeatable), `--cell-limit <n>`, `--save`, `--no-auto-save`,
|
|
110
|
+
`--format <table|json|json-compact|csv>`, `--result-ttl-minutes <n>`, and
|
|
111
|
+
`--refresh-metadata`. `tables` and `columns` support the same four format values.
|
|
112
|
+
CLI `UPDATE`, `UPSERT`, `REPLACE`, matched `MERGE`, and `DELETE` statements are
|
|
113
|
+
backed up automatically before the write runs.
|
|
98
114
|
|
|
99
115
|
```bash
|
|
100
116
|
cf-hana query eu10/example-org/space-demo/app-demo "SELECT ID, STATUS FROM ORDERS WHERE STATUS = ?" \
|
|
@@ -106,6 +122,27 @@ cf-hana columns app-demo ORDERS_APP.ORDERS
|
|
|
106
122
|
cf-hana ping eu10/example-org/space-demo/app-demo
|
|
107
123
|
```
|
|
108
124
|
|
|
125
|
+
## Output formats and schemas
|
|
126
|
+
|
|
127
|
+
With no `query --format`, successful `SELECT`/`WITH` output remains compact CSV
|
|
128
|
+
for backward compatibility. An explicit format is lossless at the cell level:
|
|
129
|
+
|
|
130
|
+
- `query --format json` returns `[{COLUMN: value, ...}]`.
|
|
131
|
+
- `query --format json-compact` returns `[value, ...]` for a single-column
|
|
132
|
+
projection and falls back to row objects for multiple columns.
|
|
133
|
+
- `query --format csv` returns lossless RFC 4180 CSV.
|
|
134
|
+
- `query --format table` returns a lossless aligned table.
|
|
135
|
+
- `tables --format json` returns `[{SCHEMA,TABLE,TYPE}]`; its `json-compact`
|
|
136
|
+
mode returns `[TABLE, ...]`.
|
|
137
|
+
- `columns --format json` returns
|
|
138
|
+
`[{COLUMN,TYPE,LENGTH,NULLABLE,POSITION}]`; its `json-compact` mode returns
|
|
139
|
+
`[COLUMN, ...]`.
|
|
140
|
+
|
|
141
|
+
The existing uppercase catalog keys are unchanged. Query formats are available
|
|
142
|
+
only for `SELECT`/`WITH`. `--save` cannot be combined with `--format`, which
|
|
143
|
+
keeps JSON and CSV stdout valid machine output. The automatic row cap still
|
|
144
|
+
applies unless changed with `--limit` or `--no-auto-limit`.
|
|
145
|
+
|
|
109
146
|
## Compact query output and saved refs
|
|
110
147
|
|
|
111
148
|
For CLI `SELECT` and `WITH` statements, stdout is CSV. Bare reads return at most
|
|
@@ -113,7 +150,14 @@ For CLI `SELECT` and `WITH` statements, stdout is CSV. Bare reads return at most
|
|
|
113
150
|
disable the automatic cap. Data cells display at most 128 Unicode characters by
|
|
114
151
|
default; pass `--cell-limit <n>` to choose a value from 1 through 10,000.
|
|
115
152
|
|
|
116
|
-
|
|
153
|
+
When compact output actually shortens one or more cells, cf-hana automatically
|
|
154
|
+
saves the exact returned rows and prints a concrete `result show` command with
|
|
155
|
+
the generated ref to stderr. This does not add a `ref=` line to stdout. Disable
|
|
156
|
+
implicit retention with `--no-auto-save`. If an implicit save exceeds the
|
|
157
|
+
256 MiB store ceiling or local storage is unavailable, the query still succeeds
|
|
158
|
+
and the hint recommends `--save` or a larger `--cell-limit`.
|
|
159
|
+
|
|
160
|
+
Use explicit `--save` when you want a ref regardless of whether cells are shortened:
|
|
117
161
|
|
|
118
162
|
```bash
|
|
119
163
|
cf-hana query app-demo "SELECT ID, CONTENT FROM ORDERS" --read-only --save
|
|
@@ -145,9 +189,18 @@ cf-hana result prune
|
|
|
145
189
|
cf-hana result clear
|
|
146
190
|
```
|
|
147
191
|
|
|
148
|
-
`--save` is available only for `SELECT` and `WITH` statements
|
|
149
|
-
|
|
150
|
-
refs.
|
|
192
|
+
`--save` is available only for `SELECT` and `WITH` statements and remains a
|
|
193
|
+
hard failure if the result cannot be stored. The programmatic API keeps
|
|
194
|
+
returning full-fidelity `QueryResult` values and does not write result refs.
|
|
195
|
+
|
|
196
|
+
## Insufficient-privilege guidance
|
|
197
|
+
|
|
198
|
+
When HANA reports error code 258, or the equivalent `insufficient privilege`
|
|
199
|
+
message without a numeric code, cf-hana keeps the original failure and exit
|
|
200
|
+
status and adds a stderr hint. The hint identifies the schema, role-selected
|
|
201
|
+
technical user, current binding, and other named HANA bindings already found on
|
|
202
|
+
the app. It suggests an explicit `--binding <name>` or another app/full
|
|
203
|
+
selector. It never retries the SQL automatically under another database user.
|
|
151
204
|
|
|
152
205
|
## Invalid table/view suggestions and metadata cache
|
|
153
206
|
|
|
@@ -167,8 +220,9 @@ only schema, object name, and object type under:
|
|
|
167
220
|
Metadata cache files are private (`0700` directories, `0600` files), written
|
|
168
221
|
atomically, and expire after exactly 30 minutes. The cache key is derived from
|
|
169
222
|
non-secret connection identity: selector, app name, host, active schema, role,
|
|
170
|
-
and
|
|
171
|
-
values, result rows, or table data, and
|
|
223
|
+
driver, and selected binding name/index. It does not include passwords,
|
|
224
|
+
certificates, tokens, SQL parameter values, result rows, or table data, and
|
|
225
|
+
malformed cache files are treated as
|
|
172
226
|
misses. Pass `--refresh-metadata` to bypass this cache for a query. The legacy
|
|
173
227
|
`--refresh` flag is accepted for compatibility but does not bypass the metadata
|
|
174
228
|
cache and is not a credential-cache control because binding discovery is already
|
|
@@ -189,6 +243,12 @@ query error and simply omits suggestions.
|
|
|
189
243
|
`bindingIndex`, `readOnly`, `allowDestructive`, `autoLimit`, `queryTimeoutMs`,
|
|
190
244
|
`connectTimeoutMs`, deprecated `refresh`, `pool`.
|
|
191
245
|
|
|
246
|
+
`HanaClient.info` additively exposes optional target and binding provenance for
|
|
247
|
+
programmatic checks: `selectorSource`, `regionConfirmed`,
|
|
248
|
+
`selectorCanBePinned`, `bindingName`, `bindingIndex`, and
|
|
249
|
+
`availableBindingNames`. Library connections remain silent; only the CLI writes
|
|
250
|
+
the resolved-target notice to stderr.
|
|
251
|
+
|
|
192
252
|
## Credentials
|
|
193
253
|
|
|
194
254
|
Credential discovery is **live-only** and does not read `@saptools/cf-sync`
|
|
@@ -198,6 +258,8 @@ snapshots or `~/.saptools/cf-db-bindings.json`.
|
|
|
198
258
|
validated API endpoint, and first run `cf env app-demo` with your current CF
|
|
199
259
|
session. This path does not require `SAP_EMAIL` or `SAP_PASSWORD` while the
|
|
200
260
|
current session is healthy.
|
|
261
|
+
- A successful direct `cf env` is accepted only if a second `cf target` read
|
|
262
|
+
confirms the same API endpoint, org, and space.
|
|
201
263
|
- If that direct bare-app call fails with an auth/session error, cf-hana falls
|
|
202
264
|
back to an isolated temporary `CF_HOME`, runs `cf api <current-endpoint>`,
|
|
203
265
|
authenticates with `SAP_EMAIL` / `SAP_PASSWORD` (or the programmatic `email` /
|
|
@@ -213,6 +275,10 @@ has no credential-cache meaning; binding discovery is already live. Use
|
|
|
213
275
|
suggestion metadata cache. Credential resolution writes no binding credentials
|
|
214
276
|
under `~/.saptools/`.
|
|
215
277
|
|
|
278
|
+
Cloud Foundry shell-outs use 60-second bounded timeouts and retry transient
|
|
279
|
+
timeout/network failures. HANA connection and query timeout defaults are also
|
|
280
|
+
60 seconds unless overridden with `--timeout` or API options.
|
|
281
|
+
|
|
216
282
|
## SQL history
|
|
217
283
|
|
|
218
284
|
Successful direct SQL calls are appended to daily JSONL files:
|
|
@@ -233,16 +299,27 @@ history.
|
|
|
233
299
|
|
|
234
300
|
## Write backups
|
|
235
301
|
|
|
236
|
-
When `cf-hana query` receives
|
|
237
|
-
|
|
302
|
+
When `cf-hana query` receives a supported write, it first builds and runs a
|
|
303
|
+
pre-image `SELECT`:
|
|
238
304
|
|
|
239
305
|
- `UPDATE <target> SET ... WHERE ...` becomes
|
|
240
306
|
`SELECT * FROM <target> WHERE ...`.
|
|
241
307
|
- `UPSERT <target> VALUES ... WHERE ...` becomes
|
|
242
308
|
`SELECT * FROM <target> WHERE ...`.
|
|
309
|
+
- `REPLACE` follows the same plan as its HANA `UPSERT` synonym.
|
|
310
|
+
- A reliably parsed matched `MERGE INTO` uses a correlated `EXISTS` query for
|
|
311
|
+
the matched target rows. If the target is unambiguous but an exact matched set
|
|
312
|
+
is not, cf-hana backs up the whole target table.
|
|
243
313
|
- `DELETE FROM <target> WHERE ...` becomes
|
|
244
314
|
`SELECT * FROM <target> WHERE ...`.
|
|
245
315
|
|
|
316
|
+
UPSERT/REPLACE subquery forms use a conservative whole-target pre-image.
|
|
317
|
+
Insert-only MERGE statements need no pre-image. For the supported write forms
|
|
318
|
+
above, cf-hana refuses execution if it cannot identify a trustworthy target,
|
|
319
|
+
derive a safe pre-image, preserve the backup within the 256 MiB ceiling, or
|
|
320
|
+
write the backup files. This refusal cannot be overridden with
|
|
321
|
+
`--allow-destructive`.
|
|
322
|
+
|
|
246
323
|
The backup is saved before the write runs:
|
|
247
324
|
|
|
248
325
|
```text
|
|
@@ -258,12 +335,15 @@ shape. The companion `.statement.sql` file contains the original write statement
|
|
|
258
335
|
and `.json` contains non-secret metadata for auditability. Backup files are not
|
|
259
336
|
deleted by `cf-hana`; clean them up manually when they are no longer needed. The
|
|
260
337
|
backup path is printed to stderr so stdout remains parseable.
|
|
338
|
+
Backup directories use mode `0700`; statement, CSV, and metadata files use
|
|
339
|
+
mode `0600`.
|
|
261
340
|
|
|
262
341
|
## Safety
|
|
263
342
|
|
|
264
343
|
- **Read-only mode** (`readOnly` / `--read-only`) rejects every DML and DDL statement.
|
|
265
344
|
- **Destructive guard** blocks `DROP` / `TRUNCATE` / `ALTER` and `UPDATE` / `DELETE`
|
|
266
|
-
without a `WHERE
|
|
345
|
+
without a top-level `WHERE`, plus unconditional matched `MERGE DELETE`, unless
|
|
346
|
+
`allowDestructive` / `--allow-destructive` is set.
|
|
267
347
|
- **Auto-limit** appends a `LIMIT` to bare `SELECT` statements (default 100);
|
|
268
348
|
`QueryResult.truncated` reports when it clipped the result. Disable with
|
|
269
349
|
`autoLimit: false` / `--no-auto-limit`.
|