@bayoudhi/moose-lib-serverless 0.7.2 → 0.7.4
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/browserCompatible.d.ts +12 -0
- package/dist/index-DdE-_e4q.d.ts +2412 -0
- package/dist/index.d.mts +300 -2387
- package/dist/index.d.ts +300 -2387
- 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 -2
package/dist/index.mjs
CHANGED
|
@@ -4,7 +4,13 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __getProtoOf = Object.getPrototypeOf;
|
|
6
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var
|
|
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
|
+
var __commonJS = (cb, mod) => function __require3() {
|
|
8
14
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
9
15
|
};
|
|
10
16
|
var __copyProps = (to, from, except, desc) => {
|
|
@@ -180,9 +186,10 @@ var require_confluent_schema_registry = __commonJS({
|
|
|
180
186
|
}
|
|
181
187
|
});
|
|
182
188
|
|
|
183
|
-
//
|
|
189
|
+
// ../../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
|
|
184
190
|
var import_kafka_javascript = __toESM(require_kafka_javascript(), 1);
|
|
185
191
|
var import_client2 = __toESM(require_client(), 1);
|
|
192
|
+
var import_redis = __toESM(require_redis(), 1);
|
|
186
193
|
import {
|
|
187
194
|
existsSync,
|
|
188
195
|
readdirSync,
|
|
@@ -191,16 +198,27 @@ import {
|
|
|
191
198
|
} from "fs";
|
|
192
199
|
import nodePath from "path";
|
|
193
200
|
import { createClient } from "@clickhouse/client";
|
|
194
|
-
import
|
|
201
|
+
import path3 from "path";
|
|
195
202
|
import * as toml from "toml";
|
|
196
203
|
import process2 from "process";
|
|
197
|
-
|
|
198
|
-
import {
|
|
204
|
+
import * as path2 from "path";
|
|
205
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
206
|
+
import path from "path";
|
|
199
207
|
import { Readable } from "stream";
|
|
208
|
+
import { createHash } from "crypto";
|
|
200
209
|
import { createHash as createHash2 } from "crypto";
|
|
201
|
-
import { createHash as createHash3 } from "crypto";
|
|
210
|
+
import { createHash as createHash3, randomUUID } from "crypto";
|
|
211
|
+
import { performance } from "perf_hooks";
|
|
212
|
+
import * as fs from "fs";
|
|
213
|
+
import { parse as parse2 } from "csv-parse";
|
|
202
214
|
var __defProp2 = Object.defineProperty;
|
|
203
215
|
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
216
|
+
var __require2 = /* @__PURE__ */ ((x) => typeof __require !== "undefined" ? __require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
217
|
+
get: (a, b) => (typeof __require !== "undefined" ? __require : a)[b]
|
|
218
|
+
}) : x)(function(x) {
|
|
219
|
+
if (typeof __require !== "undefined") return __require.apply(this, arguments);
|
|
220
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
221
|
+
});
|
|
204
222
|
var __esm = (fn, res) => function __init() {
|
|
205
223
|
return fn && (res = (0, fn[__getOwnPropNames2(fn)[0]])(fn = 0)), res;
|
|
206
224
|
};
|
|
@@ -268,11 +286,11 @@ function walkDirectory(dir, extensions) {
|
|
|
268
286
|
}
|
|
269
287
|
return results;
|
|
270
288
|
}
|
|
271
|
-
function addJsExtensionToImports(
|
|
289
|
+
function addJsExtensionToImports(content2, fileDir) {
|
|
272
290
|
const fromPattern = /(from\s+['"])(\.\.?\/[^'"]*?)(['"])/g;
|
|
273
291
|
const bareImportPattern = /(import\s+['"])(\.\.?\/[^'"]*?)(['"])/g;
|
|
274
292
|
const dynamicPattern = /(import\s*\(\s*['"])(\.\.?\/[^'"]*?)(['"])/g;
|
|
275
|
-
let result =
|
|
293
|
+
let result = content2;
|
|
276
294
|
result = result.replace(fromPattern, (match, prefix, importPath, quote) => {
|
|
277
295
|
return rewriteImportPath(match, prefix, importPath, quote, fileDir);
|
|
278
296
|
});
|
|
@@ -323,10 +341,10 @@ function rewriteImportPath(match, prefix, importPath, quote, fileDir) {
|
|
|
323
341
|
function rewriteImportExtensions(outDir) {
|
|
324
342
|
const files = walkDirectory(outDir, [".js", ".mjs"]);
|
|
325
343
|
for (const filePath of files) {
|
|
326
|
-
const
|
|
344
|
+
const content2 = readFileSync(filePath, "utf-8");
|
|
327
345
|
const fileDir = nodePath.dirname(filePath);
|
|
328
|
-
const rewritten = addJsExtensionToImports(
|
|
329
|
-
if (
|
|
346
|
+
const rewritten = addJsExtensionToImports(content2, fileDir);
|
|
347
|
+
if (content2 !== rewritten) {
|
|
330
348
|
writeFileSync(filePath, rewritten, "utf-8");
|
|
331
349
|
}
|
|
332
350
|
}
|
|
@@ -378,7 +396,7 @@ var init_commons = __esm({
|
|
|
378
396
|
console.log(message);
|
|
379
397
|
}
|
|
380
398
|
};
|
|
381
|
-
antiCachePath = (
|
|
399
|
+
antiCachePath = (path4) => `${path4}?num=${Math.random().toString()}&time=${Date.now()}`;
|
|
382
400
|
getFileName = (filePath) => {
|
|
383
401
|
const regex = /\/([^\/]+)\.ts/;
|
|
384
402
|
const matches = filePath.match(regex);
|
|
@@ -476,14 +494,14 @@ var init_commons = __esm({
|
|
|
476
494
|
}
|
|
477
495
|
});
|
|
478
496
|
async function findConfigFile(startDir = process.cwd()) {
|
|
479
|
-
const
|
|
480
|
-
let currentDir =
|
|
497
|
+
const fs2 = await import("fs");
|
|
498
|
+
let currentDir = path3.resolve(startDir);
|
|
481
499
|
while (true) {
|
|
482
|
-
const configPath =
|
|
483
|
-
if (
|
|
500
|
+
const configPath = path3.join(currentDir, "moose.config.toml");
|
|
501
|
+
if (fs2.existsSync(configPath)) {
|
|
484
502
|
return configPath;
|
|
485
503
|
}
|
|
486
|
-
const parentDir =
|
|
504
|
+
const parentDir = path3.dirname(currentDir);
|
|
487
505
|
if (parentDir === currentDir) {
|
|
488
506
|
break;
|
|
489
507
|
}
|
|
@@ -492,7 +510,7 @@ async function findConfigFile(startDir = process.cwd()) {
|
|
|
492
510
|
return null;
|
|
493
511
|
}
|
|
494
512
|
async function readProjectConfig() {
|
|
495
|
-
const
|
|
513
|
+
const fs2 = await import("fs");
|
|
496
514
|
const configPath = await findConfigFile();
|
|
497
515
|
if (!configPath) {
|
|
498
516
|
throw new ConfigError(
|
|
@@ -500,7 +518,7 @@ async function readProjectConfig() {
|
|
|
500
518
|
);
|
|
501
519
|
}
|
|
502
520
|
try {
|
|
503
|
-
const configContent =
|
|
521
|
+
const configContent = fs2.readFileSync(configPath, "utf-8");
|
|
504
522
|
const config = toml.parse(configContent);
|
|
505
523
|
return config;
|
|
506
524
|
} catch (error) {
|
|
@@ -791,6 +809,7 @@ var ClickHouseEngines = /* @__PURE__ */ ((ClickHouseEngines2) => {
|
|
|
791
809
|
ClickHouseEngines2["Distributed"] = "Distributed";
|
|
792
810
|
ClickHouseEngines2["IcebergS3"] = "IcebergS3";
|
|
793
811
|
ClickHouseEngines2["Kafka"] = "Kafka";
|
|
812
|
+
ClickHouseEngines2["Merge"] = "Merge";
|
|
794
813
|
ClickHouseEngines2["ReplicatedMergeTree"] = "ReplicatedMergeTree";
|
|
795
814
|
ClickHouseEngines2["ReplicatedReplacingMergeTree"] = "ReplicatedReplacingMergeTree";
|
|
796
815
|
ClickHouseEngines2["ReplicatedAggregatingMergeTree"] = "ReplicatedAggregatingMergeTree";
|
|
@@ -800,50 +819,292 @@ var ClickHouseEngines = /* @__PURE__ */ ((ClickHouseEngines2) => {
|
|
|
800
819
|
return ClickHouseEngines2;
|
|
801
820
|
})(ClickHouseEngines || {});
|
|
802
821
|
init_commons();
|
|
803
|
-
var
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
822
|
+
var MOOSE_COMPILER_PLUGINS = [
|
|
823
|
+
{
|
|
824
|
+
transform: "./node_modules/@514labs/moose-lib/dist/compilerPlugin.js"
|
|
825
|
+
// No longer using transformProgram - direct typia integration eliminates
|
|
826
|
+
// the need for program replacement and the associated incremental compilation issues
|
|
827
|
+
},
|
|
828
|
+
{
|
|
829
|
+
// Keep typia plugin for users who use typia directly (not through Moose resources)
|
|
830
|
+
transform: "typia/lib/transform"
|
|
831
|
+
}
|
|
832
|
+
];
|
|
833
|
+
var MOOSE_COMPILER_OPTIONS = {
|
|
834
|
+
experimentalDecorators: true,
|
|
835
|
+
esModuleInterop: true,
|
|
836
|
+
// Disable strict module syntax checking to avoid dual-package type conflicts
|
|
837
|
+
// This prevents errors where the same type imported with different resolution
|
|
838
|
+
// modes (CJS vs ESM) is treated as incompatible
|
|
839
|
+
verbatimModuleSyntax: false
|
|
840
|
+
};
|
|
841
|
+
var MOOSE_MODULE_OPTIONS = {
|
|
842
|
+
module: "NodeNext",
|
|
843
|
+
moduleResolution: "NodeNext"
|
|
844
|
+
};
|
|
845
|
+
function getSourceDir() {
|
|
846
|
+
return process.env.MOOSE_SOURCE_DIR || "app";
|
|
847
|
+
}
|
|
848
|
+
var DEFAULT_OUT_DIR = ".moose/compiled";
|
|
849
|
+
function readUserOutDir(projectRoot = process.cwd()) {
|
|
850
|
+
try {
|
|
851
|
+
let content = readFileSync2(
|
|
852
|
+
path.join(projectRoot, "tsconfig.json"),
|
|
853
|
+
"utf-8"
|
|
854
|
+
);
|
|
855
|
+
if (content.charCodeAt(0) === 65279) {
|
|
856
|
+
content = content.slice(1);
|
|
831
857
|
}
|
|
832
|
-
const
|
|
833
|
-
|
|
834
|
-
|
|
858
|
+
const tsconfig = eval(`(${content})`);
|
|
859
|
+
return tsconfig.compilerOptions?.outDir || null;
|
|
860
|
+
} catch {
|
|
861
|
+
return null;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
function getOutDir(projectRoot2 = process.cwd()) {
|
|
865
|
+
const userOutDir = readUserOutDir(projectRoot2);
|
|
866
|
+
return userOutDir || DEFAULT_OUT_DIR;
|
|
867
|
+
}
|
|
868
|
+
function getCompiledIndexPath(projectRoot2 = process.cwd()) {
|
|
869
|
+
const outDir = getOutDir(projectRoot2);
|
|
870
|
+
const sourceDir = getSourceDir();
|
|
871
|
+
return path.resolve(projectRoot2, outDir, sourceDir, "index.js");
|
|
872
|
+
}
|
|
873
|
+
function hasCompiledArtifacts(projectRoot2 = process.cwd()) {
|
|
874
|
+
return existsSync2(getCompiledIndexPath(projectRoot2));
|
|
875
|
+
}
|
|
876
|
+
function detectModuleSystem(projectRoot2 = process.cwd()) {
|
|
877
|
+
const pkgPath = path.join(projectRoot2, "package.json");
|
|
878
|
+
if (existsSync2(pkgPath)) {
|
|
879
|
+
try {
|
|
880
|
+
const pkgContent = readFileSync2(pkgPath, "utf-8");
|
|
881
|
+
const pkg = JSON.parse(pkgContent);
|
|
882
|
+
if (pkg.type === "module") {
|
|
883
|
+
return "esm";
|
|
884
|
+
}
|
|
885
|
+
} catch (e) {
|
|
886
|
+
console.debug(
|
|
887
|
+
`[moose] Failed to parse package.json at ${pkgPath}, defaulting to CJS:`,
|
|
888
|
+
e
|
|
889
|
+
);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
return "cjs";
|
|
893
|
+
}
|
|
894
|
+
function getModuleOptions(moduleSystem) {
|
|
895
|
+
if (moduleSystem === "esm") {
|
|
896
|
+
return {
|
|
897
|
+
module: "ES2022",
|
|
898
|
+
moduleResolution: "bundler"
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
return {
|
|
902
|
+
module: "CommonJS",
|
|
903
|
+
moduleResolution: "Node"
|
|
904
|
+
};
|
|
905
|
+
}
|
|
906
|
+
async function loadModule(modulePath, projectRoot2 = process.cwd()) {
|
|
907
|
+
const moduleSystem = detectModuleSystem(projectRoot2);
|
|
908
|
+
if (moduleSystem === "esm") {
|
|
909
|
+
const { pathToFileURL } = await import("url");
|
|
910
|
+
const fileUrl = pathToFileURL(modulePath).href;
|
|
911
|
+
return await import(fileUrl);
|
|
912
|
+
}
|
|
913
|
+
return __require2(modulePath);
|
|
914
|
+
}
|
|
915
|
+
var isClientOnlyMode = () => process2.env.MOOSE_CLIENT_ONLY === "true";
|
|
916
|
+
var moose_internal = {
|
|
917
|
+
tables: /* @__PURE__ */ new Map(),
|
|
918
|
+
streams: /* @__PURE__ */ new Map(),
|
|
919
|
+
ingestApis: /* @__PURE__ */ new Map(),
|
|
920
|
+
apis: /* @__PURE__ */ new Map(),
|
|
921
|
+
sqlResources: /* @__PURE__ */ new Map(),
|
|
922
|
+
workflows: /* @__PURE__ */ new Map(),
|
|
923
|
+
webApps: /* @__PURE__ */ new Map(),
|
|
924
|
+
materializedViews: /* @__PURE__ */ new Map(),
|
|
925
|
+
views: /* @__PURE__ */ new Map()
|
|
926
|
+
};
|
|
927
|
+
var defaultRetentionPeriod = 60 * 60 * 24 * 7;
|
|
928
|
+
var getMooseInternal = () => globalThis.moose_internal;
|
|
929
|
+
if (getMooseInternal() === void 0) {
|
|
930
|
+
globalThis.moose_internal = moose_internal;
|
|
931
|
+
}
|
|
932
|
+
var loadIndex = async () => {
|
|
933
|
+
if (!hasCompiledArtifacts()) {
|
|
934
|
+
const outDir2 = getOutDir();
|
|
935
|
+
const sourceDir = getSourceDir();
|
|
936
|
+
throw new Error(
|
|
937
|
+
`Compiled artifacts not found at ${outDir2}/${sourceDir}/index.js. Run 'npx moose-tspc' to compile your TypeScript first.`
|
|
938
|
+
);
|
|
939
|
+
}
|
|
940
|
+
const registry = getMooseInternal();
|
|
941
|
+
registry.tables.clear();
|
|
942
|
+
registry.streams.clear();
|
|
943
|
+
registry.ingestApis.clear();
|
|
944
|
+
registry.apis.clear();
|
|
945
|
+
registry.sqlResources.clear();
|
|
946
|
+
registry.workflows.clear();
|
|
947
|
+
registry.webApps.clear();
|
|
948
|
+
registry.materializedViews.clear();
|
|
949
|
+
registry.views.clear();
|
|
950
|
+
const outDir = getOutDir();
|
|
951
|
+
const compiledDir = path2.isAbsolute(outDir) ? outDir : path2.join(process2.cwd(), outDir);
|
|
952
|
+
Object.keys(__require2.cache).forEach((key) => {
|
|
953
|
+
if (key.startsWith(compiledDir)) {
|
|
954
|
+
delete __require2.cache[key];
|
|
955
|
+
}
|
|
956
|
+
});
|
|
957
|
+
try {
|
|
958
|
+
const indexPath = getCompiledIndexPath();
|
|
959
|
+
await loadModule(indexPath);
|
|
960
|
+
} catch (error) {
|
|
961
|
+
let hint;
|
|
962
|
+
let includeDetails = true;
|
|
963
|
+
const details = error instanceof Error ? error.message : String(error);
|
|
964
|
+
if (details.includes("no transform has been configured") || details.includes("NoTransformConfigurationError")) {
|
|
965
|
+
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";
|
|
966
|
+
includeDetails = false;
|
|
967
|
+
} else if (details.includes("ERR_REQUIRE_ESM") || details.includes("ES Module")) {
|
|
968
|
+
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";
|
|
969
|
+
}
|
|
970
|
+
if (hint === void 0) {
|
|
971
|
+
throw error;
|
|
835
972
|
} else {
|
|
836
|
-
const
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
973
|
+
const errorMsg = includeDetails ? `${hint}${details}` : hint;
|
|
974
|
+
const cause = error instanceof Error ? error : void 0;
|
|
975
|
+
throw new Error(errorMsg, { cause });
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
};
|
|
979
|
+
var dlqSchema = {
|
|
980
|
+
version: "3.1",
|
|
981
|
+
components: {
|
|
982
|
+
schemas: {
|
|
983
|
+
DeadLetterModel: {
|
|
984
|
+
type: "object",
|
|
985
|
+
properties: {
|
|
986
|
+
originalRecord: {
|
|
987
|
+
$ref: "#/components/schemas/Recordstringany"
|
|
988
|
+
},
|
|
989
|
+
errorMessage: {
|
|
990
|
+
type: "string"
|
|
991
|
+
},
|
|
992
|
+
errorType: {
|
|
993
|
+
type: "string"
|
|
994
|
+
},
|
|
995
|
+
failedAt: {
|
|
996
|
+
type: "string",
|
|
997
|
+
format: "date-time"
|
|
998
|
+
},
|
|
999
|
+
source: {
|
|
1000
|
+
oneOf: [
|
|
1001
|
+
{
|
|
1002
|
+
const: "api"
|
|
1003
|
+
},
|
|
1004
|
+
{
|
|
1005
|
+
const: "transform"
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
const: "table"
|
|
1009
|
+
}
|
|
1010
|
+
]
|
|
1011
|
+
}
|
|
1012
|
+
},
|
|
1013
|
+
required: [
|
|
1014
|
+
"originalRecord",
|
|
1015
|
+
"errorMessage",
|
|
1016
|
+
"errorType",
|
|
1017
|
+
"failedAt",
|
|
1018
|
+
"source"
|
|
1019
|
+
]
|
|
1020
|
+
},
|
|
1021
|
+
Recordstringany: {
|
|
1022
|
+
type: "object",
|
|
1023
|
+
properties: {},
|
|
1024
|
+
required: [],
|
|
1025
|
+
description: "Construct a type with a set of properties K of type T",
|
|
1026
|
+
additionalProperties: {}
|
|
841
1027
|
}
|
|
842
|
-
return value;
|
|
843
1028
|
}
|
|
1029
|
+
},
|
|
1030
|
+
schemas: [
|
|
1031
|
+
{
|
|
1032
|
+
$ref: "#/components/schemas/DeadLetterModel"
|
|
1033
|
+
}
|
|
1034
|
+
]
|
|
1035
|
+
};
|
|
1036
|
+
var dlqColumns = [
|
|
1037
|
+
{
|
|
1038
|
+
name: "originalRecord",
|
|
1039
|
+
data_type: "Json",
|
|
1040
|
+
primary_key: false,
|
|
1041
|
+
required: true,
|
|
1042
|
+
unique: false,
|
|
1043
|
+
default: null,
|
|
1044
|
+
annotations: [],
|
|
1045
|
+
ttl: null,
|
|
1046
|
+
codec: null,
|
|
1047
|
+
materialized: null,
|
|
1048
|
+
comment: null
|
|
1049
|
+
},
|
|
1050
|
+
{
|
|
1051
|
+
name: "errorMessage",
|
|
1052
|
+
data_type: "String",
|
|
1053
|
+
primary_key: false,
|
|
1054
|
+
required: true,
|
|
1055
|
+
unique: false,
|
|
1056
|
+
default: null,
|
|
1057
|
+
annotations: [],
|
|
1058
|
+
ttl: null,
|
|
1059
|
+
codec: null,
|
|
1060
|
+
materialized: null,
|
|
1061
|
+
comment: null
|
|
1062
|
+
},
|
|
1063
|
+
{
|
|
1064
|
+
name: "errorType",
|
|
1065
|
+
data_type: "String",
|
|
1066
|
+
primary_key: false,
|
|
1067
|
+
required: true,
|
|
1068
|
+
unique: false,
|
|
1069
|
+
default: null,
|
|
1070
|
+
annotations: [],
|
|
1071
|
+
ttl: null,
|
|
1072
|
+
codec: null,
|
|
1073
|
+
materialized: null,
|
|
1074
|
+
comment: null
|
|
1075
|
+
},
|
|
1076
|
+
{
|
|
1077
|
+
name: "failedAt",
|
|
1078
|
+
data_type: "DateTime",
|
|
1079
|
+
primary_key: false,
|
|
1080
|
+
required: true,
|
|
1081
|
+
unique: false,
|
|
1082
|
+
default: null,
|
|
1083
|
+
annotations: [],
|
|
1084
|
+
ttl: null,
|
|
1085
|
+
codec: null,
|
|
1086
|
+
materialized: null,
|
|
1087
|
+
comment: null
|
|
1088
|
+
},
|
|
1089
|
+
{
|
|
1090
|
+
name: "source",
|
|
1091
|
+
data_type: "String",
|
|
1092
|
+
primary_key: false,
|
|
1093
|
+
required: true,
|
|
1094
|
+
unique: false,
|
|
1095
|
+
default: null,
|
|
1096
|
+
annotations: [],
|
|
1097
|
+
ttl: null,
|
|
1098
|
+
codec: null,
|
|
1099
|
+
materialized: null,
|
|
1100
|
+
comment: null
|
|
844
1101
|
}
|
|
1102
|
+
];
|
|
1103
|
+
var getWorkflows = async () => {
|
|
1104
|
+
await loadIndex();
|
|
1105
|
+
const registry = getMooseInternal();
|
|
1106
|
+
return registry.workflows;
|
|
845
1107
|
};
|
|
846
|
-
var mooseEnvSecrets = mooseRuntimeEnv;
|
|
847
1108
|
var quoteIdentifier = (name) => {
|
|
848
1109
|
return name.startsWith("`") && name.endsWith("`") ? name : `\`${name}\``;
|
|
849
1110
|
};
|
|
@@ -1014,216 +1275,6 @@ var mapToClickHouseType = (value) => {
|
|
|
1014
1275
|
function emptyIfUndefined(value) {
|
|
1015
1276
|
return value === void 0 ? "" : value;
|
|
1016
1277
|
}
|
|
1017
|
-
init_commons();
|
|
1018
|
-
function jsonDateReviver(key, value) {
|
|
1019
|
-
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)?)?)?)$/;
|
|
1020
|
-
if (typeof value === "string" && iso8601Format.test(value)) {
|
|
1021
|
-
return new Date(value);
|
|
1022
|
-
}
|
|
1023
|
-
return value;
|
|
1024
|
-
}
|
|
1025
|
-
function parseCSV(content, config) {
|
|
1026
|
-
return new Promise((resolve, reject) => {
|
|
1027
|
-
const results = [];
|
|
1028
|
-
parse2(content, {
|
|
1029
|
-
delimiter: config.delimiter,
|
|
1030
|
-
columns: config.columns ?? true,
|
|
1031
|
-
skip_empty_lines: config.skipEmptyLines ?? true,
|
|
1032
|
-
trim: config.trim ?? true
|
|
1033
|
-
}).on("data", (row) => {
|
|
1034
|
-
results.push(row);
|
|
1035
|
-
}).on("end", () => {
|
|
1036
|
-
resolve(results);
|
|
1037
|
-
}).on("error", (error) => {
|
|
1038
|
-
reject(error);
|
|
1039
|
-
});
|
|
1040
|
-
});
|
|
1041
|
-
}
|
|
1042
|
-
function parseJSON(content, config = {}) {
|
|
1043
|
-
try {
|
|
1044
|
-
const parsed = JSON.parse(content, config.reviver);
|
|
1045
|
-
if (Array.isArray(parsed)) {
|
|
1046
|
-
return parsed;
|
|
1047
|
-
} else {
|
|
1048
|
-
return [parsed];
|
|
1049
|
-
}
|
|
1050
|
-
} catch (error) {
|
|
1051
|
-
throw new Error(
|
|
1052
|
-
`Failed to parse JSON: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
1053
|
-
);
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
function parseJSONWithDates(content) {
|
|
1057
|
-
return parseJSON(content, { reviver: jsonDateReviver });
|
|
1058
|
-
}
|
|
1059
|
-
function isValidCSVDelimiter(delimiter) {
|
|
1060
|
-
return delimiter.length === 1 && !/\s/.test(delimiter);
|
|
1061
|
-
}
|
|
1062
|
-
var CSV_DELIMITERS = {
|
|
1063
|
-
COMMA: ",",
|
|
1064
|
-
TAB: " ",
|
|
1065
|
-
SEMICOLON: ";",
|
|
1066
|
-
PIPE: "|"
|
|
1067
|
-
};
|
|
1068
|
-
var DEFAULT_CSV_CONFIG = {
|
|
1069
|
-
delimiter: CSV_DELIMITERS.COMMA,
|
|
1070
|
-
columns: true,
|
|
1071
|
-
skipEmptyLines: true,
|
|
1072
|
-
trim: true
|
|
1073
|
-
};
|
|
1074
|
-
var DEFAULT_JSON_CONFIG = {
|
|
1075
|
-
reviver: jsonDateReviver
|
|
1076
|
-
};
|
|
1077
|
-
var DataSource = class {
|
|
1078
|
-
name;
|
|
1079
|
-
supportsIncremental;
|
|
1080
|
-
constructor(config) {
|
|
1081
|
-
this.name = config.name;
|
|
1082
|
-
this.supportsIncremental = config.supportsIncremental ?? false;
|
|
1083
|
-
}
|
|
1084
|
-
};
|
|
1085
|
-
init_commons();
|
|
1086
|
-
var isClientOnlyMode = () => process2.env.MOOSE_CLIENT_ONLY === "true";
|
|
1087
|
-
var moose_internal = {
|
|
1088
|
-
tables: /* @__PURE__ */ new Map(),
|
|
1089
|
-
streams: /* @__PURE__ */ new Map(),
|
|
1090
|
-
ingestApis: /* @__PURE__ */ new Map(),
|
|
1091
|
-
apis: /* @__PURE__ */ new Map(),
|
|
1092
|
-
sqlResources: /* @__PURE__ */ new Map(),
|
|
1093
|
-
workflows: /* @__PURE__ */ new Map(),
|
|
1094
|
-
webApps: /* @__PURE__ */ new Map(),
|
|
1095
|
-
materializedViews: /* @__PURE__ */ new Map(),
|
|
1096
|
-
views: /* @__PURE__ */ new Map()
|
|
1097
|
-
};
|
|
1098
|
-
var defaultRetentionPeriod = 60 * 60 * 24 * 7;
|
|
1099
|
-
var getMooseInternal = () => globalThis.moose_internal;
|
|
1100
|
-
if (getMooseInternal() === void 0) {
|
|
1101
|
-
globalThis.moose_internal = moose_internal;
|
|
1102
|
-
}
|
|
1103
|
-
var dlqSchema = {
|
|
1104
|
-
version: "3.1",
|
|
1105
|
-
components: {
|
|
1106
|
-
schemas: {
|
|
1107
|
-
DeadLetterModel: {
|
|
1108
|
-
type: "object",
|
|
1109
|
-
properties: {
|
|
1110
|
-
originalRecord: {
|
|
1111
|
-
$ref: "#/components/schemas/Recordstringany"
|
|
1112
|
-
},
|
|
1113
|
-
errorMessage: {
|
|
1114
|
-
type: "string"
|
|
1115
|
-
},
|
|
1116
|
-
errorType: {
|
|
1117
|
-
type: "string"
|
|
1118
|
-
},
|
|
1119
|
-
failedAt: {
|
|
1120
|
-
type: "string",
|
|
1121
|
-
format: "date-time"
|
|
1122
|
-
},
|
|
1123
|
-
source: {
|
|
1124
|
-
oneOf: [
|
|
1125
|
-
{
|
|
1126
|
-
const: "api"
|
|
1127
|
-
},
|
|
1128
|
-
{
|
|
1129
|
-
const: "transform"
|
|
1130
|
-
},
|
|
1131
|
-
{
|
|
1132
|
-
const: "table"
|
|
1133
|
-
}
|
|
1134
|
-
]
|
|
1135
|
-
}
|
|
1136
|
-
},
|
|
1137
|
-
required: [
|
|
1138
|
-
"originalRecord",
|
|
1139
|
-
"errorMessage",
|
|
1140
|
-
"errorType",
|
|
1141
|
-
"failedAt",
|
|
1142
|
-
"source"
|
|
1143
|
-
]
|
|
1144
|
-
},
|
|
1145
|
-
Recordstringany: {
|
|
1146
|
-
type: "object",
|
|
1147
|
-
properties: {},
|
|
1148
|
-
required: [],
|
|
1149
|
-
description: "Construct a type with a set of properties K of type T",
|
|
1150
|
-
additionalProperties: {}
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
},
|
|
1154
|
-
schemas: [
|
|
1155
|
-
{
|
|
1156
|
-
$ref: "#/components/schemas/DeadLetterModel"
|
|
1157
|
-
}
|
|
1158
|
-
]
|
|
1159
|
-
};
|
|
1160
|
-
var dlqColumns = [
|
|
1161
|
-
{
|
|
1162
|
-
name: "originalRecord",
|
|
1163
|
-
data_type: "Json",
|
|
1164
|
-
primary_key: false,
|
|
1165
|
-
required: true,
|
|
1166
|
-
unique: false,
|
|
1167
|
-
default: null,
|
|
1168
|
-
annotations: [],
|
|
1169
|
-
ttl: null,
|
|
1170
|
-
codec: null,
|
|
1171
|
-
materialized: null,
|
|
1172
|
-
comment: null
|
|
1173
|
-
},
|
|
1174
|
-
{
|
|
1175
|
-
name: "errorMessage",
|
|
1176
|
-
data_type: "String",
|
|
1177
|
-
primary_key: false,
|
|
1178
|
-
required: true,
|
|
1179
|
-
unique: false,
|
|
1180
|
-
default: null,
|
|
1181
|
-
annotations: [],
|
|
1182
|
-
ttl: null,
|
|
1183
|
-
codec: null,
|
|
1184
|
-
materialized: null,
|
|
1185
|
-
comment: null
|
|
1186
|
-
},
|
|
1187
|
-
{
|
|
1188
|
-
name: "errorType",
|
|
1189
|
-
data_type: "String",
|
|
1190
|
-
primary_key: false,
|
|
1191
|
-
required: true,
|
|
1192
|
-
unique: false,
|
|
1193
|
-
default: null,
|
|
1194
|
-
annotations: [],
|
|
1195
|
-
ttl: null,
|
|
1196
|
-
codec: null,
|
|
1197
|
-
materialized: null,
|
|
1198
|
-
comment: null
|
|
1199
|
-
},
|
|
1200
|
-
{
|
|
1201
|
-
name: "failedAt",
|
|
1202
|
-
data_type: "DateTime",
|
|
1203
|
-
primary_key: false,
|
|
1204
|
-
required: true,
|
|
1205
|
-
unique: false,
|
|
1206
|
-
default: null,
|
|
1207
|
-
annotations: [],
|
|
1208
|
-
ttl: null,
|
|
1209
|
-
codec: null,
|
|
1210
|
-
materialized: null,
|
|
1211
|
-
comment: null
|
|
1212
|
-
},
|
|
1213
|
-
{
|
|
1214
|
-
name: "source",
|
|
1215
|
-
data_type: "String",
|
|
1216
|
-
primary_key: false,
|
|
1217
|
-
required: true,
|
|
1218
|
-
unique: false,
|
|
1219
|
-
default: null,
|
|
1220
|
-
annotations: [],
|
|
1221
|
-
ttl: null,
|
|
1222
|
-
codec: null,
|
|
1223
|
-
materialized: null,
|
|
1224
|
-
comment: null
|
|
1225
|
-
}
|
|
1226
|
-
];
|
|
1227
1278
|
var OlapTable = class extends TypedBase {
|
|
1228
1279
|
name;
|
|
1229
1280
|
/** @internal */
|
|
@@ -1295,7 +1346,7 @@ var OlapTable = class extends TypedBase {
|
|
|
1295
1346
|
createConfigHash(clickhouseConfig) {
|
|
1296
1347
|
const effectiveDatabase = this.config.database ?? clickhouseConfig.database;
|
|
1297
1348
|
const configString = `${clickhouseConfig.host}:${clickhouseConfig.port}:${clickhouseConfig.username}:${clickhouseConfig.password}:${effectiveDatabase}:${clickhouseConfig.useSSL}`;
|
|
1298
|
-
return
|
|
1349
|
+
return createHash("sha256").update(configString).digest("hex").substring(0, 16);
|
|
1299
1350
|
}
|
|
1300
1351
|
/**
|
|
1301
1352
|
* Gets or creates a memoized ClickHouse client.
|
|
@@ -1985,7 +2036,7 @@ var Stream = class extends TypedBase {
|
|
|
1985
2036
|
kafkaConfig.securityProtocol,
|
|
1986
2037
|
kafkaConfig.namespace
|
|
1987
2038
|
].join(":");
|
|
1988
|
-
return
|
|
2039
|
+
return createHash2("sha256").update(configString).digest("hex").substring(0, 16);
|
|
1989
2040
|
}
|
|
1990
2041
|
/**
|
|
1991
2042
|
* Gets or creates a memoized KafkaJS producer using runtime configuration.
|
|
@@ -2426,22 +2477,22 @@ var Api = class extends TypedBase {
|
|
|
2426
2477
|
return this._handler;
|
|
2427
2478
|
};
|
|
2428
2479
|
async call(baseUrl, queryParams) {
|
|
2429
|
-
let
|
|
2480
|
+
let path4;
|
|
2430
2481
|
if (this.config?.path) {
|
|
2431
2482
|
if (this.config.version) {
|
|
2432
2483
|
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] === "/";
|
|
2433
2484
|
if (pathEndsWithVersion) {
|
|
2434
|
-
|
|
2485
|
+
path4 = this.config.path;
|
|
2435
2486
|
} else {
|
|
2436
|
-
|
|
2487
|
+
path4 = `${this.config.path.replace(/\/$/, "")}/${this.config.version}`;
|
|
2437
2488
|
}
|
|
2438
2489
|
} else {
|
|
2439
|
-
|
|
2490
|
+
path4 = this.config.path;
|
|
2440
2491
|
}
|
|
2441
2492
|
} else {
|
|
2442
|
-
|
|
2493
|
+
path4 = this.config?.version ? `${this.name}/${this.config.version}` : this.name;
|
|
2443
2494
|
}
|
|
2444
|
-
const url = new URL(`${baseUrl.replace(/\/$/, "")}/api/${
|
|
2495
|
+
const url = new URL(`${baseUrl.replace(/\/$/, "")}/api/${path4}`);
|
|
2445
2496
|
const searchParams = url.searchParams;
|
|
2446
2497
|
for (const [key, value] of Object.entries(queryParams)) {
|
|
2447
2498
|
if (Array.isArray(value)) {
|
|
@@ -2500,6 +2551,11 @@ var IngestPipeline = class extends TypedBase {
|
|
|
2500
2551
|
}
|
|
2501
2552
|
}
|
|
2502
2553
|
if (config.table) {
|
|
2554
|
+
if (typeof config.table === "object" && "engine" in config.table && config.table.engine === "Merge") {
|
|
2555
|
+
throw new Error(
|
|
2556
|
+
`IngestPipeline "${name}": Merge engine is read-only and cannot be used as a table destination.`
|
|
2557
|
+
);
|
|
2558
|
+
}
|
|
2503
2559
|
const tableConfig = typeof config.table === "object" ? {
|
|
2504
2560
|
...config.table,
|
|
2505
2561
|
lifeCycle: config.table.lifeCycle ?? config.lifeCycle,
|
|
@@ -2743,6 +2799,8 @@ var MaterializedView = class {
|
|
|
2743
2799
|
sourceTables;
|
|
2744
2800
|
/** Optional metadata for the materialized view */
|
|
2745
2801
|
metadata;
|
|
2802
|
+
/** Optional lifecycle management policy for the materialized view */
|
|
2803
|
+
lifeCycle;
|
|
2746
2804
|
constructor(options, targetSchema, targetColumns) {
|
|
2747
2805
|
let selectStatement = options.selectStatement;
|
|
2748
2806
|
if (typeof selectStatement !== "string") {
|
|
@@ -2776,6 +2834,7 @@ var MaterializedView = class {
|
|
|
2776
2834
|
this.sourceTables = options.selectTables.map(
|
|
2777
2835
|
(t) => formatTableReference(t)
|
|
2778
2836
|
);
|
|
2837
|
+
this.lifeCycle = options.lifeCycle;
|
|
2779
2838
|
this.metadata = options.metadata ? { ...options.metadata } : {};
|
|
2780
2839
|
if (!this.metadata.source) {
|
|
2781
2840
|
const stack = new Error().stack;
|
|
@@ -3084,6 +3143,675 @@ function getView(name) {
|
|
|
3084
3143
|
return getMooseInternal().views.get(name);
|
|
3085
3144
|
}
|
|
3086
3145
|
init_commons();
|
|
3146
|
+
var MOOSE_RUNTIME_ENV_PREFIX = "__MOOSE_RUNTIME_ENV__:";
|
|
3147
|
+
var mooseRuntimeEnv = {
|
|
3148
|
+
/**
|
|
3149
|
+
* Gets a value from an environment variable, with behavior depending on context.
|
|
3150
|
+
*
|
|
3151
|
+
* When IS_LOADING_INFRA_MAP=true (infrastructure loading):
|
|
3152
|
+
* Returns a marker string that Moose CLI will resolve later
|
|
3153
|
+
*
|
|
3154
|
+
* When IS_LOADING_INFRA_MAP is unset (function/workflow runtime):
|
|
3155
|
+
* Returns the actual value from the environment variable
|
|
3156
|
+
*
|
|
3157
|
+
* @param envVarName - Name of the environment variable to resolve
|
|
3158
|
+
* @returns Either a marker string or the actual environment variable value
|
|
3159
|
+
* @throws {Error} If the environment variable name is empty
|
|
3160
|
+
* @throws {Error} If the environment variable is not set (runtime mode only)
|
|
3161
|
+
*
|
|
3162
|
+
* @example
|
|
3163
|
+
* ```typescript
|
|
3164
|
+
* // Instead of this (evaluated at build time):
|
|
3165
|
+
* awsAccessKeyId: process.env.AWS_ACCESS_KEY_ID
|
|
3166
|
+
*
|
|
3167
|
+
* // Use this (evaluated at runtime):
|
|
3168
|
+
* awsAccessKeyId: mooseRuntimeEnv.get("AWS_ACCESS_KEY_ID")
|
|
3169
|
+
* ```
|
|
3170
|
+
*/
|
|
3171
|
+
get(envVarName) {
|
|
3172
|
+
if (!envVarName || envVarName.trim() === "") {
|
|
3173
|
+
throw new Error("Environment variable name cannot be empty");
|
|
3174
|
+
}
|
|
3175
|
+
const isLoadingInfraMap = process.env.IS_LOADING_INFRA_MAP === "true";
|
|
3176
|
+
if (isLoadingInfraMap) {
|
|
3177
|
+
return `${MOOSE_RUNTIME_ENV_PREFIX}${envVarName}`;
|
|
3178
|
+
} else {
|
|
3179
|
+
const value = process.env[envVarName];
|
|
3180
|
+
if (value === void 0) {
|
|
3181
|
+
throw new Error(
|
|
3182
|
+
`Environment variable '${envVarName}' is not set. This is required for runtime execution of functions/workflows.`
|
|
3183
|
+
);
|
|
3184
|
+
}
|
|
3185
|
+
return value;
|
|
3186
|
+
}
|
|
3187
|
+
}
|
|
3188
|
+
};
|
|
3189
|
+
var mooseEnvSecrets = mooseRuntimeEnv;
|
|
3190
|
+
function formatElapsedTime(ms) {
|
|
3191
|
+
if (ms < 1e3) {
|
|
3192
|
+
return `${Math.round(ms)} ms`;
|
|
3193
|
+
}
|
|
3194
|
+
const seconds = ms / 1e3;
|
|
3195
|
+
if (seconds < 60) {
|
|
3196
|
+
return `${seconds.toFixed(2)} seconds`;
|
|
3197
|
+
}
|
|
3198
|
+
const minutes = Math.floor(seconds / 60);
|
|
3199
|
+
const remainingSeconds = seconds % 60;
|
|
3200
|
+
return `${minutes} minutes and ${remainingSeconds.toFixed(2)} seconds`;
|
|
3201
|
+
}
|
|
3202
|
+
var MooseClient = class {
|
|
3203
|
+
query;
|
|
3204
|
+
workflow;
|
|
3205
|
+
constructor(queryClient, temporalClient) {
|
|
3206
|
+
this.query = queryClient;
|
|
3207
|
+
this.workflow = new WorkflowClient(temporalClient);
|
|
3208
|
+
}
|
|
3209
|
+
};
|
|
3210
|
+
var QueryClient = class {
|
|
3211
|
+
client;
|
|
3212
|
+
query_id_prefix;
|
|
3213
|
+
constructor(client, query_id_prefix) {
|
|
3214
|
+
this.client = client;
|
|
3215
|
+
this.query_id_prefix = query_id_prefix;
|
|
3216
|
+
}
|
|
3217
|
+
async execute(sql3) {
|
|
3218
|
+
const [query, query_params] = toQuery(sql3);
|
|
3219
|
+
console.log(`[QueryClient] | Query: ${toQueryPreview(sql3)}`);
|
|
3220
|
+
const start = performance.now();
|
|
3221
|
+
const result = await this.client.query({
|
|
3222
|
+
query,
|
|
3223
|
+
query_params,
|
|
3224
|
+
format: "JSONEachRow",
|
|
3225
|
+
query_id: this.query_id_prefix + randomUUID()
|
|
3226
|
+
// Note: wait_end_of_query deliberately NOT set here as this is used for SELECT queries
|
|
3227
|
+
// where response buffering would harm streaming performance and concurrency
|
|
3228
|
+
});
|
|
3229
|
+
const elapsedMs = performance.now() - start;
|
|
3230
|
+
console.log(
|
|
3231
|
+
`[QueryClient] | Query completed: ${formatElapsedTime(elapsedMs)}`
|
|
3232
|
+
);
|
|
3233
|
+
return result;
|
|
3234
|
+
}
|
|
3235
|
+
async command(sql3) {
|
|
3236
|
+
const [query, query_params] = toQuery(sql3);
|
|
3237
|
+
console.log(`[QueryClient] | Command: ${toQueryPreview(sql3)}`);
|
|
3238
|
+
const start = performance.now();
|
|
3239
|
+
const result = await this.client.command({
|
|
3240
|
+
query,
|
|
3241
|
+
query_params,
|
|
3242
|
+
query_id: this.query_id_prefix + randomUUID()
|
|
3243
|
+
});
|
|
3244
|
+
const elapsedMs = performance.now() - start;
|
|
3245
|
+
console.log(
|
|
3246
|
+
`[QueryClient] | Command completed: ${formatElapsedTime(elapsedMs)}`
|
|
3247
|
+
);
|
|
3248
|
+
return result;
|
|
3249
|
+
}
|
|
3250
|
+
};
|
|
3251
|
+
var WorkflowClient = class {
|
|
3252
|
+
client;
|
|
3253
|
+
constructor(temporalClient) {
|
|
3254
|
+
this.client = temporalClient;
|
|
3255
|
+
}
|
|
3256
|
+
async execute(name, input_data) {
|
|
3257
|
+
try {
|
|
3258
|
+
if (!this.client) {
|
|
3259
|
+
return {
|
|
3260
|
+
status: 404,
|
|
3261
|
+
body: `Temporal client not found. Is the feature flag enabled?`
|
|
3262
|
+
};
|
|
3263
|
+
}
|
|
3264
|
+
const config = await this.getWorkflowConfig(name);
|
|
3265
|
+
const [processedInput, workflowId] = this.processInputData(
|
|
3266
|
+
name,
|
|
3267
|
+
input_data
|
|
3268
|
+
);
|
|
3269
|
+
console.log(
|
|
3270
|
+
`WorkflowClient - starting workflow: ${name} with config ${JSON.stringify(config)} and input_data ${JSON.stringify(processedInput)}`
|
|
3271
|
+
);
|
|
3272
|
+
const handle = await this.client.workflow.start("ScriptWorkflow", {
|
|
3273
|
+
args: [
|
|
3274
|
+
{ workflow_name: name, execution_mode: "start" },
|
|
3275
|
+
processedInput
|
|
3276
|
+
],
|
|
3277
|
+
taskQueue: "typescript-script-queue",
|
|
3278
|
+
workflowId,
|
|
3279
|
+
workflowIdConflictPolicy: "FAIL",
|
|
3280
|
+
workflowIdReusePolicy: "ALLOW_DUPLICATE",
|
|
3281
|
+
retry: {
|
|
3282
|
+
// Temporal's maximumAttempts = total attempts (initial + retries)
|
|
3283
|
+
maximumAttempts: config.retries + 1
|
|
3284
|
+
},
|
|
3285
|
+
workflowRunTimeout: config.timeout
|
|
3286
|
+
});
|
|
3287
|
+
return {
|
|
3288
|
+
status: 200,
|
|
3289
|
+
body: `Workflow started: ${name}. View it in the Temporal dashboard: http://localhost:8080/namespaces/default/workflows/${workflowId}/${handle.firstExecutionRunId}/history`
|
|
3290
|
+
};
|
|
3291
|
+
} catch (error) {
|
|
3292
|
+
return {
|
|
3293
|
+
status: 400,
|
|
3294
|
+
body: `Error starting workflow: ${error}`
|
|
3295
|
+
};
|
|
3296
|
+
}
|
|
3297
|
+
}
|
|
3298
|
+
async terminate(workflowId) {
|
|
3299
|
+
try {
|
|
3300
|
+
if (!this.client) {
|
|
3301
|
+
return {
|
|
3302
|
+
status: 404,
|
|
3303
|
+
body: `Temporal client not found. Is the feature flag enabled?`
|
|
3304
|
+
};
|
|
3305
|
+
}
|
|
3306
|
+
const handle = this.client.workflow.getHandle(workflowId);
|
|
3307
|
+
await handle.terminate();
|
|
3308
|
+
return {
|
|
3309
|
+
status: 200,
|
|
3310
|
+
body: `Workflow terminated: ${workflowId}`
|
|
3311
|
+
};
|
|
3312
|
+
} catch (error) {
|
|
3313
|
+
return {
|
|
3314
|
+
status: 400,
|
|
3315
|
+
body: `Error terminating workflow: ${error}`
|
|
3316
|
+
};
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
async getWorkflowConfig(name) {
|
|
3320
|
+
const workflows = await getWorkflows();
|
|
3321
|
+
const workflow = workflows.get(name);
|
|
3322
|
+
if (workflow) {
|
|
3323
|
+
return {
|
|
3324
|
+
retries: workflow.config.retries || 3,
|
|
3325
|
+
timeout: workflow.config.timeout || "1h"
|
|
3326
|
+
};
|
|
3327
|
+
}
|
|
3328
|
+
throw new Error(`Workflow config not found for ${name}`);
|
|
3329
|
+
}
|
|
3330
|
+
processInputData(name, input_data) {
|
|
3331
|
+
let workflowId = name;
|
|
3332
|
+
if (input_data) {
|
|
3333
|
+
const hash = createHash3("sha256").update(JSON.stringify(input_data)).digest("hex").slice(0, 16);
|
|
3334
|
+
workflowId = `${name}-${hash}`;
|
|
3335
|
+
}
|
|
3336
|
+
return [input_data, workflowId];
|
|
3337
|
+
}
|
|
3338
|
+
};
|
|
3339
|
+
async function getTemporalClient(temporalUrl, namespace, clientCert, clientKey, apiKey) {
|
|
3340
|
+
try {
|
|
3341
|
+
console.info(
|
|
3342
|
+
`<api> Using temporal_url: ${temporalUrl} and namespace: ${namespace}`
|
|
3343
|
+
);
|
|
3344
|
+
let connectionOptions = {
|
|
3345
|
+
address: temporalUrl,
|
|
3346
|
+
connectTimeout: "3s"
|
|
3347
|
+
};
|
|
3348
|
+
if (clientCert && clientKey) {
|
|
3349
|
+
console.log("Using TLS for secure Temporal");
|
|
3350
|
+
const cert = await fs.readFileSync(clientCert);
|
|
3351
|
+
const key = await fs.readFileSync(clientKey);
|
|
3352
|
+
connectionOptions.tls = {
|
|
3353
|
+
clientCertPair: { crt: cert, key }
|
|
3354
|
+
};
|
|
3355
|
+
} else if (apiKey) {
|
|
3356
|
+
console.log("Using API key for secure Temporal");
|
|
3357
|
+
connectionOptions.address = "us-west1.gcp.api.temporal.io:7233";
|
|
3358
|
+
connectionOptions.apiKey = apiKey;
|
|
3359
|
+
connectionOptions.tls = {};
|
|
3360
|
+
connectionOptions.metadata = {
|
|
3361
|
+
"temporal-namespace": namespace
|
|
3362
|
+
};
|
|
3363
|
+
}
|
|
3364
|
+
console.log(`<api> Connecting to Temporal at ${connectionOptions.address}`);
|
|
3365
|
+
const connection = await import_client2.Connection.connect(connectionOptions);
|
|
3366
|
+
const client = new import_client2.Client({ connection, namespace });
|
|
3367
|
+
console.log("<api> Connected to Temporal server");
|
|
3368
|
+
return client;
|
|
3369
|
+
} catch (error) {
|
|
3370
|
+
console.warn(`Failed to connect to Temporal. Is the feature flag enabled?`);
|
|
3371
|
+
console.warn(error);
|
|
3372
|
+
return void 0;
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
var ApiHelpers = {
|
|
3376
|
+
column: (value) => ["Identifier", value],
|
|
3377
|
+
table: (value) => ["Identifier", value]
|
|
3378
|
+
};
|
|
3379
|
+
var ConsumptionHelpers = ApiHelpers;
|
|
3380
|
+
function joinQueries({
|
|
3381
|
+
values,
|
|
3382
|
+
separator = ",",
|
|
3383
|
+
prefix = "",
|
|
3384
|
+
suffix = ""
|
|
3385
|
+
}) {
|
|
3386
|
+
if (values.length === 0) {
|
|
3387
|
+
throw new TypeError(
|
|
3388
|
+
"Expected `join([])` to be called with an array of multiple elements, but got an empty array"
|
|
3389
|
+
);
|
|
3390
|
+
}
|
|
3391
|
+
return new Sql(
|
|
3392
|
+
[prefix, ...Array(values.length - 1).fill(separator), suffix],
|
|
3393
|
+
values
|
|
3394
|
+
);
|
|
3395
|
+
}
|
|
3396
|
+
function getMooseUtilsFromRequest(req) {
|
|
3397
|
+
console.warn(
|
|
3398
|
+
"[DEPRECATED] getMooseUtilsFromRequest() is deprecated. Import getMooseUtils from '@514labs/moose-lib' and call it without parameters: const { client, sql } = await getMooseUtils();"
|
|
3399
|
+
);
|
|
3400
|
+
return req.moose;
|
|
3401
|
+
}
|
|
3402
|
+
var getLegacyMooseUtils = getMooseUtilsFromRequest;
|
|
3403
|
+
function expressMiddleware() {
|
|
3404
|
+
console.warn(
|
|
3405
|
+
"[DEPRECATED] expressMiddleware() is deprecated. Use getMooseUtils() directly or rely on injectMooseUtils config."
|
|
3406
|
+
);
|
|
3407
|
+
return (req, res, next) => {
|
|
3408
|
+
if (!req.moose && req.raw && req.raw.moose) {
|
|
3409
|
+
req.moose = req.raw.moose;
|
|
3410
|
+
}
|
|
3411
|
+
next();
|
|
3412
|
+
};
|
|
3413
|
+
}
|
|
3414
|
+
var instance = null;
|
|
3415
|
+
var initPromise = null;
|
|
3416
|
+
var MooseCache = class _MooseCache {
|
|
3417
|
+
client;
|
|
3418
|
+
isConnected = false;
|
|
3419
|
+
keyPrefix;
|
|
3420
|
+
disconnectTimer = null;
|
|
3421
|
+
idleTimeout;
|
|
3422
|
+
connectPromise = null;
|
|
3423
|
+
constructor() {
|
|
3424
|
+
const redisUrl = process.env.MOOSE_REDIS_CONFIG__URL || "redis://127.0.0.1:6379";
|
|
3425
|
+
const prefix = process.env.MOOSE_REDIS_CONFIG__KEY_PREFIX || "MS";
|
|
3426
|
+
this.idleTimeout = parseInt(process.env.MOOSE_REDIS_CONFIG__IDLE_TIMEOUT || "30", 10) * 1e3;
|
|
3427
|
+
this.keyPrefix = `${prefix}::moosecache::`;
|
|
3428
|
+
this.client = (0, import_redis.createClient)({
|
|
3429
|
+
url: redisUrl
|
|
3430
|
+
});
|
|
3431
|
+
process.on("SIGTERM", this.gracefulShutdown);
|
|
3432
|
+
process.on("SIGINT", this.gracefulShutdown);
|
|
3433
|
+
this.client.on("error", async (err) => {
|
|
3434
|
+
console.error("TS Redis client error:", err);
|
|
3435
|
+
await this.disconnect();
|
|
3436
|
+
});
|
|
3437
|
+
this.client.on("connect", () => {
|
|
3438
|
+
this.isConnected = true;
|
|
3439
|
+
console.log("TS Redis client connected");
|
|
3440
|
+
});
|
|
3441
|
+
this.client.on("end", () => {
|
|
3442
|
+
this.isConnected = false;
|
|
3443
|
+
console.log("TS Redis client disconnected");
|
|
3444
|
+
this.clearDisconnectTimer();
|
|
3445
|
+
});
|
|
3446
|
+
}
|
|
3447
|
+
clearDisconnectTimer() {
|
|
3448
|
+
if (this.disconnectTimer) {
|
|
3449
|
+
clearTimeout(this.disconnectTimer);
|
|
3450
|
+
this.disconnectTimer = null;
|
|
3451
|
+
}
|
|
3452
|
+
}
|
|
3453
|
+
resetDisconnectTimer() {
|
|
3454
|
+
this.clearDisconnectTimer();
|
|
3455
|
+
this.disconnectTimer = setTimeout(async () => {
|
|
3456
|
+
if (this.isConnected) {
|
|
3457
|
+
console.log("TS Redis client disconnecting due to inactivity");
|
|
3458
|
+
await this.disconnect();
|
|
3459
|
+
}
|
|
3460
|
+
}, this.idleTimeout);
|
|
3461
|
+
}
|
|
3462
|
+
async ensureConnected() {
|
|
3463
|
+
if (!this.isConnected) {
|
|
3464
|
+
await this.connect();
|
|
3465
|
+
}
|
|
3466
|
+
this.resetDisconnectTimer();
|
|
3467
|
+
}
|
|
3468
|
+
async connect() {
|
|
3469
|
+
if (this.isConnected) {
|
|
3470
|
+
return;
|
|
3471
|
+
}
|
|
3472
|
+
if (this.connectPromise) {
|
|
3473
|
+
return this.connectPromise;
|
|
3474
|
+
}
|
|
3475
|
+
this.connectPromise = (async () => {
|
|
3476
|
+
try {
|
|
3477
|
+
await this.client.connect();
|
|
3478
|
+
this.resetDisconnectTimer();
|
|
3479
|
+
} catch (error) {
|
|
3480
|
+
this.connectPromise = null;
|
|
3481
|
+
throw error;
|
|
3482
|
+
}
|
|
3483
|
+
})();
|
|
3484
|
+
return this.connectPromise;
|
|
3485
|
+
}
|
|
3486
|
+
async gracefulShutdown() {
|
|
3487
|
+
if (this.isConnected) {
|
|
3488
|
+
await this.disconnect();
|
|
3489
|
+
}
|
|
3490
|
+
process.exit(0);
|
|
3491
|
+
}
|
|
3492
|
+
getPrefixedKey(key) {
|
|
3493
|
+
return `${this.keyPrefix}${key}`;
|
|
3494
|
+
}
|
|
3495
|
+
/**
|
|
3496
|
+
* Gets the singleton instance of MooseCache. Creates a new instance if one doesn't exist.
|
|
3497
|
+
* The client will automatically connect to Redis and handle reconnection if needed.
|
|
3498
|
+
*
|
|
3499
|
+
* @returns Promise<MooseCache> The singleton instance of MooseCache
|
|
3500
|
+
* @example
|
|
3501
|
+
* const cache = await MooseCache.get();
|
|
3502
|
+
*/
|
|
3503
|
+
static async get() {
|
|
3504
|
+
if (instance) {
|
|
3505
|
+
return instance;
|
|
3506
|
+
}
|
|
3507
|
+
if (initPromise) {
|
|
3508
|
+
return initPromise;
|
|
3509
|
+
}
|
|
3510
|
+
initPromise = (async () => {
|
|
3511
|
+
try {
|
|
3512
|
+
const newInstance = new _MooseCache();
|
|
3513
|
+
await newInstance.connect();
|
|
3514
|
+
instance = newInstance;
|
|
3515
|
+
return newInstance;
|
|
3516
|
+
} catch (error) {
|
|
3517
|
+
initPromise = null;
|
|
3518
|
+
throw error;
|
|
3519
|
+
}
|
|
3520
|
+
})();
|
|
3521
|
+
return initPromise;
|
|
3522
|
+
}
|
|
3523
|
+
/**
|
|
3524
|
+
* Sets a value in the cache. Objects are automatically JSON stringified.
|
|
3525
|
+
*
|
|
3526
|
+
* @param key - The key to store the value under
|
|
3527
|
+
* @param value - The value to store. Can be a string or any object (will be JSON stringified)
|
|
3528
|
+
* @param ttlSeconds - Optional time-to-live in seconds. If not provided, defaults to 1 hour (3600 seconds).
|
|
3529
|
+
* Must be a non-negative number. If 0, the key will expire immediately.
|
|
3530
|
+
* @example
|
|
3531
|
+
* // Store a string
|
|
3532
|
+
* await cache.set("foo", "bar");
|
|
3533
|
+
*
|
|
3534
|
+
* // Store an object with custom TTL
|
|
3535
|
+
* await cache.set("foo:config", { baz: 123, qux: true }, 60); // expires in 1 minute
|
|
3536
|
+
*
|
|
3537
|
+
* // This is essentially a get-set, which returns the previous value if it exists.
|
|
3538
|
+
* // You can create logic to only do work for the first time.
|
|
3539
|
+
* const value = await cache.set("testSessionId", "true");
|
|
3540
|
+
* if (value) {
|
|
3541
|
+
* // Cache was set before, return
|
|
3542
|
+
* } else {
|
|
3543
|
+
* // Cache was set for first time, do work
|
|
3544
|
+
* }
|
|
3545
|
+
*/
|
|
3546
|
+
async set(key, value, ttlSeconds) {
|
|
3547
|
+
try {
|
|
3548
|
+
if (ttlSeconds !== void 0 && ttlSeconds < 0) {
|
|
3549
|
+
throw new Error("ttlSeconds must be a non-negative number");
|
|
3550
|
+
}
|
|
3551
|
+
await this.ensureConnected();
|
|
3552
|
+
const prefixedKey = this.getPrefixedKey(key);
|
|
3553
|
+
const stringValue = typeof value === "object" ? JSON.stringify(value) : value;
|
|
3554
|
+
const ttl = ttlSeconds ?? 3600;
|
|
3555
|
+
return await this.client.set(prefixedKey, stringValue, {
|
|
3556
|
+
EX: ttl,
|
|
3557
|
+
GET: true
|
|
3558
|
+
});
|
|
3559
|
+
} catch (error) {
|
|
3560
|
+
console.error(`Error setting cache key ${key}:`, error);
|
|
3561
|
+
throw error;
|
|
3562
|
+
}
|
|
3563
|
+
}
|
|
3564
|
+
/**
|
|
3565
|
+
* Retrieves a value from the cache. Attempts to parse the value as JSON if possible.
|
|
3566
|
+
*
|
|
3567
|
+
* @param key - The key to retrieve
|
|
3568
|
+
* @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
|
|
3569
|
+
* @example
|
|
3570
|
+
* // Get a string
|
|
3571
|
+
* const value = await cache.get("foo");
|
|
3572
|
+
*
|
|
3573
|
+
* // Get and parse an object with type safety
|
|
3574
|
+
* interface Config { baz: number; qux: boolean; }
|
|
3575
|
+
* const config = await cache.get<Config>("foo:config");
|
|
3576
|
+
*/
|
|
3577
|
+
async get(key) {
|
|
3578
|
+
try {
|
|
3579
|
+
await this.ensureConnected();
|
|
3580
|
+
const prefixedKey = this.getPrefixedKey(key);
|
|
3581
|
+
const value = await this.client.get(prefixedKey);
|
|
3582
|
+
if (value === null) return null;
|
|
3583
|
+
try {
|
|
3584
|
+
const parsed = JSON.parse(value);
|
|
3585
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
3586
|
+
return parsed;
|
|
3587
|
+
}
|
|
3588
|
+
return value;
|
|
3589
|
+
} catch {
|
|
3590
|
+
return value;
|
|
3591
|
+
}
|
|
3592
|
+
} catch (error) {
|
|
3593
|
+
console.error(`Error getting cache key ${key}:`, error);
|
|
3594
|
+
throw error;
|
|
3595
|
+
}
|
|
3596
|
+
}
|
|
3597
|
+
/**
|
|
3598
|
+
* Deletes a specific key from the cache.
|
|
3599
|
+
*
|
|
3600
|
+
* @param key - The key to delete
|
|
3601
|
+
* @example
|
|
3602
|
+
* await cache.delete("foo");
|
|
3603
|
+
*/
|
|
3604
|
+
async delete(key) {
|
|
3605
|
+
try {
|
|
3606
|
+
await this.ensureConnected();
|
|
3607
|
+
const prefixedKey = this.getPrefixedKey(key);
|
|
3608
|
+
await this.client.del(prefixedKey);
|
|
3609
|
+
} catch (error) {
|
|
3610
|
+
console.error(`Error deleting cache key ${key}:`, error);
|
|
3611
|
+
throw error;
|
|
3612
|
+
}
|
|
3613
|
+
}
|
|
3614
|
+
/**
|
|
3615
|
+
* Deletes all keys that start with the given prefix.
|
|
3616
|
+
*
|
|
3617
|
+
* @param keyPrefix - The prefix of keys to delete
|
|
3618
|
+
* @example
|
|
3619
|
+
* // Delete all keys starting with "foo"
|
|
3620
|
+
* await cache.clearKeys("foo");
|
|
3621
|
+
*/
|
|
3622
|
+
async clearKeys(keyPrefix) {
|
|
3623
|
+
try {
|
|
3624
|
+
await this.ensureConnected();
|
|
3625
|
+
const prefixedKey = this.getPrefixedKey(keyPrefix);
|
|
3626
|
+
const keys = await this.client.keys(`${prefixedKey}*`);
|
|
3627
|
+
if (keys.length > 0) {
|
|
3628
|
+
await this.client.del(keys);
|
|
3629
|
+
}
|
|
3630
|
+
} catch (error) {
|
|
3631
|
+
console.error(
|
|
3632
|
+
`Error clearing cache keys with prefix ${keyPrefix}:`,
|
|
3633
|
+
error
|
|
3634
|
+
);
|
|
3635
|
+
throw error;
|
|
3636
|
+
}
|
|
3637
|
+
}
|
|
3638
|
+
/**
|
|
3639
|
+
* Deletes all keys in the cache
|
|
3640
|
+
*
|
|
3641
|
+
* @example
|
|
3642
|
+
* await cache.clear();
|
|
3643
|
+
*/
|
|
3644
|
+
async clear() {
|
|
3645
|
+
try {
|
|
3646
|
+
await this.ensureConnected();
|
|
3647
|
+
const keys = await this.client.keys(`${this.keyPrefix}*`);
|
|
3648
|
+
if (keys.length > 0) {
|
|
3649
|
+
await this.client.del(keys);
|
|
3650
|
+
}
|
|
3651
|
+
} catch (error) {
|
|
3652
|
+
console.error("Error clearing cache:", error);
|
|
3653
|
+
throw error;
|
|
3654
|
+
}
|
|
3655
|
+
}
|
|
3656
|
+
/**
|
|
3657
|
+
* Manually disconnects the Redis client. The client will automatically reconnect
|
|
3658
|
+
* when the next operation is performed.
|
|
3659
|
+
*
|
|
3660
|
+
* @example
|
|
3661
|
+
* await cache.disconnect();
|
|
3662
|
+
*/
|
|
3663
|
+
async disconnect() {
|
|
3664
|
+
this.clearDisconnectTimer();
|
|
3665
|
+
this.connectPromise = null;
|
|
3666
|
+
if (this.isConnected) {
|
|
3667
|
+
await this.client.quit();
|
|
3668
|
+
}
|
|
3669
|
+
}
|
|
3670
|
+
};
|
|
3671
|
+
init_commons();
|
|
3672
|
+
var standaloneUtils = null;
|
|
3673
|
+
var initPromise2 = null;
|
|
3674
|
+
var toClientConfig = (config) => ({
|
|
3675
|
+
...config,
|
|
3676
|
+
useSSL: config.useSSL ? "true" : "false"
|
|
3677
|
+
});
|
|
3678
|
+
async function getMooseUtils(req) {
|
|
3679
|
+
if (req !== void 0) {
|
|
3680
|
+
console.warn(
|
|
3681
|
+
"[DEPRECATED] getMooseUtils(req) no longer requires a request parameter. Use getMooseUtils() instead."
|
|
3682
|
+
);
|
|
3683
|
+
}
|
|
3684
|
+
const runtimeContext = globalThis._mooseRuntimeContext;
|
|
3685
|
+
if (runtimeContext) {
|
|
3686
|
+
return {
|
|
3687
|
+
client: runtimeContext.client,
|
|
3688
|
+
sql,
|
|
3689
|
+
jwt: runtimeContext.jwt
|
|
3690
|
+
};
|
|
3691
|
+
}
|
|
3692
|
+
if (standaloneUtils) {
|
|
3693
|
+
return standaloneUtils;
|
|
3694
|
+
}
|
|
3695
|
+
if (initPromise2) {
|
|
3696
|
+
return initPromise2;
|
|
3697
|
+
}
|
|
3698
|
+
initPromise2 = (async () => {
|
|
3699
|
+
await Promise.resolve().then(() => (init_runtime(), runtime_exports));
|
|
3700
|
+
const configRegistry = globalThis._mooseConfigRegistry;
|
|
3701
|
+
if (!configRegistry) {
|
|
3702
|
+
throw new Error(
|
|
3703
|
+
"Moose not initialized. Ensure you're running within a Moose app or have proper configuration set up."
|
|
3704
|
+
);
|
|
3705
|
+
}
|
|
3706
|
+
const clickhouseConfig = await configRegistry.getStandaloneClickhouseConfig();
|
|
3707
|
+
const clickhouseClient = getClickhouseClient(
|
|
3708
|
+
toClientConfig(clickhouseConfig)
|
|
3709
|
+
);
|
|
3710
|
+
const queryClient = new QueryClient(clickhouseClient, "standalone");
|
|
3711
|
+
const mooseClient = new MooseClient(queryClient);
|
|
3712
|
+
standaloneUtils = {
|
|
3713
|
+
client: mooseClient,
|
|
3714
|
+
sql,
|
|
3715
|
+
jwt: void 0
|
|
3716
|
+
};
|
|
3717
|
+
return standaloneUtils;
|
|
3718
|
+
})();
|
|
3719
|
+
try {
|
|
3720
|
+
return await initPromise2;
|
|
3721
|
+
} finally {
|
|
3722
|
+
initPromise2 = null;
|
|
3723
|
+
}
|
|
3724
|
+
}
|
|
3725
|
+
async function getMooseClients(config) {
|
|
3726
|
+
console.warn(
|
|
3727
|
+
"[DEPRECATED] getMooseClients() is deprecated. Use getMooseUtils() instead."
|
|
3728
|
+
);
|
|
3729
|
+
if (config && Object.keys(config).length > 0) {
|
|
3730
|
+
await Promise.resolve().then(() => (init_runtime(), runtime_exports));
|
|
3731
|
+
const configRegistry = globalThis._mooseConfigRegistry;
|
|
3732
|
+
if (!configRegistry) {
|
|
3733
|
+
throw new Error(
|
|
3734
|
+
"Configuration registry not initialized. Ensure the Moose framework is properly set up."
|
|
3735
|
+
);
|
|
3736
|
+
}
|
|
3737
|
+
const clickhouseConfig = await configRegistry.getStandaloneClickhouseConfig(config);
|
|
3738
|
+
const clickhouseClient = getClickhouseClient(
|
|
3739
|
+
toClientConfig(clickhouseConfig)
|
|
3740
|
+
);
|
|
3741
|
+
const queryClient = new QueryClient(clickhouseClient, "standalone");
|
|
3742
|
+
const mooseClient = new MooseClient(queryClient);
|
|
3743
|
+
return { client: mooseClient };
|
|
3744
|
+
}
|
|
3745
|
+
const utils = await getMooseUtils();
|
|
3746
|
+
return { client: utils.client };
|
|
3747
|
+
}
|
|
3748
|
+
function jsonDateReviver(key, value) {
|
|
3749
|
+
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)?)?)?)$/;
|
|
3750
|
+
if (typeof value === "string" && iso8601Format.test(value)) {
|
|
3751
|
+
return new Date(value);
|
|
3752
|
+
}
|
|
3753
|
+
return value;
|
|
3754
|
+
}
|
|
3755
|
+
function parseCSV(content2, config) {
|
|
3756
|
+
return new Promise((resolve2, reject) => {
|
|
3757
|
+
const results = [];
|
|
3758
|
+
parse2(content2, {
|
|
3759
|
+
delimiter: config.delimiter,
|
|
3760
|
+
columns: config.columns ?? true,
|
|
3761
|
+
skip_empty_lines: config.skipEmptyLines ?? true,
|
|
3762
|
+
trim: config.trim ?? true
|
|
3763
|
+
}).on("data", (row) => {
|
|
3764
|
+
results.push(row);
|
|
3765
|
+
}).on("end", () => {
|
|
3766
|
+
resolve2(results);
|
|
3767
|
+
}).on("error", (error) => {
|
|
3768
|
+
reject(error);
|
|
3769
|
+
});
|
|
3770
|
+
});
|
|
3771
|
+
}
|
|
3772
|
+
function parseJSON(content2, config = {}) {
|
|
3773
|
+
try {
|
|
3774
|
+
const parsed = JSON.parse(content2, config.reviver);
|
|
3775
|
+
if (Array.isArray(parsed)) {
|
|
3776
|
+
return parsed;
|
|
3777
|
+
} else {
|
|
3778
|
+
return [parsed];
|
|
3779
|
+
}
|
|
3780
|
+
} catch (error) {
|
|
3781
|
+
throw new Error(
|
|
3782
|
+
`Failed to parse JSON: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
3783
|
+
);
|
|
3784
|
+
}
|
|
3785
|
+
}
|
|
3786
|
+
function parseJSONWithDates(content2) {
|
|
3787
|
+
return parseJSON(content2, { reviver: jsonDateReviver });
|
|
3788
|
+
}
|
|
3789
|
+
function isValidCSVDelimiter(delimiter) {
|
|
3790
|
+
return delimiter.length === 1 && !/\s/.test(delimiter);
|
|
3791
|
+
}
|
|
3792
|
+
var CSV_DELIMITERS = {
|
|
3793
|
+
COMMA: ",",
|
|
3794
|
+
TAB: " ",
|
|
3795
|
+
SEMICOLON: ";",
|
|
3796
|
+
PIPE: "|"
|
|
3797
|
+
};
|
|
3798
|
+
var DEFAULT_CSV_CONFIG = {
|
|
3799
|
+
delimiter: CSV_DELIMITERS.COMMA,
|
|
3800
|
+
columns: true,
|
|
3801
|
+
skipEmptyLines: true,
|
|
3802
|
+
trim: true
|
|
3803
|
+
};
|
|
3804
|
+
var DEFAULT_JSON_CONFIG = {
|
|
3805
|
+
reviver: jsonDateReviver
|
|
3806
|
+
};
|
|
3807
|
+
var DataSource = class {
|
|
3808
|
+
name;
|
|
3809
|
+
supportsIncremental;
|
|
3810
|
+
constructor(config) {
|
|
3811
|
+
this.name = config.name;
|
|
3812
|
+
this.supportsIncremental = config.supportsIncremental ?? false;
|
|
3813
|
+
}
|
|
3814
|
+
};
|
|
3087
3815
|
|
|
3088
3816
|
// src/index.ts
|
|
3089
3817
|
var _pendingClickHouseConfig = null;
|
|
@@ -3120,9 +3848,11 @@ function configureClickHouse(config) {
|
|
|
3120
3848
|
export {
|
|
3121
3849
|
ACKs,
|
|
3122
3850
|
Api,
|
|
3851
|
+
ApiHelpers,
|
|
3123
3852
|
CSV_DELIMITERS,
|
|
3124
3853
|
ClickHouseEngines,
|
|
3125
3854
|
ConsumptionApi,
|
|
3855
|
+
ConsumptionHelpers,
|
|
3126
3856
|
DEFAULT_CSV_CONFIG,
|
|
3127
3857
|
DEFAULT_JSON_CONFIG,
|
|
3128
3858
|
DataSource,
|
|
@@ -3136,7 +3866,10 @@ export {
|
|
|
3136
3866
|
MAX_RETRY_TIME_MS,
|
|
3137
3867
|
MOOSE_RUNTIME_ENV_PREFIX,
|
|
3138
3868
|
MaterializedView,
|
|
3869
|
+
MooseCache,
|
|
3870
|
+
MooseClient,
|
|
3139
3871
|
OlapTable,
|
|
3872
|
+
QueryClient,
|
|
3140
3873
|
RETRY_FACTOR_PRODUCER,
|
|
3141
3874
|
RETRY_INITIAL_TIME_MS,
|
|
3142
3875
|
Sql,
|
|
@@ -3146,24 +3879,35 @@ export {
|
|
|
3146
3879
|
View,
|
|
3147
3880
|
WebApp,
|
|
3148
3881
|
Workflow,
|
|
3882
|
+
WorkflowClient,
|
|
3149
3883
|
antiCachePath,
|
|
3150
3884
|
cliLog,
|
|
3151
3885
|
compilerLog,
|
|
3152
3886
|
configureClickHouse,
|
|
3153
3887
|
createClickhouseParameter,
|
|
3888
|
+
createProducerConfig,
|
|
3889
|
+
expressMiddleware,
|
|
3154
3890
|
getApi,
|
|
3155
3891
|
getApis,
|
|
3892
|
+
getClickhouseClient,
|
|
3156
3893
|
getFileName,
|
|
3157
3894
|
getIngestApi,
|
|
3158
3895
|
getIngestApis,
|
|
3896
|
+
getKafkaClient,
|
|
3897
|
+
getKafkaProducer,
|
|
3898
|
+
getLegacyMooseUtils,
|
|
3159
3899
|
getMaterializedView,
|
|
3160
3900
|
getMaterializedViews,
|
|
3901
|
+
getMooseClients,
|
|
3902
|
+
getMooseUtils,
|
|
3903
|
+
getMooseUtilsFromRequest,
|
|
3161
3904
|
getSqlResource,
|
|
3162
3905
|
getSqlResources,
|
|
3163
3906
|
getStream,
|
|
3164
3907
|
getStreams,
|
|
3165
3908
|
getTable,
|
|
3166
3909
|
getTables,
|
|
3910
|
+
getTemporalClient,
|
|
3167
3911
|
getValueFromParameter,
|
|
3168
3912
|
getView,
|
|
3169
3913
|
getViews,
|
|
@@ -3172,6 +3916,7 @@ export {
|
|
|
3172
3916
|
getWorkflow,
|
|
3173
3917
|
getWorkflows2 as getWorkflows,
|
|
3174
3918
|
isValidCSVDelimiter,
|
|
3919
|
+
joinQueries,
|
|
3175
3920
|
logError,
|
|
3176
3921
|
mapToClickHouseType,
|
|
3177
3922
|
mapTstoJs,
|
|
@@ -3181,6 +3926,7 @@ export {
|
|
|
3181
3926
|
parseJSON,
|
|
3182
3927
|
parseJSONWithDates,
|
|
3183
3928
|
quoteIdentifier,
|
|
3929
|
+
rewriteImportExtensions,
|
|
3184
3930
|
sql,
|
|
3185
3931
|
toQuery,
|
|
3186
3932
|
toQueryPreview,
|