-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
293 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@datatruck/cli": minor | ||
--- | ||
|
||
Add cron server |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import { BackupCommandOptions } from "../../Command/BackupCommand"; | ||
import { CopyCommandOptionsType } from "../../Command/CopyCommand"; | ||
import { CommandConstructorFactory } from "../../Factory/CommandFactory"; | ||
import { stringifyOptions } from "../cli"; | ||
import { exec } from "../process"; | ||
import { Cron } from "croner"; | ||
|
||
export type CronAction = | ||
| { | ||
schedule: string; | ||
name: "backup"; | ||
options: BackupCommandOptions; | ||
} | ||
| { | ||
schedule: string; | ||
name: "copy"; | ||
options: CopyCommandOptionsType; | ||
}; | ||
|
||
export type DatatruckCronServerOptions = { | ||
enabled?: boolean; | ||
actions?: CronAction[]; | ||
}; | ||
|
||
function createJobs( | ||
actions: CronAction[], | ||
currentJobs: Cron[] = [], | ||
worker: (action: CronAction, index: number) => Promise<void>, | ||
) { | ||
const jobs: Cron[] = []; | ||
for (const action of actions) { | ||
const index = actions.indexOf(action); | ||
const context = JSON.stringify({ | ||
index: actions.indexOf(action), | ||
data: action, | ||
}); | ||
const job = currentJobs.at(index); | ||
if (!job || job.options.context !== context) { | ||
job?.stop(); | ||
jobs.push( | ||
Cron( | ||
action.schedule, | ||
{ | ||
paused: true, | ||
context: JSON.stringify(action), | ||
catch: true, | ||
protect: true, | ||
}, | ||
() => worker(action, index), | ||
), | ||
); | ||
} | ||
} | ||
return jobs; | ||
} | ||
|
||
export function createCronServer( | ||
options: DatatruckCronServerOptions, | ||
config: { | ||
log: boolean; | ||
verbose: boolean; | ||
configPath: string; | ||
}, | ||
) { | ||
const worker = async (action: CronAction, index: number) => { | ||
if (config.log) console.info(`> [job] ${index} - ${action.name}`); | ||
try { | ||
const Command = CommandConstructorFactory(action.name as any); | ||
const command = new Command( | ||
{ config: { packages: [], repositories: [] } }, | ||
{}, | ||
); | ||
const cliOptions = stringifyOptions(command.onOptions(), action.options); | ||
const [node, bin] = process.argv; | ||
await exec( | ||
node, | ||
[bin, "-c", config.configPath, action.name, ...cliOptions], | ||
{}, | ||
{ log: config.verbose }, | ||
); | ||
if (config.log) console.info(`< [job] ${index} - ${action.name}`); | ||
} catch (error) { | ||
if (config.log) console.error(`< [job] ${index} - ${action.name}`, error); | ||
} | ||
}; | ||
|
||
const jobs = createJobs(options.actions || [], [], worker); | ||
|
||
return { | ||
start: () => { | ||
for (const job of jobs) job.resume(); | ||
}, | ||
stop: () => { | ||
for (const job of jobs) job.stop(); | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { omitProp } from "./object"; | ||
import { JSONSchema7 } from "json-schema"; | ||
|
||
export function omitPropertySchema< | ||
T extends { properties: Record<string, any> }, | ||
N extends keyof T["properties"], | ||
>( | ||
object: T, | ||
name: N, | ||
): Omit<T, "properties"> & { properties: Omit<T["properties"], N> } { | ||
return { | ||
...object, | ||
properties: omitProp(object.properties, name as any), | ||
}; | ||
} | ||
|
||
type IfSchema< | ||
KType extends string, | ||
KValue extends string, | ||
T extends string, | ||
V extends JSONSchema7, | ||
> = { | ||
if: { | ||
type: "object"; | ||
properties: { | ||
[k in KType]: { const: T }; | ||
}; | ||
}; | ||
then: { | ||
type: "object"; | ||
properties: { | ||
[k in KValue]: V; | ||
}; | ||
}; | ||
else: false; | ||
}; | ||
|
||
export function createCaseSchema< | ||
KType extends string, | ||
KValue extends string, | ||
V extends { [K in KType]: JSONSchema7 }, | ||
>( | ||
keys: { type: KType; value: KValue }, | ||
value: V, | ||
): IfSchema<KType, KValue, string, JSONSchema7>[] { | ||
return Object.entries(value).reduce( | ||
(schemas, [type, value]) => { | ||
schemas.push(createIfSchema(keys, type, value as JSONSchema7)); | ||
return schemas; | ||
}, | ||
[] as IfSchema<KType, KValue, string, JSONSchema7>[], | ||
); | ||
} | ||
|
||
export function createIfSchema< | ||
KType extends string, | ||
KValue extends string, | ||
T extends string, | ||
V extends JSONSchema7, | ||
>( | ||
keys: { type: KType; value: KValue }, | ||
type: T, | ||
value: V, | ||
): IfSchema<KType, KValue, T, V> { | ||
return { | ||
if: { | ||
type: "object", | ||
properties: { | ||
[keys.type]: { const: type }, | ||
} as any, | ||
}, | ||
then: { | ||
type: "object", | ||
properties: { | ||
[keys.value]: value, | ||
} as any, | ||
}, | ||
else: false, | ||
}; | ||
} |
Oops, something went wrong.