@datachonk/cli 0.1.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.
- package/README.md +200 -0
- package/dist/__tests__/cache.test.d.ts +2 -0
- package/dist/__tests__/cache.test.d.ts.map +1 -0
- package/dist/__tests__/cache.test.js +40 -0
- package/dist/__tests__/cache.test.js.map +1 -0
- package/dist/__tests__/config.test.d.ts +2 -0
- package/dist/__tests__/config.test.d.ts.map +1 -0
- package/dist/__tests__/config.test.js +113 -0
- package/dist/__tests__/config.test.js.map +1 -0
- package/dist/__tests__/templates.test.d.ts +2 -0
- package/dist/__tests__/templates.test.d.ts.map +1 -0
- package/dist/__tests__/templates.test.js +51 -0
- package/dist/__tests__/templates.test.js.map +1 -0
- package/dist/commands/analyze.d.ts +10 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +156 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/chat.d.ts +3 -0
- package/dist/commands/chat.d.ts.map +1 -0
- package/dist/commands/chat.js +121 -0
- package/dist/commands/chat.js.map +1 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +287 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/docs.d.ts +7 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +208 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/commands/generate.d.ts +9 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +130 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +149 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/lineage.d.ts +9 -0
- package/dist/commands/lineage.d.ts.map +1 -0
- package/dist/commands/lineage.js +186 -0
- package/dist/commands/lineage.js.map +1 -0
- package/dist/commands/migrate.d.ts +3 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +213 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/review.d.ts +8 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +215 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/scan.d.ts +18 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +335 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/test.d.ts +3 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +244 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +232 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/analyzer.d.ts +39 -0
- package/dist/utils/analyzer.d.ts.map +1 -0
- package/dist/utils/analyzer.js +310 -0
- package/dist/utils/analyzer.js.map +1 -0
- package/dist/utils/cache.d.ts +98 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +253 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/config.d.ts +56 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +108 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/generators.d.ts +8 -0
- package/dist/utils/generators.d.ts.map +1 -0
- package/dist/utils/generators.js +265 -0
- package/dist/utils/generators.js.map +1 -0
- package/dist/utils/plugins.d.ts +94 -0
- package/dist/utils/plugins.d.ts.map +1 -0
- package/dist/utils/plugins.js +164 -0
- package/dist/utils/plugins.js.map +1 -0
- package/dist/utils/templates.d.ts +57 -0
- package/dist/utils/templates.d.ts.map +1 -0
- package/dist/utils/templates.js +458 -0
- package/dist/utils/templates.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
export function generateStagingModel(name, source, warehouse) {
|
|
2
|
+
const [schema, table] = source.includes(".") ? source.split(".").slice(-2) : ["raw", source];
|
|
3
|
+
const modelName = name.startsWith("stg_") ? name : `stg_${name}`;
|
|
4
|
+
const timestampCast = warehouse === "bigquery"
|
|
5
|
+
? "cast(created_at as timestamp)"
|
|
6
|
+
: "created_at::timestamp";
|
|
7
|
+
return `{{
|
|
8
|
+
config(
|
|
9
|
+
materialized='view',
|
|
10
|
+
tags=['staging']
|
|
11
|
+
)
|
|
12
|
+
}}
|
|
13
|
+
|
|
14
|
+
with source as (
|
|
15
|
+
select * from {{ source('${schema}', '${table}') }}
|
|
16
|
+
),
|
|
17
|
+
|
|
18
|
+
renamed as (
|
|
19
|
+
select
|
|
20
|
+
-- IDs
|
|
21
|
+
id as ${name}_id,
|
|
22
|
+
|
|
23
|
+
-- Strings
|
|
24
|
+
-- name,
|
|
25
|
+
-- status,
|
|
26
|
+
|
|
27
|
+
-- Numerics
|
|
28
|
+
-- amount,
|
|
29
|
+
|
|
30
|
+
-- Timestamps
|
|
31
|
+
${timestampCast} as created_at,
|
|
32
|
+
${timestampCast.replace("created_at", "updated_at")} as updated_at
|
|
33
|
+
|
|
34
|
+
from source
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
select * from renamed
|
|
38
|
+
`;
|
|
39
|
+
}
|
|
40
|
+
export function generateIntermediateModel(name, source, warehouse) {
|
|
41
|
+
const modelName = name.startsWith("int_") ? name : `int_${name}`;
|
|
42
|
+
const sourceRef = source.startsWith("stg_") || source.startsWith("int_")
|
|
43
|
+
? source
|
|
44
|
+
: `stg_${source}`;
|
|
45
|
+
return `{{
|
|
46
|
+
config(
|
|
47
|
+
materialized='view',
|
|
48
|
+
tags=['intermediate']
|
|
49
|
+
)
|
|
50
|
+
}}
|
|
51
|
+
|
|
52
|
+
with ${sourceRef.replace(/^(stg_|int_)/, "")} as (
|
|
53
|
+
select * from {{ ref('${sourceRef}') }}
|
|
54
|
+
),
|
|
55
|
+
|
|
56
|
+
-- Add business logic transformations here
|
|
57
|
+
transformed as (
|
|
58
|
+
select
|
|
59
|
+
*,
|
|
60
|
+
-- Example: Add derived columns
|
|
61
|
+
-- case
|
|
62
|
+
-- when status = 'active' then true
|
|
63
|
+
-- else false
|
|
64
|
+
-- end as is_active
|
|
65
|
+
|
|
66
|
+
from ${sourceRef.replace(/^(stg_|int_)/, "")}
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
select * from transformed
|
|
70
|
+
`;
|
|
71
|
+
}
|
|
72
|
+
export function generateMartModel(name, source, type, warehouse) {
|
|
73
|
+
const prefix = type === "fact" ? "fct" : "dim";
|
|
74
|
+
const modelName = name.startsWith(`${prefix}_`) ? name : `${prefix}_${name}`;
|
|
75
|
+
if (type === "dimension") {
|
|
76
|
+
return `{{
|
|
77
|
+
config(
|
|
78
|
+
materialized='table',
|
|
79
|
+
tags=['mart', 'dimension']
|
|
80
|
+
)
|
|
81
|
+
}}
|
|
82
|
+
|
|
83
|
+
with source as (
|
|
84
|
+
select * from {{ ref('${source}') }}
|
|
85
|
+
),
|
|
86
|
+
|
|
87
|
+
final as (
|
|
88
|
+
select
|
|
89
|
+
-- Surrogate key
|
|
90
|
+
{{ dbt_utils.generate_surrogate_key(['${name}_id']) }} as ${name}_key,
|
|
91
|
+
|
|
92
|
+
-- Natural key
|
|
93
|
+
${name}_id,
|
|
94
|
+
|
|
95
|
+
-- Attributes
|
|
96
|
+
-- name,
|
|
97
|
+
-- description,
|
|
98
|
+
-- type,
|
|
99
|
+
|
|
100
|
+
-- Metadata
|
|
101
|
+
created_at,
|
|
102
|
+
updated_at,
|
|
103
|
+
current_timestamp() as dbt_updated_at
|
|
104
|
+
|
|
105
|
+
from source
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
select * from final
|
|
109
|
+
`;
|
|
110
|
+
}
|
|
111
|
+
// Fact table
|
|
112
|
+
return `{{
|
|
113
|
+
config(
|
|
114
|
+
materialized='incremental',
|
|
115
|
+
unique_key='${name}_id',
|
|
116
|
+
tags=['mart', 'fact'],
|
|
117
|
+
incremental_strategy='merge'
|
|
118
|
+
)
|
|
119
|
+
}}
|
|
120
|
+
|
|
121
|
+
with source as (
|
|
122
|
+
select * from {{ ref('${source}') }}
|
|
123
|
+
{% if is_incremental() %}
|
|
124
|
+
where updated_at > (select max(updated_at) from {{ this }})
|
|
125
|
+
and updated_at < current_timestamp()
|
|
126
|
+
{% endif %}
|
|
127
|
+
),
|
|
128
|
+
|
|
129
|
+
final as (
|
|
130
|
+
select
|
|
131
|
+
-- Keys
|
|
132
|
+
${name}_id,
|
|
133
|
+
-- Add dimension foreign keys here
|
|
134
|
+
-- customer_key,
|
|
135
|
+
-- product_key,
|
|
136
|
+
|
|
137
|
+
-- Measures
|
|
138
|
+
-- quantity,
|
|
139
|
+
-- amount,
|
|
140
|
+
|
|
141
|
+
-- Degenerate dimensions
|
|
142
|
+
-- order_number,
|
|
143
|
+
|
|
144
|
+
-- Timestamps
|
|
145
|
+
created_at,
|
|
146
|
+
updated_at,
|
|
147
|
+
current_timestamp() as dbt_updated_at
|
|
148
|
+
|
|
149
|
+
from source
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
select * from final
|
|
153
|
+
`;
|
|
154
|
+
}
|
|
155
|
+
export function generateSnapshot(name, source, warehouse) {
|
|
156
|
+
const [schema, table] = source.includes(".") ? source.split(".").slice(-2) : ["raw", source];
|
|
157
|
+
return `{% snapshot ${name}_snapshot %}
|
|
158
|
+
|
|
159
|
+
{{
|
|
160
|
+
config(
|
|
161
|
+
target_schema='snapshots',
|
|
162
|
+
unique_key='id',
|
|
163
|
+
strategy='timestamp',
|
|
164
|
+
updated_at='updated_at',
|
|
165
|
+
invalidate_hard_deletes=True
|
|
166
|
+
)
|
|
167
|
+
}}
|
|
168
|
+
|
|
169
|
+
select * from {{ source('${schema}', '${table}') }}
|
|
170
|
+
|
|
171
|
+
{% endsnapshot %}
|
|
172
|
+
`;
|
|
173
|
+
}
|
|
174
|
+
export function generateSourceYaml(name, source) {
|
|
175
|
+
const [schema, table] = source.includes(".") ? source.split(".").slice(-2) : [name, source || "table_name"];
|
|
176
|
+
return `version: 2
|
|
177
|
+
|
|
178
|
+
sources:
|
|
179
|
+
- name: ${schema}
|
|
180
|
+
description: "Source data from ${schema}"
|
|
181
|
+
database: "{{ env_var('DBT_DATABASE', 'your_database') }}"
|
|
182
|
+
schema: ${schema}
|
|
183
|
+
|
|
184
|
+
tables:
|
|
185
|
+
- name: ${table}
|
|
186
|
+
description: "Raw ${table} data"
|
|
187
|
+
columns:
|
|
188
|
+
- name: id
|
|
189
|
+
description: "Primary key"
|
|
190
|
+
data_tests:
|
|
191
|
+
- unique
|
|
192
|
+
- not_null
|
|
193
|
+
- name: created_at
|
|
194
|
+
description: "Timestamp when record was created"
|
|
195
|
+
- name: updated_at
|
|
196
|
+
description: "Timestamp when record was last updated"
|
|
197
|
+
|
|
198
|
+
freshness:
|
|
199
|
+
warn_after: { count: 12, period: hour }
|
|
200
|
+
error_after: { count: 24, period: hour }
|
|
201
|
+
loaded_at_field: updated_at
|
|
202
|
+
`;
|
|
203
|
+
}
|
|
204
|
+
export function generateTests(name, source) {
|
|
205
|
+
return `-- Custom data test for ${name}
|
|
206
|
+
-- Tests that ${name} data meets business requirements
|
|
207
|
+
|
|
208
|
+
with validation as (
|
|
209
|
+
select
|
|
210
|
+
${name}_id,
|
|
211
|
+
-- Add validation logic here
|
|
212
|
+
case
|
|
213
|
+
when ${name}_id is null then 'missing_id'
|
|
214
|
+
-- Add more validation rules
|
|
215
|
+
else null
|
|
216
|
+
end as validation_error
|
|
217
|
+
|
|
218
|
+
from {{ ref('${source || name}') }}
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
select *
|
|
222
|
+
from validation
|
|
223
|
+
where validation_error is not null
|
|
224
|
+
`;
|
|
225
|
+
}
|
|
226
|
+
export function generateDocs(name, type, source) {
|
|
227
|
+
const description = getModelDescription(name, type, source);
|
|
228
|
+
return `version: 2
|
|
229
|
+
|
|
230
|
+
models:
|
|
231
|
+
- name: ${name}
|
|
232
|
+
description: "${description}"
|
|
233
|
+
|
|
234
|
+
columns:
|
|
235
|
+
- name: ${name.replace(/^(stg_|int_|fct_|dim_)/, "")}_id
|
|
236
|
+
description: "Primary key"
|
|
237
|
+
data_tests:
|
|
238
|
+
- unique
|
|
239
|
+
- not_null
|
|
240
|
+
|
|
241
|
+
- name: created_at
|
|
242
|
+
description: "Timestamp when record was created"
|
|
243
|
+
|
|
244
|
+
- name: updated_at
|
|
245
|
+
description: "Timestamp when record was last updated"
|
|
246
|
+
`;
|
|
247
|
+
}
|
|
248
|
+
function getModelDescription(name, type, source) {
|
|
249
|
+
const baseName = name.replace(/^(stg_|int_|fct_|dim_|obt_)/, "").replace(/_/g, " ");
|
|
250
|
+
switch (type) {
|
|
251
|
+
case "staging":
|
|
252
|
+
return `Staging model for ${baseName}. Provides cleaned and typed source data from ${source || "raw source"}.`;
|
|
253
|
+
case "intermediate":
|
|
254
|
+
return `Intermediate model for ${baseName}. Applies business logic and transformations.`;
|
|
255
|
+
case "fact":
|
|
256
|
+
return `Fact table for ${baseName}. Contains measurable, quantitative data for analysis.`;
|
|
257
|
+
case "dimension":
|
|
258
|
+
return `Dimension table for ${baseName}. Contains descriptive attributes for slicing and dicing facts.`;
|
|
259
|
+
case "mart":
|
|
260
|
+
return `Mart model for ${baseName}. Business-ready data model for analytics and reporting.`;
|
|
261
|
+
default:
|
|
262
|
+
return `Model for ${baseName} data.`;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=generators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generators.js","sourceRoot":"","sources":["../../src/utils/generators.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Architecture for DataChonk CLI
|
|
3
|
+
*
|
|
4
|
+
* Plugins can extend DataChonk functionality:
|
|
5
|
+
* - Custom warehouse parsers (Snowflake-specific, BigQuery-specific)
|
|
6
|
+
* - Custom SQL dialects
|
|
7
|
+
* - Business logic extractors
|
|
8
|
+
* - Template generators
|
|
9
|
+
* - Validation hooks
|
|
10
|
+
*/
|
|
11
|
+
export interface PluginContext {
|
|
12
|
+
config: Record<string, unknown>;
|
|
13
|
+
cwd: string;
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface ParserPlugin {
|
|
17
|
+
name: string;
|
|
18
|
+
type: "parser";
|
|
19
|
+
supportedWarehouses: string[];
|
|
20
|
+
parse: (sql: string, context: PluginContext) => Promise<ParseResult>;
|
|
21
|
+
}
|
|
22
|
+
export interface GeneratorPlugin {
|
|
23
|
+
name: string;
|
|
24
|
+
type: "generator";
|
|
25
|
+
templates: string[];
|
|
26
|
+
generate: (templateName: string, context: PluginContext) => Promise<string>;
|
|
27
|
+
}
|
|
28
|
+
export interface ValidatorPlugin {
|
|
29
|
+
name: string;
|
|
30
|
+
type: "validator";
|
|
31
|
+
validate: (code: string, context: PluginContext) => Promise<ValidationResult[]>;
|
|
32
|
+
}
|
|
33
|
+
export type Plugin = ParserPlugin | GeneratorPlugin | ValidatorPlugin;
|
|
34
|
+
export interface ParseResult {
|
|
35
|
+
tables: Array<{
|
|
36
|
+
name: string;
|
|
37
|
+
alias?: string;
|
|
38
|
+
}>;
|
|
39
|
+
columns: Array<{
|
|
40
|
+
name: string;
|
|
41
|
+
table?: string;
|
|
42
|
+
}>;
|
|
43
|
+
ctes: Array<{
|
|
44
|
+
name: string;
|
|
45
|
+
sql: string;
|
|
46
|
+
}>;
|
|
47
|
+
functions: string[];
|
|
48
|
+
warnings: string[];
|
|
49
|
+
}
|
|
50
|
+
export interface ValidationResult {
|
|
51
|
+
level: "error" | "warning" | "info";
|
|
52
|
+
message: string;
|
|
53
|
+
line?: number;
|
|
54
|
+
column?: number;
|
|
55
|
+
rule: string;
|
|
56
|
+
fix?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Load plugins from plugin directories and npm packages
|
|
60
|
+
*/
|
|
61
|
+
export declare function loadPlugins(): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Register a plugin
|
|
64
|
+
*/
|
|
65
|
+
export declare function registerPlugin(plugin: Plugin): void;
|
|
66
|
+
/**
|
|
67
|
+
* Get all registered plugins
|
|
68
|
+
*/
|
|
69
|
+
export declare function getPlugins(): Plugin[];
|
|
70
|
+
/**
|
|
71
|
+
* Get plugins by type
|
|
72
|
+
*/
|
|
73
|
+
export declare function getPluginsByType<T extends Plugin>(type: T["type"]): T[];
|
|
74
|
+
/**
|
|
75
|
+
* Get parser plugins for a specific warehouse
|
|
76
|
+
*/
|
|
77
|
+
export declare function getParsersForWarehouse(warehouse: string): ParserPlugin[];
|
|
78
|
+
/**
|
|
79
|
+
* Get generator plugins with a specific template
|
|
80
|
+
*/
|
|
81
|
+
export declare function getGeneratorsForTemplate(template: string): GeneratorPlugin[];
|
|
82
|
+
/**
|
|
83
|
+
* Run all validators on code
|
|
84
|
+
*/
|
|
85
|
+
export declare function runValidators(code: string, context: PluginContext): Promise<ValidationResult[]>;
|
|
86
|
+
/**
|
|
87
|
+
* Default SQL parser plugin
|
|
88
|
+
*/
|
|
89
|
+
export declare const defaultParserPlugin: ParserPlugin;
|
|
90
|
+
/**
|
|
91
|
+
* Create a custom plugin
|
|
92
|
+
*/
|
|
93
|
+
export declare function createPlugin<T extends Plugin>(config: T): T;
|
|
94
|
+
//# sourceMappingURL=plugins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/utils/plugins.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
// Plugin registry
|
|
5
|
+
const plugins = new Map();
|
|
6
|
+
// Built-in plugin locations
|
|
7
|
+
const PLUGIN_DIRS = [
|
|
8
|
+
join(process.cwd(), ".datachonk", "plugins"),
|
|
9
|
+
join(process.env.HOME || "~", ".datachonk", "plugins"),
|
|
10
|
+
];
|
|
11
|
+
/**
|
|
12
|
+
* Load plugins from plugin directories and npm packages
|
|
13
|
+
*/
|
|
14
|
+
export async function loadPlugins() {
|
|
15
|
+
// Load from plugin directories
|
|
16
|
+
for (const dir of PLUGIN_DIRS) {
|
|
17
|
+
if (existsSync(dir)) {
|
|
18
|
+
const files = readdirSync(dir).filter((f) => f.endsWith(".js") || f.endsWith(".mjs"));
|
|
19
|
+
for (const file of files) {
|
|
20
|
+
try {
|
|
21
|
+
const plugin = await import(join(dir, file));
|
|
22
|
+
if (plugin.default && isValidPlugin(plugin.default)) {
|
|
23
|
+
registerPlugin(plugin.default);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
console.warn(chalk.yellow(`Failed to load plugin ${file}: ${err}`));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Load npm plugins (packages starting with datachonk-plugin-)
|
|
33
|
+
try {
|
|
34
|
+
const packageJson = JSON.parse(readFileSync(join(process.cwd(), "package.json"), "utf-8"));
|
|
35
|
+
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
36
|
+
for (const [name] of Object.entries(deps)) {
|
|
37
|
+
if (name.startsWith("datachonk-plugin-")) {
|
|
38
|
+
try {
|
|
39
|
+
const plugin = await import(name);
|
|
40
|
+
if (plugin.default && isValidPlugin(plugin.default)) {
|
|
41
|
+
registerPlugin(plugin.default);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
console.warn(chalk.yellow(`Failed to load plugin ${name}: ${err}`));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// No package.json or error reading it
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Validate plugin structure
|
|
56
|
+
*/
|
|
57
|
+
function isValidPlugin(obj) {
|
|
58
|
+
if (!obj || typeof obj !== "object")
|
|
59
|
+
return false;
|
|
60
|
+
const p = obj;
|
|
61
|
+
return (typeof p.name === "string" &&
|
|
62
|
+
typeof p.type === "string" &&
|
|
63
|
+
["parser", "generator", "validator"].includes(p.type));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Register a plugin
|
|
67
|
+
*/
|
|
68
|
+
export function registerPlugin(plugin) {
|
|
69
|
+
plugins.set(plugin.name, plugin);
|
|
70
|
+
console.log(chalk.gray(`Loaded plugin: ${plugin.name} (${plugin.type})`));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get all registered plugins
|
|
74
|
+
*/
|
|
75
|
+
export function getPlugins() {
|
|
76
|
+
return Array.from(plugins.values());
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Get plugins by type
|
|
80
|
+
*/
|
|
81
|
+
export function getPluginsByType(type) {
|
|
82
|
+
return Array.from(plugins.values()).filter((p) => p.type === type);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get parser plugins for a specific warehouse
|
|
86
|
+
*/
|
|
87
|
+
export function getParsersForWarehouse(warehouse) {
|
|
88
|
+
return getPluginsByType("parser").filter((p) => p.supportedWarehouses.includes(warehouse) || p.supportedWarehouses.includes("*"));
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get generator plugins with a specific template
|
|
92
|
+
*/
|
|
93
|
+
export function getGeneratorsForTemplate(template) {
|
|
94
|
+
return getPluginsByType("generator").filter((p) => p.templates.includes(template) || p.templates.includes("*"));
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Run all validators on code
|
|
98
|
+
*/
|
|
99
|
+
export async function runValidators(code, context) {
|
|
100
|
+
const validators = getPluginsByType("validator");
|
|
101
|
+
const results = [];
|
|
102
|
+
for (const validator of validators) {
|
|
103
|
+
try {
|
|
104
|
+
const validatorResults = await validator.validate(code, context);
|
|
105
|
+
results.push(...validatorResults);
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
results.push({
|
|
109
|
+
level: "warning",
|
|
110
|
+
message: `Validator ${validator.name} failed: ${err}`,
|
|
111
|
+
rule: "plugin-error",
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return results;
|
|
116
|
+
}
|
|
117
|
+
// Built-in plugins
|
|
118
|
+
/**
|
|
119
|
+
* Default SQL parser plugin
|
|
120
|
+
*/
|
|
121
|
+
export const defaultParserPlugin = {
|
|
122
|
+
name: "default-parser",
|
|
123
|
+
type: "parser",
|
|
124
|
+
supportedWarehouses: ["*"],
|
|
125
|
+
async parse(sql) {
|
|
126
|
+
const tables = [];
|
|
127
|
+
const columns = [];
|
|
128
|
+
const ctes = [];
|
|
129
|
+
const functions = [];
|
|
130
|
+
const warnings = [];
|
|
131
|
+
// Simple regex-based parsing (plugins can provide more sophisticated parsing)
|
|
132
|
+
// Extract CTEs
|
|
133
|
+
const cteRegex = /(\w+)\s+as\s*\(\s*([\s\S]*?)\s*\)(?=\s*,\s*\w+\s+as\s*\(|\s*select)/gi;
|
|
134
|
+
let match;
|
|
135
|
+
while ((match = cteRegex.exec(sql)) !== null) {
|
|
136
|
+
ctes.push({ name: match[1], sql: match[2] });
|
|
137
|
+
}
|
|
138
|
+
// Extract table references
|
|
139
|
+
const fromRegex = /(?:from|join)\s+([`"']?[\w.]+[`"']?)(?:\s+(?:as\s+)?(\w+))?/gi;
|
|
140
|
+
while ((match = fromRegex.exec(sql)) !== null) {
|
|
141
|
+
tables.push({ name: match[1].replace(/[`"']/g, ""), alias: match[2] });
|
|
142
|
+
}
|
|
143
|
+
// Extract function calls
|
|
144
|
+
const funcRegex = /\b(\w+)\s*\(/g;
|
|
145
|
+
const seenFuncs = new Set();
|
|
146
|
+
while ((match = funcRegex.exec(sql)) !== null) {
|
|
147
|
+
const func = match[1].toLowerCase();
|
|
148
|
+
if (!seenFuncs.has(func) && !["select", "from", "where", "and", "or", "case", "when"].includes(func)) {
|
|
149
|
+
seenFuncs.add(func);
|
|
150
|
+
functions.push(func);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return { tables, columns, ctes, functions, warnings };
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
// Register built-in plugins
|
|
157
|
+
registerPlugin(defaultParserPlugin);
|
|
158
|
+
/**
|
|
159
|
+
* Create a custom plugin
|
|
160
|
+
*/
|
|
161
|
+
export function createPlugin(config) {
|
|
162
|
+
return config;
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=plugins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../src/utils/plugins.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template System for DataChonk CLI
|
|
3
|
+
*
|
|
4
|
+
* Allows teams to customize dbt code patterns via configurable Jinja templates.
|
|
5
|
+
* Templates can be stored locally or fetched from a remote registry.
|
|
6
|
+
*/
|
|
7
|
+
export interface TemplateVariable {
|
|
8
|
+
name: string;
|
|
9
|
+
type: "string" | "boolean" | "array" | "object";
|
|
10
|
+
required: boolean;
|
|
11
|
+
default?: unknown;
|
|
12
|
+
description?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface Template {
|
|
15
|
+
name: string;
|
|
16
|
+
version: string;
|
|
17
|
+
description: string;
|
|
18
|
+
category: "staging" | "intermediate" | "mart" | "snapshot" | "source" | "test" | "macro" | "custom";
|
|
19
|
+
variables: TemplateVariable[];
|
|
20
|
+
content: string;
|
|
21
|
+
author?: string;
|
|
22
|
+
tags?: string[];
|
|
23
|
+
}
|
|
24
|
+
export interface TemplateRegistry {
|
|
25
|
+
templates: Map<string, Template>;
|
|
26
|
+
customDir: string;
|
|
27
|
+
builtInDir: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Initialize the template registry
|
|
31
|
+
*/
|
|
32
|
+
export declare function initTemplates(): TemplateRegistry;
|
|
33
|
+
/**
|
|
34
|
+
* Get a template by name
|
|
35
|
+
*/
|
|
36
|
+
export declare function getTemplate(name: string): Template | null;
|
|
37
|
+
/**
|
|
38
|
+
* List all available templates
|
|
39
|
+
*/
|
|
40
|
+
export declare function listTemplates(category?: string): Template[];
|
|
41
|
+
/**
|
|
42
|
+
* Render a template with variables
|
|
43
|
+
*/
|
|
44
|
+
export declare function renderTemplate(templateName: string, variables: Record<string, unknown>): string;
|
|
45
|
+
/**
|
|
46
|
+
* Save a custom template
|
|
47
|
+
*/
|
|
48
|
+
export declare function saveTemplate(template: Template, location?: "project" | "user"): void;
|
|
49
|
+
/**
|
|
50
|
+
* Delete a custom template
|
|
51
|
+
*/
|
|
52
|
+
export declare function deleteTemplate(name: string): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Print available templates
|
|
55
|
+
*/
|
|
56
|
+
export declare function printTemplates(): void;
|
|
57
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/utils/templates.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;IAChD,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,SAAS,GAAG,cAAc,GAAG,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpG,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAqRD;;GAEG;AACH,wBAAgB,aAAa,IAAI,gBAAgB,CAmBhD;AAuCD;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAGzD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,EAAE,CAU3D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,MAAM,CAuER;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,GAAE,SAAS,GAAG,MAAkB,GAAG,IAAI,CAgB/F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAUpD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAiBrC"}
|