@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.
Files changed (56) hide show
  1. package/README.md +62 -0
  2. package/auth/basic.js +8 -0
  3. package/auth/cookie.js +10 -0
  4. package/auth/jwks.js +6 -0
  5. package/auth/jwt.js +9 -0
  6. package/auth/openid.js +5 -0
  7. package/auth/webscoket.js +6 -0
  8. package/builder/EnvBuilder.js +0 -0
  9. package/builder/createCjsModule.js +95 -0
  10. package/builder/editModelInteractive.js +159 -0
  11. package/builder/interactiveModelBuilder.js +215 -0
  12. package/builder/interactiveMongobuilder.js +189 -0
  13. package/builder/interactiveUnifiedBuilder.js +277 -0
  14. package/builder/joiValidatorBuilder.js +218 -0
  15. package/builder/mongooseModelBuilder.js +290 -0
  16. package/builder/mongooseModelBuilder2.js +313 -0
  17. package/builder/runMigrations.js +106 -0
  18. package/builder/sequelizeModelBuilder.js +180 -0
  19. package/cli.js +60 -0
  20. package/commands/create.js +57 -0
  21. package/commands/generate.js +74 -0
  22. package/dev/Uset.schema.json +18 -0
  23. package/dev/buildSchemaInteractive.js +189 -0
  24. package/dev/buildSequelizeSchemaInteractive.js +128 -0
  25. package/dev/createJoiSchemaFromJson.js +137 -0
  26. package/dev/createModelFromJson.js +280 -0
  27. package/dev/generateAllFiles.js +45 -0
  28. package/dev/generateJoiFile.js +95 -0
  29. package/dev/generateSequelizeFiles.js +167 -0
  30. package/dev/interactiveJoiBuilder.js +177 -0
  31. package/dev/ra.js +22 -0
  32. package/dev/rj.js +18 -0
  33. package/dev/run.js +16 -0
  34. package/dev/run_seq.js +18 -0
  35. package/dev/tracker.js +23 -0
  36. package/editJsConfig.js +188 -0
  37. package/index.js +548 -0
  38. package/lib/ModelGenerator.js +203 -0
  39. package/lib/ProjectGenerator.js +246 -0
  40. package/lib/utils.js +100 -0
  41. package/logo.js +3 -0
  42. package/package.json +35 -0
  43. package/readme.md +2 -0
  44. package/schema.json +42 -0
  45. package/templates/auth_vals.json +3 -0
  46. package/templates/config.js +0 -0
  47. package/templates/example-route.js +94 -0
  48. package/templates/example-service.js +63 -0
  49. package/templates/example-validator.js +15 -0
  50. package/templates/example-worker.js +83 -0
  51. package/templates/index.txt +41 -0
  52. package/templates/post-init.js +78 -0
  53. package/templates/settings.js +192 -0
  54. package/templates/template1.settings.txt +15 -0
  55. package/templates/templatev1.json +38 -0
  56. 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 };