@superatomai/sdk-node 0.0.9 → 0.0.11
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/dist/index.js +69 -511
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +72 -540
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,439 +1,12 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
1
|
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
9
|
-
}) : x)(function(x) {
|
|
10
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
|
-
});
|
|
13
3
|
var __esm = (fn, res) => function __init() {
|
|
14
4
|
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
15
5
|
};
|
|
16
|
-
var __commonJS = (cb, mod) => function __require2() {
|
|
17
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
18
|
-
};
|
|
19
6
|
var __export = (target, all) => {
|
|
20
7
|
for (var name in all)
|
|
21
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
22
9
|
};
|
|
23
|
-
var __copyProps = (to, from, except, desc) => {
|
|
24
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
25
|
-
for (let key of __getOwnPropNames(from))
|
|
26
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
27
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
28
|
-
}
|
|
29
|
-
return to;
|
|
30
|
-
};
|
|
31
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
32
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
33
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
34
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
35
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
36
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
37
|
-
mod
|
|
38
|
-
));
|
|
39
|
-
|
|
40
|
-
// node_modules/dotenv/package.json
|
|
41
|
-
var require_package = __commonJS({
|
|
42
|
-
"node_modules/dotenv/package.json"(exports, module) {
|
|
43
|
-
module.exports = {
|
|
44
|
-
name: "dotenv",
|
|
45
|
-
version: "17.2.3",
|
|
46
|
-
description: "Loads environment variables from .env file",
|
|
47
|
-
main: "lib/main.js",
|
|
48
|
-
types: "lib/main.d.ts",
|
|
49
|
-
exports: {
|
|
50
|
-
".": {
|
|
51
|
-
types: "./lib/main.d.ts",
|
|
52
|
-
require: "./lib/main.js",
|
|
53
|
-
default: "./lib/main.js"
|
|
54
|
-
},
|
|
55
|
-
"./config": "./config.js",
|
|
56
|
-
"./config.js": "./config.js",
|
|
57
|
-
"./lib/env-options": "./lib/env-options.js",
|
|
58
|
-
"./lib/env-options.js": "./lib/env-options.js",
|
|
59
|
-
"./lib/cli-options": "./lib/cli-options.js",
|
|
60
|
-
"./lib/cli-options.js": "./lib/cli-options.js",
|
|
61
|
-
"./package.json": "./package.json"
|
|
62
|
-
},
|
|
63
|
-
scripts: {
|
|
64
|
-
"dts-check": "tsc --project tests/types/tsconfig.json",
|
|
65
|
-
lint: "standard",
|
|
66
|
-
pretest: "npm run lint && npm run dts-check",
|
|
67
|
-
test: "tap run tests/**/*.js --allow-empty-coverage --disable-coverage --timeout=60000",
|
|
68
|
-
"test:coverage": "tap run tests/**/*.js --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov",
|
|
69
|
-
prerelease: "npm test",
|
|
70
|
-
release: "standard-version"
|
|
71
|
-
},
|
|
72
|
-
repository: {
|
|
73
|
-
type: "git",
|
|
74
|
-
url: "git://github.com/motdotla/dotenv.git"
|
|
75
|
-
},
|
|
76
|
-
homepage: "https://github.com/motdotla/dotenv#readme",
|
|
77
|
-
funding: "https://dotenvx.com",
|
|
78
|
-
keywords: [
|
|
79
|
-
"dotenv",
|
|
80
|
-
"env",
|
|
81
|
-
".env",
|
|
82
|
-
"environment",
|
|
83
|
-
"variables",
|
|
84
|
-
"config",
|
|
85
|
-
"settings"
|
|
86
|
-
],
|
|
87
|
-
readmeFilename: "README.md",
|
|
88
|
-
license: "BSD-2-Clause",
|
|
89
|
-
devDependencies: {
|
|
90
|
-
"@types/node": "^18.11.3",
|
|
91
|
-
decache: "^4.6.2",
|
|
92
|
-
sinon: "^14.0.1",
|
|
93
|
-
standard: "^17.0.0",
|
|
94
|
-
"standard-version": "^9.5.0",
|
|
95
|
-
tap: "^19.2.0",
|
|
96
|
-
typescript: "^4.8.4"
|
|
97
|
-
},
|
|
98
|
-
engines: {
|
|
99
|
-
node: ">=12"
|
|
100
|
-
},
|
|
101
|
-
browser: {
|
|
102
|
-
fs: false
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
// node_modules/dotenv/lib/main.js
|
|
109
|
-
var require_main = __commonJS({
|
|
110
|
-
"node_modules/dotenv/lib/main.js"(exports, module) {
|
|
111
|
-
"use strict";
|
|
112
|
-
var fs8 = __require("fs");
|
|
113
|
-
var path7 = __require("path");
|
|
114
|
-
var os4 = __require("os");
|
|
115
|
-
var crypto2 = __require("crypto");
|
|
116
|
-
var packageJson = require_package();
|
|
117
|
-
var version = packageJson.version;
|
|
118
|
-
var TIPS = [
|
|
119
|
-
"\u{1F510} encrypt with Dotenvx: https://dotenvx.com",
|
|
120
|
-
"\u{1F510} prevent committing .env to code: https://dotenvx.com/precommit",
|
|
121
|
-
"\u{1F510} prevent building .env in docker: https://dotenvx.com/prebuild",
|
|
122
|
-
"\u{1F4E1} add observability to secrets: https://dotenvx.com/ops",
|
|
123
|
-
"\u{1F465} sync secrets across teammates & machines: https://dotenvx.com/ops",
|
|
124
|
-
"\u{1F5C2}\uFE0F backup and recover secrets: https://dotenvx.com/ops",
|
|
125
|
-
"\u2705 audit secrets and track compliance: https://dotenvx.com/ops",
|
|
126
|
-
"\u{1F504} add secrets lifecycle management: https://dotenvx.com/ops",
|
|
127
|
-
"\u{1F511} add access controls to secrets: https://dotenvx.com/ops",
|
|
128
|
-
"\u{1F6E0}\uFE0F run anywhere with `dotenvx run -- yourcommand`",
|
|
129
|
-
"\u2699\uFE0F specify custom .env file path with { path: '/custom/path/.env' }",
|
|
130
|
-
"\u2699\uFE0F enable debug logging with { debug: true }",
|
|
131
|
-
"\u2699\uFE0F override existing env vars with { override: true }",
|
|
132
|
-
"\u2699\uFE0F suppress all logs with { quiet: true }",
|
|
133
|
-
"\u2699\uFE0F write to custom object with { processEnv: myObject }",
|
|
134
|
-
"\u2699\uFE0F load multiple .env files with { path: ['.env.local', '.env'] }"
|
|
135
|
-
];
|
|
136
|
-
function _getRandomTip() {
|
|
137
|
-
return TIPS[Math.floor(Math.random() * TIPS.length)];
|
|
138
|
-
}
|
|
139
|
-
function parseBoolean(value) {
|
|
140
|
-
if (typeof value === "string") {
|
|
141
|
-
return !["false", "0", "no", "off", ""].includes(value.toLowerCase());
|
|
142
|
-
}
|
|
143
|
-
return Boolean(value);
|
|
144
|
-
}
|
|
145
|
-
function supportsAnsi() {
|
|
146
|
-
return process.stdout.isTTY;
|
|
147
|
-
}
|
|
148
|
-
function dim(text) {
|
|
149
|
-
return supportsAnsi() ? `\x1B[2m${text}\x1B[0m` : text;
|
|
150
|
-
}
|
|
151
|
-
var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
|
|
152
|
-
function parse(src) {
|
|
153
|
-
const obj = {};
|
|
154
|
-
let lines = src.toString();
|
|
155
|
-
lines = lines.replace(/\r\n?/mg, "\n");
|
|
156
|
-
let match;
|
|
157
|
-
while ((match = LINE.exec(lines)) != null) {
|
|
158
|
-
const key = match[1];
|
|
159
|
-
let value = match[2] || "";
|
|
160
|
-
value = value.trim();
|
|
161
|
-
const maybeQuote = value[0];
|
|
162
|
-
value = value.replace(/^(['"`])([\s\S]*)\1$/mg, "$2");
|
|
163
|
-
if (maybeQuote === '"') {
|
|
164
|
-
value = value.replace(/\\n/g, "\n");
|
|
165
|
-
value = value.replace(/\\r/g, "\r");
|
|
166
|
-
}
|
|
167
|
-
obj[key] = value;
|
|
168
|
-
}
|
|
169
|
-
return obj;
|
|
170
|
-
}
|
|
171
|
-
function _parseVault(options) {
|
|
172
|
-
options = options || {};
|
|
173
|
-
const vaultPath = _vaultPath(options);
|
|
174
|
-
options.path = vaultPath;
|
|
175
|
-
const result = DotenvModule.configDotenv(options);
|
|
176
|
-
if (!result.parsed) {
|
|
177
|
-
const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
|
|
178
|
-
err.code = "MISSING_DATA";
|
|
179
|
-
throw err;
|
|
180
|
-
}
|
|
181
|
-
const keys = _dotenvKey(options).split(",");
|
|
182
|
-
const length = keys.length;
|
|
183
|
-
let decrypted;
|
|
184
|
-
for (let i = 0; i < length; i++) {
|
|
185
|
-
try {
|
|
186
|
-
const key = keys[i].trim();
|
|
187
|
-
const attrs = _instructions(result, key);
|
|
188
|
-
decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
|
|
189
|
-
break;
|
|
190
|
-
} catch (error) {
|
|
191
|
-
if (i + 1 >= length) {
|
|
192
|
-
throw error;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return DotenvModule.parse(decrypted);
|
|
197
|
-
}
|
|
198
|
-
function _warn(message) {
|
|
199
|
-
console.error(`[dotenv@${version}][WARN] ${message}`);
|
|
200
|
-
}
|
|
201
|
-
function _debug(message) {
|
|
202
|
-
console.log(`[dotenv@${version}][DEBUG] ${message}`);
|
|
203
|
-
}
|
|
204
|
-
function _log(message) {
|
|
205
|
-
console.log(`[dotenv@${version}] ${message}`);
|
|
206
|
-
}
|
|
207
|
-
function _dotenvKey(options) {
|
|
208
|
-
if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {
|
|
209
|
-
return options.DOTENV_KEY;
|
|
210
|
-
}
|
|
211
|
-
if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {
|
|
212
|
-
return process.env.DOTENV_KEY;
|
|
213
|
-
}
|
|
214
|
-
return "";
|
|
215
|
-
}
|
|
216
|
-
function _instructions(result, dotenvKey) {
|
|
217
|
-
let uri;
|
|
218
|
-
try {
|
|
219
|
-
uri = new URL(dotenvKey);
|
|
220
|
-
} catch (error) {
|
|
221
|
-
if (error.code === "ERR_INVALID_URL") {
|
|
222
|
-
const err = new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");
|
|
223
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
224
|
-
throw err;
|
|
225
|
-
}
|
|
226
|
-
throw error;
|
|
227
|
-
}
|
|
228
|
-
const key = uri.password;
|
|
229
|
-
if (!key) {
|
|
230
|
-
const err = new Error("INVALID_DOTENV_KEY: Missing key part");
|
|
231
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
232
|
-
throw err;
|
|
233
|
-
}
|
|
234
|
-
const environment = uri.searchParams.get("environment");
|
|
235
|
-
if (!environment) {
|
|
236
|
-
const err = new Error("INVALID_DOTENV_KEY: Missing environment part");
|
|
237
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
238
|
-
throw err;
|
|
239
|
-
}
|
|
240
|
-
const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
|
|
241
|
-
const ciphertext = result.parsed[environmentKey];
|
|
242
|
-
if (!ciphertext) {
|
|
243
|
-
const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
|
|
244
|
-
err.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
|
|
245
|
-
throw err;
|
|
246
|
-
}
|
|
247
|
-
return { ciphertext, key };
|
|
248
|
-
}
|
|
249
|
-
function _vaultPath(options) {
|
|
250
|
-
let possibleVaultPath = null;
|
|
251
|
-
if (options && options.path && options.path.length > 0) {
|
|
252
|
-
if (Array.isArray(options.path)) {
|
|
253
|
-
for (const filepath of options.path) {
|
|
254
|
-
if (fs8.existsSync(filepath)) {
|
|
255
|
-
possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
} else {
|
|
259
|
-
possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
260
|
-
}
|
|
261
|
-
} else {
|
|
262
|
-
possibleVaultPath = path7.resolve(process.cwd(), ".env.vault");
|
|
263
|
-
}
|
|
264
|
-
if (fs8.existsSync(possibleVaultPath)) {
|
|
265
|
-
return possibleVaultPath;
|
|
266
|
-
}
|
|
267
|
-
return null;
|
|
268
|
-
}
|
|
269
|
-
function _resolveHome(envPath) {
|
|
270
|
-
return envPath[0] === "~" ? path7.join(os4.homedir(), envPath.slice(1)) : envPath;
|
|
271
|
-
}
|
|
272
|
-
function _configVault(options) {
|
|
273
|
-
const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
274
|
-
const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || options && options.quiet);
|
|
275
|
-
if (debug || !quiet) {
|
|
276
|
-
_log("Loading env from encrypted .env.vault");
|
|
277
|
-
}
|
|
278
|
-
const parsed = DotenvModule._parseVault(options);
|
|
279
|
-
let processEnv = process.env;
|
|
280
|
-
if (options && options.processEnv != null) {
|
|
281
|
-
processEnv = options.processEnv;
|
|
282
|
-
}
|
|
283
|
-
DotenvModule.populate(processEnv, parsed, options);
|
|
284
|
-
return { parsed };
|
|
285
|
-
}
|
|
286
|
-
function configDotenv(options) {
|
|
287
|
-
const dotenvPath = path7.resolve(process.cwd(), ".env");
|
|
288
|
-
let encoding = "utf8";
|
|
289
|
-
let processEnv = process.env;
|
|
290
|
-
if (options && options.processEnv != null) {
|
|
291
|
-
processEnv = options.processEnv;
|
|
292
|
-
}
|
|
293
|
-
let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
294
|
-
let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || options && options.quiet);
|
|
295
|
-
if (options && options.encoding) {
|
|
296
|
-
encoding = options.encoding;
|
|
297
|
-
} else {
|
|
298
|
-
if (debug) {
|
|
299
|
-
_debug("No encoding is specified. UTF-8 is used by default");
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
let optionPaths = [dotenvPath];
|
|
303
|
-
if (options && options.path) {
|
|
304
|
-
if (!Array.isArray(options.path)) {
|
|
305
|
-
optionPaths = [_resolveHome(options.path)];
|
|
306
|
-
} else {
|
|
307
|
-
optionPaths = [];
|
|
308
|
-
for (const filepath of options.path) {
|
|
309
|
-
optionPaths.push(_resolveHome(filepath));
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
let lastError;
|
|
314
|
-
const parsedAll = {};
|
|
315
|
-
for (const path8 of optionPaths) {
|
|
316
|
-
try {
|
|
317
|
-
const parsed = DotenvModule.parse(fs8.readFileSync(path8, { encoding }));
|
|
318
|
-
DotenvModule.populate(parsedAll, parsed, options);
|
|
319
|
-
} catch (e) {
|
|
320
|
-
if (debug) {
|
|
321
|
-
_debug(`Failed to load ${path8} ${e.message}`);
|
|
322
|
-
}
|
|
323
|
-
lastError = e;
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
const populated = DotenvModule.populate(processEnv, parsedAll, options);
|
|
327
|
-
debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug);
|
|
328
|
-
quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet);
|
|
329
|
-
if (debug || !quiet) {
|
|
330
|
-
const keysCount = Object.keys(populated).length;
|
|
331
|
-
const shortPaths = [];
|
|
332
|
-
for (const filePath of optionPaths) {
|
|
333
|
-
try {
|
|
334
|
-
const relative = path7.relative(process.cwd(), filePath);
|
|
335
|
-
shortPaths.push(relative);
|
|
336
|
-
} catch (e) {
|
|
337
|
-
if (debug) {
|
|
338
|
-
_debug(`Failed to load ${filePath} ${e.message}`);
|
|
339
|
-
}
|
|
340
|
-
lastError = e;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
_log(`injecting env (${keysCount}) from ${shortPaths.join(",")} ${dim(`-- tip: ${_getRandomTip()}`)}`);
|
|
344
|
-
}
|
|
345
|
-
if (lastError) {
|
|
346
|
-
return { parsed: parsedAll, error: lastError };
|
|
347
|
-
} else {
|
|
348
|
-
return { parsed: parsedAll };
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
function config(options) {
|
|
352
|
-
if (_dotenvKey(options).length === 0) {
|
|
353
|
-
return DotenvModule.configDotenv(options);
|
|
354
|
-
}
|
|
355
|
-
const vaultPath = _vaultPath(options);
|
|
356
|
-
if (!vaultPath) {
|
|
357
|
-
_warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`);
|
|
358
|
-
return DotenvModule.configDotenv(options);
|
|
359
|
-
}
|
|
360
|
-
return DotenvModule._configVault(options);
|
|
361
|
-
}
|
|
362
|
-
function decrypt(encrypted, keyStr) {
|
|
363
|
-
const key = Buffer.from(keyStr.slice(-64), "hex");
|
|
364
|
-
let ciphertext = Buffer.from(encrypted, "base64");
|
|
365
|
-
const nonce = ciphertext.subarray(0, 12);
|
|
366
|
-
const authTag = ciphertext.subarray(-16);
|
|
367
|
-
ciphertext = ciphertext.subarray(12, -16);
|
|
368
|
-
try {
|
|
369
|
-
const aesgcm = crypto2.createDecipheriv("aes-256-gcm", key, nonce);
|
|
370
|
-
aesgcm.setAuthTag(authTag);
|
|
371
|
-
return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
|
|
372
|
-
} catch (error) {
|
|
373
|
-
const isRange = error instanceof RangeError;
|
|
374
|
-
const invalidKeyLength = error.message === "Invalid key length";
|
|
375
|
-
const decryptionFailed = error.message === "Unsupported state or unable to authenticate data";
|
|
376
|
-
if (isRange || invalidKeyLength) {
|
|
377
|
-
const err = new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
|
|
378
|
-
err.code = "INVALID_DOTENV_KEY";
|
|
379
|
-
throw err;
|
|
380
|
-
} else if (decryptionFailed) {
|
|
381
|
-
const err = new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
|
|
382
|
-
err.code = "DECRYPTION_FAILED";
|
|
383
|
-
throw err;
|
|
384
|
-
} else {
|
|
385
|
-
throw error;
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
function populate(processEnv, parsed, options = {}) {
|
|
390
|
-
const debug = Boolean(options && options.debug);
|
|
391
|
-
const override = Boolean(options && options.override);
|
|
392
|
-
const populated = {};
|
|
393
|
-
if (typeof parsed !== "object") {
|
|
394
|
-
const err = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
|
|
395
|
-
err.code = "OBJECT_REQUIRED";
|
|
396
|
-
throw err;
|
|
397
|
-
}
|
|
398
|
-
for (const key of Object.keys(parsed)) {
|
|
399
|
-
if (Object.prototype.hasOwnProperty.call(processEnv, key)) {
|
|
400
|
-
if (override === true) {
|
|
401
|
-
processEnv[key] = parsed[key];
|
|
402
|
-
populated[key] = parsed[key];
|
|
403
|
-
}
|
|
404
|
-
if (debug) {
|
|
405
|
-
if (override === true) {
|
|
406
|
-
_debug(`"${key}" is already defined and WAS overwritten`);
|
|
407
|
-
} else {
|
|
408
|
-
_debug(`"${key}" is already defined and was NOT overwritten`);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
} else {
|
|
412
|
-
processEnv[key] = parsed[key];
|
|
413
|
-
populated[key] = parsed[key];
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
return populated;
|
|
417
|
-
}
|
|
418
|
-
var DotenvModule = {
|
|
419
|
-
configDotenv,
|
|
420
|
-
_configVault,
|
|
421
|
-
_parseVault,
|
|
422
|
-
config,
|
|
423
|
-
decrypt,
|
|
424
|
-
parse,
|
|
425
|
-
populate
|
|
426
|
-
};
|
|
427
|
-
module.exports.configDotenv = DotenvModule.configDotenv;
|
|
428
|
-
module.exports._configVault = DotenvModule._configVault;
|
|
429
|
-
module.exports._parseVault = DotenvModule._parseVault;
|
|
430
|
-
module.exports.config = DotenvModule.config;
|
|
431
|
-
module.exports.decrypt = DotenvModule.decrypt;
|
|
432
|
-
module.exports.parse = DotenvModule.parse;
|
|
433
|
-
module.exports.populate = DotenvModule.populate;
|
|
434
|
-
module.exports = DotenvModule;
|
|
435
|
-
}
|
|
436
|
-
});
|
|
437
10
|
|
|
438
11
|
// src/userResponse/utils.ts
|
|
439
12
|
var utils_exports = {};
|
|
@@ -847,7 +420,7 @@ var UserPromptSuggestionsMessageSchema = z3.object({
|
|
|
847
420
|
payload: UserPromptSuggestionsPayloadSchema
|
|
848
421
|
});
|
|
849
422
|
var ComponentPropsSchema = z3.object({
|
|
850
|
-
query: z3.string().optional(),
|
|
423
|
+
query: z3.string().or(z3.object({})).optional(),
|
|
851
424
|
title: z3.string().optional(),
|
|
852
425
|
description: z3.string().optional(),
|
|
853
426
|
config: z3.record(z3.unknown()).optional(),
|
|
@@ -1399,6 +972,7 @@ var Thread = class {
|
|
|
1399
972
|
let assistantResponse = "";
|
|
1400
973
|
const hasComponent = metadata && Object.keys(metadata).length > 0 && metadata.type;
|
|
1401
974
|
const hasTextResponse = textResponse && textResponse.trim().length > 0;
|
|
975
|
+
const responseParts = [];
|
|
1402
976
|
if (hasComponent) {
|
|
1403
977
|
const parts = [];
|
|
1404
978
|
if (metadata.type) {
|
|
@@ -1407,21 +981,19 @@ var Thread = class {
|
|
|
1407
981
|
if (metadata.name) {
|
|
1408
982
|
parts.push(`Name: ${metadata.name}`);
|
|
1409
983
|
}
|
|
1410
|
-
if (metadata.
|
|
1411
|
-
parts.push(`
|
|
1412
|
-
}
|
|
1413
|
-
if (metadata.props?.query) {
|
|
1414
|
-
const query = metadata.props.query;
|
|
1415
|
-
const truncatedQuery = query.length > 200 ? query.substring(0, 200) + "..." : query;
|
|
1416
|
-
parts.push(`Query: ${truncatedQuery}`);
|
|
984
|
+
if (metadata.description) {
|
|
985
|
+
parts.push(`Description: ${metadata.description}`);
|
|
1417
986
|
}
|
|
1418
|
-
if (metadata.props
|
|
1419
|
-
|
|
1420
|
-
parts.push(`Multi-component with: ${componentTypes}`);
|
|
987
|
+
if (metadata.props) {
|
|
988
|
+
parts.push(`Props: ${JSON.stringify(metadata.props)}`);
|
|
1421
989
|
}
|
|
1422
|
-
|
|
1423
|
-
}
|
|
1424
|
-
|
|
990
|
+
responseParts.push(parts.join("\n"));
|
|
991
|
+
}
|
|
992
|
+
if (hasTextResponse) {
|
|
993
|
+
responseParts.push(textResponse);
|
|
994
|
+
}
|
|
995
|
+
if (responseParts.length > 0) {
|
|
996
|
+
assistantResponse = responseParts.join("\n");
|
|
1425
997
|
} else {
|
|
1426
998
|
assistantResponse = "No response generated";
|
|
1427
999
|
}
|
|
@@ -2046,7 +1618,7 @@ function sendDataResponse3(id, res, sendMessage, clientId) {
|
|
|
2046
1618
|
}
|
|
2047
1619
|
|
|
2048
1620
|
// src/userResponse/groq.ts
|
|
2049
|
-
|
|
1621
|
+
import dotenv from "dotenv";
|
|
2050
1622
|
|
|
2051
1623
|
// src/userResponse/base-llm.ts
|
|
2052
1624
|
init_utils();
|
|
@@ -2773,18 +2345,16 @@ Your job is to:
|
|
|
2773
2345
|
1. **Parse the component suggestions** from the text response (format: 1:component_type : reasoning)
|
|
2774
2346
|
2. **Match each suggestion with an actual component** from the available list
|
|
2775
2347
|
3. **Generate proper props** for each matched component to **visualize the analysis results** that were already fetched
|
|
2776
|
-
4. **
|
|
2348
|
+
4. **Generate title and description** for the dashboard container
|
|
2777
2349
|
5. **Generate intelligent follow-up questions (actions)** that the user might naturally ask next based on the data analysis
|
|
2778
2350
|
|
|
2779
2351
|
**CRITICAL GOAL**: Create dashboard components that display the **same data that was already analyzed** - NOT new data. The queries already ran and got results. You're just creating different visualizations of those results.
|
|
2780
2352
|
|
|
2781
|
-
**APPROACH**: First match all the components suggested in the text response, THEN find the layout that best fits those components.
|
|
2782
|
-
|
|
2783
2353
|
## Available Components
|
|
2784
2354
|
|
|
2785
2355
|
{{AVAILABLE_COMPONENTS}}
|
|
2786
2356
|
|
|
2787
|
-
## Component Matching Rules
|
|
2357
|
+
## Component Matching Rules
|
|
2788
2358
|
For each component suggestion (c1, c2, c3, etc.) from the text response:
|
|
2789
2359
|
|
|
2790
2360
|
1. **Match by type**: Find components whose \`type\` matches the suggested component type
|
|
@@ -2793,23 +2363,10 @@ For each component suggestion (c1, c2, c3, etc.) from the text response:
|
|
|
2793
2363
|
- Best fit for the data being visualized
|
|
2794
2364
|
3. **Fallback**: If no exact type match, find the closest alternative
|
|
2795
2365
|
|
|
2796
|
-
##
|
|
2797
|
-
|
|
2798
|
-
**
|
|
2799
|
-
|
|
2800
|
-
1. **Find layout components** by looking for components with \`type: "DashboardLayout"\` in the available components list
|
|
2801
|
-
2. **Read each layout's description** to understand:
|
|
2802
|
-
- What structure it provides
|
|
2803
|
-
- When it's best used (e.g., comprehensive analysis vs focused analysis)
|
|
2804
|
-
- The number and types of components it can accommodate
|
|
2805
|
-
3. **Select the best layout** based on:
|
|
2806
|
-
- Which layout can best display ALL the matched components
|
|
2807
|
-
- The layout's capacity (how many components it supports)
|
|
2808
|
-
- The types of matched components (KPI, charts, tables, etc.)
|
|
2809
|
-
- The user question and data complexity
|
|
2810
|
-
4. **If no specific layout fits**, fall back to "MultiComponentContainer" as the default layout
|
|
2811
|
-
|
|
2812
|
-
**IMPORTANT:** The layout should be chosen to FIT the matched components, not the other way around. Don't force components to fit a layout - find a layout that accommodates your components.
|
|
2366
|
+
## Dashboard Container
|
|
2367
|
+
All matched components will be placed in the default **MultiComponentContainer** layout. Your job is to:
|
|
2368
|
+
1. **Generate a clear title** for the dashboard that summarizes what it shows
|
|
2369
|
+
2. **Generate a brief description** explaining the dashboard's purpose and scope
|
|
2813
2370
|
|
|
2814
2371
|
## Props Generation Rules
|
|
2815
2372
|
|
|
@@ -2923,8 +2480,8 @@ You MUST respond with ONLY a valid JSON object (no markdown, no code blocks):
|
|
|
2923
2480
|
|
|
2924
2481
|
\`\`\`json
|
|
2925
2482
|
{
|
|
2926
|
-
"
|
|
2927
|
-
"
|
|
2483
|
+
"layoutTitle": "Clear, concise title for the overall dashboard/layout (5-10 words)",
|
|
2484
|
+
"layoutDescription": "Brief description of what the dashboard shows and its purpose (1-2 sentences)",
|
|
2928
2485
|
"matchedComponents": [
|
|
2929
2486
|
{
|
|
2930
2487
|
"componentId": "id_from_available_list",
|
|
@@ -2954,17 +2511,14 @@ You MUST respond with ONLY a valid JSON object (no markdown, no code blocks):
|
|
|
2954
2511
|
\`\`\`
|
|
2955
2512
|
|
|
2956
2513
|
**CRITICAL:**
|
|
2957
|
-
- \`matchedComponents\` MUST include ALL components suggested in the text response
|
|
2958
|
-
- \`
|
|
2959
|
-
-
|
|
2960
|
-
|
|
2961
|
-
-
|
|
2962
|
-
- Why this layout is the best fit for displaying these specific matched components
|
|
2963
|
-
- What makes this layout appropriate for the component types and count
|
|
2964
|
-
- The layout selection happens AFTER component matching - don't force components to fit a pre-selected layout
|
|
2514
|
+
- \`matchedComponents\` MUST include ALL components suggested in the text response
|
|
2515
|
+
- \`layoutTitle\` MUST be a clear, concise title (5-10 words) that summarizes what the entire dashboard shows
|
|
2516
|
+
- Examples: "Sales Performance Overview", "Customer Metrics Analysis", "Product Category Breakdown"
|
|
2517
|
+
- \`layoutDescription\` MUST be a brief description (1-2 sentences) explaining the purpose and scope of the dashboard
|
|
2518
|
+
- Should describe what insights the dashboard provides and what data it shows
|
|
2965
2519
|
- \`actions\` MUST be an array of 4-5 intelligent follow-up questions based on the analysis
|
|
2966
2520
|
- Return ONLY valid JSON (no markdown code blocks, no text before/after)
|
|
2967
|
-
- Generate complete props for each component
|
|
2521
|
+
- Generate complete props for each component including query, title, description, and config
|
|
2968
2522
|
|
|
2969
2523
|
|
|
2970
2524
|
`,
|
|
@@ -4060,12 +3614,13 @@ var BaseLLM = class {
|
|
|
4060
3614
|
/**
|
|
4061
3615
|
* Match components from text response suggestions and generate follow-up questions
|
|
4062
3616
|
* Takes a text response with component suggestions (c1:type format) and matches with available components
|
|
4063
|
-
* Also generates intelligent follow-up questions (actions) based on the analysis
|
|
3617
|
+
* Also generates title, description, and intelligent follow-up questions (actions) based on the analysis
|
|
3618
|
+
* All components are placed in a default MultiComponentContainer layout
|
|
4064
3619
|
* @param textResponse - The text response containing component suggestions
|
|
4065
3620
|
* @param components - List of available components
|
|
4066
3621
|
* @param apiKey - Optional API key
|
|
4067
3622
|
* @param logCollector - Optional log collector
|
|
4068
|
-
* @returns Object containing matched components,
|
|
3623
|
+
* @returns Object containing matched components, layout title/description, and follow-up actions
|
|
4069
3624
|
*/
|
|
4070
3625
|
async matchComponentsFromTextResponse(textResponse, components, apiKey, logCollector) {
|
|
4071
3626
|
try {
|
|
@@ -4108,24 +3663,17 @@ var BaseLLM = class {
|
|
|
4108
3663
|
);
|
|
4109
3664
|
logger.debug(`[${this.getProviderName()}] Component matching response parsed successfully`);
|
|
4110
3665
|
const matchedComponents = result.matchedComponents || [];
|
|
4111
|
-
const
|
|
4112
|
-
const
|
|
3666
|
+
const layoutTitle = result.layoutTitle || "Dashboard";
|
|
3667
|
+
const layoutDescription = result.layoutDescription || "Multi-component dashboard";
|
|
4113
3668
|
const rawActions = result.actions || [];
|
|
4114
3669
|
const actions = convertQuestionsToActions(rawActions);
|
|
4115
|
-
let selectedLayoutComponent = null;
|
|
4116
|
-
if (selectedLayoutId) {
|
|
4117
|
-
selectedLayoutComponent = components.find((c) => c.id === selectedLayoutId) || null;
|
|
4118
|
-
if (!selectedLayoutComponent) {
|
|
4119
|
-
logger.warn(`[${this.getProviderName()}] Layout component ${selectedLayoutId} not found in available components`);
|
|
4120
|
-
}
|
|
4121
|
-
}
|
|
4122
3670
|
logger.info(`[${this.getProviderName()}] Matched ${matchedComponents.length} components from text response`);
|
|
4123
|
-
logger.info(`[${this.getProviderName()}]
|
|
4124
|
-
logger.info(`[${this.getProviderName()}] Layout
|
|
3671
|
+
logger.info(`[${this.getProviderName()}] Layout title: "${layoutTitle}"`);
|
|
3672
|
+
logger.info(`[${this.getProviderName()}] Layout description: "${layoutDescription}"`);
|
|
4125
3673
|
logger.info(`[${this.getProviderName()}] Generated ${actions.length} follow-up actions`);
|
|
4126
3674
|
if (matchedComponents.length > 0) {
|
|
4127
|
-
logCollector?.info(`Matched ${matchedComponents.length} components for visualization
|
|
4128
|
-
logCollector?.info(`
|
|
3675
|
+
logCollector?.info(`Matched ${matchedComponents.length} components for visualization`);
|
|
3676
|
+
logCollector?.info(`Dashboard: "${layoutTitle}"`);
|
|
4129
3677
|
matchedComponents.forEach((comp, idx) => {
|
|
4130
3678
|
logCollector?.info(` ${idx + 1}. ${comp.componentName} (${comp.componentType}): ${comp.reasoning}`);
|
|
4131
3679
|
if (comp.props?.query) {
|
|
@@ -4159,9 +3707,8 @@ var BaseLLM = class {
|
|
|
4159
3707
|
}).filter(Boolean);
|
|
4160
3708
|
return {
|
|
4161
3709
|
components: finalComponents,
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
layoutReasoning,
|
|
3710
|
+
layoutTitle,
|
|
3711
|
+
layoutDescription,
|
|
4165
3712
|
actions
|
|
4166
3713
|
};
|
|
4167
3714
|
} catch (error) {
|
|
@@ -4170,9 +3717,8 @@ var BaseLLM = class {
|
|
|
4170
3717
|
logCollector?.error(`Failed to match components: ${errorMsg}`);
|
|
4171
3718
|
return {
|
|
4172
3719
|
components: [],
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
layoutReasoning: "Failed to match components due to parsing error",
|
|
3720
|
+
layoutTitle: "Dashboard",
|
|
3721
|
+
layoutDescription: "Failed to generate dashboard",
|
|
4176
3722
|
actions: []
|
|
4177
3723
|
};
|
|
4178
3724
|
}
|
|
@@ -4416,9 +3962,12 @@ ${errorMsg}
|
|
|
4416
3962
|
textLength: textResponse.length
|
|
4417
3963
|
}
|
|
4418
3964
|
);
|
|
3965
|
+
if (wrappedStreamCallback && components && components.length > 0) {
|
|
3966
|
+
wrappedStreamCallback("__TEXT_COMPLETE__COMPONENT_GENERATION_START__");
|
|
3967
|
+
}
|
|
4419
3968
|
let matchedComponents = [];
|
|
4420
|
-
let
|
|
4421
|
-
let
|
|
3969
|
+
let layoutTitle = "Dashboard";
|
|
3970
|
+
let layoutDescription = "Multi-component dashboard";
|
|
4422
3971
|
let actions = [];
|
|
4423
3972
|
if (components && components.length > 0) {
|
|
4424
3973
|
logger.info(`[${this.getProviderName()}] Matching components from text response...`);
|
|
@@ -4429,46 +3978,30 @@ ${errorMsg}
|
|
|
4429
3978
|
logCollector
|
|
4430
3979
|
);
|
|
4431
3980
|
matchedComponents = matchResult.components;
|
|
4432
|
-
|
|
4433
|
-
|
|
3981
|
+
layoutTitle = matchResult.layoutTitle;
|
|
3982
|
+
layoutDescription = matchResult.layoutDescription;
|
|
4434
3983
|
actions = matchResult.actions;
|
|
4435
3984
|
}
|
|
4436
3985
|
let container_componet = null;
|
|
4437
3986
|
if (matchedComponents.length > 0) {
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
}
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
}
|
|
4455
|
-
|
|
4456
|
-
id: `multi_container_${Date.now()}`,
|
|
4457
|
-
name: "MultiComponentContainer",
|
|
4458
|
-
type: "Container",
|
|
4459
|
-
description: layoutReasoning,
|
|
4460
|
-
category: "dynamic",
|
|
4461
|
-
keywords: ["dashboard", "layout", "container"],
|
|
4462
|
-
props: {
|
|
4463
|
-
config: {
|
|
4464
|
-
components: matchedComponents
|
|
4465
|
-
},
|
|
4466
|
-
actions
|
|
4467
|
-
}
|
|
4468
|
-
};
|
|
4469
|
-
logger.info(`[${this.getProviderName()}] Created fallback MultiComponentContainer with ${matchedComponents.length} components and ${actions.length} actions`);
|
|
4470
|
-
logCollector?.info(`Created MultiComponentContainer with ${matchedComponents.length} components and ${actions.length} actions: ${layoutReasoning}`);
|
|
4471
|
-
}
|
|
3987
|
+
container_componet = {
|
|
3988
|
+
id: `multi_container_${Date.now()}`,
|
|
3989
|
+
name: "MultiComponentContainer",
|
|
3990
|
+
type: "Container",
|
|
3991
|
+
description: layoutDescription,
|
|
3992
|
+
category: "dynamic",
|
|
3993
|
+
keywords: ["dashboard", "layout", "container"],
|
|
3994
|
+
props: {
|
|
3995
|
+
config: {
|
|
3996
|
+
components: matchedComponents,
|
|
3997
|
+
title: layoutTitle,
|
|
3998
|
+
description: layoutDescription
|
|
3999
|
+
},
|
|
4000
|
+
actions
|
|
4001
|
+
}
|
|
4002
|
+
};
|
|
4003
|
+
logger.info(`[${this.getProviderName()}] Created MultiComponentContainer: "${layoutTitle}" with ${matchedComponents.length} components and ${actions.length} actions`);
|
|
4004
|
+
logCollector?.info(`Created dashboard: "${layoutTitle}" with ${matchedComponents.length} components and ${actions.length} actions`);
|
|
4472
4005
|
}
|
|
4473
4006
|
return {
|
|
4474
4007
|
success: true,
|
|
@@ -4476,7 +4009,6 @@ ${errorMsg}
|
|
|
4476
4009
|
text: textResponse,
|
|
4477
4010
|
matchedComponents,
|
|
4478
4011
|
component: container_componet,
|
|
4479
|
-
layoutReasoning,
|
|
4480
4012
|
actions,
|
|
4481
4013
|
method: `${this.getProviderName()}-text-response`
|
|
4482
4014
|
},
|
|
@@ -4790,7 +4322,7 @@ ${errorMsg}
|
|
|
4790
4322
|
};
|
|
4791
4323
|
|
|
4792
4324
|
// src/userResponse/groq.ts
|
|
4793
|
-
|
|
4325
|
+
dotenv.config();
|
|
4794
4326
|
var GroqLLM = class extends BaseLLM {
|
|
4795
4327
|
constructor(config) {
|
|
4796
4328
|
super(config);
|
|
@@ -4808,8 +4340,8 @@ var GroqLLM = class extends BaseLLM {
|
|
|
4808
4340
|
var groqLLM = new GroqLLM();
|
|
4809
4341
|
|
|
4810
4342
|
// src/userResponse/anthropic.ts
|
|
4811
|
-
|
|
4812
|
-
|
|
4343
|
+
import dotenv2 from "dotenv";
|
|
4344
|
+
dotenv2.config();
|
|
4813
4345
|
var AnthropicLLM = class extends BaseLLM {
|
|
4814
4346
|
constructor(config) {
|
|
4815
4347
|
super(config);
|
|
@@ -4827,8 +4359,8 @@ var AnthropicLLM = class extends BaseLLM {
|
|
|
4827
4359
|
var anthropicLLM = new AnthropicLLM();
|
|
4828
4360
|
|
|
4829
4361
|
// src/userResponse/index.ts
|
|
4830
|
-
|
|
4831
|
-
|
|
4362
|
+
import dotenv3 from "dotenv";
|
|
4363
|
+
dotenv3.config();
|
|
4832
4364
|
function getLLMProviders() {
|
|
4833
4365
|
const envProviders = process.env.LLM_PROVIDERS;
|
|
4834
4366
|
const DEFAULT_PROVIDERS = ["anthropic", "groq"];
|
|
@@ -5142,7 +4674,7 @@ var CONTEXT_CONFIG = {
|
|
|
5142
4674
|
* Set to 0 to disable conversation history
|
|
5143
4675
|
* Higher values provide more context but may increase token usage
|
|
5144
4676
|
*/
|
|
5145
|
-
MAX_CONVERSATION_CONTEXT_BLOCKS:
|
|
4677
|
+
MAX_CONVERSATION_CONTEXT_BLOCKS: 3
|
|
5146
4678
|
};
|
|
5147
4679
|
|
|
5148
4680
|
// src/handlers/user-prompt-request.ts
|