fenrir-runtime 0.0.1

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 (94) hide show
  1. package/App/App.axaml +8 -0
  2. package/App/App.axaml.cs +23 -0
  3. package/App/FenrirLinux.csproj +27 -0
  4. package/App/LICENSE +674 -0
  5. package/App/MainWindow.axaml +10 -0
  6. package/App/MainWindow.axaml.cs +16 -0
  7. package/App/Program.cs +19 -0
  8. package/App/README.md +24 -0
  9. package/App/Views/InstallationView.axaml +48 -0
  10. package/App/Views/InstallationView.axaml.cs +204 -0
  11. package/App/Views/PasswordView.axaml +34 -0
  12. package/App/Views/PasswordView.axaml.cs +62 -0
  13. package/App/Views/WelcomeView.axaml +63 -0
  14. package/App/Views/WelcomeView.axaml.cs +22 -0
  15. package/App/app.manifest +18 -0
  16. package/App/images/screenshot1.png +0 -0
  17. package/App/images/screenshot2.png +0 -0
  18. package/App/obj/Debug/net9.0/Avalonia/Resources.Inputs.cache +1 -0
  19. package/App/obj/Debug/net9.0/Avalonia/original.dll +0 -0
  20. package/App/obj/Debug/net9.0/Avalonia/original.pdb +0 -0
  21. package/App/obj/Debug/net9.0/Avalonia/original.ref.dll +0 -0
  22. package/App/obj/Debug/net9.0/Avalonia/references +202 -0
  23. package/App/obj/Debug/net9.0/Avalonia/resources +0 -0
  24. package/App/obj/Debug/net9.0/FenrirLi.7B98506C.Up2Date +0 -0
  25. package/App/obj/Debug/net9.0/FenrirLinux.AssemblyInfo.cs +22 -0
  26. package/App/obj/Debug/net9.0/FenrirLinux.AssemblyInfoInputs.cache +1 -0
  27. package/App/obj/Debug/net9.0/FenrirLinux.GeneratedMSBuildEditorConfig.editorconfig +35 -0
  28. package/App/obj/Debug/net9.0/FenrirLinux.assets.cache +0 -0
  29. package/App/obj/Debug/net9.0/FenrirLinux.csproj.AssemblyReference.cache +0 -0
  30. package/App/obj/Debug/net9.0/FenrirLinux.csproj.CoreCompileInputs.cache +1 -0
  31. package/App/obj/Debug/net9.0/FenrirLinux.csproj.FileListAbsolute.txt +135 -0
  32. package/App/obj/Debug/net9.0/FenrirLinux.dll +0 -0
  33. package/App/obj/Debug/net9.0/FenrirLinux.genruntimeconfig.cache +1 -0
  34. package/App/obj/Debug/net9.0/FenrirLinux.pdb +0 -0
  35. package/App/obj/Debug/net9.0/apphost +0 -0
  36. package/App/obj/Debug/net9.0/ref/FenrirLinux.dll +0 -0
  37. package/App/obj/Debug/net9.0/refint/FenrirLinux.dll +0 -0
  38. package/App/obj/FenrirLinux.csproj.nuget.dgspec.json +115 -0
  39. package/App/obj/FenrirLinux.csproj.nuget.g.props +26 -0
  40. package/App/obj/FenrirLinux.csproj.nuget.g.targets +9 -0
  41. package/App/obj/Release/net9.0/linux-x64/Avalonia/Resources.Inputs.cache +1 -0
  42. package/App/obj/Release/net9.0/linux-x64/Avalonia/original.dll +0 -0
  43. package/App/obj/Release/net9.0/linux-x64/Avalonia/original.pdb +0 -0
  44. package/App/obj/Release/net9.0/linux-x64/Avalonia/original.ref.dll +0 -0
  45. package/App/obj/Release/net9.0/linux-x64/Avalonia/references +194 -0
  46. package/App/obj/Release/net9.0/linux-x64/Avalonia/resources +0 -0
  47. package/App/obj/Release/net9.0/linux-x64/FenrirLi.7B98506C.Up2Date +0 -0
  48. package/App/obj/Release/net9.0/linux-x64/FenrirLinux.AssemblyInfo.cs +22 -0
  49. package/App/obj/Release/net9.0/linux-x64/FenrirLinux.AssemblyInfoInputs.cache +1 -0
  50. package/App/obj/Release/net9.0/linux-x64/FenrirLinux.GeneratedMSBuildEditorConfig.editorconfig +39 -0
  51. package/App/obj/Release/net9.0/linux-x64/FenrirLinux.assets.cache +0 -0
  52. package/App/obj/Release/net9.0/linux-x64/FenrirLinux.csproj.AssemblyReference.cache +0 -0
  53. package/App/obj/Release/net9.0/linux-x64/FenrirLinux.csproj.CoreCompileInputs.cache +1 -0
  54. package/App/obj/Release/net9.0/linux-x64/FenrirLinux.csproj.FileListAbsolute.txt +238 -0
  55. package/App/obj/Release/net9.0/linux-x64/FenrirLinux.deps.json +1317 -0
  56. package/App/obj/Release/net9.0/linux-x64/FenrirLinux.dll +0 -0
  57. package/App/obj/Release/net9.0/linux-x64/FenrirLinux.genbundle.cache +1 -0
  58. package/App/obj/Release/net9.0/linux-x64/FenrirLinux.genpublishdeps.cache +1 -0
  59. package/App/obj/Release/net9.0/linux-x64/FenrirLinux.genruntimeconfig.cache +1 -0
  60. package/App/obj/Release/net9.0/linux-x64/FenrirLinux.pdb +0 -0
  61. package/App/obj/Release/net9.0/linux-x64/PublishOutputs.fac9e24064.txt +4 -0
  62. package/App/obj/Release/net9.0/linux-x64/apphost +0 -0
  63. package/App/obj/Release/net9.0/linux-x64/ref/FenrirLinux.dll +0 -0
  64. package/App/obj/Release/net9.0/linux-x64/refint/FenrirLinux.dll +0 -0
  65. package/App/obj/Release/net9.0/linux-x64/singlefilehost +0 -0
  66. package/App/obj/project.assets.json +2463 -0
  67. package/App/obj/project.nuget.cache +47 -0
  68. package/LICENSE +674 -0
  69. package/Makefile +16 -0
  70. package/README.md +89 -0
  71. package/dist/archiveSystem.js +219 -0
  72. package/dist/cli.js +188 -0
  73. package/dist/packageManager.js +98 -0
  74. package/dist/parser.js +24 -0
  75. package/dist/runtime.js +99 -0
  76. package/dist/transformer.js +120 -0
  77. package/example/fenrir+aperium/aperium.json +17 -0
  78. package/example/fenrir+aperium/aperium_modules/hello-world/index.js +4 -0
  79. package/example/fenrir+aperium/aperium_modules/hello-world/module.json +6 -0
  80. package/example/fenrir+aperium/app.fnr +19 -0
  81. package/example/fenrir+aperium/package-lock.json +890 -0
  82. package/example/fenrir+aperium/package.json +17 -0
  83. package/example/fenrir.json +10 -0
  84. package/example/main.fnr +18 -0
  85. package/example/package-lock.json +867 -0
  86. package/example/package.json +17 -0
  87. package/package.json +32 -0
  88. package/src/archiveSystem.ts +264 -0
  89. package/src/cli.ts +216 -0
  90. package/src/packageManager.ts +119 -0
  91. package/src/parser.ts +36 -0
  92. package/src/runtime.ts +111 -0
  93. package/src/transformer.ts +147 -0
  94. package/tsconfig.json +15 -0
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "example",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "main.fnr",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "keywords": [],
10
+ "author": "",
11
+ "license": "GPL",
12
+ "type": "module",
13
+ "dependencies": {
14
+ "express": "^5.1.0",
15
+ "fs-extra": "^11.3.1"
16
+ }
17
+ }
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "fenrir-runtime",
3
+ "version": "0.0.1",
4
+ "description": "Fenrir Runtime",
5
+ "main": "dist/cli.js",
6
+ "bin": {
7
+ "fenrir": "./dist/cli.js"
8
+ },
9
+ "type": "module",
10
+ "scripts": {
11
+ "build": "tsc && npm link",
12
+ "dev": "tsc --watch",
13
+ "test": "node dist/test.js"
14
+ },
15
+ "keywords": [
16
+ "fenrir",
17
+ "runtime",
18
+ "typescript",
19
+ "version-control"
20
+ ],
21
+ "author": "openbyte.",
22
+ "license": "GPL-3 or later",
23
+ "dependencies": {
24
+ "fs-extra": "^11.2.0",
25
+ "glob": "^10.3.10"
26
+ },
27
+ "devDependencies": {
28
+ "@types/fs-extra": "^11.0.4",
29
+ "@types/node": "^20.10.6",
30
+ "typescript": "^5.3.3"
31
+ }
32
+ }
@@ -0,0 +1,264 @@
1
+ import fs from 'fs-extra';
2
+ import path from 'path';
3
+ import crypto from 'crypto';
4
+ import { execSync } from 'child_process';
5
+ import { glob } from 'glob';
6
+
7
+ export class ArchiveSystem {
8
+ private projectRoot: string;
9
+ private archiveDir: string;
10
+
11
+ constructor(projectRoot: string = process.cwd()) {
12
+ this.projectRoot = projectRoot;
13
+ this.archiveDir = path.join(projectRoot, '.fenrir', 'archives');
14
+ }
15
+
16
+ async createArchive(message?: string): Promise<string> {
17
+ const now = new Date();
18
+ const timestamp = this.formatTimestamp(now);
19
+ const archivePath = path.join(this.archiveDir, timestamp);
20
+
21
+ await fs.ensureDir(archivePath);
22
+
23
+ const filesToArchive = await this.getFilesToArchive();
24
+
25
+ for (const file of filesToArchive) {
26
+ const srcPath = path.join(this.projectRoot, file);
27
+ const destPath = path.join(archivePath, file);
28
+
29
+ await fs.ensureDir(path.dirname(destPath));
30
+ await fs.copy(srcPath, destPath);
31
+ }
32
+
33
+ const metadata = {
34
+ timestamp: now.toISOString(),
35
+ message: message || 'Automatic archiving',
36
+ files: filesToArchive.length,
37
+ hash: this.generateHash(filesToArchive),
38
+ gitHash: await this.getGitHash().catch(() => null)
39
+ };
40
+
41
+ await fs.writeJSON(path.join(archivePath, '.metadata.json'), metadata, { spaces: 2 });
42
+
43
+ console.log(`Archive created: ${timestamp}`);
44
+ console.log(` ${filesToArchive.length} file archived`);
45
+ console.log(`message: ${metadata.message}`);
46
+
47
+ return timestamp;
48
+ }
49
+
50
+ async listArchives(): Promise<void> {
51
+ if (!fs.existsSync(this.archiveDir)) {
52
+ console.log('No archives have been created yet.');
53
+ return;
54
+ }
55
+
56
+ const archives = await fs.readdir(this.archiveDir);
57
+ archives.sort().reverse();
58
+
59
+ console.log('Archive history:');
60
+
61
+ for (const archive of archives.slice(0, 10)) {
62
+ const metadataPath = path.join(this.archiveDir, archive, '.metadata.json');
63
+
64
+ if (fs.existsSync(metadataPath)) {
65
+ const metadata = await fs.readJSON(metadataPath);
66
+ const date = new Date(metadata.timestamp);
67
+
68
+ console.log(` ${archive} - ${metadata.message}`);
69
+ console.log(` ${date.toLocaleString('en-US')}`);
70
+ console.log(` ${metadata.files} file`);
71
+ console.log('');
72
+ }
73
+ }
74
+
75
+ if (archives.length > 10) {
76
+ console.log(` ... and ${archives.length - 10} archive more`);
77
+ }
78
+ }
79
+
80
+ async rollback(archiveId?: string): Promise<void> {
81
+ if (!fs.existsSync(this.archiveDir)) {
82
+ console.log('Archive not found.');
83
+ return;
84
+ }
85
+
86
+ let targetArchive = archiveId;
87
+
88
+ if (!targetArchive) {
89
+ const archives = await fs.readdir(this.archiveDir);
90
+ archives.sort().reverse();
91
+ targetArchive = archives[0];
92
+ }
93
+
94
+ const archivePath = path.join(this.archiveDir, targetArchive);
95
+
96
+ if (!fs.existsSync(archivePath)) {
97
+ console.log(`Archive not found: ${targetArchive}`);
98
+ return;
99
+ }
100
+
101
+ console.log('Current status is being backed up...');
102
+ await this.createArchive(`Pre-rollback backup - ${new Date().toISOString()}`);
103
+
104
+ const metadataPath = path.join(archivePath, '.metadata.json');
105
+ const metadata = await fs.readJSON(metadataPath);
106
+
107
+ console.log(`${targetArchive} returning to archive...`);
108
+ console.log(` ${metadata.message}`);
109
+
110
+ const currentFiles = await this.getFilesToArchive();
111
+ for (const file of currentFiles) {
112
+ const filePath = path.join(this.projectRoot, file);
113
+ if (fs.existsSync(filePath)) {
114
+ await fs.remove(filePath);
115
+ }
116
+ }
117
+
118
+ const archiveFiles = await glob('**/*', {
119
+ cwd: archivePath,
120
+ nodir: true,
121
+ ignore: '.metadata.json'
122
+ });
123
+
124
+ for (const file of archiveFiles) {
125
+ const srcPath = path.join(archivePath, file);
126
+ const destPath = path.join(this.projectRoot, file);
127
+
128
+ await fs.ensureDir(path.dirname(destPath));
129
+ await fs.copy(srcPath, destPath);
130
+ }
131
+
132
+ console.log(`The return has been completed!`);
133
+ console.log(`${archiveFiles.length} file restored`);
134
+ }
135
+
136
+ async cleanArchives(keepCount: number = 10): Promise<void> {
137
+ if (!fs.existsSync(this.archiveDir)) {
138
+ return;
139
+ }
140
+
141
+ const archives = await fs.readdir(this.archiveDir);
142
+ archives.sort().reverse();
143
+
144
+ if (archives.length <= keepCount) {
145
+ console.log(`${archives.length} There is an archive, no cleaning is necessary.`);
146
+ return;
147
+ }
148
+
149
+ const toDelete = archives.slice(keepCount);
150
+
151
+ for (const archive of toDelete) {
152
+ await fs.remove(path.join(this.archiveDir, archive));
153
+ }
154
+
155
+ console.log(`${toDelete.length} The old archive has been cleared.`);
156
+ console.log(`${keepCount} The archive has been preserved.`);
157
+ }
158
+
159
+ private formatTimestamp(date: Date): string {
160
+ return date.toISOString()
161
+ .replace(/T/, '_')
162
+ .replace(/:/g, '-')
163
+ .substring(0, 19);
164
+ }
165
+
166
+ private async getFilesToArchive(): Promise<string[]> {
167
+ const patterns = [
168
+ '**/*.py',
169
+ '**/*.pyc',
170
+ '**/*.pyo',
171
+ '**/*.java',
172
+ '**/*.class',
173
+ '**/*.jar',
174
+ '**/*.cpp',
175
+ '**/*.cxx',
176
+ '**/*.cc',
177
+ '**/*.c',
178
+ '**/*.hpp',
179
+ '**/*.h',
180
+ '**/*.hxx',
181
+ '**/*.cs',
182
+ '**/*.csproj',
183
+ '**/*.sln',
184
+ '**/*.rb',
185
+ '**/*.rake',
186
+ '**/*.php',
187
+ '**/*.phtml',
188
+ '**/*.php3',
189
+ '**/*.php4',
190
+ '**/*.php5',
191
+ '**/*.swift',
192
+ '**/*.go',
193
+ '**/*.rs',
194
+ '**/*.js',
195
+ '**/*.ts',
196
+ '**/*.jsx',
197
+ '**/*.tsx',
198
+ '**/*.mjs',
199
+ '**/*.cjs',
200
+ '**/*.css',
201
+ '**/*.scss',
202
+ '**/*.sass',
203
+ '**/*.less',
204
+ '**/*.html',
205
+ '**/*.htm',
206
+ '**/*.xhtml',
207
+ '**/*.json',
208
+ '**/*.xml',
209
+ '**/*.yml',
210
+ '**/*.yaml',
211
+ '**/*.md',
212
+ '**/*.markdown',
213
+ '**/*.mdown',
214
+ '**/*.txt',
215
+ '**/*.ini',
216
+ '**/*.conf',
217
+ '**/*.cfg',
218
+ '**/*.sh',
219
+ '**/*.bash',
220
+ '**/*.npm',
221
+ '**/*.lock',
222
+ '**/*.fnr'
223
+ ];
224
+
225
+ const ignorePatterns = [
226
+ '.fenrir/**',
227
+ 'node_modules/**',
228
+ '.git/**',
229
+ '*.log',
230
+ '.DS_Store',
231
+ 'Thumbs.db',
232
+ '.env*',
233
+ 'dist/**',
234
+ 'build/**',
235
+ '.cache/**'
236
+ ];
237
+
238
+ const files: string[] = [];
239
+
240
+ for (const pattern of patterns) {
241
+ const matches = await glob(pattern, {
242
+ cwd: this.projectRoot,
243
+ ignore: ignorePatterns,
244
+ nodir: true
245
+ });
246
+ files.push(...matches);
247
+ }
248
+
249
+ return [...new Set(files)].sort();
250
+ }
251
+
252
+ private generateHash(files: string[]): string {
253
+ const hash = crypto.createHash('md5');
254
+ hash.update(files.join('|'));
255
+ return hash.digest('hex').substring(0, 8);
256
+ }
257
+
258
+ private async getGitHash(): Promise<string> {
259
+ return execSync('git rev-parse HEAD', {
260
+ cwd: this.projectRoot,
261
+ encoding: 'utf8'
262
+ }).trim();
263
+ }
264
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,216 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawn } from 'child_process';
4
+ import path from 'path';
5
+ import fs from 'fs-extra';
6
+ import os from 'os';
7
+ import { fileURLToPath } from 'url';
8
+
9
+ import { transformFenrirCode } from './transformer.js';
10
+ import { PackageManager } from './packageManager.js';
11
+ import { ArchiveSystem } from './archiveSystem.js';
12
+
13
+ const __filename = fileURLToPath(import.meta.url);
14
+ const __dirname = path.dirname(__filename);
15
+
16
+ const command = process.argv[2];
17
+ const args = process.argv.slice(3);
18
+
19
+ const packageManager = new PackageManager();
20
+ const archiveSystem = new ArchiveSystem();
21
+
22
+ const executeCode = async (filePath: string) => {
23
+ try {
24
+ if (!await fs.pathExists(filePath)) {
25
+ console.error(`Error: File ${filePath} not found.`);
26
+ process.exit(1);
27
+ }
28
+
29
+ const fileContent = await fs.readFile(filePath, 'utf-8');
30
+
31
+ if (!fileContent.trim()) {
32
+ console.error('Error: The file is empty or contains only space characters.');
33
+ process.exit(1);
34
+ }
35
+
36
+ const aperiumConfig = fs.existsSync('fenrir.json')
37
+ ? JSON.parse(await fs.readFile('fenrir.json', 'utf8'))
38
+ : {};
39
+
40
+ const jsCode = await transformFenrirCode(fileContent, filePath, aperiumConfig.imports || {});
41
+
42
+ if (process.env.FENRIR_DEBUG) {
43
+ console.log('\nConverted JavaScript code:');
44
+ console.log(jsCode);
45
+ }
46
+
47
+ const tempDir = path.join(os.tmpdir(), `fenrir_temp_${Date.now()}`);
48
+ await fs.ensureDir(tempDir);
49
+ const tempFilePath = path.join(tempDir, 'runtime_output.mjs');
50
+
51
+ // node_modules kopyalama işlemini iyileştir
52
+ const originalNodeModulesPath = path.join(process.cwd(), 'node_modules');
53
+ const tempNodeModulesPath = path.join(tempDir, 'node_modules');
54
+
55
+ if (await fs.pathExists(originalNodeModulesPath)) {
56
+ try {
57
+ await fs.copy(originalNodeModulesPath, tempNodeModulesPath, {
58
+ dereference: true,
59
+ preserveTimestamps: false
60
+ });
61
+ } catch (copyError: any) {
62
+ console.warn('Warning: Could not copy node_modules:', copyError?.message || copyError);
63
+ }
64
+ }
65
+
66
+ const originalPackageJsonPath = path.join(process.cwd(), 'package.json');
67
+ if (await fs.pathExists(originalPackageJsonPath)) {
68
+ try {
69
+ await fs.copy(originalPackageJsonPath, path.join(tempDir, 'package.json'));
70
+ } catch (err: any) {
71
+ console.warn('Warning: Could not copy package.json:', err?.message || err);
72
+ }
73
+ }
74
+
75
+ const runtimePath = path.join(__dirname, 'runtime.js');
76
+ let finalCode = jsCode;
77
+
78
+ if (fs.existsSync(runtimePath)) {
79
+ const runtimeCode = await fs.readFile(runtimePath, 'utf8');
80
+ finalCode = `${runtimeCode}\n\n${jsCode}`;
81
+ }
82
+
83
+ await fs.writeFile(tempFilePath, finalCode);
84
+
85
+ const env = {
86
+ ...process.env,
87
+ NODE_PATH: [
88
+ path.join(tempDir, 'node_modules'),
89
+ path.join(process.cwd(), 'node_modules'),
90
+ process.env.NODE_PATH
91
+ ].filter(Boolean).join(path.delimiter)
92
+ };
93
+
94
+ if (process.env.FENRIR_DEBUG) {
95
+ console.log('Temp directory:', tempDir);
96
+ console.log('Original CWD:', process.cwd());
97
+ console.log('NODE_PATH:', env.NODE_PATH);
98
+ console.log('\nGenerated code:');
99
+ console.log('================');
100
+ console.log(finalCode);
101
+ console.log('================\n');
102
+ }
103
+
104
+ const child = spawn('node', [tempFilePath], {
105
+ stdio: 'inherit',
106
+ shell: false,
107
+ env: env,
108
+ cwd: process.cwd()
109
+ });
110
+
111
+ child.on('close', async (code) => {
112
+ try {
113
+ await fs.remove(tempDir);
114
+ } catch (err) {
115
+ }
116
+ process.exit(code || 0);
117
+ });
118
+
119
+ child.on('error', async (err: any) => {
120
+ console.error('An error occurred while running Node.js:');
121
+
122
+ if (err.message.includes('SyntaxError')) {
123
+ console.error('Syntax error detected. Transformed code:');
124
+ finalCode.split('\n').forEach((line: string, index: number) => {
125
+ console.error(`${(index + 1).toString().padStart(2, ' ')}: ${line}`);
126
+ });
127
+ } else {
128
+ console.error(err);
129
+ }
130
+
131
+ try {
132
+ await fs.remove(tempDir);
133
+ } catch (cleanupErr) {
134
+ }
135
+ process.exit(1);
136
+ });
137
+
138
+ } catch (error) {
139
+ if (error instanceof SyntaxError) {
140
+ console.error('Syntax error:', error.message);
141
+ } else {
142
+ console.error('An unexpected error occurred:', error);
143
+ }
144
+ process.exit(1);
145
+ }
146
+ };
147
+
148
+ const showHelp = () => {
149
+ console.log(`
150
+ Fenrir Programming Language v0.0.1
151
+
152
+ Usage:
153
+ fenrir <file.fnr>
154
+ fenrir install [package]
155
+ fenrir remove <package>
156
+ fenrir archive [message]
157
+ fenrir archives
158
+ fenrir rollback [archive-id]
159
+ fenrir clean [number]
160
+ fenrir help
161
+ `);
162
+ };
163
+
164
+ const run = async () => {
165
+ if (!command || command === 'help') {
166
+ showHelp();
167
+ return;
168
+ }
169
+
170
+ switch (command) {
171
+ case 'install':
172
+ await packageManager.install(args[0]);
173
+ break;
174
+
175
+ case 'remove':
176
+ if (!args[0]) {
177
+ console.error('Package name not specified.');
178
+ console.log('Usage: fenrir remove <package-name>');
179
+ process.exit(1);
180
+ }
181
+ await packageManager.remove(args[0]);
182
+ break;
183
+
184
+ case 'archive':
185
+ await archiveSystem.createArchive(args[0]);
186
+ break;
187
+
188
+ case 'archives':
189
+ await archiveSystem.listArchives();
190
+ break;
191
+
192
+ case 'rollback':
193
+ await archiveSystem.rollback(args[0]);
194
+ break;
195
+
196
+ case 'clean':
197
+ const keepCount = args[0] ? parseInt(args[0]) : 10;
198
+ await archiveSystem.cleanArchives(keepCount);
199
+ break;
200
+
201
+ default:
202
+ if (command.endsWith('.fnr')) {
203
+ const filePath = path.resolve(process.cwd(), command);
204
+ await executeCode(filePath);
205
+ } else {
206
+ console.error(`Unknown command: ${command}`);
207
+ console.log('For help: fenrir help');
208
+ process.exit(1);
209
+ }
210
+ }
211
+ };
212
+
213
+ run().catch((error) => {
214
+ console.error('A critical error occurred while running the program:', error);
215
+ process.exit(1);
216
+ });
@@ -0,0 +1,119 @@
1
+ import { execSync } from 'child_process';
2
+ import fs from 'fs-extra';
3
+ import path from 'path';
4
+
5
+ export class PackageManager {
6
+ private projectRoot: string;
7
+ private packageJsonPath: string;
8
+ private fenrirJsonPath: string;
9
+
10
+ constructor(projectRoot: string = process.cwd()) {
11
+ this.projectRoot = projectRoot;
12
+ this.packageJsonPath = path.join(projectRoot, 'package.json');
13
+ this.fenrirJsonPath = path.join(projectRoot, 'fenrir.json');
14
+ }
15
+
16
+ async install(packageName?: string): Promise<void> {
17
+ if (!fs.existsSync(this.fenrirJsonPath)) {
18
+ await this.initProject();
19
+ }
20
+
21
+ if (packageName) {
22
+ console.log(`${packageName} loading...`);
23
+
24
+ try {
25
+ execSync(`npm install ${packageName}`, {
26
+ cwd: this.projectRoot,
27
+ stdio: 'pipe'
28
+ });
29
+
30
+ await this.updateFenrirJson(packageName);
31
+
32
+ console.log(`${packageName} Successfully loaded!`);
33
+ } catch (error) {
34
+ console.error(`${packageName} An error occurred while loading:`, error);
35
+ throw error;
36
+ }
37
+ } else {
38
+ console.log('All dependencies are being loaded...');
39
+ execSync('npm install', {
40
+ cwd: this.projectRoot,
41
+ stdio: 'inherit'
42
+ });
43
+ }
44
+ }
45
+
46
+ async remove(packageName: string): Promise<void> {
47
+ console.log(` ${packageName} being removed...`);
48
+
49
+ try {
50
+ execSync(`npm uninstall ${packageName}`, {
51
+ cwd: this.projectRoot,
52
+ stdio: 'pipe'
53
+ });
54
+
55
+ await this.removeFomFenrirJson(packageName);
56
+
57
+ console.log(`${packageName} removed!`);
58
+ } catch (error) {
59
+ console.error(`${packageName} An error occurred while removing:`, error);
60
+ }
61
+ }
62
+
63
+ private async initProject(): Promise<void> {
64
+ const projectName = path.basename(this.projectRoot);
65
+
66
+ const fenrirJson = {
67
+ name: projectName,
68
+ version: "0.0.1",
69
+ description: "A Fenrir project",
70
+ dependencies: {},
71
+ fenrirVersion: "0.0.1"
72
+ };
73
+
74
+ await fs.writeJSON(this.fenrirJsonPath, fenrirJson, { spaces: 2 });
75
+
76
+ if (!fs.existsSync(this.packageJsonPath)) {
77
+ const packageJson = {
78
+ name: projectName.toLowerCase().replace(/[^a-z0-9-]/g, '-'),
79
+ version: "0.0.1",
80
+ type: "module",
81
+ dependencies: {}
82
+ };
83
+ await fs.writeJSON(this.packageJsonPath, packageJson, { spaces: 2 });
84
+ }
85
+
86
+ console.log('The Fenrir project has been launched!');
87
+ }
88
+
89
+ private async readFenrirJson(): Promise<any> {
90
+ if (!fs.existsSync(this.fenrirJsonPath)) {
91
+ return { dependencies: {} };
92
+ }
93
+ return await fs.readJSON(this.fenrirJsonPath);
94
+ }
95
+
96
+ private async updateFenrirJson(packageName: string): Promise<void> {
97
+ const fenrirJson = await this.readFenrirJson();
98
+
99
+ const packageJson = await fs.readJSON(this.packageJsonPath);
100
+ const version = packageJson.dependencies?.[packageName] || 'latest';
101
+
102
+ if (!fenrirJson.dependencies) {
103
+ fenrirJson.dependencies = {};
104
+ }
105
+
106
+ fenrirJson.dependencies[packageName] = version;
107
+
108
+ await fs.writeJSON(this.fenrirJsonPath, fenrirJson, { spaces: 2 });
109
+ }
110
+
111
+ private async removeFomFenrirJson(packageName: string): Promise<void> {
112
+ const fenrirJson = await this.readFenrirJson();
113
+
114
+ if (fenrirJson.dependencies && fenrirJson.dependencies[packageName]) {
115
+ delete fenrirJson.dependencies[packageName];
116
+ await fs.writeJSON(this.fenrirJsonPath, fenrirJson, { spaces: 2 });
117
+ }
118
+ }
119
+ }
package/src/parser.ts ADDED
@@ -0,0 +1,36 @@
1
+ interface Token {
2
+ type: string;
3
+ value: string;
4
+ }
5
+
6
+ interface ASTNode {
7
+ type: string;
8
+ value?: any;
9
+ children?: ASTNode[];
10
+ }
11
+
12
+ export const parse = (code: string): ASTNode => {
13
+ const tokens: Token[] = [];
14
+ const lines = code.split('\n');
15
+
16
+ for (const line of lines) {
17
+ if (line.trim().startsWith('fn')) {
18
+ tokens.push({ type: 'FN_DECL', value: line.trim() });
19
+ // DEĞİŞTİRİLDİ: Artık 'declare' kelimesini bir import beyanı olarak tanıyor
20
+ } else if (line.trim().startsWith('declare')) {
21
+ tokens.push({ type: 'IMPORT_DECL', value: line.trim() });
22
+ } else {
23
+ tokens.push({ type: 'EXPRESSION', value: line.trim() });
24
+ }
25
+ }
26
+
27
+ const ast: ASTNode = {
28
+ type: 'Program',
29
+ children: tokens.map(token => ({
30
+ type: token.type,
31
+ value: token.value
32
+ }))
33
+ };
34
+
35
+ return ast;
36
+ };