@meetploy/cli 1.17.0 → 1.17.1
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/dashboard-dist/assets/{main-B-euJxpr.css → main-5Kt9I_hM.css} +1 -1
- package/dist/dashboard-dist/assets/main-Ch3tPHX5.js +354 -0
- package/dist/dashboard-dist/index.html +2 -2
- package/dist/dev.js +180 -0
- package/dist/index.js +398 -2
- package/package.json +1 -1
- package/dist/dashboard-dist/assets/main-duAiLjPq.js +0 -339
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Ploy Dev Dashboard</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/main-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="/assets/main-
|
|
7
|
+
<script type="module" crossorigin src="/assets/main-Ch3tPHX5.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="/assets/main-5Kt9I_hM.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
package/dist/dev.js
CHANGED
|
@@ -49,6 +49,62 @@ function readPloyConfig(projectDir, configPath) {
|
|
|
49
49
|
}
|
|
50
50
|
return config;
|
|
51
51
|
}
|
|
52
|
+
|
|
53
|
+
// ../emulator/dist/services/alarm-service.js
|
|
54
|
+
function createAlarmHandlers(db) {
|
|
55
|
+
const setHandler = async (c) => {
|
|
56
|
+
try {
|
|
57
|
+
const body = await c.req.json();
|
|
58
|
+
const { alarmName, id, scheduledTime, payload, intervalMs } = body;
|
|
59
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
60
|
+
const scheduledTimeSec = Math.floor(scheduledTime / 1e3);
|
|
61
|
+
db.prepare(`INSERT OR REPLACE INTO alarm_entries (id, alarm_name, scheduled_time, payload, interval_ms, status, created_at)
|
|
62
|
+
VALUES (?, ?, ?, ?, ?, 'pending', ?)`).run(id, alarmName, scheduledTimeSec, payload !== void 0 ? JSON.stringify(payload) : null, intervalMs ?? null, now);
|
|
63
|
+
return c.json({ success: true });
|
|
64
|
+
} catch (err) {
|
|
65
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
66
|
+
return c.json({ success: false, error: message }, 500);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const getHandler = async (c) => {
|
|
70
|
+
try {
|
|
71
|
+
const body = await c.req.json();
|
|
72
|
+
const { alarmName, id } = body;
|
|
73
|
+
const row = db.prepare(`SELECT id, scheduled_time, payload, interval_ms FROM alarm_entries
|
|
74
|
+
WHERE alarm_name = ? AND id = ? AND status = 'pending'`).get(alarmName, id);
|
|
75
|
+
if (!row) {
|
|
76
|
+
return c.json({ alarm: null });
|
|
77
|
+
}
|
|
78
|
+
return c.json({
|
|
79
|
+
alarm: {
|
|
80
|
+
id: row.id,
|
|
81
|
+
scheduledTime: row.scheduled_time * 1e3,
|
|
82
|
+
payload: row.payload ? JSON.parse(row.payload) : void 0,
|
|
83
|
+
intervalMs: row.interval_ms ?? void 0
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
} catch (err) {
|
|
87
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
88
|
+
return c.json({ success: false, error: message }, 500);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
const deleteHandler = async (c) => {
|
|
92
|
+
try {
|
|
93
|
+
const body = await c.req.json();
|
|
94
|
+
const { alarmName, id } = body;
|
|
95
|
+
db.prepare(`DELETE FROM alarm_entries WHERE alarm_name = ? AND id = ?`).run(alarmName, id);
|
|
96
|
+
return c.json({ success: true });
|
|
97
|
+
} catch (err) {
|
|
98
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
99
|
+
return c.json({ success: false, error: message }, 500);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
return {
|
|
103
|
+
setHandler,
|
|
104
|
+
getHandler,
|
|
105
|
+
deleteHandler
|
|
106
|
+
};
|
|
107
|
+
}
|
|
52
108
|
function getDataDir(projectDir) {
|
|
53
109
|
return join(projectDir, ".ploy");
|
|
54
110
|
}
|
|
@@ -381,6 +437,7 @@ function createDashboardRoutes(app, dbManager2, config) {
|
|
|
381
437
|
fs: config.fs,
|
|
382
438
|
workflow: config.workflow,
|
|
383
439
|
cron: config.cron,
|
|
440
|
+
alarm: config.alarm,
|
|
384
441
|
auth: config.auth
|
|
385
442
|
});
|
|
386
443
|
});
|
|
@@ -935,6 +992,93 @@ function createDashboardRoutes(app, dbManager2, config) {
|
|
|
935
992
|
return c.json({ error: err instanceof Error ? err.message : String(err) }, 500);
|
|
936
993
|
}
|
|
937
994
|
});
|
|
995
|
+
app.get("/api/alarm/:binding/entries", (c) => {
|
|
996
|
+
const binding = c.req.param("binding");
|
|
997
|
+
const alarmName = config.alarm?.[binding];
|
|
998
|
+
const limit = parseInt(c.req.query("limit") ?? "20", 10);
|
|
999
|
+
const offset = parseInt(c.req.query("offset") ?? "0", 10);
|
|
1000
|
+
if (!alarmName) {
|
|
1001
|
+
return c.json({ error: "Alarm binding not found" }, 404);
|
|
1002
|
+
}
|
|
1003
|
+
try {
|
|
1004
|
+
const db = dbManager2.emulatorDb;
|
|
1005
|
+
const total = db.prepare(`SELECT COUNT(*) as count FROM alarm_entries WHERE alarm_name = ?`).get(alarmName).count;
|
|
1006
|
+
const entries = db.prepare(`SELECT id, scheduled_time, payload, interval_ms, status, created_at
|
|
1007
|
+
FROM alarm_entries
|
|
1008
|
+
WHERE alarm_name = ?
|
|
1009
|
+
ORDER BY scheduled_time DESC
|
|
1010
|
+
LIMIT ? OFFSET ?`).all(alarmName, limit, offset);
|
|
1011
|
+
return c.json({
|
|
1012
|
+
entries: entries.map((e) => ({
|
|
1013
|
+
id: e.id,
|
|
1014
|
+
scheduledTime: new Date(e.scheduled_time * 1e3).toISOString(),
|
|
1015
|
+
payload: e.payload ? JSON.parse(e.payload) : null,
|
|
1016
|
+
intervalMs: e.interval_ms,
|
|
1017
|
+
status: e.status.toUpperCase(),
|
|
1018
|
+
createdAt: new Date(e.created_at * 1e3).toISOString()
|
|
1019
|
+
})),
|
|
1020
|
+
total,
|
|
1021
|
+
limit,
|
|
1022
|
+
offset
|
|
1023
|
+
});
|
|
1024
|
+
} catch (err) {
|
|
1025
|
+
return c.json({ error: err instanceof Error ? err.message : String(err) }, 500);
|
|
1026
|
+
}
|
|
1027
|
+
});
|
|
1028
|
+
app.get("/api/alarm/:binding/metrics", (c) => {
|
|
1029
|
+
const binding = c.req.param("binding");
|
|
1030
|
+
const alarmName = config.alarm?.[binding];
|
|
1031
|
+
if (!alarmName) {
|
|
1032
|
+
return c.json({ error: "Alarm binding not found" }, 404);
|
|
1033
|
+
}
|
|
1034
|
+
try {
|
|
1035
|
+
const db = dbManager2.emulatorDb;
|
|
1036
|
+
const metrics = { pending: 0, fired: 0 };
|
|
1037
|
+
const statusCounts = db.prepare(`SELECT status, COUNT(*) as count
|
|
1038
|
+
FROM alarm_entries
|
|
1039
|
+
WHERE alarm_name = ?
|
|
1040
|
+
GROUP BY status`).all(alarmName);
|
|
1041
|
+
for (const row of statusCounts) {
|
|
1042
|
+
if (row.status === "pending") {
|
|
1043
|
+
metrics.pending = row.count;
|
|
1044
|
+
} else if (row.status === "fired") {
|
|
1045
|
+
metrics.fired = row.count;
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
return c.json({ metrics });
|
|
1049
|
+
} catch (err) {
|
|
1050
|
+
return c.json({ error: err instanceof Error ? err.message : String(err) }, 500);
|
|
1051
|
+
}
|
|
1052
|
+
});
|
|
1053
|
+
app.get("/api/alarm/:binding/executions", (c) => {
|
|
1054
|
+
const binding = c.req.param("binding");
|
|
1055
|
+
const alarmName = config.alarm?.[binding];
|
|
1056
|
+
const limit = parseInt(c.req.query("limit") ?? "20", 10);
|
|
1057
|
+
if (!alarmName) {
|
|
1058
|
+
return c.json({ error: "Alarm binding not found" }, 404);
|
|
1059
|
+
}
|
|
1060
|
+
try {
|
|
1061
|
+
const db = dbManager2.emulatorDb;
|
|
1062
|
+
const executions = db.prepare(`SELECT id, alarm_id, scheduled_time, status, error, duration_ms, created_at
|
|
1063
|
+
FROM alarm_executions
|
|
1064
|
+
WHERE alarm_name = ?
|
|
1065
|
+
ORDER BY created_at DESC
|
|
1066
|
+
LIMIT ?`).all(alarmName, limit);
|
|
1067
|
+
return c.json({
|
|
1068
|
+
executions: executions.map((e) => ({
|
|
1069
|
+
id: e.id,
|
|
1070
|
+
alarmId: e.alarm_id,
|
|
1071
|
+
scheduledTime: new Date(e.scheduled_time * 1e3).toISOString(),
|
|
1072
|
+
status: e.status.toUpperCase(),
|
|
1073
|
+
error: e.error,
|
|
1074
|
+
durationMs: e.duration_ms,
|
|
1075
|
+
createdAt: new Date(e.created_at * 1e3).toISOString()
|
|
1076
|
+
}))
|
|
1077
|
+
});
|
|
1078
|
+
} catch (err) {
|
|
1079
|
+
return c.json({ error: err instanceof Error ? err.message : String(err) }, 500);
|
|
1080
|
+
}
|
|
1081
|
+
});
|
|
938
1082
|
if (hasDashboard) {
|
|
939
1083
|
app.get("/assets/*", (c) => {
|
|
940
1084
|
const path = c.req.path;
|
|
@@ -1538,6 +1682,12 @@ async function startMockServer(dbManager2, config, options = {}) {
|
|
|
1538
1682
|
app.post("/fs/delete", fsHandlers.deleteHandler);
|
|
1539
1683
|
app.post("/fs/list", fsHandlers.listHandler);
|
|
1540
1684
|
}
|
|
1685
|
+
if (config.alarm) {
|
|
1686
|
+
const alarmHandlers = createAlarmHandlers(dbManager2.emulatorDb);
|
|
1687
|
+
app.post("/alarm/set", alarmHandlers.setHandler);
|
|
1688
|
+
app.post("/alarm/get", alarmHandlers.getHandler);
|
|
1689
|
+
app.post("/alarm/delete", alarmHandlers.deleteHandler);
|
|
1690
|
+
}
|
|
1541
1691
|
if (config.auth) {
|
|
1542
1692
|
const authHandlers = createAuthHandlers(dbManager2.emulatorDb);
|
|
1543
1693
|
app.post("/auth/signup", authHandlers.signupHandler);
|
|
@@ -1701,6 +1851,36 @@ CREATE TABLE IF NOT EXISTS cron_executions (
|
|
|
1701
1851
|
|
|
1702
1852
|
CREATE INDEX IF NOT EXISTS idx_cron_executions_name
|
|
1703
1853
|
ON cron_executions(cron_name, triggered_at);
|
|
1854
|
+
|
|
1855
|
+
-- Alarm entries table (durable timers, optionally recurring)
|
|
1856
|
+
CREATE TABLE IF NOT EXISTS alarm_entries (
|
|
1857
|
+
id TEXT NOT NULL,
|
|
1858
|
+
alarm_name TEXT NOT NULL,
|
|
1859
|
+
scheduled_time INTEGER NOT NULL,
|
|
1860
|
+
payload TEXT,
|
|
1861
|
+
interval_ms INTEGER,
|
|
1862
|
+
status TEXT DEFAULT 'pending',
|
|
1863
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now')),
|
|
1864
|
+
PRIMARY KEY (alarm_name, id)
|
|
1865
|
+
);
|
|
1866
|
+
|
|
1867
|
+
CREATE INDEX IF NOT EXISTS idx_alarm_entries_status_time
|
|
1868
|
+
ON alarm_entries(status, scheduled_time);
|
|
1869
|
+
|
|
1870
|
+
-- Alarm execution log
|
|
1871
|
+
CREATE TABLE IF NOT EXISTS alarm_executions (
|
|
1872
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1873
|
+
alarm_id TEXT NOT NULL,
|
|
1874
|
+
alarm_name TEXT NOT NULL,
|
|
1875
|
+
scheduled_time INTEGER NOT NULL,
|
|
1876
|
+
status TEXT DEFAULT 'pending',
|
|
1877
|
+
error TEXT,
|
|
1878
|
+
duration_ms INTEGER,
|
|
1879
|
+
created_at INTEGER DEFAULT (strftime('%s', 'now'))
|
|
1880
|
+
);
|
|
1881
|
+
|
|
1882
|
+
CREATE INDEX IF NOT EXISTS idx_alarm_executions_name
|
|
1883
|
+
ON alarm_executions(alarm_name, created_at);
|
|
1704
1884
|
`;
|
|
1705
1885
|
function initializeDatabases(projectDir) {
|
|
1706
1886
|
const dataDir = ensureDataDir(projectDir);
|