@udixio/tailwind 1.2.1 → 1.3.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/CHANGELOG.md +14 -0
- package/dist/file.d.ts +1 -1
- package/dist/file.d.ts.map +1 -1
- package/dist/index.cjs +69 -26
- package/dist/index.js +71 -28
- package/package.json +3 -2
- package/src/file.ts +92 -28
- package/vite.config.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## 1.3.0 (2025-08-25)
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- **tailwind:** enhance file utilities and integrate `pathe` for path normalization ([2c73d40](https://github.com/Udixio/UI/commit/2c73d40))
|
|
6
|
+
|
|
7
|
+
### 🧱 Updated Dependencies
|
|
8
|
+
|
|
9
|
+
- Updated @udixio/theme to 1.1.0
|
|
10
|
+
|
|
11
|
+
### ❤️ Thank You
|
|
12
|
+
|
|
13
|
+
- Joël VIGREUX
|
|
14
|
+
|
|
1
15
|
## 1.2.1 (2025-08-22)
|
|
2
16
|
|
|
3
17
|
### 🩹 Fixes
|
package/dist/file.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export declare const createOrUpdateFile: (filePath: string, content: string) =>
|
|
|
2
2
|
export declare const getFileContent: (filePath: string, searchPattern?: RegExp | string) => string | false | null;
|
|
3
3
|
export declare const replaceFileContent: (filePath: string, searchPattern: RegExp | string, replacement: string) => void;
|
|
4
4
|
export declare const findTailwindCssFile: (startDir: string, searchPattern: RegExp | string) => string | never;
|
|
5
|
-
export declare function findProjectRoot(startPath:
|
|
5
|
+
export declare function findProjectRoot(startPath: string): string;
|
|
6
6
|
//# sourceMappingURL=file.d.ts.map
|
package/dist/file.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../src/file.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../src/file.ts"],"names":[],"mappings":"AA8CA,eAAO,MAAM,kBAAkB,GAAI,UAAU,MAAM,EAAE,SAAS,MAAM,KAAG,IActE,CAAC;AAEF,eAAO,MAAM,cAAc,GACzB,UAAU,MAAM,EAChB,gBAAgB,MAAM,GAAG,MAAM,KAC9B,MAAM,GAAG,KAAK,GAAG,IA8CnB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAC7B,UAAU,MAAM,EAChB,eAAe,MAAM,GAAG,MAAM,EAC9B,aAAa,MAAM,KAClB,IAsBF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,UAAU,MAAM,EAChB,eAAe,MAAM,GAAG,MAAM,KAC7B,MAAM,GAAG,KAkEX,CAAC;AAEF,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAczD"}
|
package/dist/index.cjs
CHANGED
|
@@ -5,9 +5,11 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
5
5
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
6
6
|
const plugin = require("tailwindcss/plugin");
|
|
7
7
|
const fs = require("fs");
|
|
8
|
-
const path = require("path");
|
|
9
8
|
const replaceInFile = require("replace-in-file");
|
|
10
9
|
const console = require("node:console");
|
|
10
|
+
const pathe = require("pathe");
|
|
11
|
+
const url = require("url");
|
|
12
|
+
const path = require("path");
|
|
11
13
|
const theme = require("@udixio/theme");
|
|
12
14
|
function _interopNamespaceDefault(e) {
|
|
13
15
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
@@ -26,7 +28,6 @@ function _interopNamespaceDefault(e) {
|
|
|
26
28
|
return Object.freeze(n);
|
|
27
29
|
}
|
|
28
30
|
const fs__namespace = /* @__PURE__ */ _interopNamespaceDefault(fs);
|
|
29
|
-
const path__namespace = /* @__PURE__ */ _interopNamespaceDefault(path);
|
|
30
31
|
const console__namespace = /* @__PURE__ */ _interopNamespaceDefault(console);
|
|
31
32
|
const defaultConfig = {
|
|
32
33
|
statePrefix: "state",
|
|
@@ -186,17 +187,41 @@ const main = plugin.withOptions((args) => {
|
|
|
186
187
|
shadow.handler(api);
|
|
187
188
|
};
|
|
188
189
|
});
|
|
190
|
+
const normalizePath = (filePath) => {
|
|
191
|
+
try {
|
|
192
|
+
if (filePath.startsWith("file://")) {
|
|
193
|
+
return pathe.normalize(url.fileURLToPath(filePath));
|
|
194
|
+
}
|
|
195
|
+
return pathe.normalize(filePath);
|
|
196
|
+
} catch (error) {
|
|
197
|
+
console__namespace.warn(
|
|
198
|
+
`Warning: Could not process path ${filePath}, treating as regular path`
|
|
199
|
+
);
|
|
200
|
+
return pathe.normalize(filePath);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
const safeExistsSync = (filePath) => {
|
|
204
|
+
return fs__namespace.existsSync(normalizePath(filePath));
|
|
205
|
+
};
|
|
206
|
+
const safeReadFileSync = (filePath, encoding = "utf8") => {
|
|
207
|
+
return fs__namespace.readFileSync(normalizePath(filePath), encoding);
|
|
208
|
+
};
|
|
209
|
+
const safeWriteFileSync = (filePath, data) => {
|
|
210
|
+
const normalizedPath = normalizePath(filePath);
|
|
211
|
+
const dirPath = pathe.dirname(normalizedPath);
|
|
212
|
+
if (!fs__namespace.existsSync(dirPath)) {
|
|
213
|
+
fs__namespace.mkdirSync(dirPath, { recursive: true });
|
|
214
|
+
}
|
|
215
|
+
fs__namespace.writeFileSync(normalizedPath, data);
|
|
216
|
+
};
|
|
189
217
|
const createOrUpdateFile = (filePath, content) => {
|
|
190
218
|
try {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
fs__namespace.writeFileSync(filePath, content);
|
|
197
|
-
console__namespace.log(`✅ File successfully created: ${filePath}`);
|
|
219
|
+
const normalizedPath = normalizePath(filePath);
|
|
220
|
+
if (!safeExistsSync(filePath)) {
|
|
221
|
+
safeWriteFileSync(filePath, content);
|
|
222
|
+
console__namespace.log(`✅ File successfully created: ${normalizedPath}`);
|
|
198
223
|
} else {
|
|
199
|
-
console__namespace.log(`⚠️ File already exists: ${
|
|
224
|
+
console__namespace.log(`⚠️ File already exists: ${normalizedPath}`);
|
|
200
225
|
replaceFileContent(filePath, /[\s\S]*/, content);
|
|
201
226
|
}
|
|
202
227
|
} catch (error) {
|
|
@@ -205,11 +230,12 @@ const createOrUpdateFile = (filePath, content) => {
|
|
|
205
230
|
};
|
|
206
231
|
const getFileContent = (filePath, searchPattern) => {
|
|
207
232
|
try {
|
|
208
|
-
|
|
209
|
-
|
|
233
|
+
const normalizedPath = normalizePath(filePath);
|
|
234
|
+
if (!safeExistsSync(filePath)) {
|
|
235
|
+
console__namespace.error(`❌ The specified file does not exist: ${normalizedPath}`);
|
|
210
236
|
return null;
|
|
211
237
|
}
|
|
212
|
-
const fileContent =
|
|
238
|
+
const fileContent = safeReadFileSync(filePath);
|
|
213
239
|
if (searchPattern) {
|
|
214
240
|
if (typeof searchPattern === "string") {
|
|
215
241
|
const found = fileContent.includes(searchPattern) ? searchPattern : false;
|
|
@@ -239,13 +265,16 @@ const getFileContent = (filePath, searchPattern) => {
|
|
|
239
265
|
};
|
|
240
266
|
const replaceFileContent = (filePath, searchPattern, replacement) => {
|
|
241
267
|
try {
|
|
268
|
+
const normalizedPath = normalizePath(filePath);
|
|
242
269
|
const results = replaceInFile.replaceInFileSync({
|
|
243
|
-
files:
|
|
270
|
+
files: normalizedPath,
|
|
244
271
|
from: searchPattern,
|
|
245
272
|
to: replacement
|
|
246
273
|
});
|
|
247
274
|
if (results.length > 0 && results[0].hasChanged) {
|
|
248
|
-
console__namespace.log(
|
|
275
|
+
console__namespace.log(
|
|
276
|
+
`✅ Content successfully replaced in the file: ${normalizedPath}`
|
|
277
|
+
);
|
|
249
278
|
} else {
|
|
250
279
|
console__namespace.log(
|
|
251
280
|
`⚠️ No replacement made. Here are some possible reasons:
|
|
@@ -258,13 +287,23 @@ const replaceFileContent = (filePath, searchPattern, replacement) => {
|
|
|
258
287
|
}
|
|
259
288
|
};
|
|
260
289
|
const findTailwindCssFile = (startDir, searchPattern) => {
|
|
261
|
-
|
|
262
|
-
|
|
290
|
+
const normalizedStartDir = normalizePath(startDir);
|
|
291
|
+
console__namespace.log("Recherche du fichier contenant le motif...", normalizedStartDir);
|
|
292
|
+
const stack = [normalizedStartDir];
|
|
263
293
|
while (stack.length > 0) {
|
|
264
294
|
const currentDir = stack.pop();
|
|
265
|
-
|
|
295
|
+
let files;
|
|
296
|
+
try {
|
|
297
|
+
files = fs__namespace.readdirSync(currentDir);
|
|
298
|
+
} catch (error) {
|
|
299
|
+
console__namespace.error(
|
|
300
|
+
`Erreur lors de la lecture du répertoire ${currentDir}:`,
|
|
301
|
+
error
|
|
302
|
+
);
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
266
305
|
for (const file of files) {
|
|
267
|
-
const filePath =
|
|
306
|
+
const filePath = pathe.join(currentDir, file);
|
|
268
307
|
let stats;
|
|
269
308
|
try {
|
|
270
309
|
stats = fs__namespace.statSync(filePath);
|
|
@@ -273,12 +312,15 @@ const findTailwindCssFile = (startDir, searchPattern) => {
|
|
|
273
312
|
continue;
|
|
274
313
|
}
|
|
275
314
|
if (stats.isDirectory()) {
|
|
276
|
-
if (file !== "node_modules"
|
|
315
|
+
if (file !== "node_modules" && !file.startsWith(".")) {
|
|
316
|
+
stack.push(filePath);
|
|
317
|
+
}
|
|
277
318
|
} else if (stats.isFile() && (file.endsWith(".css") || file.endsWith(".scss") || file.endsWith(".sass"))) {
|
|
278
319
|
try {
|
|
279
320
|
console__namespace.log(`Analyse du fichier : ${filePath}`);
|
|
280
|
-
const content =
|
|
281
|
-
|
|
321
|
+
const content = safeReadFileSync(filePath);
|
|
322
|
+
const hasMatch = typeof searchPattern === "string" ? content.includes(searchPattern) : searchPattern.test(content);
|
|
323
|
+
if (hasMatch) {
|
|
282
324
|
console__namespace.log("Fichier trouvé :", filePath);
|
|
283
325
|
return filePath;
|
|
284
326
|
}
|
|
@@ -289,13 +331,14 @@ const findTailwindCssFile = (startDir, searchPattern) => {
|
|
|
289
331
|
}
|
|
290
332
|
}
|
|
291
333
|
throw new Error(
|
|
292
|
-
`Impossible de trouver un fichier contenant "${searchPattern}" dans "${
|
|
334
|
+
`Impossible de trouver un fichier contenant "${searchPattern}" dans "${normalizedStartDir}".`
|
|
293
335
|
);
|
|
294
336
|
};
|
|
295
337
|
function findProjectRoot(startPath) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
338
|
+
const normalizedStartPath = normalizePath(startPath);
|
|
339
|
+
let currentPath = pathe.resolve(normalizedStartPath);
|
|
340
|
+
while (!fs__namespace.existsSync(pathe.join(currentPath, "package.json"))) {
|
|
341
|
+
const parentPath = pathe.dirname(currentPath);
|
|
299
342
|
if (currentPath === parentPath) {
|
|
300
343
|
throw new Error("Impossible de localiser la racine du projet.");
|
|
301
344
|
}
|
package/dist/index.js
CHANGED
|
@@ -3,10 +3,11 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
|
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
4
|
import plugin from "tailwindcss/plugin";
|
|
5
5
|
import * as fs from "fs";
|
|
6
|
-
import * as path from "path";
|
|
7
|
-
import path__default from "path";
|
|
8
6
|
import { replaceInFileSync } from "replace-in-file";
|
|
9
7
|
import * as console from "node:console";
|
|
8
|
+
import { resolve, join, dirname, normalize } from "pathe";
|
|
9
|
+
import { fileURLToPath } from "url";
|
|
10
|
+
import path from "path";
|
|
10
11
|
import { PluginAbstract, FontPlugin, PluginImplAbstract } from "@udixio/theme";
|
|
11
12
|
const defaultConfig = {
|
|
12
13
|
statePrefix: "state",
|
|
@@ -166,17 +167,41 @@ const main = plugin.withOptions((args) => {
|
|
|
166
167
|
shadow.handler(api);
|
|
167
168
|
};
|
|
168
169
|
});
|
|
170
|
+
const normalizePath = (filePath) => {
|
|
171
|
+
try {
|
|
172
|
+
if (filePath.startsWith("file://")) {
|
|
173
|
+
return normalize(fileURLToPath(filePath));
|
|
174
|
+
}
|
|
175
|
+
return normalize(filePath);
|
|
176
|
+
} catch (error) {
|
|
177
|
+
console.warn(
|
|
178
|
+
`Warning: Could not process path ${filePath}, treating as regular path`
|
|
179
|
+
);
|
|
180
|
+
return normalize(filePath);
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
const safeExistsSync = (filePath) => {
|
|
184
|
+
return fs.existsSync(normalizePath(filePath));
|
|
185
|
+
};
|
|
186
|
+
const safeReadFileSync = (filePath, encoding = "utf8") => {
|
|
187
|
+
return fs.readFileSync(normalizePath(filePath), encoding);
|
|
188
|
+
};
|
|
189
|
+
const safeWriteFileSync = (filePath, data) => {
|
|
190
|
+
const normalizedPath = normalizePath(filePath);
|
|
191
|
+
const dirPath = dirname(normalizedPath);
|
|
192
|
+
if (!fs.existsSync(dirPath)) {
|
|
193
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
194
|
+
}
|
|
195
|
+
fs.writeFileSync(normalizedPath, data);
|
|
196
|
+
};
|
|
169
197
|
const createOrUpdateFile = (filePath, content) => {
|
|
170
198
|
try {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
fs.writeFileSync(filePath, content);
|
|
177
|
-
console.log(`✅ File successfully created: ${filePath}`);
|
|
199
|
+
const normalizedPath = normalizePath(filePath);
|
|
200
|
+
if (!safeExistsSync(filePath)) {
|
|
201
|
+
safeWriteFileSync(filePath, content);
|
|
202
|
+
console.log(`✅ File successfully created: ${normalizedPath}`);
|
|
178
203
|
} else {
|
|
179
|
-
console.log(`⚠️ File already exists: ${
|
|
204
|
+
console.log(`⚠️ File already exists: ${normalizedPath}`);
|
|
180
205
|
replaceFileContent(filePath, /[\s\S]*/, content);
|
|
181
206
|
}
|
|
182
207
|
} catch (error) {
|
|
@@ -185,11 +210,12 @@ const createOrUpdateFile = (filePath, content) => {
|
|
|
185
210
|
};
|
|
186
211
|
const getFileContent = (filePath, searchPattern) => {
|
|
187
212
|
try {
|
|
188
|
-
|
|
189
|
-
|
|
213
|
+
const normalizedPath = normalizePath(filePath);
|
|
214
|
+
if (!safeExistsSync(filePath)) {
|
|
215
|
+
console.error(`❌ The specified file does not exist: ${normalizedPath}`);
|
|
190
216
|
return null;
|
|
191
217
|
}
|
|
192
|
-
const fileContent =
|
|
218
|
+
const fileContent = safeReadFileSync(filePath);
|
|
193
219
|
if (searchPattern) {
|
|
194
220
|
if (typeof searchPattern === "string") {
|
|
195
221
|
const found = fileContent.includes(searchPattern) ? searchPattern : false;
|
|
@@ -219,13 +245,16 @@ const getFileContent = (filePath, searchPattern) => {
|
|
|
219
245
|
};
|
|
220
246
|
const replaceFileContent = (filePath, searchPattern, replacement) => {
|
|
221
247
|
try {
|
|
248
|
+
const normalizedPath = normalizePath(filePath);
|
|
222
249
|
const results = replaceInFileSync({
|
|
223
|
-
files:
|
|
250
|
+
files: normalizedPath,
|
|
224
251
|
from: searchPattern,
|
|
225
252
|
to: replacement
|
|
226
253
|
});
|
|
227
254
|
if (results.length > 0 && results[0].hasChanged) {
|
|
228
|
-
console.log(
|
|
255
|
+
console.log(
|
|
256
|
+
`✅ Content successfully replaced in the file: ${normalizedPath}`
|
|
257
|
+
);
|
|
229
258
|
} else {
|
|
230
259
|
console.log(
|
|
231
260
|
`⚠️ No replacement made. Here are some possible reasons:
|
|
@@ -238,13 +267,23 @@ const replaceFileContent = (filePath, searchPattern, replacement) => {
|
|
|
238
267
|
}
|
|
239
268
|
};
|
|
240
269
|
const findTailwindCssFile = (startDir, searchPattern) => {
|
|
241
|
-
|
|
242
|
-
|
|
270
|
+
const normalizedStartDir = normalizePath(startDir);
|
|
271
|
+
console.log("Recherche du fichier contenant le motif...", normalizedStartDir);
|
|
272
|
+
const stack = [normalizedStartDir];
|
|
243
273
|
while (stack.length > 0) {
|
|
244
274
|
const currentDir = stack.pop();
|
|
245
|
-
|
|
275
|
+
let files;
|
|
276
|
+
try {
|
|
277
|
+
files = fs.readdirSync(currentDir);
|
|
278
|
+
} catch (error) {
|
|
279
|
+
console.error(
|
|
280
|
+
`Erreur lors de la lecture du répertoire ${currentDir}:`,
|
|
281
|
+
error
|
|
282
|
+
);
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
246
285
|
for (const file of files) {
|
|
247
|
-
const filePath =
|
|
286
|
+
const filePath = join(currentDir, file);
|
|
248
287
|
let stats;
|
|
249
288
|
try {
|
|
250
289
|
stats = fs.statSync(filePath);
|
|
@@ -253,12 +292,15 @@ const findTailwindCssFile = (startDir, searchPattern) => {
|
|
|
253
292
|
continue;
|
|
254
293
|
}
|
|
255
294
|
if (stats.isDirectory()) {
|
|
256
|
-
if (file !== "node_modules"
|
|
295
|
+
if (file !== "node_modules" && !file.startsWith(".")) {
|
|
296
|
+
stack.push(filePath);
|
|
297
|
+
}
|
|
257
298
|
} else if (stats.isFile() && (file.endsWith(".css") || file.endsWith(".scss") || file.endsWith(".sass"))) {
|
|
258
299
|
try {
|
|
259
300
|
console.log(`Analyse du fichier : ${filePath}`);
|
|
260
|
-
const content =
|
|
261
|
-
|
|
301
|
+
const content = safeReadFileSync(filePath);
|
|
302
|
+
const hasMatch = typeof searchPattern === "string" ? content.includes(searchPattern) : searchPattern.test(content);
|
|
303
|
+
if (hasMatch) {
|
|
262
304
|
console.log("Fichier trouvé :", filePath);
|
|
263
305
|
return filePath;
|
|
264
306
|
}
|
|
@@ -269,13 +311,14 @@ const findTailwindCssFile = (startDir, searchPattern) => {
|
|
|
269
311
|
}
|
|
270
312
|
}
|
|
271
313
|
throw new Error(
|
|
272
|
-
`Impossible de trouver un fichier contenant "${searchPattern}" dans "${
|
|
314
|
+
`Impossible de trouver un fichier contenant "${searchPattern}" dans "${normalizedStartDir}".`
|
|
273
315
|
);
|
|
274
316
|
};
|
|
275
317
|
function findProjectRoot(startPath) {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
318
|
+
const normalizedStartPath = normalizePath(startPath);
|
|
319
|
+
let currentPath = resolve(normalizedStartPath);
|
|
320
|
+
while (!fs.existsSync(join(currentPath, "package.json"))) {
|
|
321
|
+
const parentPath = dirname(currentPath);
|
|
279
322
|
if (currentPath === parentPath) {
|
|
280
323
|
throw new Error("Impossible de localiser la racine du projet.");
|
|
281
324
|
}
|
|
@@ -300,13 +343,13 @@ class TailwindImplPlugin extends PluginImplAbstract {
|
|
|
300
343
|
}
|
|
301
344
|
onLoad() {
|
|
302
345
|
let udixioCssPath = this.options.styleFilePath;
|
|
303
|
-
const projectRoot = findProjectRoot(
|
|
346
|
+
const projectRoot = findProjectRoot(path.resolve());
|
|
304
347
|
if (!udixioCssPath) {
|
|
305
348
|
const searchPattern = /@import ["']tailwindcss["'];/;
|
|
306
349
|
const replacement = `@import 'tailwindcss';
|
|
307
350
|
@import "./udixio.css";`;
|
|
308
351
|
const tailwindCssPath = findTailwindCssFile(projectRoot, searchPattern);
|
|
309
|
-
udixioCssPath =
|
|
352
|
+
udixioCssPath = path.join(tailwindCssPath, "../udixio.css");
|
|
310
353
|
if (!getFileContent(tailwindCssPath, /@import\s+"\.\/udixio\.css";/)) {
|
|
311
354
|
replaceFileContent(tailwindCssPath, searchPattern, replacement);
|
|
312
355
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@udixio/tailwind",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
+
"pathe": "^2.0.3",
|
|
19
20
|
"tslib": "^2.3.0",
|
|
20
|
-
"@udixio/theme": "1.
|
|
21
|
+
"@udixio/theme": "1.1.0"
|
|
21
22
|
},
|
|
22
23
|
"repository": {
|
|
23
24
|
"type": "git",
|
package/src/file.ts
CHANGED
|
@@ -1,22 +1,58 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
|
-
import * as path from 'path';
|
|
3
2
|
import { replaceInFileSync } from 'replace-in-file';
|
|
4
3
|
import * as console from 'node:console';
|
|
4
|
+
import { dirname, join, normalize, resolve } from 'pathe';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
// Fonction utilitaire universelle de normalisation des chemins
|
|
8
|
+
const normalizePath = (filePath: string): string => {
|
|
9
|
+
try {
|
|
10
|
+
if (filePath.startsWith('file://')) {
|
|
11
|
+
return normalize(fileURLToPath(filePath));
|
|
12
|
+
}
|
|
13
|
+
return normalize(filePath);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.warn(
|
|
16
|
+
`Warning: Could not process path ${filePath}, treating as regular path`,
|
|
17
|
+
);
|
|
18
|
+
return normalize(filePath);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Wrapper sécurisé pour fs.existsSync
|
|
23
|
+
const safeExistsSync = (filePath: string): boolean => {
|
|
24
|
+
return fs.existsSync(normalizePath(filePath));
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Wrapper sécurisé pour fs.readFileSync
|
|
28
|
+
const safeReadFileSync = (
|
|
29
|
+
filePath: string,
|
|
30
|
+
encoding: BufferEncoding = 'utf8',
|
|
31
|
+
): string => {
|
|
32
|
+
return fs.readFileSync(normalizePath(filePath), encoding);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// Wrapper sécurisé pour fs.writeFileSync
|
|
36
|
+
const safeWriteFileSync = (filePath: string, data: string): void => {
|
|
37
|
+
const normalizedPath = normalizePath(filePath);
|
|
38
|
+
const dirPath = dirname(normalizedPath);
|
|
39
|
+
|
|
40
|
+
if (!fs.existsSync(dirPath)) {
|
|
41
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
fs.writeFileSync(normalizedPath, data);
|
|
45
|
+
};
|
|
5
46
|
|
|
6
47
|
export const createOrUpdateFile = (filePath: string, content: string): void => {
|
|
7
48
|
try {
|
|
8
|
-
|
|
9
|
-
// Create the folder if necessary.
|
|
10
|
-
const dirPath = path.dirname(filePath);
|
|
11
|
-
if (!fs.existsSync(dirPath)) {
|
|
12
|
-
fs.mkdirSync(dirPath, { recursive: true });
|
|
13
|
-
}
|
|
49
|
+
const normalizedPath = normalizePath(filePath);
|
|
14
50
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
console.log(`✅ File successfully created: ${
|
|
51
|
+
if (!safeExistsSync(filePath)) {
|
|
52
|
+
safeWriteFileSync(filePath, content);
|
|
53
|
+
console.log(`✅ File successfully created: ${normalizedPath}`);
|
|
18
54
|
} else {
|
|
19
|
-
console.log(`⚠️ File already exists: ${
|
|
55
|
+
console.log(`⚠️ File already exists: ${normalizedPath}`);
|
|
20
56
|
replaceFileContent(filePath, /[\s\S]*/, content);
|
|
21
57
|
}
|
|
22
58
|
} catch (error) {
|
|
@@ -29,14 +65,16 @@ export const getFileContent = (
|
|
|
29
65
|
searchPattern?: RegExp | string,
|
|
30
66
|
): string | false | null => {
|
|
31
67
|
try {
|
|
68
|
+
const normalizedPath = normalizePath(filePath);
|
|
69
|
+
|
|
32
70
|
// Vérifier si le fichier existe
|
|
33
|
-
if (!
|
|
34
|
-
console.error(`❌ The specified file does not exist: ${
|
|
71
|
+
if (!safeExistsSync(filePath)) {
|
|
72
|
+
console.error(`❌ The specified file does not exist: ${normalizedPath}`);
|
|
35
73
|
return null;
|
|
36
74
|
}
|
|
37
75
|
|
|
38
76
|
// Lire le contenu du fichier entier
|
|
39
|
-
const fileContent =
|
|
77
|
+
const fileContent = safeReadFileSync(filePath);
|
|
40
78
|
|
|
41
79
|
// Si un motif est fourni, chercher le texte correspondant
|
|
42
80
|
if (searchPattern) {
|
|
@@ -79,14 +117,18 @@ export const replaceFileContent = (
|
|
|
79
117
|
replacement: string,
|
|
80
118
|
): void => {
|
|
81
119
|
try {
|
|
120
|
+
const normalizedPath = normalizePath(filePath);
|
|
121
|
+
|
|
82
122
|
const results = replaceInFileSync({
|
|
83
|
-
files:
|
|
123
|
+
files: normalizedPath,
|
|
84
124
|
from: searchPattern,
|
|
85
125
|
to: replacement,
|
|
86
126
|
});
|
|
87
127
|
|
|
88
128
|
if (results.length > 0 && results[0].hasChanged) {
|
|
89
|
-
console.log(
|
|
129
|
+
console.log(
|
|
130
|
+
`✅ Content successfully replaced in the file: ${normalizedPath}`,
|
|
131
|
+
);
|
|
90
132
|
} else {
|
|
91
133
|
console.log(
|
|
92
134
|
`⚠️ No replacement made. Here are some possible reasons:\n- The pattern ${searchPattern} was not found.\n- The file might already contain the expected content.`,
|
|
@@ -96,20 +138,32 @@ export const replaceFileContent = (
|
|
|
96
138
|
console.error('❌ Error while replacing the file content:', error);
|
|
97
139
|
}
|
|
98
140
|
};
|
|
141
|
+
|
|
99
142
|
export const findTailwindCssFile = (
|
|
100
143
|
startDir: string,
|
|
101
144
|
searchPattern: RegExp | string,
|
|
102
145
|
): string | never => {
|
|
103
|
-
|
|
146
|
+
const normalizedStartDir = normalizePath(startDir);
|
|
147
|
+
console.log('Recherche du fichier contenant le motif...', normalizedStartDir);
|
|
104
148
|
|
|
105
|
-
const stack = [
|
|
149
|
+
const stack = [normalizedStartDir]; // Pile pour éviter une récursion implicite.
|
|
106
150
|
|
|
107
151
|
while (stack.length > 0) {
|
|
108
152
|
const currentDir = stack.pop()!; // Récupérer un répertoire de la pile.
|
|
109
|
-
|
|
153
|
+
|
|
154
|
+
let files: string[];
|
|
155
|
+
try {
|
|
156
|
+
files = fs.readdirSync(currentDir);
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error(
|
|
159
|
+
`Erreur lors de la lecture du répertoire ${currentDir}:`,
|
|
160
|
+
error,
|
|
161
|
+
);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
110
164
|
|
|
111
165
|
for (const file of files) {
|
|
112
|
-
const filePath =
|
|
166
|
+
const filePath = join(currentDir, file);
|
|
113
167
|
|
|
114
168
|
let stats: fs.Stats;
|
|
115
169
|
try {
|
|
@@ -121,7 +175,9 @@ export const findTailwindCssFile = (
|
|
|
121
175
|
|
|
122
176
|
// Ignorer le dossier `node_modules` et autres fichiers inutiles.
|
|
123
177
|
if (stats.isDirectory()) {
|
|
124
|
-
if (file !== 'node_modules'
|
|
178
|
+
if (file !== 'node_modules' && !file.startsWith('.')) {
|
|
179
|
+
stack.push(filePath); // Empiler seulement les dossiers valides.
|
|
180
|
+
}
|
|
125
181
|
} else if (
|
|
126
182
|
stats.isFile() &&
|
|
127
183
|
(file.endsWith('.css') ||
|
|
@@ -130,8 +186,15 @@ export const findTailwindCssFile = (
|
|
|
130
186
|
) {
|
|
131
187
|
try {
|
|
132
188
|
console.log(`Analyse du fichier : ${filePath}`);
|
|
133
|
-
const content =
|
|
134
|
-
|
|
189
|
+
const content = safeReadFileSync(filePath);
|
|
190
|
+
|
|
191
|
+
// Gérer les deux types de searchPattern
|
|
192
|
+
const hasMatch =
|
|
193
|
+
typeof searchPattern === 'string'
|
|
194
|
+
? content.includes(searchPattern)
|
|
195
|
+
: searchPattern.test(content);
|
|
196
|
+
|
|
197
|
+
if (hasMatch) {
|
|
135
198
|
console.log('Fichier trouvé :', filePath);
|
|
136
199
|
return filePath; // Retour dès qu'un fichier valide est identifié.
|
|
137
200
|
}
|
|
@@ -143,16 +206,17 @@ export const findTailwindCssFile = (
|
|
|
143
206
|
}
|
|
144
207
|
|
|
145
208
|
throw new Error(
|
|
146
|
-
`Impossible de trouver un fichier contenant "${searchPattern}" dans "${
|
|
209
|
+
`Impossible de trouver un fichier contenant "${searchPattern}" dans "${normalizedStartDir}".`,
|
|
147
210
|
);
|
|
148
211
|
};
|
|
149
212
|
|
|
150
|
-
export function findProjectRoot(startPath) {
|
|
151
|
-
|
|
213
|
+
export function findProjectRoot(startPath: string): string {
|
|
214
|
+
const normalizedStartPath = normalizePath(startPath);
|
|
215
|
+
let currentPath = resolve(normalizedStartPath);
|
|
152
216
|
|
|
153
217
|
// Boucle jusqu'à trouver un package.json ou jusqu'à arriver à la racine du système
|
|
154
|
-
while (!fs.existsSync(
|
|
155
|
-
const parentPath =
|
|
218
|
+
while (!fs.existsSync(join(currentPath, 'package.json'))) {
|
|
219
|
+
const parentPath = dirname(currentPath);
|
|
156
220
|
if (currentPath === parentPath) {
|
|
157
221
|
throw new Error('Impossible de localiser la racine du projet.');
|
|
158
222
|
}
|
package/vite.config.ts
CHANGED