not-node 6.5.18 → 6.5.21

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/.husky/pre-commit CHANGED
@@ -1,4 +1 @@
1
- #!/usr/bin/env sh
2
- . "$(dirname -- "$0")/_/husky.sh"
3
-
4
1
  npm test
package/eslint.config.cjs CHANGED
@@ -19,9 +19,9 @@ module.exports = [
19
19
  ],
20
20
  },
21
21
  ...compat.extends(
22
- "eslint:recommended",
22
+ "eslint:recommended"
23
23
  //"plugin:node/recommended",
24
- "plugin:sonarjs/recommended-legacy"
24
+ //"plugin:sonarjs/recommended-legacy"
25
25
  ),
26
26
  {
27
27
  languageOptions: {
package/index.js CHANGED
@@ -37,6 +37,8 @@ module.exports.Enrich = require("./src/model/enrich");
37
37
  module.exports.Routine = require("./src/model/routine");
38
38
  /** Common functions */
39
39
  module.exports.Common = require("./src/common");
40
+ /** Task Runner */
41
+ module.exports.TaskRunner = require("./src/task.runner.js");
40
42
  /** Fields library manager */
41
43
  module.exports.Fields = require("./src/fields");
42
44
  /** Application generic helpers */
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "not-node",
3
- "version": "6.5.18",
3
+ "version": "6.5.21",
4
4
  "description": "node complimentary part for client side notFramework.",
5
5
  "main": "index.js",
6
6
  "scripts": {
7
- "test": "mocha --require mocha-suppress-logs --reporter spec --timeout 12000",
7
+ "test": "mocha --exit --require mocha-suppress-logs --reporter spec --timeout 12000",
8
8
  "lint": "eslint ./src --fix",
9
9
  "pretest": "eslint ./src",
10
10
  "docs": "jsdoc -c jsdoc.json",
@@ -12,7 +12,7 @@
12
12
  "watch:build:cover:dev": "npm-run-all --parallel js-watch",
13
13
  "cover": "nyc npm test",
14
14
  "clear:playground": "rm -rf ./playground",
15
- "prepare": "husky install"
15
+ "prepare": "husky"
16
16
  },
17
17
  "bin": {
18
18
  "not-node": "bin/not-node.js",
@@ -59,7 +59,7 @@
59
59
  "mongoose-validator": "*",
60
60
  "nconf": "*",
61
61
  "not-config": "*",
62
- "not-filter": "*",
62
+ "not-filter": "^0.3.15",
63
63
  "not-inform": "*",
64
64
  "not-locale": "^0.0.22",
65
65
  "not-log": "*",
@@ -135,4 +135,4 @@
135
135
  ]
136
136
  }
137
137
  }
138
- }
138
+ }
package/src/auth/const.js CHANGED
@@ -29,7 +29,10 @@ const METHOD_SIGNAURES = {
29
29
 
30
30
  const OBJECT_STRING = "[object String]";
31
31
 
32
+ //document owned by registered user
32
33
  const DOCUMENT_OWNER_FIELD_NAME = "owner";
34
+ //document owned by guest user
35
+ const DOCUMENT_SESSION_FIELD_NAME = "session";
33
36
  const TOKEN_TTL = 3600;
34
37
 
35
38
  module.exports = {
@@ -39,6 +42,7 @@ module.exports = {
39
42
  DEFAULT_USER_ROLE_FOR_ROOT,
40
43
  DEFAULT_USER_ROLE_FOR_ADMIN,
41
44
  DOCUMENT_OWNER_FIELD_NAME,
45
+ DOCUMENT_SESSION_FIELD_NAME,
42
46
  ACTION_SIGNATURES,
43
47
  METHOD_SIGNAURES,
44
48
  };
@@ -76,5 +76,6 @@
76
76
  "select_from_list_label": "Выберите из списка...",
77
77
  "field_actions_label": "Действия",
78
78
  "form_exception_field_extractor_is_undefined": "Экстрактор для поля входных данных отсутствует",
79
+ "form_exception_identity_or_query_is_undefined": "Identity или Query отсутствуют",
79
80
  "versioning_error_same_old_data": "Данные не изменились, сохранение отклонено."
80
81
  }
package/src/domain.js CHANGED
@@ -59,7 +59,6 @@ class notDomain extends EventEmitter {
59
59
  constructor(options) {
60
60
  super();
61
61
  this.#options = options;
62
-
63
62
  return this;
64
63
  }
65
64
 
@@ -138,8 +137,8 @@ class notDomain extends EventEmitter {
138
137
 
139
138
  /**
140
139
  * Returns route
141
- * @param {string} name 'moduleName//routeName//functionName' ('not-user//user//add')
142
- * @return {function} route
140
+ * @param {string} name 'moduleName//routeName//functionName' ('not-user//user//add')
141
+ * @return {function} route
143
142
  **/
144
143
  getRoute(name) {
145
144
  if (name.indexOf("//") > 0) {
@@ -34,3 +34,16 @@ class FormExceptionTooManyRequests extends HttpExceptionTooManyRequests {
34
34
  }
35
35
 
36
36
  module.exports.FormExceptionTooManyRequests = FormExceptionTooManyRequests;
37
+
38
+ Error("no prepared identity or query");
39
+
40
+ class FormExceptionIdentityOrQueryIsUndefined extends notRequestError {
41
+ constructor(formName) {
42
+ super("not-node:form_exception_identity_or_query_is_undefined", {
43
+ params: { formName },
44
+ });
45
+ }
46
+ }
47
+
48
+ module.exports.FormExceptionIdentityOrQueryIsUndefined =
49
+ FormExceptionIdentityOrQueryIsUndefined;
@@ -8,6 +8,7 @@ const { getSafeFieldsForRoleAction } = require("../auth/fields");
8
8
  const {
9
9
  DEFAULT_USER_ROLE_FOR_GUEST,
10
10
  ACTION_SIGNATURES,
11
+ DOCUMENT_SESSION_FIELD_NAME,
11
12
  } = require("../auth/const");
12
13
  /**
13
14
  * notFieldsFilter.filter(fields, getApp().getModelSchema(MODEL_NAME), {action});
@@ -144,7 +145,11 @@ class notFieldsFilter {
144
145
  system
145
146
  );
146
147
  },
147
- [SPECIAL_SET_UNSAFE]: ["salt", "password", "session"],
148
+ [SPECIAL_SET_UNSAFE]: [
149
+ "salt",
150
+ "password",
151
+ DOCUMENT_SESSION_FIELD_NAME,
152
+ ],
148
153
  [SPECIAL_SET_TIMESTAMPS]: ["createdAt", "updatedAt"],
149
154
  [SPECIAL_SET_OWNAGE]: (schema) => {
150
155
  const inSchema = Object.keys(schema);
@@ -15,6 +15,7 @@ function createDefaultInstance({
15
15
  MODULE_NAME,
16
16
  MODEL_NAME,
17
17
  actionName,
18
+ config,
18
19
  /* validators = [],
19
20
  dataValidators = [],*/
20
21
  }) {
@@ -23,7 +24,7 @@ function createDefaultInstance({
23
24
  ["data", `${MODULE_NAME}//_${Common.firstLetterToLower(MODEL_NAME)}`],
24
25
  ];
25
26
  const FORM_NAME = Form.createName(MODULE_NAME, MODEL_NAME, actionName);
26
- return new Form({ FIELDS, FORM_NAME, app, MODULE_NAME });
27
+ return new Form({ FIELDS, FORM_NAME, app, MODULE_NAME, config });
27
28
  }
28
29
 
29
30
  module.exports = createDefaultInstance;
@@ -5,9 +5,16 @@ const Form = require("../../form/form");
5
5
  * @param {object} param0
6
6
  * @param {string} param0.MODULE_NAME
7
7
  * @param {string} param0.MODEL_NAME
8
- * @param {string} param0.actionName
9
- * @param {Array<function>} param0.validators
10
- * @param {function} param0.afterExtract
8
+ * @param {string} [param0.actionName = '_data']
9
+ * @param {Array<function>} [param0.validators=[]]
10
+ * @param {function} [param0.afterExtract = async (input, req = null) => input || req]
11
+ * @param {import('../../types.js').notAppConfigReader} [param0.config]
12
+ * @param {Object.<string, Function>} [param0.EXTRACTORS]
13
+ * @param {Object.<string, Function>} [param0.TRANSFORMERS]
14
+ * @param {import('../../types.js').notAppFormProcessingPipe} [param0.INSTRUCTIONS]
15
+ * @param {Array<Function>} [param0.AFTER_EXTRACT_TRANSFORMERS]
16
+ * @param {Object.<string, import('../../types.js').notAppFormEnvExtractor>} [param0.ENV_EXTRACTORS]
17
+ * @param {import('../../types.js').notAppFormRateLimiterOptions} [param0.rate]
11
18
  * @returns
12
19
  */
13
20
  module.exports = ({
@@ -16,15 +23,34 @@ module.exports = ({
16
23
  actionName = "_data",
17
24
  validators = [],
18
25
  afterExtract = async (input, req = null) => input || req,
26
+ EXTRACTORS = {},
27
+ ENV_EXTRACTORS = {},
28
+ TRANSFORMERS = {},
29
+ INSTRUCTIONS = undefined,
30
+ AFTER_EXTRACT_TRANSFORMERS = [],
31
+ rate = undefined,
19
32
  }) => {
20
33
  return class extends Form {
21
34
  /**
22
35
  *
23
36
  * @param {object} param0
24
37
  * @param {import('../../app')} param0.app
38
+ * @param {import('../../types.js').notAppConfigReader} param0.config
25
39
  */
26
- constructor({ app }) {
27
- super({ app, MODULE_NAME, MODEL_NAME, actionName });
40
+ constructor({ app, config }) {
41
+ super({
42
+ app,
43
+ config,
44
+ MODULE_NAME,
45
+ MODEL_NAME,
46
+ actionName,
47
+ EXTRACTORS,
48
+ ENV_EXTRACTORS,
49
+ TRANSFORMERS,
50
+ INSTRUCTIONS,
51
+ AFTER_EXTRACT_TRANSFORMERS,
52
+ rate,
53
+ });
28
54
  }
29
55
 
30
56
  extract(data) {
@@ -1,8 +1,10 @@
1
1
  const Form = require("../../form/form");
2
-
2
+ const {
3
+ DOCUMENT_OWNER_FIELD_NAME,
4
+ DOCUMENT_SESSION_FIELD_NAME,
5
+ } = require("../../auth/const");
3
6
  const notFilter = require("not-filter");
4
- const notAppIdentity = require("../../identity");
5
-
7
+ const FormExceptions = require("../../exceptions/form");
6
8
  const FIELDS = [
7
9
  ["query", `not-filter//_filterQuery`],
8
10
  ["identity", "not-node//identity"],
@@ -30,29 +32,41 @@ const FactoryFormList = ({ MODULE_NAME, MODEL_NAME, actionName = "list" }) => {
30
32
  }
31
33
 
32
34
  /**
33
- *
34
- *
35
+ * Adds owner id or session to query.filter
36
+ * @param {import('../../types').PreparedData} prepared
35
37
  * @param {import('../../types').notNodeExpressRequest} req
36
38
  * @return {Promise<import('../../types').PreparedData>}
37
39
  */
38
- async extract(req) {
39
- const envs = this.extractRequestEnvs(req);
40
- const user = notAppIdentity.extractAuthData(req);
41
- if (user.auth && !user.root && !user.admin) {
42
- if (!envs.query.filter) {
43
- envs.query.filter = notFilter.filter.createFilter();
44
- }
45
- envs.query.filter = notFilter.filter.modifyRules(
46
- envs.query.filter,
40
+ async afterExtract(prepared, req) {
41
+ prepared = await super.afterExtract(prepared, req);
42
+ if (!prepared.identity || !prepared.query) {
43
+ throw new FormExceptions.FormExceptionIdentityOrQueryIsUndefined(
44
+ this.FORM_NAME
45
+ );
46
+ }
47
+ if (!prepared.query.filter) {
48
+ prepared.query.filter = notFilter.filter.createANDFilter();
49
+ }
50
+ if (
51
+ prepared.identity.auth &&
52
+ !prepared.identity.root &&
53
+ !prepared.identity.admin
54
+ ) {
55
+ prepared.query.filter = notFilter.filter.modifyRules(
56
+ prepared.query.filter,
47
57
  {
48
- owner: user.uid,
58
+ [DOCUMENT_OWNER_FIELD_NAME]: prepared.identity.uid,
59
+ }
60
+ );
61
+ } else if (!prepared.identity.auth && prepared.identity.sid) {
62
+ prepared.query.filter = notFilter.filter.modifyRules(
63
+ prepared.query.filter,
64
+ {
65
+ [DOCUMENT_SESSION_FIELD_NAME]: prepared.identity.sid,
49
66
  }
50
67
  );
51
68
  }
52
-
53
- return {
54
- ...envs,
55
- };
69
+ return prepared;
56
70
  }
57
71
  };
58
72
  };
@@ -1,63 +1,8 @@
1
- const Form = require("../../form/form");
1
+ const FactoryFormList = require("./form.list");
2
2
 
3
- const notFilter = require("not-filter");
4
- const notAppIdentity = require("../../identity");
5
-
6
- const FIELDS = [
7
- ["query", `not-filter//_filterQuery`],
8
- ["identity", "not-node//identity"],
9
- ];
10
-
11
- /**
12
- * Generates generic form to get perform list and count action
13
- *
14
- * @param {object} params
15
- * @param {string} params.MODULE_NAME //module name
16
- * @param {string} params.MODEL_NAME //model name
17
- * @param {string} params.actionName //action name
18
- * @return {Form} form class definition
19
- */
20
- const FactoryFormListAndCount = ({
21
- MODULE_NAME,
22
- MODEL_NAME,
23
- actionName = "listAndCount",
24
- }) => {
25
- return class extends Form {
26
- constructor(params) {
27
- super({
28
- ...params,
29
- FIELDS,
30
- MODULE_NAME,
31
- MODEL_NAME,
32
- actionName,
33
- });
34
- }
35
-
36
- /**
37
- *
38
- *
39
- * @param {import('../../types').notNodeExpressRequest} req
40
- * @return {Promise<import('../../types').PreparedData>}
41
- */
42
- async extract(req) {
43
- const envs = this.extractRequestEnvs(req);
44
- const user = notAppIdentity.extractAuthData(req);
45
- if (user.auth && !user.root && !user.admin) {
46
- if (!envs.query.filter) {
47
- envs.query.filter = notFilter.filter.createFilter();
48
- }
49
- envs.query.filter = notFilter.filter.modifyRules(
50
- envs.query.filter,
51
- {
52
- owner: user.uid,
53
- }
54
- );
55
- }
56
- return {
57
- ...envs,
58
- };
59
- }
60
- };
3
+ module.exports = (params) => {
4
+ if (!params.actionName) {
5
+ params.actionName = "listAndCount";
6
+ }
7
+ return FactoryFormList(params);
61
8
  };
62
-
63
- module.exports = FactoryFormListAndCount;
@@ -0,0 +1,95 @@
1
+ const MIN_TASK_CHECK_INTERVAL = 3600;
2
+
3
+ class TaskRunner {
4
+ static #logger = console;
5
+ static #runEvery = 3600;
6
+ static #checkEvery = 3500; //every hour
7
+ static #int = setInterval(TaskRunner.#check, TaskRunner.#checkEvery * 1000);
8
+ static #tasks = [];
9
+
10
+ static setLogger(logger) {
11
+ TaskRunner.#logger = logger;
12
+ }
13
+
14
+ static #create(id, task, tag) {
15
+ return {
16
+ id,
17
+ task,
18
+ tag,
19
+ count: 0,
20
+ lastRunnedAt: -1,
21
+ };
22
+ }
23
+
24
+ static add(task, tag) {
25
+ const id = Math.random();
26
+ if (!tag) {
27
+ tag = `task#${TaskRunner.#tasks.length + 1}`;
28
+ }
29
+ TaskRunner.#tasks.push(TaskRunner.#create(id, task, tag));
30
+ }
31
+
32
+ static remove(id) {
33
+ const task = TaskRunner.#tasks.find((item) => item.id === id);
34
+ if (task) {
35
+ TaskRunner.#tasks.splice(TaskRunner.#tasks.indexOf(task), 1);
36
+ return true;
37
+ }
38
+ return false;
39
+ }
40
+
41
+ static clear() {
42
+ this.#tasks = [];
43
+ }
44
+
45
+ static async #check() {
46
+ try {
47
+ const runners = TaskRunner.#tasks
48
+ .filter(TaskRunner.#taskShouldBeRunned)
49
+ .map(TaskRunner.#taskToPromise);
50
+ await Promise.allSettled(runners);
51
+ } catch (e) {
52
+ TaskRunner.#logger.error("Task Set Failed", new Date(), e);
53
+ }
54
+ }
55
+
56
+ static async #taskToPromise(taskItem) {
57
+ const { tag } = taskItem;
58
+ try {
59
+ await taskItem.task();
60
+ taskItem.lastRunnedAt = Date.now();
61
+ taskItem.count += 1;
62
+ } catch (e) {
63
+ TaskRunner.#logger.error("Task Failed", tag, new Date(), e);
64
+ }
65
+ }
66
+
67
+ static #taskShouldBeRunned(taskItem) {
68
+ if (taskItem.count === 0) {
69
+ return true;
70
+ }
71
+ return taskItem.lastRunnedAt < Date.now() - TaskRunner.#runEvery;
72
+ }
73
+
74
+ static stop() {
75
+ clearInterval(TaskRunner.#int);
76
+ }
77
+
78
+ static start() {
79
+ TaskRunner.#int = setInterval(
80
+ TaskRunner.#check,
81
+ TaskRunner.#checkEvery * 1000
82
+ );
83
+ }
84
+
85
+ static setInterval(int = MIN_TASK_CHECK_INTERVAL) {
86
+ if (isNaN(int) || int < MIN_TASK_CHECK_INTERVAL) {
87
+ return false;
88
+ }
89
+ TaskRunner.#checkEvery = int;
90
+ TaskRunner.stop();
91
+ TaskRunner.start();
92
+ }
93
+ }
94
+
95
+ module.exports = TaskRunner;
package/.eslintignore DELETED
@@ -1,4 +0,0 @@
1
- /node_modules/**
2
- src/rollup.js
3
- src/repos.js
4
- src/lib.js