yamchart 0.9.4 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/{advisor-SC64RTZO.js → advisor-O2BRAI4T.js} +24 -14
  2. package/dist/advisor-O2BRAI4T.js.map +1 -0
  3. package/dist/{chunk-NXQ6ZO3V.js → chunk-5FHV22X2.js} +6 -6
  4. package/dist/chunk-5FHV22X2.js.map +1 -0
  5. package/dist/{chunk-7CD6UQAV.js → chunk-DZVT6PHW.js} +9 -1
  6. package/dist/chunk-DZVT6PHW.js.map +1 -0
  7. package/dist/chunk-FN6R2LAC.js +15442 -0
  8. package/dist/chunk-FN6R2LAC.js.map +1 -0
  9. package/dist/chunk-QJ5CPQJK.js +2053 -0
  10. package/dist/chunk-QJ5CPQJK.js.map +1 -0
  11. package/dist/{chunk-S7YQXEKM.js → chunk-QUIDZO5G.js} +103 -275
  12. package/dist/chunk-QUIDZO5G.js.map +1 -0
  13. package/dist/{chunk-RMIDEBHD.js → chunk-S2CH4HUZ.js} +6 -6
  14. package/dist/{chunk-UND73EOB.js → chunk-UFDQ3C7Q.js} +473 -4
  15. package/dist/chunk-UFDQ3C7Q.js.map +1 -0
  16. package/dist/{chunk-H4L3FNLS.js → chunk-ZBCQNWVN.js} +2 -2
  17. package/dist/{chunk-RM6MNDVF.js → chunk-ZIY22VO7.js} +192 -11
  18. package/dist/chunk-ZIY22VO7.js.map +1 -0
  19. package/dist/{connection-utils-C4FQGBW6.js → connection-utils-FEUWER5I.js} +5 -5
  20. package/dist/{describe-X75C2VDU.js → describe-MEP72B56.js} +6 -6
  21. package/dist/{dev-7YLRQ6SA.js → dev-LZ4YHNDJ.js} +1334 -77
  22. package/dist/dev-LZ4YHNDJ.js.map +1 -0
  23. package/dist/dist-5IFWLWND.js +48 -0
  24. package/dist/{dist-NGQG7Z4G.js → dist-MIKFZKSD.js} +2 -2
  25. package/dist/{dist-MX5K2ABB.js → dist-PPAD6KOM.js} +44 -2
  26. package/dist/{dist-JMLAZUL7.js → dist-XNCED7JW.js} +29 -12
  27. package/dist/fileFromPath-7TNUU6RI.js +130 -0
  28. package/dist/fileFromPath-7TNUU6RI.js.map +1 -0
  29. package/dist/index.js +25 -25
  30. package/dist/public/assets/DataView-DUCz_96y.js +9 -0
  31. package/dist/public/assets/{EventManagement-B7leMxfo.js → EventManagement-BnmeJDQl.js} +1 -1
  32. package/dist/public/assets/{ExplorePage-zI1OiYlH.js → ExplorePage-kk4z9ldZ.js} +1 -1
  33. package/dist/public/assets/{LoginPage-Dyk2ILmo.js → LoginPage-CzaFkkjg.js} +1 -1
  34. package/dist/public/assets/{PublicViewer-C2tNYBR2.js → PublicViewer-irjxqH6a.js} +1 -1
  35. package/dist/public/assets/{SetupWizard-BzZSJlbt.js → SetupWizard-ConWIcmy.js} +1 -1
  36. package/dist/public/assets/{ShareManagement-C7RIZRWe.js → ShareManagement-CP4wdwLR.js} +1 -1
  37. package/dist/public/assets/SourceDetailView-DZS5518E.js +1 -0
  38. package/dist/public/assets/{UserManagement-BD-lLbVH.js → UserManagement-AubGd9hl.js} +1 -1
  39. package/dist/public/assets/data-3vtzSuAZ.js +1 -0
  40. package/dist/public/assets/{index-CfyF2Wf-.css → index-C1X8RW4Z.css} +1 -1
  41. package/dist/public/assets/{index-lklRbe2I.js → index-jlfTO7f5.js} +44 -44
  42. package/dist/public/assets/{index.es-CLyC5-GY.js → index.es-CgnvEWi5.js} +1 -1
  43. package/dist/public/assets/{jspdf.es.min-CTZVk96E.js → jspdf.es.min-Cw5WefMt.js} +3 -3
  44. package/dist/public/index.html +2 -2
  45. package/dist/{query-QNRDS74I.js → query-2H3YOPI2.js} +5 -5
  46. package/dist/{reset-password-HDCLH7PZ.js → reset-password-YVCZKZPC.js} +2 -2
  47. package/dist/{sample-SKLHBZBU.js → sample-ODUGGSFA.js} +5 -5
  48. package/dist/{search-4KMETZVX.js → search-IPE4ISFB.js} +6 -6
  49. package/dist/{semantic-6WKELH5V.js → semantic-K3MYXXJI.js} +3 -2
  50. package/dist/{semantic-6WKELH5V.js.map → semantic-K3MYXXJI.js.map} +1 -1
  51. package/dist/{source-resolver-R7WBIL7M.js → source-resolver-HZQLOODU.js} +6 -6
  52. package/dist/source-resolver-HZQLOODU.js.map +1 -0
  53. package/dist/{sync-warehouse-UWRNUXE7.js → sync-warehouse-26L6JDSV.js} +10 -10
  54. package/dist/{tables-V65QUGHK.js → tables-K5NAN2WK.js} +6 -6
  55. package/dist/templates/default/docs/yamchart-reference.md +46 -0
  56. package/dist/{test-UE5OWG3E.js → test-SRHVOXZB.js} +8 -7
  57. package/dist/{test-UE5OWG3E.js.map → test-SRHVOXZB.js.map} +1 -1
  58. package/package.json +2 -2
  59. package/dist/advisor-SC64RTZO.js.map +0 -1
  60. package/dist/chunk-7CD6UQAV.js.map +0 -1
  61. package/dist/chunk-NXQ6ZO3V.js.map +0 -1
  62. package/dist/chunk-RM6MNDVF.js.map +0 -1
  63. package/dist/chunk-S7YQXEKM.js.map +0 -1
  64. package/dist/chunk-UND73EOB.js.map +0 -1
  65. package/dist/dev-7YLRQ6SA.js.map +0 -1
  66. package/dist/dist-MNXSMGV6.js +0 -790
  67. package/dist/dist-MNXSMGV6.js.map +0 -1
  68. /package/dist/{chunk-RMIDEBHD.js.map → chunk-S2CH4HUZ.js.map} +0 -0
  69. /package/dist/{chunk-H4L3FNLS.js.map → chunk-ZBCQNWVN.js.map} +0 -0
  70. /package/dist/{connection-utils-C4FQGBW6.js.map → connection-utils-FEUWER5I.js.map} +0 -0
  71. /package/dist/{describe-X75C2VDU.js.map → describe-MEP72B56.js.map} +0 -0
  72. /package/dist/{dist-JMLAZUL7.js.map → dist-5IFWLWND.js.map} +0 -0
  73. /package/dist/{dist-MX5K2ABB.js.map → dist-MIKFZKSD.js.map} +0 -0
  74. /package/dist/{dist-NGQG7Z4G.js.map → dist-PPAD6KOM.js.map} +0 -0
  75. /package/dist/{source-resolver-R7WBIL7M.js.map → dist-XNCED7JW.js.map} +0 -0
  76. /package/dist/{query-QNRDS74I.js.map → query-2H3YOPI2.js.map} +0 -0
  77. /package/dist/{reset-password-HDCLH7PZ.js.map → reset-password-YVCZKZPC.js.map} +0 -0
  78. /package/dist/{sample-SKLHBZBU.js.map → sample-ODUGGSFA.js.map} +0 -0
  79. /package/dist/{search-4KMETZVX.js.map → search-IPE4ISFB.js.map} +0 -0
  80. /package/dist/{sync-warehouse-UWRNUXE7.js.map → sync-warehouse-26L6JDSV.js.map} +0 -0
  81. /package/dist/{tables-V65QUGHK.js.map → tables-K5NAN2WK.js.map} +0 -0
@@ -1,3 +1,12 @@
1
+ import {
2
+ expandCustomDateRange,
3
+ expandDatePreset,
4
+ expandRelativeDateRange,
5
+ getDialect,
6
+ isCustomDateRange,
7
+ isDatePreset,
8
+ isRelativeDateRange
9
+ } from "./chunk-UFDQ3C7Q.js";
1
10
  import {
2
11
  __require
3
12
  } from "./chunk-7D4SUZUM.js";
@@ -123,261 +132,6 @@ function parseReturnColumn(input) {
123
132
  return col;
124
133
  }
125
134
 
126
- // ../../packages/query/dist/presets.js
127
- import { subDays, subWeeks, subMonths, subYears, subQuarters, addDays, addWeeks, addMonths, addYears, addQuarters, startOfDay, startOfWeek, startOfYear, startOfMonth, startOfQuarter, endOfWeek, endOfMonth, endOfQuarter, endOfYear, differenceInDays, parseISO, format } from "date-fns";
128
- function isCustomDateRange(value) {
129
- return typeof value === "object" && value !== null && "type" in value && value.type === "custom" && "start" in value && "end" in value;
130
- }
131
- function expandCustomDateRange(range) {
132
- return {
133
- start_date: range.start,
134
- end_date: range.end
135
- };
136
- }
137
- var DATE_PRESETS = [
138
- "today",
139
- "yesterday",
140
- "last_7_days",
141
- "last_30_days",
142
- "last_90_days",
143
- "last_12_months",
144
- "year_to_date",
145
- "month_to_date",
146
- "quarter_to_date",
147
- "previous_month",
148
- "previous_quarter",
149
- "previous_year"
150
- ];
151
- var DATE_FORMAT = "yyyy-MM-dd";
152
- function formatDate(date) {
153
- return format(date, DATE_FORMAT);
154
- }
155
- function expandDatePreset(preset) {
156
- const now = /* @__PURE__ */ new Date();
157
- const today = formatDate(now);
158
- switch (preset) {
159
- case "today":
160
- return {
161
- start_date: today,
162
- end_date: today
163
- };
164
- case "yesterday": {
165
- const yesterday = formatDate(subDays(now, 1));
166
- return {
167
- start_date: yesterday,
168
- end_date: yesterday
169
- };
170
- }
171
- case "last_7_days": {
172
- const yesterday = formatDate(subDays(now, 1));
173
- return {
174
- start_date: formatDate(subDays(now, 7)),
175
- end_date: yesterday
176
- };
177
- }
178
- case "last_30_days": {
179
- const yesterday = formatDate(subDays(now, 1));
180
- return {
181
- start_date: formatDate(subDays(now, 30)),
182
- end_date: yesterday
183
- };
184
- }
185
- case "last_90_days": {
186
- const yesterday = formatDate(subDays(now, 1));
187
- return {
188
- start_date: formatDate(subDays(now, 90)),
189
- end_date: yesterday
190
- };
191
- }
192
- case "last_12_months": {
193
- const yesterday = formatDate(subDays(now, 1));
194
- return {
195
- start_date: formatDate(subMonths(now, 12)),
196
- end_date: yesterday
197
- };
198
- }
199
- case "year_to_date":
200
- return {
201
- start_date: formatDate(startOfYear(now)),
202
- end_date: today
203
- };
204
- case "month_to_date":
205
- return {
206
- start_date: formatDate(startOfMonth(now)),
207
- end_date: today
208
- };
209
- case "quarter_to_date":
210
- return {
211
- start_date: formatDate(startOfQuarter(now)),
212
- end_date: today
213
- };
214
- case "previous_month": {
215
- const lastMonth = subMonths(now, 1);
216
- return {
217
- start_date: formatDate(startOfMonth(lastMonth)),
218
- end_date: formatDate(endOfMonth(lastMonth))
219
- };
220
- }
221
- case "previous_quarter": {
222
- const lastQuarter = subMonths(now, 3);
223
- return {
224
- start_date: formatDate(startOfQuarter(lastQuarter)),
225
- end_date: formatDate(endOfQuarter(lastQuarter))
226
- };
227
- }
228
- case "previous_year": {
229
- const lastYear = subYears(now, 1);
230
- return {
231
- start_date: formatDate(startOfYear(lastYear)),
232
- end_date: formatDate(endOfYear(lastYear))
233
- };
234
- }
235
- default:
236
- return null;
237
- }
238
- }
239
- function computePreviousPeriod(startDate, endDate, presetName) {
240
- const start = parseISO(startDate);
241
- const end = parseISO(endDate);
242
- switch (presetName) {
243
- case "today":
244
- case "yesterday": {
245
- return {
246
- start_date: formatDate(subDays(start, 1)),
247
- end_date: formatDate(subDays(end, 1))
248
- };
249
- }
250
- case "last_7_days": {
251
- return {
252
- start_date: formatDate(subDays(start, 7)),
253
- end_date: formatDate(subDays(end, 7))
254
- };
255
- }
256
- case "last_30_days": {
257
- return {
258
- start_date: formatDate(subDays(start, 30)),
259
- end_date: formatDate(subDays(end, 30))
260
- };
261
- }
262
- case "last_90_days": {
263
- return {
264
- start_date: formatDate(subDays(start, 90)),
265
- end_date: formatDate(subDays(end, 90))
266
- };
267
- }
268
- case "last_12_months":
269
- case "last_365_days": {
270
- return {
271
- start_date: formatDate(subMonths(start, 12)),
272
- end_date: formatDate(subMonths(end, 12))
273
- };
274
- }
275
- case "year_to_date": {
276
- return {
277
- start_date: formatDate(subYears(start, 1)),
278
- end_date: formatDate(subYears(end, 1))
279
- };
280
- }
281
- case "month_to_date": {
282
- return {
283
- start_date: formatDate(subMonths(start, 1)),
284
- end_date: formatDate(subMonths(end, 1))
285
- };
286
- }
287
- case "quarter_to_date": {
288
- return {
289
- start_date: formatDate(subQuarters(start, 1)),
290
- end_date: formatDate(subQuarters(end, 1))
291
- };
292
- }
293
- case "previous_month": {
294
- const shifted = subMonths(start, 1);
295
- return {
296
- start_date: formatDate(startOfMonth(shifted)),
297
- end_date: formatDate(endOfMonth(shifted))
298
- };
299
- }
300
- case "previous_quarter": {
301
- const shifted = subQuarters(start, 1);
302
- return {
303
- start_date: formatDate(startOfQuarter(shifted)),
304
- end_date: formatDate(endOfQuarter(shifted))
305
- };
306
- }
307
- case "previous_year": {
308
- const shifted = subYears(start, 1);
309
- return {
310
- start_date: formatDate(startOfYear(shifted)),
311
- end_date: formatDate(endOfYear(shifted))
312
- };
313
- }
314
- default: {
315
- const days = differenceInDays(end, start);
316
- return {
317
- start_date: formatDate(subDays(start, days)),
318
- end_date: formatDate(subDays(end, days))
319
- };
320
- }
321
- }
322
- }
323
- function formatPeriodLabel(startDate, endDate) {
324
- const start = parseISO(startDate);
325
- const end = parseISO(endDate);
326
- if (startDate === endDate) {
327
- return format(start, "MMM d");
328
- }
329
- const startYear = start.getFullYear();
330
- const endYear = end.getFullYear();
331
- if (startYear === endYear) {
332
- return `${format(start, "MMM d")} \u2013 ${format(end, "MMM d")}`;
333
- }
334
- return `${format(start, "MMM d, yyyy")} \u2013 ${format(end, "MMM d, yyyy")}`;
335
- }
336
- function isDatePreset(value) {
337
- return DATE_PRESETS.includes(value);
338
- }
339
- function isRelativeDateRange(value) {
340
- return typeof value === "object" && value !== null && "type" in value && value.type === "relative";
341
- }
342
- function expandRelativeDateRange(rel) {
343
- const now = /* @__PURE__ */ new Date();
344
- const today = startOfDay(now);
345
- if (rel.direction === "current") {
346
- switch (rel.unit) {
347
- case "day":
348
- return { start_date: formatDate(today), end_date: formatDate(today) };
349
- case "week":
350
- return {
351
- start_date: formatDate(startOfWeek(today, { weekStartsOn: 1 })),
352
- end_date: formatDate(endOfWeek(today, { weekStartsOn: 1 }))
353
- };
354
- case "month":
355
- return { start_date: formatDate(startOfMonth(today)), end_date: formatDate(endOfMonth(today)) };
356
- case "quarter":
357
- return { start_date: formatDate(startOfQuarter(today)), end_date: formatDate(endOfQuarter(today)) };
358
- case "year":
359
- return { start_date: formatDate(startOfYear(today)), end_date: formatDate(endOfYear(today)) };
360
- }
361
- }
362
- const n = rel.value ?? 1;
363
- if (rel.direction === "previous") {
364
- const end2 = rel.includeToday ? today : subDays(today, 1);
365
- const shiftFns2 = { day: subDays, week: subWeeks, month: subMonths, quarter: subQuarters, year: subYears };
366
- const start2 = shiftFns2[rel.unit](rel.includeToday ? today : today, n);
367
- return {
368
- start_date: formatDate(start2 < end2 ? start2 : end2),
369
- end_date: formatDate(start2 < end2 ? end2 : start2)
370
- };
371
- }
372
- const start = rel.includeToday ? today : addDays(today, 1);
373
- const shiftFns = { day: addDays, week: addWeeks, month: addMonths, quarter: addQuarters, year: addYears };
374
- const end = shiftFns[rel.unit](start, n);
375
- return {
376
- start_date: formatDate(start < end ? start : end),
377
- end_date: formatDate(start < end ? end : start)
378
- };
379
- }
380
-
381
135
  // ../../packages/query/dist/template.js
382
136
  import nunjucks from "nunjucks";
383
137
  var env = new nunjucks.Environment(null, {
@@ -440,35 +194,35 @@ function extractTemplateVariables(template) {
440
194
 
441
195
  // ../../packages/query/dist/compiler.js
442
196
  import { createHash } from "crypto";
443
- import { format as format2, subDays as subDays2, addDays as addDays2, startOfYear as startOfYear2, startOfMonth as startOfMonth2, startOfQuarter as startOfQuarter2, endOfYear as endOfYear2, endOfMonth as endOfMonth2, endOfQuarter as endOfQuarter2 } from "date-fns";
197
+ import { format, subDays, addDays, startOfYear, startOfMonth, startOfQuarter, endOfYear, endOfMonth, endOfQuarter } from "date-fns";
444
198
  function resolveDynamicDefault(value) {
445
199
  if (typeof value !== "string")
446
200
  return value;
447
201
  const trimmed = value.trim().toLowerCase();
448
202
  if (trimmed === "current_date()" || trimmed === "current_date" || trimmed === "now()" || trimmed === "today") {
449
- return format2(/* @__PURE__ */ new Date(), "yyyy-MM-dd");
203
+ return format(/* @__PURE__ */ new Date(), "yyyy-MM-dd");
450
204
  }
451
205
  const now = /* @__PURE__ */ new Date();
452
206
  switch (trimmed) {
453
207
  case "start_of_year":
454
- return format2(startOfYear2(now), "yyyy-MM-dd");
208
+ return format(startOfYear(now), "yyyy-MM-dd");
455
209
  case "start_of_month":
456
- return format2(startOfMonth2(now), "yyyy-MM-dd");
210
+ return format(startOfMonth(now), "yyyy-MM-dd");
457
211
  case "start_of_quarter":
458
- return format2(startOfQuarter2(now), "yyyy-MM-dd");
212
+ return format(startOfQuarter(now), "yyyy-MM-dd");
459
213
  case "end_of_year":
460
- return format2(endOfYear2(now), "yyyy-MM-dd");
214
+ return format(endOfYear(now), "yyyy-MM-dd");
461
215
  case "end_of_month":
462
- return format2(endOfMonth2(now), "yyyy-MM-dd");
216
+ return format(endOfMonth(now), "yyyy-MM-dd");
463
217
  case "end_of_quarter":
464
- return format2(endOfQuarter2(now), "yyyy-MM-dd");
218
+ return format(endOfQuarter(now), "yyyy-MM-dd");
465
219
  }
466
220
  const arithMatch = trimmed.match(/^(?:today|current_date(?:\(\))?)\s*([+-])\s*(\d+)\s*d?$/);
467
221
  if (arithMatch) {
468
222
  const [, op, numStr] = arithMatch;
469
223
  const days = parseInt(numStr, 10);
470
- const result = op === "-" ? subDays2(now, days) : addDays2(now, days);
471
- return format2(result, "yyyy-MM-dd");
224
+ const result = op === "-" ? subDays(now, days) : addDays(now, days);
225
+ return format(result, "yyyy-MM-dd");
472
226
  }
473
227
  return value;
474
228
  }
@@ -1738,20 +1492,90 @@ async function checkSchema(compiledSql, connector, expectedReturns) {
1738
1492
  };
1739
1493
  }
1740
1494
 
1495
+ // ../../packages/query/dist/profiling/profiler.js
1496
+ var NUMERIC = /(INT|DEC|NUM|DOUBLE|FLOAT|REAL|BIGINT)/i;
1497
+ var STRINGY = /(CHAR|TEXT|STRING|VARCHAR)/i;
1498
+ var TOP_N = 10;
1499
+ function buildTableStatsSql(table, columns, dialect) {
1500
+ const d = getDialect(dialect);
1501
+ const tbl = d.quoteIdent(table);
1502
+ const parts = ["COUNT(*) AS total"];
1503
+ for (const c of columns) {
1504
+ const col = d.quoteIdent(c.name);
1505
+ parts.push(`COUNT(*) - COUNT(${col}) AS ${c.name}_nulls`);
1506
+ parts.push(`COUNT(DISTINCT ${col}) AS ${c.name}_distinct`);
1507
+ if (NUMERIC.test(c.type)) {
1508
+ parts.push(`MIN(${col}) AS ${c.name}_min`);
1509
+ parts.push(`MAX(${col}) AS ${c.name}_max`);
1510
+ }
1511
+ }
1512
+ return `SELECT ${parts.join(", ")} FROM ${tbl}`;
1513
+ }
1514
+ function buildTopValuesSql(table, column, dialect) {
1515
+ const d = getDialect(dialect);
1516
+ const tbl = d.quoteIdent(table);
1517
+ const col = d.quoteIdent(column);
1518
+ return `SELECT ${col} AS v, COUNT(*) AS c FROM ${tbl} GROUP BY ${col} ORDER BY c DESC LIMIT ${TOP_N}`;
1519
+ }
1520
+ async function buildSourceProfile(input) {
1521
+ const { connection, dialect, tables, execute } = input;
1522
+ const d = getDialect(dialect);
1523
+ const maxTopValueDistinct = input.maxTopValueDistinct ?? 50;
1524
+ const tableProfiles = [];
1525
+ for (const t of tables) {
1526
+ try {
1527
+ const statsRes = await execute(buildTableStatsSql(t.table, t.columns, dialect));
1528
+ const stats = statsRes.rows[0] ?? {};
1529
+ const total = Number(stats.total ?? 0);
1530
+ const columns = [];
1531
+ for (const c of t.columns) {
1532
+ const nulls = Number(stats[`${c.name}_nulls`] ?? 0);
1533
+ const distinct = stats[`${c.name}_distinct`] != null ? Number(stats[`${c.name}_distinct`]) : void 0;
1534
+ const col = {
1535
+ name: c.name,
1536
+ type: c.type,
1537
+ nullRate: total > 0 ? nulls / total : void 0,
1538
+ distinctCount: distinct,
1539
+ min: stats[`${c.name}_min`],
1540
+ max: stats[`${c.name}_max`]
1541
+ };
1542
+ if (STRINGY.test(c.type) && distinct != null && distinct <= maxTopValueDistinct) {
1543
+ const tv = await execute(buildTopValuesSql(t.table, c.name, dialect));
1544
+ col.topValues = tv.rows.map((r) => ({ value: r.v, count: Number(r.c) }));
1545
+ }
1546
+ columns.push(col);
1547
+ }
1548
+ const sampleLimit = input.sampleLimit ?? 5;
1549
+ const sampleRows = sampleLimit > 0 ? (await execute(`SELECT * FROM ${d.quoteIdent(t.table)} LIMIT ${sampleLimit}`)).rows : [];
1550
+ tableProfiles.push({ table: t.table, rowCount: total, columns, sampleRows });
1551
+ } catch {
1552
+ tableProfiles.push({ table: t.table, columns: t.columns.map((c) => ({ name: c.name, type: c.type })), sampleRows: [] });
1553
+ }
1554
+ }
1555
+ return { connection, profiledAt: (/* @__PURE__ */ new Date()).toISOString(), tables: tableProfiles };
1556
+ }
1557
+
1558
+ // ../../packages/query/dist/sql-safety.js
1559
+ var DESTRUCTIVE_START = /^\s*(INSERT|UPDATE|DELETE|DROP|ALTER|TRUNCATE|CREATE|MERGE|GRANT|REVOKE|COPY|ATTACH|DETACH|EXPORT|IMPORT|INSTALL|LOAD)\b/i;
1560
+ var WRITABLE_CTE = /\b(INSERT|UPDATE|DELETE|MERGE)\b/i;
1561
+ var READ_ONLY_START = /^\s*(SELECT|WITH)\b/i;
1562
+ function isReadOnlySql(sql) {
1563
+ let s = sql.trim();
1564
+ s = s.replace(/;\s*$/, "");
1565
+ if (s.includes(";"))
1566
+ return false;
1567
+ if (DESTRUCTIVE_START.test(s))
1568
+ return false;
1569
+ if (/^\s*WITH\b/i.test(s) && WRITABLE_CTE.test(s))
1570
+ return false;
1571
+ return READ_ONLY_START.test(s);
1572
+ }
1573
+
1741
1574
  // ../../packages/query/dist/index.js
1742
1575
  var VERSION = "0.1.0";
1743
1576
 
1744
1577
  export {
1745
1578
  parseModelMetadata,
1746
- isCustomDateRange,
1747
- expandCustomDateRange,
1748
- DATE_PRESETS,
1749
- expandDatePreset,
1750
- computePreviousPeriod,
1751
- formatPeriodLabel,
1752
- isDatePreset,
1753
- isRelativeDateRange,
1754
- expandRelativeDateRange,
1755
1579
  SqlList,
1756
1580
  createTemplateContext,
1757
1581
  renderTemplate,
@@ -1777,6 +1601,10 @@ export {
1777
1601
  runModel,
1778
1602
  runAll,
1779
1603
  checkSchema,
1604
+ buildTableStatsSql,
1605
+ buildTopValuesSql,
1606
+ buildSourceProfile,
1607
+ isReadOnlySql,
1780
1608
  VERSION
1781
1609
  };
1782
- //# sourceMappingURL=chunk-S7YQXEKM.js.map
1610
+ //# sourceMappingURL=chunk-QUIDZO5G.js.map