@opengis/fastify-table 1.2.94 → 1.2.96

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.
Files changed (42) hide show
  1. package/README.md +86 -86
  2. package/package.json +1 -1
  3. package/server/migrations/cls.sql +40 -39
  4. package/server/plugins/cron/funcs/addCron.js +130 -130
  5. package/server/plugins/cron/index.js +6 -6
  6. package/server/plugins/crud/funcs/getOpt.js +13 -13
  7. package/server/plugins/crud/funcs/setOpt.js +21 -21
  8. package/server/plugins/crud/funcs/setToken.js +44 -44
  9. package/server/plugins/crud/funcs/utils/getFolder.js +11 -11
  10. package/server/plugins/crud/index.js +23 -23
  11. package/server/plugins/hook/index.js +8 -8
  12. package/server/plugins/logger/errorStatus.js +19 -19
  13. package/server/plugins/logger/index.js +26 -26
  14. package/server/plugins/migration/index.js +7 -7
  15. package/server/plugins/policy/sqlInjection.js +33 -33
  16. package/server/plugins/redis/client.js +8 -8
  17. package/server/plugins/redis/funcs/redisClients.js +3 -3
  18. package/server/plugins/redis/index.js +17 -17
  19. package/server/plugins/table/funcs/getFilterSQL/util/getCustomQuery.js +13 -13
  20. package/server/plugins/table/funcs/getFilterSQL/util/getTableSql.js +34 -34
  21. package/server/plugins/table/funcs/getTemplates.js +19 -19
  22. package/server/plugins/table/funcs/gisIRColumn.js +82 -82
  23. package/server/plugins/table/funcs/loadTemplate.js +1 -1
  24. package/server/plugins/table/funcs/loadTemplatePath.js +1 -1
  25. package/server/plugins/table/funcs/userTemplateDir.js +1 -1
  26. package/server/plugins/table/index.js +13 -13
  27. package/server/plugins/util/index.js +7 -7
  28. package/server/routes/cron/index.js +14 -14
  29. package/server/routes/logger/controllers/logger.file.js +92 -92
  30. package/server/routes/logger/controllers/utils/checkUserAccess.js +19 -19
  31. package/server/routes/logger/controllers/utils/getRootDir.js +26 -26
  32. package/server/routes/logger/index.js +17 -17
  33. package/server/routes/properties/controllers/properties.add.js +55 -55
  34. package/server/routes/properties/controllers/properties.get.js +17 -17
  35. package/server/routes/properties/index.js +16 -16
  36. package/server/routes/table/controllers/data.js +1 -1
  37. package/server/routes/table/controllers/form.js +42 -42
  38. package/server/routes/table/controllers/search.js +74 -74
  39. package/server/routes/table/index.js +29 -29
  40. package/server/routes/table/schema.js +64 -64
  41. package/server/routes/util/controllers/status.monitor.js +8 -8
  42. package/server/routes/util/index.js +12 -12
package/README.md CHANGED
@@ -1,87 +1,87 @@
1
- # fastify-table
2
-
3
- <!-- ![alt text](https://cdn.softpro.ua/data/npm/admin/opengis-admin.png) -->
4
-
5
- [![NPM version](https://img.shields.io/npm/v/@opengis/fastify-table?style=plain)](https://www.npmjs.com/package/@opengis/fastify-table)
6
- [![NPM last update](https://img.shields.io/npm/last-update/@opengis/fastify-table?style=plain)]()
7
- [![NPM downloads](https://img.shields.io/npm/dw/@opengis/fastify-table?style=plain)]()
8
- [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=plain)](http://standardjs.com/)
9
-
10
- This is a backend toolkit for database management and more.
11
-
12
- ### Why fastify-table?
13
-
14
- - **Logger** - Monitoring user activity and system status.
15
- - **Redis cache** - Optimizes web page rendering for lightning-fast performance.
16
- - **Secure** - Ensures protection against XSS attacks in queries.
17
- - **SQL Migration** - Automatically adds all necessary tables to your project's database.
18
-
19
-
20
- ### Features
21
-
22
- - CRUD
23
- - cron
24
- - Logger
25
- - Redis
26
- - pg
27
-
28
- ---
29
-
30
- ### Install
31
-
32
- ```bash
33
- npm i @opengis/fastify-table
34
- ```
35
-
36
- ### Usage
37
-
38
- ```js
39
- fastify.register(import('@opengis/fastify-table'), config);
40
- ```
41
-
42
- ---
43
-
44
- ### Documenation
45
-
46
- For a detailed understanding `fastify-table`, its features, and how to use them, refer to our [Documentation](https://apidocs.softpro.ua/fastify-table/).
47
-
48
- ---
49
-
50
- ### Technology stack
51
-
52
- <a href="https://fastify.dev/" target="_blank">
53
- <img src="https://img.shields.io/badge/Fastify-323330?style=for-the-badge&logo=fastify" /></a>
54
-
55
- <a href="https://www.postgresql.org/" target="_blank">
56
- <img src="https://img.shields.io/badge/PostgreSQL-323330?style=for-the-badge&logo=postgresql&logoColor=white" /></a>
57
-
58
- <a href="https://redis.io/" target="_blank">
59
- <img src="https://img.shields.io/badge/redis-323330.svg?&style=for-the-badge&logo=redis&logoColor=" /></a>
60
-
61
- <a href="https://www.npmjs.com/package/pino" target="_blank">
62
- <img src="https://img.shields.io/badge/pino-323330.svg?&style=for-the-badge&logo=pino&logoColor=" /></a>
63
-
64
- ---
65
-
66
- ### Contribute
67
-
68
- Feel free to contact us through our website [SOFTPRO.UA](https://softpro.ua) or email <info@softpro.ua>
69
-
70
- - Report bugs
71
- - Share your ideas
72
- - Ask questions
73
-
74
- ### Follow Us
75
-
76
- [Official site](https://softpro.ua)
77
-
78
- <p>
79
- <a href="https://www.instagram.com/gissoftpro/" target="_blank"><img src="https://cdn.softpro.ua/data/npm/instagram.png" alt="Softpro Instagram" title="oftpro Instagram"></a>&nbsp;&nbsp;
80
- <a href="https://www.facebook.com/gissoftpro" target="_blank"><img src="https://cdn.softpro.ua/data/npm/facebook.png" alt="Softpro Facebook" title="Softpro Facebook"></a>&nbsp;&nbsp;
81
- <a href="https://t.me/softprogis" target="_blank"><img src="https://cdn.softpro.ua/data/npm/telegram.png" alt="Softpro Telegram" title="Softpro Telegram"></a>&nbsp;&nbsp;
82
- <a href="https://www.linkedin.com/in/softpro-ukraine-a8876b282/recent-activity/all/" target="_blank"><img src="https://cdn.softpro.ua/data/npm/social/linkedin.png" alt="Softpro Linkedin" title="Softpro LinkedIn"></a>&nbsp;&nbsp;
83
- </p>
84
-
85
- ### License
86
-
1
+ # fastify-table
2
+
3
+ <!-- ![alt text](https://cdn.softpro.ua/data/npm/admin/opengis-admin.png) -->
4
+
5
+ [![NPM version](https://img.shields.io/npm/v/@opengis/fastify-table?style=plain)](https://www.npmjs.com/package/@opengis/fastify-table)
6
+ [![NPM last update](https://img.shields.io/npm/last-update/@opengis/fastify-table?style=plain)]()
7
+ [![NPM downloads](https://img.shields.io/npm/dw/@opengis/fastify-table?style=plain)]()
8
+ [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=plain)](http://standardjs.com/)
9
+
10
+ This is a backend toolkit for database management and more.
11
+
12
+ ### Why fastify-table?
13
+
14
+ - **Logger** - Monitoring user activity and system status.
15
+ - **Redis cache** - Optimizes web page rendering for lightning-fast performance.
16
+ - **Secure** - Ensures protection against XSS attacks in queries.
17
+ - **SQL Migration** - Automatically adds all necessary tables to your project's database.
18
+
19
+
20
+ ### Features
21
+
22
+ - CRUD
23
+ - cron
24
+ - Logger
25
+ - Redis
26
+ - pg
27
+
28
+ ---
29
+
30
+ ### Install
31
+
32
+ ```bash
33
+ npm i @opengis/fastify-table
34
+ ```
35
+
36
+ ### Usage
37
+
38
+ ```js
39
+ fastify.register(import('@opengis/fastify-table'), config);
40
+ ```
41
+
42
+ ---
43
+
44
+ ### Documenation
45
+
46
+ For a detailed understanding `fastify-table`, its features, and how to use them, refer to our [Documentation](https://apidocs.softpro.ua/fastify-table/).
47
+
48
+ ---
49
+
50
+ ### Technology stack
51
+
52
+ <a href="https://fastify.dev/" target="_blank">
53
+ <img src="https://img.shields.io/badge/Fastify-323330?style=for-the-badge&logo=fastify" /></a>
54
+
55
+ <a href="https://www.postgresql.org/" target="_blank">
56
+ <img src="https://img.shields.io/badge/PostgreSQL-323330?style=for-the-badge&logo=postgresql&logoColor=white" /></a>
57
+
58
+ <a href="https://redis.io/" target="_blank">
59
+ <img src="https://img.shields.io/badge/redis-323330.svg?&style=for-the-badge&logo=redis&logoColor=" /></a>
60
+
61
+ <a href="https://www.npmjs.com/package/pino" target="_blank">
62
+ <img src="https://img.shields.io/badge/pino-323330.svg?&style=for-the-badge&logo=pino&logoColor=" /></a>
63
+
64
+ ---
65
+
66
+ ### Contribute
67
+
68
+ Feel free to contact us through our website [SOFTPRO.UA](https://softpro.ua) or email <info@softpro.ua>
69
+
70
+ - Report bugs
71
+ - Share your ideas
72
+ - Ask questions
73
+
74
+ ### Follow Us
75
+
76
+ [Official site](https://softpro.ua)
77
+
78
+ <p>
79
+ <a href="https://www.instagram.com/gissoftpro/" target="_blank"><img src="https://cdn.softpro.ua/data/npm/instagram.png" alt="Softpro Instagram" title="oftpro Instagram"></a>&nbsp;&nbsp;
80
+ <a href="https://www.facebook.com/gissoftpro" target="_blank"><img src="https://cdn.softpro.ua/data/npm/facebook.png" alt="Softpro Facebook" title="Softpro Facebook"></a>&nbsp;&nbsp;
81
+ <a href="https://t.me/softprogis" target="_blank"><img src="https://cdn.softpro.ua/data/npm/telegram.png" alt="Softpro Telegram" title="Softpro Telegram"></a>&nbsp;&nbsp;
82
+ <a href="https://www.linkedin.com/in/softpro-ukraine-a8876b282/recent-activity/all/" target="_blank"><img src="https://cdn.softpro.ua/data/npm/social/linkedin.png" alt="Softpro Linkedin" title="Softpro LinkedIn"></a>&nbsp;&nbsp;
83
+ </p>
84
+
85
+ ### License
86
+
87
87
  Copyright © SOFTPRO. All rights reserved.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/fastify-table",
3
- "version": "1.2.94",
3
+ "version": "1.2.96",
4
4
  "type": "module",
5
5
  "description": "core-plugins",
6
6
  "keywords": [
@@ -1,39 +1,40 @@
1
- create schema if not exists admin;
2
-
3
- CREATE TABLE if not exists admin.cls();
4
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS clsid text;
5
- ALTER TABLE admin.cls DROP CONSTRAINT IF EXISTS admin_cls_pkey;
6
- ALTER TABLE admin.cls DROP CONSTRAINT IF EXISTS admin_cls_unique;
7
-
8
- ALTER TABLE admin.cls ALTER COLUMN clsid SET NOT NULL;
9
- ALTER TABLE admin.cls ALTER COLUMN clsid SET DEFAULT next_id();
10
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS name text;
11
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS data text;
12
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS type text;
13
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS code text;
14
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS parent text;
15
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS ua text;
16
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS en text;
17
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS module text;
18
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS files json;
19
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS cdate timestamp without time zone;
20
- ALTER TABLE admin.cls ALTER COLUMN cdate SET DEFAULT (now())::timestamp without time zone;
21
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS editor_id text;
22
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS editor_date timestamp without time zone;
23
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS uid text;
24
- ALTER TABLE admin.cls ALTER COLUMN uid SET NOT NULL;
25
- ALTER TABLE admin.cls ALTER COLUMN uid SET DEFAULT '1'::text;
26
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS icon text;
27
- ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS color text;
28
-
29
- ALTER TABLE admin.cls ADD CONSTRAINT admin_cls_pkey PRIMARY KEY (clsid);
30
- ALTER TABLE admin.cls ADD CONSTRAINT admin_cls_unique UNIQUE (code, parent);
31
-
32
- COMMENT ON COLUMN admin.cls.name IS 'Назва';
33
- COMMENT ON COLUMN admin.cls.type IS 'Тип';
34
- COMMENT ON COLUMN admin.cls.data IS 'SQL';
35
- COMMENT ON COLUMN admin.cls.code IS 'Код';
36
- COMMENT ON COLUMN admin.cls.parent IS 'Назва батьківського об''єкту';
37
- COMMENT ON COLUMN admin.cls.module IS 'Модуль';
38
- COMMENT ON COLUMN admin.cls.icon IS 'Іконка';
39
- COMMENT ON COLUMN admin.cls.color IS 'Колір';
1
+ create schema if not exists admin;
2
+
3
+ CREATE TABLE if not exists admin.cls();
4
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS clsid text;
5
+ ALTER TABLE admin.cls DROP CONSTRAINT IF EXISTS admin_cls_pkey;
6
+ ALTER TABLE admin.cls DROP CONSTRAINT IF EXISTS admin_cls_unique;
7
+
8
+ ALTER TABLE admin.cls ALTER COLUMN clsid SET NOT NULL;
9
+ ALTER TABLE admin.cls ALTER COLUMN clsid SET DEFAULT next_id();
10
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS name text;
11
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS data text;
12
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS type text;
13
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS code text;
14
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS parent text;
15
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS ua text;
16
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS en text;
17
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS module text;
18
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS files json;
19
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS cdate timestamp without time zone;
20
+ ALTER TABLE admin.cls ALTER COLUMN cdate SET DEFAULT (now())::timestamp without time zone;
21
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS editor_id text;
22
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS editor_date timestamp without time zone;
23
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS uid text;
24
+ ALTER TABLE admin.cls ALTER COLUMN uid SET NOT NULL;
25
+ ALTER TABLE admin.cls ALTER COLUMN uid SET DEFAULT '1'::text;
26
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS icon text;
27
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS color text;
28
+ ALTER TABLE admin.cls ADD COLUMN IF NOT EXISTS hash text;
29
+
30
+ ALTER TABLE admin.cls ADD CONSTRAINT admin_cls_pkey PRIMARY KEY (clsid);
31
+ ALTER TABLE admin.cls ADD CONSTRAINT admin_cls_unique UNIQUE (code, parent);
32
+
33
+ COMMENT ON COLUMN admin.cls.name IS 'Назва';
34
+ COMMENT ON COLUMN admin.cls.type IS 'Тип';
35
+ COMMENT ON COLUMN admin.cls.data IS 'SQL';
36
+ COMMENT ON COLUMN admin.cls.code IS 'Код';
37
+ COMMENT ON COLUMN admin.cls.parent IS 'Назва батьківського об''єкту';
38
+ COMMENT ON COLUMN admin.cls.module IS 'Модуль';
39
+ COMMENT ON COLUMN admin.cls.icon IS 'Іконка';
40
+ COMMENT ON COLUMN admin.cls.color IS 'Колір';
@@ -1,130 +1,130 @@
1
- import { createHash } from 'crypto';
2
-
3
- import config from '../../../../config.js';
4
- import getRedis from '../../redis/funcs/getRedis.js';
5
- import getPG from '../../pg/funcs/getPG.js';
6
- import logger from '../../logger/getLogger.js';
7
- import cronList from '../cronList.js';
8
-
9
- const md5 = (string) => createHash('md5').update(string).digest('hex');
10
-
11
- const rclient = getRedis();
12
- async function verifyUnique(name) {
13
- const cronId = config.port || 3000 + md5(name);
14
- // one per node check
15
- const key = `cron:unique:${cronId}`;
16
- const unique = await rclient.setnx(key, 1);
17
- const ttl = await rclient.ttl(key);
18
- if (!unique && ttl !== -1) {
19
- return false;
20
- }
21
- await rclient.expire(key, 20);
22
- return true;
23
- }
24
-
25
- const intervalStringMs = {
26
- everyMin: 1000 * 60,
27
- tenMin: 1000 * 60 * 10,
28
- everyHour: 1000 * 60 * 60,
29
- isHalfday: 1000 * 60 * 60 * 12,
30
- dailyHour: 1000 * 60 * 60 * 24,
31
- };
32
-
33
- const interval2ms = {
34
- string: (interval) => {
35
- const date = new Date();
36
- const intervarSplit = interval.match(/^(\*{2}|(\*)?(\d{1,2})):(\*(\d)|(\d{2}))/);
37
- if (!intervarSplit) {
38
- throw new Error(`interval ${interval} not suported`);
39
- }
40
- const [, , isHalfday, dailyHour, , tenMin, HourlyMin] = intervarSplit;
41
- const intervalMs = (isHalfday && intervalStringMs.isHalfday)
42
- || (dailyHour && intervalStringMs.dailyHour)
43
- || (tenMin && intervalStringMs.tenMin)
44
- || intervalStringMs.everyHour;
45
- const offsetDay = ((+dailyHour || 0) * 60 + (+tenMin || +HourlyMin)) * 60 * 1000;
46
- const offsetCur = (date - date.getTimezoneOffset() * 1000 * 60) % intervalMs;
47
- const waitMs = (offsetDay - offsetCur + intervalMs) % intervalMs;
48
- return [waitMs, intervalMs];
49
- },
50
- number: (interval) => {
51
- const date = new Date();
52
- const intervalMs = interval * 1000;
53
- const dateWithTZ = date - date.getTimezoneOffset() * 1000 * 60;
54
- const offsetCur = dateWithTZ % intervalMs;
55
- // start every cron within 1 hour
56
- const sixtyMinutesStartMs = 3600000;
57
- const waitMs = (intervalMs - offsetCur) % sixtyMinutesStartMs;
58
- return [waitMs, intervalMs];
59
- },
60
- };
61
-
62
- async function runCron({
63
- func, name,
64
- }) {
65
- const pg = getPG();
66
-
67
- const unique = await verifyUnique(name);
68
-
69
- if (!unique) return;
70
- const db = pg.options.database;
71
-
72
- try {
73
- // console.log(`cron:${name}`);
74
- const data = await func({ pg });
75
- const subdir = !!data ? 'cron' : 'cron/null';
76
- logger.file(subdir, {
77
- db, name, result: data,
78
- });
79
- }
80
- catch (err) {
81
- logger.file('cron', {
82
- db, name, error: err.toString(),
83
- });
84
- logger.error(err);
85
- }
86
- }
87
-
88
- /**
89
- * interval:
90
- * - 02:54 - every day
91
- * - 2:03 - every day
92
- * - *1:43 - 2 times a day
93
- * - *12:03 - 2 times a day
94
- * - **:54 - every hour
95
- * - **:*3 - every 10 minutes
96
- * - 60 - every minute
97
- * - 10 * 60 - every 10 minutes
98
- */
99
-
100
- export default async function addCron(func, interval) {
101
- const { time = {}, disabled = [] } = config.cron || {};
102
-
103
- const name = func.name || func.toString().split('/').at(-1).split('\'')[0];
104
-
105
- // if (!config.isServer) return;
106
-
107
- if (disabled.includes(name)) {
108
- logger.file('cron', { name, message: 'cron disabled' });
109
- return;
110
- }
111
-
112
- cronList[name] = func;
113
-
114
- const userInterval = time[name] || interval;
115
- const [waitMs, intervalMs] = interval2ms[typeof interval](userInterval);
116
-
117
- if (intervalMs < 1000) {
118
- logger.file('cron', { name, error: `interval ${interval} to small` });
119
- return;
120
- }
121
-
122
- // setTimeout to w8 for the time to start
123
- setTimeout(() => {
124
- runCron({ func, name });
125
- // interval
126
- setInterval(() => {
127
- runCron({ func, name });
128
- }, intervalMs);
129
- }, waitMs);
130
- }
1
+ import { createHash } from 'crypto';
2
+
3
+ import config from '../../../../config.js';
4
+ import getRedis from '../../redis/funcs/getRedis.js';
5
+ import getPG from '../../pg/funcs/getPG.js';
6
+ import logger from '../../logger/getLogger.js';
7
+ import cronList from '../cronList.js';
8
+
9
+ const md5 = (string) => createHash('md5').update(string).digest('hex');
10
+
11
+ const rclient = getRedis();
12
+ async function verifyUnique(name) {
13
+ const cronId = config.port || 3000 + md5(name);
14
+ // one per node check
15
+ const key = `cron:unique:${cronId}`;
16
+ const unique = await rclient.setnx(key, 1);
17
+ const ttl = await rclient.ttl(key);
18
+ if (!unique && ttl !== -1) {
19
+ return false;
20
+ }
21
+ await rclient.expire(key, 20);
22
+ return true;
23
+ }
24
+
25
+ const intervalStringMs = {
26
+ everyMin: 1000 * 60,
27
+ tenMin: 1000 * 60 * 10,
28
+ everyHour: 1000 * 60 * 60,
29
+ isHalfday: 1000 * 60 * 60 * 12,
30
+ dailyHour: 1000 * 60 * 60 * 24,
31
+ };
32
+
33
+ const interval2ms = {
34
+ string: (interval) => {
35
+ const date = new Date();
36
+ const intervarSplit = interval.match(/^(\*{2}|(\*)?(\d{1,2})):(\*(\d)|(\d{2}))/);
37
+ if (!intervarSplit) {
38
+ throw new Error(`interval ${interval} not suported`);
39
+ }
40
+ const [, , isHalfday, dailyHour, , tenMin, HourlyMin] = intervarSplit;
41
+ const intervalMs = (isHalfday && intervalStringMs.isHalfday)
42
+ || (dailyHour && intervalStringMs.dailyHour)
43
+ || (tenMin && intervalStringMs.tenMin)
44
+ || intervalStringMs.everyHour;
45
+ const offsetDay = ((+dailyHour || 0) * 60 + (+tenMin || +HourlyMin)) * 60 * 1000;
46
+ const offsetCur = (date - date.getTimezoneOffset() * 1000 * 60) % intervalMs;
47
+ const waitMs = (offsetDay - offsetCur + intervalMs) % intervalMs;
48
+ return [waitMs, intervalMs];
49
+ },
50
+ number: (interval) => {
51
+ const date = new Date();
52
+ const intervalMs = interval * 1000;
53
+ const dateWithTZ = date - date.getTimezoneOffset() * 1000 * 60;
54
+ const offsetCur = dateWithTZ % intervalMs;
55
+ // start every cron within 1 hour
56
+ const sixtyMinutesStartMs = 3600000;
57
+ const waitMs = (intervalMs - offsetCur) % sixtyMinutesStartMs;
58
+ return [waitMs, intervalMs];
59
+ },
60
+ };
61
+
62
+ async function runCron({
63
+ func, name,
64
+ }) {
65
+ const pg = getPG();
66
+
67
+ const unique = await verifyUnique(name);
68
+
69
+ if (!unique) return;
70
+ const db = pg.options.database;
71
+
72
+ try {
73
+ // console.log(`cron:${name}`);
74
+ const data = await func({ pg });
75
+ const subdir = !!data ? 'cron' : 'cron/null';
76
+ logger.file(subdir, {
77
+ db, name, result: data,
78
+ });
79
+ }
80
+ catch (err) {
81
+ logger.file('cron', {
82
+ db, name, error: err.toString(),
83
+ });
84
+ logger.error(err);
85
+ }
86
+ }
87
+
88
+ /**
89
+ * interval:
90
+ * - 02:54 - every day
91
+ * - 2:03 - every day
92
+ * - *1:43 - 2 times a day
93
+ * - *12:03 - 2 times a day
94
+ * - **:54 - every hour
95
+ * - **:*3 - every 10 minutes
96
+ * - 60 - every minute
97
+ * - 10 * 60 - every 10 minutes
98
+ */
99
+
100
+ export default async function addCron(func, interval) {
101
+ const { time = {}, disabled = [] } = config.cron || {};
102
+
103
+ const name = func.name || func.toString().split('/').at(-1).split('\'')[0];
104
+
105
+ // if (!config.isServer) return;
106
+
107
+ if (disabled.includes(name)) {
108
+ logger.file('cron', { name, message: 'cron disabled' });
109
+ return;
110
+ }
111
+
112
+ cronList[name] = func;
113
+
114
+ const userInterval = time[name] || interval;
115
+ const [waitMs, intervalMs] = interval2ms[typeof interval](userInterval);
116
+
117
+ if (intervalMs < 1000) {
118
+ logger.file('cron', { name, error: `interval ${interval} to small` });
119
+ return;
120
+ }
121
+
122
+ // setTimeout to w8 for the time to start
123
+ setTimeout(() => {
124
+ runCron({ func, name });
125
+ // interval
126
+ setInterval(() => {
127
+ runCron({ func, name });
128
+ }, intervalMs);
129
+ }, waitMs);
130
+ }
@@ -1,6 +1,6 @@
1
- import addCron from './funcs/addCron.js';
2
-
3
- async function plugin(fastify) {
4
- // fastify.decorate('addCron', addCron);
5
- }
6
- export default plugin;
1
+ import addCron from './funcs/addCron.js';
2
+
3
+ async function plugin(fastify) {
4
+ // fastify.decorate('addCron', addCron);
5
+ }
6
+ export default plugin;
@@ -1,13 +1,13 @@
1
- import getRedis from '../../redis/funcs/getRedis.js';
2
-
3
- // import { getRedis } from '../../../../utils.js';
4
-
5
- export default async function getOpt(token, uid = 0) {
6
- const rclient = getRedis({ db: 0 });
7
-
8
- const key = `opt:${uid}:${token}`;
9
- // console.log(key);
10
- const data = await rclient.get(key);
11
- if (!data) return null;
12
- return JSON.parse(data);
13
- }
1
+ import getRedis from '../../redis/funcs/getRedis.js';
2
+
3
+ // import { getRedis } from '../../../../utils.js';
4
+
5
+ export default async function getOpt(token, uid = 0) {
6
+ const rclient = getRedis({ db: 0 });
7
+
8
+ const key = `opt:${uid}:${token}`;
9
+ // console.log(key);
10
+ const data = await rclient.get(key);
11
+ if (!data) return null;
12
+ return JSON.parse(data);
13
+ }
@@ -1,21 +1,21 @@
1
- import { createHash, randomUUID } from 'crypto';
2
-
3
- const random = randomUUID();
4
-
5
- import getRedis from '../../redis/funcs/getRedis.js';
6
-
7
- // import { getRedis } from '../../../../utils.js';
8
-
9
- function md5(string) {
10
- return createHash('md5').update(string).digest('hex');
11
- }
12
-
13
- export default function setOpt(params, uid = 0) {
14
- const token = Buffer.from(md5(typeof params === 'object' ? JSON.stringify(params) : params) + random, 'hex').toString('base64').replace(/[+-=]+/g, '');
15
- // const token = md5(params);
16
- const key = `opt:${uid}:${token}`;
17
-
18
- const rclient = getRedis({ db: 0 });
19
- rclient.set(key, JSON.stringify(params), 'EX', 60 * 60);
20
- return token;
21
- }
1
+ import { createHash, randomUUID } from 'crypto';
2
+
3
+ const random = randomUUID();
4
+
5
+ import getRedis from '../../redis/funcs/getRedis.js';
6
+
7
+ // import { getRedis } from '../../../../utils.js';
8
+
9
+ function md5(string) {
10
+ return createHash('md5').update(string).digest('hex');
11
+ }
12
+
13
+ export default function setOpt(params, uid = 0) {
14
+ const token = Buffer.from(md5(typeof params === 'object' ? JSON.stringify(params) : params) + random, 'hex').toString('base64').replace(/[+-=]+/g, '');
15
+ // const token = md5(params);
16
+ const key = `opt:${uid}:${token}`;
17
+
18
+ const rclient = getRedis({ db: 0 });
19
+ rclient.set(key, JSON.stringify(params), 'EX', 60 * 60);
20
+ return token;
21
+ }