@regardio/dev 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +416 -0
  3. package/dist/bin/exec-clean.d.ts +3 -0
  4. package/dist/bin/exec-clean.d.ts.map +1 -0
  5. package/dist/bin/exec-clean.js +18 -0
  6. package/dist/bin/exec-husky.d.ts +3 -0
  7. package/dist/bin/exec-husky.d.ts.map +1 -0
  8. package/dist/bin/exec-husky.js +8 -0
  9. package/dist/bin/exec-p.d.ts +3 -0
  10. package/dist/bin/exec-p.d.ts.map +1 -0
  11. package/dist/bin/exec-p.js +8 -0
  12. package/dist/bin/exec-s.d.ts +3 -0
  13. package/dist/bin/exec-s.d.ts.map +1 -0
  14. package/dist/bin/exec-s.js +8 -0
  15. package/dist/bin/exec-ts.d.ts +3 -0
  16. package/dist/bin/exec-ts.d.ts.map +1 -0
  17. package/dist/bin/exec-ts.js +28 -0
  18. package/dist/bin/exec-tsc.d.ts +3 -0
  19. package/dist/bin/exec-tsc.d.ts.map +1 -0
  20. package/dist/bin/exec-tsc.js +8 -0
  21. package/dist/bin/flow-branch.d.ts +3 -0
  22. package/dist/bin/flow-branch.d.ts.map +1 -0
  23. package/dist/bin/flow-branch.js +27 -0
  24. package/dist/bin/flow-version.d.ts +3 -0
  25. package/dist/bin/flow-version.d.ts.map +1 -0
  26. package/dist/bin/flow-version.js +83 -0
  27. package/dist/bin/lint-biome.d.ts +3 -0
  28. package/dist/bin/lint-biome.d.ts.map +1 -0
  29. package/dist/bin/lint-biome.js +8 -0
  30. package/dist/bin/lint-commit.d.ts +3 -0
  31. package/dist/bin/lint-commit.d.ts.map +1 -0
  32. package/dist/bin/lint-commit.js +8 -0
  33. package/dist/bin/lint-md.d.ts +3 -0
  34. package/dist/bin/lint-md.d.ts.map +1 -0
  35. package/dist/bin/lint-md.js +10 -0
  36. package/dist/config.test.d.ts +2 -0
  37. package/dist/config.test.d.ts.map +1 -0
  38. package/dist/config.test.js +101 -0
  39. package/dist/playwright/index.d.ts +10 -0
  40. package/dist/playwright/index.d.ts.map +1 -0
  41. package/dist/playwright/index.js +42 -0
  42. package/dist/playwright/index.test.d.ts +2 -0
  43. package/dist/playwright/index.test.d.ts.map +1 -0
  44. package/dist/playwright/index.test.js +55 -0
  45. package/dist/testing/setup-react.d.ts +2 -0
  46. package/dist/testing/setup-react.d.ts.map +1 -0
  47. package/dist/testing/setup-react.js +1 -0
  48. package/dist/vitest/node.d.ts +3 -0
  49. package/dist/vitest/node.d.ts.map +1 -0
  50. package/dist/vitest/node.js +6 -0
  51. package/dist/vitest/react.d.ts +3 -0
  52. package/dist/vitest/react.d.ts.map +1 -0
  53. package/dist/vitest/react.js +7 -0
  54. package/package.json +104 -0
  55. package/src/bin/exec-clean.ts +24 -0
  56. package/src/bin/exec-husky.ts +13 -0
  57. package/src/bin/exec-p.ts +13 -0
  58. package/src/bin/exec-s.ts +13 -0
  59. package/src/bin/exec-ts.ts +39 -0
  60. package/src/bin/exec-tsc.ts +13 -0
  61. package/src/bin/lint-biome.ts +13 -0
  62. package/src/bin/lint-commit.ts +13 -0
  63. package/src/bin/lint-md.ts +16 -0
  64. package/src/biome/preset.json +297 -0
  65. package/src/commitlint/commitlint.cjs +26 -0
  66. package/src/config.test.ts +129 -0
  67. package/src/markdownlint/markdownlint.json +9 -0
  68. package/src/playwright/index.test.ts +73 -0
  69. package/src/playwright/index.ts +63 -0
  70. package/src/testing/setup-react.ts +8 -0
  71. package/src/typescript/base.json +50 -0
  72. package/src/typescript/build.json +19 -0
  73. package/src/typescript/react.json +8 -0
  74. package/src/vitest/node.ts +12 -0
  75. package/src/vitest/react.ts +15 -0
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from 'node:child_process';
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ function fail(message) {
6
+ console.error(message);
7
+ process.exit(1);
8
+ }
9
+ function run(cmd, args, options = {}) {
10
+ const result = spawnSync(cmd, args, { stdio: 'inherit', ...options });
11
+ if (result.status !== 0) {
12
+ fail(`Command failed: ${cmd} ${args.join(' ')}`);
13
+ }
14
+ }
15
+ const type = process.argv[2];
16
+ if (!type || !['patch', 'minor', 'major'].includes(type)) {
17
+ fail('Usage: flow-version <patch|minor|major>');
18
+ }
19
+ const pkgPath = path.resolve(process.cwd(), 'package.json');
20
+ if (!fs.existsSync(pkgPath)) {
21
+ fail('Error: package.json not found in current directory');
22
+ }
23
+ const pkgRaw = fs.readFileSync(pkgPath, 'utf8');
24
+ let pkg;
25
+ try {
26
+ pkg = JSON.parse(pkgRaw);
27
+ }
28
+ catch (_e) {
29
+ fail('Error: Failed to parse package.json');
30
+ }
31
+ const current = pkg.version || '0.0.0';
32
+ console.log(`Current version: ${current}`);
33
+ const [majorStr, minorStr, patchStr] = String(current).split('.');
34
+ let major = Number(majorStr);
35
+ let minor = Number(minorStr);
36
+ let patch = Number(patchStr);
37
+ switch (type) {
38
+ case 'major':
39
+ major += 1;
40
+ minor = 0;
41
+ patch = 0;
42
+ break;
43
+ case 'minor':
44
+ minor += 1;
45
+ patch = 0;
46
+ break;
47
+ case 'patch':
48
+ patch += 1;
49
+ break;
50
+ }
51
+ const newVersion = `${major}.${minor}.${patch}`;
52
+ console.log(`New version: ${newVersion}`);
53
+ pkg.version = newVersion;
54
+ fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`, 'utf8');
55
+ run('pnpm', ['lint']);
56
+ const isMajor = type === 'major';
57
+ const isPatch = type === 'patch';
58
+ const conventionalType = isPatch ? 'fix' : 'feat';
59
+ const scope = 'release';
60
+ const subject = `v${newVersion}`;
61
+ const breakingBang = isMajor ? '!' : '';
62
+ const commitMessage = `${conventionalType}(${scope})${breakingBang}: ${subject}` +
63
+ (isMajor ? `\n\nBREAKING CHANGE: ${subject}` : '');
64
+ const branchRes = spawnSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
65
+ encoding: 'utf8',
66
+ });
67
+ if (branchRes.status !== 0)
68
+ fail('Error: Not a git repository or git not available');
69
+ const currentBranch = branchRes.stdout.trim();
70
+ if (currentBranch !== 'develop') {
71
+ fail(`Error: You must run releases from 'develop' (current: ${currentBranch})`);
72
+ }
73
+ run('git', ['add', 'package.json']);
74
+ run('git', ['commit', '-m', commitMessage]);
75
+ run('git', ['checkout', 'main']);
76
+ run('git', ['merge', 'develop', '--no-ff', '-m', commitMessage]);
77
+ run('git', ['tag', '-a', `v${newVersion}`, '-m', commitMessage]);
78
+ run('git', ['push', 'origin', 'main']);
79
+ run('git', ['push', 'origin', '--tags']);
80
+ run('git', ['checkout', 'develop']);
81
+ run('git', ['merge', 'main', '--ff-only']);
82
+ run('git', ['push', 'origin', 'develop']);
83
+ console.log(`Released version ${newVersion} successfully!`);
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=lint-biome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint-biome.d.ts","sourceRoot":"","sources":["../../src/bin/lint-biome.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from 'node:child_process';
3
+ import { createRequire } from 'node:module';
4
+ const require = createRequire(import.meta.url);
5
+ const bin = require.resolve('@biomejs/biome/bin/biome');
6
+ const args = process.argv.slice(2);
7
+ const child = spawn(process.execPath, [bin, ...args], { stdio: 'inherit' });
8
+ child.on('exit', (code) => process.exit(code ?? 0));
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=lint-commit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint-commit.d.ts","sourceRoot":"","sources":["../../src/bin/lint-commit.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from 'node:child_process';
3
+ import { createRequire } from 'node:module';
4
+ const require = createRequire(import.meta.url);
5
+ const bin = require.resolve('@commitlint/cli/cli.js');
6
+ const args = process.argv.slice(2);
7
+ const child = spawn(process.execPath, [bin, ...args], { stdio: 'inherit' });
8
+ child.on('exit', (code) => process.exit(code ?? 0));
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=lint-md.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lint-md.d.ts","sourceRoot":"","sources":["../../src/bin/lint-md.ts"],"names":[],"mappings":""}
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ import { spawn } from 'node:child_process';
3
+ import { createRequire } from 'node:module';
4
+ import { dirname, join } from 'node:path';
5
+ const require = createRequire(import.meta.url);
6
+ const packageDir = dirname(require.resolve('markdownlint-cli2'));
7
+ const bin = join(packageDir, 'markdownlint-cli2-bin.mjs');
8
+ const args = process.argv.slice(2);
9
+ const child = spawn(process.execPath, [bin, ...args], { stdio: 'inherit' });
10
+ child.on('exit', (code) => process.exit(code ?? 0));
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../src/config.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,101 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { describe, expect, it } from 'vitest';
5
+ const srcDir = path.dirname(fileURLToPath(import.meta.url));
6
+ function readJson(filePath) {
7
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
8
+ }
9
+ describe('Config Structure Validation', () => {
10
+ describe('biome/preset.json', () => {
11
+ const configPath = path.join(srcDir, 'biome/preset.json');
12
+ const config = readJson(configPath);
13
+ it('has $schema defined', () => {
14
+ expect(config.$schema).toContain('biomejs.dev');
15
+ });
16
+ it('has linter enabled', () => {
17
+ expect(config.linter?.enabled).toBe(true);
18
+ });
19
+ it('has formatter enabled', () => {
20
+ expect(config.formatter?.enabled).toBe(true);
21
+ });
22
+ it('has recommended rules enabled', () => {
23
+ expect(config.linter?.rules?.recommended).toBe(true);
24
+ });
25
+ it('disallows explicit any', () => {
26
+ expect(config.linter?.rules?.suspicious?.noExplicitAny).toBe('error');
27
+ });
28
+ });
29
+ describe('typescript/base.json', () => {
30
+ const configPath = path.join(srcDir, 'typescript/base.json');
31
+ const config = readJson(configPath);
32
+ it('has $schema defined', () => {
33
+ expect(config.$schema).toContain('schemastore.org');
34
+ });
35
+ it('has strict mode enabled', () => {
36
+ expect(config.compilerOptions?.strict).toBe(true);
37
+ });
38
+ it('has noUncheckedIndexedAccess enabled', () => {
39
+ expect(config.compilerOptions?.noUncheckedIndexedAccess).toBe(true);
40
+ });
41
+ it('has strictNullChecks enabled', () => {
42
+ expect(config.compilerOptions?.strictNullChecks).toBe(true);
43
+ });
44
+ it('has noImplicitAny enabled', () => {
45
+ expect(config.compilerOptions?.noImplicitAny).toBe(true);
46
+ });
47
+ it('targets ES2022', () => {
48
+ expect(config.compilerOptions?.target).toBe('ES2022');
49
+ });
50
+ it('uses ESNext module', () => {
51
+ expect(config.compilerOptions?.module).toBe('ESNext');
52
+ });
53
+ });
54
+ describe('typescript/react.json', () => {
55
+ const configPath = path.join(srcDir, 'typescript/react.json');
56
+ const config = readJson(configPath);
57
+ it('extends base.json', () => {
58
+ expect(config.extends).toContain('./base.json');
59
+ });
60
+ it('has jsx set to react-jsx', () => {
61
+ expect(config.compilerOptions?.jsx).toBe('react-jsx');
62
+ });
63
+ });
64
+ describe('markdownlint/markdownlint.json', () => {
65
+ const configPath = path.join(srcDir, 'markdownlint/markdownlint.json');
66
+ const config = readJson(configPath);
67
+ it('is a valid JSON object', () => {
68
+ expect(typeof config).toBe('object');
69
+ expect(config).not.toBeNull();
70
+ });
71
+ it('has MD013 (line-length) rule configured', () => {
72
+ expect(config.MD013).toBeDefined();
73
+ });
74
+ });
75
+ describe('commitlint/commitlint.cjs', () => {
76
+ const configPath = path.join(srcDir, 'commitlint/commitlint.cjs');
77
+ it('file exists', () => {
78
+ expect(fs.existsSync(configPath)).toBe(true);
79
+ });
80
+ it('exports extends with conventional config', () => {
81
+ const content = fs.readFileSync(configPath, 'utf8');
82
+ expect(content).toContain('@commitlint/config-conventional');
83
+ });
84
+ });
85
+ });
86
+ describe('Vitest Configs', () => {
87
+ describe('vitest/node', () => {
88
+ it('exports vitestNodeConfig', async () => {
89
+ const { vitestNodeConfig } = await import('./vitest/node.js');
90
+ expect(vitestNodeConfig).toBeDefined();
91
+ expect(vitestNodeConfig.environment).toBe('node');
92
+ });
93
+ });
94
+ describe('vitest/react', () => {
95
+ it('exports vitestReactConfig', async () => {
96
+ const { vitestReactConfig } = await import('./vitest/react.js');
97
+ expect(vitestReactConfig).toBeDefined();
98
+ expect(vitestReactConfig.environment).toBe('jsdom');
99
+ });
100
+ });
101
+ });
@@ -0,0 +1,10 @@
1
+ import type { PlaywrightTestConfig } from '@playwright/test';
2
+ export interface BuildPlaywrightBaseConfigParams {
3
+ appUrl: string;
4
+ appPort: number;
5
+ devices: typeof import('@playwright/test').devices;
6
+ ci?: boolean;
7
+ webServerCommand: string;
8
+ }
9
+ export declare function buildPlaywrightBaseConfig({ appUrl, appPort, devices, ci, webServerCommand, }: BuildPlaywrightBaseConfigParams): PlaywrightTestConfig;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/playwright/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,cAAc,kBAAkB,EAAE,OAAO,CAAC;IACnD,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAMD,wBAAgB,yBAAyB,CAAC,EACxC,MAAM,EACN,OAAO,EACP,OAAO,EACP,EAAqB,EACrB,gBAAgB,GACjB,EAAE,+BAA+B,GAAG,oBAAoB,CA0CxD"}
@@ -0,0 +1,42 @@
1
+ export function buildPlaywrightBaseConfig({ appUrl, appPort, devices, ci = !!process.env.CI, webServerCommand, }) {
2
+ if (!appUrl || typeof appUrl !== 'string') {
3
+ throw new Error('[playwright] appUrl must be a non-empty string');
4
+ }
5
+ if (!appPort || typeof appPort !== 'number') {
6
+ throw new Error('[playwright] appPort must be a number');
7
+ }
8
+ if (!devices) {
9
+ throw new Error('[playwright] devices must be provided from "@playwright/test"');
10
+ }
11
+ return {
12
+ forbidOnly: ci,
13
+ fullyParallel: true,
14
+ outputDir: './tests/test-results',
15
+ projects: [
16
+ { name: 'chromium', use: { ...devices['Desktop Chrome'] } },
17
+ { name: 'firefox', use: { ...devices['Desktop Firefox'] } },
18
+ { name: 'webkit', use: { ...devices['Desktop Safari'] } },
19
+ {
20
+ name: 'iPad Pro 11 landscape',
21
+ use: { ...devices['iPad Pro 11 landscape'] },
22
+ },
23
+ { name: 'iPhone 14 portrait', use: { ...devices['iPhone 14'] } },
24
+ { name: 'Pixel 7 portrait', use: { ...devices['Pixel 7'] } },
25
+ ],
26
+ reporter: [['html', { open: 'never', outputFolder: './tests/playwright-report' }]],
27
+ retries: ci ? 2 : 0,
28
+ testDir: './tests',
29
+ testMatch: '**/*.e2e.ts',
30
+ use: {
31
+ baseURL: appUrl,
32
+ trace: 'on-first-retry',
33
+ },
34
+ webServer: {
35
+ command: webServerCommand,
36
+ ignoreHTTPSErrors: true,
37
+ reuseExistingServer: !ci,
38
+ url: appUrl,
39
+ },
40
+ ...(ci ? { workers: 1 } : {}),
41
+ };
42
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/playwright/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ import { devices } from '@playwright/test';
2
+ import { describe, expect, it } from 'vitest';
3
+ import { buildPlaywrightBaseConfig } from './index.js';
4
+ describe('buildPlaywrightBaseConfig', () => {
5
+ const validParams = {
6
+ appPort: 3000,
7
+ appUrl: 'http://localhost:3000',
8
+ devices,
9
+ webServerCommand: 'pnpm dev',
10
+ };
11
+ describe('validation', () => {
12
+ it('throws if appUrl is missing', () => {
13
+ expect(() => buildPlaywrightBaseConfig({ ...validParams, appUrl: '' })).toThrow('[playwright] appUrl must be a non-empty string');
14
+ });
15
+ it('throws if appPort is not a number', () => {
16
+ expect(() => buildPlaywrightBaseConfig({ ...validParams, appPort: '3000' })).toThrow('[playwright] appPort must be a number');
17
+ });
18
+ it('throws if devices is missing', () => {
19
+ expect(() => buildPlaywrightBaseConfig({
20
+ ...validParams,
21
+ devices: undefined,
22
+ })).toThrow('[playwright] devices must be provided');
23
+ });
24
+ });
25
+ describe('config output', () => {
26
+ it('returns valid Playwright config structure', () => {
27
+ const config = buildPlaywrightBaseConfig(validParams);
28
+ expect(config).toHaveProperty('projects');
29
+ expect(config).toHaveProperty('testDir', './tests');
30
+ expect(config).toHaveProperty('testMatch', '**/*.e2e.ts');
31
+ expect(config).toHaveProperty('webServer');
32
+ expect(config).toHaveProperty('use.baseURL', 'http://localhost:3000');
33
+ });
34
+ it('configures 6 browser projects', () => {
35
+ const config = buildPlaywrightBaseConfig(validParams);
36
+ expect(config.projects).toHaveLength(6);
37
+ });
38
+ it('sets retries to 0 when not in CI', () => {
39
+ const config = buildPlaywrightBaseConfig({ ...validParams, ci: false });
40
+ expect(config.retries).toBe(0);
41
+ });
42
+ it('sets retries to 2 in CI', () => {
43
+ const config = buildPlaywrightBaseConfig({ ...validParams, ci: true });
44
+ expect(config.retries).toBe(2);
45
+ });
46
+ it('sets workers to 1 in CI', () => {
47
+ const config = buildPlaywrightBaseConfig({ ...validParams, ci: true });
48
+ expect(config.workers).toBe(1);
49
+ });
50
+ it('sets forbidOnly to true in CI', () => {
51
+ const config = buildPlaywrightBaseConfig({ ...validParams, ci: true });
52
+ expect(config.forbidOnly).toBe(true);
53
+ });
54
+ });
55
+ });
@@ -0,0 +1,2 @@
1
+ import '@testing-library/jest-dom/vitest';
2
+ //# sourceMappingURL=setup-react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-react.d.ts","sourceRoot":"","sources":["../../src/testing/setup-react.ts"],"names":[],"mappings":"AAOA,OAAO,kCAAkC,CAAC"}
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom/vitest';
@@ -0,0 +1,3 @@
1
+ import type { TestUserConfig } from 'vitest/node';
2
+ export declare const vitestNodeConfig: TestUserConfig;
3
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/vitest/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAMlD,eAAO,MAAM,gBAAgB,EAAE,cAK9B,CAAC"}
@@ -0,0 +1,6 @@
1
+ export const vitestNodeConfig = {
2
+ environment: 'node',
3
+ exclude: ['node_modules', 'dist', 'build', '.turbo', '.react-router'],
4
+ globals: true,
5
+ include: ['**/*.test.ts', '**/*.test.tsx'],
6
+ };
@@ -0,0 +1,3 @@
1
+ import type { TestUserConfig } from 'vitest/node';
2
+ export declare const vitestReactConfig: TestUserConfig;
3
+ //# sourceMappingURL=react.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/vitest/react.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAQlD,eAAO,MAAM,iBAAiB,EAAE,cAM/B,CAAC"}
@@ -0,0 +1,7 @@
1
+ export const vitestReactConfig = {
2
+ environment: 'jsdom',
3
+ exclude: ['node_modules', 'dist', 'build', '.turbo', '.react-router'],
4
+ globals: true,
5
+ include: ['**/*.test.ts', '**/*.test.tsx'],
6
+ setupFiles: ['./src/test-setup.ts'],
7
+ };
package/package.json ADDED
@@ -0,0 +1,104 @@
1
+ {
2
+ "$schema": "https://www.schemastore.org/package.json",
3
+ "author": "Bernd Matzner <bernd.matzner@regard.io>",
4
+ "bin": {
5
+ "exec-clean": "./dist/bin/exec-clean.js",
6
+ "exec-husky": "./dist/bin/exec-husky.js",
7
+ "exec-p": "./dist/bin/exec-p.js",
8
+ "exec-s": "./dist/bin/exec-s.js",
9
+ "exec-ts": "./dist/bin/exec-ts.js",
10
+ "exec-tsc": "./dist/bin/exec-tsc.js",
11
+ "lint-biome": "./dist/bin/lint-biome.js",
12
+ "lint-commit": "./dist/bin/lint-commit.js",
13
+ "lint-md": "./dist/bin/lint-md.js"
14
+ },
15
+ "bugs": {
16
+ "url": "https://github.com/regardio/dev/issues"
17
+ },
18
+ "description": "Regardio developer tooling for testing, linting, and build workflows",
19
+ "devDependencies": {
20
+ "@biomejs/biome": "2.3.10",
21
+ "@changesets/changelog-github": "0.5.2",
22
+ "@changesets/cli": "2.29.8",
23
+ "@commitlint/cli": "20.2.0",
24
+ "@commitlint/config-conventional": "20.2.0",
25
+ "@playwright/test": "1.57.0",
26
+ "@testing-library/jest-dom": "6.9.1",
27
+ "@testing-library/react": "16.3.1",
28
+ "@total-typescript/ts-reset": "0.6.1",
29
+ "@types/node": "25.0.3",
30
+ "@vitest/ui": "4.0.16",
31
+ "husky": "9.1.7",
32
+ "jsdom": "27.3.0",
33
+ "markdownlint-cli2": "0.20.0",
34
+ "npm-run-all": "4.1.5",
35
+ "rimraf": "6.1.2",
36
+ "tsx": "4.21.0",
37
+ "typescript": "5.9.3",
38
+ "vite": "7.3.0",
39
+ "vitest": "4.0.16"
40
+ },
41
+ "engines": {
42
+ "node": ">=18"
43
+ },
44
+ "exports": {
45
+ ".": {
46
+ "default": "./dist/index.js",
47
+ "types": "./dist/index.d.ts"
48
+ },
49
+ "./biome": "./src/biome/preset.json",
50
+ "./commitlint": "./src/commitlint/commitlint.cjs",
51
+ "./markdownlint": "./src/markdownlint/markdownlint.json",
52
+ "./playwright": {
53
+ "default": "./dist/playwright/index.js",
54
+ "types": "./dist/playwright/index.d.ts"
55
+ },
56
+ "./testing/setup-react": {
57
+ "default": "./dist/testing/setup-react.js",
58
+ "types": "./dist/testing/setup-react.d.ts"
59
+ },
60
+ "./typescript/base.json": "./src/typescript/base.json",
61
+ "./typescript/build.json": "./src/typescript/build.json",
62
+ "./typescript/react.json": "./src/typescript/react.json",
63
+ "./vitest/node": {
64
+ "default": "./dist/vitest/node.js",
65
+ "types": "./dist/vitest/node.d.ts"
66
+ },
67
+ "./vitest/react": {
68
+ "default": "./dist/vitest/react.js",
69
+ "types": "./dist/vitest/react.d.ts"
70
+ }
71
+ },
72
+ "files": ["dist", "src"],
73
+ "homepage": "https://github.com/regardio/dev/blob/main/README.md",
74
+ "keywords": ["dev", "tooling", "testing", "linting", "biome", "vitest", "playwright"],
75
+ "license": "MIT",
76
+ "name": "@regardio/dev",
77
+ "private": false,
78
+ "publishConfig": {
79
+ "access": "public"
80
+ },
81
+ "repository": {
82
+ "directory": "packages/dev",
83
+ "type": "git",
84
+ "url": "https://github.com/regardio/dev.git"
85
+ },
86
+ "scripts": {
87
+ "build": "pnpm exec tsc -p tsconfig.build.json",
88
+ "clean": "pnpm exec tsx src/bin/exec-clean.ts .turbo dist",
89
+ "fix": "exec-p fix:*",
90
+ "fix:biome": "biome check --write --unsafe .",
91
+ "fix:md": "markdownlint-cli2 --fix \"**/*.md\" \"**/*.mdx\" \"!**/node_modules/**\" \"!**/dist/**\"",
92
+ "lint": "run-p lint:*",
93
+ "lint:biome": "biome check .",
94
+ "lint:md": "markdownlint-cli2 \"**/*.md\" \"**/*.mdx\" \"!**/node_modules/**\" \"!**/dist/**\"",
95
+ "prepare": "pnpm run build && husky",
96
+ "release": "pnpm changeset publish",
97
+ "test": "run-p test:*",
98
+ "test:unit": "vitest run",
99
+ "version": "pnpm changeset version"
100
+ },
101
+ "sideEffects": false,
102
+ "type": "module",
103
+ "version": "0.9.0"
104
+ }
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * exec-clean: Thin wrapper around rimraf for cleaning paths.
4
+ * Usage: exec-clean <path> [morePaths...]
5
+ */
6
+ import { spawn } from 'node:child_process';
7
+ import { createRequire } from 'node:module';
8
+ import path from 'node:path';
9
+
10
+ const require = createRequire(import.meta.url);
11
+ const pkgPath = require.resolve('rimraf/package.json');
12
+ const pkg = require(pkgPath);
13
+ let binRel = typeof pkg.bin === 'string' ? pkg.bin : pkg.bin?.rimraf;
14
+ if (!binRel) {
15
+ console.error('Unable to locate rimraf binary from package.json bin field');
16
+ process.exit(1);
17
+ }
18
+ if (binRel.startsWith('./')) binRel = binRel.slice(2);
19
+ // Build an absolute path to the bin file relative to the resolved package root
20
+ const bin = path.join(path.dirname(pkgPath), binRel);
21
+
22
+ const args = process.argv.slice(2);
23
+ const child = spawn(process.execPath, [bin, ...args], { stdio: 'inherit' });
24
+ child.on('exit', (code) => process.exit(code ?? 0));
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * exec-husky: Initializes Husky git hooks (delegates to husky's bin).
4
+ * Usage: exec-husky
5
+ */
6
+ import { spawn } from 'node:child_process';
7
+ import { createRequire } from 'node:module';
8
+
9
+ const require = createRequire(import.meta.url);
10
+ const bin = require.resolve('husky');
11
+ const args = process.argv.slice(2);
12
+ const child = spawn(process.execPath, [bin, ...args], { stdio: 'inherit' });
13
+ child.on('exit', (code) => process.exit(code ?? 0));
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * exec-p: Run npm scripts in parallel via npm-run-all's run-p.
4
+ * Usage: exec-p <script-patterns>
5
+ */
6
+ import { spawn } from 'node:child_process';
7
+ import { createRequire } from 'node:module';
8
+
9
+ const require = createRequire(import.meta.url);
10
+ const bin = require.resolve('npm-run-all/bin/run-p/index.js');
11
+ const args = process.argv.slice(2);
12
+ const child = spawn(process.execPath, [bin, ...args], { stdio: 'inherit' });
13
+ child.on('exit', (code) => process.exit(code ?? 0));
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * exec-s: Run npm scripts sequentially via npm-run-all's run-s.
4
+ * Usage: exec-s <script-patterns>
5
+ */
6
+ import { spawn } from 'node:child_process';
7
+ import { createRequire } from 'node:module';
8
+
9
+ const require = createRequire(import.meta.url);
10
+ const bin = require.resolve('npm-run-all/bin/run-s/index.js');
11
+ const args = process.argv.slice(2);
12
+ const child = spawn(process.execPath, [bin, ...args], { stdio: 'inherit' });
13
+ child.on('exit', (code) => process.exit(code ?? 0));
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * exec-ts: Run a local TypeScript file via tsx with TS support.
4
+ * Usage: exec-ts path/to/script.ts [args...]
5
+ */
6
+ import { type SpawnOptions, spawn } from 'node:child_process';
7
+ import { createRequire } from 'node:module';
8
+ import path from 'node:path';
9
+
10
+ const args = process.argv.slice(2);
11
+ if (args.length === 0) {
12
+ console.error('Usage: exec-ts <script.ts> [args...]');
13
+ process.exit(1);
14
+ }
15
+
16
+ const [scriptArg, ...rest] = args;
17
+ const script = scriptArg ?? '';
18
+
19
+ // Delegate to tsx to run a local TypeScript file with full TypeScript support
20
+ const require = createRequire(import.meta.url);
21
+ const pkgPath = require.resolve('tsx/package.json');
22
+ const pkg = require(pkgPath);
23
+ const binRel = pkg.bin;
24
+ const binPath: string | undefined =
25
+ typeof binRel === 'string'
26
+ ? binRel
27
+ : typeof binRel === 'object' && binRel !== null && 'tsx' in binRel
28
+ ? (binRel as Record<string, string>).tsx
29
+ : undefined;
30
+
31
+ if (!binPath) {
32
+ console.error('Unable to locate tsx binary from package.json bin field');
33
+ process.exit(1);
34
+ }
35
+ // Build an absolute path to the bin file relative to the resolved package root
36
+ const bin = path.join(path.dirname(pkgPath), binPath);
37
+ const spawnOptions: SpawnOptions = { stdio: 'inherit' };
38
+ const child = spawn(process.execPath, [bin, script, ...rest], spawnOptions);
39
+ child.on('exit', (code: number | null) => process.exit(code ?? 0));
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * exec-tsc: Run the TypeScript compiler (tsc) via local dependency.
4
+ * Usage: exec-tsc [tsc args...]
5
+ */
6
+ import { spawn } from 'node:child_process';
7
+ import { createRequire } from 'node:module';
8
+
9
+ const require = createRequire(import.meta.url);
10
+ const bin = require.resolve('typescript/bin/tsc');
11
+ const args = process.argv.slice(2);
12
+ const child = spawn(process.execPath, [bin, ...args], { stdio: 'inherit' });
13
+ child.on('exit', (code) => process.exit(code ?? 0));