@duckcodeailabs/dql-cli 0.1.0 → 0.1.2

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 (112) hide show
  1. package/README.md +62 -0
  2. package/dist/args.d.ts +9 -0
  3. package/dist/args.d.ts.map +1 -1
  4. package/dist/args.js +43 -1
  5. package/dist/args.js.map +1 -1
  6. package/dist/args.test.d.ts +2 -0
  7. package/dist/args.test.d.ts.map +1 -0
  8. package/dist/args.test.js +33 -0
  9. package/dist/args.test.js.map +1 -0
  10. package/dist/assets/notebook-browser/app.js +537 -0
  11. package/dist/assets/notebook-browser/index.html +83 -0
  12. package/dist/assets/notebook-browser/styles.css +336 -0
  13. package/dist/assets/templates/ecommerce/README.md +27 -0
  14. package/dist/assets/templates/ecommerce/blocks/repeat_rate.dql +26 -0
  15. package/dist/assets/templates/ecommerce/blocks/revenue_by_segment.dql +24 -0
  16. package/dist/assets/templates/ecommerce/dashboards/revenue_command_center.dql +25 -0
  17. package/dist/assets/templates/ecommerce/data/customers.csv +11 -0
  18. package/dist/assets/templates/ecommerce/data/funnel.csv +6 -0
  19. package/dist/assets/templates/ecommerce/data/orders.csv +16 -0
  20. package/dist/assets/templates/ecommerce/dql.config.json +13 -0
  21. package/dist/assets/templates/ecommerce/semantic-layer/dimensions/channel.yaml +4 -0
  22. package/dist/assets/templates/ecommerce/semantic-layer/metrics/gmv.yaml +4 -0
  23. package/dist/assets/templates/ecommerce/workbooks/.gitkeep +1 -0
  24. package/dist/assets/templates/saas/README.md +20 -0
  25. package/dist/assets/templates/saas/blocks/churn_pressure.dql +25 -0
  26. package/dist/assets/templates/saas/blocks/revenue_by_segment.dql +25 -0
  27. package/dist/assets/templates/saas/dashboards/growth_scorecard.dql +25 -0
  28. package/dist/assets/templates/saas/data/cohorts.csv +7 -0
  29. package/dist/assets/templates/saas/data/subscriptions.csv +13 -0
  30. package/dist/assets/templates/saas/dql.config.json +13 -0
  31. package/dist/assets/templates/saas/semantic-layer/metrics/mrr.yaml +4 -0
  32. package/dist/assets/templates/saas/workbooks/.gitkeep +1 -0
  33. package/dist/assets/templates/starter/README.md +54 -0
  34. package/dist/assets/templates/starter/blocks/revenue_by_segment.dql +29 -0
  35. package/dist/assets/templates/starter/blocks/revenue_trend_query_only.dql +20 -0
  36. package/dist/assets/templates/starter/dashboards/.gitkeep +1 -0
  37. package/dist/assets/templates/starter/data/revenue.csv +13 -0
  38. package/dist/assets/templates/starter/dql.config.json +13 -0
  39. package/dist/assets/templates/starter/semantic-layer/blocks/revenue_by_segment.yaml +11 -0
  40. package/dist/assets/templates/starter/semantic-layer/dimensions/segment_tier.yaml +6 -0
  41. package/dist/assets/templates/starter/semantic-layer/hierarchies/revenue_time.yaml +12 -0
  42. package/dist/assets/templates/starter/semantic-layer/metrics/revenue.yaml +7 -0
  43. package/dist/assets/templates/starter/workbooks/.gitkeep +1 -0
  44. package/dist/assets/templates/taxi/README.md +19 -0
  45. package/dist/assets/templates/taxi/blocks/airport_mix.dql +25 -0
  46. package/dist/assets/templates/taxi/blocks/revenue_by_segment.dql +24 -0
  47. package/dist/assets/templates/taxi/dashboards/city_operations.dql +25 -0
  48. package/dist/assets/templates/taxi/data/trips.csv +13 -0
  49. package/dist/assets/templates/taxi/dql.config.json +13 -0
  50. package/dist/assets/templates/taxi/semantic-layer/.gitkeep +1 -0
  51. package/dist/assets/templates/taxi/workbooks/.gitkeep +1 -0
  52. package/dist/commands/build.d.ts +3 -0
  53. package/dist/commands/build.d.ts.map +1 -0
  54. package/dist/commands/build.js +41 -0
  55. package/dist/commands/build.js.map +1 -0
  56. package/dist/commands/build.test.d.ts +2 -0
  57. package/dist/commands/build.test.d.ts.map +1 -0
  58. package/dist/commands/build.test.js +42 -0
  59. package/dist/commands/build.test.js.map +1 -0
  60. package/dist/commands/doctor.d.ts +3 -0
  61. package/dist/commands/doctor.d.ts.map +1 -0
  62. package/dist/commands/doctor.js +127 -0
  63. package/dist/commands/doctor.js.map +1 -0
  64. package/dist/commands/doctor.test.d.ts +2 -0
  65. package/dist/commands/doctor.test.d.ts.map +1 -0
  66. package/dist/commands/doctor.test.js +41 -0
  67. package/dist/commands/doctor.test.js.map +1 -0
  68. package/dist/commands/init.d.ts +3 -0
  69. package/dist/commands/init.d.ts.map +1 -0
  70. package/dist/commands/init.js +117 -0
  71. package/dist/commands/init.js.map +1 -0
  72. package/dist/commands/init.test.d.ts +2 -0
  73. package/dist/commands/init.test.d.ts.map +1 -0
  74. package/dist/commands/init.test.js +38 -0
  75. package/dist/commands/init.test.js.map +1 -0
  76. package/dist/commands/migrate.js +4 -4
  77. package/dist/commands/migrate.js.map +1 -1
  78. package/dist/commands/new.d.ts +3 -0
  79. package/dist/commands/new.d.ts.map +1 -0
  80. package/dist/commands/new.js +405 -0
  81. package/dist/commands/new.js.map +1 -0
  82. package/dist/commands/new.test.d.ts +2 -0
  83. package/dist/commands/new.test.d.ts.map +1 -0
  84. package/dist/commands/new.test.js +177 -0
  85. package/dist/commands/new.test.js.map +1 -0
  86. package/dist/commands/notebook.d.ts +3 -0
  87. package/dist/commands/notebook.d.ts.map +1 -0
  88. package/dist/commands/notebook.js +31 -0
  89. package/dist/commands/notebook.js.map +1 -0
  90. package/dist/commands/preview.d.ts +3 -0
  91. package/dist/commands/preview.d.ts.map +1 -0
  92. package/dist/commands/preview.js +42 -0
  93. package/dist/commands/preview.js.map +1 -0
  94. package/dist/commands/serve.d.ts +3 -0
  95. package/dist/commands/serve.d.ts.map +1 -0
  96. package/dist/commands/serve.js +30 -0
  97. package/dist/commands/serve.js.map +1 -0
  98. package/dist/index.js +46 -2
  99. package/dist/index.js.map +1 -1
  100. package/dist/local-runtime.d.ts +25 -0
  101. package/dist/local-runtime.d.ts.map +1 -0
  102. package/dist/local-runtime.js +302 -0
  103. package/dist/local-runtime.js.map +1 -0
  104. package/dist/local-runtime.test.d.ts +2 -0
  105. package/dist/local-runtime.test.d.ts.map +1 -0
  106. package/dist/local-runtime.test.js +21 -0
  107. package/dist/local-runtime.test.js.map +1 -0
  108. package/dist/open-browser.d.ts +2 -0
  109. package/dist/open-browser.d.ts.map +1 -0
  110. package/dist/open-browser.js +29 -0
  111. package/dist/open-browser.js.map +1 -0
  112. package/package.json +8 -6
@@ -0,0 +1,54 @@
1
+ # __PROJECT_NAME__
2
+
3
+ This starter gives you a local-first DQL project that is ready for parsing,
4
+ previewing, notebook exploration, and experimentation.
5
+
6
+ ```text
7
+ blocks/
8
+ dashboards/
9
+ data/
10
+ dql.config.json
11
+ notebooks/
12
+ workbooks/
13
+ semantic-layer/
14
+ metrics/
15
+ dimensions/
16
+ hierarchies/
17
+ blocks/
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ```bash
23
+ dql doctor
24
+ dql notebook
25
+ dql new block "Pipeline Health"
26
+ dql new semantic-block "ARR Growth"
27
+ dql new dashboard "Revenue Overview"
28
+ dql new workbook "Quarterly Review"
29
+ dql parse blocks/pipeline_health.dql
30
+ dql preview blocks/pipeline_health.dql --open
31
+ dql build blocks/pipeline_health.dql
32
+ dql serve dist/pipeline_health
33
+ ```
34
+
35
+ ## What's Included
36
+
37
+ - `blocks/` — example charted and query-only DQL blocks
38
+ - `dashboards/` — empty folder for dashboard scaffolds
39
+ - `data/` — sample revenue CSV for local DuckDB/file preview flows
40
+ - `dql.config.json` — starter project configuration
41
+ - `notebooks/welcome.dqlnb` — guided notebook walkthrough for the browser notebook
42
+ - `workbooks/` — empty folder for workbook scaffolds
43
+ - `semantic-layer/` — example metrics, dimensions, hierarchies, and companion metadata
44
+
45
+ ## Adopt the Starter Safely
46
+
47
+ - start in local file mode first
48
+ - keep sample datasets under `data/`
49
+ - run `dql doctor` before previewing if setup feels off
50
+ - add tests to every reusable block
51
+
52
+ ## Learn More
53
+
54
+ - See the main DQL documentation for `project-config` and `data-sources` guidance.
@@ -0,0 +1,29 @@
1
+ block "Revenue by Segment" {
2
+ domain = "revenue"
3
+ type = "custom"
4
+ description = "Starter block for segment revenue analysis using local CSV sample data"
5
+ tags = ["starter", "revenue"]
6
+ owner = "template"
7
+
8
+ params {
9
+ period = "current_quarter"
10
+ }
11
+
12
+ query = """
13
+ SELECT segment_tier AS segment, SUM(amount) AS revenue
14
+ FROM read_csv_auto('./data/revenue.csv')
15
+ WHERE fiscal_period = ${period}
16
+ GROUP BY segment_tier
17
+ ORDER BY revenue DESC
18
+ """
19
+
20
+ visualization {
21
+ chart = "bar"
22
+ x = segment
23
+ y = revenue
24
+ }
25
+
26
+ tests {
27
+ assert row_count > 0
28
+ }
29
+ }
@@ -0,0 +1,20 @@
1
+ block "Revenue Trend Query" {
2
+ domain = "revenue"
3
+ type = "custom"
4
+ description = "Starter query-only block for monthly revenue trends using local CSV sample data"
5
+ tags = ["starter", "revenue", "query-only"]
6
+ owner = "template"
7
+
8
+ query = """
9
+ SELECT
10
+ DATE_TRUNC('month', CAST(recognized_at AS DATE)) AS revenue_month,
11
+ SUM(amount) AS total_revenue
12
+ FROM read_csv_auto('./data/revenue.csv')
13
+ GROUP BY 1
14
+ ORDER BY 1
15
+ """
16
+
17
+ tests {
18
+ assert row_count > 0
19
+ }
20
+ }
@@ -0,0 +1,13 @@
1
+ recognized_at,segment_tier,amount,fiscal_period,fiscal_year,fiscal_quarter
2
+ 2025-01-03,Enterprise,185000,current_quarter,2025,Q1
3
+ 2025-01-14,Mid-Market,92000,current_quarter,2025,Q1
4
+ 2025-01-25,SMB,28000,current_quarter,2025,Q1
5
+ 2025-02-05,Enterprise,210000,current_quarter,2025,Q1
6
+ 2025-02-09,Mid-Market,101000,current_quarter,2025,Q1
7
+ 2025-02-18,SMB,31000,current_quarter,2025,Q1
8
+ 2025-03-02,Enterprise,223000,current_quarter,2025,Q1
9
+ 2025-03-11,Mid-Market,108000,current_quarter,2025,Q1
10
+ 2025-03-19,SMB,34000,current_quarter,2025,Q1
11
+ 2025-04-07,Enterprise,205000,next_quarter,2025,Q2
12
+ 2025-04-16,Mid-Market,99000,next_quarter,2025,Q2
13
+ 2025-04-23,SMB,29000,next_quarter,2025,Q2
@@ -0,0 +1,13 @@
1
+ {
2
+ "project": "__PROJECT_NAME__",
3
+ "defaultConnection": {
4
+ "driver": "file",
5
+ "filepath": ":memory:"
6
+ },
7
+ "dataDir": "./data",
8
+ "preview": {
9
+ "port": 3474,
10
+ "open": true,
11
+ "theme": "dark"
12
+ }
13
+ }
@@ -0,0 +1,11 @@
1
+ name: revenue_by_segment
2
+ block: revenue_by_segment
3
+ domain: revenue
4
+ description: Optional companion metadata for the starter block
5
+ tags:
6
+ - revenue
7
+ - starter
8
+ semanticMappings:
9
+ segment: segment_tier
10
+ revenue: total_revenue
11
+ reviewStatus: draft
@@ -0,0 +1,6 @@
1
+ name: segment_tier
2
+ label: Segment Tier
3
+ description: Customer segment tier
4
+ sql: segment_tier
5
+ type: string
6
+ table: fct_revenue
@@ -0,0 +1,12 @@
1
+ name: revenue_time
2
+ label: Revenue Time
3
+ description: Example fiscal calendar hierarchy
4
+ domain: revenue
5
+ levels:
6
+ - name: fiscal_year
7
+ dimension: fiscal_year
8
+ order: 1
9
+ - name: fiscal_quarter
10
+ dimension: fiscal_quarter
11
+ order: 2
12
+ defaultRollup: sum
@@ -0,0 +1,7 @@
1
+ name: total_revenue
2
+ label: Total Revenue
3
+ description: Sum of recognized revenue
4
+ domain: revenue
5
+ sql: SUM(amount)
6
+ type: sum
7
+ table: fct_revenue
@@ -0,0 +1,19 @@
1
+ # __PROJECT_NAME__
2
+
3
+ This template packages a city mobility analytics sandbox with taxi trip data.
4
+
5
+ ## Included assets
6
+
7
+ - `blocks/revenue_by_segment.dql` — trip volume by pickup borough
8
+ - `blocks/airport_mix.dql` — airport trip fare mix
9
+ - `dashboards/city_operations.dql` — operations dashboard with fares and trip counts
10
+ - `data/trips.csv` — local taxi trip sample dataset
11
+ - `notebooks/welcome.dqlnb` — browser notebook walkthrough
12
+
13
+ ## Quick start
14
+
15
+ ```bash
16
+ dql doctor
17
+ dql notebook
18
+ dql preview blocks/revenue_by_segment.dql --open
19
+ ```
@@ -0,0 +1,25 @@
1
+ block "Airport Fare Mix" {
2
+ domain = "mobility"
3
+ type = "custom"
4
+ description = "Average fare for airport versus non-airport trips"
5
+ tags = ["taxi", "airport"]
6
+ owner = "template"
7
+
8
+ query = """
9
+ SELECT CASE WHEN airport_flag THEN 'Airport' ELSE 'City' END AS trip_type,
10
+ ROUND(AVG(fare_amount), 2) AS avg_fare
11
+ FROM read_csv_auto('./data/trips.csv')
12
+ GROUP BY trip_type
13
+ ORDER BY avg_fare DESC
14
+ """
15
+
16
+ visualization {
17
+ chart = "bar"
18
+ x = trip_type
19
+ y = avg_fare
20
+ }
21
+
22
+ tests {
23
+ assert row_count > 0
24
+ }
25
+ }
@@ -0,0 +1,24 @@
1
+ block "Trips by Borough" {
2
+ domain = "mobility"
3
+ type = "custom"
4
+ description = "Trip count by pickup borough"
5
+ tags = ["taxi", "operations"]
6
+ owner = "template"
7
+
8
+ query = """
9
+ SELECT pickup_borough, COUNT(*) AS revenue
10
+ FROM read_csv_auto('./data/trips.csv')
11
+ GROUP BY pickup_borough
12
+ ORDER BY revenue DESC
13
+ """
14
+
15
+ visualization {
16
+ chart = "bar"
17
+ x = pickup_borough
18
+ y = revenue
19
+ }
20
+
21
+ tests {
22
+ assert row_count > 0
23
+ }
24
+ }
@@ -0,0 +1,25 @@
1
+ dashboard "City Operations" {
2
+ chart.kpi(
3
+ SELECT COUNT(*) AS total_trips
4
+ FROM read_csv_auto('./data/trips.csv'),
5
+ metrics = ["total_trips"],
6
+ title = "Total Trips"
7
+ )
8
+
9
+ chart.line(
10
+ SELECT pickup_hour, ROUND(AVG(fare_amount), 2) AS avg_fare
11
+ FROM read_csv_auto('./data/trips.csv')
12
+ GROUP BY pickup_hour
13
+ ORDER BY pickup_hour,
14
+ x = pickup_hour,
15
+ y = avg_fare,
16
+ title = "Average Fare by Hour"
17
+ )
18
+
19
+ chart.table(
20
+ SELECT pickup_date, pickup_borough, dropoff_borough, trip_miles, fare_amount, tip_amount
21
+ FROM read_csv_auto('./data/trips.csv')
22
+ ORDER BY fare_amount DESC,
23
+ title = "Highest Fare Trips"
24
+ )
25
+ }
@@ -0,0 +1,13 @@
1
+ trip_id,pickup_date,pickup_hour,pickup_borough,dropoff_borough,payment_type,fare_amount,tip_amount,trip_miles,airport_flag
2
+ T-001,2025-01-03,6,Manhattan,Queens,Card,32.5,6.2,8.4,true
3
+ T-002,2025-01-03,7,Brooklyn,Manhattan,Card,21.4,4.1,5.6,false
4
+ T-003,2025-01-04,8,Queens,Manhattan,Cash,27.8,0,7.1,true
5
+ T-004,2025-01-04,9,Manhattan,Brooklyn,Card,18.9,3.7,4.9,false
6
+ T-005,2025-01-05,11,Bronx,Manhattan,Card,25.7,5.1,6.8,false
7
+ T-006,2025-01-05,12,Manhattan,Queens,Card,34.2,6.8,8.9,true
8
+ T-007,2025-01-06,13,Queens,Brooklyn,Card,19.3,3.5,5.2,false
9
+ T-008,2025-01-06,15,Manhattan,Manhattan,Card,14.6,3.2,2.8,false
10
+ T-009,2025-01-07,17,Brooklyn,Queens,Cash,16.8,0,4.1,false
11
+ T-010,2025-01-07,18,Manhattan,Staten Island,Card,41.1,7.4,12.3,false
12
+ T-011,2025-01-08,19,Queens,Manhattan,Card,29.6,5.9,7.7,true
13
+ T-012,2025-01-08,21,Brooklyn,Manhattan,Card,22.1,4.6,5.9,false
@@ -0,0 +1,13 @@
1
+ {
2
+ "project": "__PROJECT_NAME__",
3
+ "defaultConnection": {
4
+ "driver": "file",
5
+ "filepath": ":memory:"
6
+ },
7
+ "dataDir": "./data",
8
+ "preview": {
9
+ "port": 3474,
10
+ "open": true,
11
+ "theme": "dark"
12
+ }
13
+ }
@@ -0,0 +1,3 @@
1
+ import type { CLIFlags } from '../args.js';
2
+ export declare function runBuild(filePath: string, flags: CLIFlags): Promise<void>;
3
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAwC/E"}
@@ -0,0 +1,41 @@
1
+ import { mkdirSync, readFileSync } from 'node:fs';
2
+ import { basename, dirname, extname, join, resolve } from 'node:path';
3
+ import { compile, writeBundle } from '@duckcodeailabs/dql-compiler';
4
+ import { findProjectRoot, loadProjectConfig } from '../local-runtime.js';
5
+ export async function runBuild(filePath, flags) {
6
+ const absoluteFile = resolve(filePath);
7
+ const projectRoot = findProjectRoot(dirname(absoluteFile));
8
+ const config = loadProjectConfig(projectRoot);
9
+ const source = readFileSync(absoluteFile, 'utf-8');
10
+ const result = compile(source, {
11
+ file: absoluteFile,
12
+ theme: config.preview?.theme ?? 'light',
13
+ });
14
+ if (result.errors.length > 0) {
15
+ throw new Error(`Build failed:\n${result.errors.map((e) => `- ${e}`).join('\n')}`);
16
+ }
17
+ if (result.dashboards.length === 0) {
18
+ throw new Error('Build requires a charted block, dashboard, or workbook that compiles to HTML output.');
19
+ }
20
+ const name = basename(absoluteFile, extname(absoluteFile));
21
+ const outDir = resolve(flags.outDir || join(projectRoot, 'dist', name));
22
+ mkdirSync(outDir, { recursive: true });
23
+ writeBundle(result.dashboards[0], outDir);
24
+ if (flags.format === 'json') {
25
+ console.log(JSON.stringify({
26
+ source: absoluteFile,
27
+ outDir,
28
+ built: true,
29
+ files: ['index.html', 'dql-metadata.json', 'specs/'],
30
+ }, null, 2));
31
+ return;
32
+ }
33
+ console.log(`\n ✓ Built DQL bundle`);
34
+ console.log(` Source: ${absoluteFile}`);
35
+ console.log(` Output: ${outDir}`);
36
+ console.log('');
37
+ console.log(' Next step:');
38
+ console.log(` dql serve ${outDir}`);
39
+ console.log('');
40
+ }
41
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAEzE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB,EAAE,KAAe;IAC9D,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE;QAC7B,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,IAAI,OAAO;KACxC,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,kBAAkB,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,sFAAsF,CAAC,CAAC;IAC1G,CAAC;IAED,MAAM,IAAI,GAAG,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IACxE,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAE1C,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YACzB,MAAM,EAAE,YAAY;YACpB,MAAM;YACN,KAAK,EAAE,IAAI;YACX,KAAK,EAAE,CAAC,YAAY,EAAE,mBAAmB,EAAE,QAAQ,CAAC;SACrD,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACb,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,eAAe,YAAY,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,EAAE,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,EAAE,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=build.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.test.d.ts","sourceRoot":"","sources":["../../src/commands/build.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ import { mkdtempSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { tmpdir } from 'node:os';
4
+ import { describe, expect, it } from 'vitest';
5
+ import { runBuild } from './build.js';
6
+ describe('runBuild', () => {
7
+ it('writes an HTML bundle and metadata for a standalone block', async () => {
8
+ const projectDir = mkdtempSync(join(tmpdir(), 'dql-build-'));
9
+ const sourcePath = join(projectDir, 'sample.dql');
10
+ const outDir = join(projectDir, 'out');
11
+ writeFileSync(sourcePath, `block "Revenue Preview" {
12
+ domain = "revenue"
13
+ type = "custom"
14
+ query = """
15
+ SELECT 'Enterprise' AS segment, 100 AS revenue
16
+ """
17
+ visualization {
18
+ chart = "bar"
19
+ x = segment
20
+ y = revenue
21
+ }
22
+ }`);
23
+ await runBuild(sourcePath, {
24
+ check: false,
25
+ chart: '',
26
+ domain: '',
27
+ format: 'json',
28
+ help: false,
29
+ open: null,
30
+ input: '',
31
+ outDir,
32
+ owner: '',
33
+ port: null,
34
+ queryOnly: false,
35
+ template: 'starter',
36
+ verbose: false,
37
+ });
38
+ expect(readFileSync(join(outDir, 'index.html'), 'utf-8')).toContain('Revenue Preview');
39
+ expect(readFileSync(join(outDir, 'dql-metadata.json'), 'utf-8')).toContain('Revenue Preview');
40
+ });
41
+ });
42
+ //# sourceMappingURL=build.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.test.js","sourceRoot":"","sources":["../../src/commands/build.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;IACxB,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC;QAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAEvC,aAAa,CAAC,UAAU,EAAE;;;;;;;;;;;EAW5B,CAAC,CAAC;QAEA,MAAM,QAAQ,CAAC,UAAU,EAAE;YACzB,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,EAAE;YACV,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,EAAE;YACT,MAAM;YACN,KAAK,EAAE,EAAE;YACT,IAAI,EAAE,IAAI;YACV,SAAS,EAAE,KAAK;YAChB,QAAQ,EAAE,SAAS;YACnB,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QAEH,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QACvF,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;IAChG,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CLIFlags } from '../args.js';
2
+ export declare function runDoctor(targetPath: string | null, flags: CLIFlags): Promise<void>;
3
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAS3C,wBAAsB,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAmEzF"}
@@ -0,0 +1,127 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { join, resolve } from 'node:path';
3
+ import { QueryExecutor } from '@duckcodeailabs/dql-connectors';
4
+ import { assertLocalQueryRuntimeReady, findProjectRoot, loadProjectConfig } from '../local-runtime.js';
5
+ export async function runDoctor(targetPath, flags) {
6
+ const cwd = resolve(targetPath || '.');
7
+ const projectRoot = findProjectRoot(cwd);
8
+ const config = loadProjectConfig(projectRoot);
9
+ const checks = [
10
+ checkNodeVersion(),
11
+ {
12
+ name: 'Project root',
13
+ ok: existsSync(projectRoot),
14
+ detail: projectRoot,
15
+ },
16
+ {
17
+ name: 'dql.config.json',
18
+ ok: existsSync(join(projectRoot, 'dql.config.json')),
19
+ detail: existsSync(join(projectRoot, 'dql.config.json')) ? 'found' : 'missing',
20
+ },
21
+ {
22
+ name: 'blocks/',
23
+ ok: existsSync(join(projectRoot, 'blocks')),
24
+ detail: existsSync(join(projectRoot, 'blocks')) ? 'found' : 'missing',
25
+ },
26
+ {
27
+ name: 'semantic-layer/',
28
+ ok: existsSync(join(projectRoot, 'semantic-layer')),
29
+ detail: existsSync(join(projectRoot, 'semantic-layer')) ? 'found' : 'missing',
30
+ },
31
+ {
32
+ name: 'data/',
33
+ ok: existsSync(join(projectRoot, 'data')),
34
+ detail: existsSync(join(projectRoot, 'data')) ? 'found' : 'missing',
35
+ },
36
+ {
37
+ name: 'Default connection',
38
+ ok: Boolean(config.defaultConnection?.driver),
39
+ detail: config.defaultConnection?.driver ? `driver=${config.defaultConnection.driver}` : 'not configured',
40
+ },
41
+ ];
42
+ if (config.defaultConnection?.driver === 'file' || config.defaultConnection?.driver === 'duckdb') {
43
+ checks.push(checkDuckDBDependency(projectRoot));
44
+ }
45
+ if (config.defaultConnection?.driver) {
46
+ checks.push(await checkLocalQueryRuntime(projectRoot, config.defaultConnection));
47
+ }
48
+ const passed = checks.filter((check) => check.ok).length;
49
+ if (flags.format === 'json') {
50
+ console.log(JSON.stringify({
51
+ ok: passed === checks.length,
52
+ projectRoot,
53
+ checks,
54
+ }, null, 2));
55
+ return;
56
+ }
57
+ console.log(`\n DQL Doctor`);
58
+ console.log(` Project: ${projectRoot}`);
59
+ console.log('');
60
+ for (const check of checks) {
61
+ console.log(` ${check.ok ? '✓' : '✗'} ${check.name}`);
62
+ console.log(` ${check.detail}`);
63
+ }
64
+ console.log('');
65
+ console.log(` Summary: ${passed}/${checks.length} checks passed`);
66
+ console.log('');
67
+ }
68
+ function checkNodeVersion() {
69
+ const match = process.versions.node.match(/^(\d+)/);
70
+ const major = match ? Number(match[1]) : 0;
71
+ return {
72
+ name: 'Node.js',
73
+ ok: major >= 18,
74
+ detail: `version=${process.versions.node} (requires >= 18)`,
75
+ };
76
+ }
77
+ function checkDuckDBDependency(projectRoot) {
78
+ const packageJsonPath = join(projectRoot, 'package.json');
79
+ if (!existsSync(packageJsonPath)) {
80
+ return {
81
+ name: 'duckdb dependency',
82
+ ok: true,
83
+ detail: 'no project package.json; skipping dependency check',
84
+ };
85
+ }
86
+ try {
87
+ const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
88
+ const hasDuckDB = Boolean(pkg.dependencies?.duckdb || pkg.devDependencies?.duckdb);
89
+ return {
90
+ name: 'duckdb dependency',
91
+ ok: hasDuckDB,
92
+ detail: hasDuckDB ? 'duckdb listed in package.json' : 'add duckdb for file/duckdb local preview support',
93
+ };
94
+ }
95
+ catch {
96
+ return {
97
+ name: 'duckdb dependency',
98
+ ok: false,
99
+ detail: 'failed to parse package.json',
100
+ };
101
+ }
102
+ }
103
+ async function checkLocalQueryRuntime(projectRoot, connection) {
104
+ const previousCwd = process.cwd();
105
+ const executor = new QueryExecutor();
106
+ try {
107
+ process.chdir(projectRoot);
108
+ await assertLocalQueryRuntimeReady(executor, connection);
109
+ return {
110
+ name: 'Local query runtime',
111
+ ok: true,
112
+ detail: `driver=${connection.driver} is available`,
113
+ };
114
+ }
115
+ catch (error) {
116
+ return {
117
+ name: 'Local query runtime',
118
+ ok: false,
119
+ detail: error instanceof Error ? error.message : String(error),
120
+ };
121
+ }
122
+ finally {
123
+ process.chdir(previousCwd);
124
+ await executor.disconnect().catch(() => { });
125
+ }
126
+ }
127
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,OAAO,EAAE,4BAA4B,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAQvG,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,UAAyB,EAAE,KAAe;IACxE,MAAM,GAAG,GAAG,OAAO,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC;IACvC,MAAM,WAAW,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAE9C,MAAM,MAAM,GAAY;QACtB,gBAAgB,EAAE;QAClB;YACE,IAAI,EAAE,cAAc;YACpB,EAAE,EAAE,UAAU,CAAC,WAAW,CAAC;YAC3B,MAAM,EAAE,WAAW;SACpB;QACD;YACE,IAAI,EAAE,iBAAiB;YACvB,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;YACpD,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SAC/E;QACD;YACE,IAAI,EAAE,SAAS;YACf,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAC3C,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SACtE;QACD;YACE,IAAI,EAAE,iBAAiB;YACvB,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;YACnD,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SAC9E;QACD;YACE,IAAI,EAAE,OAAO;YACb,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YACzC,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;SACpE;QACD;YACE,IAAI,EAAE,oBAAoB;YAC1B,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC;YAC7C,MAAM,EAAE,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,gBAAgB;SAC1G;KACF,CAAC;IAEF,IAAI,MAAM,CAAC,iBAAiB,EAAE,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,iBAAiB,EAAE,MAAM,KAAK,QAAQ,EAAE,CAAC;QACjG,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC;IAClD,CAAC;IACD,IAAI,MAAM,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,MAAM,sBAAsB,CAAC,WAAW,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACnF,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;IAEzD,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YACzB,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM;YAC5B,WAAW;YACX,MAAM;SACP,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACb,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,gBAAgB,WAAW,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,IAAI,MAAM,CAAC,MAAM,gBAAgB,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,gBAAgB;IACvB,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3C,OAAO;QACL,IAAI,EAAE,SAAS;QACf,EAAE,EAAE,KAAK,IAAI,EAAE;QACf,MAAM,EAAE,WAAW,OAAO,CAAC,QAAQ,CAAC,IAAI,mBAAmB;KAC5D,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,WAAmB;IAChD,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAC1D,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACjC,OAAO;YACL,IAAI,EAAE,mBAAmB;YACzB,EAAE,EAAE,IAAI;YACR,MAAM,EAAE,oDAAoD;SAC7D,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAG5D,CAAC;QACF,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,IAAI,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QACnF,OAAO;YACL,IAAI,EAAE,mBAAmB;YACzB,EAAE,EAAE,SAAS;YACb,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC,kDAAkD;SACzG,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,IAAI,EAAE,mBAAmB;YACzB,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,8BAA8B;SACvC,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,WAAmB,EAAE,UAAkF;IAC3I,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,IAAI,aAAa,EAAE,CAAC;IAErC,IAAI,CAAC;QACH,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC3B,MAAM,4BAA4B,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QACzD,OAAO;YACL,IAAI,EAAE,qBAAqB;YAC3B,EAAE,EAAE,IAAI;YACR,MAAM,EAAE,UAAU,UAAU,CAAC,MAAM,eAAe;SACnD,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,IAAI,EAAE,qBAAqB;YAC3B,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC/D,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC3B,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=doctor.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.test.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,41 @@
1
+ import { mkdtempSync, mkdirSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { tmpdir } from 'node:os';
4
+ import { describe, expect, it, vi } from 'vitest';
5
+ import { runDoctor } from './doctor.js';
6
+ describe('runDoctor', () => {
7
+ it('reports health for a starter-like project', async () => {
8
+ const projectDir = mkdtempSync(join(tmpdir(), 'dql-doctor-'));
9
+ mkdirSync(join(projectDir, 'blocks'));
10
+ mkdirSync(join(projectDir, 'semantic-layer'));
11
+ mkdirSync(join(projectDir, 'data'));
12
+ writeFileSync(join(projectDir, 'dql.config.json'), JSON.stringify({
13
+ defaultConnection: { driver: 'file', filepath: ':memory:' },
14
+ }, null, 2));
15
+ writeFileSync(join(projectDir, 'package.json'), JSON.stringify({
16
+ dependencies: { duckdb: '^1.1.0' },
17
+ }, null, 2));
18
+ const spy = vi.spyOn(console, 'log').mockImplementation(() => { });
19
+ await runDoctor(projectDir, {
20
+ check: false,
21
+ chart: '',
22
+ domain: '',
23
+ format: 'text',
24
+ help: false,
25
+ open: null,
26
+ input: '',
27
+ outDir: '',
28
+ owner: '',
29
+ port: null,
30
+ queryOnly: false,
31
+ template: 'starter',
32
+ verbose: false,
33
+ });
34
+ expect(spy).toHaveBeenCalled();
35
+ const output = spy.mock.calls.flat().join('\n');
36
+ expect(output).toContain('DQL Doctor');
37
+ expect(output).toContain('blocks/');
38
+ spy.mockRestore();
39
+ });
40
+ });
41
+ //# sourceMappingURL=doctor.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.test.js","sourceRoot":"","sources":["../../src/commands/doctor.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;QAC9D,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;QACtC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC;QAC9C,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;QACpC,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;YAChE,iBAAiB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE;SAC5D,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACb,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;YAC7D,YAAY,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE;SACnC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAEb,MAAM,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAElE,MAAM,SAAS,CAAC,UAAU,EAAE;YAC1B,KAAK,EAAE,KAAK;YACZ,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,EAAE;YACV,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,EAAE;YACV,KAAK,EAAE,EAAE;YACT,IAAI,EAAE,IAAI;YACV,SAAS,EAAE,KAAK;YAChB,QAAQ,EAAE,SAAS;YACnB,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QAEH,MAAM,CAAC,GAAG,CAAC,CAAC,gBAAgB,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QACvC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACpC,GAAG,CAAC,WAAW,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { CLIFlags } from '../args.js';
2
+ export declare function runInit(targetArg: string | null, flags: CLIFlags): Promise<void>;
3
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAkB3C,wBAAsB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CA2DtF"}