@triophore/falcon-cli 1.0.0
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/README.md +62 -0
- package/auth/basic.js +8 -0
- package/auth/cookie.js +10 -0
- package/auth/jwks.js +6 -0
- package/auth/jwt.js +9 -0
- package/auth/openid.js +5 -0
- package/auth/webscoket.js +6 -0
- package/builder/EnvBuilder.js +0 -0
- package/builder/createCjsModule.js +95 -0
- package/builder/editModelInteractive.js +159 -0
- package/builder/interactiveModelBuilder.js +215 -0
- package/builder/interactiveMongobuilder.js +189 -0
- package/builder/interactiveUnifiedBuilder.js +277 -0
- package/builder/joiValidatorBuilder.js +218 -0
- package/builder/mongooseModelBuilder.js +290 -0
- package/builder/mongooseModelBuilder2.js +313 -0
- package/builder/runMigrations.js +106 -0
- package/builder/sequelizeModelBuilder.js +180 -0
- package/cli.js +60 -0
- package/commands/create.js +57 -0
- package/commands/generate.js +74 -0
- package/dev/Uset.schema.json +18 -0
- package/dev/buildSchemaInteractive.js +189 -0
- package/dev/buildSequelizeSchemaInteractive.js +128 -0
- package/dev/createJoiSchemaFromJson.js +137 -0
- package/dev/createModelFromJson.js +280 -0
- package/dev/generateAllFiles.js +45 -0
- package/dev/generateJoiFile.js +95 -0
- package/dev/generateSequelizeFiles.js +167 -0
- package/dev/interactiveJoiBuilder.js +177 -0
- package/dev/ra.js +22 -0
- package/dev/rj.js +18 -0
- package/dev/run.js +16 -0
- package/dev/run_seq.js +18 -0
- package/dev/tracker.js +23 -0
- package/editJsConfig.js +188 -0
- package/index.js +548 -0
- package/lib/ModelGenerator.js +203 -0
- package/lib/ProjectGenerator.js +246 -0
- package/lib/utils.js +100 -0
- package/logo.js +3 -0
- package/package.json +35 -0
- package/readme.md +2 -0
- package/schema.json +42 -0
- package/templates/auth_vals.json +3 -0
- package/templates/config.js +0 -0
- package/templates/example-route.js +94 -0
- package/templates/example-service.js +63 -0
- package/templates/example-validator.js +15 -0
- package/templates/example-worker.js +83 -0
- package/templates/index.txt +41 -0
- package/templates/post-init.js +78 -0
- package/templates/settings.js +192 -0
- package/templates/template1.settings.txt +15 -0
- package/templates/templatev1.json +38 -0
- package/validateJsConfig.js +125 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// validateJsConfig.js
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const acorn = require('acorn');
|
|
5
|
+
const estraverse = require('estraverse');
|
|
6
|
+
const Ajv = require('ajv');
|
|
7
|
+
|
|
8
|
+
const ajv = new Ajv({ allErrors: true, strict: false });
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Validate JS config file against JSON schema
|
|
12
|
+
* @param {string} filePath - Path to .js config file
|
|
13
|
+
* @param {Object} schema - JSON schema for validation
|
|
14
|
+
* @returns {Object} { valid: boolean, errors: Array }
|
|
15
|
+
*/
|
|
16
|
+
function validateJsConfig(filePath, schema) {
|
|
17
|
+
try {
|
|
18
|
+
const fullPath = path.resolve(filePath);
|
|
19
|
+
if (!fs.existsSync(fullPath)) {
|
|
20
|
+
return {
|
|
21
|
+
valid: false,
|
|
22
|
+
errors: [{ message: `File not found: ${fullPath}` }]
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Step 1: Extract settings object from JS
|
|
27
|
+
const settings = extractSettingsFromJs(fullPath);
|
|
28
|
+
if (!settings) {
|
|
29
|
+
return {
|
|
30
|
+
valid: false,
|
|
31
|
+
errors: [{ message: 'Could not parse module.exports.settings' }]
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Step 2: Validate with AJV
|
|
36
|
+
const validate = ajv.compile(schema);
|
|
37
|
+
const valid = validate(settings);
|
|
38
|
+
|
|
39
|
+
if (!valid) {
|
|
40
|
+
const errors = validate.errors.map(err => ({
|
|
41
|
+
path: err.instancePath || err.dataPath,
|
|
42
|
+
message: err.message,
|
|
43
|
+
value: getValueByPath(settings, err.instancePath.replace(/^\//, '').replace(/\//g, '.')),
|
|
44
|
+
expected: err.params
|
|
45
|
+
}));
|
|
46
|
+
return { valid: false, errors };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return { valid: true, errors: [] };
|
|
50
|
+
|
|
51
|
+
} catch (err) {
|
|
52
|
+
return {
|
|
53
|
+
valid: false,
|
|
54
|
+
errors: [{ message: `Parse error: ${err.message}` }]
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ── Extract settings from JS file (safe)
|
|
60
|
+
function extractSettingsFromJs(filePath) {
|
|
61
|
+
const code = fs.readFileSync(filePath, 'utf8');
|
|
62
|
+
const ast = acorn.parse(code, {
|
|
63
|
+
ecmaVersion: 'latest',
|
|
64
|
+
sourceType: 'module',
|
|
65
|
+
locations: true,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
let settingsValue = null;
|
|
69
|
+
|
|
70
|
+
estraverse.traverse(ast, {
|
|
71
|
+
enter(node) {
|
|
72
|
+
if (
|
|
73
|
+
node.type === 'AssignmentExpression' &&
|
|
74
|
+
node.left.type === 'MemberExpression' &&
|
|
75
|
+
node.left.object.name === 'module' &&
|
|
76
|
+
node.left.property.name === 'exports' &&
|
|
77
|
+
node.right.type === 'MemberExpression' &&
|
|
78
|
+
node.right.property.name === 'settings'
|
|
79
|
+
) {
|
|
80
|
+
settingsValue = evaluateObjectExpression(node.right.object);
|
|
81
|
+
this.break();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
return settingsValue;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ── Convert AST ObjectExpression → JS Object
|
|
90
|
+
function evaluateObjectExpression(node) {
|
|
91
|
+
if (node.type !== 'ObjectExpression') return null;
|
|
92
|
+
|
|
93
|
+
const obj = {};
|
|
94
|
+
for (const prop of node.properties) {
|
|
95
|
+
if (prop.type !== 'Property' || prop.key.type !== 'Identifier') continue;
|
|
96
|
+
|
|
97
|
+
const key = prop.key.name;
|
|
98
|
+
const valueNode = prop.value;
|
|
99
|
+
|
|
100
|
+
switch (valueNode.type) {
|
|
101
|
+
case 'Literal':
|
|
102
|
+
obj[key] = valueNode.value;
|
|
103
|
+
break;
|
|
104
|
+
case 'ArrayExpression':
|
|
105
|
+
obj[key] = valueNode.elements
|
|
106
|
+
.filter(el => el.type === 'Literal')
|
|
107
|
+
.map(el => el.value);
|
|
108
|
+
break;
|
|
109
|
+
case 'ObjectExpression':
|
|
110
|
+
obj[key] = evaluateObjectExpression(valueNode);
|
|
111
|
+
break;
|
|
112
|
+
default:
|
|
113
|
+
obj[key] = null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return obj;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// ── Helper: Get nested value by dot path
|
|
120
|
+
function getValueByPath(obj, path) {
|
|
121
|
+
return path.split('.').reduce((acc, part) => (acc && acc[part] !== undefined) ? acc[part] : undefined, obj);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// ── Export
|
|
125
|
+
module.exports = { validateJsConfig };
|