Skip to content

Commit 82de202

Browse files
committed
feat: allow resiliency with accepted extensions
1 parent 4f388fe commit 82de202

File tree

9 files changed

+118
-14
lines changed

9 files changed

+118
-14
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ coverage
77
locales/
88
package-lock.json
99
yarn.lock
10+
examples/**/dist
1011

1112
Thumbs.db
1213
tmp/
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import process from 'node:process';
2+
import * as path from 'node:path';
3+
import Bree from 'bree';
4+
5+
const bree = new Bree({
6+
/**
7+
* Always set the root option when doing any type of
8+
* compiling with bree. This just makes it clearer where
9+
* bree should resolve the jobs folder from. By default it
10+
* resolves to the jobs folder relative to where the program
11+
* is executed.
12+
*/
13+
root: path.join(__dirname, 'jobs'),
14+
/**
15+
* We only need the default extension to be "ts"
16+
* when we are running the app with ts-node - otherwise
17+
* the compiled-to-js code still needs to use JS
18+
*/
19+
defaultExtension: process.env.TS_NODE ? 'ts' : 'js',
20+
acceptedExtensions: ['.ts', '.js'],
21+
jobs: [
22+
{ cron: '* * * * *', name: 'job' },
23+
{ cron: '* * * * *', name: 'defaults' }
24+
]
25+
});
26+
27+
(async () => {
28+
await bree.start();
29+
})();
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { parentPort } from 'node:worker_threads';
2+
import process from 'node:process';
3+
4+
console.log('Hello TypeScript Defaults!');
5+
6+
// signal to parent that the job is done
7+
if (parentPort) parentPort.postMessage('done');
8+
// eslint-disable-next-line unicorn/no-process-exit
9+
else process.exit(0);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { parentPort } from 'node:worker_threads';
2+
import process from 'node:process';
3+
4+
console.log('Hello TypeScript!');
5+
6+
// signal to parent that the job is done
7+
if (parentPort) parentPort.postMessage('done');
8+
// eslint-disable-next-line unicorn/no-process-exit
9+
else process.exit(0);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "bree-js-example-jobserver",
3+
"version": "1.0.0",
4+
"description": "basic bree typescript jobserver example",
5+
"main": "index.ts",
6+
"author": "Mike Valstar <[email protected]> (https://valstar.dev/)",
7+
"license": "MIT",
8+
"devDependencies": {
9+
"@tsconfig/node20": "^20.1.2",
10+
"@types/node": "^20.8.0",
11+
"ts-node": "^10.9.1",
12+
"tslib": "^2.6.2",
13+
"typescript": "^5.2.2"
14+
},
15+
"scripts": {
16+
"dev": "TS_NODE=true NODE_OPTIONS=\"-r ts-node/register\" node index.ts",
17+
"start": "rm -rf dist && tsc && node dist/index.js"
18+
},
19+
"dependencies": {
20+
"bree": "latest"
21+
}
22+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"extends": "@tsconfig/node20/tsconfig.json",
3+
"include": ["**/*.ts", "jobs/index.js"],
4+
"compilerOptions": {
5+
"outDir": "dist",
6+
"moduleResolution": "NodeNext",
7+
"esModuleInterop": true
8+
}
9+
}

src/job-builder.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const isSANB = require('is-string-and-not-blank');
33
const isValidPath = require('is-valid-path');
44
const later = require('@breejs/later');
55
const { boolean } = require('boolean');
6-
const { isSchedule, parseValue } = require('./job-utils');
6+
const { isSchedule, parseValue, getJobPath } = require('./job-utils');
77

88
later.date.localTime();
99

@@ -12,9 +12,7 @@ const buildJob = (job, config) => {
1212
if (isSANB(job)) {
1313
const path = join(
1414
config.root,
15-
config.acceptedExtensions.some((ext) => job.endsWith(ext))
16-
? job
17-
: `${job}.${config.defaultExtension}`
15+
getJobPath(job, config.acceptedExtensions, config.defaultExtension)
1816
);
1917

2018
const jobObject = {
@@ -61,9 +59,11 @@ const buildJob = (job, config) => {
6159
? job.path
6260
: join(
6361
config.root,
64-
config.acceptedExtensions.some((ext) => job.name.endsWith(ext))
65-
? job.name
66-
: `${job.name}.${config.defaultExtension}`
62+
getJobPath(
63+
job.name,
64+
config.acceptedExtensions,
65+
config.defaultExtension
66+
)
6767
);
6868

6969
if (isValidPath(path)) {

src/job-utils.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,34 @@ const getJobNames = (jobs, excludeIndex) => {
9595
return names;
9696
};
9797

98+
/**
99+
* Processes job name to generate a partial path for the job
100+
* Allows for resiliancy when the path extensions are either
101+
* provided or not on both default and accepted extensions
102+
*
103+
* @param {string} name
104+
* @param {number} acceptedExtensions
105+
* @param {string} defaultExtension
106+
* @returns {string} job path
107+
*/
108+
const getJobPath = (name, acceptedExtensions, defaultExtension) => {
109+
const extFindArray = acceptedExtensions.map((ext) => {
110+
return ext.startsWith('.') ? ext : `.${ext}`;
111+
});
112+
113+
const hasExt = extFindArray.find((ext) => name.endsWith(ext));
114+
115+
if (hasExt) return name;
116+
117+
return defaultExtension.startsWith('.')
118+
? `${name}${defaultExtension}`
119+
: `${name}.${defaultExtension}`;
120+
};
121+
98122
module.exports = {
99123
getHumanToMs,
100124
getJobNames,
125+
getJobPath,
101126
getName,
102127
isSchedule,
103128
parseValue

src/job-validator.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const cron = require('cron-validate');
55
const isSANB = require('is-string-and-not-blank');
66
const isValidPath = require('is-valid-path');
77

8-
const { getName, isSchedule, parseValue } = require('./job-utils');
8+
const { getName, isSchedule, parseValue, getJobPath } = require('./job-utils');
99

1010
const validateReservedJobName = (name) => {
1111
// Don't allow a job to have the `index` file name
@@ -37,9 +37,7 @@ const validateStringJob = async (job, i, config) => {
3737

3838
const path = join(
3939
config.root,
40-
config.acceptedExtensions.some((ext) => job.endsWith(ext))
41-
? job
42-
: `${job}.${config.defaultExtension}`
40+
getJobPath(job, config.acceptedExtensions, config.defaultExtension)
4341
);
4442

4543
const stats = await fs.promises.stat(path);
@@ -86,9 +84,11 @@ const validateJobPath = async (job, prefix, config) => {
8684
? job.path
8785
: join(
8886
config.root,
89-
config.acceptedExtensions.some((ext) => job.name.endsWith(ext))
90-
? job.name
91-
: `${job.name}.${config.defaultExtension}`
87+
getJobPath(
88+
job.name,
89+
config.acceptedExtensions,
90+
config.defaultExtension
91+
)
9292
);
9393
if (isValidPath(path)) {
9494
try {

0 commit comments

Comments
 (0)