@udixio/tailwind 1.2.0 → 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 +24 -0
- package/dist/file.d.ts +1 -1
- package/dist/file.d.ts.map +1 -1
- package/dist/index.cjs +71 -28
- package/dist/index.js +73 -30
- package/dist/tailwind.plugin.d.ts.map +1 -1
- package/package.json +3 -2
- package/src/file.ts +92 -28
- package/src/main.ts +3 -1
- package/src/tailwind.plugin.ts +0 -3
- package/vite.config.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
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
|
+
|
|
15
|
+
## 1.2.1 (2025-08-22)
|
|
16
|
+
|
|
17
|
+
### 🩹 Fixes
|
|
18
|
+
|
|
19
|
+
- **tailwind:** remove unused imports and enhance breakpoint parsing ([34dc995](https://github.com/Udixio/UI/commit/34dc995))
|
|
20
|
+
|
|
21
|
+
### ❤️ Thank You
|
|
22
|
+
|
|
23
|
+
- Joël VIGREUX
|
|
24
|
+
|
|
1
25
|
## 1.2.0 (2025-08-21)
|
|
2
26
|
|
|
3
27
|
### 🚀 Features
|
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",
|
|
@@ -171,7 +172,8 @@ const main = plugin.withOptions((args) => {
|
|
|
171
172
|
breakPointsCss = [breakPointsCss];
|
|
172
173
|
}
|
|
173
174
|
const responsiveBreakPoints = {};
|
|
174
|
-
breakPointsCss.forEach((
|
|
175
|
+
breakPointsCss.forEach((line) => {
|
|
176
|
+
const [key, value] = line.split(" ");
|
|
175
177
|
responsiveBreakPoints[key] = value;
|
|
176
178
|
});
|
|
177
179
|
const options = {
|
|
@@ -185,17 +187,41 @@ const main = plugin.withOptions((args) => {
|
|
|
185
187
|
shadow.handler(api);
|
|
186
188
|
};
|
|
187
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
|
+
};
|
|
188
217
|
const createOrUpdateFile = (filePath, content) => {
|
|
189
218
|
try {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
fs__namespace.writeFileSync(filePath, content);
|
|
196
|
-
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}`);
|
|
197
223
|
} else {
|
|
198
|
-
console__namespace.log(`⚠️ File already exists: ${
|
|
224
|
+
console__namespace.log(`⚠️ File already exists: ${normalizedPath}`);
|
|
199
225
|
replaceFileContent(filePath, /[\s\S]*/, content);
|
|
200
226
|
}
|
|
201
227
|
} catch (error) {
|
|
@@ -204,11 +230,12 @@ const createOrUpdateFile = (filePath, content) => {
|
|
|
204
230
|
};
|
|
205
231
|
const getFileContent = (filePath, searchPattern) => {
|
|
206
232
|
try {
|
|
207
|
-
|
|
208
|
-
|
|
233
|
+
const normalizedPath = normalizePath(filePath);
|
|
234
|
+
if (!safeExistsSync(filePath)) {
|
|
235
|
+
console__namespace.error(`❌ The specified file does not exist: ${normalizedPath}`);
|
|
209
236
|
return null;
|
|
210
237
|
}
|
|
211
|
-
const fileContent =
|
|
238
|
+
const fileContent = safeReadFileSync(filePath);
|
|
212
239
|
if (searchPattern) {
|
|
213
240
|
if (typeof searchPattern === "string") {
|
|
214
241
|
const found = fileContent.includes(searchPattern) ? searchPattern : false;
|
|
@@ -238,13 +265,16 @@ const getFileContent = (filePath, searchPattern) => {
|
|
|
238
265
|
};
|
|
239
266
|
const replaceFileContent = (filePath, searchPattern, replacement) => {
|
|
240
267
|
try {
|
|
268
|
+
const normalizedPath = normalizePath(filePath);
|
|
241
269
|
const results = replaceInFile.replaceInFileSync({
|
|
242
|
-
files:
|
|
270
|
+
files: normalizedPath,
|
|
243
271
|
from: searchPattern,
|
|
244
272
|
to: replacement
|
|
245
273
|
});
|
|
246
274
|
if (results.length > 0 && results[0].hasChanged) {
|
|
247
|
-
console__namespace.log(
|
|
275
|
+
console__namespace.log(
|
|
276
|
+
`✅ Content successfully replaced in the file: ${normalizedPath}`
|
|
277
|
+
);
|
|
248
278
|
} else {
|
|
249
279
|
console__namespace.log(
|
|
250
280
|
`⚠️ No replacement made. Here are some possible reasons:
|
|
@@ -257,13 +287,23 @@ const replaceFileContent = (filePath, searchPattern, replacement) => {
|
|
|
257
287
|
}
|
|
258
288
|
};
|
|
259
289
|
const findTailwindCssFile = (startDir, searchPattern) => {
|
|
260
|
-
|
|
261
|
-
|
|
290
|
+
const normalizedStartDir = normalizePath(startDir);
|
|
291
|
+
console__namespace.log("Recherche du fichier contenant le motif...", normalizedStartDir);
|
|
292
|
+
const stack = [normalizedStartDir];
|
|
262
293
|
while (stack.length > 0) {
|
|
263
294
|
const currentDir = stack.pop();
|
|
264
|
-
|
|
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
|
+
}
|
|
265
305
|
for (const file of files) {
|
|
266
|
-
const filePath =
|
|
306
|
+
const filePath = pathe.join(currentDir, file);
|
|
267
307
|
let stats;
|
|
268
308
|
try {
|
|
269
309
|
stats = fs__namespace.statSync(filePath);
|
|
@@ -272,12 +312,15 @@ const findTailwindCssFile = (startDir, searchPattern) => {
|
|
|
272
312
|
continue;
|
|
273
313
|
}
|
|
274
314
|
if (stats.isDirectory()) {
|
|
275
|
-
if (file !== "node_modules"
|
|
315
|
+
if (file !== "node_modules" && !file.startsWith(".")) {
|
|
316
|
+
stack.push(filePath);
|
|
317
|
+
}
|
|
276
318
|
} else if (stats.isFile() && (file.endsWith(".css") || file.endsWith(".scss") || file.endsWith(".sass"))) {
|
|
277
319
|
try {
|
|
278
320
|
console__namespace.log(`Analyse du fichier : ${filePath}`);
|
|
279
|
-
const content =
|
|
280
|
-
|
|
321
|
+
const content = safeReadFileSync(filePath);
|
|
322
|
+
const hasMatch = typeof searchPattern === "string" ? content.includes(searchPattern) : searchPattern.test(content);
|
|
323
|
+
if (hasMatch) {
|
|
281
324
|
console__namespace.log("Fichier trouvé :", filePath);
|
|
282
325
|
return filePath;
|
|
283
326
|
}
|
|
@@ -288,13 +331,14 @@ const findTailwindCssFile = (startDir, searchPattern) => {
|
|
|
288
331
|
}
|
|
289
332
|
}
|
|
290
333
|
throw new Error(
|
|
291
|
-
`Impossible de trouver un fichier contenant "${searchPattern}" dans "${
|
|
334
|
+
`Impossible de trouver un fichier contenant "${searchPattern}" dans "${normalizedStartDir}".`
|
|
292
335
|
);
|
|
293
336
|
};
|
|
294
337
|
function findProjectRoot(startPath) {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
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);
|
|
298
342
|
if (currentPath === parentPath) {
|
|
299
343
|
throw new Error("Impossible de localiser la racine du projet.");
|
|
300
344
|
}
|
|
@@ -326,7 +370,6 @@ class TailwindImplPlugin extends theme.PluginImplAbstract {
|
|
|
326
370
|
@import "./udixio.css";`;
|
|
327
371
|
const tailwindCssPath = findTailwindCssFile(projectRoot, searchPattern);
|
|
328
372
|
udixioCssPath = path.join(tailwindCssPath, "../udixio.css");
|
|
329
|
-
console__namespace.log("rrgfgt", tailwindCssPath, udixioCssPath);
|
|
330
373
|
if (!getFileContent(tailwindCssPath, /@import\s+"\.\/udixio\.css";/)) {
|
|
331
374
|
replaceFileContent(tailwindCssPath, searchPattern, replacement);
|
|
332
375
|
}
|
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",
|
|
@@ -151,7 +152,8 @@ const main = plugin.withOptions((args) => {
|
|
|
151
152
|
breakPointsCss = [breakPointsCss];
|
|
152
153
|
}
|
|
153
154
|
const responsiveBreakPoints = {};
|
|
154
|
-
breakPointsCss.forEach((
|
|
155
|
+
breakPointsCss.forEach((line) => {
|
|
156
|
+
const [key, value] = line.split(" ");
|
|
155
157
|
responsiveBreakPoints[key] = value;
|
|
156
158
|
});
|
|
157
159
|
const options = {
|
|
@@ -165,17 +167,41 @@ const main = plugin.withOptions((args) => {
|
|
|
165
167
|
shadow.handler(api);
|
|
166
168
|
};
|
|
167
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
|
+
};
|
|
168
197
|
const createOrUpdateFile = (filePath, content) => {
|
|
169
198
|
try {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
fs.writeFileSync(filePath, content);
|
|
176
|
-
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}`);
|
|
177
203
|
} else {
|
|
178
|
-
console.log(`⚠️ File already exists: ${
|
|
204
|
+
console.log(`⚠️ File already exists: ${normalizedPath}`);
|
|
179
205
|
replaceFileContent(filePath, /[\s\S]*/, content);
|
|
180
206
|
}
|
|
181
207
|
} catch (error) {
|
|
@@ -184,11 +210,12 @@ const createOrUpdateFile = (filePath, content) => {
|
|
|
184
210
|
};
|
|
185
211
|
const getFileContent = (filePath, searchPattern) => {
|
|
186
212
|
try {
|
|
187
|
-
|
|
188
|
-
|
|
213
|
+
const normalizedPath = normalizePath(filePath);
|
|
214
|
+
if (!safeExistsSync(filePath)) {
|
|
215
|
+
console.error(`❌ The specified file does not exist: ${normalizedPath}`);
|
|
189
216
|
return null;
|
|
190
217
|
}
|
|
191
|
-
const fileContent =
|
|
218
|
+
const fileContent = safeReadFileSync(filePath);
|
|
192
219
|
if (searchPattern) {
|
|
193
220
|
if (typeof searchPattern === "string") {
|
|
194
221
|
const found = fileContent.includes(searchPattern) ? searchPattern : false;
|
|
@@ -218,13 +245,16 @@ const getFileContent = (filePath, searchPattern) => {
|
|
|
218
245
|
};
|
|
219
246
|
const replaceFileContent = (filePath, searchPattern, replacement) => {
|
|
220
247
|
try {
|
|
248
|
+
const normalizedPath = normalizePath(filePath);
|
|
221
249
|
const results = replaceInFileSync({
|
|
222
|
-
files:
|
|
250
|
+
files: normalizedPath,
|
|
223
251
|
from: searchPattern,
|
|
224
252
|
to: replacement
|
|
225
253
|
});
|
|
226
254
|
if (results.length > 0 && results[0].hasChanged) {
|
|
227
|
-
console.log(
|
|
255
|
+
console.log(
|
|
256
|
+
`✅ Content successfully replaced in the file: ${normalizedPath}`
|
|
257
|
+
);
|
|
228
258
|
} else {
|
|
229
259
|
console.log(
|
|
230
260
|
`⚠️ No replacement made. Here are some possible reasons:
|
|
@@ -237,13 +267,23 @@ const replaceFileContent = (filePath, searchPattern, replacement) => {
|
|
|
237
267
|
}
|
|
238
268
|
};
|
|
239
269
|
const findTailwindCssFile = (startDir, searchPattern) => {
|
|
240
|
-
|
|
241
|
-
|
|
270
|
+
const normalizedStartDir = normalizePath(startDir);
|
|
271
|
+
console.log("Recherche du fichier contenant le motif...", normalizedStartDir);
|
|
272
|
+
const stack = [normalizedStartDir];
|
|
242
273
|
while (stack.length > 0) {
|
|
243
274
|
const currentDir = stack.pop();
|
|
244
|
-
|
|
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
|
+
}
|
|
245
285
|
for (const file of files) {
|
|
246
|
-
const filePath =
|
|
286
|
+
const filePath = join(currentDir, file);
|
|
247
287
|
let stats;
|
|
248
288
|
try {
|
|
249
289
|
stats = fs.statSync(filePath);
|
|
@@ -252,12 +292,15 @@ const findTailwindCssFile = (startDir, searchPattern) => {
|
|
|
252
292
|
continue;
|
|
253
293
|
}
|
|
254
294
|
if (stats.isDirectory()) {
|
|
255
|
-
if (file !== "node_modules"
|
|
295
|
+
if (file !== "node_modules" && !file.startsWith(".")) {
|
|
296
|
+
stack.push(filePath);
|
|
297
|
+
}
|
|
256
298
|
} else if (stats.isFile() && (file.endsWith(".css") || file.endsWith(".scss") || file.endsWith(".sass"))) {
|
|
257
299
|
try {
|
|
258
300
|
console.log(`Analyse du fichier : ${filePath}`);
|
|
259
|
-
const content =
|
|
260
|
-
|
|
301
|
+
const content = safeReadFileSync(filePath);
|
|
302
|
+
const hasMatch = typeof searchPattern === "string" ? content.includes(searchPattern) : searchPattern.test(content);
|
|
303
|
+
if (hasMatch) {
|
|
261
304
|
console.log("Fichier trouvé :", filePath);
|
|
262
305
|
return filePath;
|
|
263
306
|
}
|
|
@@ -268,13 +311,14 @@ const findTailwindCssFile = (startDir, searchPattern) => {
|
|
|
268
311
|
}
|
|
269
312
|
}
|
|
270
313
|
throw new Error(
|
|
271
|
-
`Impossible de trouver un fichier contenant "${searchPattern}" dans "${
|
|
314
|
+
`Impossible de trouver un fichier contenant "${searchPattern}" dans "${normalizedStartDir}".`
|
|
272
315
|
);
|
|
273
316
|
};
|
|
274
317
|
function findProjectRoot(startPath) {
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
318
|
+
const normalizedStartPath = normalizePath(startPath);
|
|
319
|
+
let currentPath = resolve(normalizedStartPath);
|
|
320
|
+
while (!fs.existsSync(join(currentPath, "package.json"))) {
|
|
321
|
+
const parentPath = dirname(currentPath);
|
|
278
322
|
if (currentPath === parentPath) {
|
|
279
323
|
throw new Error("Impossible de localiser la racine du projet.");
|
|
280
324
|
}
|
|
@@ -299,14 +343,13 @@ class TailwindImplPlugin extends PluginImplAbstract {
|
|
|
299
343
|
}
|
|
300
344
|
onLoad() {
|
|
301
345
|
let udixioCssPath = this.options.styleFilePath;
|
|
302
|
-
const projectRoot = findProjectRoot(
|
|
346
|
+
const projectRoot = findProjectRoot(path.resolve());
|
|
303
347
|
if (!udixioCssPath) {
|
|
304
348
|
const searchPattern = /@import ["']tailwindcss["'];/;
|
|
305
349
|
const replacement = `@import 'tailwindcss';
|
|
306
350
|
@import "./udixio.css";`;
|
|
307
351
|
const tailwindCssPath = findTailwindCssFile(projectRoot, searchPattern);
|
|
308
|
-
udixioCssPath =
|
|
309
|
-
console.log("rrgfgt", tailwindCssPath, 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
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tailwind.plugin.d.ts","sourceRoot":"","sources":["../src/tailwind.plugin.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"tailwind.plugin.d.ts","sourceRoot":"","sources":["../src/tailwind.plugin.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAG/E,UAAU,qBAAqB;IAE7B,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,MAAM,CAAC;CAExB;AAED,qBAAa,cAAe,SAAQ,cAAc,CAChD,kBAAkB,EAClB,qBAAqB,CACtB;IACQ,YAAY,wBAAgB;IAC5B,IAAI,SAAc;IACzB,WAAW,4BAAsB;CAClC;AAED,cAAM,kBAAmB,SAAQ,kBAAkB,CAAC,qBAAqB,CAAC;IACxE,MAAM;IAMN,MAAM;CA+FP"}
|
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/src/main.ts
CHANGED
|
@@ -35,8 +35,10 @@ export const main = plugin.withOptions<ConfigJs>((args) => {
|
|
|
35
35
|
if (!Array.isArray(breakPointsCss)) {
|
|
36
36
|
breakPointsCss = [breakPointsCss];
|
|
37
37
|
}
|
|
38
|
+
|
|
38
39
|
const responsiveBreakPoints: any = {};
|
|
39
|
-
breakPointsCss.forEach((
|
|
40
|
+
breakPointsCss.forEach((line) => {
|
|
41
|
+
const [key, value] = line.split(' ');
|
|
40
42
|
responsiveBreakPoints[key] = value;
|
|
41
43
|
});
|
|
42
44
|
|
package/src/tailwind.plugin.ts
CHANGED
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
import path from 'path';
|
|
9
9
|
import { FontPlugin, PluginAbstract, PluginImplAbstract } from '@udixio/theme';
|
|
10
10
|
import { ConfigCss } from './main';
|
|
11
|
-
import * as console from 'node:console';
|
|
12
11
|
|
|
13
12
|
interface TailwindPluginOptions {
|
|
14
13
|
// darkMode?: 'class' | 'media';
|
|
@@ -45,8 +44,6 @@ class TailwindImplPlugin extends PluginImplAbstract<TailwindPluginOptions> {
|
|
|
45
44
|
const tailwindCssPath = findTailwindCssFile(projectRoot, searchPattern);
|
|
46
45
|
udixioCssPath = path.join(tailwindCssPath, '../udixio.css');
|
|
47
46
|
|
|
48
|
-
console.log('rrgfgt', tailwindCssPath, udixioCssPath);
|
|
49
|
-
|
|
50
47
|
if (!getFileContent(tailwindCssPath, /@import\s+"\.\/udixio\.css";/)) {
|
|
51
48
|
replaceFileContent(tailwindCssPath, searchPattern, replacement);
|
|
52
49
|
}
|
package/vite.config.ts
CHANGED