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.
- package/package.json +1 -1
- package/src/cli/actions/entity.mjs +3 -2
- package/src/cli/lib/entity.mjs +11 -2
- package/src/cli/lib/module.server.mjs +12 -2
- package/src/cli/readers/fields.mjs +4 -1
- package/src/cli/renderers/controllersCommons.mjs +21 -2
- package/src/common.js +21 -0
- package/src/core/fields/ID.js +1 -0
- package/src/core/fields/_id.js +3 -0
- package/src/core/fields/active.js +2 -1
- package/src/core/fields/boolean.js +2 -1
- package/src/core/fields/codeName.js +2 -1
- package/src/core/fields/createdAt.js +1 -4
- package/src/core/fields/default.js +1 -0
- package/src/core/fields/description.js +2 -1
- package/src/core/fields/email.js +2 -1
- package/src/core/fields/enabled.js +1 -0
- package/src/core/fields/expiredAt.js +1 -4
- package/src/core/fields/height.js +1 -0
- package/src/core/fields/identity.js +1 -4
- package/src/core/fields/ip.js +2 -1
- package/src/core/fields/objectId.js +2 -4
- package/src/core/fields/owner.js +9 -4
- package/src/core/fields/ownerModel.js +2 -5
- package/src/core/fields/price.js +1 -0
- package/src/core/fields/requiredObject.js +1 -4
- package/src/core/fields/session.js +2 -1
- package/src/core/fields/size.js +1 -0
- package/src/core/fields/telephone.js +2 -1
- package/src/core/fields/title.js +2 -5
- package/src/core/fields/updatedAt.js +1 -4
- package/src/core/fields/userId.js +1 -0
- package/src/core/fields/uuid.js +2 -1
- package/src/core/fields/width.js +1 -0
- package/src/core/safety.protocols.js +22 -0
- package/src/fields/filter.js +83 -4
- package/src/form/transformers/__CLEAR__.js +3 -0
- package/src/form/transformers/index.js +1 -0
- package/test/filter.js +95 -2
- package/tmpl/files/module.server/layers/controllers/common/crud.ejs +5 -4
- package/tmpl/files/module.server/layers/controllers/common/index.ejs +2 -1
- package/tmpl/files/module.server/layers/controllers/common/service.ejs +23 -0
- package/tmpl/files/module.server/layers/controllers/role/index.ejs +4 -1
- package/tmpl/files/notComponent.ejs +0 -57
- package/tmpl/files/notService.ejs +0 -39
package/package.json
CHANGED
|
@@ -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
|
};
|
package/src/cli/lib/entity.mjs
CHANGED
|
@@ -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 = {
|
|
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 {
|
|
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 = {
|
|
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 [${
|
|
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
|
package/src/core/fields/ID.js
CHANGED
package/src/core/fields/_id.js
CHANGED
package/src/core/fields/email.js
CHANGED
package/src/core/fields/ip.js
CHANGED
|
@@ -5,9 +5,7 @@ module.exports = {
|
|
|
5
5
|
type: ObjectId,
|
|
6
6
|
required: true,
|
|
7
7
|
default: {},
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
read: ["@owner", "root", "admin"],
|
|
11
|
-
},
|
|
8
|
+
transformers: ["xss", "__CLEAR__"],
|
|
9
|
+
safe: require("../safety.protocols").ownerRootAdmin,
|
|
12
10
|
},
|
|
13
11
|
};
|
package/src/core/fields/owner.js
CHANGED
|
@@ -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
|
-
|
|
9
|
-
|
|
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
|
-
|
|
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",
|
package/src/core/fields/price.js
CHANGED
package/src/core/fields/size.js
CHANGED
package/src/core/fields/title.js
CHANGED
|
@@ -9,10 +9,7 @@ module.exports = {
|
|
|
9
9
|
required: true,
|
|
10
10
|
searchable: true,
|
|
11
11
|
sortable: true,
|
|
12
|
-
safe:
|
|
13
|
-
|
|
14
|
-
read: ["@owner", "root", "admin"],
|
|
15
|
-
},
|
|
16
|
-
transformers: ['xss']
|
|
12
|
+
safe: require("../safety.protocols").ownerRootAdmin,
|
|
13
|
+
transformers: ["xss"],
|
|
17
14
|
},
|
|
18
15
|
};
|
package/src/core/fields/uuid.js
CHANGED
package/src/core/fields/width.js
CHANGED
|
@@ -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
|
+
});
|
package/src/fields/filter.js
CHANGED
|
@@ -5,7 +5,10 @@ const {
|
|
|
5
5
|
isNotEmptyString,
|
|
6
6
|
} = require("../common");
|
|
7
7
|
const { getSafeFieldsForRoleAction } = require("../auth/fields");
|
|
8
|
-
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]:
|
|
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
|
|
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}:${
|
|
12
|
-
single: `${MODULE_NAME}:${
|
|
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.
|
|
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 %>;
|