Socket
Socket
Sign inDemoInstall

@ariya/berkala

Package Overview
Dependencies
45
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.1.9 to 1.2.0

tests/cli.bats

166

index.js
#!/usr/bin/env node
const fs = require('fs');
const os = require('os');
const child_process = require('child_process');

@@ -9,2 +11,4 @@ const manifest = require('./package.json');

const Bree = require('bree');
const which = require('which');
const say = require('say');

@@ -18,22 +22,23 @@ const CONFIG_FILENAME = 'berkala.yml';

boot:
type: notify
message: Berkala starts now
steps:
- notify: Berkala starts now
# We need to stay hydrated
hourly-ping:
type: print
stay-hydrated:
interval: every 1 hour
message: Drink some water!
steps:
- notify: Drink some water! # TODO: how much?
- print: Reminder was sent
lunch-reminder:
type: notify
lunch:
interval: at 11:58am
title: Important reminder
message: It's lunch time very soon
steps:
- notify: It's lunch time very soon
title: Important
- say: Get ready for lunch
weekend-exercise:
type: notify
cron: 0 9 * * 6 # every 9 morning on Saturday
title: Stay healthy
message: Time for some exercises!
steps:
- notify: Time for some exercises!
title: Stay healthy
`;

@@ -78,29 +83,7 @@

/**
* A simple job to print a message via console.
*/
function printJob() {
const { workerData } = require('worker_threads');
const { job } = workerData;
const { message } = job;
console.log(message);
}
/**
* A job that sends desktop notification.
*/
function notifyJob() {
const os = require('os');
const child_process = require('child_process');
const { workerData } = require('worker_threads');
const { job } = workerData;
const { message } = job;
let { title } = job;
if (!title) {
title = 'Berkala';
}
function platformNotify(title, message) {
if (os.type() === 'Linux') {
child_process.spawnSync('notify-send', ['-a', 'Berkala', title, message]);
} else if (os.type() === 'Darwin') {
const command = `display notification "${message}" with title "${title}"`;
const command = `display notification "${message}" with title "Berkala" subtitle "${title}"`;
child_process.spawnSync('osascript', ['-e', command]);

@@ -143,10 +126,61 @@ } else if (os.type() === 'Windows_NT') {

function platformSay(message) {
if (os.type() === 'Linux') {
const resolved = which.sync('festival', { nothrow: true });
if (resolved) {
say.speak(message);
} else {
console.error('say: unable to locate Festival');
platformNotify(message);
}
} else if (os.type() === 'Windows_NT') {
// TODO: check for Powershell first
say.speak(message);
} else if (os.type() === 'Darwin') {
say.speak(message, 'Samantha'); // Siri's voice
} else {
// unsupported
console.error('say: unsupport system', os.type());
platformNotify(message);
}
}
function workerMessageHandler(workerData) {
const workerMsg = workerData.message;
const { duty } = workerMsg;
if (duty === 'print') {
const { message } = workerMsg;
console.log(message);
} else if (duty === 'notify') {
const { title, message } = workerMsg;
platformNotify(title, message);
} else if (duty === 'say') {
const { message } = workerMsg;
platformSay(message);
}
}
/**
* A job that dumps the worker data, useful for debugging.
* Run a task, execute the steps sequentially.
*/
function debugJob() {
const { workerData } = require('worker_threads');
function runTask() {
const { workerData, parentPort } = require('worker_threads');
const { job } = workerData;
const { steps } = job;
console.log('debug job=', JSON.stringify(job));
steps.forEach((step) => {
if (step.print) {
parentPort.postMessage({ duty: 'print', message: step.print });
} else if (step.notify) {
const title = step.title ? step.title : 'Berkala';
const message = step.notify.trim();
parentPort.postMessage({ duty: 'notify', title, message });
} else if (step.say) {
parentPort.postMessage({ duty: 'say', message: step.say });
} else {
console.error('Unknown step', step);
}
});
}

@@ -158,33 +192,19 @@

function convert(name, task) {
const { type, interval, cron } = task;
const { interval, cron } = task;
let { steps } = task;
let path;
let options = {};
const { message = null } = task;
switch (type) {
case 'debug':
path = debugJob;
options = task;
break;
case 'print':
path = printJob;
options = { message };
break;
case 'notify':
path = notifyJob;
const { title = null } = task;
options = { title, message };
break;
default:
break;
if (!steps || !Array.isArray(steps) || steps.length === 0) {
// Migrate legacy task format
steps = [];
const { type } = task;
if (type === 'print') {
const { message } = task;
steps.push({ print: message });
} else if (type === 'notify') {
const { message, title } = task;
steps.push({ notify: message, title });
}
}
if (!path) {
throw new Error('Unknown task type: ' + type);
}
const path = runTask;
return {

@@ -195,3 +215,3 @@ name,

cron,
...options
steps
};

@@ -204,3 +224,3 @@ }

function setupTasks(config) {
const { tasks } = config;
const { tasks = [] } = config;
const jobs = Object.keys(tasks).map((name) => {

@@ -210,3 +230,3 @@ return convert(name, tasks[name]);

const root = false;
return new Bree({ root, jobs });
return new Bree({ root, jobs, workerMessageHandler });
}

@@ -217,4 +237,4 @@

const config = getConfig();
const config = getConfig() || {};
const tasks = setupTasks(config);
tasks.start();
{
"name": "@ariya/berkala",
"version": "1.1.9",
"version": "1.2.0",
"description": "Run scheduled tasks",

@@ -14,2 +14,3 @@ "main": "index.js",

"format-code": "prettier --write \"**/*.js\"",
"cli-tests": "npx bats tests/cli.bats",
"build": "pkg --compress brotli ."

@@ -35,5 +36,10 @@ },

"js-yaml": "~4.1.0",
"readline-sync": "~1.4.10"
"readline-sync": "~1.4.10",
"say": "~0.16.0",
"which": "~2.0.2"
},
"devDependencies": {
"bats": "~1.4.1",
"bats-assert": "~2.0.0",
"bats-support": "~0.3.0",
"pkg": "~5.3.1",

@@ -40,0 +46,0 @@ "prettier": "~2.3.2"

@@ -18,33 +18,60 @@ # Berkala

boot:
type: notify
message: Berkala starts now
steps:
- notify: Berkala starts now
# We need to stay hydrated
hourly-ping:
type: print
stay-hydrated:
interval: every 1 hour
message: Drink some water!
steps:
- notify: Drink some water! # TODO: how much?
- print: Reminder was sent
lunch-reminder:
type: notify
lunch:
interval: at 11:58am
title: Important reminder
message: It's lunch time very soon
steps:
- notify: It's lunch time very soon
title: Important
- say: Get ready for lunch
weekend-exercise:
type: notify
cron: 0 9 * * 6 # every 9 morning on Saturday
title: Stay healthy
message: Time for some exercises!
steps:
- notify: Time for some exercises!
title: Stay healthy
```
Just like any regular YAML, everything from the `#` character until the end of the line will be ignored. Use this to insert comments.
The schedule for each task can be specified either with a human-friendly interval (e.g. `every 5 minutes`, `at 5pm`) or a cron expression (refer to [crontab guru](https://crontab.guru/) for more details). If neither is explicitly stated, then the task runs right away.
The schedule for each task can be specified as:
* [a human-friendly interval](https://breejs.github.io/later/parsers.html#text), e.g. `every 5 minutes`, `at 5pm`, or
* [a cron expression](https://crontab.guru/), e.g. `0 9 * * 6`
As of now, only the following types of tasks are available:
If neither is explicitly stated, then the task runs right away.
* `print`: displays a message to the standard output
* `notify`: sends a desktop notification
Each task consists of one or more steps.
Just like any regular YAML, everything from the `#` character until the end of the line will be ignored. Use this to insert comments.
Every step must be one of the following:
<details><summary><code>print</code>: displays a message to the standard output</summary></details>
<details><summary><code>notify</code>: sends a desktop notification</summary>
The notification is supported on the following system:
* Windows: [Windows.UI.Notifications](https://docs.microsoft.com/en-us/uwp/api/windows.ui.notifications.toastnotification) via [Powershell scripting](https://docs.microsoft.com/en-us/powershell/scripting)
* macOS: `display notification` with [AppleScript](https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_cmds.html)
* Linux: [notify-send](https://www.commandlinux.com/man-page/man1/notify-send.1.html), e.g. part of `libnotify-bin` package on Debian/Ubuntu
</details>
<details><summary><code>say</code>: converts text to audible speech</summary>
The text-to-speech conversion is supported on the following system:
* Windows: [System.Speech.Synthesis](https://docs.microsoft.com/en-us/dotnet/api/system.speech.synthesis) via [Powershell scripting](https://docs.microsoft.com/en-us/powershell/scripting)
* macOS: `say` with [AppleScript](https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_cmds.html)
* Linux: [Festival speech synthesis](https://www.cstr.ed.ac.uk/projects/festival/), e.g. `festival` and `festvox-kallpc16k` on Debian/Ubuntu
</details>
Found a problem or have a new idea? File [an issue](https://github.com/ariya/berkala/issues)!
<details>

@@ -51,0 +78,0 @@ <summary>Alternative way to run Berkala (with Node.js)</summary>

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc