@videan/cli 0.3.1 → 0.4.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 +5 -0
- package/dist/index.js +56 -5
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,6 +16,11 @@ videan secrets set KEY=value
|
|
|
16
16
|
videan apps list
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
Apps run as a **container** (default: always on) or **serverless** (scales to
|
|
20
|
+
zero, cold start after idle): `videan apps create --mode serverless`, or switch
|
|
21
|
+
later with `videan apps set --mode …` — applied by the next deploy. Serverless
|
|
22
|
+
refuses cron, background jobs, WebSockets and custom Dockerfiles.
|
|
23
|
+
|
|
19
24
|
The deployed contract is **expose an HTTP port on 3000**. Runtime (Node,
|
|
20
25
|
Python, Next.js, Go, or your own Dockerfile) is detected from the files.
|
|
21
26
|
Every deploy is an immutable snapshot; production is a pointer to one.
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,9 @@ import os from "node:os";
|
|
|
14
14
|
var DEFAULT_API_URL = "https://api.videan.xyz/v1";
|
|
15
15
|
var APP_DOMAIN = process.env.CLOUD_APP_DOMAIN || "videan.xyz";
|
|
16
16
|
var MAX_FILE_SIZE_BYTES = 50 * 1024 * 1024;
|
|
17
|
+
var APP_PORT = 3e3;
|
|
18
|
+
var LAMBDA_ADAPTER = `COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.9.1 /lambda-adapter /opt/extensions/lambda-adapter
|
|
19
|
+
ENV AWS_LWA_PORT=${APP_PORT}`;
|
|
17
20
|
var FARGATE_SIZES = {
|
|
18
21
|
256: { min: 512, max: 2048, step: 512 },
|
|
19
22
|
512: { min: 1024, max: 4096, step: 1024 },
|
|
@@ -170,7 +173,9 @@ var AppsNamespace = class {
|
|
|
170
173
|
storage_enabled: opts.storage,
|
|
171
174
|
email_enabled: opts.email,
|
|
172
175
|
auth_required: opts.authRequired,
|
|
173
|
-
visibility: opts.visibility
|
|
176
|
+
visibility: opts.visibility,
|
|
177
|
+
stack: opts.stack,
|
|
178
|
+
mode: opts.mode
|
|
174
179
|
};
|
|
175
180
|
const res = await this.client.request("POST", "/apps", body);
|
|
176
181
|
return res.data;
|
|
@@ -199,6 +204,8 @@ var AppsNamespace = class {
|
|
|
199
204
|
if (changes.postgres !== void 0) body.postgres_enabled = changes.postgres;
|
|
200
205
|
if (changes.storage !== void 0) body.storage_enabled = changes.storage;
|
|
201
206
|
if (changes.email !== void 0) body.email_enabled = changes.email;
|
|
207
|
+
if (changes.stack !== void 0) body.stack = changes.stack;
|
|
208
|
+
if (changes.mode !== void 0) body.mode = changes.mode;
|
|
202
209
|
const res = await this.client.request(
|
|
203
210
|
"PATCH",
|
|
204
211
|
`/apps/${appId}`,
|
|
@@ -677,6 +684,12 @@ var OrgsNamespace = class {
|
|
|
677
684
|
}
|
|
678
685
|
};
|
|
679
686
|
|
|
687
|
+
// ../shared/src/types.ts
|
|
688
|
+
var APP_MODES = ["container", "serverless"];
|
|
689
|
+
function isAppMode(value) {
|
|
690
|
+
return APP_MODES.includes(value);
|
|
691
|
+
}
|
|
692
|
+
|
|
680
693
|
// ../shared/src/constants.ts
|
|
681
694
|
var SUPPORTED_RUNTIMES = [
|
|
682
695
|
"node-20",
|
|
@@ -694,6 +707,11 @@ function appUrl(slug) {
|
|
|
694
707
|
var CONFIG_FILE_NAME = "cloud.yaml";
|
|
695
708
|
var MAX_FILE_SIZE_BYTES2 = 50 * 1024 * 1024;
|
|
696
709
|
|
|
710
|
+
// ../shared/src/detect.ts
|
|
711
|
+
var APP_PORT2 = 3e3;
|
|
712
|
+
var LAMBDA_ADAPTER2 = `COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.9.1 /lambda-adapter /opt/extensions/lambda-adapter
|
|
713
|
+
ENV AWS_LWA_PORT=${APP_PORT2}`;
|
|
714
|
+
|
|
697
715
|
// ../shared/src/sizing.ts
|
|
698
716
|
var FARGATE_SIZES2 = {
|
|
699
717
|
256: { min: 512, max: 2048, step: 512 },
|
|
@@ -965,6 +983,15 @@ This platform puts a sign-in gate in front of apps unless they are public.
|
|
|
965
983
|
|
|
966
984
|
Secrets: \`videan secrets set KEY=value\` (UPPERCASE keys) \u2014 injected as env
|
|
967
985
|
vars on the next deploy. Never commit credentials to this repo instead.
|
|
986
|
+
|
|
987
|
+
## Execution modes
|
|
988
|
+
|
|
989
|
+
Apps run as a **container** (default: always on, no cold starts) or
|
|
990
|
+
**serverless** (scales to zero, cold start after idle \u2014 good for internal
|
|
991
|
+
tools with sporadic traffic). Set at create (\`videan apps create --mode
|
|
992
|
+
serverless\`) or later (\`videan apps set --mode \u2026\`, applied by the next
|
|
993
|
+
deploy). Serverless refuses cron, background jobs, WebSockets and custom
|
|
994
|
+
Dockerfiles; container mode supports all of them.
|
|
968
995
|
`;
|
|
969
996
|
var POINTER = "\n## Videan\n\nThis project deploys to Videan \u2014 see VIDEAN.md for the platform contract (port 3000, auth headers, deploy commands) before writing server or login code.\n";
|
|
970
997
|
async function writeVideanMd(dir) {
|
|
@@ -1503,6 +1530,15 @@ function accessOption(value) {
|
|
|
1503
1530
|
}
|
|
1504
1531
|
return tier;
|
|
1505
1532
|
}
|
|
1533
|
+
function modeOption(value) {
|
|
1534
|
+
if (value === void 0) return void 0;
|
|
1535
|
+
const mode = value.trim().toLowerCase();
|
|
1536
|
+
if (!isAppMode(mode)) {
|
|
1537
|
+
console.error(chalk11.red(`Unknown --mode value "${value}". Use one of: ${APP_MODES.join(", ")}`));
|
|
1538
|
+
process.exit(1);
|
|
1539
|
+
}
|
|
1540
|
+
return mode;
|
|
1541
|
+
}
|
|
1506
1542
|
function describeAccess(app) {
|
|
1507
1543
|
const tier = app.visibility ? visibilityOf(app.visibility) : app.authRequired ? "org" : "public";
|
|
1508
1544
|
return `${tier} \u2014 ${VISIBILITY_LABELS[tier].toLowerCase()}`;
|
|
@@ -1523,7 +1559,13 @@ appsCommand.command("list").description("List all apps").option("-o, --org <id>"
|
|
|
1523
1559
|
console.log(formatRow([app.name, app.id, app.status, appUrl(app.slug)], widths));
|
|
1524
1560
|
}
|
|
1525
1561
|
});
|
|
1526
|
-
appsCommand.command("create").description("Create a new app").option("-n, --name <name>", "App name").option("-o, --org <id>", "Organization ID").option("--postgres", "Provision a managed Postgres database").option("--storage", "Give the app an object-storage prefix").option("--email", "Let the app send mail through the platform").option("--public", "Serve the app without the platform login gate (same as --access public)").option("--access <tier>", `Who may open the app: ${VISIBILITIES.join(" | ")} (default: ${DEFAULT_VISIBILITY})`).
|
|
1562
|
+
appsCommand.command("create").description("Create a new app").option("-n, --name <name>", "App name").option("-o, --org <id>", "Organization ID").option("--postgres", "Provision a managed Postgres database").option("--storage", "Give the app an object-storage prefix").option("--email", "Let the app send mail through the platform").option("--public", "Serve the app without the platform login gate (same as --access public)").option("--access <tier>", `Who may open the app: ${VISIBILITIES.join(" | ")} (default: ${DEFAULT_VISIBILITY})`).option(
|
|
1563
|
+
"--stack <label>",
|
|
1564
|
+
"Group this app with its siblings (set the same label on a split frontend and backend)"
|
|
1565
|
+
).option(
|
|
1566
|
+
"--mode <mode>",
|
|
1567
|
+
`How the app runs: ${APP_MODES.join(" | ")} (default: container). serverless scales to zero but runs no cron, jobs or WebSockets`
|
|
1568
|
+
).action(
|
|
1527
1569
|
async (opts) => {
|
|
1528
1570
|
const apiKey = getApiKey();
|
|
1529
1571
|
requireApiKey(apiKey);
|
|
@@ -1540,6 +1582,7 @@ appsCommand.command("create").description("Create a new app").option("-n, --name
|
|
|
1540
1582
|
process.exit(1);
|
|
1541
1583
|
}
|
|
1542
1584
|
const visibility = accessOption(opts.access) ?? (opts.public ? "public" : void 0);
|
|
1585
|
+
const mode = modeOption(opts.mode);
|
|
1543
1586
|
const client4 = new CloudClient({ apiKey, baseUrl: getBaseUrl() });
|
|
1544
1587
|
const app = await client4.apps.create({
|
|
1545
1588
|
name,
|
|
@@ -1547,16 +1590,19 @@ appsCommand.command("create").description("Create a new app").option("-n, --name
|
|
|
1547
1590
|
postgres: opts.postgres ?? false,
|
|
1548
1591
|
storage: opts.storage ?? false,
|
|
1549
1592
|
email: opts.email ?? false,
|
|
1550
|
-
visibility
|
|
1593
|
+
visibility,
|
|
1594
|
+
stack: opts.stack,
|
|
1595
|
+
mode
|
|
1551
1596
|
});
|
|
1552
1597
|
setCurrentApp(app.id);
|
|
1553
1598
|
console.log(chalk11.green(`App "${app.name}" created (${app.id})`));
|
|
1599
|
+
console.log(chalk11.gray(` Mode: ${app.mode ?? "container"}`));
|
|
1554
1600
|
console.log(chalk11.gray(` Access: ${describeAccess(app)}`));
|
|
1555
1601
|
console.log(chalk11.gray(` URL after first deploy: ${appUrl(app.slug)}`));
|
|
1556
1602
|
console.log(chalk11.gray(" Push code with `videan deploy` \u2014 the runtime is auto-detected."));
|
|
1557
1603
|
}
|
|
1558
1604
|
);
|
|
1559
|
-
appsCommand.command("set").description("Change an app's settings (scale, rate limit, gate, capabilities)").option("-a, --app <id>", "App ID").option("-n, --name <name>", "Rename the app (the URL keeps its original slug)").option("--cpu <units>", "CPU units per instance (256 = 0.25 vCPU)").option("--memory <mib>", "Memory per instance, in MiB").option("--instances <n>", "Number of instances to run").option("--rate-limit <rpm>", "Requests per minute per client").option("--no-rate-limit", "Remove the rate limit").option("--access <tier>", `Who may open the app: ${VISIBILITIES.join(" | ")}`).option("--public", "Serve without the platform login gate (same as --access public)").option("--private", "Require platform login (leaves the tier alone if it is already gated)").option("--postgres", "Provision a managed Postgres database").option("--storage", "Give the app an object-storage prefix").option("--email", "Let the app send mail through the platform").option("--json", "Print the raw response").action(
|
|
1605
|
+
appsCommand.command("set").description("Change an app's settings (scale, rate limit, gate, capabilities)").option("-a, --app <id>", "App ID").option("-n, --name <name>", "Rename the app (the URL keeps its original slug)").option("--cpu <units>", "CPU units per instance (256 = 0.25 vCPU)").option("--memory <mib>", "Memory per instance, in MiB").option("--instances <n>", "Number of instances to run").option("--rate-limit <rpm>", "Requests per minute per client").option("--no-rate-limit", "Remove the rate limit").option("--access <tier>", `Who may open the app: ${VISIBILITIES.join(" | ")}`).option("--public", "Serve without the platform login gate (same as --access public)").option("--private", "Require platform login (leaves the tier alone if it is already gated)").option("--postgres", "Provision a managed Postgres database").option("--storage", "Give the app an object-storage prefix").option("--email", "Let the app send mail through the platform").option("--stack <label>", "Group this app with its siblings under a shared label").option("--no-stack", "Remove the app from its stack").option("--mode <mode>", `How the app runs: ${APP_MODES.join(" | ")} (applies on the next deploy or restart)`).option("--json", "Print the raw response").action(
|
|
1560
1606
|
async (opts) => {
|
|
1561
1607
|
const apiKey = getApiKey();
|
|
1562
1608
|
requireApiKey(apiKey);
|
|
@@ -1574,8 +1620,10 @@ appsCommand.command("set").description("Change an app's settings (scale, rate li
|
|
|
1574
1620
|
console.error(chalk11.red("--access already says who may open the app; drop --public/--private."));
|
|
1575
1621
|
process.exit(1);
|
|
1576
1622
|
}
|
|
1623
|
+
const mode = modeOption(opts.mode);
|
|
1577
1624
|
const changes = {};
|
|
1578
1625
|
if (opts.name) changes.name = opts.name;
|
|
1626
|
+
if (mode) changes.mode = mode;
|
|
1579
1627
|
if (opts.cpu !== void 0) changes.cpu = intOption("--cpu", opts.cpu);
|
|
1580
1628
|
if (opts.memory !== void 0) changes.memory = intOption("--memory", opts.memory);
|
|
1581
1629
|
if (opts.instances !== void 0) {
|
|
@@ -1591,6 +1639,8 @@ appsCommand.command("set").description("Change an app's settings (scale, rate li
|
|
|
1591
1639
|
if (opts.postgres) changes.postgres = true;
|
|
1592
1640
|
if (opts.storage) changes.storage = true;
|
|
1593
1641
|
if (opts.email) changes.email = true;
|
|
1642
|
+
if (opts.stack === false) changes.stack = null;
|
|
1643
|
+
else if (typeof opts.stack === "string") changes.stack = opts.stack;
|
|
1594
1644
|
if (Object.keys(changes).length === 0) {
|
|
1595
1645
|
console.error(chalk11.red("Nothing to change. Pass at least one option."));
|
|
1596
1646
|
process.exit(1);
|
|
@@ -1602,6 +1652,7 @@ appsCommand.command("set").description("Change an app's settings (scale, rate li
|
|
|
1602
1652
|
return;
|
|
1603
1653
|
}
|
|
1604
1654
|
console.log(chalk11.green(`Updated ${app.name} (${app.id})`));
|
|
1655
|
+
console.log(` Mode: ${app.mode ?? "container"}`);
|
|
1605
1656
|
console.log(` Access: ${describeAccess(app)}`);
|
|
1606
1657
|
console.log(` Scale: ${app.cpu ?? "default"} CPU / ${app.memory ?? "default"} MiB`);
|
|
1607
1658
|
console.log(
|
|
@@ -2237,7 +2288,7 @@ function period(start, end) {
|
|
|
2237
2288
|
|
|
2238
2289
|
// src/index.ts
|
|
2239
2290
|
var program = new Command18();
|
|
2240
|
-
program.name("videan").description("Videan CLI \u2014 deploy apps in seconds").version("0.
|
|
2291
|
+
program.name("videan").description("Videan CLI \u2014 deploy apps in seconds").version("0.4.0");
|
|
2241
2292
|
program.addCommand(loginCommand);
|
|
2242
2293
|
program.addCommand(logoutCommand);
|
|
2243
2294
|
program.addCommand(initCommand);
|