@guanjinke/artifact-client 1.18.0 → 1.20.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/README.md +2 -0
- package/dist/artifact-client.d.ts +3 -1
- package/dist/artifact-client.d.ts.map +1 -1
- package/dist/artifact-client.js +6 -1
- package/dist/artifact-client.js.map +1 -1
- package/dist/cli/config-manager.d.ts +3 -0
- package/dist/cli/config-manager.d.ts.map +1 -1
- package/dist/cli/config-manager.js +44 -0
- package/dist/cli/config-manager.js.map +1 -1
- package/dist/cli/environment.d.ts.map +1 -1
- package/dist/cli/environment.js +117 -1
- package/dist/cli/environment.js.map +1 -1
- package/dist/cli/jdbc-service-client.d.ts +9 -0
- package/dist/cli/jdbc-service-client.d.ts.map +1 -0
- package/dist/cli/jdbc-service-client.js +19 -0
- package/dist/cli/jdbc-service-client.js.map +1 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +46 -2
- package/dist/cli/setup.js.map +1 -1
- package/dist/environment/builder.d.ts +9 -0
- package/dist/environment/builder.d.ts.map +1 -1
- package/dist/environment/builder.js +65 -6
- package/dist/environment/builder.js.map +1 -1
- package/dist/environment/catalog.d.ts +7 -0
- package/dist/environment/catalog.d.ts.map +1 -1
- package/dist/environment/catalog.js +15 -0
- package/dist/environment/catalog.js.map +1 -1
- package/dist/environment/config.d.ts +3 -1
- package/dist/environment/config.d.ts.map +1 -1
- package/dist/environment/config.js +103 -1
- package/dist/environment/config.js.map +1 -1
- package/dist/environment/driver-discovery.d.ts +3 -0
- package/dist/environment/driver-discovery.d.ts.map +1 -0
- package/dist/environment/driver-discovery.js +163 -0
- package/dist/environment/driver-discovery.js.map +1 -0
- package/dist/environment/driver-oss.d.ts +14 -0
- package/dist/environment/driver-oss.d.ts.map +1 -0
- package/dist/environment/driver-oss.js +144 -0
- package/dist/environment/driver-oss.js.map +1 -0
- package/dist/environment/drivers.d.ts +33 -0
- package/dist/environment/drivers.d.ts.map +1 -0
- package/dist/environment/drivers.js +274 -0
- package/dist/environment/drivers.js.map +1 -0
- package/dist/environment/hana-archive.d.ts +9 -0
- package/dist/environment/hana-archive.d.ts.map +1 -0
- package/dist/environment/hana-archive.js +181 -0
- package/dist/environment/hana-archive.js.map +1 -0
- package/dist/environment/hana.d.ts +58 -0
- package/dist/environment/hana.d.ts.map +1 -0
- package/dist/environment/hana.js +238 -0
- package/dist/environment/hana.js.map +1 -0
- package/dist/environment/jdbc-connection-test.d.ts +25 -0
- package/dist/environment/jdbc-connection-test.d.ts.map +1 -0
- package/dist/environment/jdbc-connection-test.js +146 -0
- package/dist/environment/jdbc-connection-test.js.map +1 -0
- package/dist/environment/jdbc-diagnostics.d.ts +13 -0
- package/dist/environment/jdbc-diagnostics.d.ts.map +1 -0
- package/dist/environment/jdbc-diagnostics.js +108 -0
- package/dist/environment/jdbc-diagnostics.js.map +1 -0
- package/dist/environment/jdbc-service.d.ts +91 -0
- package/dist/environment/jdbc-service.d.ts.map +1 -0
- package/dist/environment/jdbc-service.js +375 -0
- package/dist/environment/jdbc-service.js.map +1 -0
- package/dist/environment/jdbc.d.ts +28 -0
- package/dist/environment/jdbc.d.ts.map +1 -0
- package/dist/environment/jdbc.js +164 -0
- package/dist/environment/jdbc.js.map +1 -0
- package/dist/environment/manager.d.ts +10 -0
- package/dist/environment/manager.d.ts.map +1 -1
- package/dist/environment/manager.js +74 -9
- package/dist/environment/manager.js.map +1 -1
- package/dist/environment/manifest.d.ts +4 -0
- package/dist/environment/manifest.d.ts.map +1 -1
- package/dist/environment/manifest.js +5 -0
- package/dist/environment/manifest.js.map +1 -1
- package/dist/environment/plan.d.ts +3 -0
- package/dist/environment/plan.d.ts.map +1 -1
- package/dist/environment/plan.js +38 -6
- package/dist/environment/plan.js.map +1 -1
- package/dist/environment/ports.d.ts +34 -0
- package/dist/environment/ports.d.ts.map +1 -0
- package/dist/environment/ports.js +128 -0
- package/dist/environment/ports.js.map +1 -0
- package/dist/environment/process.d.ts.map +1 -1
- package/dist/environment/process.js +13 -6
- package/dist/environment/process.js.map +1 -1
- package/dist/environment/registry.d.ts +17 -0
- package/dist/environment/registry.d.ts.map +1 -1
- package/dist/environment/registry.js +12 -0
- package/dist/environment/registry.js.map +1 -1
- package/dist/environment/site-init.d.ts +16 -0
- package/dist/environment/site-init.d.ts.map +1 -0
- package/dist/environment/site-init.js +108 -0
- package/dist/environment/site-init.js.map +1 -0
- package/dist/environment/types.d.ts +24 -1
- package/dist/environment/types.d.ts.map +1 -1
- package/dist/environment/types.js.map +1 -1
- package/dist/environment/update.d.ts.map +1 -1
- package/dist/environment/update.js +610 -603
- package/dist/environment/update.js.map +1 -1
- package/dist/environment/validate.d.ts +2 -0
- package/dist/environment/validate.d.ts.map +1 -1
- package/dist/environment/validate.js +5 -2
- package/dist/environment/validate.js.map +1 -1
- package/dist/providers/oss-provider.d.ts +6 -2
- package/dist/providers/oss-provider.d.ts.map +1 -1
- package/dist/providers/oss-provider.js +37 -7
- package/dist/providers/oss-provider.js.map +1 -1
- package/dist/web/api.js +2 -1
- package/dist/web/api.js.map +1 -1
- package/dist/web/static/app.js +7 -7
- package/package.json +1 -1
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.HanaDeployWriteError = exports.HanaPrepareWriteError = exports.VERIFIED_HANA_WINDOWS_SHA256 = void 0;
|
|
37
|
+
exports.inspectWindowsHanaPackage = inspectWindowsHanaPackage;
|
|
38
|
+
exports.prepareWindowsHana = prepareWindowsHana;
|
|
39
|
+
exports.deployWindowsHana = deployWindowsHana;
|
|
40
|
+
const fs = __importStar(require("fs/promises"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const os = __importStar(require("os"));
|
|
43
|
+
const crypto_1 = require("crypto");
|
|
44
|
+
const hana_archive_1 = require("./hana-archive");
|
|
45
|
+
const registry_1 = require("./registry");
|
|
46
|
+
const process_1 = require("./process");
|
|
47
|
+
const validate_1 = require("./validate");
|
|
48
|
+
/** Fingerprint of the locally verified SAP HANA Client 2.10.15 Windows x64 DOTNETCORE.TGZ. */
|
|
49
|
+
exports.VERIFIED_HANA_WINDOWS_SHA256 = '95b7b6f1dbe9f4b0367b92189e3d819a9786c178555ea2e8b6246cac01850d7b';
|
|
50
|
+
const MAX_ARCHIVE_SIZE = 64 * 1024 * 1024;
|
|
51
|
+
/** Inspect a known Windows package without extracting, deploying, or changing environment variables. */
|
|
52
|
+
async function inspectWindowsHanaPackage(archive) {
|
|
53
|
+
if (process.platform !== 'win32' || process.arch !== 'x64')
|
|
54
|
+
throw new Error('HANA package inspection requires a Windows x64 process. On Linux install the SAP HANA Client for Linux on every Server and COT Worker host and follow the official procedure manually.');
|
|
55
|
+
if (archive !== undefined && (typeof archive !== 'string' || !archive || archive.includes('\0')))
|
|
56
|
+
throw new Error('Invalid HANA archive path.');
|
|
57
|
+
const file = path.resolve(archive ?? path.join(os.homedir(), 'Downloads', 'Hana', 'hanaclient-2.10-windows-x64', 'client', 'DOTNETCORE.TGZ'));
|
|
58
|
+
let current = path.parse(file).root;
|
|
59
|
+
for (const part of file.slice(current.length).split(path.sep).filter(Boolean)) {
|
|
60
|
+
current = path.join(current, part);
|
|
61
|
+
if ((await fs.lstat(current)).isSymbolicLink())
|
|
62
|
+
throw new Error('HANA archive path contains a link.');
|
|
63
|
+
}
|
|
64
|
+
const handle = await fs.open(file, 'r');
|
|
65
|
+
try {
|
|
66
|
+
const before = await handle.stat();
|
|
67
|
+
if (!before.isFile() || before.size <= 0 || before.size > MAX_ARCHIVE_SIZE)
|
|
68
|
+
throw new Error('Invalid HANA archive file or size.');
|
|
69
|
+
const hash = (0, crypto_1.createHash)('sha256');
|
|
70
|
+
const buffer = Buffer.alloc(1024 * 1024);
|
|
71
|
+
let offset = 0;
|
|
72
|
+
while (offset < before.size) {
|
|
73
|
+
const { bytesRead } = await handle.read(buffer, 0, Math.min(buffer.length, before.size - offset), offset);
|
|
74
|
+
if (!bytesRead)
|
|
75
|
+
throw new Error('HANA archive changed during inspection.');
|
|
76
|
+
hash.update(buffer.subarray(0, bytesRead));
|
|
77
|
+
offset += bytesRead;
|
|
78
|
+
}
|
|
79
|
+
const after = await handle.stat();
|
|
80
|
+
if (after.size !== before.size || after.mtimeMs !== before.mtimeMs || after.ctimeMs !== before.ctimeMs)
|
|
81
|
+
throw new Error('HANA archive changed during inspection.');
|
|
82
|
+
const sha256 = hash.digest('hex');
|
|
83
|
+
return { archive: file, sha256, platform: 'win32', architecture: 'x64', version: sha256 === exports.VERIFIED_HANA_WINDOWS_SHA256 ? '2.10.15' : null, verified: sha256 === exports.VERIFIED_HANA_WINDOWS_SHA256, action: 'inspection-only' };
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
await handle.close();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const HANA_MEMBERS = ['dotnetcore/v2.1/Sap.Data.Hana.Core.v2.1.dll', 'dotnetcore/libadonetHDB.dll'];
|
|
90
|
+
class HanaPrepareWriteError extends Error {
|
|
91
|
+
created;
|
|
92
|
+
failed;
|
|
93
|
+
constructor(created, failed) {
|
|
94
|
+
super(`HANA preparation incomplete; created: ${created.join(', ') || '(none)'}; failed or possibly partial: ${failed}. No files removed.`);
|
|
95
|
+
this.created = created;
|
|
96
|
+
this.failed = failed;
|
|
97
|
+
this.name = 'HanaPrepareWriteError';
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
exports.HanaPrepareWriteError = HanaPrepareWriteError;
|
|
101
|
+
async function missing(target) {
|
|
102
|
+
try {
|
|
103
|
+
return await fs.lstat(target);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
if (error.code === 'ENOENT')
|
|
107
|
+
return undefined;
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/** Run a plan inside the environment lock, after ownership and stopped-state checks. */
|
|
112
|
+
async function withStoppedEnvironment(name, dependencies, plan) {
|
|
113
|
+
const registry = dependencies.registry ?? new registry_1.EnvironmentRegistry();
|
|
114
|
+
const processes = dependencies.processes ?? new process_1.WindowsProcessBackend();
|
|
115
|
+
const original = await registry.get(name);
|
|
116
|
+
return registry.locked(`env-${original.id}`, async () => {
|
|
117
|
+
const entry = await registry.get(name);
|
|
118
|
+
if (entry.id !== original.id || entry.root !== original.root)
|
|
119
|
+
throw new Error('Environment changed during operation.');
|
|
120
|
+
await (0, validate_1.validateEnvironmentOwnership)(entry, registry.directory);
|
|
121
|
+
const state = await (0, validate_1.observeRuntimeState)(entry, processes);
|
|
122
|
+
if (state !== 'stopped' && state !== 'ready')
|
|
123
|
+
throw new Error(`Environment must be stopped; observed state: ${state}.`);
|
|
124
|
+
return plan(entry);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/** Prepare the pinned pair only; does not configure or install a Wyn provider. */
|
|
128
|
+
async function prepareWindowsHana(name, archive, dependencies = {}) {
|
|
129
|
+
const inspected = await inspectWindowsHanaPackage(archive);
|
|
130
|
+
if (!inspected.verified)
|
|
131
|
+
throw new Error('HANA archive is not the verified 2.10.15 package.');
|
|
132
|
+
const files = await (0, hana_archive_1.extractTrustedTgz)(inspected.archive, exports.VERIFIED_HANA_WINDOWS_SHA256, HANA_MEMBERS);
|
|
133
|
+
return withStoppedEnvironment(name, dependencies, async (entry) => {
|
|
134
|
+
const parent = path.join(entry.root, '.afm-hana');
|
|
135
|
+
const directory = path.join(parent, '2.10.15');
|
|
136
|
+
for (const dir of [parent, directory]) {
|
|
137
|
+
const stat = await missing(dir);
|
|
138
|
+
if (stat && (!stat.isDirectory() || stat.isSymbolicLink()))
|
|
139
|
+
throw new Error(`HANA destination is not a real directory: ${dir}.`);
|
|
140
|
+
}
|
|
141
|
+
const plans = HANA_MEMBERS.map(member => ({ name: path.posix.basename(member), content: files.get(member) }));
|
|
142
|
+
for (const plan of plans) {
|
|
143
|
+
const target = path.join(directory, plan.name);
|
|
144
|
+
if (await missing(target))
|
|
145
|
+
throw new Error(`HANA destination conflict: ${target}.`);
|
|
146
|
+
}
|
|
147
|
+
const created = [];
|
|
148
|
+
let failed = parent;
|
|
149
|
+
try {
|
|
150
|
+
for (const dir of [parent, directory]) {
|
|
151
|
+
failed = dir;
|
|
152
|
+
try {
|
|
153
|
+
await fs.mkdir(dir);
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
if (error.code !== 'EEXIST')
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
const stat = await fs.lstat(dir);
|
|
160
|
+
if (!stat.isDirectory() || stat.isSymbolicLink())
|
|
161
|
+
throw new Error('Invalid destination directory.');
|
|
162
|
+
}
|
|
163
|
+
for (const plan of plans) {
|
|
164
|
+
failed = path.join(directory, plan.name);
|
|
165
|
+
await fs.writeFile(failed, plan.content, { flag: 'wx' });
|
|
166
|
+
created.push(failed);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
throw new HanaPrepareWriteError(created, failed);
|
|
171
|
+
}
|
|
172
|
+
return { name: entry.name, directory, files: created, status: 'prepared', configured: false, installed: false, loadability: 'unverified' };
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
class HanaDeployWriteError extends Error {
|
|
176
|
+
created;
|
|
177
|
+
failed;
|
|
178
|
+
constructor(created, failed) {
|
|
179
|
+
super(`HANA deployment incomplete; created: ${created.join(', ') || '(none)'}; failed or possibly partial: ${failed}. No files removed.`);
|
|
180
|
+
this.created = created;
|
|
181
|
+
this.failed = failed;
|
|
182
|
+
this.name = 'HanaDeployWriteError';
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
exports.HanaDeployWriteError = HanaDeployWriteError;
|
|
186
|
+
/**
|
|
187
|
+
* Deploy the pinned managed and native files to the two Windows locations used by Wyn.
|
|
188
|
+
* The deployed files are not a complete installation: the provider stays unconfigured, plugin
|
|
189
|
+
* precedence and the native search path are not verified here, and a restart is required.
|
|
190
|
+
*/
|
|
191
|
+
async function deployWindowsHana(name, archive, dependencies = {}) {
|
|
192
|
+
if ((dependencies.platform ?? process.platform) !== 'win32' || (dependencies.arch ?? process.arch) !== 'x64') {
|
|
193
|
+
throw new Error('HANA deployment requires a Windows x64 process. On Linux install the SAP HANA Client for Linux on every Server and COT Worker host and follow the official procedure manually.');
|
|
194
|
+
}
|
|
195
|
+
const inspected = await inspectWindowsHanaPackage(archive);
|
|
196
|
+
if (!inspected.verified)
|
|
197
|
+
throw new Error('HANA archive is not the verified 2.10.15 package.');
|
|
198
|
+
const files = await (0, hana_archive_1.extractTrustedTgz)(inspected.archive, exports.VERIFIED_HANA_WINDOWS_SHA256, HANA_MEMBERS);
|
|
199
|
+
const plans = HANA_MEMBERS.map(member => ({ name: path.posix.basename(member), content: files.get(member) }));
|
|
200
|
+
return withStoppedEnvironment(name, dependencies, async (entry) => {
|
|
201
|
+
const destinations = [path.join(entry.root, 'Plugins', 'Dataset'), path.join(entry.root, 'CotWorker')];
|
|
202
|
+
// Preflight every destination before writing anything, so a conflict cannot leave a half-deployed pair.
|
|
203
|
+
for (const directory of destinations) {
|
|
204
|
+
const stat = await missing(directory);
|
|
205
|
+
if (!stat || !stat.isDirectory() || stat.isSymbolicLink())
|
|
206
|
+
throw new Error(`HANA destination directory is missing or not real: ${directory}.`);
|
|
207
|
+
for (const plan of plans) {
|
|
208
|
+
const target = path.join(directory, plan.name);
|
|
209
|
+
if (await missing(target))
|
|
210
|
+
throw new Error(`HANA destination conflict: ${target}.`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
const created = [];
|
|
214
|
+
let failed = destinations[0];
|
|
215
|
+
try {
|
|
216
|
+
for (const directory of destinations) {
|
|
217
|
+
for (const plan of plans) {
|
|
218
|
+
failed = path.join(directory, plan.name);
|
|
219
|
+
await fs.writeFile(failed, plan.content, { flag: 'wx' });
|
|
220
|
+
created.push(failed);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
throw new HanaDeployWriteError(created, failed);
|
|
226
|
+
}
|
|
227
|
+
return {
|
|
228
|
+
name: entry.name,
|
|
229
|
+
files: created,
|
|
230
|
+
status: 'deployed',
|
|
231
|
+
configured: false,
|
|
232
|
+
installed: false,
|
|
233
|
+
loadability: 'unverified',
|
|
234
|
+
restartRequired: true,
|
|
235
|
+
};
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=hana.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hana.js","sourceRoot":"","sources":["../../src/environment/hana.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Classification of a provider connection attempt; never carries credentials or raw server text. */
|
|
2
|
+
export type JdbcConnectionOutcome = 'success' | 'connection-error' | 'invalid-connection-string' | 'unsupported-protocol' | 'driver-missing' | 'unknown';
|
|
3
|
+
export interface JdbcConnectionTestResult {
|
|
4
|
+
provider: string;
|
|
5
|
+
outcome: JdbcConnectionOutcome;
|
|
6
|
+
errorCode: number | null;
|
|
7
|
+
/** True only when the outcome proves the driver was registered and reached the network stage. */
|
|
8
|
+
reachedNetwork: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface JdbcConnectionTestOptions {
|
|
11
|
+
uri: string;
|
|
12
|
+
provider: string;
|
|
13
|
+
connectionString: string;
|
|
14
|
+
timeoutMs?: number;
|
|
15
|
+
env?: NodeJS.ProcessEnv;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Calls the data source service connection test and classifies the result.
|
|
19
|
+
* A connection failure that names a network error proves the driver was registered and reached the
|
|
20
|
+
* network stage; neither that nor `success` proves the driver is complete for every query the provider
|
|
21
|
+
* supports. The raw service message is never returned because the service logs and may echo the
|
|
22
|
+
* connection string, which can contain credentials.
|
|
23
|
+
*/
|
|
24
|
+
export declare function testJdbcConnection(options: JdbcConnectionTestOptions): Promise<JdbcConnectionTestResult>;
|
|
25
|
+
//# sourceMappingURL=jdbc-connection-test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jdbc-connection-test.d.ts","sourceRoot":"","sources":["../../src/environment/jdbc-connection-test.ts"],"names":[],"mappings":"AAEA,qGAAqG;AACrG,MAAM,MAAM,qBAAqB,GAC7B,SAAS,GACT,kBAAkB,GAClB,2BAA2B,GAC3B,sBAAsB,GACtB,gBAAgB,GAChB,SAAS,CAAC;AAEd,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iGAAiG;IACjG,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAkDD;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAmB9G"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.testJdbcConnection = testJdbcConnection;
|
|
37
|
+
const http = __importStar(require("http"));
|
|
38
|
+
const MAX_RESPONSE = 64 * 1024;
|
|
39
|
+
const MAX_CONNECTION_STRING = 4096;
|
|
40
|
+
const PARAMETER_ERROR = /project ?id|projectid|required (parameter|property|field)|missing (parameter|property|field)|invalid (connection )?(url|parameter|property|connection string)|no suitable driver/i;
|
|
41
|
+
const NETWORK_ERROR = /connection refused|failed to connect|connectexception|connect timed out|unknownhost|network is unreachable|connection reset|socket|refused/i;
|
|
42
|
+
const DRIVER_ERROR = /classnotfoundexception|noclassdeffounderror/i;
|
|
43
|
+
function origin(value) {
|
|
44
|
+
let url;
|
|
45
|
+
try {
|
|
46
|
+
url = new URL(value);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
throw new Error('Invalid JDBC service URI.');
|
|
50
|
+
}
|
|
51
|
+
if (url.protocol !== 'http:' || !['127.0.0.1', '[::1]'].includes(url.hostname) || !url.port || url.username || url.password || url.pathname !== '/' || url.search || url.hash)
|
|
52
|
+
throw new Error('JDBC service URI must be an explicit loopback HTTP origin.');
|
|
53
|
+
return url;
|
|
54
|
+
}
|
|
55
|
+
function post(url, endpoint, body, authorization, timeoutMs) {
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
let settled = false;
|
|
58
|
+
const fail = () => { if (!settled) {
|
|
59
|
+
settled = true;
|
|
60
|
+
reject(new Error('JDBC connection test request failed.'));
|
|
61
|
+
} };
|
|
62
|
+
const payload = Buffer.from(body, 'utf8');
|
|
63
|
+
const req = http.request({
|
|
64
|
+
protocol: 'http:',
|
|
65
|
+
hostname: url.hostname === '[::1]' ? '::1' : url.hostname,
|
|
66
|
+
port: url.port,
|
|
67
|
+
path: endpoint,
|
|
68
|
+
method: 'POST',
|
|
69
|
+
headers: { Authorization: authorization, 'Content-Type': 'application/json', 'Content-Length': payload.length },
|
|
70
|
+
agent: false,
|
|
71
|
+
}, response => {
|
|
72
|
+
if (response.statusCode !== 200) {
|
|
73
|
+
response.resume();
|
|
74
|
+
fail();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const chunks = [];
|
|
78
|
+
let size = 0;
|
|
79
|
+
response.on('data', (chunk) => { size += chunk.length; if (size > MAX_RESPONSE) {
|
|
80
|
+
response.destroy();
|
|
81
|
+
fail();
|
|
82
|
+
}
|
|
83
|
+
else
|
|
84
|
+
chunks.push(chunk); });
|
|
85
|
+
response.on('error', fail);
|
|
86
|
+
response.on('end', () => { if (!settled) {
|
|
87
|
+
settled = true;
|
|
88
|
+
resolve(Buffer.concat(chunks).toString('utf8'));
|
|
89
|
+
} });
|
|
90
|
+
});
|
|
91
|
+
const timer = setTimeout(() => { req.destroy(); fail(); }, timeoutMs);
|
|
92
|
+
req.on('close', () => clearTimeout(timer));
|
|
93
|
+
req.on('error', fail);
|
|
94
|
+
req.end(payload);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function classify(errorCode, message) {
|
|
98
|
+
if (errorCode === 4005)
|
|
99
|
+
return { outcome: 'unsupported-protocol', reachedNetwork: false };
|
|
100
|
+
if (errorCode === 4001 || DRIVER_ERROR.test(message))
|
|
101
|
+
return { outcome: 'driver-missing', reachedNetwork: false };
|
|
102
|
+
if (PARAMETER_ERROR.test(message))
|
|
103
|
+
return { outcome: 'invalid-connection-string', reachedNetwork: false };
|
|
104
|
+
if (NETWORK_ERROR.test(message))
|
|
105
|
+
return { outcome: 'connection-error', reachedNetwork: true };
|
|
106
|
+
return { outcome: 'unknown', reachedNetwork: false };
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Calls the data source service connection test and classifies the result.
|
|
110
|
+
* A connection failure that names a network error proves the driver was registered and reached the
|
|
111
|
+
* network stage; neither that nor `success` proves the driver is complete for every query the provider
|
|
112
|
+
* supports. The raw service message is never returned because the service logs and may echo the
|
|
113
|
+
* connection string, which can contain credentials.
|
|
114
|
+
*/
|
|
115
|
+
async function testJdbcConnection(options) {
|
|
116
|
+
const url = origin(options.uri);
|
|
117
|
+
const timeout = options.timeoutMs ?? 5000;
|
|
118
|
+
if (!Number.isInteger(timeout) || timeout < 1 || timeout > 30000)
|
|
119
|
+
throw new Error('Invalid JDBC connection test timeout.');
|
|
120
|
+
if (typeof options.provider !== 'string' || !/^[A-Za-z][A-Za-z0-9 ._-]{0,63}$/.test(options.provider))
|
|
121
|
+
throw new Error('Invalid JDBC provider name.');
|
|
122
|
+
if (typeof options.connectionString !== 'string' || !options.connectionString.trim() || options.connectionString.length > MAX_CONNECTION_STRING || /[\x00-\x1f\x7f]/.test(options.connectionString))
|
|
123
|
+
throw new Error('Invalid JDBC connection string.');
|
|
124
|
+
const env = options.env ?? process.env;
|
|
125
|
+
const user = env.AFM_JDBC_USERNAME, password = env.AFM_JDBC_PASSWORD;
|
|
126
|
+
if (!user || !password || user.includes(':') || /[\r\n]/.test(user + password))
|
|
127
|
+
throw new Error('JDBC diagnostic credentials are missing or invalid.');
|
|
128
|
+
const authorization = 'Basic ' + Buffer.from(`${user}:${password}`, 'utf8').toString('base64');
|
|
129
|
+
const response = await post(url, '/api/datasource/connection/test', JSON.stringify({ providerName: options.provider, connectionString: options.connectionString }), authorization, timeout);
|
|
130
|
+
let parsed;
|
|
131
|
+
try {
|
|
132
|
+
parsed = JSON.parse(response);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
throw new Error('Invalid JDBC connection test response.');
|
|
136
|
+
}
|
|
137
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
138
|
+
throw new Error('Invalid JDBC connection test response.');
|
|
139
|
+
const body = parsed;
|
|
140
|
+
if (body.isSuccess === true)
|
|
141
|
+
return { provider: options.provider, outcome: 'success', errorCode: null, reachedNetwork: true };
|
|
142
|
+
const errorCode = typeof body.errorCode === 'number' && Number.isInteger(body.errorCode) ? body.errorCode : null;
|
|
143
|
+
const message = [body.errorMessage, body.message].filter(value => typeof value === 'string').join(' ');
|
|
144
|
+
return { provider: options.provider, errorCode, ...classify(errorCode, message) };
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=jdbc-connection-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jdbc-connection-test.js","sourceRoot":"","sources":["../../src/environment/jdbc-connection-test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface JdbcDiagnostics {
|
|
2
|
+
health: 'ok';
|
|
3
|
+
unavailableProviders: string[];
|
|
4
|
+
externalListening: 'unverified';
|
|
5
|
+
}
|
|
6
|
+
export interface JdbcDiagnosticOptions {
|
|
7
|
+
uri: string;
|
|
8
|
+
timeoutMs?: number;
|
|
9
|
+
env?: NodeJS.ProcessEnv;
|
|
10
|
+
}
|
|
11
|
+
/** Reads status only; a loopback target does not prove the service binds only to loopback. */
|
|
12
|
+
export declare function diagnoseJdbcService(options: JdbcDiagnosticOptions): Promise<JdbcDiagnostics>;
|
|
13
|
+
//# sourceMappingURL=jdbc-diagnostics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jdbc-diagnostics.d.ts","sourceRoot":"","sources":["../../src/environment/jdbc-diagnostics.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,IAAI,CAAC;IACb,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,iBAAiB,EAAE,YAAY,CAAC;CACjC;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AA6BD,8FAA8F;AAC9F,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAclG"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.diagnoseJdbcService = diagnoseJdbcService;
|
|
37
|
+
const http = __importStar(require("http"));
|
|
38
|
+
const MAX_RESPONSE = 64 * 1024;
|
|
39
|
+
function origin(value) {
|
|
40
|
+
let url;
|
|
41
|
+
try {
|
|
42
|
+
url = new URL(value);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
throw new Error('Invalid JDBC service URI.');
|
|
46
|
+
}
|
|
47
|
+
if (url.protocol !== 'http:' || !['127.0.0.1', '[::1]'].includes(url.hostname) || !url.port || url.username || url.password || url.pathname !== '/' || url.search || url.hash)
|
|
48
|
+
throw new Error('JDBC service URI must be an explicit loopback HTTP origin.');
|
|
49
|
+
return url;
|
|
50
|
+
}
|
|
51
|
+
function get(url, endpoint, timeoutMs, authorization) {
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
let settled = false;
|
|
54
|
+
const fail = () => { if (!settled) {
|
|
55
|
+
settled = true;
|
|
56
|
+
reject(new Error('JDBC diagnostic request failed.'));
|
|
57
|
+
} };
|
|
58
|
+
const req = http.request({ protocol: 'http:', hostname: url.hostname === '[::1]' ? '::1' : url.hostname, port: url.port, path: endpoint, method: 'GET', headers: authorization ? { Authorization: authorization } : {}, agent: false }, response => {
|
|
59
|
+
if (response.statusCode !== 200) {
|
|
60
|
+
response.resume();
|
|
61
|
+
fail();
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const chunks = [];
|
|
65
|
+
let size = 0;
|
|
66
|
+
response.on('data', (chunk) => { size += chunk.length; if (size > MAX_RESPONSE) {
|
|
67
|
+
response.destroy();
|
|
68
|
+
fail();
|
|
69
|
+
}
|
|
70
|
+
else
|
|
71
|
+
chunks.push(chunk); });
|
|
72
|
+
response.on('error', fail);
|
|
73
|
+
response.on('end', () => { if (!settled) {
|
|
74
|
+
settled = true;
|
|
75
|
+
resolve(Buffer.concat(chunks).toString('utf8'));
|
|
76
|
+
} });
|
|
77
|
+
});
|
|
78
|
+
const timer = setTimeout(() => { req.destroy(); fail(); }, timeoutMs);
|
|
79
|
+
req.on('close', () => clearTimeout(timer));
|
|
80
|
+
req.on('error', fail);
|
|
81
|
+
req.end();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
/** Reads status only; a loopback target does not prove the service binds only to loopback. */
|
|
85
|
+
async function diagnoseJdbcService(options) {
|
|
86
|
+
const url = origin(options.uri);
|
|
87
|
+
const timeout = options.timeoutMs ?? 5000;
|
|
88
|
+
if (!Number.isInteger(timeout) || timeout < 1 || timeout > 30000)
|
|
89
|
+
throw new Error('Invalid JDBC diagnostic timeout.');
|
|
90
|
+
const env = options.env ?? process.env;
|
|
91
|
+
const user = env.AFM_JDBC_USERNAME, password = env.AFM_JDBC_PASSWORD;
|
|
92
|
+
if (!user || !password || user.includes(':') || /[\r\n]/.test(user + password))
|
|
93
|
+
throw new Error('JDBC diagnostic credentials are missing or invalid.');
|
|
94
|
+
const auth = 'Basic ' + Buffer.from(`${user}:${password}`, 'utf8').toString('base64');
|
|
95
|
+
await get(url, '/api/healthcheck', timeout);
|
|
96
|
+
const body = await get(url, '/api/datasource/unavailableproviders/get', timeout, auth);
|
|
97
|
+
let providers;
|
|
98
|
+
try {
|
|
99
|
+
providers = JSON.parse(body);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
throw new Error('Invalid JDBC provider response.');
|
|
103
|
+
}
|
|
104
|
+
if (!Array.isArray(providers) || providers.some(value => typeof value !== 'string' || value.length > 256 || /[\x00-\x1f\x7f]/.test(value)))
|
|
105
|
+
throw new Error('Invalid JDBC provider response.');
|
|
106
|
+
return { health: 'ok', unavailableProviders: providers, externalListening: 'unverified' };
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=jdbc-diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jdbc-diagnostics.js","sourceRoot":"","sources":["../../src/environment/jdbc-diagnostics.ts"],"names":[],"mappings":"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"}
|