@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.
- package/README.md +62 -0
- package/dist/args.d.ts +9 -0
- package/dist/args.d.ts.map +1 -1
- package/dist/args.js +43 -1
- package/dist/args.js.map +1 -1
- package/dist/args.test.d.ts +2 -0
- package/dist/args.test.d.ts.map +1 -0
- package/dist/args.test.js +33 -0
- package/dist/args.test.js.map +1 -0
- package/dist/assets/notebook-browser/app.js +537 -0
- package/dist/assets/notebook-browser/index.html +83 -0
- package/dist/assets/notebook-browser/styles.css +336 -0
- package/dist/assets/templates/ecommerce/README.md +27 -0
- package/dist/assets/templates/ecommerce/blocks/repeat_rate.dql +26 -0
- package/dist/assets/templates/ecommerce/blocks/revenue_by_segment.dql +24 -0
- package/dist/assets/templates/ecommerce/dashboards/revenue_command_center.dql +25 -0
- package/dist/assets/templates/ecommerce/data/customers.csv +11 -0
- package/dist/assets/templates/ecommerce/data/funnel.csv +6 -0
- package/dist/assets/templates/ecommerce/data/orders.csv +16 -0
- package/dist/assets/templates/ecommerce/dql.config.json +13 -0
- package/dist/assets/templates/ecommerce/semantic-layer/dimensions/channel.yaml +4 -0
- package/dist/assets/templates/ecommerce/semantic-layer/metrics/gmv.yaml +4 -0
- package/dist/assets/templates/ecommerce/workbooks/.gitkeep +1 -0
- package/dist/assets/templates/saas/README.md +20 -0
- package/dist/assets/templates/saas/blocks/churn_pressure.dql +25 -0
- package/dist/assets/templates/saas/blocks/revenue_by_segment.dql +25 -0
- package/dist/assets/templates/saas/dashboards/growth_scorecard.dql +25 -0
- package/dist/assets/templates/saas/data/cohorts.csv +7 -0
- package/dist/assets/templates/saas/data/subscriptions.csv +13 -0
- package/dist/assets/templates/saas/dql.config.json +13 -0
- package/dist/assets/templates/saas/semantic-layer/metrics/mrr.yaml +4 -0
- package/dist/assets/templates/saas/workbooks/.gitkeep +1 -0
- package/dist/assets/templates/starter/README.md +54 -0
- package/dist/assets/templates/starter/blocks/revenue_by_segment.dql +29 -0
- package/dist/assets/templates/starter/blocks/revenue_trend_query_only.dql +20 -0
- package/dist/assets/templates/starter/dashboards/.gitkeep +1 -0
- package/dist/assets/templates/starter/data/revenue.csv +13 -0
- package/dist/assets/templates/starter/dql.config.json +13 -0
- package/dist/assets/templates/starter/semantic-layer/blocks/revenue_by_segment.yaml +11 -0
- package/dist/assets/templates/starter/semantic-layer/dimensions/segment_tier.yaml +6 -0
- package/dist/assets/templates/starter/semantic-layer/hierarchies/revenue_time.yaml +12 -0
- package/dist/assets/templates/starter/semantic-layer/metrics/revenue.yaml +7 -0
- package/dist/assets/templates/starter/workbooks/.gitkeep +1 -0
- package/dist/assets/templates/taxi/README.md +19 -0
- package/dist/assets/templates/taxi/blocks/airport_mix.dql +25 -0
- package/dist/assets/templates/taxi/blocks/revenue_by_segment.dql +24 -0
- package/dist/assets/templates/taxi/dashboards/city_operations.dql +25 -0
- package/dist/assets/templates/taxi/data/trips.csv +13 -0
- package/dist/assets/templates/taxi/dql.config.json +13 -0
- package/dist/assets/templates/taxi/semantic-layer/.gitkeep +1 -0
- package/dist/assets/templates/taxi/workbooks/.gitkeep +1 -0
- package/dist/commands/build.d.ts +3 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +41 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/build.test.d.ts +2 -0
- package/dist/commands/build.test.d.ts.map +1 -0
- package/dist/commands/build.test.js +42 -0
- package/dist/commands/build.test.js.map +1 -0
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +127 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/doctor.test.d.ts +2 -0
- package/dist/commands/doctor.test.d.ts.map +1 -0
- package/dist/commands/doctor.test.js +41 -0
- package/dist/commands/doctor.test.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +117 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/init.test.d.ts +2 -0
- package/dist/commands/init.test.d.ts.map +1 -0
- package/dist/commands/init.test.js +38 -0
- package/dist/commands/init.test.js.map +1 -0
- package/dist/commands/migrate.js +4 -4
- package/dist/commands/migrate.js.map +1 -1
- package/dist/commands/new.d.ts +3 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +405 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/new.test.d.ts +2 -0
- package/dist/commands/new.test.d.ts.map +1 -0
- package/dist/commands/new.test.js +177 -0
- package/dist/commands/new.test.js.map +1 -0
- package/dist/commands/notebook.d.ts +3 -0
- package/dist/commands/notebook.d.ts.map +1 -0
- package/dist/commands/notebook.js +31 -0
- package/dist/commands/notebook.js.map +1 -0
- package/dist/commands/preview.d.ts +3 -0
- package/dist/commands/preview.d.ts.map +1 -0
- package/dist/commands/preview.js +42 -0
- package/dist/commands/preview.js.map +1 -0
- package/dist/commands/serve.d.ts +3 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +30 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/index.js +46 -2
- package/dist/index.js.map +1 -1
- package/dist/local-runtime.d.ts +25 -0
- package/dist/local-runtime.d.ts.map +1 -0
- package/dist/local-runtime.js +302 -0
- package/dist/local-runtime.js.map +1 -0
- package/dist/local-runtime.test.d.ts +2 -0
- package/dist/local-runtime.test.d.ts.map +1 -0
- package/dist/local-runtime.test.js +21 -0
- package/dist/local-runtime.test.js.map +1 -0
- package/dist/open-browser.d.ts +2 -0
- package/dist/open-browser.d.ts.map +1 -0
- package/dist/open-browser.js +29 -0
- package/dist/open-browser.js.map +1 -0
- 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 @@
|
|
|
1
|
+
|
|
@@ -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,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,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 @@
|
|
|
1
|
+
|
|
@@ -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 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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":"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"}
|
|
@@ -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 @@
|
|
|
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"}
|