@reliverse/dler 1.2.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 (101) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +312 -0
  3. package/bin/cli/args/agg/main.js +0 -0
  4. package/bin/cli/args/conv/README.md +3 -0
  5. package/bin/cli/args/conv/main.js +0 -0
  6. package/bin/cli/args/deps/analyzer.js +42 -0
  7. package/bin/cli/args/deps/filesystem.js +42 -0
  8. package/bin/cli/args/deps/formatter.js +65 -0
  9. package/bin/cli/args/deps/mod.js +48 -0
  10. package/bin/cli/args/deps/parser.js +59 -0
  11. package/bin/cli/args/deps/types.js +0 -0
  12. package/bin/cli/args/init/README.md +121 -0
  13. package/bin/cli/args/init/libs/reinit/reinit-main.js +5 -0
  14. package/bin/cli/args/init/libs/reinit/reint-impl/const.js +26 -0
  15. package/bin/cli/args/init/libs/reinit/reint-impl/mod.txt +395 -0
  16. package/bin/cli/args/init/libs/reinit/reint-impl/templates/t-gitignore.js +9 -0
  17. package/bin/cli/args/init/libs/reinit/reint-impl/templates/t-license.js +22 -0
  18. package/bin/cli/args/init/libs/reinit/reint-impl/templates/t-readme.js +59 -0
  19. package/bin/cli/args/init/libs/reinit/reint-impl/types.js +0 -0
  20. package/bin/cli/args/init/libs/reinit/reint-impl/utils.js +3 -0
  21. package/bin/cli/args/init/main.txt +121 -0
  22. package/bin/cli/args/init/types.js +1 -0
  23. package/bin/cli/args/inject/README.md +148 -0
  24. package/bin/cli/args/inject/arg-ts-expect-error.txt +49 -0
  25. package/bin/cli/args/inject/cli-mod.js +32 -0
  26. package/bin/cli/args/inject/main.txt +28 -0
  27. package/bin/cli/args/inject/reinject.config.js +4 -0
  28. package/bin/cli/args/inject/ts-expect-error.txt +277 -0
  29. package/bin/cli/args/merger/README.md +125 -0
  30. package/bin/cli/args/merger/main.txt +306 -0
  31. package/bin/cli/args/mono/main.js +0 -0
  32. package/bin/cli/args/spells/mod.js +44 -0
  33. package/bin/cli/args/split/README.md +13 -0
  34. package/bin/cli/args/split/split-main.js +26 -0
  35. package/bin/cli/args/split/split-mod.js +117 -0
  36. package/bin/cli/args/tools/index.js +81 -0
  37. package/bin/cli/args/tools/tools-impl.js +296 -0
  38. package/bin/cli.js +111 -0
  39. package/bin/init.js +157 -0
  40. package/bin/libs/cfg/cfg-default.js +50 -0
  41. package/bin/libs/cfg/cfg-main.js +1 -0
  42. package/bin/libs/cfg/cfg-mod.js +4 -0
  43. package/bin/libs/cfg/cfg-types.js +1 -0
  44. package/bin/libs/sdk/sdk-impl/build/build-library.js +865 -0
  45. package/bin/libs/sdk/sdk-impl/build/build-regular.js +373 -0
  46. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/auto.js +110 -0
  47. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/build.js +322 -0
  48. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/copy/copy.js +62 -0
  49. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/copy/types.js +0 -0
  50. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/mkdist/mkdist.js +57 -0
  51. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/mkdist/types.js +0 -0
  52. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/rollup/build.js +104 -0
  53. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/rollup/config.js +124 -0
  54. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/rollup/plugins/cjs.js +48 -0
  55. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/rollup/plugins/esbuild.js +91 -0
  56. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/rollup/plugins/json.js +17 -0
  57. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/rollup/plugins/raw.js +20 -0
  58. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/rollup/plugins/shebang.js +42 -0
  59. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/rollup/stub.js +137 -0
  60. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/rollup/types.js +0 -0
  61. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/rollup/utils.js +41 -0
  62. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/rollup/watch.js +33 -0
  63. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/types.js +6 -0
  64. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/untyped/index.js +125 -0
  65. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/untyped/types.js +0 -0
  66. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/utils.js +158 -0
  67. package/bin/libs/sdk/sdk-impl/build/bundlers/unified/validate.js +68 -0
  68. package/bin/libs/sdk/sdk-impl/library-flow.js +169 -0
  69. package/bin/libs/sdk/sdk-impl/pub/pub-library.js +132 -0
  70. package/bin/libs/sdk/sdk-impl/pub/pub-regular.js +69 -0
  71. package/bin/libs/sdk/sdk-impl/regular-flow.js +219 -0
  72. package/bin/libs/sdk/sdk-impl/spells/spells-executors.js +307 -0
  73. package/bin/libs/sdk/sdk-impl/spells/spells-filesystem.js +72 -0
  74. package/bin/libs/sdk/sdk-impl/spells/spells-main.js +87 -0
  75. package/bin/libs/sdk/sdk-impl/spells/spells-parser.js +60 -0
  76. package/bin/libs/sdk/sdk-impl/spells/spells-types.js +0 -0
  77. package/bin/libs/sdk/sdk-impl/utils/tools/tools-agg.js +149 -0
  78. package/bin/libs/sdk/sdk-impl/utils/tools/tools-impl.js +21 -0
  79. package/bin/libs/sdk/sdk-impl/utils/utils-build.js +102 -0
  80. package/bin/libs/sdk/sdk-impl/utils/utils-bump.js +238 -0
  81. package/bin/libs/sdk/sdk-impl/utils/utils-clean.js +35 -0
  82. package/bin/libs/sdk/sdk-impl/utils/utils-consts.js +17 -0
  83. package/bin/libs/sdk/sdk-impl/utils/utils-cwd.js +36 -0
  84. package/bin/libs/sdk/sdk-impl/utils/utils-deps.js +73 -0
  85. package/bin/libs/sdk/sdk-impl/utils/utils-determine.js +25 -0
  86. package/bin/libs/sdk/sdk-impl/utils/utils-error.js +17 -0
  87. package/bin/libs/sdk/sdk-impl/utils/utils-fs.js +202 -0
  88. package/bin/libs/sdk/sdk-impl/utils/utils-info.js +42 -0
  89. package/bin/libs/sdk/sdk-impl/utils/utils-jsr-json.js +51 -0
  90. package/bin/libs/sdk/sdk-impl/utils/utils-paths.js +658 -0
  91. package/bin/libs/sdk/sdk-impl/utils/utils-perf.js +22 -0
  92. package/bin/libs/sdk/sdk-impl/utils/utils-pkg-json-libs.js +259 -0
  93. package/bin/libs/sdk/sdk-impl/utils/utils-pkg-json-reg.js +207 -0
  94. package/bin/libs/sdk/sdk-impl/utils/utils-tsconfig.js +44 -0
  95. package/bin/libs/sdk/sdk-main.js +114 -0
  96. package/bin/libs/sdk/sdk-types.js +1 -0
  97. package/bin/load.js +27 -0
  98. package/bin/main.js +46 -0
  99. package/bin/tools.txt +92 -0
  100. package/bin/types.js +0 -0
  101. package/package.json +93 -0
@@ -0,0 +1,219 @@
1
+ import { relinka } from "@reliverse/relinka";
2
+ import pAll from "p-all";
3
+ import {
4
+ regular_buildJsrDist,
5
+ regular_buildNpmDist
6
+ } from "./build/build-regular.js";
7
+ import { regular_pubToJsr, regular_pubToNpm } from "./pub/pub-regular.js";
8
+ import { CONCURRENCY_DEFAULT } from "./utils/utils-consts.js";
9
+ export async function processRegularFlow(timer, isDev, coreIsCLI, libsActMode, commonPubRegistry, coreEntrySrcDir, distNpmDirName, distNpmBuilder, coreEntryFile, distJsrDryRun, distJsrFailOnWarn, commonPubPause, distJsrDirName, distJsrBuilder, transpileTarget, transpileFormat, transpileSplitting, transpileMinify, transpileSourcemap, transpilePublicPath, distJsrAllowDirty, distJsrSlowTypes, unifiedBundlerOutExt, rmDepsMode, transpileStub, transpileWatch, distJsrGenTsconfig, coreDeclarations) {
10
+ if (libsActMode !== "main-project-only" && libsActMode !== "main-and-libs") {
11
+ relinka(
12
+ "info",
13
+ "Skipping main project build/publish as libsActMode is set to 'libs-only'"
14
+ );
15
+ return;
16
+ }
17
+ switch (commonPubRegistry) {
18
+ case "jsr":
19
+ relinka(
20
+ "info",
21
+ "Initializing build process for main project to JSR only..."
22
+ );
23
+ await regular_buildJsrDist(
24
+ isDev,
25
+ true,
26
+ coreIsCLI,
27
+ coreEntrySrcDir,
28
+ distJsrDirName,
29
+ distJsrBuilder,
30
+ coreEntryFile,
31
+ transpileTarget,
32
+ transpileFormat,
33
+ transpileSplitting,
34
+ transpileMinify,
35
+ transpileSourcemap,
36
+ transpilePublicPath,
37
+ unifiedBundlerOutExt,
38
+ rmDepsMode,
39
+ timer,
40
+ transpileStub,
41
+ transpileWatch,
42
+ distJsrGenTsconfig,
43
+ coreDeclarations
44
+ );
45
+ if (!isDev) {
46
+ await regular_pubToJsr(
47
+ distJsrDryRun,
48
+ distJsrFailOnWarn,
49
+ isDev,
50
+ commonPubPause,
51
+ distJsrDirName,
52
+ distJsrAllowDirty,
53
+ distJsrSlowTypes,
54
+ timer
55
+ );
56
+ }
57
+ break;
58
+ case "npm":
59
+ relinka(
60
+ "info",
61
+ "Initializing build process for main project to NPM only..."
62
+ );
63
+ await regular_buildNpmDist(
64
+ isDev,
65
+ coreEntrySrcDir,
66
+ distNpmDirName,
67
+ distNpmBuilder,
68
+ coreEntryFile,
69
+ unifiedBundlerOutExt,
70
+ rmDepsMode,
71
+ coreIsCLI,
72
+ transpileTarget,
73
+ transpileFormat,
74
+ transpileSplitting,
75
+ transpileMinify,
76
+ transpileSourcemap,
77
+ transpilePublicPath,
78
+ transpileStub,
79
+ transpileWatch,
80
+ timer,
81
+ coreDeclarations
82
+ );
83
+ if (!isDev) {
84
+ await regular_pubToNpm(
85
+ distJsrDryRun,
86
+ isDev,
87
+ commonPubPause,
88
+ distNpmDirName,
89
+ timer
90
+ );
91
+ }
92
+ break;
93
+ case "npm-jsr": {
94
+ relinka(
95
+ "info",
96
+ "Initializing build process for main project to both NPM and JSR..."
97
+ );
98
+ const buildTasks = [
99
+ () => regular_buildJsrDist(
100
+ isDev,
101
+ true,
102
+ coreIsCLI,
103
+ coreEntrySrcDir,
104
+ distJsrDirName,
105
+ distJsrBuilder,
106
+ coreEntryFile,
107
+ transpileTarget,
108
+ transpileFormat,
109
+ transpileSplitting,
110
+ transpileMinify,
111
+ transpileSourcemap,
112
+ transpilePublicPath,
113
+ unifiedBundlerOutExt,
114
+ rmDepsMode,
115
+ timer,
116
+ transpileStub,
117
+ transpileWatch,
118
+ distJsrGenTsconfig,
119
+ coreDeclarations
120
+ ),
121
+ () => regular_buildNpmDist(
122
+ isDev,
123
+ coreEntrySrcDir,
124
+ distNpmDirName,
125
+ distNpmBuilder,
126
+ coreEntryFile,
127
+ unifiedBundlerOutExt,
128
+ rmDepsMode,
129
+ coreIsCLI,
130
+ transpileTarget,
131
+ transpileFormat,
132
+ transpileSplitting,
133
+ transpileMinify,
134
+ transpileSourcemap,
135
+ transpilePublicPath,
136
+ transpileStub,
137
+ transpileWatch,
138
+ timer,
139
+ coreDeclarations
140
+ )
141
+ ];
142
+ await pAll(buildTasks, { concurrency: CONCURRENCY_DEFAULT });
143
+ if (!isDev) {
144
+ const publishTasks = [
145
+ () => regular_pubToJsr(
146
+ distJsrDryRun,
147
+ distJsrFailOnWarn,
148
+ isDev,
149
+ commonPubPause,
150
+ distJsrDirName,
151
+ distJsrAllowDirty,
152
+ distJsrSlowTypes,
153
+ timer
154
+ ),
155
+ () => regular_pubToNpm(
156
+ distJsrDryRun,
157
+ isDev,
158
+ commonPubPause,
159
+ distNpmDirName,
160
+ timer
161
+ )
162
+ ];
163
+ await pAll(publishTasks, { concurrency: CONCURRENCY_DEFAULT });
164
+ }
165
+ break;
166
+ }
167
+ default: {
168
+ relinka(
169
+ "warn",
170
+ `Registry "${commonPubRegistry}" not recognized. Building main project only...`
171
+ );
172
+ const fallbackBuildTasks = [
173
+ () => regular_buildNpmDist(
174
+ isDev,
175
+ coreEntrySrcDir,
176
+ distNpmDirName,
177
+ distNpmBuilder,
178
+ coreEntryFile,
179
+ unifiedBundlerOutExt,
180
+ rmDepsMode,
181
+ coreIsCLI,
182
+ transpileTarget,
183
+ transpileFormat,
184
+ transpileSplitting,
185
+ transpileMinify,
186
+ transpileSourcemap,
187
+ transpilePublicPath,
188
+ transpileStub,
189
+ transpileWatch,
190
+ timer,
191
+ coreDeclarations
192
+ ),
193
+ () => regular_buildJsrDist(
194
+ isDev,
195
+ true,
196
+ coreIsCLI,
197
+ coreEntrySrcDir,
198
+ distJsrDirName,
199
+ distJsrBuilder,
200
+ coreEntryFile,
201
+ transpileTarget,
202
+ transpileFormat,
203
+ transpileSplitting,
204
+ transpileMinify,
205
+ transpileSourcemap,
206
+ transpilePublicPath,
207
+ unifiedBundlerOutExt,
208
+ rmDepsMode,
209
+ timer,
210
+ transpileStub,
211
+ transpileWatch,
212
+ distJsrGenTsconfig,
213
+ coreDeclarations
214
+ )
215
+ ];
216
+ await pAll(fallbackBuildTasks, { concurrency: CONCURRENCY_DEFAULT });
217
+ }
218
+ }
219
+ }
@@ -0,0 +1,307 @@
1
+ import path from "pathe";
2
+ import * as fs from "./spells-filesystem.js";
3
+ export const replaceLineExecutor = async (spell, filePath, content) => {
4
+ if (!spell.lineNumber) {
5
+ return {
6
+ spell,
7
+ file: filePath,
8
+ success: false,
9
+ message: "Line number not provided"
10
+ };
11
+ }
12
+ if (!spell.value) {
13
+ return {
14
+ spell,
15
+ file: filePath,
16
+ success: false,
17
+ message: "Target file not specified"
18
+ };
19
+ }
20
+ const includeFilePath = path.resolve(path.dirname(filePath), spell.value);
21
+ try {
22
+ const includeContent = await fs.readFile(includeFilePath);
23
+ const lines = content.split("\n");
24
+ const originalLine = lines[spell.lineNumber - 1];
25
+ lines[spell.lineNumber - 1] = includeContent.trim();
26
+ const newContent = lines.join("\n");
27
+ await fs.writeFile(filePath, newContent);
28
+ return {
29
+ spell,
30
+ file: filePath,
31
+ success: true,
32
+ message: `Line replaced with content from ${includeFilePath}`,
33
+ changes: {
34
+ before: originalLine ?? "",
35
+ after: includeContent.trim()
36
+ }
37
+ };
38
+ } catch (error) {
39
+ return {
40
+ spell,
41
+ file: filePath,
42
+ success: false,
43
+ message: `Failed to replace line: ${error}`
44
+ };
45
+ }
46
+ };
47
+ export const renameFileExecutor = async (spell, filePath) => {
48
+ if (!spell.value) {
49
+ return {
50
+ spell,
51
+ file: filePath,
52
+ success: false,
53
+ message: "New filename not provided"
54
+ };
55
+ }
56
+ const newPath = path.resolve(path.dirname(filePath), spell.value);
57
+ try {
58
+ await fs.renameFile(filePath, newPath);
59
+ return {
60
+ spell,
61
+ file: filePath,
62
+ success: true,
63
+ message: `File renamed to ${newPath}`
64
+ };
65
+ } catch (error) {
66
+ return {
67
+ spell,
68
+ file: filePath,
69
+ success: false,
70
+ message: `Failed to rename file: ${error}`
71
+ };
72
+ }
73
+ };
74
+ export const removeCommentExecutor = async (spell, filePath, content) => {
75
+ if (!spell.lineNumber || !spell.fullMatch) {
76
+ return {
77
+ spell,
78
+ file: filePath,
79
+ success: false,
80
+ message: "Line number or full match not provided"
81
+ };
82
+ }
83
+ try {
84
+ const lines = content.split("\n");
85
+ const originalLine = lines[spell.lineNumber - 1];
86
+ lines[spell.lineNumber - 1] = (originalLine ?? "").replace(spell.fullMatch, "").trim();
87
+ const newContent = lines.join("\n");
88
+ await fs.writeFile(filePath, newContent);
89
+ return {
90
+ spell,
91
+ file: filePath,
92
+ success: true,
93
+ message: "Comment removed",
94
+ changes: {
95
+ before: originalLine ?? "",
96
+ after: lines[spell.lineNumber - 1] ?? ""
97
+ }
98
+ };
99
+ } catch (error) {
100
+ return {
101
+ spell,
102
+ file: filePath,
103
+ success: false,
104
+ message: `Failed to remove comment: ${error}`
105
+ };
106
+ }
107
+ };
108
+ export const removeLineExecutor = async (spell, filePath, content) => {
109
+ if (!spell.lineNumber) {
110
+ return {
111
+ spell,
112
+ file: filePath,
113
+ success: false,
114
+ message: "Line number not provided"
115
+ };
116
+ }
117
+ try {
118
+ const lines = content.split("\n");
119
+ const originalLine = lines[spell.lineNumber - 1];
120
+ lines.splice(spell.lineNumber - 1, 1);
121
+ const newContent = lines.join("\n");
122
+ await fs.writeFile(filePath, newContent);
123
+ return {
124
+ spell,
125
+ file: filePath,
126
+ success: true,
127
+ message: "Line removed",
128
+ changes: {
129
+ before: originalLine ?? "",
130
+ after: ""
131
+ }
132
+ };
133
+ } catch (error) {
134
+ return {
135
+ spell,
136
+ file: filePath,
137
+ success: false,
138
+ message: `Failed to remove line: ${error}`
139
+ };
140
+ }
141
+ };
142
+ export const removeFileExecutor = async (spell, filePath) => {
143
+ try {
144
+ await fs.removeFile(filePath);
145
+ return {
146
+ spell,
147
+ file: filePath,
148
+ success: true,
149
+ message: "File removed"
150
+ };
151
+ } catch (error) {
152
+ return {
153
+ spell,
154
+ file: filePath,
155
+ success: false,
156
+ message: `Failed to remove file: ${error}`
157
+ };
158
+ }
159
+ };
160
+ export const copyFileExecutor = async (spell, filePath) => {
161
+ if (!spell.value) {
162
+ return {
163
+ spell,
164
+ file: filePath,
165
+ success: false,
166
+ message: "Target path not provided"
167
+ };
168
+ }
169
+ const targetPath = path.resolve(path.dirname(filePath), spell.value);
170
+ try {
171
+ await fs.copyFile(filePath, targetPath);
172
+ return {
173
+ spell,
174
+ file: filePath,
175
+ success: true,
176
+ message: `File copied to ${targetPath}`
177
+ };
178
+ } catch (error) {
179
+ return {
180
+ spell,
181
+ file: filePath,
182
+ success: false,
183
+ message: `Failed to copy file: ${error}`
184
+ };
185
+ }
186
+ };
187
+ export const moveFileExecutor = async (spell, filePath) => {
188
+ if (!spell.value) {
189
+ return {
190
+ spell,
191
+ file: filePath,
192
+ success: false,
193
+ message: "Target path not provided"
194
+ };
195
+ }
196
+ const targetPath = path.resolve(path.dirname(filePath), spell.value);
197
+ try {
198
+ await fs.renameFile(filePath, targetPath);
199
+ return {
200
+ spell,
201
+ file: filePath,
202
+ success: true,
203
+ message: `File moved to ${targetPath}`
204
+ };
205
+ } catch (error) {
206
+ return {
207
+ spell,
208
+ file: filePath,
209
+ success: false,
210
+ message: `Failed to move file: ${error}`
211
+ };
212
+ }
213
+ };
214
+ export const transformContentExecutor = async (spell, filePath, content) => {
215
+ if (!spell.value) {
216
+ return {
217
+ spell,
218
+ file: filePath,
219
+ success: false,
220
+ message: "Transform function not provided"
221
+ };
222
+ }
223
+ try {
224
+ let newContent = content;
225
+ switch (spell.value) {
226
+ case "trim-empty-lines":
227
+ newContent = content.split("\n").filter((line) => line.trim() !== "").join("\n");
228
+ break;
229
+ case "normalize-imports":
230
+ newContent = content.replace(
231
+ /import\s+{([^}]+)}\s+from\s+['"]([^'"]+)['"]/g,
232
+ (_, imports, source) => {
233
+ const normalizedImports = imports.split(",").map((i) => i.trim()).sort().join(", ");
234
+ return `import { ${normalizedImports} } from "${source}"`;
235
+ }
236
+ );
237
+ break;
238
+ default:
239
+ return {
240
+ spell,
241
+ file: filePath,
242
+ success: false,
243
+ message: `Unknown transformation: ${spell.value}`
244
+ };
245
+ }
246
+ await fs.writeFile(filePath, newContent);
247
+ return {
248
+ spell,
249
+ file: filePath,
250
+ success: true,
251
+ message: `Content transformed with ${spell.value}`,
252
+ changes: {
253
+ before: content,
254
+ after: newContent
255
+ }
256
+ };
257
+ } catch (error) {
258
+ return {
259
+ spell,
260
+ file: filePath,
261
+ success: false,
262
+ message: `Failed to transform content: ${error}`
263
+ };
264
+ }
265
+ };
266
+ export const insertAtExecutor = async (spell, filePath, content) => {
267
+ if (!spell.value || !spell.params.content) {
268
+ return {
269
+ spell,
270
+ file: filePath,
271
+ success: false,
272
+ message: "Position or content not provided"
273
+ };
274
+ }
275
+ try {
276
+ const lines = content.split("\n");
277
+ const position = Number(spell.value);
278
+ if (Number.isNaN(position) || position < 0 || position > lines.length) {
279
+ return {
280
+ spell,
281
+ file: filePath,
282
+ success: false,
283
+ message: `Invalid position: ${spell.value}`
284
+ };
285
+ }
286
+ lines.splice(position, 0, spell.params.content);
287
+ const newContent = lines.join("\n");
288
+ await fs.writeFile(filePath, newContent);
289
+ return {
290
+ spell,
291
+ file: filePath,
292
+ success: true,
293
+ message: `Content inserted at position ${position}`,
294
+ changes: {
295
+ before: content,
296
+ after: newContent
297
+ }
298
+ };
299
+ } catch (error) {
300
+ return {
301
+ spell,
302
+ file: filePath,
303
+ success: false,
304
+ message: `Failed to insert content: ${error}`
305
+ };
306
+ }
307
+ };
@@ -0,0 +1,72 @@
1
+ import fs from "fs-extra";
2
+ import path from "pathe";
3
+ export const fileExists = async (filePath) => {
4
+ try {
5
+ await fs.access(filePath);
6
+ return true;
7
+ } catch {
8
+ return false;
9
+ }
10
+ };
11
+ export const readFile = async (filePath) => {
12
+ return await fs.readFile(filePath, "utf-8");
13
+ };
14
+ export const writeFile = async (filePath, content) => {
15
+ const dir = path.dirname(filePath);
16
+ try {
17
+ await fs.mkdir(dir, { recursive: true });
18
+ await fs.writeFile(filePath, content, "utf-8");
19
+ } catch (error) {
20
+ throw new Error(`Failed to write file ${filePath}: ${error}`);
21
+ }
22
+ };
23
+ export const removeFile = async (filePath) => {
24
+ try {
25
+ await fs.unlink(filePath);
26
+ } catch (error) {
27
+ throw new Error(`Failed to remove file ${filePath}: ${error}`);
28
+ }
29
+ };
30
+ export const renameFile = async (oldPath, newPath) => {
31
+ try {
32
+ const dir = path.dirname(newPath);
33
+ await fs.mkdir(dir, { recursive: true });
34
+ await fs.rename(oldPath, newPath);
35
+ } catch (error) {
36
+ throw new Error(`Failed to rename file ${oldPath} to ${newPath}: ${error}`);
37
+ }
38
+ };
39
+ export const copyFile = async (sourcePath, targetPath) => {
40
+ try {
41
+ const dir = path.dirname(targetPath);
42
+ await fs.mkdir(dir, { recursive: true });
43
+ await fs.copyFile(sourcePath, targetPath);
44
+ } catch (error) {
45
+ throw new Error(
46
+ `Failed to copy file ${sourcePath} to ${targetPath}: ${error}`
47
+ );
48
+ }
49
+ };
50
+ export const findFiles = async (patterns, cwd = process.cwd()) => {
51
+ const results = [];
52
+ const scanDir = async (dir) => {
53
+ const entries = await fs.readdir(dir, { withFileTypes: true });
54
+ for (const entry of entries) {
55
+ const fullPath = path.join(dir, entry.name);
56
+ if (entry.isDirectory()) {
57
+ await scanDir(fullPath);
58
+ } else if (matchesAnyPattern(fullPath, patterns)) {
59
+ results.push(fullPath);
60
+ }
61
+ }
62
+ };
63
+ await scanDir(cwd);
64
+ return results;
65
+ };
66
+ const matchesAnyPattern = (filePath, patterns) => {
67
+ if (patterns.length === 0) return true;
68
+ return patterns.some((pattern) => {
69
+ if (pattern === "*") return true;
70
+ return filePath.includes(pattern);
71
+ });
72
+ };
@@ -0,0 +1,87 @@
1
+ import * as executors from "./spells-executors.js";
2
+ import * as fs from "./spells-filesystem.js";
3
+ import { extractSpellsFromFile } from "./spells-parser.js";
4
+ export const executeSpell = async (spell, filePath, content) => {
5
+ if (spell.params.hooked) {
6
+ return {
7
+ spell,
8
+ file: filePath,
9
+ success: true,
10
+ message: "Skipped (hooked=true)"
11
+ };
12
+ }
13
+ switch (spell.type) {
14
+ case "replace-line":
15
+ return await executors.replaceLineExecutor(spell, filePath, content);
16
+ case "rename-file":
17
+ return await executors.renameFileExecutor(spell, filePath);
18
+ case "remove-comment":
19
+ return await executors.removeCommentExecutor(spell, filePath, content);
20
+ case "remove-line":
21
+ return await executors.removeLineExecutor(spell, filePath, content);
22
+ case "remove-file":
23
+ return await executors.removeFileExecutor(spell, filePath);
24
+ case "transform-content":
25
+ return await executors.transformContentExecutor(spell, filePath, content);
26
+ case "copy-file":
27
+ return await executors.copyFileExecutor(spell, filePath);
28
+ case "move-file":
29
+ return await executors.moveFileExecutor(spell, filePath);
30
+ case "insert-at":
31
+ return await executors.insertAtExecutor(spell, filePath, content);
32
+ default:
33
+ return {
34
+ spell,
35
+ file: filePath,
36
+ success: false,
37
+ message: `Unknown spell type: ${spell.type}`
38
+ };
39
+ }
40
+ };
41
+ export const processFile = async (filePath, options = {}) => {
42
+ const results = [];
43
+ try {
44
+ const content = await fs.readFile(filePath);
45
+ const spells2 = await extractSpellsFromFile(filePath, content);
46
+ for (const spell of spells2) {
47
+ if (options.spells && options.spells.length > 0 && !options.spells.includes("all") && !options.spells.includes(spell.type)) {
48
+ continue;
49
+ }
50
+ const result = await executeSpell(spell, filePath, content);
51
+ results.push(result);
52
+ if (result.success && (spell.type === "remove-file" || spell.type === "rename-file")) {
53
+ break;
54
+ }
55
+ }
56
+ return results;
57
+ } catch (error) {
58
+ return [
59
+ {
60
+ spell: { type: "unknown", params: { hooked: false } },
61
+ file: filePath,
62
+ success: false,
63
+ message: `Failed to process file: ${error}`
64
+ }
65
+ ];
66
+ }
67
+ };
68
+ export const spells = async (options = {}) => {
69
+ const results = [];
70
+ try {
71
+ const filesToProcess = options.files?.length ? options.files : await fs.findFiles(["*"], process.cwd());
72
+ for (const filePath of filesToProcess) {
73
+ const fileResults = await processFile(filePath, options);
74
+ results.push(...fileResults);
75
+ }
76
+ return results;
77
+ } catch (error) {
78
+ return [
79
+ {
80
+ spell: { type: "unknown", params: { hooked: false } },
81
+ file: "unknown",
82
+ success: false,
83
+ message: `Failed to trigger spells: ${error}`
84
+ }
85
+ ];
86
+ }
87
+ };