@zenweb/schedule 3.1.0 → 3.3.0

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/index.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import { SetupFunction } from '@zenweb/core';
2
- import { schedule } from './register';
2
+ import { schedule, ScheduleRegister } from './register';
3
3
  import { ScheduleOption } from './types';
4
4
  export { ScheduleOption, schedule };
5
5
  export default function setup(option?: ScheduleOption): SetupFunction;
6
+ declare module '@zenweb/core' {
7
+ interface Core {
8
+ schedule: ScheduleRegister;
9
+ }
10
+ }
package/dist/index.js CHANGED
@@ -8,25 +8,33 @@ Object.defineProperty(exports, "schedule", { enumerable: true, get: function ()
8
8
  function setup(option) {
9
9
  option = Object.assign({
10
10
  paths: [path.join(process.cwd(), 'app', 'schedule')],
11
+ disabled: process.env.ZENWEB_SCHEDULE_DISABLED === '1',
11
12
  }, option);
12
13
  return async function schedule(setup) {
13
14
  setup.checkCoreProperty('injector', '@zenweb/inject');
14
15
  setup.checkCoreProperty('router', '@zenweb/router');
15
16
  setup.checkCoreProperty('log', '@zenweb/log');
16
17
  setup.debug('option: %o', option);
17
- setup.defineCoreProperty('schedule', { value: true });
18
+ const schedule = new register_1.ScheduleRegister(setup.core, option);
19
+ setup.defineCoreProperty('schedule', { value: schedule });
18
20
  if (option.paths && option.paths.length) {
19
21
  for (const d of option.paths) {
20
22
  for (const file of await globby(option.patterns || '**/*.{ts,js}', { cwd: d, absolute: true })) {
21
23
  const mod = require(file.slice(0, -3));
22
24
  for (const i of Object.values(mod)) {
23
25
  if (typeof i === 'function') {
24
- (0, register_1.registerSchedule)(setup.core, i);
26
+ schedule.register(i);
25
27
  }
26
28
  }
27
29
  }
28
30
  }
29
31
  }
32
+ setup.after(() => {
33
+ schedule.addToCoreRouter();
34
+ });
35
+ setup.destroy(() => {
36
+ schedule.destory();
37
+ });
30
38
  };
31
39
  }
32
40
  exports.default = setup;
@@ -1,32 +1,28 @@
1
1
  import '@zenweb/inject';
2
2
  import '@zenweb/router';
3
3
  import '@zenweb/log';
4
- import { Middleware } from 'koa';
5
- import { Core } from '@zenweb/core';
4
+ import { Core, Middleware } from '@zenweb/core';
6
5
  import { RecurrenceRule, RecurrenceSpecDateRange, RecurrenceSpecObjLit } from 'node-schedule';
6
+ import { ScheduleOption } from './types';
7
7
  interface ScheduleMethodOption {
8
8
  rule: RecurrenceRule | RecurrenceSpecDateRange | RecurrenceSpecObjLit | Date | string | number;
9
9
  middleware?: Middleware | Middleware[];
10
10
  }
11
- interface JobItem extends ScheduleMethodOption {
12
- path: string;
13
- handle: (...args: any[]) => Promise<void> | void;
14
- params: any[];
15
- }
16
- /**
17
- * 取得对象中的任务列表
18
- */
19
- export declare function getJobs(target: any): JobItem[];
20
- /**
21
- * 在对象中添加任务配置
22
- */
23
- export declare function addJob(target: any, item: JobItem): void;
24
11
  /**
25
12
  * 定时任务设定
26
13
  */
27
- export declare function schedule(opt: ScheduleMethodOption): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
28
- /**
29
- * 添加定时任务到路由并启动定时器
30
- */
31
- export declare function registerSchedule(core: Core, target: any): void;
14
+ export declare function schedule(opt: ScheduleMethodOption): (target: Object, propertyKey: string | symbol, descriptor_or_paramtypes?: any[] | PropertyDescriptor) => void;
15
+ export declare class ScheduleRegister {
16
+ private core;
17
+ private router;
18
+ private option;
19
+ private jobs;
20
+ constructor(core: Core, option: ScheduleOption);
21
+ /**
22
+ * 添加定时任务到路由并启动定时器
23
+ */
24
+ register(target: any): void;
25
+ addToCoreRouter(): void;
26
+ destory(): void;
27
+ }
32
28
  export {};
package/dist/register.js CHANGED
@@ -1,14 +1,16 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.registerSchedule = exports.schedule = exports.addJob = exports.getJobs = void 0;
3
+ exports.ScheduleRegister = exports.schedule = void 0;
4
4
  require("@zenweb/inject");
5
5
  require("@zenweb/router");
6
6
  require("@zenweb/log");
7
7
  const http_1 = require("http");
8
8
  const node_schedule_1 = require("node-schedule");
9
9
  const crypto_1 = require("crypto");
10
+ const decorator_make_1 = require("decorator-make");
11
+ const router_1 = require("@zenweb/router");
12
+ const inject_1 = require("@zenweb/inject");
10
13
  const SAFE_IP = '127.0.0.1';
11
- const JOBS = Symbol('Schedule#jobs');
12
14
  /**
13
15
  * 安全检查,防止外部调用
14
16
  */
@@ -28,73 +30,78 @@ async function safeCheck(ctx, next) {
28
30
  ctx.log.info('end', Date.now() - startTime, 'ms');
29
31
  }
30
32
  }
31
- /**
32
- * 取得对象中的任务列表
33
- */
34
- function getJobs(target) {
35
- return Reflect.getMetadata(JOBS, target) || [];
36
- }
37
- exports.getJobs = getJobs;
38
- /**
39
- * 在对象中添加任务配置
40
- */
41
- function addJob(target, item) {
42
- const list = [...getJobs(target), item];
43
- Reflect.defineMetadata(JOBS, list, target);
44
- }
45
- exports.addJob = addJob;
33
+ const scheduleDecorator = (0, decorator_make_1.makeMethodDecorator)();
46
34
  /**
47
35
  * 定时任务设定
48
36
  */
49
37
  function schedule(opt) {
50
- return function (target, propertyKey, descriptor) {
51
- const path = `/__schedule/${(0, crypto_1.randomUUID)()}/${target.constructor.name}.${propertyKey}`;
52
- const params = Reflect.getOwnMetadata('design:paramtypes', target, propertyKey) || [];
53
- addJob(target, Object.assign({
54
- path,
55
- handle: descriptor.value,
56
- params,
57
- }, opt));
58
- };
38
+ return scheduleDecorator.wrap((descriptor, target) => {
39
+ const path = `${(0, crypto_1.randomUUID)()}/${target.constructor.name}.${descriptor.handle.name}`;
40
+ return Object.assign({ path }, descriptor, opt);
41
+ });
59
42
  }
60
43
  exports.schedule = schedule;
61
- /**
62
- * 添加定时任务到路由并启动定时器
63
- */
64
- function registerSchedule(core, target) {
65
- const jobs = getJobs(target.prototype);
66
- if (jobs.length > 0) {
67
- for (const item of jobs) {
68
- // 添加到路由中
69
- core.router.post(item.path, safeCheck, ...(item.middleware ?
70
- (Array.isArray(item.middleware) ? item.middleware : [item.middleware]) : []), async (ctx) => {
71
- const cls = await ctx.injector.getInstance(target);
72
- await ctx.injector.apply(cls, item);
73
- });
74
- // 启用定时器
75
- (0, node_schedule_1.scheduleJob)(item.rule, function callback() {
76
- const request = Object.assign({
77
- headers: {
44
+ class ScheduleRegister {
45
+ constructor(core, option) {
46
+ this.jobs = [];
47
+ this.core = core;
48
+ this.router = new router_1.Router({
49
+ prefix: '/__schedule/',
50
+ });
51
+ this.option = option;
52
+ }
53
+ /**
54
+ * 添加定时任务到路由并启动定时器
55
+ */
56
+ register(target) {
57
+ const methods = scheduleDecorator.getMethods(target.prototype);
58
+ if (methods.length > 0) {
59
+ (0, inject_1.scope)('prototype', false)(target);
60
+ for (const item of methods) {
61
+ // 添加到路由中
62
+ this.router.post(item.path, safeCheck, ...(item.middleware ?
63
+ (Array.isArray(item.middleware) ? item.middleware : [item.middleware]) : []), async (ctx) => {
64
+ const cls = await ctx.injector.getInstance(target);
65
+ await ctx.injector.apply(cls, item);
66
+ });
67
+ if (this.option.disabled) {
68
+ continue;
69
+ }
70
+ // 启用定时器
71
+ const job = (0, node_schedule_1.scheduleJob)(item.rule, () => {
72
+ const path = '/__schedule/' + item.path;
73
+ const request = Object.assign({
74
+ headers: {
75
+ host: '127.0.0.1',
76
+ },
77
+ query: {},
78
+ querystring: '',
78
79
  host: '127.0.0.1',
79
- },
80
- query: {},
81
- querystring: '',
82
- host: '127.0.0.1',
83
- hostname: '127.0.0.1',
84
- protocol: 'http',
85
- secure: 'false',
86
- method: 'POST',
87
- url: item.path,
88
- path: item.path,
89
- socket: {
90
- remoteAddress: SAFE_IP,
91
- remotePort: 7001,
92
- },
80
+ hostname: '127.0.0.1',
81
+ protocol: 'http',
82
+ secure: 'false',
83
+ method: 'POST',
84
+ url: path,
85
+ path,
86
+ socket: {
87
+ remoteAddress: SAFE_IP,
88
+ remotePort: 7001,
89
+ },
90
+ });
91
+ const response = new http_1.ServerResponse(request);
92
+ this.core.koa.callback()(request, response);
93
93
  });
94
- const response = new http_1.ServerResponse(request);
95
- core.koa.callback()(request, response);
96
- });
94
+ this.jobs.push(job);
95
+ }
96
+ }
97
+ }
98
+ addToCoreRouter() {
99
+ this.core.router.use(this.router.routes());
100
+ }
101
+ destory() {
102
+ for (const job of this.jobs) {
103
+ job.cancel();
97
104
  }
98
105
  }
99
106
  }
100
- exports.registerSchedule = registerSchedule;
107
+ exports.ScheduleRegister = ScheduleRegister;
package/dist/types.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { ServerResponse, IncomingMessage } from 'http';
3
- export declare type RequestCallback = (request: IncomingMessage, response: ServerResponse) => void;
4
- export declare type JobCallback = (request: IncomingMessage, response: ServerResponse, callback: RequestCallback) => void;
3
+ export type RequestCallback = (request: IncomingMessage, response: ServerResponse) => void;
4
+ export type JobCallback = (request: IncomingMessage, response: ServerResponse, callback: RequestCallback) => void;
5
5
  export interface ScheduleOption {
6
6
  /**
7
7
  * 加载 schedule 文件目录,默认: ./app/schedule
@@ -11,4 +11,12 @@ export interface ScheduleOption {
11
11
  * 文件匹配规则,默认: ** /*.{ts,js}
12
12
  */
13
13
  patterns?: string;
14
+ /**
15
+ * 是否禁用定时器
16
+ * 如禁用只注册到路由而不自动执行
17
+ * 可以通过环境变量 ZENWEB_SCHEDULE_DISABLED=1 控制
18
+ *
19
+ * @default false
20
+ */
21
+ disabled?: boolean;
14
22
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenweb/schedule",
3
- "version": "3.1.0",
3
+ "version": "3.3.0",
4
4
  "description": "Zenweb Schedule module",
5
5
  "exports": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -8,7 +8,8 @@
8
8
  "dist"
9
9
  ],
10
10
  "scripts": {
11
- "prepublishOnly": "rm -fr dist && tsc",
11
+ "build": "rimraf dist && tsc",
12
+ "prepublishOnly": "npm run build",
12
13
  "dev": "cd example && DEBUG=* ts-node app"
13
14
  },
14
15
  "author": {
@@ -33,14 +34,18 @@
33
34
  "url": "https://github.com/yefei/zenweb-schedule/issues"
34
35
  },
35
36
  "devDependencies": {
36
- "@zenweb/core": "^2.4.1",
37
- "@zenweb/inject": "^3.5.0",
38
- "@zenweb/log": "^2.3.1",
39
- "@zenweb/router": "^3.0.0"
37
+ "@zenweb/core": "^3.1.6",
38
+ "@zenweb/inject": "^3.17.0",
39
+ "@zenweb/log": "^3.0.0",
40
+ "@zenweb/router": "^3.1.1",
41
+ "rimraf": "^4.3.1",
42
+ "ts-node": "^10.9.1",
43
+ "typescript": "^4.8.2"
40
44
  },
41
45
  "dependencies": {
42
- "@types/node-schedule": "^1.3.2",
46
+ "@types/node-schedule": "^2.1.0",
47
+ "decorator-make": "^1.3.0",
43
48
  "globby": "11.0.4",
44
- "node-schedule": "^2.0.0"
49
+ "node-schedule": "^2.1.1"
45
50
  }
46
51
  }