@boltic/cli 1.1.1-dev.1 → 1.1.1-dev.2
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/commands/serverless.js +7 -7
- package/helper/serverless.js +144 -102
- package/package.json +2 -1
package/commands/serverless.js
CHANGED
|
@@ -74,8 +74,8 @@ const commands = {
|
|
|
74
74
|
|
|
75
75
|
// Serverless type choices for dropdown
|
|
76
76
|
const SERVERLESS_TYPE_CHOICES = [
|
|
77
|
-
{ name: "
|
|
78
|
-
{ name: "
|
|
77
|
+
{ name: "📦 Git - Deploy from Git repository", value: "git" },
|
|
78
|
+
{ name: "📝 Blueprint - Write code directly", value: "code" },
|
|
79
79
|
{ name: "🐳 Container - Deploy Docker container", value: "container" },
|
|
80
80
|
];
|
|
81
81
|
|
|
@@ -347,7 +347,7 @@ async function handleCodeTypeCreate(name, language, version, targetDir) {
|
|
|
347
347
|
// Display success message
|
|
348
348
|
console.log("\n" + chalk.bgGreen.black(" ✓ CREATED ") + "\n");
|
|
349
349
|
console.log(
|
|
350
|
-
chalk.green("📝
|
|
350
|
+
chalk.green("📝 Blueprint serverless function created successfully!")
|
|
351
351
|
);
|
|
352
352
|
console.log();
|
|
353
353
|
console.log(chalk.cyan(" Name: ") + chalk.white(name));
|
|
@@ -1563,7 +1563,7 @@ function showHelp() {
|
|
|
1563
1563
|
console.log(
|
|
1564
1564
|
chalk.bold(" --type, -t") +
|
|
1565
1565
|
chalk.dim(" ") +
|
|
1566
|
-
"Serverless type:
|
|
1566
|
+
"Serverless type: blueprint, git, or container (prompts if not provided)"
|
|
1567
1567
|
);
|
|
1568
1568
|
console.log(
|
|
1569
1569
|
chalk.bold(" --name, -n") +
|
|
@@ -1619,9 +1619,9 @@ function showHelp() {
|
|
|
1619
1619
|
)
|
|
1620
1620
|
);
|
|
1621
1621
|
console.log(" boltic serverless create\n");
|
|
1622
|
-
console.log(chalk.dim(" # Create
|
|
1622
|
+
console.log(chalk.dim(" # Create blueprint serverless"));
|
|
1623
1623
|
console.log(
|
|
1624
|
-
" boltic serverless create --type
|
|
1624
|
+
" boltic serverless create --type blueprint --name my-api --language nodejs\n"
|
|
1625
1625
|
);
|
|
1626
1626
|
console.log(
|
|
1627
1627
|
chalk.dim(
|
|
@@ -1637,7 +1637,7 @@ function showHelp() {
|
|
|
1637
1637
|
);
|
|
1638
1638
|
console.log(chalk.dim(" # With custom directory"));
|
|
1639
1639
|
console.log(
|
|
1640
|
-
" boltic serverless create --type
|
|
1640
|
+
" boltic serverless create --type blueprint --name my-function --language python --directory ./projects\n"
|
|
1641
1641
|
);
|
|
1642
1642
|
|
|
1643
1643
|
console.log(chalk.cyan("\nTest Examples:\n"));
|
package/helper/serverless.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
adjectives,
|
|
9
9
|
animals,
|
|
10
10
|
} from "unique-names-generator";
|
|
11
|
+
import ora from "ora";
|
|
11
12
|
|
|
12
13
|
// Supported languages and their versions
|
|
13
14
|
export const SUPPORTED_LANGUAGES = ["nodejs", "python", "golang", "java"];
|
|
@@ -59,7 +60,12 @@ export function parseCreateArgs(args) {
|
|
|
59
60
|
parsed.directory = path.resolve(nextArg);
|
|
60
61
|
i++;
|
|
61
62
|
} else if ((arg === "--type" || arg === "-t") && nextArg) {
|
|
62
|
-
|
|
63
|
+
let typeValue = nextArg.toLowerCase();
|
|
64
|
+
// Map "blueprint" to "code" for UI consistency
|
|
65
|
+
if (typeValue === "blueprint") {
|
|
66
|
+
typeValue = "code";
|
|
67
|
+
}
|
|
68
|
+
parsed.type = typeValue;
|
|
63
69
|
i++;
|
|
64
70
|
}
|
|
65
71
|
}
|
|
@@ -1526,8 +1532,6 @@ export async function pollServerlessStatus(
|
|
|
1526
1532
|
) {
|
|
1527
1533
|
const { apiUrl, token, accountId, session } = credentials;
|
|
1528
1534
|
const startTime = Date.now();
|
|
1529
|
-
const spinnerFrames = ["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"];
|
|
1530
|
-
let spinnerIndex = 0;
|
|
1531
1535
|
let initialBuildId = null;
|
|
1532
1536
|
let sawNewBuild = false;
|
|
1533
1537
|
|
|
@@ -1540,136 +1544,174 @@ export async function pollServerlessStatus(
|
|
|
1540
1544
|
return `${minutes}m ${remainingSecs}s`;
|
|
1541
1545
|
};
|
|
1542
1546
|
|
|
1543
|
-
// Get status
|
|
1544
|
-
const
|
|
1547
|
+
// Get status text (without chalk for ora)
|
|
1548
|
+
const getStatusText = (status) => {
|
|
1545
1549
|
switch (status) {
|
|
1546
1550
|
case "running":
|
|
1547
|
-
return
|
|
1551
|
+
return "Running";
|
|
1548
1552
|
case "building":
|
|
1549
|
-
return
|
|
1553
|
+
return "Building";
|
|
1550
1554
|
case "pending":
|
|
1551
|
-
return
|
|
1555
|
+
return "Pending";
|
|
1552
1556
|
case "draft":
|
|
1553
|
-
return
|
|
1557
|
+
return "Initializing";
|
|
1554
1558
|
case "failed":
|
|
1555
1559
|
case "error":
|
|
1556
|
-
return
|
|
1560
|
+
return "Failed";
|
|
1557
1561
|
case "success":
|
|
1558
1562
|
case "successful":
|
|
1559
|
-
return
|
|
1563
|
+
return "Success";
|
|
1560
1564
|
default:
|
|
1561
|
-
return
|
|
1565
|
+
return status || "Waiting";
|
|
1562
1566
|
}
|
|
1563
1567
|
};
|
|
1564
1568
|
|
|
1565
1569
|
console.log();
|
|
1566
1570
|
console.log(chalk.cyan(" Deploying serverless function..."));
|
|
1571
|
+
console.log(
|
|
1572
|
+
chalk.dim(" Press Ctrl+C to exit. Check status later with: ") +
|
|
1573
|
+
chalk.white("boltic serverless status -n <name>")
|
|
1574
|
+
);
|
|
1567
1575
|
console.log();
|
|
1568
1576
|
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1577
|
+
// Track current status for display
|
|
1578
|
+
let status = "pending";
|
|
1579
|
+
let buildStatus = null;
|
|
1580
|
+
let lastServerless = null;
|
|
1573
1581
|
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
session,
|
|
1581
|
-
serverlessId
|
|
1582
|
-
);
|
|
1582
|
+
// Create ora spinner
|
|
1583
|
+
const spinner = ora({
|
|
1584
|
+
text: `${getStatusText(status)} (0s)`,
|
|
1585
|
+
spinner: "dots",
|
|
1586
|
+
color: "cyan",
|
|
1587
|
+
}).start();
|
|
1583
1588
|
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1589
|
+
// Update elapsed time every second
|
|
1590
|
+
const timerInterval = setInterval(() => {
|
|
1591
|
+
const elapsed = Date.now() - startTime;
|
|
1592
|
+
let text = getStatusText(status);
|
|
1593
|
+
if (buildStatus && buildStatus !== status) {
|
|
1594
|
+
text += ` • Build: ${getStatusText(buildStatus)}`;
|
|
1595
|
+
}
|
|
1596
|
+
text += ` (${formatElapsed(elapsed)})`;
|
|
1597
|
+
spinner.text = text;
|
|
1598
|
+
}, 1000);
|
|
1588
1599
|
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1600
|
+
// Cleanup function
|
|
1601
|
+
const cleanup = () => {
|
|
1602
|
+
clearInterval(timerInterval);
|
|
1603
|
+
};
|
|
1593
1604
|
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1605
|
+
try {
|
|
1606
|
+
while (Date.now() - startTime < maxTime) {
|
|
1607
|
+
try {
|
|
1608
|
+
// Fetch serverless status
|
|
1609
|
+
const serverless = await fetchStatus(
|
|
1610
|
+
apiUrl,
|
|
1611
|
+
token,
|
|
1612
|
+
accountId,
|
|
1613
|
+
session,
|
|
1614
|
+
serverlessId
|
|
1615
|
+
);
|
|
1602
1616
|
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
}
|
|
1617
|
+
lastServerless = serverless;
|
|
1618
|
+
status = serverless?.Status || "pending";
|
|
1619
|
+
buildStatus =
|
|
1620
|
+
serverless?.LastBuild?.StatusHistory?.slice(-1)[0]?.Status;
|
|
1621
|
+
const currentBuildId = serverless?.LastBuild?.ID;
|
|
1609
1622
|
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1623
|
+
// Track if a new build has started
|
|
1624
|
+
if (!initialBuildId) {
|
|
1625
|
+
initialBuildId = currentBuildId;
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
// Detect new build
|
|
1629
|
+
if (
|
|
1630
|
+
currentBuildId !== initialBuildId ||
|
|
1631
|
+
buildStatus === "building" ||
|
|
1632
|
+
buildStatus === "created"
|
|
1633
|
+
) {
|
|
1634
|
+
sawNewBuild = true;
|
|
1635
|
+
}
|
|
1614
1636
|
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1637
|
+
// Update spinner color based on status
|
|
1638
|
+
if (status === "running" || buildStatus === "success") {
|
|
1639
|
+
spinner.color = "green";
|
|
1640
|
+
} else if (status === "failed" || buildStatus === "failed") {
|
|
1641
|
+
spinner.color = "red";
|
|
1642
|
+
} else if (
|
|
1643
|
+
status === "building" ||
|
|
1644
|
+
buildStatus === "building"
|
|
1645
|
+
) {
|
|
1646
|
+
spinner.color = "yellow";
|
|
1647
|
+
}
|
|
1622
1648
|
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
console.log(chalk.cyan(" 🌐 Your serverless is live at:"));
|
|
1637
|
-
console.log(chalk.white.bold(` ${url}`));
|
|
1649
|
+
// Success condition
|
|
1650
|
+
const isBuildComplete =
|
|
1651
|
+
buildStatus === "success" || buildStatus === "successful";
|
|
1652
|
+
const isRunning = status === "running";
|
|
1653
|
+
|
|
1654
|
+
if (sawNewBuild && isRunning && isBuildComplete) {
|
|
1655
|
+
const elapsed = Date.now() - startTime;
|
|
1656
|
+
cleanup();
|
|
1657
|
+
spinner.succeed(
|
|
1658
|
+
chalk.green(
|
|
1659
|
+
`Deployed successfully in ${formatElapsed(elapsed)}`
|
|
1660
|
+
)
|
|
1661
|
+
);
|
|
1638
1662
|
console.log();
|
|
1663
|
+
|
|
1664
|
+
// Print access URL if available
|
|
1665
|
+
const appDomain = serverless?.AppDomain?.[0];
|
|
1666
|
+
if (appDomain) {
|
|
1667
|
+
const url = `https://${appDomain.DomainName}.${appDomain.BaseUrl || "serverless.boltic.app"}`;
|
|
1668
|
+
console.log(
|
|
1669
|
+
chalk.cyan(" 🌐 Your serverless is live at:")
|
|
1670
|
+
);
|
|
1671
|
+
console.log(chalk.white.bold(` ${url}`));
|
|
1672
|
+
console.log();
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
return { success: true, status, serverless };
|
|
1639
1676
|
}
|
|
1640
1677
|
|
|
1641
|
-
|
|
1678
|
+
// Check for failed status
|
|
1679
|
+
if (status === "failed" || buildStatus === "failed") {
|
|
1680
|
+
const elapsed = Date.now() - startTime;
|
|
1681
|
+
cleanup();
|
|
1682
|
+
spinner.fail(
|
|
1683
|
+
chalk.red(
|
|
1684
|
+
`Deployment failed after ${formatElapsed(elapsed)}`
|
|
1685
|
+
)
|
|
1686
|
+
);
|
|
1687
|
+
console.log();
|
|
1688
|
+
return { success: false, status, serverless };
|
|
1689
|
+
}
|
|
1690
|
+
} catch (error) {
|
|
1691
|
+
// Error during fetch - will retry on next poll
|
|
1642
1692
|
}
|
|
1643
1693
|
|
|
1644
|
-
//
|
|
1645
|
-
|
|
1646
|
-
process.stdout.write("\r\x1b[K"); // Clear spinner line
|
|
1647
|
-
console.log(
|
|
1648
|
-
chalk.red(
|
|
1649
|
-
` ✗ Deployment failed after ${formatElapsed(elapsed)}`
|
|
1650
|
-
)
|
|
1651
|
-
);
|
|
1652
|
-
console.log();
|
|
1653
|
-
return { success: false, status, serverless };
|
|
1654
|
-
}
|
|
1655
|
-
} catch (error) {
|
|
1656
|
-
process.stdout.write(
|
|
1657
|
-
`\r\x1b[K ${chalk.yellow("!")} ${chalk.dim("Retrying...")} ${chalk.dim(`(${formatElapsed(elapsed)})`)}`
|
|
1658
|
-
);
|
|
1694
|
+
// Wait before next poll
|
|
1695
|
+
await new Promise((r) => setTimeout(r, interval));
|
|
1659
1696
|
}
|
|
1660
1697
|
|
|
1661
|
-
//
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
console.log(
|
|
1670
|
-
chalk.dim(" Check status: boltic serverless status -n <name>")
|
|
1671
|
-
);
|
|
1672
|
-
console.log();
|
|
1698
|
+
// Timeout reached
|
|
1699
|
+
cleanup();
|
|
1700
|
+
spinner.warn(chalk.yellow(`Timeout after ${formatElapsed(maxTime)}`));
|
|
1701
|
+
console.log(chalk.dim(" Deployment may still be in progress."));
|
|
1702
|
+
console.log(
|
|
1703
|
+
chalk.dim(" Check status: boltic serverless status -n <name>")
|
|
1704
|
+
);
|
|
1705
|
+
console.log();
|
|
1673
1706
|
|
|
1674
|
-
|
|
1707
|
+
return {
|
|
1708
|
+
success: false,
|
|
1709
|
+
status: "timeout",
|
|
1710
|
+
serverless: lastServerless,
|
|
1711
|
+
};
|
|
1712
|
+
} catch (error) {
|
|
1713
|
+
cleanup();
|
|
1714
|
+
spinner.fail("Polling interrupted");
|
|
1715
|
+
throw error;
|
|
1716
|
+
}
|
|
1675
1717
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@boltic/cli",
|
|
3
|
-
"version": "v1.1.1-dev.
|
|
3
|
+
"version": "v1.1.1-dev.2",
|
|
4
4
|
"description": "A powerful CLI tool for managing Boltic Workflow integrations - create, sync, test, and publish integrations with ease",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -105,6 +105,7 @@
|
|
|
105
105
|
"keytar": "^7.9.0",
|
|
106
106
|
"lodash.isempty": "^4.4.0",
|
|
107
107
|
"open": "^10.2.0",
|
|
108
|
+
"ora": "^9.0.0",
|
|
108
109
|
"unique-names-generator": "^4.7.1",
|
|
109
110
|
"uuid": "^11.1.0"
|
|
110
111
|
},
|