@microlight/core 0.6.1 → 0.8.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.
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import { parse } from '@babel/parser';
|
|
3
|
+
export const parseJSONFromDotJSFile = filePath => {
|
|
4
|
+
console.log(filePath);
|
|
5
|
+
// Read the contents of the file as UTF-8 text
|
|
6
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
7
|
+
try {
|
|
8
|
+
// Parse the file content into an Abstract Syntax Tree (AST)
|
|
9
|
+
// sourceType: 'module' allows ES6 import/export syntax
|
|
10
|
+
// plugins enable parsing of JSX and TypeScript syntax
|
|
11
|
+
const ast = parse(content, {
|
|
12
|
+
sourceType: 'module',
|
|
13
|
+
plugins: ['jsx', 'typescript']
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
// Search through the top-level statements (ast.program.body)
|
|
17
|
+
// to find the 'export default' statement
|
|
18
|
+
// Find the export default declaration
|
|
19
|
+
const exportDecl = ast.program.body.find(node => node.type === 'ExportDefaultDeclaration');
|
|
20
|
+
|
|
21
|
+
// If no export default is found, return null
|
|
22
|
+
if (!exportDecl) return null;
|
|
23
|
+
|
|
24
|
+
// Get the exported object, either direct or via identifier
|
|
25
|
+
// Get what's being exported (the declaration)
|
|
26
|
+
let objectAst = exportDecl.declaration;
|
|
27
|
+
// If the export is a variable (e.g., export default taskConfig)
|
|
28
|
+
if (objectAst.type === 'Identifier') {
|
|
29
|
+
// Find the variable declaration in the file
|
|
30
|
+
// (e.g., const taskConfig = { ... })
|
|
31
|
+
const varDecl = ast.program.body.find(node => node.type === 'VariableDeclaration' && node.declarations.some(d => d.id.name === objectAst.name));
|
|
32
|
+
if (varDecl) {
|
|
33
|
+
// Get the actual object from the variable declaration
|
|
34
|
+
objectAst = varDecl.declarations[0].init;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Convert AST to string, replacing function values with null
|
|
39
|
+
// Convert the AST object to a string, with a custom replacer function
|
|
40
|
+
const cleanObject = JSON.stringify(objectAst, (key, value) => {
|
|
41
|
+
// If the value is a function (any type of function), replace it with null
|
|
42
|
+
if (value?.type === 'FunctionExpression' || value?.type === 'ArrowFunctionExpression' || value?.type === 'FunctionDeclaration') {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
// Keep all other values as is
|
|
46
|
+
return value;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Parse the cleaned object to get the final result
|
|
50
|
+
// Parse the string back to an object
|
|
51
|
+
// Replace AST-specific property names with prefixed versions
|
|
52
|
+
// This prevents these technical properties from conflicting with task properties
|
|
53
|
+
const taskConfig = JSON.parse(cleanObject.replace(/"type":|"start":|"end":|"loc":|"range":/g, '"_$1":'));
|
|
54
|
+
|
|
55
|
+
// Extract only the properties we care about
|
|
56
|
+
// Remove all the AST-specific properties using destructuring
|
|
57
|
+
// ...finalConfig contains all the remaining properties we want to keep
|
|
58
|
+
const {
|
|
59
|
+
_type,
|
|
60
|
+
_start,
|
|
61
|
+
_end,
|
|
62
|
+
_loc,
|
|
63
|
+
_range,
|
|
64
|
+
...finalConfig
|
|
65
|
+
} = taskConfig;
|
|
66
|
+
|
|
67
|
+
// Return the clean task configuration object
|
|
68
|
+
return finalConfig;
|
|
69
|
+
} catch (err) {
|
|
70
|
+
// If any error occurs during parsing, log it and return null
|
|
71
|
+
console.error(`Error parsing task file ${filePath}:`, err);
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
@@ -3,9 +3,10 @@ import path from 'path';
|
|
|
3
3
|
// import { join, relative, dirname } from 'path';
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
const tasksDir = path.join(process.cwd(), 'src', 'tasks');
|
|
6
|
-
const outputFile = path.resolve(process.cwd(), '.microlight', 'folderMap.
|
|
7
|
-
const taskMapFile = path.resolve(process.cwd(), '.microlight', 'taskMap.
|
|
8
|
-
const taskMap = (
|
|
6
|
+
const outputFile = path.resolve(process.cwd(), '.microlight', 'folderMap.json');
|
|
7
|
+
const taskMapFile = path.resolve(process.cwd(), '.microlight', 'taskMap.json');
|
|
8
|
+
const taskMap = JSON.parse(fs.readFileSync(taskMapFile, 'utf-8'));
|
|
9
|
+
// const taskMap = (await import(taskMapFile))?.default;
|
|
9
10
|
let taskMapByFileName = {};
|
|
10
11
|
Object.keys(taskMap).forEach(function (slug) {
|
|
11
12
|
const task = taskMap[slug];
|
|
@@ -20,7 +21,14 @@ if (!fs.existsSync(tasksDir)) {
|
|
|
20
21
|
}
|
|
21
22
|
const getFolderFiles = function () {
|
|
22
23
|
// Find all folder files
|
|
23
|
-
const folderPatterns = [
|
|
24
|
+
const folderPatterns = [
|
|
25
|
+
// '__ml.js',
|
|
26
|
+
// 'ml.js',
|
|
27
|
+
'**/.mlrc'
|
|
28
|
+
// 'ml.folder.js',
|
|
29
|
+
// '**/microlight.folder.js',
|
|
30
|
+
// '**/microlight.folder.json',
|
|
31
|
+
];
|
|
24
32
|
const folderFiles = glob.sync(folderPatterns, {
|
|
25
33
|
cwd: tasksDir,
|
|
26
34
|
absolute: false
|
|
@@ -38,7 +46,10 @@ export async function prepareFolders() {
|
|
|
38
46
|
folderName.pop();
|
|
39
47
|
folderName = folderName.join('/');
|
|
40
48
|
// console.log(folderName);
|
|
41
|
-
let folder = (await import(filePath))?.default;
|
|
49
|
+
// let folder = (await import(filePath))?.default;
|
|
50
|
+
const folder = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
51
|
+
// let folder = (await parseJSONFromDotJSFile(filePath));
|
|
52
|
+
|
|
42
53
|
// console.log(folder.default);
|
|
43
54
|
// const taskName = path.basename(filePath, '.task.js');
|
|
44
55
|
return [folderName, folder];
|
|
@@ -103,7 +114,7 @@ export async function prepareFolders() {
|
|
|
103
114
|
// })
|
|
104
115
|
|
|
105
116
|
// Write the generated code to a file
|
|
106
|
-
const outputCode =
|
|
117
|
+
const outputCode = JSON.stringify(folderMap, null, 2);
|
|
107
118
|
|
|
108
119
|
// Create the output directory if it doesn't exist
|
|
109
120
|
const outputDir = path.dirname(outputFile);
|
|
@@ -2,6 +2,9 @@ import { glob } from 'glob';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
// import { join, relative, dirname } from 'path';
|
|
4
4
|
import fs from 'fs';
|
|
5
|
+
import { parse } from '@babel/parser';
|
|
6
|
+
// import generate from '@babel/generator';
|
|
7
|
+
import generator from '@babel/generator';
|
|
5
8
|
const tasksDir = path.join(process.cwd(), 'src', 'tasks');
|
|
6
9
|
|
|
7
10
|
// Create tasks directory if it doesn't exist
|
|
@@ -25,7 +28,8 @@ const getTaskFiles = function () {
|
|
|
25
28
|
const generateImportSwitch = async tasks => {
|
|
26
29
|
let cases = await Promise.all(tasks.map(async file => {
|
|
27
30
|
const filePath = path.resolve(tasksDir, file);
|
|
28
|
-
const task = await import(filePath);
|
|
31
|
+
// const task = await import(filePath);
|
|
32
|
+
const task = await parseTaskFile(filePath);
|
|
29
33
|
// console.log(task);
|
|
30
34
|
const taskName = path.basename(file, '.task.js');
|
|
31
35
|
const taskSlug = task?.default?.slug;
|
|
@@ -47,6 +51,106 @@ ${cases}
|
|
|
47
51
|
}
|
|
48
52
|
};`.trim();
|
|
49
53
|
};
|
|
54
|
+
const parseTaskFile = filePath => {
|
|
55
|
+
// Read the contents of the file as UTF-8 text
|
|
56
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
57
|
+
// console.log(filePath);
|
|
58
|
+
// console.log(content);
|
|
59
|
+
try {
|
|
60
|
+
// Parse the file content into an Abstract Syntax Tree (AST)
|
|
61
|
+
// sourceType: 'module' allows ES6 import/export syntax
|
|
62
|
+
// plugins enable parsing of JSX and TypeScript syntax
|
|
63
|
+
const ast = parse(content, {
|
|
64
|
+
sourceType: 'module',
|
|
65
|
+
plugins: ['jsx', 'typescript']
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Search through the top-level statements (ast.program.body)
|
|
69
|
+
// to find the 'export default' statement
|
|
70
|
+
// Find the export default declaration
|
|
71
|
+
const exportDecl = ast.program.body.find(node => node.type === 'ExportDefaultDeclaration');
|
|
72
|
+
// console.log(exportDecl);
|
|
73
|
+
// If no export default is found, return null
|
|
74
|
+
if (!exportDecl) return null;
|
|
75
|
+
|
|
76
|
+
// Get the exported object, either direct or via identifier
|
|
77
|
+
// Get what's being exported (the declaration)
|
|
78
|
+
let objectAst = exportDecl.declaration;
|
|
79
|
+
// If the export is a variable (e.g., export default taskConfig)
|
|
80
|
+
if (objectAst.type === 'Identifier') {
|
|
81
|
+
// Find the variable declaration in the file
|
|
82
|
+
// (e.g., const taskConfig = { ... })
|
|
83
|
+
const varDecl = ast.program.body.find(node => node.type === 'VariableDeclaration' && node.declarations.some(d => d.id.name === objectAst.name));
|
|
84
|
+
if (varDecl) {
|
|
85
|
+
// Get the actual object from the variable declaration
|
|
86
|
+
objectAst = varDecl.declarations[0].init;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// console.log(objectAst);
|
|
91
|
+
// fs.writeFileSync('./temp/objectAst.json', JSON.stringify(objectAst,null,2), 'utf-8');
|
|
92
|
+
|
|
93
|
+
// Convert AST to string, replacing function values with null
|
|
94
|
+
// Convert the AST object to a string, with a custom replacer function
|
|
95
|
+
const cleanObject = JSON.stringify(objectAst, (key, value) => {
|
|
96
|
+
// If the value is a function (any type of function), replace it with null
|
|
97
|
+
if (value?.type === 'FunctionExpression' || value?.type === 'ArrowFunctionExpression' || value?.type === 'FunctionDeclaration') {
|
|
98
|
+
return null;
|
|
99
|
+
// return function(){};
|
|
100
|
+
}
|
|
101
|
+
// Keep all other values as is
|
|
102
|
+
return value;
|
|
103
|
+
}, 2);
|
|
104
|
+
// fs.writeFileSync('./temp/cleanObject.json', cleanObject, 'utf-8');
|
|
105
|
+
|
|
106
|
+
// Parse the cleaned object to get the final result
|
|
107
|
+
// Parse the string back to an object
|
|
108
|
+
// Replace AST-specific property names with prefixed versions
|
|
109
|
+
// This prevents these technical properties from conflicting with task properties
|
|
110
|
+
// let task = {}
|
|
111
|
+
// cleanObject.properties.forEach(function(node){
|
|
112
|
+
// task[node.key.name]='something';
|
|
113
|
+
// })
|
|
114
|
+
// const output = generate(JSON.parse(cleanObject), { /* options */ });
|
|
115
|
+
const output = generator.default(JSON.parse(cleanObject), {
|
|
116
|
+
jsonCompatible: true
|
|
117
|
+
// quotes: 'double',
|
|
118
|
+
// compact: false
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// Parse and stringify to remove null values and ensure proper JSON formatting
|
|
122
|
+
// const jsonOutput = JSON.stringify(
|
|
123
|
+
// JSON.parse(output.code, (key, value) => value === null ? undefined : value),
|
|
124
|
+
// null,
|
|
125
|
+
// 2
|
|
126
|
+
// );
|
|
127
|
+
output.code = output.code.replace('fn:\n', '');
|
|
128
|
+
|
|
129
|
+
// let task = JSON.parse(output.code);
|
|
130
|
+
const task = eval(`(${output.code})`);
|
|
131
|
+
const jsonString = JSON.stringify(eval(`(${output.code})`), null, 2);
|
|
132
|
+
// console.log(jsonString);
|
|
133
|
+
|
|
134
|
+
// fs.writeFileSync('./temp/output.json', output.code, 'utf-8');
|
|
135
|
+
// fs.writeFileSync('./temp/jsonString.json', jsonString, 'utf-8');
|
|
136
|
+
// fs.writeFileSync('./temp/output.json', JSON.stringify(output.code,null,2), 'utf-8');
|
|
137
|
+
|
|
138
|
+
const taskConfig = JSON.parse(cleanObject.replace(/"type":|"start":|"end":|"loc":|"range":/g, '"_$1":'));
|
|
139
|
+
// fs.writeFileSync('./temp/taskConfig.json', JSON.stringify(taskConfig,null,2), 'utf-8');
|
|
140
|
+
|
|
141
|
+
// fs.writeFileSync('./temp/taskConfig.json', JSON.stringify(taskConfig,null,2), 'utf-8');
|
|
142
|
+
// Extract only the properties we care about
|
|
143
|
+
// Remove all the AST-specific properties using destructuring
|
|
144
|
+
// ...finalConfig contains all the remaining properties we want to keep
|
|
145
|
+
|
|
146
|
+
// Return the clean task configuration object
|
|
147
|
+
return task;
|
|
148
|
+
} catch (err) {
|
|
149
|
+
// If any error occurs during parsing, log it and return null
|
|
150
|
+
console.error(`Error parsing task file ${filePath}:`, err);
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
};
|
|
50
154
|
export async function prepareTasks() {
|
|
51
155
|
console.log('Preparing tasks now');
|
|
52
156
|
await prepareTasksIndex();
|
|
@@ -58,14 +162,14 @@ export async function prepareTasksIndex() {
|
|
|
58
162
|
// Import all task files dynamically
|
|
59
163
|
const tasks = await Promise.all(taskFiles.map(async file => {
|
|
60
164
|
const filePath = path.resolve(tasksDir, file);
|
|
61
|
-
const task = await
|
|
165
|
+
const task = await parseTaskFile(filePath);
|
|
62
166
|
const taskName = path.basename(filePath);
|
|
63
167
|
let folderName = file.split('/');
|
|
64
168
|
folderName.pop();
|
|
65
169
|
folderName = folderName.join('/');
|
|
66
170
|
// return [taskName, task.default];
|
|
67
|
-
return [task?.
|
|
68
|
-
...task
|
|
171
|
+
return [task?.slug, {
|
|
172
|
+
...task,
|
|
69
173
|
...{
|
|
70
174
|
__file_name: taskName,
|
|
71
175
|
__folder: folderName
|
|
@@ -80,8 +184,8 @@ export async function prepareTasksIndex() {
|
|
|
80
184
|
// console.log(taskMap);
|
|
81
185
|
|
|
82
186
|
// Write the generated code to a file
|
|
83
|
-
const outputCode =
|
|
84
|
-
const outputFile = path.resolve(process.cwd(), '.microlight', 'taskMap.
|
|
187
|
+
const outputCode = JSON.stringify(taskMap, null, 2);
|
|
188
|
+
const outputFile = path.resolve(process.cwd(), '.microlight', 'taskMap.json');
|
|
85
189
|
// Create the output directory if it doesn't exist
|
|
86
190
|
const outputDir = path.dirname(outputFile);
|
|
87
191
|
if (!fs.existsSync(outputDir)) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microlight/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"prepare:tasks": "microlight-core prepare tasks",
|
|
15
15
|
"prepare:folders": "microlight-core prepare folders",
|
|
16
16
|
"prepare:server": "microlight-core prepare server",
|
|
17
|
-
"
|
|
17
|
+
"prepare2": "microlight-core prepare all",
|
|
18
18
|
"start": "next start",
|
|
19
19
|
"lint": "next lint"
|
|
20
20
|
},
|
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
"microlight-core": "./bin/microlight-core.js"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
+
"@babel/generator": "^7.26.10",
|
|
30
|
+
"@babel/parser": "^7.26.10",
|
|
29
31
|
"@mui/joy": "^5.0.0-beta.51",
|
|
30
32
|
"async": "^3.2.6",
|
|
31
33
|
"commander": "^13.1.0",
|