@tinybirdco/sdk 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +301 -205
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/init.test.js +67 -93
- package/dist/cli/commands/init.test.js.map +1 -1
- package/dist/cli/config.d.ts +3 -7
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +9 -20
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/config.test.js +11 -29
- package/dist/cli/config.test.js.map +1 -1
- package/dist/cli/git.d.ts +5 -0
- package/dist/cli/git.d.ts.map +1 -1
- package/dist/cli/git.js +15 -0
- package/dist/cli/git.js.map +1 -1
- package/dist/cli/index.js +42 -25
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/package-manager.d.ts +9 -0
- package/dist/cli/utils/package-manager.d.ts.map +1 -1
- package/dist/cli/utils/package-manager.js +130 -35
- package/dist/cli/utils/package-manager.js.map +1 -1
- package/dist/cli/utils/package-manager.test.js +124 -32
- package/dist/cli/utils/package-manager.test.js.map +1 -1
- package/dist/codegen/index.d.ts +4 -0
- package/dist/codegen/index.d.ts.map +1 -1
- package/dist/codegen/index.js +92 -0
- package/dist/codegen/index.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/init.test.ts +67 -107
- package/src/cli/commands/init.ts +350 -218
- package/src/cli/config.test.ts +12 -42
- package/src/cli/config.ts +9 -23
- package/src/cli/git.ts +15 -0
- package/src/cli/index.ts +46 -27
- package/src/cli/utils/package-manager.test.ts +165 -33
- package/src/cli/utils/package-manager.ts +133 -30
- package/src/codegen/index.ts +115 -0
|
@@ -3,42 +3,145 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { existsSync, readFileSync } from "node:fs";
|
|
6
|
-
import { join } from "node:path";
|
|
6
|
+
import { dirname, join, resolve } from "node:path";
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if (existsSync(join(
|
|
14
|
-
|
|
8
|
+
export type PackageManager = "pnpm" | "yarn" | "bun" | "npm";
|
|
9
|
+
const TINYBIRD_SDK_PACKAGE = "@tinybirdco/sdk";
|
|
10
|
+
|
|
11
|
+
function detectPackageManagerFromLockfile(dir: string): PackageManager | undefined {
|
|
12
|
+
if (existsSync(join(dir, "pnpm-lock.yaml"))) return "pnpm";
|
|
13
|
+
if (existsSync(join(dir, "yarn.lock"))) return "yarn";
|
|
14
|
+
if (existsSync(join(dir, "bun.lockb"))) return "bun";
|
|
15
|
+
if (existsSync(join(dir, "package-lock.json"))) return "npm";
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function detectPackageManagerFromWorkspace(dir: string): PackageManager | undefined {
|
|
20
|
+
if (existsSync(join(dir, "pnpm-workspace.yaml"))) return "pnpm";
|
|
21
|
+
if (existsSync(join(dir, "pnpm-workspace.yml"))) return "pnpm";
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function detectPackageManagerFromPackageJson(
|
|
26
|
+
dir: string
|
|
27
|
+
): PackageManager | undefined {
|
|
28
|
+
const packageJsonPath = join(dir, "package.json");
|
|
29
|
+
if (!existsSync(packageJsonPath)) return undefined;
|
|
30
|
+
try {
|
|
31
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
32
|
+
const pm = packageJson.packageManager;
|
|
33
|
+
if (typeof pm !== "string") return undefined;
|
|
34
|
+
if (pm.startsWith("pnpm")) return "pnpm";
|
|
35
|
+
if (pm.startsWith("yarn")) return "yarn";
|
|
36
|
+
if (pm.startsWith("bun")) return "bun";
|
|
37
|
+
if (pm.startsWith("npm")) return "npm";
|
|
38
|
+
} catch {
|
|
39
|
+
return undefined;
|
|
15
40
|
}
|
|
16
|
-
|
|
17
|
-
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function getSearchDirs(start: string): string[] {
|
|
45
|
+
const dirs: string[] = [];
|
|
46
|
+
let current = resolve(start);
|
|
47
|
+
while (true) {
|
|
48
|
+
dirs.push(current);
|
|
49
|
+
const parent = dirname(current);
|
|
50
|
+
if (parent === current) break;
|
|
51
|
+
current = parent;
|
|
52
|
+
}
|
|
53
|
+
return dirs;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function findNearestPackageJson(start: string): string | undefined {
|
|
57
|
+
for (const dir of getSearchDirs(start)) {
|
|
58
|
+
const packageJsonPath = join(dir, "package.json");
|
|
59
|
+
if (existsSync(packageJsonPath)) return packageJsonPath;
|
|
18
60
|
}
|
|
19
|
-
|
|
20
|
-
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function getPackageManagerRunCmd(packageManager: PackageManager): string {
|
|
65
|
+
switch (packageManager) {
|
|
66
|
+
case "pnpm":
|
|
67
|
+
return "pnpm run";
|
|
68
|
+
case "yarn":
|
|
69
|
+
return "yarn";
|
|
70
|
+
case "bun":
|
|
71
|
+
return "bun run";
|
|
72
|
+
case "npm":
|
|
73
|
+
default:
|
|
74
|
+
return "npm run";
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function getPackageManagerInstallCmd(
|
|
79
|
+
packageManager: PackageManager
|
|
80
|
+
): string {
|
|
81
|
+
switch (packageManager) {
|
|
82
|
+
case "pnpm":
|
|
83
|
+
return "pnpm install";
|
|
84
|
+
case "yarn":
|
|
85
|
+
return "yarn install";
|
|
86
|
+
case "bun":
|
|
87
|
+
return "bun install";
|
|
88
|
+
case "npm":
|
|
89
|
+
default:
|
|
90
|
+
return "npm install";
|
|
21
91
|
}
|
|
22
|
-
|
|
23
|
-
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Detect package manager (npm, pnpm, yarn, or bun)
|
|
96
|
+
*/
|
|
97
|
+
export function detectPackageManager(cwd: string = process.cwd()): PackageManager {
|
|
98
|
+
for (const dir of getSearchDirs(cwd)) {
|
|
99
|
+
const fromLockfile = detectPackageManagerFromLockfile(dir);
|
|
100
|
+
if (fromLockfile) return fromLockfile;
|
|
101
|
+
|
|
102
|
+
const fromWorkspace = detectPackageManagerFromWorkspace(dir);
|
|
103
|
+
if (fromWorkspace) return fromWorkspace;
|
|
104
|
+
|
|
105
|
+
const fromPackageJson = detectPackageManagerFromPackageJson(dir);
|
|
106
|
+
if (fromPackageJson) return fromPackageJson;
|
|
24
107
|
}
|
|
25
108
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
109
|
+
return "npm";
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function detectPackageManagerInstallCmd(
|
|
113
|
+
cwd: string = process.cwd()
|
|
114
|
+
): string {
|
|
115
|
+
return getPackageManagerInstallCmd(detectPackageManager(cwd));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function hasTinybirdSdkDependency(cwd: string = process.cwd()): boolean {
|
|
119
|
+
const packageJsonPath = findNearestPackageJson(cwd);
|
|
120
|
+
if (!packageJsonPath) return false;
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
124
|
+
const dependencyFields = [
|
|
125
|
+
packageJson.dependencies,
|
|
126
|
+
packageJson.devDependencies,
|
|
127
|
+
packageJson.peerDependencies,
|
|
128
|
+
packageJson.optionalDependencies,
|
|
129
|
+
];
|
|
130
|
+
|
|
131
|
+
return dependencyFields.some(
|
|
132
|
+
(deps) =>
|
|
133
|
+
deps &&
|
|
134
|
+
typeof deps === "object" &&
|
|
135
|
+
Object.prototype.hasOwnProperty.call(deps, TINYBIRD_SDK_PACKAGE)
|
|
136
|
+
);
|
|
137
|
+
} catch {
|
|
138
|
+
return false;
|
|
40
139
|
}
|
|
140
|
+
}
|
|
41
141
|
|
|
42
|
-
|
|
43
|
-
|
|
142
|
+
/**
|
|
143
|
+
* Detect package manager and return the appropriate run command
|
|
144
|
+
*/
|
|
145
|
+
export function detectPackageManagerRunCmd(cwd: string = process.cwd()): string {
|
|
146
|
+
return getPackageManagerRunCmd(detectPackageManager(cwd));
|
|
44
147
|
}
|
package/src/codegen/index.ts
CHANGED
|
@@ -20,6 +20,9 @@ export function generateDatasourceCode(ds: DatasourceInfo): string {
|
|
|
20
20
|
const typeName = toPascalCase(ds.name);
|
|
21
21
|
const lines: string[] = [];
|
|
22
22
|
|
|
23
|
+
// Check if any columns have jsonpath set
|
|
24
|
+
const hasJsonpath = ds.columns.some((col) => col.jsonpath);
|
|
25
|
+
|
|
23
26
|
// JSDoc comment
|
|
24
27
|
if (ds.description) {
|
|
25
28
|
lines.push("/**");
|
|
@@ -33,6 +36,11 @@ export function generateDatasourceCode(ds: DatasourceInfo): string {
|
|
|
33
36
|
lines.push(` description: "${escapeString(ds.description)}",`);
|
|
34
37
|
}
|
|
35
38
|
|
|
39
|
+
// Add jsonPaths: false if no columns use jsonpath
|
|
40
|
+
if (!hasJsonpath) {
|
|
41
|
+
lines.push(" jsonPaths: false,");
|
|
42
|
+
}
|
|
43
|
+
|
|
36
44
|
// Schema
|
|
37
45
|
lines.push(" schema: {");
|
|
38
46
|
for (const col of ds.columns) {
|
|
@@ -382,3 +390,110 @@ export function generateAllFiles(
|
|
|
382
390
|
pipeCount: pipes.length,
|
|
383
391
|
};
|
|
384
392
|
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Generate a single combined tinybird.ts file with all definitions
|
|
396
|
+
*/
|
|
397
|
+
export function generateCombinedFile(
|
|
398
|
+
datasources: DatasourceInfo[],
|
|
399
|
+
pipes: PipeInfo[]
|
|
400
|
+
): string {
|
|
401
|
+
const lines: string[] = [
|
|
402
|
+
"/**",
|
|
403
|
+
" * Tinybird Definitions",
|
|
404
|
+
" *",
|
|
405
|
+
" * This file contains all datasource and endpoint definitions.",
|
|
406
|
+
" * Generated from existing workspace resources.",
|
|
407
|
+
" */",
|
|
408
|
+
"",
|
|
409
|
+
];
|
|
410
|
+
|
|
411
|
+
// Build imports
|
|
412
|
+
const sdkImports: string[] = ["createTinybirdClient", "t"];
|
|
413
|
+
|
|
414
|
+
if (datasources.length > 0) {
|
|
415
|
+
sdkImports.push("defineDatasource", "engine", "type InferRow");
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const hasMaterialized = pipes.some((p) => p.type === "materialized");
|
|
419
|
+
const hasCopy = pipes.some((p) => p.type === "copy");
|
|
420
|
+
const hasEndpoint = pipes.some((p) => p.type === "endpoint");
|
|
421
|
+
const hasPlainPipe = pipes.some((p) => p.type === "pipe");
|
|
422
|
+
const hasParams = pipes.some(
|
|
423
|
+
(p) => p.params.length > 0 && p.type !== "materialized" && p.type !== "copy"
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
if (pipes.length > 0) {
|
|
427
|
+
sdkImports.push("node");
|
|
428
|
+
}
|
|
429
|
+
if (hasParams) {
|
|
430
|
+
sdkImports.push("p");
|
|
431
|
+
}
|
|
432
|
+
if (hasEndpoint) {
|
|
433
|
+
sdkImports.push("defineEndpoint", "type InferParams", "type InferOutputRow");
|
|
434
|
+
}
|
|
435
|
+
if (hasMaterialized) {
|
|
436
|
+
sdkImports.push("defineMaterializedView");
|
|
437
|
+
}
|
|
438
|
+
if (hasCopy) {
|
|
439
|
+
sdkImports.push("defineCopyPipe");
|
|
440
|
+
}
|
|
441
|
+
if (hasPlainPipe) {
|
|
442
|
+
sdkImports.push("definePipe");
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
lines.push(`import {`);
|
|
446
|
+
lines.push(` ${sdkImports.join(",\n ")},`);
|
|
447
|
+
lines.push(`} from "@tinybirdco/sdk";`);
|
|
448
|
+
lines.push("");
|
|
449
|
+
|
|
450
|
+
// Datasources section
|
|
451
|
+
if (datasources.length > 0) {
|
|
452
|
+
lines.push("// ============================================================================");
|
|
453
|
+
lines.push("// Datasources");
|
|
454
|
+
lines.push("// ============================================================================");
|
|
455
|
+
lines.push("");
|
|
456
|
+
|
|
457
|
+
for (const ds of datasources) {
|
|
458
|
+
lines.push(generateDatasourceCode(ds));
|
|
459
|
+
lines.push("");
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// Pipes/Endpoints section
|
|
464
|
+
if (pipes.length > 0) {
|
|
465
|
+
lines.push("// ============================================================================");
|
|
466
|
+
lines.push("// Endpoints");
|
|
467
|
+
lines.push("// ============================================================================");
|
|
468
|
+
lines.push("");
|
|
469
|
+
|
|
470
|
+
for (const pipe of pipes) {
|
|
471
|
+
lines.push(generatePipeCode(pipe));
|
|
472
|
+
lines.push("");
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Client section
|
|
477
|
+
lines.push("// ============================================================================");
|
|
478
|
+
lines.push("// Client");
|
|
479
|
+
lines.push("// ============================================================================");
|
|
480
|
+
lines.push("");
|
|
481
|
+
|
|
482
|
+
const dsNames =
|
|
483
|
+
datasources.length > 0
|
|
484
|
+
? datasources.map((ds) => toCamelCase(ds.name)).join(", ")
|
|
485
|
+
: "";
|
|
486
|
+
const endpoints = pipes.filter((p) => p.type === "endpoint");
|
|
487
|
+
const pipeNames =
|
|
488
|
+
endpoints.length > 0
|
|
489
|
+
? endpoints.map((p) => toCamelCase(p.name)).join(", ")
|
|
490
|
+
: "";
|
|
491
|
+
|
|
492
|
+
lines.push("export const tinybird = createTinybirdClient({");
|
|
493
|
+
lines.push(` datasources: { ${dsNames} },`);
|
|
494
|
+
lines.push(` pipes: { ${pipeNames} },`);
|
|
495
|
+
lines.push("});");
|
|
496
|
+
lines.push("");
|
|
497
|
+
|
|
498
|
+
return lines.join("\n");
|
|
499
|
+
}
|