@regardio/dev 1.11.4 → 1.12.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://www.schemastore.org/package.json",
3
3
  "name": "@regardio/dev",
4
- "version": "1.11.4",
4
+ "version": "1.12.0",
5
5
  "private": false,
6
6
  "description": "Regardio developer tooling for testing, linting, and build workflows",
7
7
  "keywords": [
@@ -67,8 +67,7 @@
67
67
  "lint-biome": "dist/bin/lint-biome.js",
68
68
  "lint-commit": "dist/bin/lint-commit.js",
69
69
  "lint-md": "dist/bin/lint-md.js",
70
- "lint-package": "dist/bin/lint-package.js",
71
- "post-build-exports": "dist/bin/post-build-exports.js"
70
+ "lint-package": "dist/bin/lint-package.js"
72
71
  },
73
72
  "files": [
74
73
  "dist",
@@ -102,9 +101,9 @@
102
101
  "@testing-library/jest-dom": "6.9.1",
103
102
  "@testing-library/react": "16.3.1",
104
103
  "@total-typescript/ts-reset": "0.6.1",
105
- "@types/node": "25.0.6",
106
- "@vitest/coverage-v8": "4.0.16",
107
- "@vitest/ui": "4.0.16",
104
+ "@types/node": "25.0.8",
105
+ "@vitest/coverage-v8": "4.0.17",
106
+ "@vitest/ui": "4.0.17",
108
107
  "husky": "9.1.7",
109
108
  "jsdom": "27.4.0",
110
109
  "markdownlint-cli2": "0.20.0",
@@ -115,7 +114,7 @@
115
114
  "tsx": "4.21.0",
116
115
  "typescript": "5.9.3",
117
116
  "vite": "7.3.1",
118
- "vitest": "4.0.16"
117
+ "vitest": "4.0.17"
119
118
  },
120
119
  "peerDependencies": {
121
120
  "postcss": "8.4"
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=post-build-exports.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"post-build-exports.d.ts","sourceRoot":"","sources":["../../src/bin/post-build-exports.ts"],"names":[],"mappings":""}
@@ -1,123 +0,0 @@
1
- #!/usr/bin/env node
2
- import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
3
- import { join, relative } from 'node:path';
4
- function parseArgs(args) {
5
- const result = {
6
- dist: 'dist',
7
- prefix: './',
8
- preserve: [],
9
- strip: '',
10
- };
11
- for (let i = 0; i < args.length; i++) {
12
- const arg = args[i];
13
- const next = args[i + 1];
14
- if (arg === '--dist' && next) {
15
- result.dist = next;
16
- i++;
17
- }
18
- else if (arg === '--preserve' && next) {
19
- result.preserve = next.split(',').map((p) => p.trim());
20
- i++;
21
- }
22
- else if (arg === '--prefix' && next) {
23
- result.prefix = next;
24
- i++;
25
- }
26
- else if (arg === '--strip' && next) {
27
- result.strip = next;
28
- i++;
29
- }
30
- }
31
- return result;
32
- }
33
- function findJsFiles(dir, baseDir) {
34
- const files = [];
35
- if (!existsSync(dir)) {
36
- return files;
37
- }
38
- const entries = readdirSync(dir);
39
- for (const entry of entries) {
40
- const fullPath = join(dir, entry);
41
- const stat = statSync(fullPath);
42
- if (stat.isDirectory()) {
43
- files.push(...findJsFiles(fullPath, baseDir));
44
- }
45
- else if (entry.endsWith('.js') && !entry.endsWith('.test.js')) {
46
- files.push(relative(baseDir, fullPath));
47
- }
48
- }
49
- return files;
50
- }
51
- function generateExportName(jsPath, strip) {
52
- let exportPath = jsPath.replace(/\.js$/, '');
53
- if (strip && exportPath.startsWith(strip)) {
54
- exportPath = exportPath.slice(strip.length);
55
- if (exportPath.startsWith('/')) {
56
- exportPath = exportPath.slice(1);
57
- }
58
- }
59
- if (exportPath.endsWith('/index')) {
60
- exportPath = exportPath.slice(0, -6);
61
- }
62
- return `./${exportPath}`;
63
- }
64
- function generateExports(jsFiles, distDir, strip) {
65
- const exports = {};
66
- for (const jsFile of jsFiles.sort()) {
67
- const exportName = generateExportName(jsFile, strip);
68
- const dtsFile = jsFile.replace(/\.js$/, '.d.ts');
69
- const dtsPath = join(process.cwd(), distDir, dtsFile.replace(/^dist\//, ''));
70
- const entry = {
71
- import: `./${distDir}/${jsFile}`.replace(/\/+/g, '/'),
72
- };
73
- if (existsSync(dtsPath) || existsSync(join(process.cwd(), distDir, dtsFile))) {
74
- entry.types = `./${distDir}/${dtsFile}`.replace(/\/+/g, '/');
75
- }
76
- exports[exportName] = entry;
77
- }
78
- return exports;
79
- }
80
- function main() {
81
- const args = process.argv.slice(2);
82
- const options = parseArgs(args);
83
- const packageJsonPath = join(process.cwd(), 'package.json');
84
- if (!existsSync(packageJsonPath)) {
85
- console.error('No package.json found in current directory');
86
- process.exit(1);
87
- }
88
- const distPath = join(process.cwd(), options.dist);
89
- if (!existsSync(distPath)) {
90
- console.error(`Dist directory not found: ${options.dist}`);
91
- console.error('Run build first before generating exports.');
92
- process.exit(1);
93
- }
94
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
95
- const existingExports = packageJson.exports || {};
96
- const preservedExports = {};
97
- for (const preservePath of options.preserve) {
98
- const existing = existingExports[preservePath];
99
- if (existing !== undefined) {
100
- preservedExports[preservePath] = existing;
101
- }
102
- }
103
- const jsFiles = findJsFiles(distPath, distPath);
104
- const generatedExports = generateExports(jsFiles, options.dist, options.strip);
105
- const newExports = {
106
- ...preservedExports,
107
- ...generatedExports,
108
- };
109
- const sortedExports = {};
110
- for (const key of Object.keys(newExports).sort()) {
111
- const value = newExports[key];
112
- if (value !== undefined) {
113
- sortedExports[key] = value;
114
- }
115
- }
116
- packageJson.exports = sortedExports;
117
- writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
118
- console.log(`✅ Generated ${Object.keys(generatedExports).length} exports in package.json`);
119
- if (options.preserve.length > 0) {
120
- console.log(` Preserved ${Object.keys(preservedExports).length} existing exports`);
121
- }
122
- }
123
- main();
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=post-build-exports.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"post-build-exports.test.d.ts","sourceRoot":"","sources":["../../src/bin/post-build-exports.test.ts"],"names":[],"mappings":""}
@@ -1,119 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- function parseArgs(args) {
3
- const result = {
4
- dist: 'dist',
5
- prefix: './',
6
- preserve: [],
7
- strip: '',
8
- };
9
- for (let i = 0; i < args.length; i++) {
10
- const arg = args[i];
11
- const next = args[i + 1];
12
- if (arg === '--dist' && next) {
13
- result.dist = next;
14
- i++;
15
- }
16
- else if (arg === '--preserve' && next) {
17
- result.preserve = next.split(',').map((p) => p.trim());
18
- i++;
19
- }
20
- else if (arg === '--prefix' && next) {
21
- result.prefix = next;
22
- i++;
23
- }
24
- else if (arg === '--strip' && next) {
25
- result.strip = next;
26
- i++;
27
- }
28
- }
29
- return result;
30
- }
31
- function generateExportName(jsPath, strip) {
32
- let exportPath = jsPath.replace(/\.js$/, '');
33
- if (strip && exportPath.startsWith(strip)) {
34
- exportPath = exportPath.slice(strip.length);
35
- if (exportPath.startsWith('/')) {
36
- exportPath = exportPath.slice(1);
37
- }
38
- }
39
- if (exportPath.endsWith('/index')) {
40
- exportPath = exportPath.slice(0, -6);
41
- }
42
- return `./${exportPath}`;
43
- }
44
- describe('post-build-exports', () => {
45
- describe('parseArgs', () => {
46
- it('should return defaults when no args provided', () => {
47
- const result = parseArgs([]);
48
- expect(result).toEqual({
49
- dist: 'dist',
50
- prefix: './',
51
- preserve: [],
52
- strip: '',
53
- });
54
- });
55
- it('should parse --dist option', () => {
56
- const result = parseArgs(['--dist', 'build']);
57
- expect(result.dist).toBe('build');
58
- });
59
- it('should parse --preserve option with single value', () => {
60
- const result = parseArgs(['--preserve', './tailwind.css']);
61
- expect(result.preserve).toEqual(['./tailwind.css']);
62
- });
63
- it('should parse --preserve option with multiple comma-separated values', () => {
64
- const result = parseArgs(['--preserve', './a.css, ./b.css, ./c.css']);
65
- expect(result.preserve).toEqual(['./a.css', './b.css', './c.css']);
66
- });
67
- it('should parse --prefix option', () => {
68
- const result = parseArgs(['--prefix', './lib/']);
69
- expect(result.prefix).toBe('./lib/');
70
- });
71
- it('should parse --strip option', () => {
72
- const result = parseArgs(['--strip', 'generated']);
73
- expect(result.strip).toBe('generated');
74
- });
75
- it('should parse multiple options together', () => {
76
- const result = parseArgs([
77
- '--dist',
78
- 'output',
79
- '--preserve',
80
- './styles.css',
81
- '--strip',
82
- 'src',
83
- ]);
84
- expect(result).toEqual({
85
- dist: 'output',
86
- prefix: './',
87
- preserve: ['./styles.css'],
88
- strip: 'src',
89
- });
90
- });
91
- it('should ignore unknown options', () => {
92
- const result = parseArgs(['--unknown', 'value', '--dist', 'build']);
93
- expect(result.dist).toBe('build');
94
- });
95
- });
96
- describe('generateExportName', () => {
97
- it('should convert .js path to export name', () => {
98
- expect(generateExportName('foo.js', '')).toBe('./foo');
99
- });
100
- it('should handle nested paths', () => {
101
- expect(generateExportName('utils/helpers.js', '')).toBe('./utils/helpers');
102
- });
103
- it('should strip /index suffix', () => {
104
- expect(generateExportName('components/button/index.js', '')).toBe('./components/button');
105
- });
106
- it('should apply strip prefix', () => {
107
- expect(generateExportName('generated/icons/arrow.js', 'generated')).toBe('./icons/arrow');
108
- });
109
- it('should handle strip with leading slash', () => {
110
- expect(generateExportName('generated/icons/arrow.js', 'generated/')).toBe('./icons/arrow');
111
- });
112
- it('should handle index.js at root', () => {
113
- expect(generateExportName('index.js', '')).toBe('./index');
114
- });
115
- it('should handle deeply nested index files', () => {
116
- expect(generateExportName('a/b/c/index.js', '')).toBe('./a/b/c');
117
- });
118
- });
119
- });
@@ -1,161 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
-
3
- /**
4
- * Parse command line arguments for post-build-exports.
5
- * Extracted from post-build-exports.ts for testing.
6
- */
7
- function parseArgs(args: string[]): {
8
- dist: string;
9
- preserve: string[];
10
- prefix: string;
11
- strip: string;
12
- } {
13
- const result = {
14
- dist: 'dist',
15
- prefix: './',
16
- preserve: [] as string[],
17
- strip: '',
18
- };
19
-
20
- for (let i = 0; i < args.length; i++) {
21
- const arg = args[i];
22
- const next = args[i + 1];
23
-
24
- if (arg === '--dist' && next) {
25
- result.dist = next;
26
- i++;
27
- } else if (arg === '--preserve' && next) {
28
- result.preserve = next.split(',').map((p) => p.trim());
29
- i++;
30
- } else if (arg === '--prefix' && next) {
31
- result.prefix = next;
32
- i++;
33
- } else if (arg === '--strip' && next) {
34
- result.strip = next;
35
- i++;
36
- }
37
- }
38
-
39
- return result;
40
- }
41
-
42
- /**
43
- * Generate export name from JS file path.
44
- * Extracted from post-build-exports.ts for testing.
45
- */
46
- function generateExportName(jsPath: string, strip: string): string {
47
- let exportPath = jsPath.replace(/\.js$/, '');
48
-
49
- if (strip && exportPath.startsWith(strip)) {
50
- exportPath = exportPath.slice(strip.length);
51
- if (exportPath.startsWith('/')) {
52
- exportPath = exportPath.slice(1);
53
- }
54
- }
55
-
56
- // Strip /index suffix for cleaner exports
57
- if (exportPath.endsWith('/index')) {
58
- exportPath = exportPath.slice(0, -6);
59
- }
60
-
61
- return `./${exportPath}`;
62
- }
63
-
64
- describe('post-build-exports', () => {
65
- describe('parseArgs', () => {
66
- it('should return defaults when no args provided', () => {
67
- const result = parseArgs([]);
68
-
69
- expect(result).toEqual({
70
- dist: 'dist',
71
- prefix: './',
72
- preserve: [],
73
- strip: '',
74
- });
75
- });
76
-
77
- it('should parse --dist option', () => {
78
- const result = parseArgs(['--dist', 'build']);
79
-
80
- expect(result.dist).toBe('build');
81
- });
82
-
83
- it('should parse --preserve option with single value', () => {
84
- const result = parseArgs(['--preserve', './tailwind.css']);
85
-
86
- expect(result.preserve).toEqual(['./tailwind.css']);
87
- });
88
-
89
- it('should parse --preserve option with multiple comma-separated values', () => {
90
- const result = parseArgs(['--preserve', './a.css, ./b.css, ./c.css']);
91
-
92
- expect(result.preserve).toEqual(['./a.css', './b.css', './c.css']);
93
- });
94
-
95
- it('should parse --prefix option', () => {
96
- const result = parseArgs(['--prefix', './lib/']);
97
-
98
- expect(result.prefix).toBe('./lib/');
99
- });
100
-
101
- it('should parse --strip option', () => {
102
- const result = parseArgs(['--strip', 'generated']);
103
-
104
- expect(result.strip).toBe('generated');
105
- });
106
-
107
- it('should parse multiple options together', () => {
108
- const result = parseArgs([
109
- '--dist',
110
- 'output',
111
- '--preserve',
112
- './styles.css',
113
- '--strip',
114
- 'src',
115
- ]);
116
-
117
- expect(result).toEqual({
118
- dist: 'output',
119
- prefix: './',
120
- preserve: ['./styles.css'],
121
- strip: 'src',
122
- });
123
- });
124
-
125
- it('should ignore unknown options', () => {
126
- const result = parseArgs(['--unknown', 'value', '--dist', 'build']);
127
-
128
- expect(result.dist).toBe('build');
129
- });
130
- });
131
-
132
- describe('generateExportName', () => {
133
- it('should convert .js path to export name', () => {
134
- expect(generateExportName('foo.js', '')).toBe('./foo');
135
- });
136
-
137
- it('should handle nested paths', () => {
138
- expect(generateExportName('utils/helpers.js', '')).toBe('./utils/helpers');
139
- });
140
-
141
- it('should strip /index suffix', () => {
142
- expect(generateExportName('components/button/index.js', '')).toBe('./components/button');
143
- });
144
-
145
- it('should apply strip prefix', () => {
146
- expect(generateExportName('generated/icons/arrow.js', 'generated')).toBe('./icons/arrow');
147
- });
148
-
149
- it('should handle strip with leading slash', () => {
150
- expect(generateExportName('generated/icons/arrow.js', 'generated/')).toBe('./icons/arrow');
151
- });
152
-
153
- it('should handle index.js at root', () => {
154
- expect(generateExportName('index.js', '')).toBe('./index');
155
- });
156
-
157
- it('should handle deeply nested index files', () => {
158
- expect(generateExportName('a/b/c/index.js', '')).toBe('./a/b/c');
159
- });
160
- });
161
- });
@@ -1,189 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * post-build-exports: Auto-generate package.json exports from built files.
4
- *
5
- * Usage: post-build-exports [options]
6
- *
7
- * Options:
8
- * --dist <path> Path to dist directory (default: "dist")
9
- * --preserve <paths> Comma-separated export paths to preserve (e.g., "./tailwind.css")
10
- * --prefix <path> Prefix for export paths (default: "./")
11
- * --strip <path> Path prefix to strip from export names (default: none)
12
- *
13
- * This script:
14
- * 1. Scans the dist directory for .js files
15
- * 2. Generates explicit exports in package.json
16
- * 3. Preserves any exports listed in --preserve
17
- *
18
- * Example:
19
- * post-build-exports --dist dist --preserve "./tailwind.css"
20
- */
21
- import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
22
- import { join, relative } from 'node:path';
23
-
24
- interface ExportEntry {
25
- import?: string;
26
- types?: string;
27
- default?: string;
28
- }
29
-
30
- type ExportsMap = Record<string, ExportEntry | string>;
31
-
32
- interface PackageJson {
33
- exports?: ExportsMap;
34
- [key: string]: unknown;
35
- }
36
-
37
- function parseArgs(args: string[]): {
38
- dist: string;
39
- preserve: string[];
40
- prefix: string;
41
- strip: string;
42
- } {
43
- const result = {
44
- dist: 'dist',
45
- prefix: './',
46
- preserve: [] as string[],
47
- strip: '',
48
- };
49
-
50
- for (let i = 0; i < args.length; i++) {
51
- const arg = args[i];
52
- const next = args[i + 1];
53
-
54
- if (arg === '--dist' && next) {
55
- result.dist = next;
56
- i++;
57
- } else if (arg === '--preserve' && next) {
58
- result.preserve = next.split(',').map((p) => p.trim());
59
- i++;
60
- } else if (arg === '--prefix' && next) {
61
- result.prefix = next;
62
- i++;
63
- } else if (arg === '--strip' && next) {
64
- result.strip = next;
65
- i++;
66
- }
67
- }
68
-
69
- return result;
70
- }
71
-
72
- function findJsFiles(dir: string, baseDir: string): string[] {
73
- const files: string[] = [];
74
-
75
- if (!existsSync(dir)) {
76
- return files;
77
- }
78
-
79
- const entries = readdirSync(dir);
80
-
81
- for (const entry of entries) {
82
- const fullPath = join(dir, entry);
83
- const stat = statSync(fullPath);
84
-
85
- if (stat.isDirectory()) {
86
- files.push(...findJsFiles(fullPath, baseDir));
87
- } else if (entry.endsWith('.js') && !entry.endsWith('.test.js')) {
88
- files.push(relative(baseDir, fullPath));
89
- }
90
- }
91
-
92
- return files;
93
- }
94
-
95
- function generateExportName(jsPath: string, strip: string): string {
96
- let exportPath = jsPath.replace(/\.js$/, '');
97
-
98
- if (strip && exportPath.startsWith(strip)) {
99
- exportPath = exportPath.slice(strip.length);
100
- if (exportPath.startsWith('/')) {
101
- exportPath = exportPath.slice(1);
102
- }
103
- }
104
-
105
- // Strip /index suffix for cleaner exports (e.g., ./carousel instead of ./carousel/index)
106
- if (exportPath.endsWith('/index')) {
107
- exportPath = exportPath.slice(0, -6);
108
- }
109
-
110
- return `./${exportPath}`;
111
- }
112
-
113
- function generateExports(jsFiles: string[], distDir: string, strip: string): ExportsMap {
114
- const exports: ExportsMap = {};
115
-
116
- for (const jsFile of jsFiles.sort()) {
117
- const exportName = generateExportName(jsFile, strip);
118
- const dtsFile = jsFile.replace(/\.js$/, '.d.ts');
119
- const dtsPath = join(process.cwd(), distDir, dtsFile.replace(/^dist\//, ''));
120
-
121
- const entry: ExportEntry = {
122
- import: `./${distDir}/${jsFile}`.replace(/\/+/g, '/'),
123
- };
124
-
125
- if (existsSync(dtsPath) || existsSync(join(process.cwd(), distDir, dtsFile))) {
126
- entry.types = `./${distDir}/${dtsFile}`.replace(/\/+/g, '/');
127
- }
128
-
129
- exports[exportName] = entry;
130
- }
131
-
132
- return exports;
133
- }
134
-
135
- function main() {
136
- const args = process.argv.slice(2);
137
- const options = parseArgs(args);
138
-
139
- const packageJsonPath = join(process.cwd(), 'package.json');
140
- if (!existsSync(packageJsonPath)) {
141
- console.error('No package.json found in current directory');
142
- process.exit(1);
143
- }
144
-
145
- const distPath = join(process.cwd(), options.dist);
146
- if (!existsSync(distPath)) {
147
- console.error(`Dist directory not found: ${options.dist}`);
148
- console.error('Run build first before generating exports.');
149
- process.exit(1);
150
- }
151
-
152
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')) as PackageJson;
153
- const existingExports = packageJson.exports || {};
154
-
155
- const preservedExports: ExportsMap = {};
156
- for (const preservePath of options.preserve) {
157
- const existing = existingExports[preservePath];
158
- if (existing !== undefined) {
159
- preservedExports[preservePath] = existing;
160
- }
161
- }
162
-
163
- const jsFiles = findJsFiles(distPath, distPath);
164
- const generatedExports = generateExports(jsFiles, options.dist, options.strip);
165
-
166
- const newExports: ExportsMap = {
167
- ...preservedExports,
168
- ...generatedExports,
169
- };
170
-
171
- const sortedExports: ExportsMap = {};
172
- for (const key of Object.keys(newExports).sort()) {
173
- const value = newExports[key];
174
- if (value !== undefined) {
175
- sortedExports[key] = value;
176
- }
177
- }
178
-
179
- packageJson.exports = sortedExports;
180
-
181
- writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
182
-
183
- console.log(`✅ Generated ${Object.keys(generatedExports).length} exports in package.json`);
184
- if (options.preserve.length > 0) {
185
- console.log(` Preserved ${Object.keys(preservedExports).length} existing exports`);
186
- }
187
- }
188
-
189
- main();