@1medium/cli 1.8.0 → 1.9.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/package.json +1 -1
- package/src/api.js +96 -0
- package/src/index.js +261 -0
package/package.json
CHANGED
package/src/api.js
CHANGED
|
@@ -208,6 +208,91 @@ async function deleteProject(id) {
|
|
|
208
208
|
return request("DELETE", `/projects/${id}`);
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
+
// ============================================================================
|
|
212
|
+
// Script API
|
|
213
|
+
// ============================================================================
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* List scripts
|
|
217
|
+
*/
|
|
218
|
+
async function listScripts(params = {}) {
|
|
219
|
+
return request("GET", "/scripts", null, params);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Get a single script
|
|
224
|
+
*/
|
|
225
|
+
async function getScript(id) {
|
|
226
|
+
return request("GET", `/scripts/${id}`);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Push (create/update) a script
|
|
231
|
+
*/
|
|
232
|
+
async function pushScript(payload) {
|
|
233
|
+
return request("POST", "/scripts/push", payload);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Deprecate a script
|
|
238
|
+
*/
|
|
239
|
+
async function deprecateScript(id) {
|
|
240
|
+
return request("POST", `/scripts/${id}/deprecate`);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// ============================================================================
|
|
244
|
+
// Script Event API
|
|
245
|
+
// ============================================================================
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* List script events
|
|
249
|
+
*/
|
|
250
|
+
async function listScriptEvents(params = {}) {
|
|
251
|
+
return request("GET", "/script-events", null, params);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Get a single script event
|
|
256
|
+
*/
|
|
257
|
+
async function getScriptEvent(id) {
|
|
258
|
+
return request("GET", `/script-events/${id}`);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Create a script event
|
|
263
|
+
*/
|
|
264
|
+
async function createScriptEvent(payload) {
|
|
265
|
+
return request("POST", "/script-events", payload);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Update a script event
|
|
270
|
+
*/
|
|
271
|
+
async function updateScriptEvent(id, payload) {
|
|
272
|
+
return request("PUT", `/script-events/${id}`, payload);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Delete a script event
|
|
277
|
+
*/
|
|
278
|
+
async function deleteScriptEvent(id) {
|
|
279
|
+
return request("DELETE", `/script-events/${id}`);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Pause a script event
|
|
284
|
+
*/
|
|
285
|
+
async function pauseScriptEvent(id) {
|
|
286
|
+
return request("POST", `/script-events/${id}/pause`);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Resume a script event
|
|
291
|
+
*/
|
|
292
|
+
async function resumeScriptEvent(id) {
|
|
293
|
+
return request("POST", `/script-events/${id}/resume`);
|
|
294
|
+
}
|
|
295
|
+
|
|
211
296
|
module.exports = {
|
|
212
297
|
whoami,
|
|
213
298
|
createTask,
|
|
@@ -226,4 +311,15 @@ module.exports = {
|
|
|
226
311
|
createProject,
|
|
227
312
|
updateProject,
|
|
228
313
|
deleteProject,
|
|
314
|
+
listScripts,
|
|
315
|
+
getScript,
|
|
316
|
+
pushScript,
|
|
317
|
+
deprecateScript,
|
|
318
|
+
listScriptEvents,
|
|
319
|
+
getScriptEvent,
|
|
320
|
+
createScriptEvent,
|
|
321
|
+
updateScriptEvent,
|
|
322
|
+
deleteScriptEvent,
|
|
323
|
+
pauseScriptEvent,
|
|
324
|
+
resumeScriptEvent,
|
|
229
325
|
};
|
package/src/index.js
CHANGED
|
@@ -714,6 +714,267 @@ program
|
|
|
714
714
|
}
|
|
715
715
|
});
|
|
716
716
|
|
|
717
|
+
// ============================================================================
|
|
718
|
+
// Script Commands
|
|
719
|
+
// ============================================================================
|
|
720
|
+
|
|
721
|
+
const scriptCmd = program.command("script").description("Manage scripts");
|
|
722
|
+
|
|
723
|
+
scriptCmd
|
|
724
|
+
.command("push <file>")
|
|
725
|
+
.description("Push a script from a local file")
|
|
726
|
+
.option("-n, --name <name>", "Script name (defaults to filename)")
|
|
727
|
+
.option("--trigger <trigger>", "Trigger type: onCreate, onUpdate, onTag, schedule", "schedule")
|
|
728
|
+
.option("-j, --json", "Output as JSON")
|
|
729
|
+
.action(async (file, options) => {
|
|
730
|
+
try {
|
|
731
|
+
const fs = require("fs");
|
|
732
|
+
const path = require("path");
|
|
733
|
+
|
|
734
|
+
if (!fs.existsSync(file)) {
|
|
735
|
+
console.error(chalk.red(`Error: File not found: ${file}`));
|
|
736
|
+
process.exit(1);
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
const code = fs.readFileSync(file, "utf-8");
|
|
740
|
+
const name = options.name || path.basename(file, path.extname(file));
|
|
741
|
+
|
|
742
|
+
// Extract metadata from header comments
|
|
743
|
+
const metadata = {};
|
|
744
|
+
const metaRegex = /\/\/\s*@(\w+)\s+(.*)/g;
|
|
745
|
+
let match;
|
|
746
|
+
while ((match = metaRegex.exec(code)) !== null) {
|
|
747
|
+
metadata[match[1]] = match[2].trim();
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
const payload = {
|
|
751
|
+
name,
|
|
752
|
+
code,
|
|
753
|
+
trigger: metadata.trigger || options.trigger,
|
|
754
|
+
};
|
|
755
|
+
|
|
756
|
+
const data = await api.pushScript(payload);
|
|
757
|
+
|
|
758
|
+
if (options.json) {
|
|
759
|
+
console.log(JSON.stringify(data, null, 2));
|
|
760
|
+
} else {
|
|
761
|
+
console.log(chalk.green("Script pushed:"));
|
|
762
|
+
console.log(` ID: ${data.script?.id || data.id}`);
|
|
763
|
+
console.log(` Name: ${name}`);
|
|
764
|
+
console.log(` Version: ${data.script?.version || data.version || 1}`);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
// Auto-create schedule if metadata includes startDateTime
|
|
768
|
+
if (metadata.startDateTime) {
|
|
769
|
+
const eventPayload = {
|
|
770
|
+
ScriptId: data.script?.id || data.id,
|
|
771
|
+
title: metadata.title || name,
|
|
772
|
+
startDateTime: metadata.startDateTime,
|
|
773
|
+
timezone: metadata.tz || metadata.timezone || "UTC",
|
|
774
|
+
};
|
|
775
|
+
if (metadata.rrule) eventPayload.rrule = metadata.rrule;
|
|
776
|
+
if (metadata.endDateTime) eventPayload.endDateTime = metadata.endDateTime;
|
|
777
|
+
|
|
778
|
+
const eventData = await api.createScriptEvent(eventPayload);
|
|
779
|
+
console.log(chalk.green("\nSchedule created:"));
|
|
780
|
+
console.log(` Event ID: ${eventData.scriptEvent?.id || eventData.id}`);
|
|
781
|
+
console.log(` Starts: ${eventPayload.startDateTime}`);
|
|
782
|
+
if (eventPayload.rrule) {
|
|
783
|
+
console.log(` Recurs: ${eventPayload.rrule}`);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
} catch (error) {
|
|
787
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
788
|
+
if (error.details) {
|
|
789
|
+
error.details.forEach((d) => console.error(chalk.red(` - ${d}`)));
|
|
790
|
+
}
|
|
791
|
+
process.exit(1);
|
|
792
|
+
}
|
|
793
|
+
});
|
|
794
|
+
|
|
795
|
+
scriptCmd
|
|
796
|
+
.command("list")
|
|
797
|
+
.description("List your scripts")
|
|
798
|
+
.option("-j, --json", "Output as JSON")
|
|
799
|
+
.action(async (options) => {
|
|
800
|
+
try {
|
|
801
|
+
const data = await api.listScripts();
|
|
802
|
+
const scripts = data.scripts || data;
|
|
803
|
+
|
|
804
|
+
if (options.json) {
|
|
805
|
+
console.log(JSON.stringify(data, null, 2));
|
|
806
|
+
} else {
|
|
807
|
+
console.log(chalk.bold("\nScripts:\n"));
|
|
808
|
+
if (!scripts.length) {
|
|
809
|
+
console.log(" No scripts found.");
|
|
810
|
+
} else {
|
|
811
|
+
for (const script of scripts) {
|
|
812
|
+
const statusColor = script.status === "active" ? chalk.green : chalk.gray;
|
|
813
|
+
console.log(` ${statusColor(script.status)} ${script.name} (v${script.version || 1})`);
|
|
814
|
+
console.log(chalk.gray(` ID: ${script.id} Trigger: ${script.trigger}`));
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
console.log("");
|
|
818
|
+
}
|
|
819
|
+
} catch (error) {
|
|
820
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
821
|
+
process.exit(1);
|
|
822
|
+
}
|
|
823
|
+
});
|
|
824
|
+
|
|
825
|
+
scriptCmd
|
|
826
|
+
.command("delete <id>")
|
|
827
|
+
.description("Deprecate a script (soft delete)")
|
|
828
|
+
.option("-j, --json", "Output as JSON")
|
|
829
|
+
.action(async (id, options) => {
|
|
830
|
+
try {
|
|
831
|
+
const data = await api.deprecateScript(id);
|
|
832
|
+
|
|
833
|
+
if (options.json) {
|
|
834
|
+
console.log(JSON.stringify(data, null, 2));
|
|
835
|
+
} else {
|
|
836
|
+
console.log(chalk.green(`Script deprecated: ${id}`));
|
|
837
|
+
}
|
|
838
|
+
} catch (error) {
|
|
839
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
840
|
+
process.exit(1);
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
|
|
844
|
+
scriptCmd
|
|
845
|
+
.command("schedule <script-id>")
|
|
846
|
+
.description("Schedule a script as a calendar event")
|
|
847
|
+
.requiredOption("--start <datetime>", "Start date/time (ISO 8601)")
|
|
848
|
+
.option("--end <datetime>", "End date/time (ISO 8601)")
|
|
849
|
+
.option("--rrule <rrule>", "Recurrence rule (RFC 5545 RRULE)")
|
|
850
|
+
.option("--tz <timezone>", "Timezone (e.g., America/New_York)", "UTC")
|
|
851
|
+
.option("-t, --title <title>", "Event title")
|
|
852
|
+
.option("-j, --json", "Output as JSON")
|
|
853
|
+
.action(async (scriptId, options) => {
|
|
854
|
+
try {
|
|
855
|
+
const payload = {
|
|
856
|
+
ScriptId: scriptId,
|
|
857
|
+
title: options.title || `Script ${scriptId}`,
|
|
858
|
+
startDateTime: options.start,
|
|
859
|
+
timezone: options.tz,
|
|
860
|
+
};
|
|
861
|
+
if (options.end) payload.endDateTime = options.end;
|
|
862
|
+
if (options.rrule) payload.rrule = options.rrule;
|
|
863
|
+
|
|
864
|
+
const data = await api.createScriptEvent(payload);
|
|
865
|
+
const event = data.scriptEvent || data;
|
|
866
|
+
|
|
867
|
+
if (options.json) {
|
|
868
|
+
console.log(JSON.stringify(data, null, 2));
|
|
869
|
+
} else {
|
|
870
|
+
console.log(chalk.green("Script scheduled:"));
|
|
871
|
+
console.log(` Event ID: ${event.id}`);
|
|
872
|
+
console.log(` Title: ${event.title}`);
|
|
873
|
+
console.log(` Starts: ${event.startDateTime}`);
|
|
874
|
+
console.log(` Timezone: ${event.timezone}`);
|
|
875
|
+
if (event.rrule) {
|
|
876
|
+
console.log(` Recurs: ${event.rrule}`);
|
|
877
|
+
}
|
|
878
|
+
if (event.nextRunAt) {
|
|
879
|
+
console.log(` Next run: ${event.nextRunAt}`);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
} catch (error) {
|
|
883
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
884
|
+
if (error.details) {
|
|
885
|
+
error.details.forEach((d) => console.error(chalk.red(` - ${d}`)));
|
|
886
|
+
}
|
|
887
|
+
process.exit(1);
|
|
888
|
+
}
|
|
889
|
+
});
|
|
890
|
+
|
|
891
|
+
scriptCmd
|
|
892
|
+
.command("events")
|
|
893
|
+
.description("List scheduled script events")
|
|
894
|
+
.option("--start <date>", "Filter by start date (ISO 8601)")
|
|
895
|
+
.option("--end <date>", "Filter by end date (ISO 8601)")
|
|
896
|
+
.option("-j, --json", "Output as JSON")
|
|
897
|
+
.action(async (options) => {
|
|
898
|
+
try {
|
|
899
|
+
const params = {};
|
|
900
|
+
if (options.start) params.start = options.start;
|
|
901
|
+
if (options.end) params.end = options.end;
|
|
902
|
+
|
|
903
|
+
const data = await api.listScriptEvents(params);
|
|
904
|
+
const events = data.scriptEvents || data;
|
|
905
|
+
|
|
906
|
+
if (options.json) {
|
|
907
|
+
console.log(JSON.stringify(data, null, 2));
|
|
908
|
+
} else {
|
|
909
|
+
console.log(chalk.bold("\nScheduled Script Events:\n"));
|
|
910
|
+
if (!events.length) {
|
|
911
|
+
console.log(" No scheduled events found.");
|
|
912
|
+
} else {
|
|
913
|
+
for (const event of events) {
|
|
914
|
+
const statusColor =
|
|
915
|
+
event.status === "active" ? chalk.green :
|
|
916
|
+
event.status === "paused" ? chalk.yellow :
|
|
917
|
+
chalk.gray;
|
|
918
|
+
console.log(` ${statusColor(event.status)} ${event.title}`);
|
|
919
|
+
console.log(chalk.gray(` ID: ${event.id}`));
|
|
920
|
+
console.log(chalk.gray(` Start: ${event.startDateTime} TZ: ${event.timezone}`));
|
|
921
|
+
if (event.rrule) {
|
|
922
|
+
console.log(chalk.gray(` Recurs: ${event.rrule}`));
|
|
923
|
+
}
|
|
924
|
+
if (event.nextRunAt) {
|
|
925
|
+
console.log(chalk.gray(` Next run: ${event.nextRunAt}`));
|
|
926
|
+
}
|
|
927
|
+
if (event.Script) {
|
|
928
|
+
console.log(chalk.gray(` Script: ${event.Script.name} (${event.Script.id})`));
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
console.log("");
|
|
933
|
+
}
|
|
934
|
+
} catch (error) {
|
|
935
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
936
|
+
process.exit(1);
|
|
937
|
+
}
|
|
938
|
+
});
|
|
939
|
+
|
|
940
|
+
scriptCmd
|
|
941
|
+
.command("pause <event-id>")
|
|
942
|
+
.description("Pause a scheduled script event")
|
|
943
|
+
.option("-j, --json", "Output as JSON")
|
|
944
|
+
.action(async (eventId, options) => {
|
|
945
|
+
try {
|
|
946
|
+
const data = await api.pauseScriptEvent(eventId);
|
|
947
|
+
|
|
948
|
+
if (options.json) {
|
|
949
|
+
console.log(JSON.stringify(data, null, 2));
|
|
950
|
+
} else {
|
|
951
|
+
console.log(chalk.green(`Script event paused: ${eventId}`));
|
|
952
|
+
}
|
|
953
|
+
} catch (error) {
|
|
954
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
955
|
+
process.exit(1);
|
|
956
|
+
}
|
|
957
|
+
});
|
|
958
|
+
|
|
959
|
+
scriptCmd
|
|
960
|
+
.command("resume <event-id>")
|
|
961
|
+
.description("Resume a paused script event")
|
|
962
|
+
.option("-j, --json", "Output as JSON")
|
|
963
|
+
.action(async (eventId, options) => {
|
|
964
|
+
try {
|
|
965
|
+
const data = await api.resumeScriptEvent(eventId);
|
|
966
|
+
|
|
967
|
+
if (options.json) {
|
|
968
|
+
console.log(JSON.stringify(data, null, 2));
|
|
969
|
+
} else {
|
|
970
|
+
console.log(chalk.green(`Script event resumed: ${eventId}`));
|
|
971
|
+
}
|
|
972
|
+
} catch (error) {
|
|
973
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
974
|
+
process.exit(1);
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
|
|
717
978
|
// ============================================================================
|
|
718
979
|
// Config Commands
|
|
719
980
|
// ============================================================================
|