@stack-dev/cli 0.1.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/.turbo/daemon/6fa76abe2aa470d0-turbo.log.2025-08-02 +5 -0
- package/.turbo/daemon/6fa76abe2aa470d0-turbo.log.2025-12-29 +1 -0
- package/.turbo/daemon/6fa76abe2aa470d0-turbo.log.2025-12-30 +0 -0
- package/.turbo/turbo-build.log +21 -0
- package/.turbo/turbo-check-types.log +5 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2097 -0
- package/dist/index.mjs +2073 -0
- package/eslint.config.mjs +3 -0
- package/package.json +35 -0
- package/prettier.config.mjs +3 -0
- package/src/file-generator/file-generator-imp.ts +20 -0
- package/src/file-generator/file-generator.ts +5 -0
- package/src/file-generator/index.ts +3 -0
- package/src/file-generator/package-json-generator.ts +23 -0
- package/src/index.ts +185 -0
- package/src/link-packages.ts +65 -0
- package/src/package-json/dependency.ts +28 -0
- package/src/package-json/index.ts +3 -0
- package/src/package-json/package-json.ts +269 -0
- package/src/packages/create-config-package.ts +29 -0
- package/src/packages/index.ts +4 -0
- package/src/packages/library-package/create-library-package.ts +85 -0
- package/src/packages/library-package/files/add-file-generator.ts +8 -0
- package/src/packages/library-package/files/add-spec-file-generator.ts +17 -0
- package/src/packages/library-package/files/eslint-config-file-generator.ts +11 -0
- package/src/packages/library-package/files/index-file-generator.ts +9 -0
- package/src/packages/library-package/files/prettier-config-file-generator.ts +11 -0
- package/src/packages/library-package/files/tsconfig-file-generator.ts +15 -0
- package/src/packages/library-package/files/tsup-config-file-generator.ts +23 -0
- package/src/packages/library-package/files/vitest-config-file-generator.ts +19 -0
- package/src/packages/library-package/index.ts +1 -0
- package/src/packages/react-package/create-react-package.ts +25 -0
- package/src/packages/react-package/create-tailwind-react-package.ts +30 -0
- package/src/packages/react-package/create-unstyled-react-package.ts +3 -0
- package/src/packages/react-package/css-react-package/create-css-react-package.ts +103 -0
- package/src/packages/react-package/css-react-package/files/button-css-module-file-generator.ts +16 -0
- package/src/packages/react-package/css-react-package/files/button-file-generator.ts +14 -0
- package/src/packages/react-package/css-react-package/files/button-spec-file-generator.ts +33 -0
- package/src/packages/react-package/css-react-package/files/eslint-config-file-generator.ts +18 -0
- package/src/packages/react-package/css-react-package/files/index-file-generator.ts +9 -0
- package/src/packages/react-package/css-react-package/files/prettier-config-file-generator.ts +11 -0
- package/src/packages/react-package/css-react-package/files/tsconfig-file-generator.ts +15 -0
- package/src/packages/react-package/css-react-package/files/tsup-config-file-generator.ts +24 -0
- package/src/packages/react-package/css-react-package/files/vitest-config-file-generator.ts +23 -0
- package/src/packages/react-package/index.ts +1 -0
- package/src/packages/react-package/styled-components-react-package/create-styled-components-react-package.ts +112 -0
- package/src/packages/react-package/styled-components-react-package/files/button-file-generator.ts +30 -0
- package/src/packages/react-package/styled-components-react-package/files/button-spec-file-generator.ts +33 -0
- package/src/packages/react-package/styled-components-react-package/files/eslint-config-file-generator.ts +18 -0
- package/src/packages/react-package/styled-components-react-package/files/index-file-generator.ts +9 -0
- package/src/packages/react-package/styled-components-react-package/files/prettier-config-file-generator.ts +11 -0
- package/src/packages/react-package/styled-components-react-package/files/tsconfig-file-generator.ts +15 -0
- package/src/packages/react-package/styled-components-react-package/files/tsup-config-file-generator.ts +21 -0
- package/src/packages/react-package/styled-components-react-package/files/vitest-config-file-generator.ts +23 -0
- package/src/packages/vite-react-app/create-vite-react-app.ts +79 -0
- package/src/packages/vite-react-app/files/app-file-generator.ts +28 -0
- package/src/packages/vite-react-app/files/eslint-config-file-generator.ts +11 -0
- package/src/packages/vite-react-app/files/index-html-file-generator.ts +20 -0
- package/src/packages/vite-react-app/files/main-file-generator.ts +14 -0
- package/src/packages/vite-react-app/files/prettier-config-file-generator.ts +11 -0
- package/src/packages/vite-react-app/files/tsconfig-file-generator.ts +15 -0
- package/src/packages/vite-react-app/files/vite-config-file-generator.ts +17 -0
- package/src/packages/vite-react-app/files/vitest-config-file-generator.ts +19 -0
- package/src/tsconfig/compiler-options.ts +83 -0
- package/src/tsconfig/index.ts +4 -0
- package/src/tsconfig/reference.ts +21 -0
- package/src/tsconfig/tsconfig.ts +137 -0
- package/src/unlink-packages.ts +47 -0
- package/src/utils/package-generator.ts +41 -0
- package/src/utils/package-type.ts +44 -0
- package/src/utils/package.ts +126 -0
- package/src/utils/style-type.ts +41 -0
- package/src/utils/utils.ts +28 -0
- package/src/utils/workspace.ts +78 -0
- package/src/workspace/create-workspace.ts +39 -0
- package/src/workspace/index.ts +1 -0
- package/src/workspace/root-package.ts +195 -0
- package/src/workspace/typescript-config.ts +84 -0
- package/tsconfig.json +14 -0
- package/tsup.config.ts +16 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { getNamespace, getWorkspaceRoot } from '../../utils/workspace';
|
|
2
|
+
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { PackageJsonGenerator } from '../../file-generator';
|
|
5
|
+
import { Dependency, PackageJSON } from '../../package-json';
|
|
6
|
+
import { PackageGenerator } from '../../utils/package-generator';
|
|
7
|
+
import { ADD_FILE_GENERATOR } from './files/add-file-generator';
|
|
8
|
+
import { ADD_SPEC_FILE_GENERATOR } from './files/add-spec-file-generator';
|
|
9
|
+
import { ESLINT_CONFIG_FILE_GENERATOR } from './files/eslint-config-file-generator';
|
|
10
|
+
import { INDEX_FILE_GENERATOR } from './files/index-file-generator';
|
|
11
|
+
import { PRETTIER_CONFIG_FILE_GENERATOR } from './files/prettier-config-file-generator';
|
|
12
|
+
import { TSCONFIG_FILE_GENERATOR } from './files/tsconfig-file-generator';
|
|
13
|
+
import { TSUP_CONFIG_FILE_GENERATOR } from './files/tsup-config-file-generator';
|
|
14
|
+
import { VITEST_CONFIG_FILE_GENERATOR } from './files/vitest-config-file-generator';
|
|
15
|
+
|
|
16
|
+
export async function createLibraryPackage(name: string): Promise<void> {
|
|
17
|
+
const rootDir = await getWorkspaceRoot();
|
|
18
|
+
const directory = path.join(rootDir, 'packages', name);
|
|
19
|
+
|
|
20
|
+
const namespace = await getNamespace(rootDir);
|
|
21
|
+
const packageName = `${namespace}/${name}`;
|
|
22
|
+
|
|
23
|
+
console.log(`✨ Creating config package: ${packageName}`);
|
|
24
|
+
|
|
25
|
+
const generator = new PackageGenerator(
|
|
26
|
+
directory,
|
|
27
|
+
makePackageGenerator(packageName, namespace),
|
|
28
|
+
[
|
|
29
|
+
INDEX_FILE_GENERATOR,
|
|
30
|
+
ADD_FILE_GENERATOR,
|
|
31
|
+
ADD_SPEC_FILE_GENERATOR,
|
|
32
|
+
TSUP_CONFIG_FILE_GENERATOR,
|
|
33
|
+
TSCONFIG_FILE_GENERATOR,
|
|
34
|
+
PRETTIER_CONFIG_FILE_GENERATOR,
|
|
35
|
+
ESLINT_CONFIG_FILE_GENERATOR,
|
|
36
|
+
VITEST_CONFIG_FILE_GENERATOR,
|
|
37
|
+
],
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
await generator.generate();
|
|
41
|
+
|
|
42
|
+
console.log(`✅ Config package created at: ${directory}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function makePackageGenerator(packageName: string, namespace: string) {
|
|
46
|
+
const packageJsonModel = new PackageJSON({
|
|
47
|
+
name: packageName,
|
|
48
|
+
devDependencies: [
|
|
49
|
+
new Dependency(`${namespace}/eslint-config`, 'workspace:*'),
|
|
50
|
+
new Dependency(`${namespace}/prettier-config`, 'workspace:*'),
|
|
51
|
+
new Dependency(`${namespace}/typescript-config`, 'workspace:*'),
|
|
52
|
+
new Dependency('eslint', '^9.32.0'),
|
|
53
|
+
new Dependency('prettier', '^3.6.2'),
|
|
54
|
+
new Dependency('prettier-plugin-organize-imports', '^4.2.0'),
|
|
55
|
+
new Dependency('tsup', '^7.3.0'),
|
|
56
|
+
new Dependency('vitest', '^3.2.4'),
|
|
57
|
+
new Dependency('@vitest/coverage-v8', '^3.2.4'),
|
|
58
|
+
],
|
|
59
|
+
additionalData: {
|
|
60
|
+
version: '0.1.0',
|
|
61
|
+
private: true,
|
|
62
|
+
main: 'dist/index.js',
|
|
63
|
+
module: 'dist/index.mjs',
|
|
64
|
+
types: 'dist/index.d.ts',
|
|
65
|
+
exports: {
|
|
66
|
+
'.': {
|
|
67
|
+
development: './src/index.ts',
|
|
68
|
+
import: './dist/index.mjs',
|
|
69
|
+
require: './dist/index.js',
|
|
70
|
+
types: './dist/index.d.ts',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
scripts: {
|
|
74
|
+
build: 'tsup',
|
|
75
|
+
lint: 'eslint',
|
|
76
|
+
format: 'prettier . --write',
|
|
77
|
+
test: 'vitest run',
|
|
78
|
+
'test:watch': 'vitest',
|
|
79
|
+
},
|
|
80
|
+
sideEffects: false,
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
return new PackageJsonGenerator(packageJsonModel, namespace);
|
|
85
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FileGeneratorImp } from '../../../file-generator/file-generator-imp';
|
|
2
|
+
|
|
3
|
+
const ADD_SPEC_TS = `import { describe, it, expect } from 'vitest';
|
|
4
|
+
|
|
5
|
+
import { add } from '../add';
|
|
6
|
+
|
|
7
|
+
describe('add', () => {
|
|
8
|
+
it('adds two numbers', () => {
|
|
9
|
+
expect(add(2, 3)).toBe(5);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
export const ADD_SPEC_FILE_GENERATOR = new FileGeneratorImp(
|
|
15
|
+
'src/spec/add.spec.ts',
|
|
16
|
+
ADD_SPEC_TS,
|
|
17
|
+
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FileGeneratorImp } from '../../../file-generator/file-generator-imp';
|
|
2
|
+
|
|
3
|
+
const ESLINT_CONFIG = `import base from '@stack-dev/eslint-config/base.mjs';
|
|
4
|
+
|
|
5
|
+
export default [...base, { ignores: ['**/dist/**'] }];
|
|
6
|
+
`;
|
|
7
|
+
|
|
8
|
+
export const ESLINT_CONFIG_FILE_GENERATOR = new FileGeneratorImp(
|
|
9
|
+
'eslint.config.mjs',
|
|
10
|
+
ESLINT_CONFIG,
|
|
11
|
+
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FileGeneratorImp } from '../../../file-generator/file-generator-imp';
|
|
2
|
+
|
|
3
|
+
const PRETTIER_CONFIG = `import base from '@stack-dev/prettier-config/base.mjs';
|
|
4
|
+
|
|
5
|
+
export default base;
|
|
6
|
+
`;
|
|
7
|
+
|
|
8
|
+
export const PRETTIER_CONFIG_FILE_GENERATOR = new FileGeneratorImp(
|
|
9
|
+
'prettier.config.mjs',
|
|
10
|
+
PRETTIER_CONFIG,
|
|
11
|
+
);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FileGeneratorImp } from '../../../file-generator/file-generator-imp';
|
|
2
|
+
|
|
3
|
+
const TSCONFIG = `{
|
|
4
|
+
"extends": "@stack-dev/typescript-config/tsconfig.base.json",
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"outDir": "dist"
|
|
7
|
+
},
|
|
8
|
+
"include": ["src"]
|
|
9
|
+
}
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
export const TSCONFIG_FILE_GENERATOR = new FileGeneratorImp(
|
|
13
|
+
'tsconfig.json',
|
|
14
|
+
TSCONFIG,
|
|
15
|
+
);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FileGeneratorImp } from '../../../file-generator/file-generator-imp';
|
|
2
|
+
|
|
3
|
+
const TSUP_CONFIG = `import { defineConfig } from 'tsup';
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
entry: ['src/index.ts'],
|
|
7
|
+
format: ['esm', 'cjs'],
|
|
8
|
+
dts: true,
|
|
9
|
+
sourcemap: true,
|
|
10
|
+
clean: true,
|
|
11
|
+
target: 'esnext',
|
|
12
|
+
outExtension({ format }) {
|
|
13
|
+
return {
|
|
14
|
+
js: format === 'esm' ? '.mjs' : '.js',
|
|
15
|
+
};
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
export const TSUP_CONFIG_FILE_GENERATOR = new FileGeneratorImp(
|
|
21
|
+
'tsup.config.ts',
|
|
22
|
+
TSUP_CONFIG,
|
|
23
|
+
);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FileGeneratorImp } from '../../../file-generator/file-generator-imp';
|
|
2
|
+
|
|
3
|
+
const VITEST_CONFIG = `import { defineConfig } from 'vitest/config';
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
test: {
|
|
7
|
+
globals: true,
|
|
8
|
+
coverage: {
|
|
9
|
+
provider: 'v8',
|
|
10
|
+
},
|
|
11
|
+
environment: 'node',
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
`;
|
|
15
|
+
|
|
16
|
+
export const VITEST_CONFIG_FILE_GENERATOR = new FileGeneratorImp(
|
|
17
|
+
'vitest.config.ts',
|
|
18
|
+
VITEST_CONFIG,
|
|
19
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './create-library-package';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { StyleType } from '../../utils/style-type';
|
|
2
|
+
import { createTailwindReactPackage } from './create-tailwind-react-package';
|
|
3
|
+
import { createUnstyledReactPackage } from './create-unstyled-react-package';
|
|
4
|
+
import { createCssReactPackage } from './css-react-package/create-css-react-package';
|
|
5
|
+
import { createStyledComponentsReactPackage } from './styled-components-react-package/create-styled-components-react-package';
|
|
6
|
+
|
|
7
|
+
export async function createReactPackage(
|
|
8
|
+
name: string,
|
|
9
|
+
style: StyleType,
|
|
10
|
+
): Promise<void> {
|
|
11
|
+
switch (style) {
|
|
12
|
+
case 'tailwind':
|
|
13
|
+
await createTailwindReactPackage(name);
|
|
14
|
+
break;
|
|
15
|
+
case 'css-modules':
|
|
16
|
+
await createCssReactPackage(name);
|
|
17
|
+
break;
|
|
18
|
+
case 'styled-components':
|
|
19
|
+
await createStyledComponentsReactPackage(name);
|
|
20
|
+
break;
|
|
21
|
+
case 'none':
|
|
22
|
+
await createUnstyledReactPackage(name);
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { FileGeneratorImp } from "../../file-generator/file-generator-imp";
|
|
2
|
+
|
|
3
|
+
export async function createTailwindReactPackage(name: string): Promise<void> {
|
|
4
|
+
throw new Error('Not implemented.');
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const STYLED_BUTTON = `import React from 'react';
|
|
8
|
+
|
|
9
|
+
interface ButtonProps {
|
|
10
|
+
label: string;
|
|
11
|
+
onClick?: () => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function TailwindButton(props: ButtonProps) {
|
|
15
|
+
const {label, onClick} = props;
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<button
|
|
19
|
+
onClick={onClick}
|
|
20
|
+
className="my-lib-bg-blue-600 my-lib-text-white my-lib-p-[10px] my-lib-border-none my-lib-rounded my-lib-cursor-pointer hover:my-lib-brightness-110"
|
|
21
|
+
>
|
|
22
|
+
{label}
|
|
23
|
+
</button>
|
|
24
|
+
);
|
|
25
|
+
};`;
|
|
26
|
+
|
|
27
|
+
export const STYLED_BUTTON_FILE_GENERATOR = new FileGeneratorImp(
|
|
28
|
+
'styled-button.ts',
|
|
29
|
+
STYLED_BUTTON,
|
|
30
|
+
);
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { PackageJsonGenerator } from '../../../file-generator';
|
|
3
|
+
import { Dependency, PackageJSON } from '../../../package-json';
|
|
4
|
+
import { PackageGenerator } from '../../../utils/package-generator';
|
|
5
|
+
import { getNamespace, getWorkspaceRoot } from '../../../utils/workspace';
|
|
6
|
+
import { BUTTON_CSS_MODULE_FILE_GENERATOR } from './files/button-css-module-file-generator';
|
|
7
|
+
import { BUTTON_FILE_GENERATOR } from './files/button-file-generator';
|
|
8
|
+
import { BUTTON_SPEC_FILE_GENERATOR } from './files/button-spec-file-generator';
|
|
9
|
+
import { ESLINT_CONFIG_FILE_GENERATOR } from './files/eslint-config-file-generator';
|
|
10
|
+
import { INDEX_FILE_GENERATOR } from './files/index-file-generator';
|
|
11
|
+
import { PRETTIER_CONFIG_FILE_GENERATOR } from './files/prettier-config-file-generator';
|
|
12
|
+
import { TSCONFIG_FILE_GENERATOR } from './files/tsconfig-file-generator';
|
|
13
|
+
import { TSUP_CONFIG_FILE_GENERATOR } from './files/tsup-config-file-generator';
|
|
14
|
+
import { VITEST_CONFIG_FILE_GENERATOR } from './files/vitest-config-file-generator';
|
|
15
|
+
|
|
16
|
+
export async function createCssReactPackage(name: string): Promise<void> {
|
|
17
|
+
const rootDir = await getWorkspaceRoot();
|
|
18
|
+
const directory = path.join(rootDir, 'packages', name);
|
|
19
|
+
|
|
20
|
+
const namespace = await getNamespace(rootDir);
|
|
21
|
+
const packageName = `${namespace}/${name}`;
|
|
22
|
+
|
|
23
|
+
console.log(`✨ Creating CSS Modules React library: ${packageName}`);
|
|
24
|
+
|
|
25
|
+
const generator = new PackageGenerator(
|
|
26
|
+
directory,
|
|
27
|
+
makePackageGenerator(packageName, namespace),
|
|
28
|
+
[
|
|
29
|
+
INDEX_FILE_GENERATOR,
|
|
30
|
+
BUTTON_FILE_GENERATOR,
|
|
31
|
+
BUTTON_CSS_MODULE_FILE_GENERATOR,
|
|
32
|
+
BUTTON_SPEC_FILE_GENERATOR,
|
|
33
|
+
TSUP_CONFIG_FILE_GENERATOR,
|
|
34
|
+
TSCONFIG_FILE_GENERATOR,
|
|
35
|
+
PRETTIER_CONFIG_FILE_GENERATOR,
|
|
36
|
+
ESLINT_CONFIG_FILE_GENERATOR,
|
|
37
|
+
VITEST_CONFIG_FILE_GENERATOR,
|
|
38
|
+
],
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
await generator.generate();
|
|
42
|
+
|
|
43
|
+
console.log(`✅ Library created at: ${directory}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function makePackageGenerator(packageName: string, namespace: string) {
|
|
47
|
+
const packageJsonModel = new PackageJSON({
|
|
48
|
+
name: packageName,
|
|
49
|
+
peerDependencies: [
|
|
50
|
+
new Dependency('react', '>=18'),
|
|
51
|
+
new Dependency('react-dom', '>=18'),
|
|
52
|
+
],
|
|
53
|
+
devDependencies: [
|
|
54
|
+
new Dependency(`${namespace}/eslint-config`, 'workspace:*'),
|
|
55
|
+
new Dependency(`${namespace}/prettier-config`, 'workspace:*'),
|
|
56
|
+
new Dependency(`${namespace}/typescript-config`, 'workspace:*'),
|
|
57
|
+
// Development React binaries
|
|
58
|
+
new Dependency('react', '^18.3.1'),
|
|
59
|
+
new Dependency('react-dom', '^18.3.1'),
|
|
60
|
+
new Dependency('@types/react', '^18.3.1'),
|
|
61
|
+
new Dependency('@types/react-dom', '^18.3.1'),
|
|
62
|
+
// Linting & Formatting
|
|
63
|
+
new Dependency('eslint', '^9.32.0'),
|
|
64
|
+
new Dependency('prettier', '^3.6.2'),
|
|
65
|
+
new Dependency('prettier-plugin-organize-imports', '^4.2.0'),
|
|
66
|
+
// Build
|
|
67
|
+
new Dependency('tsup', '^8.0.0'),
|
|
68
|
+
new Dependency('postcss', '^8.4.0'),
|
|
69
|
+
// Testing
|
|
70
|
+
new Dependency('vitest', '^3.2.4'),
|
|
71
|
+
new Dependency('@vitest/coverage-v8', '^3.2.4'),
|
|
72
|
+
new Dependency('@testing-library/react', '^16.0.0'),
|
|
73
|
+
new Dependency('@testing-library/jest-dom', '^6.0.0'),
|
|
74
|
+
new Dependency('jsdom', '^25.0.0'),
|
|
75
|
+
],
|
|
76
|
+
additionalData: {
|
|
77
|
+
version: '0.1.0',
|
|
78
|
+
private: true,
|
|
79
|
+
main: 'dist/index.js',
|
|
80
|
+
module: 'dist/index.mjs',
|
|
81
|
+
types: 'dist/index.d.ts',
|
|
82
|
+
exports: {
|
|
83
|
+
'.': {
|
|
84
|
+
development: './src/index.ts',
|
|
85
|
+
import: './dist/index.mjs',
|
|
86
|
+
require: './dist/index.js',
|
|
87
|
+
types: './dist/index.d.ts',
|
|
88
|
+
},
|
|
89
|
+
'./index.css': './dist/index.css',
|
|
90
|
+
},
|
|
91
|
+
scripts: {
|
|
92
|
+
build: 'tsup',
|
|
93
|
+
lint: 'eslint .',
|
|
94
|
+
format: 'prettier . --write',
|
|
95
|
+
test: 'vitest run',
|
|
96
|
+
'test:watch': 'vitest',
|
|
97
|
+
},
|
|
98
|
+
sideEffects: ['**/*.css'],
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
return new PackageJsonGenerator(packageJsonModel, namespace);
|
|
103
|
+
}
|
package/src/packages/react-package/css-react-package/files/button-css-module-file-generator.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { FileGeneratorImp } from '../../../../file-generator/file-generator-imp';
|
|
2
|
+
|
|
3
|
+
const BUTTON_CSS_MODULE = `.styledButton {
|
|
4
|
+
background: blue;
|
|
5
|
+
color: white;
|
|
6
|
+
padding: 10px;
|
|
7
|
+
border: none;
|
|
8
|
+
border-radius: 4px;
|
|
9
|
+
cursor: pointer;
|
|
10
|
+
}
|
|
11
|
+
`;
|
|
12
|
+
|
|
13
|
+
export const BUTTON_CSS_MODULE_FILE_GENERATOR = new FileGeneratorImp(
|
|
14
|
+
'src/button.module.css',
|
|
15
|
+
BUTTON_CSS_MODULE,
|
|
16
|
+
);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { FileGeneratorImp } from '../../../../file-generator/file-generator-imp';
|
|
2
|
+
|
|
3
|
+
const BUTTON = `import React from 'react';
|
|
4
|
+
import * as styles from './button.module.css';
|
|
5
|
+
|
|
6
|
+
export function Button(props: HTMLAttributes<HTMLButtonElement>) {
|
|
7
|
+
return <button className={styles.styledButton} {...props} />;
|
|
8
|
+
}
|
|
9
|
+
`;
|
|
10
|
+
|
|
11
|
+
export const BUTTON_FILE_GENERATOR = new FileGeneratorImp(
|
|
12
|
+
'src/button.tsx',
|
|
13
|
+
BUTTON,
|
|
14
|
+
);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { FileGeneratorImp } from '../../../../file-generator/file-generator-imp';
|
|
2
|
+
|
|
3
|
+
const BUTTON_SPEC = `import { render, screen, fireEvent } from '@testing-library/react';
|
|
4
|
+
import { Button } from './button';
|
|
5
|
+
|
|
6
|
+
describe('Button', () => {
|
|
7
|
+
it('renders the label correctly', () => {
|
|
8
|
+
render(<Button>Click Me</Button>);
|
|
9
|
+
expect(screen.getByText('Click Me')).toBeDefined();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('is a button element', () => {
|
|
13
|
+
render(<Button>Submit</Button>);
|
|
14
|
+
const buttonElement = screen.getByRole('button');
|
|
15
|
+
expect(buttonElement.tagName).toBe('BUTTON');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
/* Note: Testing for specific CSS classes with CSS Modules is tricky
|
|
19
|
+
because class names are mangled (e.g., _styledButton_123).
|
|
20
|
+
Usually, we just test that the class attribute exists.
|
|
21
|
+
*/
|
|
22
|
+
it('applies a class name', () => {
|
|
23
|
+
render(<Button>Styled</Button>);
|
|
24
|
+
const buttonElement = screen.getByRole('button');
|
|
25
|
+
expect(buttonElement.className).toBeTruthy();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
export const BUTTON_SPEC_FILE_GENERATOR = new FileGeneratorImp(
|
|
31
|
+
'src/button.spec.tsx',
|
|
32
|
+
BUTTON_SPEC,
|
|
33
|
+
);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FileGeneratorImp } from '../../../../file-generator/file-generator-imp';
|
|
2
|
+
|
|
3
|
+
const ESLINT_CONFIG = `import base from '@stack-dev/eslint-config/base.mjs';
|
|
4
|
+
import react from '@stack-dev/eslint-config/react.mjs';
|
|
5
|
+
|
|
6
|
+
export default [
|
|
7
|
+
...base,
|
|
8
|
+
...react,
|
|
9
|
+
{
|
|
10
|
+
ignores: ['**/dist/**', '**/coverage/**']
|
|
11
|
+
}
|
|
12
|
+
];
|
|
13
|
+
`;
|
|
14
|
+
|
|
15
|
+
export const ESLINT_CONFIG_FILE_GENERATOR = new FileGeneratorImp(
|
|
16
|
+
'eslint.config.mjs',
|
|
17
|
+
ESLINT_CONFIG,
|
|
18
|
+
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { FileGeneratorImp } from '../../../../file-generator/file-generator-imp';
|
|
2
|
+
|
|
3
|
+
const PRETTIER_CONFIG = `import base from '@stack-dev/prettier-config/base.mjs';
|
|
4
|
+
|
|
5
|
+
export default base;
|
|
6
|
+
`;
|
|
7
|
+
|
|
8
|
+
export const PRETTIER_CONFIG_FILE_GENERATOR = new FileGeneratorImp(
|
|
9
|
+
'prettier.config.mjs',
|
|
10
|
+
PRETTIER_CONFIG,
|
|
11
|
+
);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FileGeneratorImp } from '../../../../file-generator/file-generator-imp';
|
|
2
|
+
|
|
3
|
+
const TSCONFIG = `{
|
|
4
|
+
"extends": "@stack-dev/typescript-config/tsconfig.react.json",
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"outDir": "dist"
|
|
7
|
+
},
|
|
8
|
+
"include": ["src"]
|
|
9
|
+
}
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
export const TSCONFIG_FILE_GENERATOR = new FileGeneratorImp(
|
|
13
|
+
'tsconfig.json',
|
|
14
|
+
TSCONFIG,
|
|
15
|
+
);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { FileGeneratorImp } from '../../../../file-generator/file-generator-imp';
|
|
2
|
+
|
|
3
|
+
const TSUP_CONFIG = `import { defineConfig } from 'tsup';
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
entry: ['src/index.ts'],
|
|
7
|
+
format: ['cjs', 'esm'],
|
|
8
|
+
dts: true,
|
|
9
|
+
minify: true,
|
|
10
|
+
clean: true,
|
|
11
|
+
injectStyle: true,
|
|
12
|
+
external: ['react', 'react-dom'],
|
|
13
|
+
outExtension({ format }) {
|
|
14
|
+
return {
|
|
15
|
+
js: format === 'esm' ? '.mjs' : '.js',
|
|
16
|
+
};
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
export const TSUP_CONFIG_FILE_GENERATOR = new FileGeneratorImp(
|
|
22
|
+
'tsup.config.ts',
|
|
23
|
+
TSUP_CONFIG,
|
|
24
|
+
);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FileGeneratorImp } from '../../../../file-generator/file-generator-imp';
|
|
2
|
+
|
|
3
|
+
const VITEST_CONFIG = `import { defineConfig } from 'vitest/config';
|
|
4
|
+
import react from '@vitejs/plugin-react';
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
plugins: [react()],
|
|
8
|
+
test: {
|
|
9
|
+
globals: true,
|
|
10
|
+
environment: 'jsdom',
|
|
11
|
+
coverage: {
|
|
12
|
+
provider: 'v8',
|
|
13
|
+
reporter: ['text', 'json', 'html'],
|
|
14
|
+
},
|
|
15
|
+
css: true,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
`;
|
|
19
|
+
|
|
20
|
+
export const VITEST_CONFIG_FILE_GENERATOR = new FileGeneratorImp(
|
|
21
|
+
'vitest.config.ts',
|
|
22
|
+
VITEST_CONFIG,
|
|
23
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './create-react-package';
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { PackageJsonGenerator } from '../../../file-generator';
|
|
3
|
+
import { Dependency, PackageJSON } from '../../../package-json';
|
|
4
|
+
import { PackageGenerator } from '../../../utils/package-generator';
|
|
5
|
+
import { getNamespace, getWorkspaceRoot } from '../../../utils/workspace';
|
|
6
|
+
import { BUTTON_FILE_GENERATOR } from './files/button-file-generator';
|
|
7
|
+
import { BUTTON_SPEC_FILE_GENERATOR } from './files/button-spec-file-generator';
|
|
8
|
+
import { ESLINT_CONFIG_FILE_GENERATOR } from './files/eslint-config-file-generator';
|
|
9
|
+
import { INDEX_FILE_GENERATOR } from './files/index-file-generator';
|
|
10
|
+
import { PRETTIER_CONFIG_FILE_GENERATOR } from './files/prettier-config-file-generator';
|
|
11
|
+
import { TSCONFIG_FILE_GENERATOR } from './files/tsconfig-file-generator';
|
|
12
|
+
import { TSUP_CONFIG_FILE_GENERATOR } from './files/tsup-config-file-generator';
|
|
13
|
+
import { VITEST_CONFIG_FILE_GENERATOR } from './files/vitest-config-file-generator';
|
|
14
|
+
|
|
15
|
+
export async function createStyledComponentsReactPackage(
|
|
16
|
+
name: string,
|
|
17
|
+
): Promise<void> {
|
|
18
|
+
const rootDir = await getWorkspaceRoot();
|
|
19
|
+
const directory = path.join(rootDir, 'packages', name);
|
|
20
|
+
|
|
21
|
+
const namespace = await getNamespace(rootDir);
|
|
22
|
+
const packageName = `${namespace}/${name}`;
|
|
23
|
+
|
|
24
|
+
console.log(
|
|
25
|
+
`✨ Creating Styled Components Modules React library: ${packageName}`,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const generator = new PackageGenerator(
|
|
29
|
+
directory,
|
|
30
|
+
makePackageGenerator(packageName, namespace),
|
|
31
|
+
[
|
|
32
|
+
INDEX_FILE_GENERATOR,
|
|
33
|
+
BUTTON_FILE_GENERATOR,
|
|
34
|
+
BUTTON_SPEC_FILE_GENERATOR,
|
|
35
|
+
TSUP_CONFIG_FILE_GENERATOR,
|
|
36
|
+
TSCONFIG_FILE_GENERATOR,
|
|
37
|
+
PRETTIER_CONFIG_FILE_GENERATOR,
|
|
38
|
+
ESLINT_CONFIG_FILE_GENERATOR,
|
|
39
|
+
VITEST_CONFIG_FILE_GENERATOR,
|
|
40
|
+
],
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
await generator.generate();
|
|
44
|
+
|
|
45
|
+
console.log(`✅ Library created at: ${directory}`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function makePackageGenerator(packageName: string, namespace: string) {
|
|
49
|
+
const packageJsonModel = new PackageJSON({
|
|
50
|
+
name: packageName,
|
|
51
|
+
// Peer deps are crucial for Styled Components to prevent "Multiple instances" errors
|
|
52
|
+
peerDependencies: [
|
|
53
|
+
new Dependency('react', '>=18'),
|
|
54
|
+
new Dependency('react-dom', '>=18'),
|
|
55
|
+
new Dependency('styled-components', '>=6'),
|
|
56
|
+
],
|
|
57
|
+
devDependencies: [
|
|
58
|
+
new Dependency(`${namespace}/eslint-config`, 'workspace:*'),
|
|
59
|
+
new Dependency(`${namespace}/prettier-config`, 'workspace:*'),
|
|
60
|
+
new Dependency(`${namespace}/typescript-config`, 'workspace:*'),
|
|
61
|
+
// Development React binaries
|
|
62
|
+
new Dependency('react', '^18.3.1'),
|
|
63
|
+
new Dependency('react-dom', '^18.3.1'),
|
|
64
|
+
new Dependency('@types/react', '^18.3.1'),
|
|
65
|
+
new Dependency('@types/react-dom', '^18.3.1'),
|
|
66
|
+
// Styled Components types and binary for build time
|
|
67
|
+
new Dependency('styled-components', '^6.1.13'),
|
|
68
|
+
new Dependency('@types/styled-components', '^5.1.34'),
|
|
69
|
+
// Linting & Formatting
|
|
70
|
+
new Dependency('eslint', '^9.32.0'),
|
|
71
|
+
new Dependency('prettier', '^3.6.2'),
|
|
72
|
+
new Dependency('prettier-plugin-organize-imports', '^4.2.0'),
|
|
73
|
+
// Build
|
|
74
|
+
new Dependency('tsup', '^8.0.0'),
|
|
75
|
+
// Testing
|
|
76
|
+
new Dependency('vitest', '^3.2.4'),
|
|
77
|
+
new Dependency('@vitest/coverage-v8', '^3.2.4'),
|
|
78
|
+
new Dependency('@testing-library/react', '^16.0.0'),
|
|
79
|
+
new Dependency('@testing-library/jest-dom', '^6.0.0'),
|
|
80
|
+
new Dependency('jsdom', '^25.0.0'),
|
|
81
|
+
],
|
|
82
|
+
additionalData: {
|
|
83
|
+
version: '0.1.0',
|
|
84
|
+
private: true,
|
|
85
|
+
type: 'module', // Added this to ensure ESM consistency
|
|
86
|
+
main: 'dist/index.js',
|
|
87
|
+
module: 'dist/index.mjs',
|
|
88
|
+
types: 'dist/index.d.ts',
|
|
89
|
+
exports: {
|
|
90
|
+
'.': {
|
|
91
|
+
development: './src/index.ts',
|
|
92
|
+
import: './dist/index.mjs',
|
|
93
|
+
require: './dist/index.js',
|
|
94
|
+
types: './dist/index.d.ts',
|
|
95
|
+
},
|
|
96
|
+
// Removed './index.css' as it's no longer produced by Styled Components
|
|
97
|
+
},
|
|
98
|
+
scripts: {
|
|
99
|
+
build: 'tsup',
|
|
100
|
+
dev: 'tsup --watch', // Helpful for local lib dev
|
|
101
|
+
lint: 'eslint .',
|
|
102
|
+
format: 'prettier . --write',
|
|
103
|
+
test: 'vitest run',
|
|
104
|
+
'test:watch': 'vitest',
|
|
105
|
+
},
|
|
106
|
+
// Set to false or removed because Styled Components are pure JS/TS
|
|
107
|
+
sideEffects: false,
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return new PackageJsonGenerator(packageJsonModel, namespace);
|
|
112
|
+
}
|