not-node 6.3.93 → 6.3.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 (45) hide show
  1. package/package.json +1 -1
  2. package/src/cli/actions/entity.mjs +3 -2
  3. package/src/cli/lib/entity.mjs +11 -2
  4. package/src/cli/lib/module.server.mjs +12 -2
  5. package/src/cli/readers/fields.mjs +4 -1
  6. package/src/cli/renderers/controllersCommons.mjs +21 -2
  7. package/src/common.js +21 -0
  8. package/src/core/fields/ID.js +1 -0
  9. package/src/core/fields/_id.js +3 -0
  10. package/src/core/fields/active.js +2 -1
  11. package/src/core/fields/boolean.js +2 -1
  12. package/src/core/fields/codeName.js +2 -1
  13. package/src/core/fields/createdAt.js +1 -4
  14. package/src/core/fields/default.js +1 -0
  15. package/src/core/fields/description.js +2 -1
  16. package/src/core/fields/email.js +2 -1
  17. package/src/core/fields/enabled.js +1 -0
  18. package/src/core/fields/expiredAt.js +1 -4
  19. package/src/core/fields/height.js +1 -0
  20. package/src/core/fields/identity.js +1 -4
  21. package/src/core/fields/ip.js +2 -1
  22. package/src/core/fields/objectId.js +2 -4
  23. package/src/core/fields/owner.js +9 -4
  24. package/src/core/fields/ownerModel.js +2 -5
  25. package/src/core/fields/price.js +1 -0
  26. package/src/core/fields/requiredObject.js +1 -4
  27. package/src/core/fields/session.js +2 -1
  28. package/src/core/fields/size.js +1 -0
  29. package/src/core/fields/telephone.js +2 -1
  30. package/src/core/fields/title.js +2 -5
  31. package/src/core/fields/updatedAt.js +1 -4
  32. package/src/core/fields/userId.js +1 -0
  33. package/src/core/fields/uuid.js +2 -1
  34. package/src/core/fields/width.js +1 -0
  35. package/src/core/safety.protocols.js +22 -0
  36. package/src/fields/filter.js +83 -4
  37. package/src/form/transformers/__CLEAR__.js +3 -0
  38. package/src/form/transformers/index.js +1 -0
  39. package/test/filter.js +95 -2
  40. package/tmpl/files/module.server/layers/controllers/common/crud.ejs +5 -4
  41. package/tmpl/files/module.server/layers/controllers/common/index.ejs +2 -1
  42. package/tmpl/files/module.server/layers/controllers/common/service.ejs +23 -0
  43. package/tmpl/files/module.server/layers/controllers/role/index.ejs +4 -1
  44. package/tmpl/files/notComponent.ejs +0 -57
  45. package/tmpl/files/notService.ejs +0 -39
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "not-node",
3
- "version": "6.3.93",
3
+ "version": "6.3.96",
4
4
  "description": "node complimentary part for client side notFramework.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -3,7 +3,7 @@ import { resolve } from "node:path";
3
3
  import { createEntity } from "../lib/entity.mjs";
4
4
  import Logger from "../lib/log.mjs";
5
5
  import { loadProjectConfig } from "../lib/project.mjs";
6
- import { getProjectSiteDir } from "../lib/fs.mjs";
6
+ import { getProjectSiteDir, findAllFields } from "../lib/fs.mjs";
7
7
 
8
8
  export default (program, { CWD }) => {
9
9
  program
@@ -27,11 +27,12 @@ export default (program, { CWD }) => {
27
27
  siteDir,
28
28
  infoFromManifest.serverModulesDir
29
29
  );
30
+ const allFields = await findAllFields(siteDir, modulesDir);
30
31
  console.log("creating server module in", modulesDir);
31
32
  const ProjectConfig = {
32
33
  path: opts.dir,
33
34
  ...infoFromManifest,
34
35
  };
35
- await createEntity(modulesDir, ProjectConfig);
36
+ await createEntity(modulesDir, ProjectConfig, allFields);
36
37
  });
37
38
  };
@@ -1,6 +1,9 @@
1
1
  import { firstLetterToLower } from "../../../src/common.js";
2
2
  import { resolve } from "node:path";
3
3
  import inquirer from "inquirer";
4
+ import inquirerPrompt from "inquirer-autocomplete-prompt";
5
+
6
+ inquirer.registerPrompt("autocomplete", inquirerPrompt);
4
7
  import * as Readers from "../readers/index.mjs";
5
8
  import * as Renderers from "../renderers/index.mjs";
6
9
  import { renderFile, createDir } from "./fs.mjs";
@@ -33,12 +36,18 @@ async function renderEntityFiles(module_src_dir, data, config) {
33
36
  }
34
37
  }
35
38
 
36
- async function createEntity(modules_dir, config) {
39
+ async function createEntity(modules_dir, config, availableFields) {
37
40
  const ModuleName = await Readers.ModuleName(inquirer);
38
41
  const moduleName = firstLetterToLower(ModuleName);
39
42
  const moduleDir = resolve(modules_dir, ModuleName);
40
43
  const moduleLayers = await Readers.moduleLayers(inquirer);
41
- const moduleConfig = { ...config, moduleName, ModuleName, moduleLayers };
44
+ const moduleConfig = {
45
+ ...config,
46
+ moduleName,
47
+ ModuleName,
48
+ moduleLayers,
49
+ availableFields,
50
+ };
42
51
  // console.log("moduleConfig", moduleConfig);
43
52
  const entityData = await Readers.entityData(
44
53
  inquirer,
@@ -1,4 +1,7 @@
1
- import { firstLetterToLower } from "../../../src/common.js";
1
+ import {
2
+ firstLetterToLower,
3
+ moduleNameTransformer,
4
+ } from "../../../src/common.js";
2
5
  import { join } from "node:path";
3
6
  import inquirer from "inquirer";
4
7
  import inquirerPrompt from "inquirer-autocomplete-prompt";
@@ -75,9 +78,16 @@ async function renderServerContollersIndexes(
75
78
  async function createServerModule(modules_dir, config, availableFields) {
76
79
  //read module name
77
80
  const ModuleName = await Readers.ModuleName(inquirer);
81
+ const ModuleNameHumanReadable = moduleNameTransformer(ModuleName);
78
82
  const moduleName = firstLetterToLower(ModuleName);
79
83
  const moduleDir = join(modules_dir, ModuleName);
80
- const moduleConfig = { ...config, moduleName, ModuleName, availableFields };
84
+ const moduleConfig = {
85
+ ...config,
86
+ moduleName,
87
+ ModuleName,
88
+ ModuleNameHumanReadable,
89
+ availableFields,
90
+ };
81
91
  await createDir(moduleDir);
82
92
  //console.log(JSON.stringify(moduleConfig, null, 4));
83
93
  await createDirContent(
@@ -57,12 +57,15 @@ export default async (inquirer, config) => {
57
57
  fieldname = answer.fieldname.trim();
58
58
  });
59
59
  result.push([fieldname, fieldtype]);
60
+ const selectedFields = result.map(
61
+ (itm) => `${itm[1]} as ${itm[0]}`
62
+ );
60
63
  finished = await inquirer
61
64
  .prompt([
62
65
  {
63
66
  type: "confirm",
64
67
  name: "oneMore",
65
- message: `Add another one field to [${result.join(
68
+ message: `Add another one field to [${selectedFields.join(
66
69
  ","
67
70
  )}] (default: true)?`,
68
71
  default: true,
@@ -7,8 +7,8 @@ export default async (
7
7
  config,
8
8
  createFileContent,
9
9
  PATH_TMPL
10
- ) => {
11
- for (let entityData of entitiesList) {
10
+ ) => {
11
+ for (let entityData of entitiesList) {
12
12
  const TMPL_FILE_PATH = resolve(PATH_TMPL, TEMPLATES_DIR, `crud.ejs`);
13
13
  const DEST_FILE_PATH = resolve(
14
14
  module_layer_dir,
@@ -21,6 +21,7 @@ export default async (
21
21
  }
22
22
 
23
23
  if (entitiesList.length) {
24
+ //common validators
24
25
  const TMPL_FILE_PATH_VALIDATORS = resolve(
25
26
  PATH_TMPL,
26
27
  TEMPLATES_DIR,
@@ -38,5 +39,23 @@ export default async (
38
39
  ...entitiesList[0],
39
40
  }
40
41
  );
42
+ //common service
43
+ const TMPL_FILE_PATH_COMMON_SERVICE = resolve(
44
+ PATH_TMPL,
45
+ TEMPLATES_DIR,
46
+ `service.ejs`
47
+ );
48
+ const DEST_FILE_PATH_COMMON_SERVICE = resolve(
49
+ module_layer_dir,
50
+ `ns${config.ModuleNameHumanReadable}Common.js`
51
+ );
52
+ await createFileContent(
53
+ TMPL_FILE_PATH_COMMON_SERVICE,
54
+ DEST_FILE_PATH_COMMON_SERVICE,
55
+ {
56
+ ...config,
57
+ ...entitiesList[0],
58
+ }
59
+ );
41
60
  }
42
61
  };
package/src/common.js CHANGED
@@ -23,6 +23,27 @@ module.exports.firstLetterToUpper = function (string) {
23
23
  return string.charAt(0).toUpperCase() + string.slice(1);
24
24
  };
25
25
 
26
+ /**
27
+ * transforms not-module-name -> ModuleName
28
+ * @param {string} moduleName
29
+ * @return {string}
30
+ */
31
+ function moduleNameTransformer(moduleName) {
32
+ //not-module-name -> [not,module,name]
33
+ const ModuleNameParts = moduleName.split("-");
34
+ //[not,module,name] -> [module,name]
35
+ const moduleNameSelectedParts =
36
+ ModuleNameParts[0] === "not"
37
+ ? ModuleNameParts.splice(1)
38
+ : ModuleNameParts;
39
+ //[module,name] -> ModuleName
40
+ return moduleNameSelectedParts
41
+ .map(module.exports.firstLetterToUpper)
42
+ .join("");
43
+ }
44
+
45
+ module.exports.moduleNameTransformer = moduleNameTransformer;
46
+
26
47
  /**
27
48
  * Validates if string is a ObjectId
28
49
  * @param {string|import('mongoose').Schema.Types.ObjectId} id ObjectId string to validate
@@ -8,5 +8,6 @@ module.exports = {
8
8
  model: {
9
9
  type: Number,
10
10
  required: true,
11
+ safe: require("../safety.protocols").ownerRootAdmin,
11
12
  },
12
13
  };
@@ -5,4 +5,7 @@ module.exports = {
5
5
  label: "_id",
6
6
  readonly: true,
7
7
  },
8
+ model: {
9
+ safe: require("../safety.protocols").systemManageable,
10
+ },
8
11
  };
@@ -6,6 +6,7 @@ module.exports = {
6
6
  model: {
7
7
  type: Boolean,
8
8
  default: false,
9
- required: true
9
+ required: true,
10
+ safe: require("../safety.protocols").ownerRootAdmin,
10
11
  },
11
12
  };
@@ -6,6 +6,7 @@ module.exports = {
6
6
  model: {
7
7
  type: Boolean,
8
8
  default: false,
9
- required: true
9
+ required: true,
10
+ safe: require("../safety.protocols").ownerRootAdmin,
10
11
  },
11
12
  };
@@ -7,6 +7,7 @@ module.exports = {
7
7
  model: {
8
8
  type: String,
9
9
  required: true,
10
- transformers: ['xss']
10
+ transformers: ["xss"],
11
+ safe: require("../safety.protocols").ownerRootAdmin,
11
12
  },
12
13
  };
@@ -11,9 +11,6 @@ module.exports = {
11
11
  default: Date.now,
12
12
  searchable: true,
13
13
  sortable: true,
14
- safe: {
15
- create: ["@system"],
16
- read: ["@owner", "root", "admin"],
17
- },
14
+ safe: require("../safety.protocols").systemManageable,
18
15
  },
19
16
  };
@@ -7,5 +7,6 @@ module.exports = {
7
7
  type: Boolean,
8
8
  default: false,
9
9
  required: true,
10
+ safe: require("../safety.protocols").ownerRootAdmin,
10
11
  },
11
12
  };
@@ -9,6 +9,7 @@ module.exports = {
9
9
  required: true,
10
10
  searchable: true,
11
11
  sortable: true,
12
- transformers: ['xss']
12
+ transformers: ["xss"],
13
+ safe: require("../safety.protocols").ownerRootAdmin,
13
14
  },
14
15
  };
@@ -7,6 +7,7 @@ module.exports = {
7
7
  model: {
8
8
  type: String,
9
9
  required: true,
10
- transformers: ['xss']
10
+ transformers: ["xss"],
11
+ safe: require("../safety.protocols").ownerRootAdmin,
11
12
  },
12
13
  };
@@ -7,5 +7,6 @@ module.exports = {
7
7
  type: Boolean,
8
8
  default: true,
9
9
  required: true,
10
+ safe: require("../safety.protocols").ownerRootAdmin,
10
11
  },
11
12
  };
@@ -10,9 +10,6 @@ module.exports = {
10
10
  required: false,
11
11
  searchable: true,
12
12
  sortable: true,
13
- safe: {
14
- update: ["@owner", "root", "admin"],
15
- read: ["@owner", "root", "admin"],
16
- },
13
+ safe: require("../safety.protocols").ownerRootAdmin,
17
14
  },
18
15
  };
@@ -9,5 +9,6 @@ module.exports = {
9
9
  required: true,
10
10
  searchable: true,
11
11
  sortable: true,
12
+ safe: require("../safety.protocols").ownerRootAdmin,
12
13
  },
13
14
  };
@@ -4,9 +4,6 @@ module.exports = {
4
4
  model: {
5
5
  type: Schema.Types.Mixed,
6
6
  required: true,
7
- safe: {
8
- update: ["@owner", "root", "admin"],
9
- read: ["@owner", "root", "admin"],
10
- },
7
+ safe: require("../safety.protocols").ownerRootAdmin,
11
8
  },
12
9
  };
@@ -8,6 +8,7 @@ module.exports = {
8
8
  type: String,
9
9
  searchable: true,
10
10
  required: true,
11
- transformers: ['xss']
11
+ safe: require("../safety.protocols").ownerRootAdmin,
12
+ transformers: ["xss"],
12
13
  },
13
14
  };
@@ -5,9 +5,7 @@ module.exports = {
5
5
  type: ObjectId,
6
6
  required: true,
7
7
  default: {},
8
- safe: {
9
- update: ["@owner", "root", "admin"],
10
- read: ["@owner", "root", "admin"],
11
- },
8
+ transformers: ["xss", "__CLEAR__"],
9
+ safe: require("../safety.protocols").ownerRootAdmin,
12
10
  },
13
11
  };
@@ -1,13 +1,18 @@
1
1
  const Schema = require("mongoose").Schema;
2
+ const notFieldsFilter = require("../../fields/filter");
3
+ const { ownerRootAdmin } = require("../safety.protocols");
4
+ const { ACTION_SIGNATURES } = require("../../auth/const");
5
+
2
6
  module.exports = {
3
7
  model: {
4
8
  type: Schema.Types.ObjectId,
5
9
  refPath: "ownerModel",
6
10
  required: false,
7
- safe: {
8
- update: ["root", "admin"],
9
- read: ["@owner", "root", "admin"],
10
- },
11
+ safe: notFieldsFilter.mergeSafetyProtocols(ownerRootAdmin, {
12
+ [ACTION_SIGNATURES.CREATE]: ["-@owner"],
13
+ [ACTION_SIGNATURES.UPDATE]: ["-@owner"],
14
+ [ACTION_SIGNATURES.DELETE]: ["-@owner"],
15
+ }),
11
16
  },
12
17
  ui: {
13
18
  component: "UIHidden",
@@ -2,11 +2,8 @@ module.exports = {
2
2
  model: {
3
3
  type: String,
4
4
  required: false,
5
- safe: {
6
- update: ["@owner", "root", "admin"],
7
- read: ["@owner", "root", "admin"],
8
- },
9
- transformers: ['xss']
5
+ safe: require("../safety.protocols").ownerRootAdmin,
6
+ transformers: ["xss"],
10
7
  },
11
8
  ui: {
12
9
  component: "UIHidden",
@@ -9,5 +9,6 @@ module.exports = {
9
9
  required: true,
10
10
  searchable: true,
11
11
  sortable: true,
12
+ safe: require("../safety.protocols").ownerRootAdmin,
12
13
  },
13
14
  };
@@ -5,9 +5,6 @@ module.exports = {
5
5
  type: Schema.Types.Mixed,
6
6
  required: true,
7
7
  default: {},
8
- safe: {
9
- update: ["@owner", "root", "admin"],
10
- read: ["@owner", "root", "admin"],
11
- },
8
+ safe: require("../safety.protocols").ownerRootAdmin,
12
9
  },
13
10
  };
@@ -8,6 +8,7 @@ module.exports = {
8
8
  type: String,
9
9
  searchable: true,
10
10
  required: true,
11
- transformers: ['xss']
11
+ transformers: ["xss"],
12
+ safe: require("../safety.protocols").ownerRootAdmin,
12
13
  },
13
14
  };
@@ -9,5 +9,6 @@ module.exports = {
9
9
  required: true,
10
10
  searchable: true,
11
11
  sortable: true,
12
+ safe: require("../safety.protocols").ownerRootAdmin,
12
13
  },
13
14
  };
@@ -7,6 +7,7 @@ module.exports = {
7
7
  model: {
8
8
  type: String,
9
9
  required: true,
10
- transformers: ['xss']
10
+ transformers: ["xss"],
11
+ safe: require("../safety.protocols").ownerRootAdmin,
11
12
  },
12
13
  };
@@ -9,10 +9,7 @@ module.exports = {
9
9
  required: true,
10
10
  searchable: true,
11
11
  sortable: true,
12
- safe: {
13
- update: ["@owner", "root", "admin"],
14
- read: ["@owner", "root", "admin"],
15
- },
16
- transformers: ['xss']
12
+ safe: require("../safety.protocols").ownerRootAdmin,
13
+ transformers: ["xss"],
17
14
  },
18
15
  };
@@ -11,9 +11,6 @@ module.exports = {
11
11
  type: Date,
12
12
  required: true,
13
13
  default: Date.now,
14
- safe: {
15
- update: ["@owner", "root", "admin"],
16
- read: ["@owner", "root", "admin"],
17
- },
14
+ safe: require("../safety.protocols").ownerRootAdmin,
18
15
  },
19
16
  };
@@ -10,5 +10,6 @@ module.exports = {
10
10
  type: Schema.Types.ObjectId,
11
11
  ref: "User",
12
12
  required: false,
13
+ safe: require("../safety.protocols").ownerRootAdmin,
13
14
  },
14
15
  };
@@ -9,6 +9,7 @@ module.exports = {
9
9
  type: String,
10
10
  searchable: true,
11
11
  required: true,
12
- transformers: ['xss']
12
+ transformers: ["xss"],
13
+ safe: require("../safety.protocols").ownerRootAdmin,
13
14
  },
14
15
  };
@@ -9,5 +9,6 @@ module.exports = {
9
9
  required: true,
10
10
  searchable: true,
11
11
  sortable: true,
12
+ safe: require("../safety.protocols").ownerRootAdmin,
12
13
  },
13
14
  };
@@ -0,0 +1,22 @@
1
+ const { ACTION_SIGNATURES } = require("../auth/const");
2
+
3
+ module.exports.ownerRootAdmin = Object.freeze({
4
+ [ACTION_SIGNATURES.CREATE]: ["@owner", "root", "admin"],
5
+ [ACTION_SIGNATURES.READ]: ["@owner", "root", "admin"],
6
+ [ACTION_SIGNATURES.UPDATE]: ["@owner", "root", "admin"],
7
+ [ACTION_SIGNATURES.DELETE]: ["@owner", "root", "admin"],
8
+ });
9
+
10
+ module.exports.systemManageable = Object.freeze({
11
+ [ACTION_SIGNATURES.CREATE]: ["@system"],
12
+ [ACTION_SIGNATURES.READ]: ["@system", "@owner", "root", "admin"],
13
+ [ACTION_SIGNATURES.UPDATE]: ["@system"],
14
+ [ACTION_SIGNATURES.DELETE]: ["@system"],
15
+ });
16
+
17
+ module.exports.publicReadable = Object.freeze({
18
+ [ACTION_SIGNATURES.CREATE]: [],
19
+ [ACTION_SIGNATURES.READ]: ["@*"],
20
+ [ACTION_SIGNATURES.UPDATE]: [],
21
+ [ACTION_SIGNATURES.DELETE]: [],
22
+ });
@@ -5,7 +5,10 @@ const {
5
5
  isNotEmptyString,
6
6
  } = require("../common");
7
7
  const { getSafeFieldsForRoleAction } = require("../auth/fields");
8
- const { DEFAULT_USER_ROLE_FOR_GUEST } = require("../auth/const");
8
+ const {
9
+ DEFAULT_USER_ROLE_FOR_GUEST,
10
+ ACTION_SIGNATURES,
11
+ } = require("../auth/const");
9
12
  /**
10
13
  * notFieldsFilter.filter(fields, getApp().getModelSchema(MODEL_NAME), {action});
11
14
  *
@@ -125,9 +128,14 @@ class notFieldsFilter {
125
128
  system
126
129
  );
127
130
  },
128
- [SPECIAL_SET_UNSAFE]: ["salt", "password"],
131
+ [SPECIAL_SET_UNSAFE]: ["salt", "password", "session"],
129
132
  [SPECIAL_SET_TIMESTAMPS]: ["createdAt", "updatedAt"],
130
- [SPECIAL_SET_OWNAGE]: ["owner", "ownerId", "ownerModel"],
133
+ [SPECIAL_SET_OWNAGE]: (schema) => {
134
+ const inSchema = Object.keys(schema);
135
+ return ["owner", "ownerId", "ownerModel"].filter((itm) =>
136
+ inSchema.includes(itm)
137
+ );
138
+ },
131
139
  [SPECIAL_SET_VERSIONING]: [
132
140
  "__version",
133
141
  "__versions",
@@ -302,6 +310,10 @@ class notFieldsFilter {
302
310
  return result;
303
311
  }
304
312
 
313
+ static clearFromDuplicated(fields) {
314
+ return [...new Set(fields)];
315
+ }
316
+
305
317
  /**
306
318
  * Creates plain fields list from fields list with fields, synonyms, fields sets
307
319
  * and exlude operations
@@ -320,7 +332,74 @@ class notFieldsFilter {
320
332
  static filter(fieldsSet, schema = {}, mods = { action: undefined }) {
321
333
  const fields = [...fieldsSet];
322
334
  this.specialsToPlain(fields, schema, mods);
323
- return this.removeExcludedFields(fields);
335
+ return this.clearFromDuplicated(this.removeExcludedFields(fields));
336
+ }
337
+
338
+ /**
339
+ *
340
+ *
341
+ * @static
342
+ * @param {Object} base
343
+ * @param {Object} addition
344
+ * @return {Object}
345
+ * @memberof notFieldsFilter
346
+ */
347
+ static mergeSafetyProtocols(base, addition) {
348
+ const result = {
349
+ [ACTION_SIGNATURES.CREATE]: [
350
+ ...(base[ACTION_SIGNATURES.CREATE] || []),
351
+ ],
352
+ [ACTION_SIGNATURES.READ]: [...(base[ACTION_SIGNATURES.READ] || [])],
353
+ [ACTION_SIGNATURES.UPDATE]: [
354
+ ...(base[ACTION_SIGNATURES.UPDATE] || []),
355
+ ],
356
+ [ACTION_SIGNATURES.DELETE]: [
357
+ ...(base[ACTION_SIGNATURES.DELETE] || []),
358
+ ],
359
+ };
360
+ for (const type of Object.keys(addition)) {
361
+ if (Array.isArray(addition[type])) {
362
+ addition[type].forEach((rule) => {
363
+ if (this.isExcludeOperation(rule)) {
364
+ const ruleToDelete = this.unmarkFieldToExlude(rule);
365
+ if (result[type].includes(ruleToDelete)) {
366
+ result[type].splice(
367
+ result[type].indexOf(ruleToDelete),
368
+ 1
369
+ );
370
+ }
371
+ } else {
372
+ if (!result[type].includes(rule)) {
373
+ result[type].push(rule);
374
+ }
375
+ }
376
+ });
377
+ }
378
+ }
379
+ return Object.freeze(result);
380
+ }
381
+
382
+ static initSafetyProtocol(
383
+ create = [],
384
+ read = [],
385
+ update = [],
386
+ del = [],
387
+ all = []
388
+ ) {
389
+ return this.mergeSafetyProtocols(
390
+ {
391
+ [ACTION_SIGNATURES.CREATE]: [...all],
392
+ [ACTION_SIGNATURES.READ]: [...all],
393
+ [ACTION_SIGNATURES.UPDATE]: [...all],
394
+ [ACTION_SIGNATURES.DELETE]: [...all],
395
+ },
396
+ {
397
+ [ACTION_SIGNATURES.CREATE]: [...create],
398
+ [ACTION_SIGNATURES.READ]: [...read],
399
+ [ACTION_SIGNATURES.UPDATE]: [...update],
400
+ [ACTION_SIGNATURES.DELETE]: [...del],
401
+ }
402
+ );
324
403
  }
325
404
  }
326
405
 
@@ -0,0 +1,3 @@
1
+ module.exports = (input) => {
2
+ return input === "__CLEAR__" ? undefined : input;
3
+ };
@@ -6,4 +6,5 @@ module.exports = {
6
6
  stringToJSON: require("./stringToJSON.js"),
7
7
  xss: require("./xss.js"),
8
8
  boolean: require("./boolean.js"),
9
+ __CLEAR__: require("./__CLEAR__.js"),
9
10
  };
package/test/filter.js CHANGED
@@ -1,7 +1,9 @@
1
1
  const mongoose = require("mongoose");
2
2
  const Schema = mongoose.Schema;
3
3
  const expect = require("chai").expect,
4
- notFieldsFilter = require("../src/fields/filter");
4
+ notFieldsFilter = require("../src/fields/filter"),
5
+ { ACTION_SIGNATURES } = require("../src/auth/const"),
6
+ safetyProtocols = require("../src/core/safety.protocols");
5
7
 
6
8
  const SCHEMA = () => {
7
9
  return {
@@ -277,10 +279,101 @@ describe("Fields/notFieldsFilter", function () {
277
279
  expect(result).to.be.deep.equal([
278
280
  "id",
279
281
  "name",
280
- "name",
281
282
  "username",
282
283
  "country",
283
284
  ]);
284
285
  });
285
286
  });
287
+
288
+ describe("mergeSafetyProtocols", () => {
289
+ it("ownerRootAdmin + publicReadable", () => {
290
+ const result = notFieldsFilter.mergeSafetyProtocols(
291
+ safetyProtocols.ownerRootAdmin,
292
+ safetyProtocols.publicReadable
293
+ );
294
+ expect(result).to.be.deep.equal({
295
+ [ACTION_SIGNATURES.CREATE]: ["@owner", "root", "admin"],
296
+ [ACTION_SIGNATURES.READ]: ["@owner", "root", "admin", "@*"],
297
+ [ACTION_SIGNATURES.UPDATE]: ["@owner", "root", "admin"],
298
+ [ACTION_SIGNATURES.DELETE]: ["@owner", "root", "admin"],
299
+ });
300
+ });
301
+
302
+ it("ownerRootAdmin - @owner", () => {
303
+ const result = notFieldsFilter.mergeSafetyProtocols(
304
+ safetyProtocols.ownerRootAdmin,
305
+ {
306
+ [ACTION_SIGNATURES.CREATE]: ["-@owner"],
307
+ [ACTION_SIGNATURES.READ]: ["-@owner"],
308
+ [ACTION_SIGNATURES.UPDATE]: ["-@owner"],
309
+ [ACTION_SIGNATURES.DELETE]: ["-@owner"],
310
+ }
311
+ );
312
+ expect(result).to.be.deep.equal({
313
+ [ACTION_SIGNATURES.CREATE]: ["root", "admin"],
314
+ [ACTION_SIGNATURES.READ]: ["root", "admin"],
315
+ [ACTION_SIGNATURES.UPDATE]: ["root", "admin"],
316
+ [ACTION_SIGNATURES.DELETE]: ["root", "admin"],
317
+ });
318
+ });
319
+ });
320
+
321
+ describe("initSafetyProtocol", () => {
322
+ it("empty", () => {
323
+ const result = notFieldsFilter.initSafetyProtocol();
324
+ expect(result).to.be.deep.equal({
325
+ [ACTION_SIGNATURES.CREATE]: [],
326
+ [ACTION_SIGNATURES.READ]: [],
327
+ [ACTION_SIGNATURES.UPDATE]: [],
328
+ [ACTION_SIGNATURES.DELETE]: [],
329
+ });
330
+ });
331
+
332
+ it("all = user", () => {
333
+ const result = notFieldsFilter.initSafetyProtocol(
334
+ undefined,
335
+ undefined,
336
+ undefined,
337
+ undefined,
338
+ ["user"]
339
+ );
340
+ expect(result).to.be.deep.equal({
341
+ [ACTION_SIGNATURES.CREATE]: ["user"],
342
+ [ACTION_SIGNATURES.READ]: ["user"],
343
+ [ACTION_SIGNATURES.UPDATE]: ["user"],
344
+ [ACTION_SIGNATURES.DELETE]: ["user"],
345
+ });
346
+ });
347
+
348
+ it("CRUD - @owner", () => {
349
+ const result = notFieldsFilter.initSafetyProtocol(
350
+ ["@owner"],
351
+ ["@owner"],
352
+ ["@owner"],
353
+ ["@owner"]
354
+ );
355
+ expect(result).to.be.deep.equal({
356
+ [ACTION_SIGNATURES.CREATE]: ["@owner"],
357
+ [ACTION_SIGNATURES.READ]: ["@owner"],
358
+ [ACTION_SIGNATURES.UPDATE]: ["@owner"],
359
+ [ACTION_SIGNATURES.DELETE]: ["@owner"],
360
+ });
361
+ });
362
+
363
+ it("D - -@owner, ALL - @owner, root, admin", () => {
364
+ const result = notFieldsFilter.initSafetyProtocol(
365
+ undefined,
366
+ undefined,
367
+ undefined,
368
+ ["-@owner"],
369
+ ["@owner", "root", "admin"]
370
+ );
371
+ expect(result).to.be.deep.equal({
372
+ [ACTION_SIGNATURES.CREATE]: ["@owner", "root", "admin"],
373
+ [ACTION_SIGNATURES.READ]: ["@owner", "root", "admin"],
374
+ [ACTION_SIGNATURES.UPDATE]: ["@owner", "root", "admin"],
375
+ [ACTION_SIGNATURES.DELETE]: ["root", "admin"],
376
+ });
377
+ });
378
+ });
286
379
  });
@@ -1,15 +1,16 @@
1
1
  import { MODULE_NAME } from "../../const.js";
2
2
  import Validators from "../common/validators.js";
3
- import { Frame } from "not-bulma";
3
+ import { Frame, notCommon } from "not-bulma";
4
4
  import CRUDActionList from "not-bulma/src/frame/crud/actions/list";
5
5
 
6
6
  const { notCRUD } = Frame;
7
7
 
8
8
  const MODEL_NAME = "<%- ModelName %>";
9
+ const modelName = notCommon.lowerFirstLetter(MODEL_NAME);
9
10
 
10
11
  const LABELS = {
11
- plural: `${MODULE_NAME}:${MODEL_NAME}_label_plural`,
12
- single: `${MODULE_NAME}:${MODEL_NAME}_label_single`,
12
+ plural: `${MODULE_NAME}:${modelName}_label_plural`,
13
+ single: `${MODULE_NAME}:${modelName}_label_single`,
13
14
  };
14
15
 
15
16
  Object.freeze(LABELS);
@@ -32,7 +33,7 @@ class nc<%- ModelName %>Common extends notCRUD {
32
33
  this.setModuleName(MODULE_NAME);
33
34
  this.setModelName(MODEL_NAME);
34
35
  this.setOptions("names", LABELS);
35
- this.setOptions("Validators", Validators);
36
+ this.setValidators(Validators);
36
37
  this.setOptions("params", params);
37
38
  this.setOptions("list", {
38
39
  interface: {
@@ -1,4 +1,5 @@
1
1
  import main from "../common/ws.client.main.js";
2
+ import ns<%- ModuleNameHumanReadable %>Common from "./ns<%- ModuleNameHumanReadable %>Common.js";
2
3
 
3
4
  <% for (let {ModelName} of entities){ %>
4
5
  import nc<%- {ModelName} %> from "./nc<%- {ModelName} %>.js";
@@ -10,7 +11,7 @@ const wsc = {
10
11
 
11
12
  const uis = {};
12
13
 
13
- const services = {};
14
+ const services = {ns<%- ModuleNameHumanReadable %>Common};
14
15
 
15
16
  let manifest = {
16
17
  router: {
@@ -0,0 +1,23 @@
1
+ import { Builder } from "not-validation";
2
+ import Validator from "validator";
3
+
4
+ export default class ns<%- ModuleNameHumanReadable %>Common {
5
+ constructor(app) {
6
+ this.app = app;
7
+ }
8
+
9
+ destroy() {
10
+ delete this.app;
11
+ }
12
+
13
+ augmentValidators(validators) {
14
+ return Builder(validators, () => this.getValidatorEnv());
15
+ }
16
+
17
+ getValidatorEnv() {
18
+ return {
19
+ config: this.app.getConfigReaderForModule("<%- moduleName %>"),
20
+ validator: Validator,
21
+ };
22
+ }
23
+ }
@@ -1,10 +1,13 @@
1
+ import ns<%- ModuleNameHumanReadable %>Common from "../common/ns<%- ModuleNameHumanReadable %>Common.js";
1
2
  <% for (let {ModelName} of entities){ %>
2
3
  import nc<%- ModelName %> from "./nc<%- ModelName %>.js";
3
4
  <% } %>
4
5
 
5
6
  const wsc = {};
6
7
  const uis = {};
7
- const services = {};
8
+ const services = {
9
+ ns<%- ModuleNameHumanReadable %>Common
10
+ };
8
11
 
9
12
  let manifest = {
10
13
  router: {
@@ -1,57 +0,0 @@
1
- import UI<%- ComponentName %> from "./<%- componentName %>.svelte";
2
-
3
- class not<%- ComponentName %> extends notBase{
4
-
5
- static UIConstructor = UI<%- ComponentName %>;
6
-
7
- constructor({
8
- target = null,
9
- name = "Default",
10
- options = {},
11
- working = {},
12
- data = {},
13
- }){
14
- super({
15
- working: {
16
- name: `${name}<%- ComponentName %>`,
17
- ...working,
18
- },
19
- options,
20
- data,
21
- });
22
- if (target) {
23
- this.setOptions("target", target);
24
- }
25
- this.render();
26
- }
27
-
28
- render(){
29
- this.remove();
30
- if(this.UIConstructor){
31
- this.ui = new this.UIConstructor({
32
- target: this.getOptions('target'),
33
- props:{
34
- /* props */
35
- }
36
- });
37
- }
38
- }
39
-
40
- update(){
41
- if(this.ui){
42
- this.ui.$set({ /* update props */ });
43
- }
44
- }
45
-
46
- remove(){
47
- if (this.ui) {
48
- this.ui.$destroy();
49
- this.ui = null;
50
- }
51
- return this;
52
- }
53
-
54
- }
55
-
56
- export default not<%- ComponentName %>;
57
-
@@ -1,39 +0,0 @@
1
- const INTERVAL = 360;
2
- const INIT_UPDATE_DELAY = 5;
3
-
4
- class ns<%- ServiceName %> {
5
- #INTERVAL = INTERVAL;
6
- #INIT_UPDATE_DELAY = INIT_UPDATE_DELAY;
7
-
8
- constructor(app) {
9
- this.app = app;
10
- <% if(modelName){ %>
11
- this.interface = this.app.getInterface("<%- modelName %>"");
12
- if(this.interface){
13
- this.init();
14
- }else{
15
- app.error('no network interface');
16
- }
17
- <% }else{ %>
18
- this.init();
19
- <% } %>
20
- };
21
-
22
- init() {
23
- setTimeout(this.update.bind(this), this.#INIT_UPDATE_DELAY * 100);
24
- this.int = setInterval(this.update.bind(this), this.#INTERVAL * 1000);
25
- window.addEventListener('unload', () => {
26
- clearInterval(this.int);
27
- delete this.app;
28
- <% if(modelName){ %>
29
- delete this.interface;
30
- <% } %>
31
- });
32
- }
33
-
34
- update() {
35
- //serve
36
- }}
37
-
38
-
39
- export default ns<%- ServiceName %>;