@bayoudhi/moose-lib-serverless 0.7.1 → 0.7.3
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 +6 -5
- package/dist/index.d.mts +284 -2349
- package/dist/index.d.ts +284 -2349
- package/dist/index.js +1027 -269
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1021 -275
- package/dist/index.mjs.map +1 -1
- package/dist/moose-runner.js +221 -218
- package/dist/moose-tspc.js +267 -61
- package/package.json +2 -3
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __commonJS = (cb, mod) => function
|
|
8
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
9
9
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
10
|
};
|
|
11
11
|
var __export = (target, all) => {
|
|
@@ -191,9 +191,11 @@ var index_exports = {};
|
|
|
191
191
|
__export(index_exports, {
|
|
192
192
|
ACKs: () => ACKs,
|
|
193
193
|
Api: () => Api,
|
|
194
|
+
ApiHelpers: () => ApiHelpers,
|
|
194
195
|
CSV_DELIMITERS: () => CSV_DELIMITERS,
|
|
195
196
|
ClickHouseEngines: () => ClickHouseEngines,
|
|
196
197
|
ConsumptionApi: () => ConsumptionApi,
|
|
198
|
+
ConsumptionHelpers: () => ConsumptionHelpers,
|
|
197
199
|
DEFAULT_CSV_CONFIG: () => DEFAULT_CSV_CONFIG,
|
|
198
200
|
DEFAULT_JSON_CONFIG: () => DEFAULT_JSON_CONFIG,
|
|
199
201
|
DataSource: () => DataSource,
|
|
@@ -207,7 +209,10 @@ __export(index_exports, {
|
|
|
207
209
|
MAX_RETRY_TIME_MS: () => MAX_RETRY_TIME_MS,
|
|
208
210
|
MOOSE_RUNTIME_ENV_PREFIX: () => MOOSE_RUNTIME_ENV_PREFIX,
|
|
209
211
|
MaterializedView: () => MaterializedView,
|
|
212
|
+
MooseCache: () => MooseCache,
|
|
213
|
+
MooseClient: () => MooseClient,
|
|
210
214
|
OlapTable: () => OlapTable,
|
|
215
|
+
QueryClient: () => QueryClient,
|
|
211
216
|
RETRY_FACTOR_PRODUCER: () => RETRY_FACTOR_PRODUCER,
|
|
212
217
|
RETRY_INITIAL_TIME_MS: () => RETRY_INITIAL_TIME_MS,
|
|
213
218
|
Sql: () => Sql,
|
|
@@ -217,24 +222,35 @@ __export(index_exports, {
|
|
|
217
222
|
View: () => View,
|
|
218
223
|
WebApp: () => WebApp,
|
|
219
224
|
Workflow: () => Workflow,
|
|
225
|
+
WorkflowClient: () => WorkflowClient,
|
|
220
226
|
antiCachePath: () => antiCachePath,
|
|
221
227
|
cliLog: () => cliLog,
|
|
222
228
|
compilerLog: () => compilerLog,
|
|
223
229
|
configureClickHouse: () => configureClickHouse,
|
|
224
230
|
createClickhouseParameter: () => createClickhouseParameter,
|
|
231
|
+
createProducerConfig: () => createProducerConfig,
|
|
232
|
+
expressMiddleware: () => expressMiddleware,
|
|
225
233
|
getApi: () => getApi,
|
|
226
234
|
getApis: () => getApis,
|
|
235
|
+
getClickhouseClient: () => getClickhouseClient,
|
|
227
236
|
getFileName: () => getFileName,
|
|
228
237
|
getIngestApi: () => getIngestApi,
|
|
229
238
|
getIngestApis: () => getIngestApis,
|
|
239
|
+
getKafkaClient: () => getKafkaClient,
|
|
240
|
+
getKafkaProducer: () => getKafkaProducer,
|
|
241
|
+
getLegacyMooseUtils: () => getLegacyMooseUtils,
|
|
230
242
|
getMaterializedView: () => getMaterializedView,
|
|
231
243
|
getMaterializedViews: () => getMaterializedViews,
|
|
244
|
+
getMooseClients: () => getMooseClients,
|
|
245
|
+
getMooseUtils: () => getMooseUtils,
|
|
246
|
+
getMooseUtilsFromRequest: () => getMooseUtilsFromRequest,
|
|
232
247
|
getSqlResource: () => getSqlResource,
|
|
233
248
|
getSqlResources: () => getSqlResources,
|
|
234
249
|
getStream: () => getStream,
|
|
235
250
|
getStreams: () => getStreams,
|
|
236
251
|
getTable: () => getTable,
|
|
237
252
|
getTables: () => getTables,
|
|
253
|
+
getTemporalClient: () => getTemporalClient,
|
|
238
254
|
getValueFromParameter: () => getValueFromParameter,
|
|
239
255
|
getView: () => getView,
|
|
240
256
|
getViews: () => getViews,
|
|
@@ -243,6 +259,7 @@ __export(index_exports, {
|
|
|
243
259
|
getWorkflow: () => getWorkflow,
|
|
244
260
|
getWorkflows: () => getWorkflows2,
|
|
245
261
|
isValidCSVDelimiter: () => isValidCSVDelimiter,
|
|
262
|
+
joinQueries: () => joinQueries,
|
|
246
263
|
logError: () => logError,
|
|
247
264
|
mapToClickHouseType: () => mapToClickHouseType,
|
|
248
265
|
mapTstoJs: () => mapTstoJs,
|
|
@@ -252,6 +269,7 @@ __export(index_exports, {
|
|
|
252
269
|
parseJSON: () => parseJSON,
|
|
253
270
|
parseJSONWithDates: () => parseJSONWithDates,
|
|
254
271
|
quoteIdentifier: () => quoteIdentifier,
|
|
272
|
+
rewriteImportExtensions: () => rewriteImportExtensions,
|
|
255
273
|
sql: () => sql,
|
|
256
274
|
toQuery: () => toQuery,
|
|
257
275
|
toQueryPreview: () => toQueryPreview,
|
|
@@ -259,7 +277,7 @@ __export(index_exports, {
|
|
|
259
277
|
});
|
|
260
278
|
module.exports = __toCommonJS(index_exports);
|
|
261
279
|
|
|
262
|
-
//
|
|
280
|
+
// ../../node_modules/.pnpm/@514labs+moose-lib@0.6.417_@swc+helpers@0.5.17_esbuild@0.25.12_ts-patch@3.3.0_tsconfig-paths@_suczegg7f7vmuhhhtfsuwrbhmu/node_modules/@514labs/moose-lib/dist/index.mjs
|
|
263
281
|
var import_fs = require("fs");
|
|
264
282
|
var import_path = __toESM(require("path"), 1);
|
|
265
283
|
var import_client = require("@clickhouse/client");
|
|
@@ -267,14 +285,26 @@ var import_kafka_javascript = __toESM(require_kafka_javascript(), 1);
|
|
|
267
285
|
var import_path2 = __toESM(require("path"), 1);
|
|
268
286
|
var toml = __toESM(require("toml"), 1);
|
|
269
287
|
var import_process = __toESM(require("process"), 1);
|
|
270
|
-
var
|
|
271
|
-
var
|
|
272
|
-
var
|
|
288
|
+
var path2 = __toESM(require("path"), 1);
|
|
289
|
+
var import_fs2 = require("fs");
|
|
290
|
+
var import_path3 = __toESM(require("path"), 1);
|
|
273
291
|
var import_stream = require("stream");
|
|
274
292
|
var import_crypto = require("crypto");
|
|
275
293
|
var import_crypto2 = require("crypto");
|
|
294
|
+
var import_client2 = __toESM(require_client(), 1);
|
|
295
|
+
var import_crypto3 = require("crypto");
|
|
296
|
+
var import_perf_hooks = require("perf_hooks");
|
|
297
|
+
var fs = __toESM(require("fs"), 1);
|
|
298
|
+
var import_redis = __toESM(require_redis(), 1);
|
|
299
|
+
var import_csv_parse = require("csv-parse");
|
|
276
300
|
var __defProp2 = Object.defineProperty;
|
|
277
301
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
302
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
303
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
304
|
+
}) : x)(function(x) {
|
|
305
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
306
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
307
|
+
});
|
|
278
308
|
var __esm = (fn, res) => function __init() {
|
|
279
309
|
return fn && (res = (0, fn[__getOwnPropNames2(fn)[0]])(fn = 0)), res;
|
|
280
310
|
};
|
|
@@ -342,11 +372,11 @@ function walkDirectory(dir, extensions) {
|
|
|
342
372
|
}
|
|
343
373
|
return results;
|
|
344
374
|
}
|
|
345
|
-
function addJsExtensionToImports(
|
|
375
|
+
function addJsExtensionToImports(content2, fileDir) {
|
|
346
376
|
const fromPattern = /(from\s+['"])(\.\.?\/[^'"]*?)(['"])/g;
|
|
347
377
|
const bareImportPattern = /(import\s+['"])(\.\.?\/[^'"]*?)(['"])/g;
|
|
348
378
|
const dynamicPattern = /(import\s*\(\s*['"])(\.\.?\/[^'"]*?)(['"])/g;
|
|
349
|
-
let result =
|
|
379
|
+
let result = content2;
|
|
350
380
|
result = result.replace(fromPattern, (match, prefix, importPath, quote) => {
|
|
351
381
|
return rewriteImportPath(match, prefix, importPath, quote, fileDir);
|
|
352
382
|
});
|
|
@@ -397,10 +427,10 @@ function rewriteImportPath(match, prefix, importPath, quote, fileDir) {
|
|
|
397
427
|
function rewriteImportExtensions(outDir) {
|
|
398
428
|
const files = walkDirectory(outDir, [".js", ".mjs"]);
|
|
399
429
|
for (const filePath of files) {
|
|
400
|
-
const
|
|
430
|
+
const content2 = (0, import_fs.readFileSync)(filePath, "utf-8");
|
|
401
431
|
const fileDir = import_path.default.dirname(filePath);
|
|
402
|
-
const rewritten = addJsExtensionToImports(
|
|
403
|
-
if (
|
|
432
|
+
const rewritten = addJsExtensionToImports(content2, fileDir);
|
|
433
|
+
if (content2 !== rewritten) {
|
|
404
434
|
(0, import_fs.writeFileSync)(filePath, rewritten, "utf-8");
|
|
405
435
|
}
|
|
406
436
|
}
|
|
@@ -452,7 +482,7 @@ var init_commons = __esm({
|
|
|
452
482
|
console.log(message);
|
|
453
483
|
}
|
|
454
484
|
};
|
|
455
|
-
antiCachePath = (
|
|
485
|
+
antiCachePath = (path4) => `${path4}?num=${Math.random().toString()}&time=${Date.now()}`;
|
|
456
486
|
getFileName = (filePath) => {
|
|
457
487
|
const regex = /\/([^\/]+)\.ts/;
|
|
458
488
|
const matches = filePath.match(regex);
|
|
@@ -550,11 +580,11 @@ var init_commons = __esm({
|
|
|
550
580
|
}
|
|
551
581
|
});
|
|
552
582
|
async function findConfigFile(startDir = process.cwd()) {
|
|
553
|
-
const
|
|
583
|
+
const fs2 = await import("fs");
|
|
554
584
|
let currentDir = import_path2.default.resolve(startDir);
|
|
555
585
|
while (true) {
|
|
556
586
|
const configPath = import_path2.default.join(currentDir, "moose.config.toml");
|
|
557
|
-
if (
|
|
587
|
+
if (fs2.existsSync(configPath)) {
|
|
558
588
|
return configPath;
|
|
559
589
|
}
|
|
560
590
|
const parentDir = import_path2.default.dirname(currentDir);
|
|
@@ -566,7 +596,7 @@ async function findConfigFile(startDir = process.cwd()) {
|
|
|
566
596
|
return null;
|
|
567
597
|
}
|
|
568
598
|
async function readProjectConfig() {
|
|
569
|
-
const
|
|
599
|
+
const fs2 = await import("fs");
|
|
570
600
|
const configPath = await findConfigFile();
|
|
571
601
|
if (!configPath) {
|
|
572
602
|
throw new ConfigError(
|
|
@@ -574,7 +604,7 @@ async function readProjectConfig() {
|
|
|
574
604
|
);
|
|
575
605
|
}
|
|
576
606
|
try {
|
|
577
|
-
const configContent =
|
|
607
|
+
const configContent = fs2.readFileSync(configPath, "utf-8");
|
|
578
608
|
const config = toml.parse(configContent);
|
|
579
609
|
return config;
|
|
580
610
|
} catch (error) {
|
|
@@ -865,6 +895,7 @@ var ClickHouseEngines = /* @__PURE__ */ ((ClickHouseEngines2) => {
|
|
|
865
895
|
ClickHouseEngines2["Distributed"] = "Distributed";
|
|
866
896
|
ClickHouseEngines2["IcebergS3"] = "IcebergS3";
|
|
867
897
|
ClickHouseEngines2["Kafka"] = "Kafka";
|
|
898
|
+
ClickHouseEngines2["Merge"] = "Merge";
|
|
868
899
|
ClickHouseEngines2["ReplicatedMergeTree"] = "ReplicatedMergeTree";
|
|
869
900
|
ClickHouseEngines2["ReplicatedReplacingMergeTree"] = "ReplicatedReplacingMergeTree";
|
|
870
901
|
ClickHouseEngines2["ReplicatedAggregatingMergeTree"] = "ReplicatedAggregatingMergeTree";
|
|
@@ -874,50 +905,292 @@ var ClickHouseEngines = /* @__PURE__ */ ((ClickHouseEngines2) => {
|
|
|
874
905
|
return ClickHouseEngines2;
|
|
875
906
|
})(ClickHouseEngines || {});
|
|
876
907
|
init_commons();
|
|
877
|
-
var
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
908
|
+
var MOOSE_COMPILER_PLUGINS = [
|
|
909
|
+
{
|
|
910
|
+
transform: "./node_modules/@514labs/moose-lib/dist/compilerPlugin.js"
|
|
911
|
+
// No longer using transformProgram - direct typia integration eliminates
|
|
912
|
+
// the need for program replacement and the associated incremental compilation issues
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
// Keep typia plugin for users who use typia directly (not through Moose resources)
|
|
916
|
+
transform: "typia/lib/transform"
|
|
917
|
+
}
|
|
918
|
+
];
|
|
919
|
+
var MOOSE_COMPILER_OPTIONS = {
|
|
920
|
+
experimentalDecorators: true,
|
|
921
|
+
esModuleInterop: true,
|
|
922
|
+
// Disable strict module syntax checking to avoid dual-package type conflicts
|
|
923
|
+
// This prevents errors where the same type imported with different resolution
|
|
924
|
+
// modes (CJS vs ESM) is treated as incompatible
|
|
925
|
+
verbatimModuleSyntax: false
|
|
926
|
+
};
|
|
927
|
+
var MOOSE_MODULE_OPTIONS = {
|
|
928
|
+
module: "NodeNext",
|
|
929
|
+
moduleResolution: "NodeNext"
|
|
930
|
+
};
|
|
931
|
+
function getSourceDir() {
|
|
932
|
+
return process.env.MOOSE_SOURCE_DIR || "app";
|
|
933
|
+
}
|
|
934
|
+
var DEFAULT_OUT_DIR = ".moose/compiled";
|
|
935
|
+
function readUserOutDir(projectRoot = process.cwd()) {
|
|
936
|
+
try {
|
|
937
|
+
let content = (0, import_fs2.readFileSync)(
|
|
938
|
+
import_path3.default.join(projectRoot, "tsconfig.json"),
|
|
939
|
+
"utf-8"
|
|
940
|
+
);
|
|
941
|
+
if (content.charCodeAt(0) === 65279) {
|
|
942
|
+
content = content.slice(1);
|
|
905
943
|
}
|
|
906
|
-
const
|
|
907
|
-
|
|
908
|
-
|
|
944
|
+
const tsconfig = eval(`(${content})`);
|
|
945
|
+
return tsconfig.compilerOptions?.outDir || null;
|
|
946
|
+
} catch {
|
|
947
|
+
return null;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
function getOutDir(projectRoot2 = process.cwd()) {
|
|
951
|
+
const userOutDir = readUserOutDir(projectRoot2);
|
|
952
|
+
return userOutDir || DEFAULT_OUT_DIR;
|
|
953
|
+
}
|
|
954
|
+
function getCompiledIndexPath(projectRoot2 = process.cwd()) {
|
|
955
|
+
const outDir = getOutDir(projectRoot2);
|
|
956
|
+
const sourceDir = getSourceDir();
|
|
957
|
+
return import_path3.default.resolve(projectRoot2, outDir, sourceDir, "index.js");
|
|
958
|
+
}
|
|
959
|
+
function hasCompiledArtifacts(projectRoot2 = process.cwd()) {
|
|
960
|
+
return (0, import_fs2.existsSync)(getCompiledIndexPath(projectRoot2));
|
|
961
|
+
}
|
|
962
|
+
function detectModuleSystem(projectRoot2 = process.cwd()) {
|
|
963
|
+
const pkgPath = import_path3.default.join(projectRoot2, "package.json");
|
|
964
|
+
if ((0, import_fs2.existsSync)(pkgPath)) {
|
|
965
|
+
try {
|
|
966
|
+
const pkgContent = (0, import_fs2.readFileSync)(pkgPath, "utf-8");
|
|
967
|
+
const pkg = JSON.parse(pkgContent);
|
|
968
|
+
if (pkg.type === "module") {
|
|
969
|
+
return "esm";
|
|
970
|
+
}
|
|
971
|
+
} catch (e) {
|
|
972
|
+
console.debug(
|
|
973
|
+
`[moose] Failed to parse package.json at ${pkgPath}, defaulting to CJS:`,
|
|
974
|
+
e
|
|
975
|
+
);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
return "cjs";
|
|
979
|
+
}
|
|
980
|
+
function getModuleOptions(moduleSystem) {
|
|
981
|
+
if (moduleSystem === "esm") {
|
|
982
|
+
return {
|
|
983
|
+
module: "ES2022",
|
|
984
|
+
moduleResolution: "bundler"
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
return {
|
|
988
|
+
module: "CommonJS",
|
|
989
|
+
moduleResolution: "Node"
|
|
990
|
+
};
|
|
991
|
+
}
|
|
992
|
+
async function loadModule(modulePath, projectRoot2 = process.cwd()) {
|
|
993
|
+
const moduleSystem = detectModuleSystem(projectRoot2);
|
|
994
|
+
if (moduleSystem === "esm") {
|
|
995
|
+
const { pathToFileURL } = await import("url");
|
|
996
|
+
const fileUrl = pathToFileURL(modulePath).href;
|
|
997
|
+
return await import(fileUrl);
|
|
998
|
+
}
|
|
999
|
+
return __require(modulePath);
|
|
1000
|
+
}
|
|
1001
|
+
var isClientOnlyMode = () => import_process.default.env.MOOSE_CLIENT_ONLY === "true";
|
|
1002
|
+
var moose_internal = {
|
|
1003
|
+
tables: /* @__PURE__ */ new Map(),
|
|
1004
|
+
streams: /* @__PURE__ */ new Map(),
|
|
1005
|
+
ingestApis: /* @__PURE__ */ new Map(),
|
|
1006
|
+
apis: /* @__PURE__ */ new Map(),
|
|
1007
|
+
sqlResources: /* @__PURE__ */ new Map(),
|
|
1008
|
+
workflows: /* @__PURE__ */ new Map(),
|
|
1009
|
+
webApps: /* @__PURE__ */ new Map(),
|
|
1010
|
+
materializedViews: /* @__PURE__ */ new Map(),
|
|
1011
|
+
views: /* @__PURE__ */ new Map()
|
|
1012
|
+
};
|
|
1013
|
+
var defaultRetentionPeriod = 60 * 60 * 24 * 7;
|
|
1014
|
+
var getMooseInternal = () => globalThis.moose_internal;
|
|
1015
|
+
if (getMooseInternal() === void 0) {
|
|
1016
|
+
globalThis.moose_internal = moose_internal;
|
|
1017
|
+
}
|
|
1018
|
+
var loadIndex = async () => {
|
|
1019
|
+
if (!hasCompiledArtifacts()) {
|
|
1020
|
+
const outDir2 = getOutDir();
|
|
1021
|
+
const sourceDir = getSourceDir();
|
|
1022
|
+
throw new Error(
|
|
1023
|
+
`Compiled artifacts not found at ${outDir2}/${sourceDir}/index.js. Run 'npx moose-tspc' to compile your TypeScript first.`
|
|
1024
|
+
);
|
|
1025
|
+
}
|
|
1026
|
+
const registry = getMooseInternal();
|
|
1027
|
+
registry.tables.clear();
|
|
1028
|
+
registry.streams.clear();
|
|
1029
|
+
registry.ingestApis.clear();
|
|
1030
|
+
registry.apis.clear();
|
|
1031
|
+
registry.sqlResources.clear();
|
|
1032
|
+
registry.workflows.clear();
|
|
1033
|
+
registry.webApps.clear();
|
|
1034
|
+
registry.materializedViews.clear();
|
|
1035
|
+
registry.views.clear();
|
|
1036
|
+
const outDir = getOutDir();
|
|
1037
|
+
const compiledDir = path2.isAbsolute(outDir) ? outDir : path2.join(import_process.default.cwd(), outDir);
|
|
1038
|
+
Object.keys(__require.cache).forEach((key) => {
|
|
1039
|
+
if (key.startsWith(compiledDir)) {
|
|
1040
|
+
delete __require.cache[key];
|
|
1041
|
+
}
|
|
1042
|
+
});
|
|
1043
|
+
try {
|
|
1044
|
+
const indexPath = getCompiledIndexPath();
|
|
1045
|
+
await loadModule(indexPath);
|
|
1046
|
+
} catch (error) {
|
|
1047
|
+
let hint;
|
|
1048
|
+
let includeDetails = true;
|
|
1049
|
+
const details = error instanceof Error ? error.message : String(error);
|
|
1050
|
+
if (details.includes("no transform has been configured") || details.includes("NoTransformConfigurationError")) {
|
|
1051
|
+
hint = "\u{1F534} Typia Transformation Error\n\nThis is likely a bug in Moose. The Typia type transformer failed to process your code.\n\nPlease report this issue:\n \u2022 Moose Slack: https://join.slack.com/t/moose-community/shared_invite/zt-2fjh5n3wz-cnOmM9Xe9DYAgQrNu8xKxg\n \u2022 Include the stack trace below and the file being processed\n\n";
|
|
1052
|
+
includeDetails = false;
|
|
1053
|
+
} else if (details.includes("ERR_REQUIRE_ESM") || details.includes("ES Module")) {
|
|
1054
|
+
hint = "The file or its dependencies are ESM-only. Switch to packages that dual-support CJS & ESM, or upgrade to Node 22.12+. If you must use Node 20, you may try Node 20.19\n\n";
|
|
1055
|
+
}
|
|
1056
|
+
if (hint === void 0) {
|
|
1057
|
+
throw error;
|
|
909
1058
|
} else {
|
|
910
|
-
const
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
1059
|
+
const errorMsg = includeDetails ? `${hint}${details}` : hint;
|
|
1060
|
+
const cause = error instanceof Error ? error : void 0;
|
|
1061
|
+
throw new Error(errorMsg, { cause });
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
};
|
|
1065
|
+
var dlqSchema = {
|
|
1066
|
+
version: "3.1",
|
|
1067
|
+
components: {
|
|
1068
|
+
schemas: {
|
|
1069
|
+
DeadLetterModel: {
|
|
1070
|
+
type: "object",
|
|
1071
|
+
properties: {
|
|
1072
|
+
originalRecord: {
|
|
1073
|
+
$ref: "#/components/schemas/Recordstringany"
|
|
1074
|
+
},
|
|
1075
|
+
errorMessage: {
|
|
1076
|
+
type: "string"
|
|
1077
|
+
},
|
|
1078
|
+
errorType: {
|
|
1079
|
+
type: "string"
|
|
1080
|
+
},
|
|
1081
|
+
failedAt: {
|
|
1082
|
+
type: "string",
|
|
1083
|
+
format: "date-time"
|
|
1084
|
+
},
|
|
1085
|
+
source: {
|
|
1086
|
+
oneOf: [
|
|
1087
|
+
{
|
|
1088
|
+
const: "api"
|
|
1089
|
+
},
|
|
1090
|
+
{
|
|
1091
|
+
const: "transform"
|
|
1092
|
+
},
|
|
1093
|
+
{
|
|
1094
|
+
const: "table"
|
|
1095
|
+
}
|
|
1096
|
+
]
|
|
1097
|
+
}
|
|
1098
|
+
},
|
|
1099
|
+
required: [
|
|
1100
|
+
"originalRecord",
|
|
1101
|
+
"errorMessage",
|
|
1102
|
+
"errorType",
|
|
1103
|
+
"failedAt",
|
|
1104
|
+
"source"
|
|
1105
|
+
]
|
|
1106
|
+
},
|
|
1107
|
+
Recordstringany: {
|
|
1108
|
+
type: "object",
|
|
1109
|
+
properties: {},
|
|
1110
|
+
required: [],
|
|
1111
|
+
description: "Construct a type with a set of properties K of type T",
|
|
1112
|
+
additionalProperties: {}
|
|
915
1113
|
}
|
|
916
|
-
return value;
|
|
917
1114
|
}
|
|
1115
|
+
},
|
|
1116
|
+
schemas: [
|
|
1117
|
+
{
|
|
1118
|
+
$ref: "#/components/schemas/DeadLetterModel"
|
|
1119
|
+
}
|
|
1120
|
+
]
|
|
1121
|
+
};
|
|
1122
|
+
var dlqColumns = [
|
|
1123
|
+
{
|
|
1124
|
+
name: "originalRecord",
|
|
1125
|
+
data_type: "Json",
|
|
1126
|
+
primary_key: false,
|
|
1127
|
+
required: true,
|
|
1128
|
+
unique: false,
|
|
1129
|
+
default: null,
|
|
1130
|
+
annotations: [],
|
|
1131
|
+
ttl: null,
|
|
1132
|
+
codec: null,
|
|
1133
|
+
materialized: null,
|
|
1134
|
+
comment: null
|
|
1135
|
+
},
|
|
1136
|
+
{
|
|
1137
|
+
name: "errorMessage",
|
|
1138
|
+
data_type: "String",
|
|
1139
|
+
primary_key: false,
|
|
1140
|
+
required: true,
|
|
1141
|
+
unique: false,
|
|
1142
|
+
default: null,
|
|
1143
|
+
annotations: [],
|
|
1144
|
+
ttl: null,
|
|
1145
|
+
codec: null,
|
|
1146
|
+
materialized: null,
|
|
1147
|
+
comment: null
|
|
1148
|
+
},
|
|
1149
|
+
{
|
|
1150
|
+
name: "errorType",
|
|
1151
|
+
data_type: "String",
|
|
1152
|
+
primary_key: false,
|
|
1153
|
+
required: true,
|
|
1154
|
+
unique: false,
|
|
1155
|
+
default: null,
|
|
1156
|
+
annotations: [],
|
|
1157
|
+
ttl: null,
|
|
1158
|
+
codec: null,
|
|
1159
|
+
materialized: null,
|
|
1160
|
+
comment: null
|
|
1161
|
+
},
|
|
1162
|
+
{
|
|
1163
|
+
name: "failedAt",
|
|
1164
|
+
data_type: "DateTime",
|
|
1165
|
+
primary_key: false,
|
|
1166
|
+
required: true,
|
|
1167
|
+
unique: false,
|
|
1168
|
+
default: null,
|
|
1169
|
+
annotations: [],
|
|
1170
|
+
ttl: null,
|
|
1171
|
+
codec: null,
|
|
1172
|
+
materialized: null,
|
|
1173
|
+
comment: null
|
|
1174
|
+
},
|
|
1175
|
+
{
|
|
1176
|
+
name: "source",
|
|
1177
|
+
data_type: "String",
|
|
1178
|
+
primary_key: false,
|
|
1179
|
+
required: true,
|
|
1180
|
+
unique: false,
|
|
1181
|
+
default: null,
|
|
1182
|
+
annotations: [],
|
|
1183
|
+
ttl: null,
|
|
1184
|
+
codec: null,
|
|
1185
|
+
materialized: null,
|
|
1186
|
+
comment: null
|
|
918
1187
|
}
|
|
1188
|
+
];
|
|
1189
|
+
var getWorkflows = async () => {
|
|
1190
|
+
await loadIndex();
|
|
1191
|
+
const registry = getMooseInternal();
|
|
1192
|
+
return registry.workflows;
|
|
919
1193
|
};
|
|
920
|
-
var mooseEnvSecrets = mooseRuntimeEnv;
|
|
921
1194
|
var quoteIdentifier = (name) => {
|
|
922
1195
|
return name.startsWith("`") && name.endsWith("`") ? name : `\`${name}\``;
|
|
923
1196
|
};
|
|
@@ -1088,216 +1361,6 @@ var mapToClickHouseType = (value) => {
|
|
|
1088
1361
|
function emptyIfUndefined(value) {
|
|
1089
1362
|
return value === void 0 ? "" : value;
|
|
1090
1363
|
}
|
|
1091
|
-
init_commons();
|
|
1092
|
-
function jsonDateReviver(key, value) {
|
|
1093
|
-
const iso8601Format = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)$/;
|
|
1094
|
-
if (typeof value === "string" && iso8601Format.test(value)) {
|
|
1095
|
-
return new Date(value);
|
|
1096
|
-
}
|
|
1097
|
-
return value;
|
|
1098
|
-
}
|
|
1099
|
-
function parseCSV(content, config) {
|
|
1100
|
-
return new Promise((resolve, reject) => {
|
|
1101
|
-
const results = [];
|
|
1102
|
-
(0, import_csv_parse.parse)(content, {
|
|
1103
|
-
delimiter: config.delimiter,
|
|
1104
|
-
columns: config.columns ?? true,
|
|
1105
|
-
skip_empty_lines: config.skipEmptyLines ?? true,
|
|
1106
|
-
trim: config.trim ?? true
|
|
1107
|
-
}).on("data", (row) => {
|
|
1108
|
-
results.push(row);
|
|
1109
|
-
}).on("end", () => {
|
|
1110
|
-
resolve(results);
|
|
1111
|
-
}).on("error", (error) => {
|
|
1112
|
-
reject(error);
|
|
1113
|
-
});
|
|
1114
|
-
});
|
|
1115
|
-
}
|
|
1116
|
-
function parseJSON(content, config = {}) {
|
|
1117
|
-
try {
|
|
1118
|
-
const parsed = JSON.parse(content, config.reviver);
|
|
1119
|
-
if (Array.isArray(parsed)) {
|
|
1120
|
-
return parsed;
|
|
1121
|
-
} else {
|
|
1122
|
-
return [parsed];
|
|
1123
|
-
}
|
|
1124
|
-
} catch (error) {
|
|
1125
|
-
throw new Error(
|
|
1126
|
-
`Failed to parse JSON: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1127
|
-
);
|
|
1128
|
-
}
|
|
1129
|
-
}
|
|
1130
|
-
function parseJSONWithDates(content) {
|
|
1131
|
-
return parseJSON(content, { reviver: jsonDateReviver });
|
|
1132
|
-
}
|
|
1133
|
-
function isValidCSVDelimiter(delimiter) {
|
|
1134
|
-
return delimiter.length === 1 && !/\s/.test(delimiter);
|
|
1135
|
-
}
|
|
1136
|
-
var CSV_DELIMITERS = {
|
|
1137
|
-
COMMA: ",",
|
|
1138
|
-
TAB: " ",
|
|
1139
|
-
SEMICOLON: ";",
|
|
1140
|
-
PIPE: "|"
|
|
1141
|
-
};
|
|
1142
|
-
var DEFAULT_CSV_CONFIG = {
|
|
1143
|
-
delimiter: CSV_DELIMITERS.COMMA,
|
|
1144
|
-
columns: true,
|
|
1145
|
-
skipEmptyLines: true,
|
|
1146
|
-
trim: true
|
|
1147
|
-
};
|
|
1148
|
-
var DEFAULT_JSON_CONFIG = {
|
|
1149
|
-
reviver: jsonDateReviver
|
|
1150
|
-
};
|
|
1151
|
-
var DataSource = class {
|
|
1152
|
-
name;
|
|
1153
|
-
supportsIncremental;
|
|
1154
|
-
constructor(config) {
|
|
1155
|
-
this.name = config.name;
|
|
1156
|
-
this.supportsIncremental = config.supportsIncremental ?? false;
|
|
1157
|
-
}
|
|
1158
|
-
};
|
|
1159
|
-
init_commons();
|
|
1160
|
-
var isClientOnlyMode = () => import_process.default.env.MOOSE_CLIENT_ONLY === "true";
|
|
1161
|
-
var moose_internal = {
|
|
1162
|
-
tables: /* @__PURE__ */ new Map(),
|
|
1163
|
-
streams: /* @__PURE__ */ new Map(),
|
|
1164
|
-
ingestApis: /* @__PURE__ */ new Map(),
|
|
1165
|
-
apis: /* @__PURE__ */ new Map(),
|
|
1166
|
-
sqlResources: /* @__PURE__ */ new Map(),
|
|
1167
|
-
workflows: /* @__PURE__ */ new Map(),
|
|
1168
|
-
webApps: /* @__PURE__ */ new Map(),
|
|
1169
|
-
materializedViews: /* @__PURE__ */ new Map(),
|
|
1170
|
-
views: /* @__PURE__ */ new Map()
|
|
1171
|
-
};
|
|
1172
|
-
var defaultRetentionPeriod = 60 * 60 * 24 * 7;
|
|
1173
|
-
var getMooseInternal = () => globalThis.moose_internal;
|
|
1174
|
-
if (getMooseInternal() === void 0) {
|
|
1175
|
-
globalThis.moose_internal = moose_internal;
|
|
1176
|
-
}
|
|
1177
|
-
var dlqSchema = {
|
|
1178
|
-
version: "3.1",
|
|
1179
|
-
components: {
|
|
1180
|
-
schemas: {
|
|
1181
|
-
DeadLetterModel: {
|
|
1182
|
-
type: "object",
|
|
1183
|
-
properties: {
|
|
1184
|
-
originalRecord: {
|
|
1185
|
-
$ref: "#/components/schemas/Recordstringany"
|
|
1186
|
-
},
|
|
1187
|
-
errorMessage: {
|
|
1188
|
-
type: "string"
|
|
1189
|
-
},
|
|
1190
|
-
errorType: {
|
|
1191
|
-
type: "string"
|
|
1192
|
-
},
|
|
1193
|
-
failedAt: {
|
|
1194
|
-
type: "string",
|
|
1195
|
-
format: "date-time"
|
|
1196
|
-
},
|
|
1197
|
-
source: {
|
|
1198
|
-
oneOf: [
|
|
1199
|
-
{
|
|
1200
|
-
const: "api"
|
|
1201
|
-
},
|
|
1202
|
-
{
|
|
1203
|
-
const: "transform"
|
|
1204
|
-
},
|
|
1205
|
-
{
|
|
1206
|
-
const: "table"
|
|
1207
|
-
}
|
|
1208
|
-
]
|
|
1209
|
-
}
|
|
1210
|
-
},
|
|
1211
|
-
required: [
|
|
1212
|
-
"originalRecord",
|
|
1213
|
-
"errorMessage",
|
|
1214
|
-
"errorType",
|
|
1215
|
-
"failedAt",
|
|
1216
|
-
"source"
|
|
1217
|
-
]
|
|
1218
|
-
},
|
|
1219
|
-
Recordstringany: {
|
|
1220
|
-
type: "object",
|
|
1221
|
-
properties: {},
|
|
1222
|
-
required: [],
|
|
1223
|
-
description: "Construct a type with a set of properties K of type T",
|
|
1224
|
-
additionalProperties: {}
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
},
|
|
1228
|
-
schemas: [
|
|
1229
|
-
{
|
|
1230
|
-
$ref: "#/components/schemas/DeadLetterModel"
|
|
1231
|
-
}
|
|
1232
|
-
]
|
|
1233
|
-
};
|
|
1234
|
-
var dlqColumns = [
|
|
1235
|
-
{
|
|
1236
|
-
name: "originalRecord",
|
|
1237
|
-
data_type: "Json",
|
|
1238
|
-
primary_key: false,
|
|
1239
|
-
required: true,
|
|
1240
|
-
unique: false,
|
|
1241
|
-
default: null,
|
|
1242
|
-
annotations: [],
|
|
1243
|
-
ttl: null,
|
|
1244
|
-
codec: null,
|
|
1245
|
-
materialized: null,
|
|
1246
|
-
comment: null
|
|
1247
|
-
},
|
|
1248
|
-
{
|
|
1249
|
-
name: "errorMessage",
|
|
1250
|
-
data_type: "String",
|
|
1251
|
-
primary_key: false,
|
|
1252
|
-
required: true,
|
|
1253
|
-
unique: false,
|
|
1254
|
-
default: null,
|
|
1255
|
-
annotations: [],
|
|
1256
|
-
ttl: null,
|
|
1257
|
-
codec: null,
|
|
1258
|
-
materialized: null,
|
|
1259
|
-
comment: null
|
|
1260
|
-
},
|
|
1261
|
-
{
|
|
1262
|
-
name: "errorType",
|
|
1263
|
-
data_type: "String",
|
|
1264
|
-
primary_key: false,
|
|
1265
|
-
required: true,
|
|
1266
|
-
unique: false,
|
|
1267
|
-
default: null,
|
|
1268
|
-
annotations: [],
|
|
1269
|
-
ttl: null,
|
|
1270
|
-
codec: null,
|
|
1271
|
-
materialized: null,
|
|
1272
|
-
comment: null
|
|
1273
|
-
},
|
|
1274
|
-
{
|
|
1275
|
-
name: "failedAt",
|
|
1276
|
-
data_type: "DateTime",
|
|
1277
|
-
primary_key: false,
|
|
1278
|
-
required: true,
|
|
1279
|
-
unique: false,
|
|
1280
|
-
default: null,
|
|
1281
|
-
annotations: [],
|
|
1282
|
-
ttl: null,
|
|
1283
|
-
codec: null,
|
|
1284
|
-
materialized: null,
|
|
1285
|
-
comment: null
|
|
1286
|
-
},
|
|
1287
|
-
{
|
|
1288
|
-
name: "source",
|
|
1289
|
-
data_type: "String",
|
|
1290
|
-
primary_key: false,
|
|
1291
|
-
required: true,
|
|
1292
|
-
unique: false,
|
|
1293
|
-
default: null,
|
|
1294
|
-
annotations: [],
|
|
1295
|
-
ttl: null,
|
|
1296
|
-
codec: null,
|
|
1297
|
-
materialized: null,
|
|
1298
|
-
comment: null
|
|
1299
|
-
}
|
|
1300
|
-
];
|
|
1301
1364
|
var OlapTable = class extends TypedBase {
|
|
1302
1365
|
name;
|
|
1303
1366
|
/** @internal */
|
|
@@ -2500,22 +2563,22 @@ var Api = class extends TypedBase {
|
|
|
2500
2563
|
return this._handler;
|
|
2501
2564
|
};
|
|
2502
2565
|
async call(baseUrl, queryParams) {
|
|
2503
|
-
let
|
|
2566
|
+
let path4;
|
|
2504
2567
|
if (this.config?.path) {
|
|
2505
2568
|
if (this.config.version) {
|
|
2506
2569
|
const pathEndsWithVersion = this.config.path.endsWith(`/${this.config.version}`) || this.config.path === this.config.version || this.config.path.endsWith(this.config.version) && this.config.path.length > this.config.version.length && this.config.path[this.config.path.length - this.config.version.length - 1] === "/";
|
|
2507
2570
|
if (pathEndsWithVersion) {
|
|
2508
|
-
|
|
2571
|
+
path4 = this.config.path;
|
|
2509
2572
|
} else {
|
|
2510
|
-
|
|
2573
|
+
path4 = `${this.config.path.replace(/\/$/, "")}/${this.config.version}`;
|
|
2511
2574
|
}
|
|
2512
2575
|
} else {
|
|
2513
|
-
|
|
2576
|
+
path4 = this.config.path;
|
|
2514
2577
|
}
|
|
2515
2578
|
} else {
|
|
2516
|
-
|
|
2579
|
+
path4 = this.config?.version ? `${this.name}/${this.config.version}` : this.name;
|
|
2517
2580
|
}
|
|
2518
|
-
const url = new URL(`${baseUrl.replace(/\/$/, "")}/api/${
|
|
2581
|
+
const url = new URL(`${baseUrl.replace(/\/$/, "")}/api/${path4}`);
|
|
2519
2582
|
const searchParams = url.searchParams;
|
|
2520
2583
|
for (const [key, value] of Object.entries(queryParams)) {
|
|
2521
2584
|
if (Array.isArray(value)) {
|
|
@@ -2574,6 +2637,11 @@ var IngestPipeline = class extends TypedBase {
|
|
|
2574
2637
|
}
|
|
2575
2638
|
}
|
|
2576
2639
|
if (config.table) {
|
|
2640
|
+
if (typeof config.table === "object" && "engine" in config.table && config.table.engine === "Merge") {
|
|
2641
|
+
throw new Error(
|
|
2642
|
+
`IngestPipeline "${name}": Merge engine is read-only and cannot be used as a table destination.`
|
|
2643
|
+
);
|
|
2644
|
+
}
|
|
2577
2645
|
const tableConfig = typeof config.table === "object" ? {
|
|
2578
2646
|
...config.table,
|
|
2579
2647
|
lifeCycle: config.table.lifeCycle ?? config.lifeCycle,
|
|
@@ -2817,6 +2885,8 @@ var MaterializedView = class {
|
|
|
2817
2885
|
sourceTables;
|
|
2818
2886
|
/** Optional metadata for the materialized view */
|
|
2819
2887
|
metadata;
|
|
2888
|
+
/** Optional lifecycle management policy for the materialized view */
|
|
2889
|
+
lifeCycle;
|
|
2820
2890
|
constructor(options, targetSchema, targetColumns) {
|
|
2821
2891
|
let selectStatement = options.selectStatement;
|
|
2822
2892
|
if (typeof selectStatement !== "string") {
|
|
@@ -2850,6 +2920,7 @@ var MaterializedView = class {
|
|
|
2850
2920
|
this.sourceTables = options.selectTables.map(
|
|
2851
2921
|
(t) => formatTableReference(t)
|
|
2852
2922
|
);
|
|
2923
|
+
this.lifeCycle = options.lifeCycle;
|
|
2853
2924
|
this.metadata = options.metadata ? { ...options.metadata } : {};
|
|
2854
2925
|
if (!this.metadata.source) {
|
|
2855
2926
|
const stack = new Error().stack;
|
|
@@ -3158,6 +3229,675 @@ function getView(name) {
|
|
|
3158
3229
|
return getMooseInternal().views.get(name);
|
|
3159
3230
|
}
|
|
3160
3231
|
init_commons();
|
|
3232
|
+
var MOOSE_RUNTIME_ENV_PREFIX = "__MOOSE_RUNTIME_ENV__:";
|
|
3233
|
+
var mooseRuntimeEnv = {
|
|
3234
|
+
/**
|
|
3235
|
+
* Gets a value from an environment variable, with behavior depending on context.
|
|
3236
|
+
*
|
|
3237
|
+
* When IS_LOADING_INFRA_MAP=true (infrastructure loading):
|
|
3238
|
+
* Returns a marker string that Moose CLI will resolve later
|
|
3239
|
+
*
|
|
3240
|
+
* When IS_LOADING_INFRA_MAP is unset (function/workflow runtime):
|
|
3241
|
+
* Returns the actual value from the environment variable
|
|
3242
|
+
*
|
|
3243
|
+
* @param envVarName - Name of the environment variable to resolve
|
|
3244
|
+
* @returns Either a marker string or the actual environment variable value
|
|
3245
|
+
* @throws {Error} If the environment variable name is empty
|
|
3246
|
+
* @throws {Error} If the environment variable is not set (runtime mode only)
|
|
3247
|
+
*
|
|
3248
|
+
* @example
|
|
3249
|
+
* ```typescript
|
|
3250
|
+
* // Instead of this (evaluated at build time):
|
|
3251
|
+
* awsAccessKeyId: process.env.AWS_ACCESS_KEY_ID
|
|
3252
|
+
*
|
|
3253
|
+
* // Use this (evaluated at runtime):
|
|
3254
|
+
* awsAccessKeyId: mooseRuntimeEnv.get("AWS_ACCESS_KEY_ID")
|
|
3255
|
+
* ```
|
|
3256
|
+
*/
|
|
3257
|
+
get(envVarName) {
|
|
3258
|
+
if (!envVarName || envVarName.trim() === "") {
|
|
3259
|
+
throw new Error("Environment variable name cannot be empty");
|
|
3260
|
+
}
|
|
3261
|
+
const isLoadingInfraMap = process.env.IS_LOADING_INFRA_MAP === "true";
|
|
3262
|
+
if (isLoadingInfraMap) {
|
|
3263
|
+
return `${MOOSE_RUNTIME_ENV_PREFIX}${envVarName}`;
|
|
3264
|
+
} else {
|
|
3265
|
+
const value = process.env[envVarName];
|
|
3266
|
+
if (value === void 0) {
|
|
3267
|
+
throw new Error(
|
|
3268
|
+
`Environment variable '${envVarName}' is not set. This is required for runtime execution of functions/workflows.`
|
|
3269
|
+
);
|
|
3270
|
+
}
|
|
3271
|
+
return value;
|
|
3272
|
+
}
|
|
3273
|
+
}
|
|
3274
|
+
};
|
|
3275
|
+
var mooseEnvSecrets = mooseRuntimeEnv;
|
|
3276
|
+
function formatElapsedTime(ms) {
|
|
3277
|
+
if (ms < 1e3) {
|
|
3278
|
+
return `${Math.round(ms)} ms`;
|
|
3279
|
+
}
|
|
3280
|
+
const seconds = ms / 1e3;
|
|
3281
|
+
if (seconds < 60) {
|
|
3282
|
+
return `${seconds.toFixed(2)} seconds`;
|
|
3283
|
+
}
|
|
3284
|
+
const minutes = Math.floor(seconds / 60);
|
|
3285
|
+
const remainingSeconds = seconds % 60;
|
|
3286
|
+
return `${minutes} minutes and ${remainingSeconds.toFixed(2)} seconds`;
|
|
3287
|
+
}
|
|
3288
|
+
var MooseClient = class {
|
|
3289
|
+
query;
|
|
3290
|
+
workflow;
|
|
3291
|
+
constructor(queryClient, temporalClient) {
|
|
3292
|
+
this.query = queryClient;
|
|
3293
|
+
this.workflow = new WorkflowClient(temporalClient);
|
|
3294
|
+
}
|
|
3295
|
+
};
|
|
3296
|
+
var QueryClient = class {
|
|
3297
|
+
client;
|
|
3298
|
+
query_id_prefix;
|
|
3299
|
+
constructor(client, query_id_prefix) {
|
|
3300
|
+
this.client = client;
|
|
3301
|
+
this.query_id_prefix = query_id_prefix;
|
|
3302
|
+
}
|
|
3303
|
+
async execute(sql3) {
|
|
3304
|
+
const [query, query_params] = toQuery(sql3);
|
|
3305
|
+
console.log(`[QueryClient] | Query: ${toQueryPreview(sql3)}`);
|
|
3306
|
+
const start = import_perf_hooks.performance.now();
|
|
3307
|
+
const result = await this.client.query({
|
|
3308
|
+
query,
|
|
3309
|
+
query_params,
|
|
3310
|
+
format: "JSONEachRow",
|
|
3311
|
+
query_id: this.query_id_prefix + (0, import_crypto3.randomUUID)()
|
|
3312
|
+
// Note: wait_end_of_query deliberately NOT set here as this is used for SELECT queries
|
|
3313
|
+
// where response buffering would harm streaming performance and concurrency
|
|
3314
|
+
});
|
|
3315
|
+
const elapsedMs = import_perf_hooks.performance.now() - start;
|
|
3316
|
+
console.log(
|
|
3317
|
+
`[QueryClient] | Query completed: ${formatElapsedTime(elapsedMs)}`
|
|
3318
|
+
);
|
|
3319
|
+
return result;
|
|
3320
|
+
}
|
|
3321
|
+
async command(sql3) {
|
|
3322
|
+
const [query, query_params] = toQuery(sql3);
|
|
3323
|
+
console.log(`[QueryClient] | Command: ${toQueryPreview(sql3)}`);
|
|
3324
|
+
const start = import_perf_hooks.performance.now();
|
|
3325
|
+
const result = await this.client.command({
|
|
3326
|
+
query,
|
|
3327
|
+
query_params,
|
|
3328
|
+
query_id: this.query_id_prefix + (0, import_crypto3.randomUUID)()
|
|
3329
|
+
});
|
|
3330
|
+
const elapsedMs = import_perf_hooks.performance.now() - start;
|
|
3331
|
+
console.log(
|
|
3332
|
+
`[QueryClient] | Command completed: ${formatElapsedTime(elapsedMs)}`
|
|
3333
|
+
);
|
|
3334
|
+
return result;
|
|
3335
|
+
}
|
|
3336
|
+
};
|
|
3337
|
+
var WorkflowClient = class {
|
|
3338
|
+
client;
|
|
3339
|
+
constructor(temporalClient) {
|
|
3340
|
+
this.client = temporalClient;
|
|
3341
|
+
}
|
|
3342
|
+
async execute(name, input_data) {
|
|
3343
|
+
try {
|
|
3344
|
+
if (!this.client) {
|
|
3345
|
+
return {
|
|
3346
|
+
status: 404,
|
|
3347
|
+
body: `Temporal client not found. Is the feature flag enabled?`
|
|
3348
|
+
};
|
|
3349
|
+
}
|
|
3350
|
+
const config = await this.getWorkflowConfig(name);
|
|
3351
|
+
const [processedInput, workflowId] = this.processInputData(
|
|
3352
|
+
name,
|
|
3353
|
+
input_data
|
|
3354
|
+
);
|
|
3355
|
+
console.log(
|
|
3356
|
+
`WorkflowClient - starting workflow: ${name} with config ${JSON.stringify(config)} and input_data ${JSON.stringify(processedInput)}`
|
|
3357
|
+
);
|
|
3358
|
+
const handle = await this.client.workflow.start("ScriptWorkflow", {
|
|
3359
|
+
args: [
|
|
3360
|
+
{ workflow_name: name, execution_mode: "start" },
|
|
3361
|
+
processedInput
|
|
3362
|
+
],
|
|
3363
|
+
taskQueue: "typescript-script-queue",
|
|
3364
|
+
workflowId,
|
|
3365
|
+
workflowIdConflictPolicy: "FAIL",
|
|
3366
|
+
workflowIdReusePolicy: "ALLOW_DUPLICATE",
|
|
3367
|
+
retry: {
|
|
3368
|
+
// Temporal's maximumAttempts = total attempts (initial + retries)
|
|
3369
|
+
maximumAttempts: config.retries + 1
|
|
3370
|
+
},
|
|
3371
|
+
workflowRunTimeout: config.timeout
|
|
3372
|
+
});
|
|
3373
|
+
return {
|
|
3374
|
+
status: 200,
|
|
3375
|
+
body: `Workflow started: ${name}. View it in the Temporal dashboard: http://localhost:8080/namespaces/default/workflows/${workflowId}/${handle.firstExecutionRunId}/history`
|
|
3376
|
+
};
|
|
3377
|
+
} catch (error) {
|
|
3378
|
+
return {
|
|
3379
|
+
status: 400,
|
|
3380
|
+
body: `Error starting workflow: ${error}`
|
|
3381
|
+
};
|
|
3382
|
+
}
|
|
3383
|
+
}
|
|
3384
|
+
async terminate(workflowId) {
|
|
3385
|
+
try {
|
|
3386
|
+
if (!this.client) {
|
|
3387
|
+
return {
|
|
3388
|
+
status: 404,
|
|
3389
|
+
body: `Temporal client not found. Is the feature flag enabled?`
|
|
3390
|
+
};
|
|
3391
|
+
}
|
|
3392
|
+
const handle = this.client.workflow.getHandle(workflowId);
|
|
3393
|
+
await handle.terminate();
|
|
3394
|
+
return {
|
|
3395
|
+
status: 200,
|
|
3396
|
+
body: `Workflow terminated: ${workflowId}`
|
|
3397
|
+
};
|
|
3398
|
+
} catch (error) {
|
|
3399
|
+
return {
|
|
3400
|
+
status: 400,
|
|
3401
|
+
body: `Error terminating workflow: ${error}`
|
|
3402
|
+
};
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
async getWorkflowConfig(name) {
|
|
3406
|
+
const workflows = await getWorkflows();
|
|
3407
|
+
const workflow = workflows.get(name);
|
|
3408
|
+
if (workflow) {
|
|
3409
|
+
return {
|
|
3410
|
+
retries: workflow.config.retries || 3,
|
|
3411
|
+
timeout: workflow.config.timeout || "1h"
|
|
3412
|
+
};
|
|
3413
|
+
}
|
|
3414
|
+
throw new Error(`Workflow config not found for ${name}`);
|
|
3415
|
+
}
|
|
3416
|
+
processInputData(name, input_data) {
|
|
3417
|
+
let workflowId = name;
|
|
3418
|
+
if (input_data) {
|
|
3419
|
+
const hash = (0, import_crypto3.createHash)("sha256").update(JSON.stringify(input_data)).digest("hex").slice(0, 16);
|
|
3420
|
+
workflowId = `${name}-${hash}`;
|
|
3421
|
+
}
|
|
3422
|
+
return [input_data, workflowId];
|
|
3423
|
+
}
|
|
3424
|
+
};
|
|
3425
|
+
async function getTemporalClient(temporalUrl, namespace, clientCert, clientKey, apiKey) {
|
|
3426
|
+
try {
|
|
3427
|
+
console.info(
|
|
3428
|
+
`<api> Using temporal_url: ${temporalUrl} and namespace: ${namespace}`
|
|
3429
|
+
);
|
|
3430
|
+
let connectionOptions = {
|
|
3431
|
+
address: temporalUrl,
|
|
3432
|
+
connectTimeout: "3s"
|
|
3433
|
+
};
|
|
3434
|
+
if (clientCert && clientKey) {
|
|
3435
|
+
console.log("Using TLS for secure Temporal");
|
|
3436
|
+
const cert = await fs.readFileSync(clientCert);
|
|
3437
|
+
const key = await fs.readFileSync(clientKey);
|
|
3438
|
+
connectionOptions.tls = {
|
|
3439
|
+
clientCertPair: { crt: cert, key }
|
|
3440
|
+
};
|
|
3441
|
+
} else if (apiKey) {
|
|
3442
|
+
console.log("Using API key for secure Temporal");
|
|
3443
|
+
connectionOptions.address = "us-west1.gcp.api.temporal.io:7233";
|
|
3444
|
+
connectionOptions.apiKey = apiKey;
|
|
3445
|
+
connectionOptions.tls = {};
|
|
3446
|
+
connectionOptions.metadata = {
|
|
3447
|
+
"temporal-namespace": namespace
|
|
3448
|
+
};
|
|
3449
|
+
}
|
|
3450
|
+
console.log(`<api> Connecting to Temporal at ${connectionOptions.address}`);
|
|
3451
|
+
const connection = await import_client2.Connection.connect(connectionOptions);
|
|
3452
|
+
const client = new import_client2.Client({ connection, namespace });
|
|
3453
|
+
console.log("<api> Connected to Temporal server");
|
|
3454
|
+
return client;
|
|
3455
|
+
} catch (error) {
|
|
3456
|
+
console.warn(`Failed to connect to Temporal. Is the feature flag enabled?`);
|
|
3457
|
+
console.warn(error);
|
|
3458
|
+
return void 0;
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
var ApiHelpers = {
|
|
3462
|
+
column: (value) => ["Identifier", value],
|
|
3463
|
+
table: (value) => ["Identifier", value]
|
|
3464
|
+
};
|
|
3465
|
+
var ConsumptionHelpers = ApiHelpers;
|
|
3466
|
+
function joinQueries({
|
|
3467
|
+
values,
|
|
3468
|
+
separator = ",",
|
|
3469
|
+
prefix = "",
|
|
3470
|
+
suffix = ""
|
|
3471
|
+
}) {
|
|
3472
|
+
if (values.length === 0) {
|
|
3473
|
+
throw new TypeError(
|
|
3474
|
+
"Expected `join([])` to be called with an array of multiple elements, but got an empty array"
|
|
3475
|
+
);
|
|
3476
|
+
}
|
|
3477
|
+
return new Sql(
|
|
3478
|
+
[prefix, ...Array(values.length - 1).fill(separator), suffix],
|
|
3479
|
+
values
|
|
3480
|
+
);
|
|
3481
|
+
}
|
|
3482
|
+
function getMooseUtilsFromRequest(req) {
|
|
3483
|
+
console.warn(
|
|
3484
|
+
"[DEPRECATED] getMooseUtilsFromRequest() is deprecated. Import getMooseUtils from '@514labs/moose-lib' and call it without parameters: const { client, sql } = await getMooseUtils();"
|
|
3485
|
+
);
|
|
3486
|
+
return req.moose;
|
|
3487
|
+
}
|
|
3488
|
+
var getLegacyMooseUtils = getMooseUtilsFromRequest;
|
|
3489
|
+
function expressMiddleware() {
|
|
3490
|
+
console.warn(
|
|
3491
|
+
"[DEPRECATED] expressMiddleware() is deprecated. Use getMooseUtils() directly or rely on injectMooseUtils config."
|
|
3492
|
+
);
|
|
3493
|
+
return (req, res, next) => {
|
|
3494
|
+
if (!req.moose && req.raw && req.raw.moose) {
|
|
3495
|
+
req.moose = req.raw.moose;
|
|
3496
|
+
}
|
|
3497
|
+
next();
|
|
3498
|
+
};
|
|
3499
|
+
}
|
|
3500
|
+
var instance = null;
|
|
3501
|
+
var initPromise = null;
|
|
3502
|
+
var MooseCache = class _MooseCache {
|
|
3503
|
+
client;
|
|
3504
|
+
isConnected = false;
|
|
3505
|
+
keyPrefix;
|
|
3506
|
+
disconnectTimer = null;
|
|
3507
|
+
idleTimeout;
|
|
3508
|
+
connectPromise = null;
|
|
3509
|
+
constructor() {
|
|
3510
|
+
const redisUrl = process.env.MOOSE_REDIS_CONFIG__URL || "redis://127.0.0.1:6379";
|
|
3511
|
+
const prefix = process.env.MOOSE_REDIS_CONFIG__KEY_PREFIX || "MS";
|
|
3512
|
+
this.idleTimeout = parseInt(process.env.MOOSE_REDIS_CONFIG__IDLE_TIMEOUT || "30", 10) * 1e3;
|
|
3513
|
+
this.keyPrefix = `${prefix}::moosecache::`;
|
|
3514
|
+
this.client = (0, import_redis.createClient)({
|
|
3515
|
+
url: redisUrl
|
|
3516
|
+
});
|
|
3517
|
+
process.on("SIGTERM", this.gracefulShutdown);
|
|
3518
|
+
process.on("SIGINT", this.gracefulShutdown);
|
|
3519
|
+
this.client.on("error", async (err) => {
|
|
3520
|
+
console.error("TS Redis client error:", err);
|
|
3521
|
+
await this.disconnect();
|
|
3522
|
+
});
|
|
3523
|
+
this.client.on("connect", () => {
|
|
3524
|
+
this.isConnected = true;
|
|
3525
|
+
console.log("TS Redis client connected");
|
|
3526
|
+
});
|
|
3527
|
+
this.client.on("end", () => {
|
|
3528
|
+
this.isConnected = false;
|
|
3529
|
+
console.log("TS Redis client disconnected");
|
|
3530
|
+
this.clearDisconnectTimer();
|
|
3531
|
+
});
|
|
3532
|
+
}
|
|
3533
|
+
clearDisconnectTimer() {
|
|
3534
|
+
if (this.disconnectTimer) {
|
|
3535
|
+
clearTimeout(this.disconnectTimer);
|
|
3536
|
+
this.disconnectTimer = null;
|
|
3537
|
+
}
|
|
3538
|
+
}
|
|
3539
|
+
resetDisconnectTimer() {
|
|
3540
|
+
this.clearDisconnectTimer();
|
|
3541
|
+
this.disconnectTimer = setTimeout(async () => {
|
|
3542
|
+
if (this.isConnected) {
|
|
3543
|
+
console.log("TS Redis client disconnecting due to inactivity");
|
|
3544
|
+
await this.disconnect();
|
|
3545
|
+
}
|
|
3546
|
+
}, this.idleTimeout);
|
|
3547
|
+
}
|
|
3548
|
+
async ensureConnected() {
|
|
3549
|
+
if (!this.isConnected) {
|
|
3550
|
+
await this.connect();
|
|
3551
|
+
}
|
|
3552
|
+
this.resetDisconnectTimer();
|
|
3553
|
+
}
|
|
3554
|
+
async connect() {
|
|
3555
|
+
if (this.isConnected) {
|
|
3556
|
+
return;
|
|
3557
|
+
}
|
|
3558
|
+
if (this.connectPromise) {
|
|
3559
|
+
return this.connectPromise;
|
|
3560
|
+
}
|
|
3561
|
+
this.connectPromise = (async () => {
|
|
3562
|
+
try {
|
|
3563
|
+
await this.client.connect();
|
|
3564
|
+
this.resetDisconnectTimer();
|
|
3565
|
+
} catch (error) {
|
|
3566
|
+
this.connectPromise = null;
|
|
3567
|
+
throw error;
|
|
3568
|
+
}
|
|
3569
|
+
})();
|
|
3570
|
+
return this.connectPromise;
|
|
3571
|
+
}
|
|
3572
|
+
async gracefulShutdown() {
|
|
3573
|
+
if (this.isConnected) {
|
|
3574
|
+
await this.disconnect();
|
|
3575
|
+
}
|
|
3576
|
+
process.exit(0);
|
|
3577
|
+
}
|
|
3578
|
+
getPrefixedKey(key) {
|
|
3579
|
+
return `${this.keyPrefix}${key}`;
|
|
3580
|
+
}
|
|
3581
|
+
/**
|
|
3582
|
+
* Gets the singleton instance of MooseCache. Creates a new instance if one doesn't exist.
|
|
3583
|
+
* The client will automatically connect to Redis and handle reconnection if needed.
|
|
3584
|
+
*
|
|
3585
|
+
* @returns Promise<MooseCache> The singleton instance of MooseCache
|
|
3586
|
+
* @example
|
|
3587
|
+
* const cache = await MooseCache.get();
|
|
3588
|
+
*/
|
|
3589
|
+
static async get() {
|
|
3590
|
+
if (instance) {
|
|
3591
|
+
return instance;
|
|
3592
|
+
}
|
|
3593
|
+
if (initPromise) {
|
|
3594
|
+
return initPromise;
|
|
3595
|
+
}
|
|
3596
|
+
initPromise = (async () => {
|
|
3597
|
+
try {
|
|
3598
|
+
const newInstance = new _MooseCache();
|
|
3599
|
+
await newInstance.connect();
|
|
3600
|
+
instance = newInstance;
|
|
3601
|
+
return newInstance;
|
|
3602
|
+
} catch (error) {
|
|
3603
|
+
initPromise = null;
|
|
3604
|
+
throw error;
|
|
3605
|
+
}
|
|
3606
|
+
})();
|
|
3607
|
+
return initPromise;
|
|
3608
|
+
}
|
|
3609
|
+
/**
|
|
3610
|
+
* Sets a value in the cache. Objects are automatically JSON stringified.
|
|
3611
|
+
*
|
|
3612
|
+
* @param key - The key to store the value under
|
|
3613
|
+
* @param value - The value to store. Can be a string or any object (will be JSON stringified)
|
|
3614
|
+
* @param ttlSeconds - Optional time-to-live in seconds. If not provided, defaults to 1 hour (3600 seconds).
|
|
3615
|
+
* Must be a non-negative number. If 0, the key will expire immediately.
|
|
3616
|
+
* @example
|
|
3617
|
+
* // Store a string
|
|
3618
|
+
* await cache.set("foo", "bar");
|
|
3619
|
+
*
|
|
3620
|
+
* // Store an object with custom TTL
|
|
3621
|
+
* await cache.set("foo:config", { baz: 123, qux: true }, 60); // expires in 1 minute
|
|
3622
|
+
*
|
|
3623
|
+
* // This is essentially a get-set, which returns the previous value if it exists.
|
|
3624
|
+
* // You can create logic to only do work for the first time.
|
|
3625
|
+
* const value = await cache.set("testSessionId", "true");
|
|
3626
|
+
* if (value) {
|
|
3627
|
+
* // Cache was set before, return
|
|
3628
|
+
* } else {
|
|
3629
|
+
* // Cache was set for first time, do work
|
|
3630
|
+
* }
|
|
3631
|
+
*/
|
|
3632
|
+
async set(key, value, ttlSeconds) {
|
|
3633
|
+
try {
|
|
3634
|
+
if (ttlSeconds !== void 0 && ttlSeconds < 0) {
|
|
3635
|
+
throw new Error("ttlSeconds must be a non-negative number");
|
|
3636
|
+
}
|
|
3637
|
+
await this.ensureConnected();
|
|
3638
|
+
const prefixedKey = this.getPrefixedKey(key);
|
|
3639
|
+
const stringValue = typeof value === "object" ? JSON.stringify(value) : value;
|
|
3640
|
+
const ttl = ttlSeconds ?? 3600;
|
|
3641
|
+
return await this.client.set(prefixedKey, stringValue, {
|
|
3642
|
+
EX: ttl,
|
|
3643
|
+
GET: true
|
|
3644
|
+
});
|
|
3645
|
+
} catch (error) {
|
|
3646
|
+
console.error(`Error setting cache key ${key}:`, error);
|
|
3647
|
+
throw error;
|
|
3648
|
+
}
|
|
3649
|
+
}
|
|
3650
|
+
/**
|
|
3651
|
+
* Retrieves a value from the cache. Attempts to parse the value as JSON if possible.
|
|
3652
|
+
*
|
|
3653
|
+
* @param key - The key to retrieve
|
|
3654
|
+
* @returns Promise<T | null> The value, parsed as type T if it was JSON, or as string if not. Returns null if key doesn't exist
|
|
3655
|
+
* @example
|
|
3656
|
+
* // Get a string
|
|
3657
|
+
* const value = await cache.get("foo");
|
|
3658
|
+
*
|
|
3659
|
+
* // Get and parse an object with type safety
|
|
3660
|
+
* interface Config { baz: number; qux: boolean; }
|
|
3661
|
+
* const config = await cache.get<Config>("foo:config");
|
|
3662
|
+
*/
|
|
3663
|
+
async get(key) {
|
|
3664
|
+
try {
|
|
3665
|
+
await this.ensureConnected();
|
|
3666
|
+
const prefixedKey = this.getPrefixedKey(key);
|
|
3667
|
+
const value = await this.client.get(prefixedKey);
|
|
3668
|
+
if (value === null) return null;
|
|
3669
|
+
try {
|
|
3670
|
+
const parsed = JSON.parse(value);
|
|
3671
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
3672
|
+
return parsed;
|
|
3673
|
+
}
|
|
3674
|
+
return value;
|
|
3675
|
+
} catch {
|
|
3676
|
+
return value;
|
|
3677
|
+
}
|
|
3678
|
+
} catch (error) {
|
|
3679
|
+
console.error(`Error getting cache key ${key}:`, error);
|
|
3680
|
+
throw error;
|
|
3681
|
+
}
|
|
3682
|
+
}
|
|
3683
|
+
/**
|
|
3684
|
+
* Deletes a specific key from the cache.
|
|
3685
|
+
*
|
|
3686
|
+
* @param key - The key to delete
|
|
3687
|
+
* @example
|
|
3688
|
+
* await cache.delete("foo");
|
|
3689
|
+
*/
|
|
3690
|
+
async delete(key) {
|
|
3691
|
+
try {
|
|
3692
|
+
await this.ensureConnected();
|
|
3693
|
+
const prefixedKey = this.getPrefixedKey(key);
|
|
3694
|
+
await this.client.del(prefixedKey);
|
|
3695
|
+
} catch (error) {
|
|
3696
|
+
console.error(`Error deleting cache key ${key}:`, error);
|
|
3697
|
+
throw error;
|
|
3698
|
+
}
|
|
3699
|
+
}
|
|
3700
|
+
/**
|
|
3701
|
+
* Deletes all keys that start with the given prefix.
|
|
3702
|
+
*
|
|
3703
|
+
* @param keyPrefix - The prefix of keys to delete
|
|
3704
|
+
* @example
|
|
3705
|
+
* // Delete all keys starting with "foo"
|
|
3706
|
+
* await cache.clearKeys("foo");
|
|
3707
|
+
*/
|
|
3708
|
+
async clearKeys(keyPrefix) {
|
|
3709
|
+
try {
|
|
3710
|
+
await this.ensureConnected();
|
|
3711
|
+
const prefixedKey = this.getPrefixedKey(keyPrefix);
|
|
3712
|
+
const keys = await this.client.keys(`${prefixedKey}*`);
|
|
3713
|
+
if (keys.length > 0) {
|
|
3714
|
+
await this.client.del(keys);
|
|
3715
|
+
}
|
|
3716
|
+
} catch (error) {
|
|
3717
|
+
console.error(
|
|
3718
|
+
`Error clearing cache keys with prefix ${keyPrefix}:`,
|
|
3719
|
+
error
|
|
3720
|
+
);
|
|
3721
|
+
throw error;
|
|
3722
|
+
}
|
|
3723
|
+
}
|
|
3724
|
+
/**
|
|
3725
|
+
* Deletes all keys in the cache
|
|
3726
|
+
*
|
|
3727
|
+
* @example
|
|
3728
|
+
* await cache.clear();
|
|
3729
|
+
*/
|
|
3730
|
+
async clear() {
|
|
3731
|
+
try {
|
|
3732
|
+
await this.ensureConnected();
|
|
3733
|
+
const keys = await this.client.keys(`${this.keyPrefix}*`);
|
|
3734
|
+
if (keys.length > 0) {
|
|
3735
|
+
await this.client.del(keys);
|
|
3736
|
+
}
|
|
3737
|
+
} catch (error) {
|
|
3738
|
+
console.error("Error clearing cache:", error);
|
|
3739
|
+
throw error;
|
|
3740
|
+
}
|
|
3741
|
+
}
|
|
3742
|
+
/**
|
|
3743
|
+
* Manually disconnects the Redis client. The client will automatically reconnect
|
|
3744
|
+
* when the next operation is performed.
|
|
3745
|
+
*
|
|
3746
|
+
* @example
|
|
3747
|
+
* await cache.disconnect();
|
|
3748
|
+
*/
|
|
3749
|
+
async disconnect() {
|
|
3750
|
+
this.clearDisconnectTimer();
|
|
3751
|
+
this.connectPromise = null;
|
|
3752
|
+
if (this.isConnected) {
|
|
3753
|
+
await this.client.quit();
|
|
3754
|
+
}
|
|
3755
|
+
}
|
|
3756
|
+
};
|
|
3757
|
+
init_commons();
|
|
3758
|
+
var standaloneUtils = null;
|
|
3759
|
+
var initPromise2 = null;
|
|
3760
|
+
var toClientConfig = (config) => ({
|
|
3761
|
+
...config,
|
|
3762
|
+
useSSL: config.useSSL ? "true" : "false"
|
|
3763
|
+
});
|
|
3764
|
+
async function getMooseUtils(req) {
|
|
3765
|
+
if (req !== void 0) {
|
|
3766
|
+
console.warn(
|
|
3767
|
+
"[DEPRECATED] getMooseUtils(req) no longer requires a request parameter. Use getMooseUtils() instead."
|
|
3768
|
+
);
|
|
3769
|
+
}
|
|
3770
|
+
const runtimeContext = globalThis._mooseRuntimeContext;
|
|
3771
|
+
if (runtimeContext) {
|
|
3772
|
+
return {
|
|
3773
|
+
client: runtimeContext.client,
|
|
3774
|
+
sql,
|
|
3775
|
+
jwt: runtimeContext.jwt
|
|
3776
|
+
};
|
|
3777
|
+
}
|
|
3778
|
+
if (standaloneUtils) {
|
|
3779
|
+
return standaloneUtils;
|
|
3780
|
+
}
|
|
3781
|
+
if (initPromise2) {
|
|
3782
|
+
return initPromise2;
|
|
3783
|
+
}
|
|
3784
|
+
initPromise2 = (async () => {
|
|
3785
|
+
await Promise.resolve().then(() => (init_runtime(), runtime_exports));
|
|
3786
|
+
const configRegistry = globalThis._mooseConfigRegistry;
|
|
3787
|
+
if (!configRegistry) {
|
|
3788
|
+
throw new Error(
|
|
3789
|
+
"Moose not initialized. Ensure you're running within a Moose app or have proper configuration set up."
|
|
3790
|
+
);
|
|
3791
|
+
}
|
|
3792
|
+
const clickhouseConfig = await configRegistry.getStandaloneClickhouseConfig();
|
|
3793
|
+
const clickhouseClient = getClickhouseClient(
|
|
3794
|
+
toClientConfig(clickhouseConfig)
|
|
3795
|
+
);
|
|
3796
|
+
const queryClient = new QueryClient(clickhouseClient, "standalone");
|
|
3797
|
+
const mooseClient = new MooseClient(queryClient);
|
|
3798
|
+
standaloneUtils = {
|
|
3799
|
+
client: mooseClient,
|
|
3800
|
+
sql,
|
|
3801
|
+
jwt: void 0
|
|
3802
|
+
};
|
|
3803
|
+
return standaloneUtils;
|
|
3804
|
+
})();
|
|
3805
|
+
try {
|
|
3806
|
+
return await initPromise2;
|
|
3807
|
+
} finally {
|
|
3808
|
+
initPromise2 = null;
|
|
3809
|
+
}
|
|
3810
|
+
}
|
|
3811
|
+
async function getMooseClients(config) {
|
|
3812
|
+
console.warn(
|
|
3813
|
+
"[DEPRECATED] getMooseClients() is deprecated. Use getMooseUtils() instead."
|
|
3814
|
+
);
|
|
3815
|
+
if (config && Object.keys(config).length > 0) {
|
|
3816
|
+
await Promise.resolve().then(() => (init_runtime(), runtime_exports));
|
|
3817
|
+
const configRegistry = globalThis._mooseConfigRegistry;
|
|
3818
|
+
if (!configRegistry) {
|
|
3819
|
+
throw new Error(
|
|
3820
|
+
"Configuration registry not initialized. Ensure the Moose framework is properly set up."
|
|
3821
|
+
);
|
|
3822
|
+
}
|
|
3823
|
+
const clickhouseConfig = await configRegistry.getStandaloneClickhouseConfig(config);
|
|
3824
|
+
const clickhouseClient = getClickhouseClient(
|
|
3825
|
+
toClientConfig(clickhouseConfig)
|
|
3826
|
+
);
|
|
3827
|
+
const queryClient = new QueryClient(clickhouseClient, "standalone");
|
|
3828
|
+
const mooseClient = new MooseClient(queryClient);
|
|
3829
|
+
return { client: mooseClient };
|
|
3830
|
+
}
|
|
3831
|
+
const utils = await getMooseUtils();
|
|
3832
|
+
return { client: utils.client };
|
|
3833
|
+
}
|
|
3834
|
+
function jsonDateReviver(key, value) {
|
|
3835
|
+
const iso8601Format = /^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)$/;
|
|
3836
|
+
if (typeof value === "string" && iso8601Format.test(value)) {
|
|
3837
|
+
return new Date(value);
|
|
3838
|
+
}
|
|
3839
|
+
return value;
|
|
3840
|
+
}
|
|
3841
|
+
function parseCSV(content2, config) {
|
|
3842
|
+
return new Promise((resolve2, reject) => {
|
|
3843
|
+
const results = [];
|
|
3844
|
+
(0, import_csv_parse.parse)(content2, {
|
|
3845
|
+
delimiter: config.delimiter,
|
|
3846
|
+
columns: config.columns ?? true,
|
|
3847
|
+
skip_empty_lines: config.skipEmptyLines ?? true,
|
|
3848
|
+
trim: config.trim ?? true
|
|
3849
|
+
}).on("data", (row) => {
|
|
3850
|
+
results.push(row);
|
|
3851
|
+
}).on("end", () => {
|
|
3852
|
+
resolve2(results);
|
|
3853
|
+
}).on("error", (error) => {
|
|
3854
|
+
reject(error);
|
|
3855
|
+
});
|
|
3856
|
+
});
|
|
3857
|
+
}
|
|
3858
|
+
function parseJSON(content2, config = {}) {
|
|
3859
|
+
try {
|
|
3860
|
+
const parsed = JSON.parse(content2, config.reviver);
|
|
3861
|
+
if (Array.isArray(parsed)) {
|
|
3862
|
+
return parsed;
|
|
3863
|
+
} else {
|
|
3864
|
+
return [parsed];
|
|
3865
|
+
}
|
|
3866
|
+
} catch (error) {
|
|
3867
|
+
throw new Error(
|
|
3868
|
+
`Failed to parse JSON: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
3869
|
+
);
|
|
3870
|
+
}
|
|
3871
|
+
}
|
|
3872
|
+
function parseJSONWithDates(content2) {
|
|
3873
|
+
return parseJSON(content2, { reviver: jsonDateReviver });
|
|
3874
|
+
}
|
|
3875
|
+
function isValidCSVDelimiter(delimiter) {
|
|
3876
|
+
return delimiter.length === 1 && !/\s/.test(delimiter);
|
|
3877
|
+
}
|
|
3878
|
+
var CSV_DELIMITERS = {
|
|
3879
|
+
COMMA: ",",
|
|
3880
|
+
TAB: " ",
|
|
3881
|
+
SEMICOLON: ";",
|
|
3882
|
+
PIPE: "|"
|
|
3883
|
+
};
|
|
3884
|
+
var DEFAULT_CSV_CONFIG = {
|
|
3885
|
+
delimiter: CSV_DELIMITERS.COMMA,
|
|
3886
|
+
columns: true,
|
|
3887
|
+
skipEmptyLines: true,
|
|
3888
|
+
trim: true
|
|
3889
|
+
};
|
|
3890
|
+
var DEFAULT_JSON_CONFIG = {
|
|
3891
|
+
reviver: jsonDateReviver
|
|
3892
|
+
};
|
|
3893
|
+
var DataSource = class {
|
|
3894
|
+
name;
|
|
3895
|
+
supportsIncremental;
|
|
3896
|
+
constructor(config) {
|
|
3897
|
+
this.name = config.name;
|
|
3898
|
+
this.supportsIncremental = config.supportsIncremental ?? false;
|
|
3899
|
+
}
|
|
3900
|
+
};
|
|
3161
3901
|
|
|
3162
3902
|
// src/index.ts
|
|
3163
3903
|
var _pendingClickHouseConfig = null;
|
|
@@ -3195,9 +3935,11 @@ function configureClickHouse(config) {
|
|
|
3195
3935
|
0 && (module.exports = {
|
|
3196
3936
|
ACKs,
|
|
3197
3937
|
Api,
|
|
3938
|
+
ApiHelpers,
|
|
3198
3939
|
CSV_DELIMITERS,
|
|
3199
3940
|
ClickHouseEngines,
|
|
3200
3941
|
ConsumptionApi,
|
|
3942
|
+
ConsumptionHelpers,
|
|
3201
3943
|
DEFAULT_CSV_CONFIG,
|
|
3202
3944
|
DEFAULT_JSON_CONFIG,
|
|
3203
3945
|
DataSource,
|
|
@@ -3211,7 +3953,10 @@ function configureClickHouse(config) {
|
|
|
3211
3953
|
MAX_RETRY_TIME_MS,
|
|
3212
3954
|
MOOSE_RUNTIME_ENV_PREFIX,
|
|
3213
3955
|
MaterializedView,
|
|
3956
|
+
MooseCache,
|
|
3957
|
+
MooseClient,
|
|
3214
3958
|
OlapTable,
|
|
3959
|
+
QueryClient,
|
|
3215
3960
|
RETRY_FACTOR_PRODUCER,
|
|
3216
3961
|
RETRY_INITIAL_TIME_MS,
|
|
3217
3962
|
Sql,
|
|
@@ -3221,24 +3966,35 @@ function configureClickHouse(config) {
|
|
|
3221
3966
|
View,
|
|
3222
3967
|
WebApp,
|
|
3223
3968
|
Workflow,
|
|
3969
|
+
WorkflowClient,
|
|
3224
3970
|
antiCachePath,
|
|
3225
3971
|
cliLog,
|
|
3226
3972
|
compilerLog,
|
|
3227
3973
|
configureClickHouse,
|
|
3228
3974
|
createClickhouseParameter,
|
|
3975
|
+
createProducerConfig,
|
|
3976
|
+
expressMiddleware,
|
|
3229
3977
|
getApi,
|
|
3230
3978
|
getApis,
|
|
3979
|
+
getClickhouseClient,
|
|
3231
3980
|
getFileName,
|
|
3232
3981
|
getIngestApi,
|
|
3233
3982
|
getIngestApis,
|
|
3983
|
+
getKafkaClient,
|
|
3984
|
+
getKafkaProducer,
|
|
3985
|
+
getLegacyMooseUtils,
|
|
3234
3986
|
getMaterializedView,
|
|
3235
3987
|
getMaterializedViews,
|
|
3988
|
+
getMooseClients,
|
|
3989
|
+
getMooseUtils,
|
|
3990
|
+
getMooseUtilsFromRequest,
|
|
3236
3991
|
getSqlResource,
|
|
3237
3992
|
getSqlResources,
|
|
3238
3993
|
getStream,
|
|
3239
3994
|
getStreams,
|
|
3240
3995
|
getTable,
|
|
3241
3996
|
getTables,
|
|
3997
|
+
getTemporalClient,
|
|
3242
3998
|
getValueFromParameter,
|
|
3243
3999
|
getView,
|
|
3244
4000
|
getViews,
|
|
@@ -3247,6 +4003,7 @@ function configureClickHouse(config) {
|
|
|
3247
4003
|
getWorkflow,
|
|
3248
4004
|
getWorkflows,
|
|
3249
4005
|
isValidCSVDelimiter,
|
|
4006
|
+
joinQueries,
|
|
3250
4007
|
logError,
|
|
3251
4008
|
mapToClickHouseType,
|
|
3252
4009
|
mapTstoJs,
|
|
@@ -3256,6 +4013,7 @@ function configureClickHouse(config) {
|
|
|
3256
4013
|
parseJSON,
|
|
3257
4014
|
parseJSONWithDates,
|
|
3258
4015
|
quoteIdentifier,
|
|
4016
|
+
rewriteImportExtensions,
|
|
3259
4017
|
sql,
|
|
3260
4018
|
toQuery,
|
|
3261
4019
|
toQueryPreview,
|