@codefast/cli 0.3.16-canary.0 → 0.3.16-canary.2
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.
|
@@ -74,7 +74,7 @@ const MAX_STRIP_VARIANT_PASSES = 12;
|
|
|
74
74
|
const EMPTY_CN_TV_BINDINGS = /* @__PURE__ */ new Set();
|
|
75
75
|
/**
|
|
76
76
|
* Bucket sort order — **render pipeline** (lower → earlier in `cn()` output).
|
|
77
|
-
*
|
|
77
|
+
*
|
|
78
78
|
* Matches README: Existence → Position → Layout → Sizing → Spacing → Shape → Background
|
|
79
79
|
* → Shadow → Typography → Composite → Motion → Starting → Behavior → State → Selector,
|
|
80
80
|
* then `other` and `arbitrary` as sort tails for unknown utilities and arbitrary properties.
|
|
@@ -129,7 +129,7 @@ const COMPATIBLE_BUCKET_SETS = [
|
|
|
129
129
|
];
|
|
130
130
|
/**
|
|
131
131
|
* Responsive / variant prefix — Tailwind v4 aware.
|
|
132
|
-
*
|
|
132
|
+
*
|
|
133
133
|
* v3: sm: md: … — v4: @sm:, @min-[600px]:, @[480px]:, named @md/sidebar:,
|
|
134
134
|
* viewport md/sidebar:, min-[100px]: / max-[100px]:, …
|
|
135
135
|
*
|
|
@@ -157,7 +157,7 @@ function inDataAttributeStem(token) {
|
|
|
157
157
|
* Uses the **full variant stack** (every `:` segment outside `[…]`), not only the
|
|
158
158
|
* outermost prefix, so `@md/foo:[&>*]:w-auto` and `@md/foo:has-[…]:mt-px` stay in
|
|
159
159
|
* separate groups while `hover:opacity` still keys as `hover` + `opacity`…
|
|
160
|
-
*
|
|
160
|
+
*
|
|
161
161
|
* `data-[…]` / `aria-[…]` normalize the first segment via {@link dataAttributeStem} /
|
|
162
162
|
* {@link ariaAttributeStem} (full token required for bracket capture).
|
|
163
163
|
*
|
|
@@ -5,22 +5,22 @@ function resolvePackageScopedConfig(configMap, pkgMeta) {
|
|
|
5
5
|
if (!configMap) return;
|
|
6
6
|
return configMap[pkgMeta.packageName];
|
|
7
7
|
}
|
|
8
|
-
function
|
|
9
|
-
const
|
|
10
|
-
for (const
|
|
11
|
-
let
|
|
8
|
+
function groupDistFilesByModule(relativeDistFiles) {
|
|
9
|
+
const distModulesByPath = /* @__PURE__ */ new Map();
|
|
10
|
+
for (const relativeDistFile of relativeDistFiles) {
|
|
11
|
+
let fileExt;
|
|
12
12
|
let modulePath;
|
|
13
|
-
const
|
|
14
|
-
if (
|
|
15
|
-
|
|
16
|
-
modulePath =
|
|
13
|
+
const declarationExt = Array.from(VALID_DTS_EXTENSIONS).find((candidate) => relativeDistFile.endsWith(candidate));
|
|
14
|
+
if (declarationExt) {
|
|
15
|
+
fileExt = declarationExt;
|
|
16
|
+
modulePath = relativeDistFile.slice(0, -declarationExt.length);
|
|
17
17
|
} else {
|
|
18
|
-
|
|
19
|
-
if (!VALID_JS_EXTENSIONS.has(
|
|
20
|
-
modulePath =
|
|
18
|
+
fileExt = nodePath.extname(relativeDistFile);
|
|
19
|
+
if (!VALID_JS_EXTENSIONS.has(fileExt)) continue;
|
|
20
|
+
modulePath = relativeDistFile.slice(0, -fileExt.length);
|
|
21
21
|
}
|
|
22
22
|
if (!nodePath.basename(modulePath)) continue;
|
|
23
|
-
let distModule =
|
|
23
|
+
let distModule = distModulesByPath.get(modulePath);
|
|
24
24
|
if (!distModule) {
|
|
25
25
|
distModule = {
|
|
26
26
|
path: modulePath,
|
|
@@ -31,21 +31,24 @@ function groupFilesByModule(files) {
|
|
|
31
31
|
dts: null
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
|
-
|
|
34
|
+
distModulesByPath.set(modulePath, distModule);
|
|
35
35
|
}
|
|
36
|
-
if (
|
|
37
|
-
else if (
|
|
38
|
-
else if (
|
|
39
|
-
else if (VALID_DTS_EXTENSIONS.has(
|
|
36
|
+
if (fileExt === ".js") distModule.files.js = relativeDistFile;
|
|
37
|
+
else if (fileExt === ".mjs") distModule.files.mjs = relativeDistFile;
|
|
38
|
+
else if (fileExt === ".cjs") distModule.files.cjs = relativeDistFile;
|
|
39
|
+
else if (VALID_DTS_EXTENSIONS.has(fileExt)) distModule.files.dts = relativeDistFile;
|
|
40
40
|
}
|
|
41
|
-
return
|
|
41
|
+
return distModulesByPath;
|
|
42
42
|
}
|
|
43
43
|
function toExportPath(distPath) {
|
|
44
44
|
if (distPath === "index") return ".";
|
|
45
45
|
if (distPath.endsWith("/index")) return `./${distPath.slice(0, -6)}`;
|
|
46
46
|
return `./${distPath}`;
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
function isBundlerChunkPath(distPath) {
|
|
49
|
+
return distPath.split("/").includes("chunks");
|
|
50
|
+
}
|
|
51
|
+
const EXPORT_GROUP_ORDER = {
|
|
49
52
|
components: 100,
|
|
50
53
|
hooks: 200,
|
|
51
54
|
primitives: 300,
|
|
@@ -56,16 +59,16 @@ const GROUP_ORDER = {
|
|
|
56
59
|
script: 750,
|
|
57
60
|
css: 900
|
|
58
61
|
};
|
|
59
|
-
function
|
|
62
|
+
function getExportSortGroup(exportPath, pathTransform) {
|
|
60
63
|
if (exportPath === ".") return [
|
|
61
64
|
".",
|
|
62
65
|
"",
|
|
63
66
|
0,
|
|
64
67
|
0
|
|
65
68
|
];
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
68
|
-
const dirName =
|
|
69
|
+
const specifierPath = exportPath.startsWith("./") ? exportPath.slice(2) : exportPath;
|
|
70
|
+
if (specifierPath.endsWith("/*")) {
|
|
71
|
+
const dirName = specifierPath.slice(0, -2);
|
|
69
72
|
return [
|
|
70
73
|
dirName,
|
|
71
74
|
"",
|
|
@@ -73,14 +76,14 @@ function getExportGroup(exportPath, pathTransform) {
|
|
|
73
76
|
0
|
|
74
77
|
];
|
|
75
78
|
}
|
|
76
|
-
const parts =
|
|
79
|
+
const parts = specifierPath.split("/");
|
|
77
80
|
if (parts.length === 1) {
|
|
78
81
|
const name = parts[0];
|
|
79
82
|
if (name === void 0) throw new Error("invariant: export path segment missing");
|
|
80
|
-
if (name in
|
|
83
|
+
if (name in EXPORT_GROUP_ORDER) return [
|
|
81
84
|
name,
|
|
82
85
|
"",
|
|
83
|
-
|
|
86
|
+
EXPORT_GROUP_ORDER[name] ?? 0,
|
|
84
87
|
0
|
|
85
88
|
];
|
|
86
89
|
if (pathTransform) return [
|
|
@@ -100,7 +103,7 @@ function getExportGroup(exportPath, pathTransform) {
|
|
|
100
103
|
return [
|
|
101
104
|
group,
|
|
102
105
|
parts.slice(1).join("/"),
|
|
103
|
-
|
|
106
|
+
EXPORT_GROUP_ORDER[group] ?? 700,
|
|
104
107
|
1
|
|
105
108
|
];
|
|
106
109
|
}
|
|
@@ -114,21 +117,21 @@ function createPathTransform(config, pkgMeta) {
|
|
|
114
117
|
if (!removePrefix) return null;
|
|
115
118
|
return (exportPath) => {
|
|
116
119
|
if (!exportPath.startsWith(removePrefix)) return exportPath;
|
|
117
|
-
const
|
|
118
|
-
if (
|
|
119
|
-
return
|
|
120
|
+
const trimmedExportPath = exportPath.slice(removePrefix.length);
|
|
121
|
+
if (trimmedExportPath && trimmedExportPath !== "." && !trimmedExportPath.startsWith("./")) return `./${trimmedExportPath}`;
|
|
122
|
+
return trimmedExportPath;
|
|
120
123
|
};
|
|
121
124
|
}
|
|
122
|
-
function
|
|
123
|
-
const [
|
|
125
|
+
function getExportSortKey(exportPath, pathTransform) {
|
|
126
|
+
const [groupName, subpath, groupOrder, indexRank] = getExportSortGroup(exportPath, pathTransform);
|
|
124
127
|
return [
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
groupOrder,
|
|
129
|
+
groupName,
|
|
130
|
+
indexRank,
|
|
128
131
|
subpath
|
|
129
132
|
];
|
|
130
133
|
}
|
|
131
|
-
function
|
|
134
|
+
function compareExportSortKeys(left, right) {
|
|
132
135
|
if (left[0] !== right[0]) return left[0] - right[0];
|
|
133
136
|
if (left[1] !== right[1]) return left[1] < right[1] ? -1 : 1;
|
|
134
137
|
if (left[2] !== right[2]) return left[2] - right[2];
|
|
@@ -142,27 +145,27 @@ async function generateCssExports(fileSystemService, distDir, cssConfig) {
|
|
|
142
145
|
const cssFiles = (await fileSystemService.listRelativeFilesRecursively(distDir)).filter((relativeDistPath) => relativeDistPath.endsWith(".css"));
|
|
143
146
|
if (!cssFiles.length) return {};
|
|
144
147
|
const cssExports = { ...cssConfig.customExports };
|
|
145
|
-
const
|
|
146
|
-
const
|
|
147
|
-
for (const
|
|
148
|
-
const dirName = nodePath.dirname(
|
|
149
|
-
if (dirName === ".")
|
|
148
|
+
const cssFilesByDir = /* @__PURE__ */ new Map();
|
|
149
|
+
const rootCssFiles = [];
|
|
150
|
+
for (const cssFile of cssFiles) {
|
|
151
|
+
const dirName = nodePath.dirname(cssFile).split(nodePath.sep).join("/");
|
|
152
|
+
if (dirName === ".") rootCssFiles.push(cssFile);
|
|
150
153
|
else {
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
+
const dirCssFiles = cssFilesByDir.get(dirName) || [];
|
|
155
|
+
dirCssFiles.push(cssFile);
|
|
156
|
+
cssFilesByDir.set(dirName, dirCssFiles);
|
|
154
157
|
}
|
|
155
158
|
}
|
|
156
|
-
for (const
|
|
157
|
-
const exportPath = `./${
|
|
158
|
-
if (!(exportPath in cssExports)) cssExports[exportPath] = `./dist/${
|
|
159
|
+
for (const cssFile of rootCssFiles) {
|
|
160
|
+
const exportPath = `./${cssFile}`;
|
|
161
|
+
if (!(exportPath in cssExports)) cssExports[exportPath] = `./dist/${cssFile}`;
|
|
159
162
|
}
|
|
160
|
-
for (const [dirName,
|
|
163
|
+
for (const [dirName, dirCssFiles] of cssFilesByDir.entries()) if (await fileSystemService.isDirectoryCssOnly(distDir, dirName) && !cssConfig.forceExportFiles) {
|
|
161
164
|
const wildcardExport = `./${dirName}/*`;
|
|
162
165
|
if (!(wildcardExport in cssExports)) cssExports[wildcardExport] = `./dist/${dirName}/*`;
|
|
163
|
-
} else for (const
|
|
164
|
-
const exportPath = `./${
|
|
165
|
-
if (!(exportPath in cssExports)) cssExports[exportPath] = `./dist/${
|
|
166
|
+
} else for (const cssFile of dirCssFiles) {
|
|
167
|
+
const exportPath = `./${cssFile}`;
|
|
168
|
+
if (!(exportPath in cssExports)) cssExports[exportPath] = `./dist/${cssFile}`;
|
|
166
169
|
}
|
|
167
170
|
return cssExports;
|
|
168
171
|
}
|
|
@@ -172,53 +175,53 @@ async function generateCssExports(fileSystemService, distDir, cssConfig) {
|
|
|
172
175
|
* @since 0.3.16-canary.0
|
|
173
176
|
*/
|
|
174
177
|
async function generateExports(fileSystemService, distDir, pathTransform, cssConfig, customExports) {
|
|
175
|
-
const
|
|
176
|
-
if (!
|
|
178
|
+
const relativeDistFiles = await fileSystemService.listRelativeFilesRecursively(distDir);
|
|
179
|
+
if (!relativeDistFiles.length) return {
|
|
177
180
|
exports: { [PACKAGE_JSON_EXPORT]: PACKAGE_JSON_EXPORT },
|
|
178
181
|
originalPathBySpecifier: { [PACKAGE_JSON_EXPORT]: PACKAGE_JSON_EXPORT },
|
|
179
182
|
jsCount: 0,
|
|
180
183
|
cssCount: 0
|
|
181
184
|
};
|
|
182
|
-
const
|
|
183
|
-
const
|
|
184
|
-
if (!
|
|
185
|
+
const distModulesByPath = groupDistFilesByModule(relativeDistFiles);
|
|
186
|
+
const exportableModules = Array.from(distModulesByPath.values()).filter((moduleEntry) => (moduleEntry.files.js || moduleEntry.files.mjs) && !isBundlerChunkPath(moduleEntry.path));
|
|
187
|
+
if (!exportableModules.length) return {
|
|
185
188
|
exports: { [PACKAGE_JSON_EXPORT]: PACKAGE_JSON_EXPORT },
|
|
186
189
|
originalPathBySpecifier: { [PACKAGE_JSON_EXPORT]: PACKAGE_JSON_EXPORT },
|
|
187
190
|
jsCount: 0,
|
|
188
191
|
cssCount: 0
|
|
189
192
|
};
|
|
190
|
-
const
|
|
193
|
+
const moduleExportsBySpecifier = {};
|
|
191
194
|
const originalPathBySpecifier = {};
|
|
192
|
-
for (const distModuleEntry of
|
|
195
|
+
for (const distModuleEntry of exportableModules) {
|
|
193
196
|
const originalExportPath = toExportPath(distModuleEntry.path);
|
|
194
197
|
let exportPath = originalExportPath;
|
|
195
198
|
if (pathTransform) exportPath = pathTransform(exportPath);
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if (distModuleEntry.files.mjs)
|
|
200
|
-
else if (distModuleEntry.files.js)
|
|
201
|
-
if (distModuleEntry.files.cjs)
|
|
202
|
-
|
|
199
|
+
const exportEntry = {};
|
|
200
|
+
const declarationFile = distModuleEntry.files.dts;
|
|
201
|
+
if (declarationFile) exportEntry.types = `./dist/${declarationFile}`;
|
|
202
|
+
if (distModuleEntry.files.mjs) exportEntry.import = `./dist/${distModuleEntry.files.mjs}`;
|
|
203
|
+
else if (distModuleEntry.files.js) exportEntry.import = `./dist/${distModuleEntry.files.js}`;
|
|
204
|
+
if (distModuleEntry.files.cjs) exportEntry.require = `./dist/${distModuleEntry.files.cjs}`;
|
|
205
|
+
moduleExportsBySpecifier[exportPath] = exportEntry;
|
|
203
206
|
originalPathBySpecifier[exportPath] = originalExportPath;
|
|
204
207
|
}
|
|
205
|
-
let
|
|
208
|
+
let sortedSpecifiers = Object.keys(moduleExportsBySpecifier).sort((leftSpecifier, rightSpecifier) => compareExportSortKeys(getExportSortKey(leftSpecifier, pathTransform), getExportSortKey(rightSpecifier, pathTransform)));
|
|
206
209
|
const sortedExports = {};
|
|
207
|
-
for (const exportKey of
|
|
210
|
+
for (const exportKey of sortedSpecifiers) sortedExports[exportKey] = moduleExportsBySpecifier[exportKey];
|
|
208
211
|
const cssExports = await generateCssExports(fileSystemService, distDir, cssConfig ?? { enabled: true });
|
|
209
212
|
Object.assign(sortedExports, cssExports);
|
|
210
213
|
for (const [specifier, mappedPath] of Object.entries(customExports || {})) if (specifier !== "./package.json") sortedExports[specifier] = mappedPath;
|
|
211
214
|
for (const cssSpecifier of Object.keys(cssExports)) if (!(cssSpecifier in originalPathBySpecifier)) originalPathBySpecifier[cssSpecifier] = cssSpecifier;
|
|
212
215
|
for (const customSpecifier of Object.keys(customExports || {})) if (customSpecifier !== "./package.json" && !(customSpecifier in originalPathBySpecifier)) originalPathBySpecifier[customSpecifier] = customSpecifier;
|
|
213
|
-
|
|
216
|
+
sortedSpecifiers = Object.keys(sortedExports).filter((exportKey) => exportKey !== PACKAGE_JSON_EXPORT).sort((leftSpecifier, rightSpecifier) => compareExportSortKeys(getExportSortKey(leftSpecifier, pathTransform), getExportSortKey(rightSpecifier, pathTransform)));
|
|
214
217
|
const finalExports = {};
|
|
215
|
-
for (const exportKey of
|
|
218
|
+
for (const exportKey of sortedSpecifiers) finalExports[exportKey] = sortedExports[exportKey];
|
|
216
219
|
finalExports[PACKAGE_JSON_EXPORT] = PACKAGE_JSON_EXPORT;
|
|
217
220
|
originalPathBySpecifier[PACKAGE_JSON_EXPORT] = PACKAGE_JSON_EXPORT;
|
|
218
221
|
return {
|
|
219
222
|
exports: finalExports,
|
|
220
223
|
originalPathBySpecifier,
|
|
221
|
-
jsCount: Object.keys(
|
|
224
|
+
jsCount: Object.keys(moduleExportsBySpecifier).length,
|
|
222
225
|
cssCount: Object.keys(cssExports).length
|
|
223
226
|
};
|
|
224
227
|
}
|
|
@@ -5,6 +5,7 @@ import ts from "typescript";
|
|
|
5
5
|
* @since 0.3.16-canary.0
|
|
6
6
|
*/
|
|
7
7
|
var TagSinceWriter = class {
|
|
8
|
+
fs;
|
|
8
9
|
sinceDocumentationTag = "@since";
|
|
9
10
|
constructor(fs) {
|
|
10
11
|
this.fs = fs;
|
|
@@ -103,7 +104,7 @@ var TagSinceWriter = class {
|
|
|
103
104
|
const hasNonEmptyAfter = lines.slice(lineIndex + 1).some((value) => value.length > 0);
|
|
104
105
|
return hasNonEmptyBefore && hasNonEmptyAfter;
|
|
105
106
|
});
|
|
106
|
-
const replacement = `/**\n${normalizedBodyLines.length > 0 ? `${normalizedBodyLines.map((line) => `${baseIndent} * ${line}`).join("\n")}\n${baseIndent} *\n` : ""}${baseIndent} * ${this.sinceDocumentationTag} ${version}\n${baseIndent} */`;
|
|
107
|
+
const replacement = `/**\n${normalizedBodyLines.length > 0 ? `${normalizedBodyLines.map((line) => line.length > 0 ? `${baseIndent} * ${line}` : `${baseIndent} *`).join("\n")}\n${baseIndent} *\n` : ""}${baseIndent} * ${this.sinceDocumentationTag} ${version}\n${baseIndent} */`;
|
|
107
108
|
return {
|
|
108
109
|
start: existingComment.pos,
|
|
109
110
|
end: existingComment.end,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codefast/cli",
|
|
3
|
-
"version": "0.3.16-canary.
|
|
3
|
+
"version": "0.3.16-canary.2",
|
|
4
4
|
"description": "Developer CLI for the Codefast monorepo (arrange, mirror, tag)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -52,20 +52,21 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"commander": "^14.0.3",
|
|
55
|
-
"jiti": "^2.
|
|
55
|
+
"jiti": "^2.7.0",
|
|
56
56
|
"picomatch": "^4.0.4",
|
|
57
57
|
"typescript": "^6.0.3",
|
|
58
|
-
"yaml": "^2.
|
|
58
|
+
"yaml": "^2.9.0",
|
|
59
59
|
"zod": "^4.4.3"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@types/node": "^25.
|
|
62
|
+
"@types/node": "^25.7.0",
|
|
63
63
|
"@types/picomatch": "^4.0.3",
|
|
64
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
65
|
-
"@vitest/coverage-v8": "^4.1.
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
64
|
+
"@typescript/native-preview": "7.0.0-dev.20260514.1",
|
|
65
|
+
"@vitest/coverage-v8": "^4.1.6",
|
|
66
|
+
"tsdown": "^0.22.0",
|
|
67
|
+
"vite": "^8.0.13",
|
|
68
|
+
"vitest": "^4.1.6",
|
|
69
|
+
"@codefast/typescript-config": "0.3.16-canary.2"
|
|
69
70
|
},
|
|
70
71
|
"engines": {
|
|
71
72
|
"node": ">=22.0.0"
|
|
@@ -75,9 +76,11 @@
|
|
|
75
76
|
"check-types": "tsgo --noEmit",
|
|
76
77
|
"clean": "rm -rf dist",
|
|
77
78
|
"test": "vitest run",
|
|
79
|
+
"test:coverage": "vitest run --coverage",
|
|
80
|
+
"test:e2e": "vitest run tests/e2e",
|
|
78
81
|
"test:integration": "vitest run tests/integration",
|
|
82
|
+
"test:type": "vitest run tests/types",
|
|
79
83
|
"test:unit": "vitest run tests/unit",
|
|
80
|
-
"test:coverage": "vitest run --coverage",
|
|
81
84
|
"test:watch": "vitest"
|
|
82
85
|
}
|
|
83
86
|
}
|