@tinybirdco/sdk 0.0.4 → 0.0.7
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 +52 -13
- package/dist/api/branches.d.ts.map +1 -1
- package/dist/api/branches.js +6 -5
- package/dist/api/branches.js.map +1 -1
- package/dist/api/branches.test.js +32 -6
- package/dist/api/branches.test.js.map +1 -1
- package/dist/api/build.d.ts.map +1 -1
- package/dist/api/build.js +2 -1
- package/dist/api/build.js.map +1 -1
- package/dist/api/deploy.d.ts +42 -3
- package/dist/api/deploy.d.ts.map +1 -1
- package/dist/api/deploy.js +162 -19
- package/dist/api/deploy.js.map +1 -1
- package/dist/api/deploy.test.js +83 -31
- package/dist/api/deploy.test.js.map +1 -1
- package/dist/api/fetcher.d.ts +6 -0
- package/dist/api/fetcher.d.ts.map +1 -0
- package/dist/api/fetcher.js +13 -0
- package/dist/api/fetcher.js.map +1 -0
- package/dist/api/local.d.ts.map +1 -1
- package/dist/api/local.js +5 -4
- package/dist/api/local.js.map +1 -1
- package/dist/api/local.test.js.map +1 -1
- package/dist/api/resources.d.ts +178 -0
- package/dist/api/resources.d.ts.map +1 -0
- package/dist/api/resources.js +245 -0
- package/dist/api/resources.js.map +1 -0
- package/dist/api/resources.test.d.ts +2 -0
- package/dist/api/resources.test.d.ts.map +1 -0
- package/dist/api/resources.test.js +255 -0
- package/dist/api/resources.test.js.map +1 -0
- package/dist/api/workspaces.d.ts.map +1 -1
- package/dist/api/workspaces.js +2 -1
- package/dist/api/workspaces.js.map +1 -1
- package/dist/api/workspaces.test.js +9 -1
- package/dist/api/workspaces.test.js.map +1 -1
- package/dist/cli/auth.d.ts.map +1 -1
- package/dist/cli/auth.js +2 -1
- package/dist/cli/auth.js.map +1 -1
- package/dist/cli/commands/build.d.ts +3 -4
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +23 -25
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/deploy.d.ts +41 -0
- package/dist/cli/commands/deploy.d.ts.map +1 -0
- package/dist/cli/commands/deploy.js +92 -0
- package/dist/cli/commands/deploy.js.map +1 -0
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +7 -3
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/init.d.ts +38 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +434 -23
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/init.test.js +190 -30
- package/dist/cli/commands/init.test.js.map +1 -1
- package/dist/cli/index.js +80 -15
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/package-manager.d.ts +8 -0
- package/dist/cli/utils/package-manager.d.ts.map +1 -0
- package/dist/cli/utils/package-manager.js +45 -0
- package/dist/cli/utils/package-manager.js.map +1 -0
- package/dist/cli/utils/package-manager.test.d.ts +2 -0
- package/dist/cli/utils/package-manager.test.d.ts.map +1 -0
- package/dist/cli/utils/package-manager.test.js +85 -0
- package/dist/cli/utils/package-manager.test.js.map +1 -0
- package/dist/client/base.d.ts.map +1 -1
- package/dist/client/base.js +2 -1
- package/dist/client/base.js.map +1 -1
- package/dist/codegen/index.d.ts +39 -0
- package/dist/codegen/index.d.ts.map +1 -0
- package/dist/codegen/index.js +300 -0
- package/dist/codegen/index.js.map +1 -0
- package/dist/codegen/index.test.d.ts +2 -0
- package/dist/codegen/index.test.d.ts.map +1 -0
- package/dist/codegen/index.test.js +310 -0
- package/dist/codegen/index.test.js.map +1 -0
- package/dist/codegen/type-mapper.d.ts +20 -0
- package/dist/codegen/type-mapper.d.ts.map +1 -0
- package/dist/codegen/type-mapper.js +238 -0
- package/dist/codegen/type-mapper.js.map +1 -0
- package/dist/codegen/type-mapper.test.d.ts +2 -0
- package/dist/codegen/type-mapper.test.d.ts.map +1 -0
- package/dist/codegen/type-mapper.test.js +167 -0
- package/dist/codegen/type-mapper.test.js.map +1 -0
- package/dist/codegen/utils.d.ts +46 -0
- package/dist/codegen/utils.d.ts.map +1 -0
- package/dist/codegen/utils.js +141 -0
- package/dist/codegen/utils.js.map +1 -0
- package/dist/codegen/utils.test.d.ts +2 -0
- package/dist/codegen/utils.test.d.ts.map +1 -0
- package/dist/codegen/utils.test.js +178 -0
- package/dist/codegen/utils.test.js.map +1 -0
- package/dist/generator/index.d.ts +3 -0
- package/dist/generator/index.d.ts.map +1 -1
- package/dist/generator/index.js +17 -1
- package/dist/generator/index.js.map +1 -1
- package/dist/generator/index.test.js +104 -1
- package/dist/generator/index.test.js.map +1 -1
- package/dist/generator/loader.d.ts +15 -0
- package/dist/generator/loader.d.ts.map +1 -1
- package/dist/generator/loader.js +24 -0
- package/dist/generator/loader.js.map +1 -1
- package/dist/schema/connection.d.ts.map +1 -1
- package/dist/schema/connection.js +3 -2
- package/dist/schema/connection.js.map +1 -1
- package/dist/schema/datasource.d.ts.map +1 -1
- package/dist/schema/datasource.js +3 -2
- package/dist/schema/datasource.js.map +1 -1
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/params.js +3 -2
- package/dist/schema/params.js.map +1 -1
- package/dist/schema/pipe.d.ts +2 -2
- package/dist/schema/pipe.d.ts.map +1 -1
- package/dist/schema/pipe.js +4 -4
- package/dist/schema/pipe.js.map +1 -1
- package/dist/schema/project.d.ts.map +1 -1
- package/dist/schema/project.js +3 -2
- package/dist/schema/project.js.map +1 -1
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +3 -2
- package/dist/schema/types.js.map +1 -1
- package/dist/test/handlers.d.ts +49 -0
- package/dist/test/handlers.d.ts.map +1 -1
- package/dist/test/handlers.js +45 -0
- package/dist/test/handlers.js.map +1 -1
- package/package.json +4 -2
- package/src/api/branches.test.ts +65 -57
- package/src/api/branches.ts +7 -5
- package/src/api/build.ts +2 -1
- package/src/api/deploy.test.ts +141 -36
- package/src/api/deploy.ts +231 -23
- package/src/api/fetcher.ts +17 -0
- package/src/api/local.test.ts +43 -31
- package/src/api/local.ts +5 -4
- package/src/api/resources.test.ts +332 -0
- package/src/api/resources.ts +555 -0
- package/src/api/workspaces.test.ts +15 -9
- package/src/api/workspaces.ts +3 -1
- package/src/cli/auth.ts +2 -1
- package/src/cli/commands/build.ts +29 -33
- package/src/cli/commands/deploy.ts +131 -0
- package/src/cli/commands/dev.ts +10 -3
- package/src/cli/commands/init.test.ts +239 -30
- package/src/cli/commands/init.ts +548 -26
- package/src/cli/index.ts +117 -20
- package/src/cli/utils/package-manager.test.ts +118 -0
- package/src/cli/utils/package-manager.ts +44 -0
- package/src/client/base.ts +3 -2
- package/src/codegen/index.test.ts +367 -0
- package/src/codegen/index.ts +379 -0
- package/src/codegen/type-mapper.test.ts +224 -0
- package/src/codegen/type-mapper.ts +265 -0
- package/src/codegen/utils.test.ts +221 -0
- package/src/codegen/utils.ts +174 -0
- package/src/generator/index.test.ts +121 -1
- package/src/generator/index.ts +19 -1
- package/src/generator/loader.ts +43 -0
- package/src/schema/connection.ts +3 -2
- package/src/schema/datasource.ts +3 -2
- package/src/schema/params.ts +3 -2
- package/src/schema/pipe.ts +4 -4
- package/src/schema/project.ts +3 -2
- package/src/schema/types.ts +3 -2
- package/src/test/handlers.ts +58 -0
package/src/cli/index.ts
CHANGED
|
@@ -16,6 +16,7 @@ import { dirname, resolve } from "node:path";
|
|
|
16
16
|
import { Command } from "commander";
|
|
17
17
|
import { runInit } from "./commands/init.js";
|
|
18
18
|
import { runBuild } from "./commands/build.js";
|
|
19
|
+
import { runDeploy } from "./commands/deploy.js";
|
|
19
20
|
import { runDev } from "./commands/dev.js";
|
|
20
21
|
import { runLogin } from "./commands/login.js";
|
|
21
22
|
import {
|
|
@@ -23,6 +24,7 @@ import {
|
|
|
23
24
|
runBranchStatus,
|
|
24
25
|
runBranchDelete,
|
|
25
26
|
} from "./commands/branch.js";
|
|
27
|
+
import { detectPackageManagerRunCmd } from "./utils/package-manager.js";
|
|
26
28
|
import type { DevMode } from "./config.js";
|
|
27
29
|
|
|
28
30
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -55,12 +57,22 @@ function createCli(): Command {
|
|
|
55
57
|
.description("Initialize a new Tinybird TypeScript project")
|
|
56
58
|
.option("-f, --force", "Overwrite existing files")
|
|
57
59
|
.option("--skip-login", "Skip browser login flow")
|
|
60
|
+
.option("-m, --mode <mode>", "Development mode: 'branch' or 'local'")
|
|
61
|
+
.option("-p, --path <path>", "Path for Tinybird client files")
|
|
58
62
|
.action(async (options) => {
|
|
59
|
-
|
|
63
|
+
// Validate mode if provided
|
|
64
|
+
if (options.mode && !["branch", "local"].includes(options.mode)) {
|
|
65
|
+
console.error(
|
|
66
|
+
`Error: Invalid mode '${options.mode}'. Use 'branch' or 'local'.`
|
|
67
|
+
);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
60
70
|
|
|
61
71
|
const result = await runInit({
|
|
62
72
|
force: options.force,
|
|
63
73
|
skipLogin: options.skipLogin,
|
|
74
|
+
devMode: options.mode,
|
|
75
|
+
clientPath: options.path,
|
|
64
76
|
});
|
|
65
77
|
|
|
66
78
|
if (!result.success) {
|
|
@@ -82,6 +94,10 @@ function createCli(): Command {
|
|
|
82
94
|
});
|
|
83
95
|
}
|
|
84
96
|
|
|
97
|
+
// Detect package manager for run command
|
|
98
|
+
const runCmd = detectPackageManagerRunCmd();
|
|
99
|
+
const clientPath = result.clientPath ?? "tinybird";
|
|
100
|
+
|
|
85
101
|
if (result.loggedIn) {
|
|
86
102
|
console.log(`\nLogged in successfully!`);
|
|
87
103
|
if (result.workspaceName) {
|
|
@@ -90,19 +106,25 @@ function createCli(): Command {
|
|
|
90
106
|
if (result.userEmail) {
|
|
91
107
|
console.log(` User: ${result.userEmail}`);
|
|
92
108
|
}
|
|
109
|
+
|
|
110
|
+
if (result.existingDatafiles && result.existingDatafiles.length > 0) {
|
|
111
|
+
console.log(
|
|
112
|
+
`\nAdded ${result.existingDatafiles.length} existing datafile(s) to tinybird.json.`
|
|
113
|
+
);
|
|
114
|
+
}
|
|
93
115
|
console.log("\nDone! Next steps:");
|
|
94
|
-
console.log(
|
|
95
|
-
console.log(
|
|
116
|
+
console.log(` 1. Edit your schema in ${clientPath}/`);
|
|
117
|
+
console.log(` 2. Run '${runCmd} tinybird:dev' to start development`);
|
|
96
118
|
} else if (result.loggedIn === false) {
|
|
97
119
|
console.log("\nLogin was skipped or failed.");
|
|
98
120
|
console.log("\nDone! Next steps:");
|
|
99
121
|
console.log(" 1. Run 'npx tinybird login' to authenticate");
|
|
100
|
-
console.log(
|
|
101
|
-
console.log(
|
|
122
|
+
console.log(` 2. Edit your schema in ${clientPath}/`);
|
|
123
|
+
console.log(` 3. Run '${runCmd} tinybird:dev' to start development`);
|
|
102
124
|
} else {
|
|
103
125
|
console.log("\nDone! Next steps:");
|
|
104
|
-
console.log(
|
|
105
|
-
console.log(
|
|
126
|
+
console.log(` 1. Edit your schema in ${clientPath}/`);
|
|
127
|
+
console.log(` 2. Run '${runCmd} tinybird:dev' to start development`);
|
|
106
128
|
}
|
|
107
129
|
});
|
|
108
130
|
|
|
@@ -135,11 +157,10 @@ function createCli(): Command {
|
|
|
135
157
|
// Build command
|
|
136
158
|
program
|
|
137
159
|
.command("build")
|
|
138
|
-
.description("Build and push resources to Tinybird")
|
|
160
|
+
.description("Build and push resources to a Tinybird branch (not main)")
|
|
139
161
|
.option("--dry-run", "Generate without pushing to API")
|
|
140
162
|
.option("--debug", "Show debug output including API requests/responses")
|
|
141
163
|
.option("--local", "Use local Tinybird container")
|
|
142
|
-
.option("--branch", "Use Tinybird cloud with branches")
|
|
143
164
|
.action(async (options) => {
|
|
144
165
|
if (options.debug) {
|
|
145
166
|
process.env.TINYBIRD_DEBUG = "1";
|
|
@@ -149,8 +170,6 @@ function createCli(): Command {
|
|
|
149
170
|
let devModeOverride: DevMode | undefined;
|
|
150
171
|
if (options.local) {
|
|
151
172
|
devModeOverride = "local";
|
|
152
|
-
} else if (options.branch) {
|
|
153
|
-
devModeOverride = "branch";
|
|
154
173
|
}
|
|
155
174
|
|
|
156
175
|
const modeLabel = devModeOverride === "local" ? " (local)" : "";
|
|
@@ -169,7 +188,9 @@ function createCli(): Command {
|
|
|
169
188
|
const { build, deploy } = result;
|
|
170
189
|
|
|
171
190
|
if (build) {
|
|
172
|
-
console.log(
|
|
191
|
+
console.log(
|
|
192
|
+
`Generated ${build.stats.datasourceCount} datasource(s), ${build.stats.pipeCount} pipe(s)`
|
|
193
|
+
);
|
|
173
194
|
}
|
|
174
195
|
|
|
175
196
|
if (options.dryRun) {
|
|
@@ -200,6 +221,68 @@ function createCli(): Command {
|
|
|
200
221
|
console.log(`\n[${formatTime()}] Done in ${result.durationMs}ms`);
|
|
201
222
|
});
|
|
202
223
|
|
|
224
|
+
// Deploy command
|
|
225
|
+
program
|
|
226
|
+
.command("deploy")
|
|
227
|
+
.description("Deploy resources to main Tinybird workspace (production)")
|
|
228
|
+
.option("--dry-run", "Generate without pushing to API")
|
|
229
|
+
.option("--check", "Validate deploy with Tinybird API without applying")
|
|
230
|
+
.option("--debug", "Show debug output including API requests/responses")
|
|
231
|
+
.action(async (options) => {
|
|
232
|
+
if (options.debug) {
|
|
233
|
+
process.env.TINYBIRD_DEBUG = "1";
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
console.log(`[${formatTime()}] Deploying to main workspace...\n`);
|
|
237
|
+
|
|
238
|
+
const result = await runDeploy({
|
|
239
|
+
dryRun: options.dryRun,
|
|
240
|
+
check: options.check,
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
if (!result.success) {
|
|
244
|
+
console.error(`Error: ${result.error}`);
|
|
245
|
+
process.exit(1);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const { build, deploy } = result;
|
|
249
|
+
|
|
250
|
+
if (build) {
|
|
251
|
+
console.log(
|
|
252
|
+
`Generated ${build.stats.datasourceCount} datasource(s), ${build.stats.pipeCount} pipe(s)`
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (options.dryRun) {
|
|
257
|
+
console.log("\n[Dry run] Resources not deployed to API");
|
|
258
|
+
|
|
259
|
+
// Show generated content
|
|
260
|
+
if (build) {
|
|
261
|
+
console.log("\n--- Generated Datasources ---");
|
|
262
|
+
build.resources.datasources.forEach((ds) => {
|
|
263
|
+
console.log(`\n${ds.name}.datasource:`);
|
|
264
|
+
console.log(ds.content);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
console.log("\n--- Generated Pipes ---");
|
|
268
|
+
build.resources.pipes.forEach((pipe) => {
|
|
269
|
+
console.log(`\n${pipe.name}.pipe:`);
|
|
270
|
+
console.log(pipe.content);
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
} else if (options.check) {
|
|
274
|
+
console.log("\n[Check] Resources validated with Tinybird API");
|
|
275
|
+
} else if (deploy) {
|
|
276
|
+
if (deploy.result === "no_changes") {
|
|
277
|
+
console.log("No changes detected - already up to date");
|
|
278
|
+
} else {
|
|
279
|
+
console.log(`Deployed to main workspace successfully`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
console.log(`\n[${formatTime()}] Done in ${result.durationMs}ms`);
|
|
284
|
+
});
|
|
285
|
+
|
|
203
286
|
// Dev command
|
|
204
287
|
program
|
|
205
288
|
.command("dev")
|
|
@@ -241,7 +324,9 @@ function createCli(): Command {
|
|
|
241
324
|
console.log("Workspace created.\n");
|
|
242
325
|
} else {
|
|
243
326
|
console.log(`Using local Tinybird container`);
|
|
244
|
-
console.log(
|
|
327
|
+
console.log(
|
|
328
|
+
`Using existing local workspace '${workspaceName}'\n`
|
|
329
|
+
);
|
|
245
330
|
}
|
|
246
331
|
} else if (info.isMainBranch) {
|
|
247
332
|
console.log("On main branch - deploying to workspace\n");
|
|
@@ -253,7 +338,9 @@ function createCli(): Command {
|
|
|
253
338
|
console.log("Branch created and token cached.\n");
|
|
254
339
|
} else {
|
|
255
340
|
console.log(`Detected git branch: ${info.gitBranch}`);
|
|
256
|
-
console.log(
|
|
341
|
+
console.log(
|
|
342
|
+
`Using existing Tinybird branch '${tinybirdName}'\n`
|
|
343
|
+
);
|
|
257
344
|
}
|
|
258
345
|
} else {
|
|
259
346
|
console.log("Not in a git repository - deploying to workspace\n");
|
|
@@ -274,7 +361,9 @@ function createCli(): Command {
|
|
|
274
361
|
if (deploy.result === "no_changes") {
|
|
275
362
|
console.log(`[${formatTime()}] No changes detected`);
|
|
276
363
|
} else {
|
|
277
|
-
console.log(
|
|
364
|
+
console.log(
|
|
365
|
+
`[${formatTime()}] Built in ${result.durationMs}ms`
|
|
366
|
+
);
|
|
278
367
|
|
|
279
368
|
// Show datasource changes
|
|
280
369
|
if (deploy.datasources) {
|
|
@@ -309,7 +398,9 @@ function createCli(): Command {
|
|
|
309
398
|
console.log(`[${formatTime()}] Schema validation:`);
|
|
310
399
|
for (const issue of validation.issues) {
|
|
311
400
|
if (issue.type === "error") {
|
|
312
|
-
console.error(
|
|
401
|
+
console.error(
|
|
402
|
+
` ERROR [${issue.pipeName}]: ${issue.message}`
|
|
403
|
+
);
|
|
313
404
|
} else {
|
|
314
405
|
console.warn(` WARN [${issue.pipeName}]: ${issue.message}`);
|
|
315
406
|
}
|
|
@@ -342,8 +433,9 @@ function createCli(): Command {
|
|
|
342
433
|
});
|
|
343
434
|
|
|
344
435
|
// Branch command
|
|
345
|
-
const branchCommand = new Command("branch")
|
|
346
|
-
|
|
436
|
+
const branchCommand = new Command("branch").description(
|
|
437
|
+
"Manage Tinybird branches"
|
|
438
|
+
);
|
|
347
439
|
|
|
348
440
|
branchCommand
|
|
349
441
|
.command("list")
|
|
@@ -380,8 +472,13 @@ function createCli(): Command {
|
|
|
380
472
|
|
|
381
473
|
console.log("Branch Status:");
|
|
382
474
|
console.log(` Git branch: ${result.gitBranch ?? "(not in git repo)"}`);
|
|
383
|
-
if (
|
|
384
|
-
|
|
475
|
+
if (
|
|
476
|
+
result.tinybirdBranchName &&
|
|
477
|
+
result.tinybirdBranchName !== result.gitBranch
|
|
478
|
+
) {
|
|
479
|
+
console.log(
|
|
480
|
+
` Tinybird branch name: ${result.tinybirdBranchName} (sanitized)`
|
|
481
|
+
);
|
|
385
482
|
}
|
|
386
483
|
console.log(` Main branch: ${result.isMainBranch ? "yes" : "no"}`);
|
|
387
484
|
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import * as os from "os";
|
|
5
|
+
import { detectPackageManagerRunCmd } from "./package-manager.js";
|
|
6
|
+
|
|
7
|
+
describe("detectPackageManagerRunCmd", () => {
|
|
8
|
+
let tempDir: string;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "pkg-manager-test-"));
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
try {
|
|
16
|
+
fs.rmSync(tempDir, { recursive: true });
|
|
17
|
+
} catch {
|
|
18
|
+
// Ignore cleanup errors
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe("lockfile detection", () => {
|
|
23
|
+
it("detects pnpm from pnpm-lock.yaml", () => {
|
|
24
|
+
fs.writeFileSync(path.join(tempDir, "pnpm-lock.yaml"), "");
|
|
25
|
+
expect(detectPackageManagerRunCmd(tempDir)).toBe("pnpm");
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("detects yarn from yarn.lock", () => {
|
|
29
|
+
fs.writeFileSync(path.join(tempDir, "yarn.lock"), "");
|
|
30
|
+
expect(detectPackageManagerRunCmd(tempDir)).toBe("yarn");
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("detects bun from bun.lockb", () => {
|
|
34
|
+
fs.writeFileSync(path.join(tempDir, "bun.lockb"), "");
|
|
35
|
+
expect(detectPackageManagerRunCmd(tempDir)).toBe("bun run");
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("detects npm from package-lock.json", () => {
|
|
39
|
+
fs.writeFileSync(path.join(tempDir, "package-lock.json"), "{}");
|
|
40
|
+
expect(detectPackageManagerRunCmd(tempDir)).toBe("npm run");
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("prioritizes pnpm lockfile over others", () => {
|
|
44
|
+
fs.writeFileSync(path.join(tempDir, "pnpm-lock.yaml"), "");
|
|
45
|
+
fs.writeFileSync(path.join(tempDir, "yarn.lock"), "");
|
|
46
|
+
fs.writeFileSync(path.join(tempDir, "package-lock.json"), "{}");
|
|
47
|
+
expect(detectPackageManagerRunCmd(tempDir)).toBe("pnpm");
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("prioritizes yarn lockfile over npm", () => {
|
|
51
|
+
fs.writeFileSync(path.join(tempDir, "yarn.lock"), "");
|
|
52
|
+
fs.writeFileSync(path.join(tempDir, "package-lock.json"), "{}");
|
|
53
|
+
expect(detectPackageManagerRunCmd(tempDir)).toBe("yarn");
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe("packageManager field detection", () => {
|
|
58
|
+
it("detects pnpm from packageManager field", () => {
|
|
59
|
+
fs.writeFileSync(
|
|
60
|
+
path.join(tempDir, "package.json"),
|
|
61
|
+
JSON.stringify({ packageManager: "pnpm@9.0.0" })
|
|
62
|
+
);
|
|
63
|
+
expect(detectPackageManagerRunCmd(tempDir)).toBe("pnpm");
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("detects yarn from packageManager field", () => {
|
|
67
|
+
fs.writeFileSync(
|
|
68
|
+
path.join(tempDir, "package.json"),
|
|
69
|
+
JSON.stringify({ packageManager: "yarn@4.0.0" })
|
|
70
|
+
);
|
|
71
|
+
expect(detectPackageManagerRunCmd(tempDir)).toBe("yarn");
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("detects bun from packageManager field", () => {
|
|
75
|
+
fs.writeFileSync(
|
|
76
|
+
path.join(tempDir, "package.json"),
|
|
77
|
+
JSON.stringify({ packageManager: "bun@1.0.0" })
|
|
78
|
+
);
|
|
79
|
+
expect(detectPackageManagerRunCmd(tempDir)).toBe("bun run");
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("prioritizes lockfile over packageManager field", () => {
|
|
83
|
+
fs.writeFileSync(path.join(tempDir, "yarn.lock"), "");
|
|
84
|
+
fs.writeFileSync(
|
|
85
|
+
path.join(tempDir, "package.json"),
|
|
86
|
+
JSON.stringify({ packageManager: "pnpm@9.0.0" })
|
|
87
|
+
);
|
|
88
|
+
expect(detectPackageManagerRunCmd(tempDir)).toBe("yarn");
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
describe("default behavior", () => {
|
|
93
|
+
it("defaults to npm run when no indicators found", () => {
|
|
94
|
+
expect(detectPackageManagerRunCmd(tempDir)).toBe("npm run");
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("defaults to npm run when package.json has no packageManager field", () => {
|
|
98
|
+
fs.writeFileSync(
|
|
99
|
+
path.join(tempDir, "package.json"),
|
|
100
|
+
JSON.stringify({ name: "test-project" })
|
|
101
|
+
);
|
|
102
|
+
expect(detectPackageManagerRunCmd(tempDir)).toBe("npm run");
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it("defaults to npm run when package.json is invalid JSON", () => {
|
|
106
|
+
fs.writeFileSync(path.join(tempDir, "package.json"), "not json");
|
|
107
|
+
expect(detectPackageManagerRunCmd(tempDir)).toBe("npm run");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("defaults to npm run when packageManager is not a string", () => {
|
|
111
|
+
fs.writeFileSync(
|
|
112
|
+
path.join(tempDir, "package.json"),
|
|
113
|
+
JSON.stringify({ packageManager: 123 })
|
|
114
|
+
);
|
|
115
|
+
expect(detectPackageManagerRunCmd(tempDir)).toBe("npm run");
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package manager detection utilities
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Detect package manager and return the appropriate run command
|
|
10
|
+
*/
|
|
11
|
+
export function detectPackageManagerRunCmd(cwd: string = process.cwd()): string {
|
|
12
|
+
// Check lockfiles first (most reliable)
|
|
13
|
+
if (existsSync(join(cwd, "pnpm-lock.yaml"))) {
|
|
14
|
+
return "pnpm";
|
|
15
|
+
}
|
|
16
|
+
if (existsSync(join(cwd, "yarn.lock"))) {
|
|
17
|
+
return "yarn";
|
|
18
|
+
}
|
|
19
|
+
if (existsSync(join(cwd, "bun.lockb"))) {
|
|
20
|
+
return "bun run";
|
|
21
|
+
}
|
|
22
|
+
if (existsSync(join(cwd, "package-lock.json"))) {
|
|
23
|
+
return "npm run";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Check packageManager field in package.json
|
|
27
|
+
const packageJsonPath = join(cwd, "package.json");
|
|
28
|
+
if (existsSync(packageJsonPath)) {
|
|
29
|
+
try {
|
|
30
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
31
|
+
const pm = packageJson.packageManager;
|
|
32
|
+
if (typeof pm === "string") {
|
|
33
|
+
if (pm.startsWith("pnpm")) return "pnpm";
|
|
34
|
+
if (pm.startsWith("yarn")) return "yarn";
|
|
35
|
+
if (pm.startsWith("bun")) return "bun run";
|
|
36
|
+
}
|
|
37
|
+
} catch {
|
|
38
|
+
// Ignore parse errors
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Default to npm
|
|
43
|
+
return "npm run";
|
|
44
|
+
}
|
package/src/client/base.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
TinybirdErrorResponse,
|
|
12
12
|
} from "./types.js";
|
|
13
13
|
import { TinybirdError } from "./types.js";
|
|
14
|
+
import { createTinybirdFetcher, type TinybirdFetch } from "../api/fetcher.js";
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* Default timeout for requests (30 seconds)
|
|
@@ -56,7 +57,7 @@ interface ResolvedTokenInfo {
|
|
|
56
57
|
*/
|
|
57
58
|
export class TinybirdClient {
|
|
58
59
|
private readonly config: ClientConfig;
|
|
59
|
-
private readonly fetchFn:
|
|
60
|
+
private readonly fetchFn: TinybirdFetch;
|
|
60
61
|
private tokenPromise: Promise<ResolvedTokenInfo> | null = null;
|
|
61
62
|
private resolvedToken: string | null = null;
|
|
62
63
|
|
|
@@ -75,7 +76,7 @@ export class TinybirdClient {
|
|
|
75
76
|
baseUrl: config.baseUrl.replace(/\/$/, ""),
|
|
76
77
|
};
|
|
77
78
|
|
|
78
|
-
this.fetchFn = config.fetch ?? globalThis.fetch;
|
|
79
|
+
this.fetchFn = createTinybirdFetcher(config.fetch ?? globalThis.fetch);
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
/**
|