freestyle-sandboxes 0.1.28 → 0.1.30
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/cli.mjs +28 -47
- package/index.cjs +4 -0
- package/index.mjs +4 -0
- package/package.json +1 -1
package/cli.mjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import 'dotenv
|
|
2
|
+
import * as dotenv from 'dotenv';
|
|
3
3
|
import yargs from 'yargs';
|
|
4
4
|
import { hideBin } from 'yargs/helpers';
|
|
5
5
|
import { Freestyle, VmSpec } from './index.mjs';
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
import * as path from 'path';
|
|
8
|
-
import * as dotenv from 'dotenv';
|
|
9
8
|
import * as os from 'os';
|
|
10
9
|
import { spawn } from 'child_process';
|
|
11
10
|
|
|
@@ -17,7 +16,6 @@ const CLI_AUTH_TIMEOUT_MILLIS = 10 * 60 * 1e3;
|
|
|
17
16
|
const POLL_INTERVAL_MILLIS = 2e3;
|
|
18
17
|
const STACK_REFRESH_TOKEN_ENV_KEY = "FREESTYLE_STACK_REFRESH_TOKEN";
|
|
19
18
|
const STACK_SAVE_TO_DOTENV_ENV_KEY = "FREESTYLE_STACK_SAVE_TO_DOTENV";
|
|
20
|
-
const STACK_CLI_AUTH_ENABLED_ENV_KEY = "FREESTYLE_ENABLE_STACK_CLI_AUTH";
|
|
21
19
|
function isTruthy(value) {
|
|
22
20
|
if (!value) {
|
|
23
21
|
return false;
|
|
@@ -25,9 +23,6 @@ function isTruthy(value) {
|
|
|
25
23
|
const normalized = value.trim().toLowerCase();
|
|
26
24
|
return normalized === "1" || normalized === "true" || normalized === "yes";
|
|
27
25
|
}
|
|
28
|
-
function isStackCliAuthEnabled() {
|
|
29
|
-
return isTruthy(process.env[STACK_CLI_AUTH_ENABLED_ENV_KEY]);
|
|
30
|
-
}
|
|
31
26
|
function loadRefreshTokenFromDotenv() {
|
|
32
27
|
const refreshToken = process.env[STACK_REFRESH_TOKEN_ENV_KEY];
|
|
33
28
|
if (!refreshToken || typeof refreshToken !== "string") {
|
|
@@ -259,15 +254,15 @@ async function startCliLogin(config) {
|
|
|
259
254
|
if (!initResponse.ok) {
|
|
260
255
|
const errorText = await initResponse.text();
|
|
261
256
|
throw new Error(
|
|
262
|
-
`Failed to start
|
|
257
|
+
`Failed to start authentication login (${initResponse.status}). ${errorText || "Check project ID and client key configuration."}`
|
|
263
258
|
);
|
|
264
259
|
}
|
|
265
260
|
const initData = await initResponse.json();
|
|
266
261
|
if (!initData.polling_code || !initData.login_code) {
|
|
267
|
-
throw new Error("
|
|
262
|
+
throw new Error("Authentication login did not return polling/login codes.");
|
|
268
263
|
}
|
|
269
264
|
const loginUrl = `${config.appUrl}/handler/cli-auth-confirm?login_code=${encodeURIComponent(initData.login_code)}`;
|
|
270
|
-
console.log("\
|
|
265
|
+
console.log("\nAuthentication is required.");
|
|
271
266
|
console.log(`Open this URL to continue:
|
|
272
267
|
${loginUrl}
|
|
273
268
|
`);
|
|
@@ -291,26 +286,27 @@ ${loginUrl}
|
|
|
291
286
|
);
|
|
292
287
|
if (![200, 201].includes(pollResponse.status)) {
|
|
293
288
|
throw new Error(
|
|
294
|
-
`Failed while polling
|
|
289
|
+
`Failed while polling authentication login (${pollResponse.status}).`
|
|
295
290
|
);
|
|
296
291
|
}
|
|
297
292
|
const pollData = await pollResponse.json();
|
|
298
|
-
if (pollData.status
|
|
293
|
+
if (pollData.status && pollData.status !== "pending") {
|
|
294
|
+
console.log("Auth poll status:", pollData.status);
|
|
295
|
+
}
|
|
296
|
+
if (pollData.status === "completed" || pollData.status === "success") {
|
|
299
297
|
if (!pollData.refresh_token) {
|
|
300
|
-
throw new Error(
|
|
301
|
-
"Stack Auth login completed without a refresh token response."
|
|
302
|
-
);
|
|
298
|
+
throw new Error("Login completed without a refresh token response.");
|
|
303
299
|
}
|
|
304
300
|
return pollData.refresh_token;
|
|
305
301
|
}
|
|
306
|
-
if (pollData.status
|
|
302
|
+
if (pollData.status && pollData.status !== "pending" && pollData.status !== "waiting") {
|
|
307
303
|
throw new Error(
|
|
308
|
-
pollData.error || `
|
|
304
|
+
pollData.error || `Authentication ${pollData.status}. Please retry.`
|
|
309
305
|
);
|
|
310
306
|
}
|
|
311
307
|
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MILLIS));
|
|
312
308
|
}
|
|
313
|
-
throw new Error("Timed out waiting for
|
|
309
|
+
throw new Error("Timed out waiting for authentication.");
|
|
314
310
|
}
|
|
315
311
|
async function refreshStackAccessToken(config, refreshToken) {
|
|
316
312
|
const response = await fetch(
|
|
@@ -320,7 +316,8 @@ async function refreshStackAccessToken(config, refreshToken) {
|
|
|
320
316
|
headers: {
|
|
321
317
|
...clientHeaders(config),
|
|
322
318
|
"x-stack-refresh-token": refreshToken
|
|
323
|
-
}
|
|
319
|
+
},
|
|
320
|
+
body: "{}"
|
|
324
321
|
}
|
|
325
322
|
);
|
|
326
323
|
if (!response.ok) {
|
|
@@ -336,9 +333,6 @@ async function refreshStackAccessToken(config, refreshToken) {
|
|
|
336
333
|
};
|
|
337
334
|
}
|
|
338
335
|
async function getStackAccessTokenForCli(options) {
|
|
339
|
-
if (!isStackCliAuthEnabled()) {
|
|
340
|
-
return null;
|
|
341
|
-
}
|
|
342
336
|
const config = resolveStackConfig();
|
|
343
337
|
if (!config) {
|
|
344
338
|
return null;
|
|
@@ -366,7 +360,7 @@ async function getStackAccessTokenForCli(options) {
|
|
|
366
360
|
refreshed = await refreshStackAccessToken(config, refreshToken);
|
|
367
361
|
}
|
|
368
362
|
if (!refreshed) {
|
|
369
|
-
throw new Error("Failed to authenticate
|
|
363
|
+
throw new Error("Failed to authenticate.");
|
|
370
364
|
}
|
|
371
365
|
if (refreshed.refreshToken && refreshed.refreshToken !== refreshToken) {
|
|
372
366
|
persistAuth(config, refreshed.refreshToken);
|
|
@@ -381,15 +375,9 @@ async function getFreestyleClient() {
|
|
|
381
375
|
if (apiKey) {
|
|
382
376
|
return new Freestyle({ apiKey, baseUrl });
|
|
383
377
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
return new Freestyle({ accessToken, baseUrl });
|
|
388
|
-
}
|
|
389
|
-
console.error(
|
|
390
|
-
"Error: Stack CLI auth is enabled but authentication failed. Run `freestyle login` first."
|
|
391
|
-
);
|
|
392
|
-
process.exit(1);
|
|
378
|
+
const accessToken = await getStackAccessTokenForCli();
|
|
379
|
+
if (accessToken) {
|
|
380
|
+
return new Freestyle({ accessToken, baseUrl });
|
|
393
381
|
}
|
|
394
382
|
console.error(
|
|
395
383
|
"Error: FREESTYLE_API_KEY is required. Set it in your current folder's .env file."
|
|
@@ -409,7 +397,7 @@ function handleError(error) {
|
|
|
409
397
|
function loadEnv() {
|
|
410
398
|
const envPath = path.join(process.cwd(), ".env");
|
|
411
399
|
if (fs.existsSync(envPath)) {
|
|
412
|
-
dotenv.config({ path: envPath });
|
|
400
|
+
dotenv.config({ path: envPath, quiet: true });
|
|
413
401
|
}
|
|
414
402
|
}
|
|
415
403
|
function formatTable(headers, rows) {
|
|
@@ -1638,11 +1626,11 @@ const cronCommand = {
|
|
|
1638
1626
|
|
|
1639
1627
|
const loginCommand = {
|
|
1640
1628
|
command: "login",
|
|
1641
|
-
describe: "Authenticate the CLI
|
|
1629
|
+
describe: "Authenticate the CLI",
|
|
1642
1630
|
builder: (yargs) => {
|
|
1643
1631
|
return yargs.option("save-to-dotenv", {
|
|
1644
1632
|
type: "boolean",
|
|
1645
|
-
description: "Save the
|
|
1633
|
+
description: "Save the refresh token into the current folder's .env as FREESTYLE_STACK_REFRESH_TOKEN",
|
|
1646
1634
|
default: false
|
|
1647
1635
|
}).option("force", {
|
|
1648
1636
|
type: "boolean",
|
|
@@ -1650,26 +1638,18 @@ const loginCommand = {
|
|
|
1650
1638
|
default: false
|
|
1651
1639
|
}).option("stack-project-id", {
|
|
1652
1640
|
type: "string",
|
|
1653
|
-
description: "
|
|
1641
|
+
description: "Project ID (overrides environment for this run)"
|
|
1654
1642
|
}).option("stack-publishable-client-key", {
|
|
1655
1643
|
type: "string",
|
|
1656
|
-
description: "
|
|
1644
|
+
description: "Publishable client key (overrides environment for this run)"
|
|
1657
1645
|
}).option("stack-app-url", {
|
|
1658
1646
|
type: "string",
|
|
1659
|
-
description: "
|
|
1647
|
+
description: "App URL for browser confirmation (default: https://freestyle.sh)"
|
|
1660
1648
|
});
|
|
1661
1649
|
},
|
|
1662
1650
|
handler: async (argv) => {
|
|
1663
1651
|
loadEnv();
|
|
1664
1652
|
const args = argv;
|
|
1665
|
-
if (!isStackCliAuthEnabled()) {
|
|
1666
|
-
handleError(
|
|
1667
|
-
new Error(
|
|
1668
|
-
"Stack CLI auth is disabled. Set FREESTYLE_ENABLE_STACK_CLI_AUTH=true to use `freestyle login`."
|
|
1669
|
-
)
|
|
1670
|
-
);
|
|
1671
|
-
return;
|
|
1672
|
-
}
|
|
1673
1653
|
if (args.stackProjectId) {
|
|
1674
1654
|
process.env.FREESTYLE_STACK_PROJECT_ID = args.stackProjectId;
|
|
1675
1655
|
}
|
|
@@ -1686,10 +1666,10 @@ const loginCommand = {
|
|
|
1686
1666
|
});
|
|
1687
1667
|
if (!accessToken) {
|
|
1688
1668
|
throw new Error(
|
|
1689
|
-
"
|
|
1669
|
+
"Authentication is not configured. Set FREESTYLE_STACK_PROJECT_ID and FREESTYLE_STACK_PUBLISHABLE_CLIENT_KEY."
|
|
1690
1670
|
);
|
|
1691
1671
|
}
|
|
1692
|
-
console.log("\u2713 Authenticated
|
|
1672
|
+
console.log("\u2713 Authenticated");
|
|
1693
1673
|
if (args.saveToDotenv) {
|
|
1694
1674
|
console.log("\u2713 Saved refresh token to .env in current directory");
|
|
1695
1675
|
} else {
|
|
@@ -1701,4 +1681,5 @@ const loginCommand = {
|
|
|
1701
1681
|
}
|
|
1702
1682
|
};
|
|
1703
1683
|
|
|
1684
|
+
dotenv.config({ quiet: true });
|
|
1704
1685
|
yargs(hideBin(process.argv)).scriptName("freestyle").usage("$0 <command> [options]").command(vmCommand).command(gitCommand).command(domainsCommand).command(cronCommand).command(loginCommand).command(deployCommand).command(runCommand).demandCommand(1, "You need to specify a command").help().alias("help", "h").version().alias("version", "v").strict().parse();
|
package/index.cjs
CHANGED
|
@@ -5679,6 +5679,10 @@ const VmBuilder = VmWith;
|
|
|
5679
5679
|
function composeCreateVmOptions(arr) {
|
|
5680
5680
|
const result = {};
|
|
5681
5681
|
for (const options of arr) {
|
|
5682
|
+
if (options.rootfsSizeGb !== void 0)
|
|
5683
|
+
result.rootfsSizeGb = options.rootfsSizeGb;
|
|
5684
|
+
if (options.memSizeGb !== void 0) result.memSizeGb = options.memSizeGb;
|
|
5685
|
+
if (options.vcpuCount !== void 0) result.vcpuCount = options.vcpuCount;
|
|
5682
5686
|
if (options.idleTimeoutSeconds !== void 0)
|
|
5683
5687
|
result.idleTimeoutSeconds = options.idleTimeoutSeconds;
|
|
5684
5688
|
if (options.waitForReadySignal !== void 0)
|
package/index.mjs
CHANGED
|
@@ -5677,6 +5677,10 @@ const VmBuilder = VmWith;
|
|
|
5677
5677
|
function composeCreateVmOptions(arr) {
|
|
5678
5678
|
const result = {};
|
|
5679
5679
|
for (const options of arr) {
|
|
5680
|
+
if (options.rootfsSizeGb !== void 0)
|
|
5681
|
+
result.rootfsSizeGb = options.rootfsSizeGb;
|
|
5682
|
+
if (options.memSizeGb !== void 0) result.memSizeGb = options.memSizeGb;
|
|
5683
|
+
if (options.vcpuCount !== void 0) result.vcpuCount = options.vcpuCount;
|
|
5680
5684
|
if (options.idleTimeoutSeconds !== void 0)
|
|
5681
5685
|
result.idleTimeoutSeconds = options.idleTimeoutSeconds;
|
|
5682
5686
|
if (options.waitForReadySignal !== void 0)
|