@514labs/moose-lib 0.6.514 → 0.6.515

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -629,6 +629,260 @@ import process3 from "process";
629
629
  import * as path4 from "path";
630
630
  init_commons();
631
631
 
632
+ // src/sqlHelpers.ts
633
+ var quoteIdentifier = (name) => {
634
+ return name.startsWith("`") && name.endsWith("`") ? name : `\`${name}\``;
635
+ };
636
+ var isTable = (value) => typeof value === "object" && value !== null && "kind" in value && value.kind === "OlapTable";
637
+ var isView = (value) => typeof value === "object" && value !== null && "kind" in value && value.kind === "View";
638
+ var isColumn = (value) => typeof value === "object" && value !== null && !("kind" in value) && "name" in value && "annotations" in value;
639
+ function sqlImpl(strings, ...values) {
640
+ return new Sql(strings, values);
641
+ }
642
+ var sql = sqlImpl;
643
+ sql.statement = function(strings, ...values) {
644
+ return new Sql(strings, values, false);
645
+ };
646
+ sql.fragment = function(strings, ...values) {
647
+ return new Sql(strings, values, true);
648
+ };
649
+ var instanceofSql = (value) => typeof value === "object" && "values" in value && "strings" in value;
650
+ var Sql = class _Sql {
651
+ values;
652
+ strings;
653
+ isFragment;
654
+ constructor(rawStrings, rawValues, isFragment) {
655
+ if (rawStrings.length - 1 !== rawValues.length) {
656
+ if (rawStrings.length === 0) {
657
+ throw new TypeError("Expected at least 1 string");
658
+ }
659
+ throw new TypeError(
660
+ `Expected ${rawStrings.length} strings to have ${rawStrings.length - 1} values`
661
+ );
662
+ }
663
+ const valuesLength = rawValues.reduce(
664
+ (len, value) => len + (instanceofSql(value) ? value.values.length : isColumn(value) || isTable(value) || isView(value) ? 0 : 1),
665
+ 0
666
+ );
667
+ this.values = new Array(valuesLength);
668
+ this.strings = new Array(valuesLength + 1);
669
+ this.isFragment = isFragment;
670
+ this.strings[0] = rawStrings[0];
671
+ let i = 0, pos = 0;
672
+ while (i < rawValues.length) {
673
+ const child = rawValues[i++];
674
+ const rawString = rawStrings[i];
675
+ if (instanceofSql(child)) {
676
+ this.strings[pos] += child.strings[0];
677
+ let childIndex = 0;
678
+ while (childIndex < child.values.length) {
679
+ this.values[pos++] = child.values[childIndex++];
680
+ this.strings[pos] = child.strings[childIndex];
681
+ }
682
+ this.strings[pos] += rawString;
683
+ } else if (isColumn(child)) {
684
+ const aggregationFunction = child.annotations.find(
685
+ ([k, _]) => k === "aggregationFunction"
686
+ );
687
+ if (aggregationFunction !== void 0) {
688
+ const funcName = aggregationFunction[1].functionName;
689
+ const parenIdx = funcName.indexOf("(");
690
+ const mergedName = parenIdx !== -1 ? `${funcName.slice(0, parenIdx)}Merge${funcName.slice(parenIdx)}` : `${funcName}Merge`;
691
+ this.strings[pos] += `${mergedName}(\`${child.name}\`)`;
692
+ } else {
693
+ this.strings[pos] += `\`${child.name}\``;
694
+ }
695
+ this.strings[pos] += rawString;
696
+ } else if (isTable(child)) {
697
+ const deployedName = child.generateTableName();
698
+ if (child.config.database) {
699
+ this.strings[pos] += `\`${child.config.database}\`.\`${deployedName}\``;
700
+ } else {
701
+ this.strings[pos] += `\`${deployedName}\``;
702
+ }
703
+ this.strings[pos] += rawString;
704
+ } else if (isView(child)) {
705
+ if (child.database) {
706
+ this.strings[pos] += `\`${child.database}\`.\`${child.name}\``;
707
+ } else {
708
+ this.strings[pos] += `\`${child.name}\``;
709
+ }
710
+ this.strings[pos] += rawString;
711
+ } else {
712
+ this.values[pos++] = child;
713
+ this.strings[pos] = rawString;
714
+ }
715
+ }
716
+ }
717
+ /**
718
+ * Append another Sql fragment, returning a new Sql instance.
719
+ */
720
+ append(other) {
721
+ return new _Sql(
722
+ [...this.strings, ""],
723
+ [...this.values, other],
724
+ this.isFragment
725
+ );
726
+ }
727
+ };
728
+ sql.join = function(fragments, separator) {
729
+ if (fragments.length === 0) return new Sql([""], [], true);
730
+ if (fragments.length === 1) {
731
+ const frag = fragments[0];
732
+ return new Sql(frag.strings, frag.values, true);
733
+ }
734
+ const sep = separator ?? ", ";
735
+ const normalized = sep.includes(" ") ? sep : ` ${sep} `;
736
+ const strings = ["", ...Array(fragments.length - 1).fill(normalized), ""];
737
+ return new Sql(strings, fragments, true);
738
+ };
739
+ sql.raw = function(text) {
740
+ return new Sql([text], [], true);
741
+ };
742
+ var toStaticQuery = (sql3) => {
743
+ const [query, params] = toQuery(sql3);
744
+ if (Object.keys(params).length !== 0) {
745
+ throw new Error(
746
+ "Dynamic SQL is not allowed in the select statement in view creation."
747
+ );
748
+ }
749
+ return query;
750
+ };
751
+ var toQuery = (sql3) => {
752
+ const parameterizedStubs = sql3.values.map(
753
+ (v, i) => createClickhouseParameter(i, v)
754
+ );
755
+ const query = sql3.strings.map(
756
+ (s, i) => s != "" ? `${s}${emptyIfUndefined(parameterizedStubs[i])}` : ""
757
+ ).join("");
758
+ const query_params = sql3.values.reduce(
759
+ (acc, v, i) => ({
760
+ ...acc,
761
+ [`p${i}`]: getValueFromParameter(v)
762
+ }),
763
+ {}
764
+ );
765
+ return [query, query_params];
766
+ };
767
+ var toQueryPreview = (sql3) => {
768
+ try {
769
+ const formatValue = (v) => {
770
+ if (Array.isArray(v)) {
771
+ const [type, val] = v;
772
+ if (type === "Identifier") {
773
+ return `\`${String(val)}\``;
774
+ }
775
+ return `[${v.map((x) => formatValue(x)).join(", ")}]`;
776
+ }
777
+ if (v === null || v === void 0) return "NULL";
778
+ if (typeof v === "string") return `'${v.replace(/'/g, "''")}'`;
779
+ if (typeof v === "number") return String(v);
780
+ if (typeof v === "boolean") return v ? "true" : "false";
781
+ if (v instanceof Date)
782
+ return `'${v.toISOString().replace("T", " ").slice(0, 19)}'`;
783
+ try {
784
+ return JSON.stringify(v);
785
+ } catch {
786
+ return String(v);
787
+ }
788
+ };
789
+ let out = sql3.strings[0] ?? "";
790
+ for (let i = 0; i < sql3.values.length; i++) {
791
+ const val = getValueFromParameter(sql3.values[i]);
792
+ out += formatValue(val);
793
+ out += sql3.strings[i + 1] ?? "";
794
+ }
795
+ return out.replace(/\s+/g, " ").trim();
796
+ } catch (error) {
797
+ console.log(`toQueryPreview error: ${error}`);
798
+ return "/* query preview unavailable */";
799
+ }
800
+ };
801
+ var getValueFromParameter = (value) => {
802
+ if (Array.isArray(value)) {
803
+ const [type, val] = value;
804
+ if (type === "Identifier") return val;
805
+ }
806
+ return value;
807
+ };
808
+ function createClickhouseParameter(parameterIndex, value) {
809
+ return `{p${parameterIndex}:${mapToClickHouseType(value)}}`;
810
+ }
811
+ var mapToClickHouseType = (value) => {
812
+ if (typeof value === "number") {
813
+ return Number.isInteger(value) ? "Int" : "Float";
814
+ }
815
+ if (typeof value === "boolean") return "Bool";
816
+ if (value instanceof Date) return "DateTime";
817
+ if (Array.isArray(value)) {
818
+ const [type, _] = value;
819
+ return type;
820
+ }
821
+ return "String";
822
+ };
823
+ function emptyIfUndefined(value) {
824
+ return value === void 0 ? "" : value;
825
+ }
826
+
827
+ // src/dmv2/sdk/tableReferenceUtils.ts
828
+ function formatTableReference(table) {
829
+ const database = table instanceof OlapTable ? table.config.database : table.database;
830
+ const deployedName = table instanceof OlapTable ? table.generateTableName() : table.name;
831
+ if (database) {
832
+ return `\`${database}\`.\`${deployedName}\``;
833
+ }
834
+ return `\`${deployedName}\``;
835
+ }
836
+
837
+ // src/dmv2/sdk/view.ts
838
+ function viewRegistryKey(database, name) {
839
+ return database ? `${database}::${name}` : name;
840
+ }
841
+ var View = class {
842
+ /** @internal */
843
+ kind = "View";
844
+ /** The name of the view */
845
+ name;
846
+ /** Optional database where the view is created. When set, the view is created as `database`.`name` in ClickHouse. */
847
+ database;
848
+ /** The SELECT SQL statement that defines the view */
849
+ selectSql;
850
+ /** Names of source tables/views that the SELECT reads from */
851
+ sourceTables;
852
+ /** Optional metadata for the view */
853
+ metadata;
854
+ constructor(name, configOrSelectStatement, baseTables, metadata) {
855
+ const config = typeof configOrSelectStatement === "object" && configOrSelectStatement !== null && "selectStatement" in configOrSelectStatement && "baseTables" in configOrSelectStatement ? configOrSelectStatement : {
856
+ selectStatement: configOrSelectStatement,
857
+ baseTables: baseTables ?? [],
858
+ metadata
859
+ };
860
+ let selectStatement = config.selectStatement;
861
+ if (typeof selectStatement !== "string") {
862
+ selectStatement = toStaticQuery(selectStatement);
863
+ }
864
+ this.name = name;
865
+ this.database = config.database;
866
+ this.selectSql = selectStatement;
867
+ this.sourceTables = config.baseTables.map((t) => formatTableReference(t));
868
+ this.metadata = config.metadata ? { ...config.metadata } : {};
869
+ if (!this.metadata.source) {
870
+ const stack = new Error().stack;
871
+ const sourceInfo = getSourceFileFromStack(stack);
872
+ if (sourceInfo) {
873
+ this.metadata.source = { file: sourceInfo };
874
+ }
875
+ }
876
+ const views = getMooseInternal().views;
877
+ const registryKey = viewRegistryKey(this.database, this.name);
878
+ if (!isClientOnlyMode() && views.has(registryKey)) {
879
+ const qualifiedName = this.database ? `${this.database}.${this.name}` : this.name;
880
+ throw new Error(`View with name ${qualifiedName} already exists`);
881
+ }
882
+ views.set(registryKey, this);
883
+ }
884
+ };
885
+
632
886
  // src/compiler-config.ts
633
887
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
634
888
  import path from "path";
@@ -1034,199 +1288,6 @@ var getWorkflows = async () => {
1034
1288
  // src/dmv2/sdk/olapTable.ts
1035
1289
  import { Readable } from "stream";
1036
1290
  import { createHash } from "crypto";
1037
-
1038
- // src/sqlHelpers.ts
1039
- var quoteIdentifier = (name) => {
1040
- return name.startsWith("`") && name.endsWith("`") ? name : `\`${name}\``;
1041
- };
1042
- var isTable = (value) => typeof value === "object" && value !== null && "kind" in value && value.kind === "OlapTable";
1043
- var isView = (value) => typeof value === "object" && value !== null && "kind" in value && value.kind === "View";
1044
- var isColumn = (value) => typeof value === "object" && value !== null && !("kind" in value) && "name" in value && "annotations" in value;
1045
- function sqlImpl(strings, ...values) {
1046
- return new Sql(strings, values);
1047
- }
1048
- var sql = sqlImpl;
1049
- sql.statement = function(strings, ...values) {
1050
- return new Sql(strings, values, false);
1051
- };
1052
- sql.fragment = function(strings, ...values) {
1053
- return new Sql(strings, values, true);
1054
- };
1055
- var instanceofSql = (value) => typeof value === "object" && "values" in value && "strings" in value;
1056
- var Sql = class _Sql {
1057
- values;
1058
- strings;
1059
- isFragment;
1060
- constructor(rawStrings, rawValues, isFragment) {
1061
- if (rawStrings.length - 1 !== rawValues.length) {
1062
- if (rawStrings.length === 0) {
1063
- throw new TypeError("Expected at least 1 string");
1064
- }
1065
- throw new TypeError(
1066
- `Expected ${rawStrings.length} strings to have ${rawStrings.length - 1} values`
1067
- );
1068
- }
1069
- const valuesLength = rawValues.reduce(
1070
- (len, value) => len + (instanceofSql(value) ? value.values.length : isColumn(value) || isTable(value) || isView(value) ? 0 : 1),
1071
- 0
1072
- );
1073
- this.values = new Array(valuesLength);
1074
- this.strings = new Array(valuesLength + 1);
1075
- this.isFragment = isFragment;
1076
- this.strings[0] = rawStrings[0];
1077
- let i = 0, pos = 0;
1078
- while (i < rawValues.length) {
1079
- const child = rawValues[i++];
1080
- const rawString = rawStrings[i];
1081
- if (instanceofSql(child)) {
1082
- this.strings[pos] += child.strings[0];
1083
- let childIndex = 0;
1084
- while (childIndex < child.values.length) {
1085
- this.values[pos++] = child.values[childIndex++];
1086
- this.strings[pos] = child.strings[childIndex];
1087
- }
1088
- this.strings[pos] += rawString;
1089
- } else if (isColumn(child)) {
1090
- const aggregationFunction = child.annotations.find(
1091
- ([k, _]) => k === "aggregationFunction"
1092
- );
1093
- if (aggregationFunction !== void 0) {
1094
- const funcName = aggregationFunction[1].functionName;
1095
- const parenIdx = funcName.indexOf("(");
1096
- const mergedName = parenIdx !== -1 ? `${funcName.slice(0, parenIdx)}Merge${funcName.slice(parenIdx)}` : `${funcName}Merge`;
1097
- this.strings[pos] += `${mergedName}(\`${child.name}\`)`;
1098
- } else {
1099
- this.strings[pos] += `\`${child.name}\``;
1100
- }
1101
- this.strings[pos] += rawString;
1102
- } else if (isTable(child)) {
1103
- const deployedName = child.generateTableName();
1104
- if (child.config.database) {
1105
- this.strings[pos] += `\`${child.config.database}\`.\`${deployedName}\``;
1106
- } else {
1107
- this.strings[pos] += `\`${deployedName}\``;
1108
- }
1109
- this.strings[pos] += rawString;
1110
- } else if (isView(child)) {
1111
- this.strings[pos] += `\`${child.name}\``;
1112
- this.strings[pos] += rawString;
1113
- } else {
1114
- this.values[pos++] = child;
1115
- this.strings[pos] = rawString;
1116
- }
1117
- }
1118
- }
1119
- /**
1120
- * Append another Sql fragment, returning a new Sql instance.
1121
- */
1122
- append(other) {
1123
- return new _Sql(
1124
- [...this.strings, ""],
1125
- [...this.values, other],
1126
- this.isFragment
1127
- );
1128
- }
1129
- };
1130
- sql.join = function(fragments, separator) {
1131
- if (fragments.length === 0) return new Sql([""], [], true);
1132
- if (fragments.length === 1) {
1133
- const frag = fragments[0];
1134
- return new Sql(frag.strings, frag.values, true);
1135
- }
1136
- const sep = separator ?? ", ";
1137
- const normalized = sep.includes(" ") ? sep : ` ${sep} `;
1138
- const strings = ["", ...Array(fragments.length - 1).fill(normalized), ""];
1139
- return new Sql(strings, fragments, true);
1140
- };
1141
- sql.raw = function(text) {
1142
- return new Sql([text], [], true);
1143
- };
1144
- var toStaticQuery = (sql3) => {
1145
- const [query, params] = toQuery(sql3);
1146
- if (Object.keys(params).length !== 0) {
1147
- throw new Error(
1148
- "Dynamic SQL is not allowed in the select statement in view creation."
1149
- );
1150
- }
1151
- return query;
1152
- };
1153
- var toQuery = (sql3) => {
1154
- const parameterizedStubs = sql3.values.map(
1155
- (v, i) => createClickhouseParameter(i, v)
1156
- );
1157
- const query = sql3.strings.map(
1158
- (s, i) => s != "" ? `${s}${emptyIfUndefined(parameterizedStubs[i])}` : ""
1159
- ).join("");
1160
- const query_params = sql3.values.reduce(
1161
- (acc, v, i) => ({
1162
- ...acc,
1163
- [`p${i}`]: getValueFromParameter(v)
1164
- }),
1165
- {}
1166
- );
1167
- return [query, query_params];
1168
- };
1169
- var toQueryPreview = (sql3) => {
1170
- try {
1171
- const formatValue = (v) => {
1172
- if (Array.isArray(v)) {
1173
- const [type, val] = v;
1174
- if (type === "Identifier") {
1175
- return `\`${String(val)}\``;
1176
- }
1177
- return `[${v.map((x) => formatValue(x)).join(", ")}]`;
1178
- }
1179
- if (v === null || v === void 0) return "NULL";
1180
- if (typeof v === "string") return `'${v.replace(/'/g, "''")}'`;
1181
- if (typeof v === "number") return String(v);
1182
- if (typeof v === "boolean") return v ? "true" : "false";
1183
- if (v instanceof Date)
1184
- return `'${v.toISOString().replace("T", " ").slice(0, 19)}'`;
1185
- try {
1186
- return JSON.stringify(v);
1187
- } catch {
1188
- return String(v);
1189
- }
1190
- };
1191
- let out = sql3.strings[0] ?? "";
1192
- for (let i = 0; i < sql3.values.length; i++) {
1193
- const val = getValueFromParameter(sql3.values[i]);
1194
- out += formatValue(val);
1195
- out += sql3.strings[i + 1] ?? "";
1196
- }
1197
- return out.replace(/\s+/g, " ").trim();
1198
- } catch (error) {
1199
- console.log(`toQueryPreview error: ${error}`);
1200
- return "/* query preview unavailable */";
1201
- }
1202
- };
1203
- var getValueFromParameter = (value) => {
1204
- if (Array.isArray(value)) {
1205
- const [type, val] = value;
1206
- if (type === "Identifier") return val;
1207
- }
1208
- return value;
1209
- };
1210
- function createClickhouseParameter(parameterIndex, value) {
1211
- return `{p${parameterIndex}:${mapToClickHouseType(value)}}`;
1212
- }
1213
- var mapToClickHouseType = (value) => {
1214
- if (typeof value === "number") {
1215
- return Number.isInteger(value) ? "Int" : "Float";
1216
- }
1217
- if (typeof value === "boolean") return "Bool";
1218
- if (value instanceof Date) return "DateTime";
1219
- if (Array.isArray(value)) {
1220
- const [type, _] = value;
1221
- return type;
1222
- }
1223
- return "String";
1224
- };
1225
- function emptyIfUndefined(value) {
1226
- return value === void 0 ? "" : value;
1227
- }
1228
-
1229
- // src/dmv2/sdk/olapTable.ts
1230
1291
  var OlapTable = class extends TypedBase {
1231
1292
  name;
1232
1293
  /** @internal */
@@ -2787,56 +2848,6 @@ var ETLPipeline = class {
2787
2848
  }
2788
2849
  };
2789
2850
 
2790
- // src/dmv2/sdk/view.ts
2791
- function formatTableReference(table) {
2792
- const database = table instanceof OlapTable ? table.config.database : void 0;
2793
- const deployedName = table instanceof OlapTable ? table.generateTableName() : table.name;
2794
- if (database) {
2795
- return `\`${database}\`.\`${deployedName}\``;
2796
- }
2797
- return `\`${deployedName}\``;
2798
- }
2799
- var View = class {
2800
- /** @internal */
2801
- kind = "View";
2802
- /** The name of the view */
2803
- name;
2804
- /** The SELECT SQL statement that defines the view */
2805
- selectSql;
2806
- /** Names of source tables/views that the SELECT reads from */
2807
- sourceTables;
2808
- /** Optional metadata for the view */
2809
- metadata;
2810
- /**
2811
- * Creates a new View instance.
2812
- * @param name The name of the view to be created.
2813
- * @param selectStatement The SQL SELECT statement that defines the view's logic.
2814
- * @param baseTables An array of OlapTable or View objects that the `selectStatement` reads from. Used for dependency tracking.
2815
- * @param metadata Optional metadata for the view (e.g., description, source file).
2816
- */
2817
- constructor(name, selectStatement, baseTables, metadata) {
2818
- if (typeof selectStatement !== "string") {
2819
- selectStatement = toStaticQuery(selectStatement);
2820
- }
2821
- this.name = name;
2822
- this.selectSql = selectStatement;
2823
- this.sourceTables = baseTables.map((t) => formatTableReference(t));
2824
- this.metadata = metadata ? { ...metadata } : {};
2825
- if (!this.metadata.source) {
2826
- const stack = new Error().stack;
2827
- const sourceInfo = getSourceFileFromStack(stack);
2828
- if (sourceInfo) {
2829
- this.metadata.source = { file: sourceInfo };
2830
- }
2831
- }
2832
- const views = getMooseInternal().views;
2833
- if (!isClientOnlyMode() && views.has(this.name)) {
2834
- throw new Error(`View with name ${this.name} already exists`);
2835
- }
2836
- views.set(this.name, this);
2837
- }
2838
- };
2839
-
2840
2851
  // src/dmv2/sdk/materializedView.ts
2841
2852
  var requireTargetTableName = (tableName) => {
2842
2853
  if (typeof tableName === "string") {
@@ -3212,8 +3223,9 @@ function getMaterializedView(name) {
3212
3223
  function getViews() {
3213
3224
  return getMooseInternal().views;
3214
3225
  }
3215
- function getView(name) {
3216
- return getMooseInternal().views.get(name);
3226
+ function getView(name, database) {
3227
+ const key = viewRegistryKey(database, name);
3228
+ return getMooseInternal().views.get(key);
3217
3229
  }
3218
3230
  function getSelectRowPolicies() {
3219
3231
  return getMooseInternal().selectRowPolicies;