not-node 6.3.31 → 6.3.33

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.
@@ -0,0 +1 @@
1
+ *.ejs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "not-node",
3
- "version": "6.3.31",
3
+ "version": "6.3.33",
4
4
  "description": "node complimentary part for client side notFramework.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -87,8 +87,8 @@ module.exports = ({
87
87
 
88
88
  const createDefaultForm = function ({ actionName, MODULE_NAME }) {
89
89
  const FIELDS = [
90
- ["identity", "not-node//requiredObject"],
91
- ["data", `${MODULE_NAME}//_data`],
90
+ ["identity", "not-node//identity"],
91
+ ["data", `${MODULE_NAME}//_${MODEL_NAME}`],
92
92
  ];
93
93
  const FORM_NAME = `${MODULE_NAME}:${firstLetterToUpper(
94
94
  actionName
@@ -3,6 +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
7
 
7
8
  export default (program, { CWD }) => {
8
9
  program
@@ -10,14 +11,17 @@ export default (program, { CWD }) => {
10
11
  .addOption(
11
12
  new Option("-v, --verbose").default(false, "extensive output")
12
13
  )
14
+ .addOption(
15
+ new Option("-d, --dir <dir>").default("", "project site directory")
16
+ )
13
17
  .description("adds entity to existing module of project")
14
18
  .action(async (opts) => {
15
- console.log(CWD);
16
- const siteDir = resolve(CWD, "./site");
19
+ console.log(CWD, opts);
20
+ const siteDir = getProjectSiteDir(opts.dir, CWD);
21
+ console.log("project in", siteDir);
17
22
  if (opts.v) {
18
23
  Logger.setSilent(false);
19
24
  }
20
- console.log("project in", opts.dir);
21
25
  const infoFromManifest = await loadProjectConfig(siteDir);
22
26
  const modulesDir = resolve(
23
27
  siteDir,
@@ -22,6 +22,15 @@ async function renderEntityFiles(module_src_dir, data, config) {
22
22
  console.error("No renderer for layer: ", layerName);
23
23
  }
24
24
  }
25
+ if (data.layers.includes("controllers") && Renderers.controllersCommons) {
26
+ Renderers.controllersCommons(
27
+ resolve(module_src_dir, `./controllers/common`),
28
+ [data],
29
+ config,
30
+ renderFile,
31
+ Options.PATH_TMPL
32
+ );
33
+ }
25
34
  }
26
35
 
27
36
  async function createEntity(modules_dir, config) {
@@ -30,12 +39,13 @@ async function createEntity(modules_dir, config) {
30
39
  const moduleDir = resolve(modules_dir, ModuleName);
31
40
  const moduleLayers = await Readers.moduleLayers(inquirer);
32
41
  const moduleConfig = { ...config, moduleName, ModuleName, moduleLayers };
33
- console.log();
42
+ console.log("moduleConfig", moduleConfig);
34
43
  const entityData = await Readers.entityData(
35
44
  inquirer,
36
45
  moduleConfig,
37
46
  moduleConfig.moduleLayers
38
47
  );
48
+ console.log("entityData", entityData);
39
49
  await renderEntityFiles(
40
50
  resolve(moduleDir, "./src"),
41
51
  entityData,
@@ -54,6 +54,22 @@ async function copyTmplFile(from, to) {
54
54
  }
55
55
  }
56
56
 
57
+ function getProjectSiteDir(dir, CWD) {
58
+ if (dir === "") {
59
+ return resolve(CWD, "./site");
60
+ } else {
61
+ if (
62
+ (dir.indexOf("/") > -1 || dir.indexOf("\\") > -1) &&
63
+ dir !== "./" &&
64
+ dir !== ".\\"
65
+ ) {
66
+ return dir;
67
+ } else {
68
+ return resolve(CWD, dir);
69
+ }
70
+ }
71
+ }
72
+
57
73
  async function createDir(dirPath) {
58
74
  try {
59
75
  //console.log("mkdir", dirPath);
@@ -173,4 +189,5 @@ export {
173
189
  buildClientSideScripts,
174
190
  installPackages,
175
191
  readJSONFile,
192
+ getProjectSiteDir,
176
193
  };
@@ -4,14 +4,25 @@ import * as url from "url";
4
4
  const __dirname = url.fileURLToPath(new URL(".", import.meta.url));
5
5
 
6
6
  class Options {
7
- #DEFAULT_SERVER_MODULES_SUB_PATH = "./site/app/server/modules";
7
+ #DEFAULT_SITE_PATH = "./site";
8
+ get DEFAULT_SITE_PATH() {
9
+ return this.#DEFAULT_SITE_PATH;
10
+ }
11
+
12
+ #DEFAULT_SERVER_MODULES_SUB_PATH = "./app/server/modules";
8
13
  get DEFAULT_SERVER_MODULES_SUB_PATH() {
9
- return this.#DEFAULT_SERVER_MODULES_SUB_PATH;
14
+ return resolve(
15
+ this.DEFAULT_SITE_PATH,
16
+ this.#DEFAULT_SERVER_MODULES_SUB_PATH
17
+ );
10
18
  }
11
19
 
12
- #DEFAULT_FRONT_MODULES_SUB_PATH = "./site/app/front/src";
20
+ #DEFAULT_FRONT_MODULES_SUB_PATH = "./app/front/src";
13
21
  get DEFAULT_FRONT_MODULES_SUB_PATH() {
14
- return this.#DEFAULT_FRONT_MODULES_SUB_PATH;
22
+ return resolve(
23
+ this.DEFAULT_SITE_PATH,
24
+ this.#DEFAULT_FRONT_MODULES_SUB_PATH
25
+ );
15
26
  }
16
27
 
17
28
  #PATH_TMPL = resolve(__dirname, "../../../tmpl/files");
@@ -5,6 +5,8 @@ import entityLayers from "./entityLayers.mjs";
5
5
  import modelValidators from "./modelValidators.mjs";
6
6
  import modelVersioning from "./modelVersioning.mjs";
7
7
  import modelIncrement from "./modelIncrement.mjs";
8
+ import modelDates from "./modelDates.mjs";
9
+ import modelOwnage from "./modelOwnage.mjs";
8
10
 
9
11
  const DEFAULT = {
10
12
  ModelName: "NewModel",
@@ -37,6 +39,14 @@ export default (inquirer, config, layersList) => {
37
39
  result.validators = await modelValidators(inquirer);
38
40
  result.versioning = await modelVersioning(inquirer);
39
41
  result.increment = await modelIncrement(inquirer, result);
42
+ result.ownage = await modelOwnage(inquirer);
43
+ result.dates = await modelDates(inquirer);
44
+ } else {
45
+ result.increment = false;
46
+ result.versioning = false;
47
+ result.validators = true;
48
+ result.ownage = false;
49
+ result.dates = false;
40
50
  }
41
51
  console.log("Entity data", JSON.stringify(result));
42
52
  return result;
@@ -0,0 +1,14 @@
1
+ export default (inquirer) => {
2
+ return inquirer
3
+ .prompt([
4
+ {
5
+ type: "confirm",
6
+ name: "enabled",
7
+ message: "Model should have createdAt and updatedAt fields",
8
+ default: false,
9
+ },
10
+ ])
11
+ .then((answer) => {
12
+ return answer.enabled;
13
+ });
14
+ };
@@ -0,0 +1,15 @@
1
+ export default (inquirer) => {
2
+ return inquirer
3
+ .prompt([
4
+ {
5
+ type: "confirm",
6
+ name: "enabled",
7
+ message:
8
+ "Model should support ownage by a specific entity (default: User)?",
9
+ default: false,
10
+ },
11
+ ])
12
+ .then((answer) => {
13
+ return answer.enabled;
14
+ });
15
+ };
@@ -0,0 +1,12 @@
1
+ const Schema = require("mongoose").Schema;
2
+
3
+ module.exports = {
4
+ model: {
5
+ type: Schema.Types.Mixed,
6
+ required: true,
7
+ safe: {
8
+ update: ["@owner", "root", "admin"],
9
+ read: ["@owner", "root", "admin"],
10
+ },
11
+ },
12
+ };
@@ -0,0 +1,64 @@
1
+ const { objHas } = require("../../../common");
2
+
3
+ module.exports = [
4
+ {
5
+ validator(val) {
6
+ return objHas(val, "root") && typeof val.root == "boolean";
7
+ },
8
+ message: "not-node:identity_field_root_is_not_valid",
9
+ },
10
+ {
11
+ validator(val) {
12
+ return objHas(val, "admin") && typeof val.admin == "boolean";
13
+ },
14
+ message: "not-node:identity_field_admin_is_not_valid",
15
+ },
16
+ {
17
+ validator(val) {
18
+ return objHas(val, "auth") && typeof val.auth == "boolean";
19
+ },
20
+ message: "not-node:identity_field_auth_is_not_valid",
21
+ },
22
+ {
23
+ validator(val) {
24
+ return (
25
+ objHas(val, "role") &&
26
+ (typeof val.role === "string" || Array.isArray(val.role))
27
+ );
28
+ },
29
+ message: "not-node:identity_field_role_is_not_valid",
30
+ },
31
+ {
32
+ validator(val) {
33
+ return (
34
+ objHas(val, "primaryRole") &&
35
+ typeof val.primaryRole === "string"
36
+ );
37
+ },
38
+ message: "not-node:identity_field_primaryRole_is_not_valid",
39
+ },
40
+ {
41
+ validator(val) {
42
+ return objHas(val, "uid");
43
+ },
44
+ message: "not-node:identity_field_uid_is_undefined",
45
+ },
46
+ {
47
+ validator(val) {
48
+ return objHas(val, "sid");
49
+ },
50
+ message: "not-node:identity_field_sid_is_undefined",
51
+ },
52
+ {
53
+ validator(val) {
54
+ return objHas(val, "ip") && typeof val.ip === "string";
55
+ },
56
+ message: "not-node:identity_field_ip_is_not_valid",
57
+ },
58
+ {
59
+ validator(val) {
60
+ return objHas(val, "provider") && typeof val.provider === "string";
61
+ },
62
+ message: "not-node:identity_field_provider_is_not_valid",
63
+ },
64
+ ];
package/src/form/form.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const validator = require("validator");
2
+ const notPath = require("not-path");
2
3
  const FormFabric = require("./fabric");
3
4
  const { createSchemaFromFields } = require("../fields");
4
5
 
@@ -24,7 +25,8 @@ const DEFAULT_TRANSFORMERS = require("./transformers");
24
25
 
25
26
  /**
26
27
  * Generic form validation class
27
- **/
28
+ * @class Form
29
+ */
28
30
  class Form {
29
31
  /**
30
32
  * @prop {import('not-validation/src/builder').notValidationSchema} validation schema
@@ -38,10 +40,11 @@ class Form {
38
40
  * @prop {string} name of form
39
41
  **/
40
42
  #FORM_NAME;
43
+
41
44
  #MODEL_NAME;
42
45
  #MODULE_NAME;
43
46
  #PROTO_FIELDS;
44
- #VALIDATOR;
47
+
45
48
  #EXTRACTORS = {
46
49
  ...DEFAULT_EXTRACTORS,
47
50
  };
@@ -59,6 +62,19 @@ class Form {
59
62
  #rateLimiterException = FormExceptionTooManyRequests;
60
63
  #rateLimiterClientName = InitRateLimiter.DEFAULT_CLIENT;
61
64
 
65
+ /**
66
+ *
67
+ * @param {Object} options
68
+ * @param {Array<string|Array<string>>} options.FIELDS
69
+ * @param {string} options.FORM_NAME
70
+ * @param {string} options.MODEL_NAME
71
+ * @param {string} options.MODULE_NAME
72
+ * @param {import('../app.js')} options.app
73
+ * @param {Object.<string, Function>} options.EXTRACTORS
74
+ * @param {Object.<string, Function>} options.TRANSFORMERS
75
+ * @param {Object.<string, import('../types.js').notAppFormEnvExtractor>} options.ENV_EXTRACTORS
76
+ * @param {import('../types.js').notAppFormRateLimiterOptions} options.rate
77
+ */
62
78
  constructor({
63
79
  FIELDS,
64
80
  FORM_NAME,
@@ -117,6 +133,7 @@ class Form {
117
133
  **/
118
134
  async run(req) {
119
135
  let data = await this.extract(req);
136
+ data = await this.afterExtract(data, req);
120
137
  await this.#checkRate(data);
121
138
  await this.#_validate(data);
122
139
  return data;
@@ -128,13 +145,10 @@ class Form {
128
145
  * @return {Promise<import('../types').PreparedData>} forma data
129
146
  **/
130
147
  async extract(req) {
131
- return this.afterExtract(
132
- {
133
- ...this.extractRequestEnvs(req),
134
- data: this.extractByInstructionsFromRouteActionFields(req),
135
- },
136
- req
137
- );
148
+ return {
149
+ ...this.extractRequestEnvs(req),
150
+ data: this.extractByInstructionsFromRouteActionFields(req),
151
+ };
138
152
  }
139
153
 
140
154
  /**
@@ -197,7 +211,7 @@ class Form {
197
211
  throw e;
198
212
  } else {
199
213
  throw new notError(
200
- "not-core:form_validation_unknown_error",
214
+ "not-node:form_validation_unknown_error",
201
215
  {
202
216
  FORM_NAME: this.#FORM_NAME,
203
217
  PROTO_FIELDS: this.#PROTO_FIELDS,
@@ -323,76 +337,119 @@ class Form {
323
337
  return FormFabric;
324
338
  }
325
339
 
340
+ /**
341
+ * Object with named extractor functions
342
+ * @param {Object.<string,function>} extractors
343
+ */
326
344
  #addExtractors(extractors = {}) {
327
345
  if (extractors) {
328
346
  this.#EXTRACTORS = { ...this.#EXTRACTORS, ...extractors };
329
347
  }
330
348
  }
331
349
 
350
+ /**
351
+ * Extracts from express Request object data by inststructions object
352
+ * @param {import('../types').notNodeExpressRequest} req
353
+ * @param {import('../types.js').notAppFormProcessingPipe} instructions {fieldName: [extractor, ...transformers]} extractors and transformers should be string (names of functions from libs) or functions
354
+ * @returns {Object}
355
+ */
332
356
  extractByInstructions(req, instructions) {
333
357
  const results = {};
334
358
  for (let fieldName in instructions) {
335
359
  const instruction = instructions[fieldName];
336
360
  if (Array.isArray(instruction)) {
337
- this.#extractByInstructionPipe({
361
+ this.#extractByInstructionPipe(
338
362
  results,
339
- instructions: instruction,
363
+ instruction,
340
364
  fieldName,
341
- req,
342
- });
365
+ req
366
+ );
343
367
  } else {
344
- this.#extractByInstruction({
368
+ this.#extractByInstruction(
345
369
  results,
346
370
  instruction,
347
371
  fieldName,
348
- req,
349
- });
372
+ req
373
+ );
350
374
  }
351
375
  }
352
376
  return results;
353
377
  }
354
378
 
355
- #extractByInstruction({ results, instruction, fieldName, req }) {
379
+ /**
380
+ * Runs one extractor provided as name of extractor from library or as a function.
381
+ * Add extracted data to results object.
382
+ * @param {Object} results
383
+ * @param {import('../types.js').notAppFormPropertyProcessingPipeInstruction} instruction
384
+ * @param {string} fieldName field name, maybe path to sub-object aka data.id
385
+ * @param {import('../types.js').notNodeExpressRequest} req
386
+ * @throws {FormExceptionExtractorForFieldIsUndefined}
387
+ */
388
+ #extractByInstruction(results, instruction, fieldName, req) {
356
389
  if (isFunc(instruction)) {
357
- results[fieldName] = instruction(req, fieldName);
390
+ //using notPath to be able use paths to sub-objects for properties as data.targetId, data.list[0].value etc
391
+ notPath.set(
392
+ notPath.PATH_START_OBJECT + fieldName,
393
+ results,
394
+ // @ts-ignore
395
+ instruction(req, fieldName)
396
+ );
358
397
  } else if (typeof instruction == "string") {
359
398
  const extractor = this.#EXTRACTORS[instruction];
360
399
  if (isFunc(extractor)) {
361
- results[fieldName] = extractor(req, fieldName);
400
+ notPath.set(
401
+ notPath.PATH_START_OBJECT + fieldName,
402
+ results,
403
+ extractor(req, fieldName)
404
+ );
362
405
  } else {
363
406
  throw new FormExceptionExtractorForFieldIsUndefined(fieldName);
364
407
  }
365
408
  }
366
409
  }
367
410
 
368
- #extractByInstructionPipe({ results, instructions, fieldName, req }) {
411
+ /**
412
+ *
413
+ * @param {Object} results resulting object
414
+ * @param {import('../types.js').notAppFormPropertyProcessingPipe} instructions
415
+ * @param {string} fieldName field name, maybe path to sub-object aka data.id
416
+ * @param {import('../types.js').notNodeExpressRequest} req
417
+ */
418
+ #extractByInstructionPipe(results, instructions, fieldName, req) {
369
419
  if (!instructions || instructions.length === 0) {
370
420
  throw new FormExceptionExtractorForFieldIsUndefined(fieldName);
371
421
  }
372
422
  //
373
- this.#extractByInstruction({
374
- results,
375
- instruction: instructions[0],
376
- fieldName,
377
- req,
378
- });
423
+ this.#extractByInstruction(results, instructions[0], fieldName, req);
379
424
  for (let t = 1; t < instructions.length; t++) {
380
425
  const instruction = instructions[t];
381
- this.#transformByInstruction({
382
- results,
383
- instruction,
384
- fieldName,
385
- });
426
+ this.#transformByInstruction(results, instruction, fieldName);
386
427
  }
387
428
  }
388
429
 
389
- #transformByInstruction({ results, instruction, fieldName }) {
430
+ /**
431
+ *
432
+ * @param {Object} results resulting object
433
+ * @param {import('../types.js').notAppFormPropertyProcessingPipeInstruction} instruction
434
+ * @param {string} fieldName field name, maybe path to sub-object aka data.id
435
+ * @throws {FormExceptionTransformerForFieldIsUndefined}
436
+ */
437
+ #transformByInstruction(results, instruction, fieldName) {
390
438
  if (isFunc(instruction)) {
391
- results[fieldName] = instruction(results[fieldName]);
439
+ notPath.set(
440
+ notPath.PATH_START_OBJECT + fieldName,
441
+ results,
442
+ // @ts-ignore
443
+ instruction(results[fieldName])
444
+ );
392
445
  } else if (typeof instruction == "string") {
393
446
  const transformer = this.#TRANSFORMERS[instruction];
394
447
  if (isFunc(transformer)) {
395
- results[fieldName] = transformer(results[fieldName]);
448
+ notPath.set(
449
+ notPath.PATH_START_OBJECT + fieldName,
450
+ results,
451
+ transformer(results[fieldName])
452
+ );
396
453
  } else {
397
454
  throw new FormExceptionTransformerForFieldIsUndefined(
398
455
  fieldName,
@@ -423,6 +480,13 @@ class Form {
423
480
  return [];
424
481
  }
425
482
 
483
+ /**
484
+ *
485
+ * @param {import('../types.js').notNodeExpressRequest} req
486
+ * @param {import('../types.js').notAppFormPropertyProcessingPipe} mainInstruction
487
+ * @param {import('../types.js').notAppFormProcessingPipe} exceptions
488
+ * @returns {import('../types.js').notAppFormProcessingPipe}
489
+ */
426
490
  createInstructionFromRouteActionFields(
427
491
  req,
428
492
  mainInstruction = ["fromBody", "xss"],
@@ -437,26 +501,32 @@ class Form {
437
501
  result[fieldName] = mainInstruction;
438
502
  }
439
503
  });
504
+ // @ts-ignore
440
505
  return result;
441
506
  }
442
507
 
443
508
  /**
444
- *
445
- * @param {import('express').Request} req
446
- * @param {Array<string>} mainInstruction
447
- * @param {object} exceptions
448
- * @returns
509
+ * Creates object {[fieldName]: Array[extractor:string|function, ...transformers:Array<string|function>]}
510
+ * @param {import('../types.js').notNodeExpressRequest} req express request with notRouteData property
511
+ * @param {import('../types.js').notAppFormPropertyProcessingPipe} mainInstruction what is a common pipe to apply to an property [extractor, ...transformers]
512
+ * @param {import('../types.js').notAppFormProcessingPipe} exceptions what shouldn't be treated as common and have own pipes {fieldName:string: [extractor, ...transformers]}
513
+ * @param {import('../types.js').notAppFormProcessingPipe} additional
514
+ * @returns {object}
449
515
  */
450
516
  extractByInstructionsFromRouteActionFields(
451
517
  req,
452
518
  mainInstruction = ["fromBody", "xss"],
453
- exceptions = {}
519
+ exceptions = {},
520
+ additional = {}
454
521
  ) {
455
- const instructions = this.createInstructionFromRouteActionFields(
456
- req,
457
- mainInstruction,
458
- exceptions
459
- );
522
+ const instructions = {
523
+ ...this.createInstructionFromRouteActionFields(
524
+ req,
525
+ mainInstruction,
526
+ exceptions
527
+ ),
528
+ ...additional,
529
+ };
460
530
  return this.extractByInstructions(req, instructions);
461
531
  }
462
532
 
package/src/types.js CHANGED
@@ -95,4 +95,32 @@
95
95
  * @property {string} provider //provider class name
96
96
  */
97
97
 
98
+ /**
99
+ * @typedef {string|function} notAppFormPropertyProcessingPipeInstruction
100
+ */
101
+
102
+ /**
103
+ * @typedef {Array<notAppFormPropertyProcessingPipeInstruction>} notAppFormPropertyProcessingPipe
104
+ */
105
+
106
+ /**
107
+ * @typedef {Object.<string, notAppFormPropertyProcessingPipe>} notAppFormProcessingPipe
108
+ */
109
+
110
+ /**
111
+ * @typedef {object} notAppFormEnvExtractor
112
+ * @property {string} name
113
+ * @property {any} value
114
+ */
115
+
116
+ /**
117
+ * @typedef {object} notAppFormRateLimiterOptions
118
+ * @property {object} [options]
119
+ * @property {string} [options.keyPrefix]
120
+ * @property {number} [options.points]
121
+ * @property {number} [options.duration]
122
+ * @property {object} [exception]
123
+ * @property {function} [idGetter]
124
+ * @property {string} [client]
125
+ */
98
126
  module.exports = {};
@@ -4,32 +4,36 @@ const Form = require("not-node").Form;
4
4
 
5
5
  const FIELDS = [
6
6
  <% if (fields && Array.isArray(fields)) { %>
7
- <% for(let field of fields){ %>
8
- <%- `"${field}",` -%>
9
- <% } %>
10
- <% } %>
11
- ["owner", "not-node//owner"],
12
- ["ownerModel", "not-node//ownerModel"],
13
- ];
14
-
15
- const FORM_NAME = `${MODULE_NAME}:_<%- ModelName %>DataForm`;
16
-
17
-
18
- //const validateTitle = require("./validators/title.js");
19
-
20
- module.exports = class _DataForm extends Form {
21
- constructor({ app }) {
22
- super({ FIELDS, FORM_NAME, app });
23
- }
24
-
25
- extract(data) {
26
- return data;
27
- }
28
-
29
- getFormValidationRules() {
30
- return [
31
- //add validators here
32
- //validateTitle,
33
- ];
34
- }
35
- };
7
+ <% for(let field of fields){ %>
8
+ <%- `"${field}",` -%>
9
+ <% } %>
10
+ <% } %>
11
+ <% if (ownage) { %>
12
+ ["owner", "not-node//owner"],
13
+ ["ownerModel", "not-node//ownerModel"],
14
+ <% } %>
15
+ ];
16
+
17
+ const FORM_NAME = `${MODULE_NAME}:_<%- ModelName %>DataForm`;
18
+
19
+ //const validateTitle = require("./validators/title.js");
20
+ class _<%- ModelName %>_DataForm extends Form {
21
+ constructor({ app }) {
22
+ super({ FIELDS, FORM_NAME, app });
23
+ }
24
+
25
+ //could do something with data, before validation
26
+ async extract(data) {
27
+ return data;
28
+ }
29
+
30
+ //fields validators are loaded automatically, form validators should be returned from here as an array
31
+ getFormValidationRules() {
32
+ return [
33
+ //add validators here
34
+ //validateTitle,
35
+ ];
36
+ }
37
+ }
38
+
39
+ module.exports = _<%- ModelName %>_DataForm;
@@ -1,45 +1,46 @@
1
- const getIP = require("not-node").Auth.getIP;
2
1
  const { MODULE_NAME } = require("../const");
3
2
  //DB related validation tools
4
3
  const Form = require("not-node").Form;
5
4
  //form
6
- const FIELDS = [
7
- ["activeUser", "not-node//requiredObject"],
8
- ["data", `${MODULE_NAME}//_<%- ModelName %>_data`],
9
- ["ip", "not-node//ip"],
10
- ];
5
+ const FIELDS = [
6
+ ["data", `${MODULE_NAME}//_<%- ModelName %>_data`],
7
+ ];
11
8
 
12
- const FORM_NAME = `${MODULE_NAME}:<%- ModelName %>CreateForm`;
9
+ const FORM_NAME = `${MODULE_NAME}:<%- ModelName %>CreateForm`;
13
10
 
14
- /**
15
- *
16
- **/
17
- module.exports = class <%- ModelName %>CreateForm extends Form {
18
- constructor({ app }) {
19
- super({ FIELDS, FORM_NAME, app });
20
- }
11
+ /**
12
+ *
13
+ **/
14
+ class <%- ModelName %>CreateForm extends Form {
15
+ constructor({ app }) {
16
+ super({ FIELDS, FORM_NAME, app });
17
+ }
21
18
 
22
- /**
23
- * Extracts data
24
- * @param {ExpressRequest} req expressjs request object
25
- * @return {Object} forma data
26
- **/
27
- extract(req) {
28
- const ip = getIP(req);
29
- const instructions = {
30
- <% if (fields && Array.isArray(fields)) { %>
31
- <% for(let field of fields){ %>
32
- <%- field+': fromBody" ,' -%>
33
- <% } %>
34
- <% } %>
35
- owner: "activeUserId",
36
- ownerModel: "activeUserModelName",
37
- };
38
- const data = this.extractByInstructions(req, instructions);
39
- return {
40
- activeUser: req.user,
41
- ip,
42
- data,
43
- };
44
- }
45
- };
19
+ /**
20
+ * Extracts data
21
+ * @param {import('not-node/src/types.js').notNodeExpressRequest} req expressjs request object
22
+ * @return {Object} forma data
23
+ **/
24
+ extract(req) {
25
+ const data = this.extractByInstructionsFromRouteActionFields(
26
+ req, //request object
27
+ ["fromBody", "xss"], //extraction common pipe [extractor, ...transformers]
28
+ {} //exceptions {fieldName: [extractor, ...transformers],...}
29
+ );
30
+ //contains targetId, identity and some more. look full list in not-node/src/form/env_extractors/index.js
31
+ const envs = this.extractRequestEnvs(req);
32
+ <% if ( ownage ) { %>
33
+ //admin could change ownage for others hardwired
34
+ if (!identity.admin) {
35
+ data.owner = identity.uid;
36
+ data.ownerModel = 'User';
37
+ }
38
+ <% } %>
39
+ return {
40
+ ...envs,
41
+ data
42
+ };
43
+ }
44
+ }
45
+
46
+ module.exports = <%- ModelName %>CreateForm;
@@ -5,4 +5,4 @@ module.exports = notNode.Generic.GenericListAndCountForm({
5
5
  MODULE_NAME,
6
6
  MODEL_NAME: "<%- ModelName %>",
7
7
  actionName: "listAll",
8
- });
8
+ });
@@ -5,4 +5,4 @@ module.exports = notNode.Generic.GenericListAndCountForm({
5
5
  MODULE_NAME,
6
6
  MODEL_NAME: "<%- ModelName %>",
7
7
  actionName: "listAndCount",
8
- });
8
+ });
@@ -1,40 +1,33 @@
1
1
  const { MODULE_NAME } = require("../const");
2
2
  const Form = require("not-node").Form;
3
- const getIP = require("not-node").Auth.getIP;
4
3
 
5
4
  const FIELDS = [
6
- ["targetId", { required: true }, "not-node//objectId"],
7
- ["activeUser", "not-node//requiredObject"],
8
- ["data", `${MODULE_NAME}//_<%- ModelName %>_data`], //sub forms validators should start with underscore
9
- ["ip", "not-node//ip"],
10
- ];
11
- const FORM_NAME = `${MODULE_NAME}:<%- ModelName %>UpdateForm`;
5
+ ["targetId", { required: true }, "not-node//objectId"],
6
+ ["identity", "not-node//identity"],
7
+ ["data", `${MODULE_NAME}//_<%- ModelName %>_data`], //sub forms validators should start with underscore
8
+ ];
9
+ const FORM_NAME = `${MODULE_NAME}:<%- ModelName %>UpdateForm`;
12
10
 
13
- module.exports = class <%- ModelName %>UpdateForm extends Form {
14
- constructor({ app }) {
15
- super({ FIELDS, FORM_NAME, app });
16
- }
11
+ class <%- ModelName %>UpdateForm extends Form {
12
+ constructor({ app }) {
13
+ super({ FIELDS, FORM_NAME, app });
14
+ }
17
15
 
18
- extract(req) {
19
- const instructions = {
20
- <% if (fields && Array.isArray(fields)) { %>
21
- <% for(let field of fields){ %>
22
- <%- field+': "fromBody" ,' -%>
23
- <% } %>
24
- <% } %>
25
- owner: "fromBody",
26
- ownerModel: "fromBody",
27
- };
28
- const data = this.extractByInstructions(req, instructions);
29
- if (!req.user.isRoot() && !req.user.isAdmin()) {
30
- data.owner = req.user._id;
31
- data.ownerModel = "User";
32
- }
33
- return {
34
- targetId: req.params._id.toString(),
35
- activeUser: req.user,
36
- data,
37
- ip: getIP(req),
38
- };
39
- }
40
- };
16
+ extract(req) {
17
+ const data = this.extractByInstructionsFromRouteActionFields(req, ["fromBody", "xss"], {});
18
+ const envs = this.extractRequestEnvs(req);
19
+ <% if ( ownage ) { %>
20
+ //admin could change ownage for others hardwired
21
+ if (!identity.admin) {
22
+ data.owner && delete data.owner;
23
+ data.ownerModel && delete data.ownerModel;
24
+ }
25
+ <% } %>
26
+ return {
27
+ ...envs, //contains targetId, identity and some more. look list in not-node/src/form/env_extractors/index.js
28
+ data,
29
+ };
30
+ }
31
+ }
32
+
33
+ module.exports = <%- ModelName %>UpdateForm;
@@ -1,32 +1,37 @@
1
1
  const notNode = require("not-node");
2
2
  const { notValidationError } = require("not-error");
3
3
 
4
+ /**
5
+ * async validation function, should throw notValidationError if validation failed
6
+ * @param {object} data form data object
7
+ * @param {object} validationEnvs special object that provides access to injected on project level resources and libraries
8
+ */
4
9
  module.exports = async (
5
10
  /**
6
11
  * Values to validate in form
7
12
  */
8
- {owner, ownerModel, vals, to , validate },
13
+ {owner, ownerModel, vals, to , validate },
9
14
  /**
10
15
  * special container to pass around global validation libs, CONSTs and inject other entities
11
16
  */
12
- validationEnvs
17
+ validationEnvs
13
18
  ) => {
14
- //some preparations
15
- if (
16
- //vals checks
17
- ) {
18
- throw new notValidationError(
19
- "<%- ModuleName %>:validation_error",
20
- {
21
- //vals: ["%- ModuleName %>:vals_should_be_valid"],
22
- },
23
- undefined, //no source error, its custom exception
24
- {
25
- //information
26
- //vals,
27
- //owner,
28
- //ownerModel
29
- }
30
- );
31
- }
32
- };
19
+ //some preparations
20
+ if (
21
+ //vals checks
22
+ ) {
23
+ throw new notValidationError(
24
+ "<%- ModuleName %>:<%- modelName %>_validation_error",
25
+ {
26
+ //vals: ["%- ModuleName %>:vals_should_be_valid"],
27
+ },
28
+ undefined, //no source error, its custom exception
29
+ {
30
+ //information
31
+ //vals,
32
+ //owner,
33
+ //ownerModel
34
+ }
35
+ );
36
+ }
37
+ };
@@ -1,13 +1,10 @@
1
1
  const { MODULE_NAME } = require("../const");
2
2
  //DB related validation tools
3
3
  const Form = require("not-node").Form;
4
- //not-node
5
- const getIP = require("not-node").Auth.getIP;
6
4
  //form
7
5
  const FIELDS = [
8
- ["activeUser", "not-node//requiredObject"],
9
- ["data", `${MODULE_NAME}//_data`],
10
- ["ip", "not-node//ip"],
6
+ ["identity", "not-node//identity"],
7
+ ["data", `${MODULE_NAME}//_data`],
11
8
  ];
12
9
 
13
10
  const FORM_NAME = `${MODULE_NAME}:CreateForm`;
@@ -1,73 +1,69 @@
1
1
  const MODEL_NAME = "<%- ModelName %>";
2
-
3
2
  const { MODULE_NAME } = require("../const.js");
4
3
  const notNode = require("not-node");
5
-
6
4
  const {
7
- Log,
8
- LogAction,
9
- say,
10
- phrase,
11
- config,
12
- getModel,
13
- getModelSchema,
14
- getLogic,
15
- getModelUser,
16
- } = notNode.Bootstrap.notBootstrapLogic({
17
- target: module,
18
- MODEL_NAME,
19
- MODULE_NAME,
20
- });
5
+ Log,
6
+ LogAction,
7
+ say,
8
+ phrase,
9
+ config,
10
+ getModel,
11
+ getModelSchema,
12
+ getLogic,
13
+ getModelUser,
14
+ } = notNode.Bootstrap.notBootstrapLogic({
15
+ target: module,
16
+ MODEL_NAME,
17
+ MODULE_NAME,
18
+ });
21
19
 
22
20
  const populateBuilders = {};
23
21
 
24
22
  const <%- ModelName %>GenericLogic = notNode.Generic.GenericLogic({
25
- MODEL_NAME,
26
- MODULE_NAME,
27
- Log,
28
- LogAction,
29
- say,
30
- phrase,
31
- config,
32
- getModel,
33
- getModelSchema,
34
- getLogic,
35
- getModelUser,
36
- populateBuilders,
37
- });
38
-
23
+ MODEL_NAME,
24
+ MODULE_NAME,
25
+ Log,
26
+ LogAction,
27
+ say,
28
+ phrase,
29
+ config,
30
+ getModel,
31
+ getModelSchema,
32
+ getLogic,
33
+ getModelUser,
34
+ populateBuilders,
35
+ });
36
+
39
37
  module.exports.thisLogicName = MODEL_NAME;
40
38
 
41
39
  class <%- ModelName %>Logic extends <%- ModelName %>GenericLogic {
42
- <% if(Object.keys(actions).length){ %>
43
- <% for(let actionName in actions) { %>
44
- static async <%- actionName %>({ targetId, activeUser, ip, root, shouldOwn, data }) {
45
- const action = "<%- actionName %>";
46
- Log.debug(
47
- `${MODULE_NAME}//Logic//${MODEL_NAME}//${action}`,
48
- targetId,
49
- ip,
50
- root
51
- );
52
-
53
- const results = await getModel().<%- actionName %>(
54
- targetId,
55
- activeUser._id,
56
- data
57
- );
58
-
59
- LogAction({
60
- action,
61
- by: activeUser._id,
62
- role: activeUser.role,
63
- ip,
64
- root,
65
- shouldOwn,
66
- });
67
- return results;
68
- }
69
- <% } %>
70
- <% } %>
40
+ <% if(Object.keys(actions).length){ %>
41
+ <% for(let actionName in actions) { %>
42
+ static async <%- actionName %>({ identity, data, targetId, shouldOwn }) {
43
+ const action = "<%- actionName %>";
44
+ Log.debug(
45
+ `${MODULE_NAME}//Logic//${MODEL_NAME}//${action}`,
46
+ targetId,
47
+ ip: identity.ip,
48
+ root: identity.root,
49
+ );
50
+ const results = await getModel().<%- actionName %>(
51
+ targetId,
52
+ data,
53
+ identity
54
+ );
55
+ LogAction({
56
+ action,
57
+ by: identity.uid,
58
+ role: identity.role,
59
+ ip: identity.ip,
60
+ root: identity.root,
61
+ shouldOwn,
62
+ });
63
+ return results;
64
+ }
65
+ <% } %>
66
+ <% } %>
71
67
  }
72
68
 
73
- module.exports[MODEL_NAME] = <%- ModelName %>Logic;
69
+ module.exports[MODEL_NAME] = <%- ModelName %>Logic;
@@ -3,45 +3,45 @@ const MODEL_NAME = "<%- ModelName %>";
3
3
  const notNode = require("not-node");
4
4
 
5
5
  const {
6
- // say,
7
- // config,
8
- // Log,
9
- before,
10
- after,
11
- getLogic,
12
- // getModel,
13
- // getModelSchema,
6
+ // say,
7
+ // config,
8
+ // Log,
9
+ before,
10
+ after,
11
+ getLogic,
12
+ // getModel,
13
+ // getModelSchema,
14
14
  } = notNode.Bootstrap.notBootstrapRoute({
15
- target: module,
16
- MODEL_NAME,
17
- MODULE_NAME,
18
- defaultAccessRule: true,
15
+ target: module,
16
+ MODEL_NAME,
17
+ MODULE_NAME,
18
+ defaultAccessRule: true,
19
19
  });
20
20
 
21
21
  const <%- ModelName %>GenericRoute = notNode.Generic.GenericRoute({
22
- before, //<-this prepares `prepared`
23
- after,
24
- getLogic,
22
+ before, //<-this prepares `prepared`
23
+ after,
24
+ getLogic,
25
25
  });
26
26
 
27
27
  class <%- ModelName %>Route extends <%- ModelName %>GenericRoute {
28
- <% if(Object.keys(actions).length){ %>
29
- <% for(let actionName in actions) { %>
30
- static async <%- actionName %>(
31
- req, res, next, //standart express routes objects
32
- prepared //extracted by `before` if form class exists
33
- ) {
34
- <% if (layers.includes('forms') && layers.includes('logics')){ %>
35
- return await getLogic().<%- actionName %>({ ...prepared });
36
- <% } %>
28
+ <% if(Object.keys(actions).length){ %>
29
+ <% for(let actionName in actions) { %>
30
+ static async <%- actionName %>(
31
+ req, res, next, //standart express routes objects
32
+ prepared //extracted by `before` if form class exists
33
+ ) {
34
+ <% if (layers.includes('forms') && layers.includes('logics')){ %>
35
+ return await getLogic().<%- actionName %>({ ...prepared });
36
+ <% } %>
37
37
 
38
- <% if (layers.includes('forms') && !layers.includes('logics')){ %>
39
- return {...prepared};
40
- <% } %>
38
+ <% if (layers.includes('forms') && !layers.includes('logics')){ %>
39
+ return {...prepared};
40
+ <% } %>
41
41
 
42
- <% if (!layers.includes('forms') && layers.includes('logics')){ %>
43
- return await getLogic().<%- actionName %>();
44
- <% } %>
42
+ <% if (!layers.includes('forms') && layers.includes('logics')){ %>
43
+ return await getLogic().<%- actionName %>();
44
+ <% } %>
45
45
  }
46
46
  <% } %>
47
47
  <% } %>