@alignui/cli 0.0.1-alpha.8 → 0.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alignui/cli",
3
- "version": "0.0.1-alpha.8",
3
+ "version": "0.0.2",
4
4
  "description": "A command line interface to setup AlignUI",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -23,6 +23,9 @@
23
23
  "alignui",
24
24
  "design system"
25
25
  ],
26
+ "files": [
27
+ "dist"
28
+ ],
26
29
  "author": "dgknca",
27
30
  "license": "MIT",
28
31
  "bugs": {
@@ -33,15 +36,13 @@
33
36
  "@antfu/ni": "^0.22.4",
34
37
  "@babel/core": "^7.25.2",
35
38
  "@babel/parser": "^7.25.3",
36
- "chalk": "^5.3.0",
39
+ "@clack/prompts": "^0.7.0",
37
40
  "commander": "^12.1.0",
38
41
  "culori": "^4.0.1",
39
42
  "execa": "^9.3.1",
40
43
  "fast-glob": "^3.3.2",
41
44
  "fs-extra": "^11.2.0",
42
45
  "lodash.template": "^4.5.0",
43
- "ora": "^8.0.1",
44
- "prompts": "^2.4.2",
45
46
  "ts-morph": "^23.0.0",
46
47
  "zod": "^3.23.8"
47
48
  },
@@ -65,4 +66,4 @@
65
66
  "type-fest": "^4.24.0",
66
67
  "typescript": "^5.5.4"
67
68
  }
68
- }
69
+ }
package/.eslintrc.json DELETED
@@ -1,11 +0,0 @@
1
- {
2
- "$schema": "https://json.schemastore.org/eslintrc",
3
- "root": true,
4
- "extends": ["prettier"],
5
- "overrides": [
6
- {
7
- "files": ["*.ts", "*.tsx"],
8
- "parser": "@typescript-eslint/parser"
9
- }
10
- ]
11
- }
package/.husky/commit-msg DELETED
@@ -1,4 +0,0 @@
1
- #!/bin/sh
2
- . "$(dirname "$0")/_/husky.sh"
3
-
4
- npx commitlint --edit
@@ -1,15 +0,0 @@
1
- {
2
- "editor.tabSize": 2,
3
- "editor.indentSize": 2,
4
- "editor.formatOnSave": true,
5
- "editor.defaultFormatter": "esbenp.prettier-vscode",
6
- "editor.codeActionsOnSave": {
7
- "source.fixAll": "explicit"
8
- },
9
- "typescript.preferences.importModuleSpecifier": "non-relative",
10
- "eslint.workingDirectories": [
11
- {
12
- "mode": "auto"
13
- }
14
- ]
15
- }
@@ -1 +0,0 @@
1
- export default { extends: ['@commitlint/config-conventional'] };
@@ -1,10 +0,0 @@
1
- const config = {
2
- arrowParens: 'always',
3
- singleQuote: true,
4
- jsxSingleQuote: true,
5
- tabWidth: 2,
6
- semi: true,
7
- printWidth: 80,
8
- };
9
-
10
- export default config;
@@ -1,272 +0,0 @@
1
- import { existsSync, promises as fs } from 'fs';
2
- import path from 'path';
3
- import { handleError } from '@/src/utils/handle-error';
4
- import { logger } from '@/src/utils/logger';
5
- import * as templates from '@/src/utils/templates';
6
- import chalk from 'chalk';
7
- import { Command } from 'commander';
8
- import { execa } from 'execa';
9
- import template from 'lodash.template';
10
- import ora from 'ora';
11
- import prompts from 'prompts';
12
- import { z } from 'zod';
13
- import {
14
- DEFAULT_TAILWIND_CONFIG,
15
- DEFAULT_TAILWIND_CSS,
16
- rawConfigSchema,
17
- resolveConfigPaths,
18
- type Config,
19
- } from '@/src/utils/get-config';
20
- import { getPackageManager } from '@/src/utils/get-package-manager';
21
- import { getProjectConfig, preFlight } from '@/src/utils/get-project-info';
22
- import {
23
- rawHexColors,
24
- tailwindColorsHex,
25
- tailwindColorsHsl,
26
- tailwindColorsRgb,
27
- borderRadii,
28
- texts,
29
- shadows,
30
- animations,
31
- } from '@/src/utils/tokens';
32
- import { prettierFormat } from '@/src/utils/prettier';
33
- import { formatHslColor, formatRgbColor } from '@/src/utils/color-helpers';
34
-
35
- const PROJECT_DEV_DEPENDENCIES = ['tailwindcss-animate'];
36
- const highlight = (text: string) => chalk.hex('#8c71f6')(text);
37
-
38
- const tailwindInitOptionsSchema = z.object({
39
- cwd: z.string(),
40
- });
41
-
42
- export const initTailwind = new Command()
43
- .name('tailwind')
44
- .description('Initialize AlignUI tailwind tokens for your project.')
45
- .option(
46
- '-c, --cwd <cwd>',
47
- 'the working directory. defaults to the current directory.',
48
- process.cwd(),
49
- )
50
- .action(async (opts) => {
51
- try {
52
- const options = tailwindInitOptionsSchema.parse(opts);
53
- const cwd = path.resolve(options.cwd);
54
-
55
- // Ensure target directory exists.
56
- if (!existsSync(cwd)) {
57
- logger.error(`The path ${cwd} does not exist. Please try again.`);
58
- process.exit(1);
59
- }
60
-
61
- preFlight(cwd);
62
-
63
- const projectConfig = await getProjectConfig(cwd);
64
-
65
- if (projectConfig) {
66
- const config = await promptForConfig(cwd, projectConfig);
67
- await runInit(cwd, config);
68
- }
69
-
70
- logger.break();
71
- logger.success('Project initialization completed!');
72
- logger.break();
73
- logger.white(`Installed the following packages:
74
-
75
- ${PROJECT_DEV_DEPENDENCIES.map((pkg) => ` - ${pkg}`).join('\n')}`);
76
- logger.break();
77
- } catch (error) {
78
- handleError(error);
79
- }
80
- });
81
-
82
- async function promptForConfig(cwd: string, defaultConfig: Config) {
83
- const options = await prompts([
84
- {
85
- type: 'select',
86
- name: 'primaryColor',
87
- message: `Which color would you like to use as ${highlight(
88
- 'primary color',
89
- )}?`,
90
- choices: [
91
- {
92
- title: 'Blue',
93
- value: 'blue',
94
- },
95
- {
96
- title: 'Purple',
97
- value: 'purple',
98
- },
99
- {
100
- title: 'Orange',
101
- value: 'orange',
102
- },
103
- {
104
- title: 'Sky',
105
- value: 'sky',
106
- },
107
- ],
108
- initial: 0,
109
- },
110
- {
111
- type: 'select',
112
- name: 'colorFormat',
113
- message: `Which ${highlight('color format')} would you like to use?`,
114
- choices: [
115
- {
116
- title: 'hex',
117
- value: 'hex',
118
- },
119
- {
120
- title: 'rgb',
121
- value: 'rgb',
122
- },
123
- {
124
- title: 'hsl',
125
- value: 'hsl',
126
- },
127
- ],
128
- initial: 0,
129
- },
130
- {
131
- type: 'text',
132
- name: 'tailwindPrefix',
133
- message: `Would you like to use a custom prefix for AlignUI specific classes? ${highlight('eg. an-')} (Recommended if you want to keep tailwind's default colors, shadows and font-sizes. Leave blank if not)`,
134
- initial: '',
135
- },
136
- {
137
- type: 'text',
138
- name: 'tailwindConfig',
139
- message: `Where is your ${highlight('tailwind config')} file?`,
140
- initial: defaultConfig?.tailwind.config ?? DEFAULT_TAILWIND_CONFIG,
141
- },
142
- {
143
- type: 'text',
144
- name: 'tailwindCss',
145
- message: `Where is your ${highlight('global CSS')} file?`,
146
- initial: defaultConfig?.tailwind.css ?? DEFAULT_TAILWIND_CSS,
147
- },
148
- ]);
149
-
150
- const config = rawConfigSchema.parse({
151
- tailwind: {
152
- config: options.tailwindConfig,
153
- css: options.tailwindCss,
154
- primaryColor: options.primaryColor,
155
- colorFormat: options.colorFormat,
156
- prefix: options.tailwindPrefix,
157
- },
158
- });
159
-
160
- return await resolveConfigPaths(cwd, config);
161
- }
162
-
163
- function applyPrefixToKeys<T extends Record<string, any>>(
164
- obj: T,
165
- prefix: string | undefined,
166
- ): T {
167
- if (!prefix) return obj;
168
-
169
- return Object.fromEntries(
170
- Object.entries(obj).map(([key, value]) => [`${prefix}${key}`, value]),
171
- ) as T;
172
- }
173
-
174
- async function runInit(cwd: string, config: Config) {
175
- const spinner = ora(`Initializing project...`)?.start();
176
-
177
- // Ensure all resolved paths directories exist.
178
- for (const [key, resolvedPath] of Object.entries(config.resolvedPaths)) {
179
- // Determine if the path is a file or directory.
180
- let dirname = path.extname(resolvedPath)
181
- ? path.dirname(resolvedPath)
182
- : resolvedPath;
183
-
184
- if (!existsSync(dirname)) {
185
- await fs.mkdir(dirname, { recursive: true });
186
- }
187
- }
188
-
189
- const tailwindConfigTemplate =
190
- path.extname(config.resolvedPaths.tailwindConfig) === '.ts'
191
- ? templates.TAILWIND_CONFIG_TS
192
- : templates.TAILWIND_CONFIG_JS;
193
-
194
- let tailwindColorsInSelectedFormat =
195
- config.tailwind.colorFormat === 'rgb'
196
- ? tailwindColorsRgb
197
- : config.tailwind.colorFormat === 'hsl'
198
- ? tailwindColorsHsl
199
- : tailwindColorsHex;
200
- let textValues: any = texts;
201
- let shadowValues: any = shadows;
202
-
203
- if (config.tailwind.prefix) {
204
- tailwindColorsInSelectedFormat = applyPrefixToKeys(
205
- tailwindColorsInSelectedFormat,
206
- config.tailwind.prefix,
207
- );
208
- textValues = applyPrefixToKeys(texts, config.tailwind.prefix);
209
- shadowValues = applyPrefixToKeys(texts, config.tailwind.prefix);
210
- }
211
-
212
- // Write tailwind config.
213
- await fs.writeFile(
214
- config.resolvedPaths.tailwindConfig,
215
- await prettierFormat(
216
- template(tailwindConfigTemplate)({
217
- prefix: config.tailwind.prefix,
218
- colors: JSON.stringify(tailwindColorsInSelectedFormat, null, 2),
219
- borderRadii: JSON.stringify(borderRadii, null, 2),
220
- texts: JSON.stringify(textValues, null, 2),
221
- shadows: JSON.stringify(shadowValues, null, 2),
222
- animations: JSON.stringify(animations, null, 2),
223
- }),
224
- ),
225
- 'utf8',
226
- );
227
-
228
- const colorVariables = Object.fromEntries(
229
- Object.entries(rawHexColors).map(([colorName, shades]) => [
230
- colorName,
231
- Object.fromEntries(
232
- Object.entries(shades).map(([shade, hex]) => {
233
- if (config.tailwind.colorFormat === 'hsl') {
234
- return [shade, formatHslColor(hex)];
235
- } else if (config.tailwind.colorFormat === 'rgb') {
236
- return [shade, formatRgbColor(hex)];
237
- }
238
- return [shade, hex];
239
- }),
240
- ),
241
- ]),
242
- );
243
-
244
- // Write globals.css
245
- await fs.writeFile(
246
- config.resolvedPaths.tailwindCss,
247
- template(templates.GLOBALS_CSS)({
248
- primaryColor: config.tailwind.primaryColor,
249
- ...colorVariables,
250
- }),
251
- 'utf8',
252
- );
253
-
254
- spinner?.succeed();
255
-
256
- // Install dependencies.
257
- const dependenciesSpinner = ora(`Installing dependencies...`)?.start();
258
- const packageManager = await getPackageManager(cwd);
259
-
260
- await execa(
261
- packageManager,
262
- [
263
- packageManager === 'npm' ? 'i' : 'add',
264
- packageManager === 'npm' ? '--save-dev' : '-D',
265
- ...PROJECT_DEV_DEPENDENCIES,
266
- ],
267
- {
268
- cwd,
269
- },
270
- );
271
- dependenciesSpinner?.succeed();
272
- }
package/src/index.ts DELETED
@@ -1,27 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { initTailwind } from '@/src/commands/tailwind';
4
- import { Command } from 'commander';
5
-
6
- import { getPackageInfo } from './utils/get-package-info';
7
-
8
- process.on('SIGINT', () => process.exit(0));
9
- process.on('SIGTERM', () => process.exit(0));
10
-
11
- async function main() {
12
- const packageInfo = await getPackageInfo();
13
-
14
- const program = new Command()
15
- .name('alignui-cli')
16
- .description(packageInfo.description || '')
17
- .version(
18
- packageInfo.version || '0.0.1',
19
- '-v, --version',
20
- 'display the version number',
21
- );
22
-
23
- program.addCommand(initTailwind);
24
- program.parse();
25
- }
26
-
27
- main();
@@ -1,36 +0,0 @@
1
- import { converter, formatHsl, formatRgb, type Color } from 'culori';
2
-
3
- const rgb = converter('rgb');
4
- const hsl = converter('hsl');
5
- const percentageFormat = new Intl.NumberFormat('en-US', { style: 'percent' })
6
- .format;
7
-
8
- export function formatHslColor(hex: string): string {
9
- const color = hsl(hex) as Color;
10
- const formattedCssColor = formatHsl(color);
11
- let [h, s, l]: any[] = formattedCssColor
12
- .replace('hsla(', '')
13
- .replace('hsl(', '')
14
- .replace(')', '')
15
- .split(', ');
16
-
17
- if (color?.alpha) {
18
- return `${h} ${s} ${l} / ${percentageFormat(color.alpha)}`;
19
- }
20
- return `${h} ${s} ${l}`;
21
- }
22
-
23
- export function formatRgbColor(hex: string): string {
24
- const color = rgb(hex) as Color;
25
- const formattedCssColor = formatRgb(color);
26
- let [r, g, b]: any[] = formattedCssColor
27
- .replace('rgba(', '')
28
- .replace('rgb(', '')
29
- .replace(')', '')
30
- .split(', ');
31
-
32
- if (color?.alpha) {
33
- return `${r} ${g} ${b} / ${percentageFormat(color.alpha)}`;
34
- }
35
- return `${r} ${g} ${b}`;
36
- }
@@ -1,38 +0,0 @@
1
- import path from 'path';
2
- import { z } from 'zod';
3
-
4
- export const DEFAULT_TAILWIND_CSS = 'app/globals.css';
5
- export const DEFAULT_TAILWIND_CONFIG = 'tailwind.config.js';
6
-
7
- export const rawConfigSchema = z
8
- .object({
9
- tailwind: z.object({
10
- config: z.string(),
11
- css: z.string(),
12
- primaryColor: z.enum(['blue', 'purple', 'orange', 'sky']),
13
- colorFormat: z.enum(['hex', 'rgb', 'hsl']),
14
- prefix: z.string().default('').optional(),
15
- }),
16
- })
17
- .strict();
18
-
19
- export type RawConfig = z.infer<typeof rawConfigSchema>;
20
-
21
- export const configSchema = rawConfigSchema.extend({
22
- resolvedPaths: z.object({
23
- tailwindConfig: z.string(),
24
- tailwindCss: z.string(),
25
- }),
26
- });
27
-
28
- export type Config = z.infer<typeof configSchema>;
29
-
30
- export async function resolveConfigPaths(cwd: string, config: RawConfig) {
31
- return configSchema.parse({
32
- ...config,
33
- resolvedPaths: {
34
- tailwindConfig: path.resolve(cwd, config.tailwind.config),
35
- tailwindCss: path.resolve(cwd, config.tailwind.css),
36
- },
37
- });
38
- }
@@ -1,9 +0,0 @@
1
- import path from 'path';
2
- import fs from 'fs-extra';
3
- import { type PackageJson } from 'type-fest';
4
-
5
- export function getPackageInfo() {
6
- const packageJsonPath = path.join('package.json');
7
-
8
- return fs.readJSONSync(packageJsonPath) as PackageJson;
9
- }
@@ -1,13 +0,0 @@
1
- import { detect } from '@antfu/ni';
2
-
3
- export async function getPackageManager(
4
- targetDir: string,
5
- ): Promise<'yarn' | 'pnpm' | 'bun' | 'npm'> {
6
- const packageManager = await detect({ programmatic: true, cwd: targetDir });
7
-
8
- if (packageManager === 'yarn@berry') return 'yarn';
9
- if (packageManager === 'pnpm@6') return 'pnpm';
10
- if (packageManager === 'bun') return 'bun';
11
-
12
- return packageManager ?? 'npm';
13
- }
@@ -1,78 +0,0 @@
1
- import path from 'path';
2
- import { Config, RawConfig, resolveConfigPaths } from '@/src/utils/get-config';
3
- import fg from 'fast-glob';
4
- import fs, { pathExists } from 'fs-extra';
5
-
6
- const PROJECT_SHARED_IGNORE = [
7
- '**/node_modules/**',
8
- '.next',
9
- 'public',
10
- 'dist',
11
- 'build',
12
- ];
13
-
14
- export async function getProjectConfig(cwd: string): Promise<Config | null> {
15
- const tailwindCssFile = await getTailwindCssFile(cwd);
16
-
17
- if (!tailwindCssFile) {
18
- return null;
19
- }
20
-
21
- const isTsx = await isTypeScriptProject(cwd);
22
-
23
- const config: RawConfig = {
24
- tailwind: {
25
- config: isTsx ? 'tailwind.config.ts' : 'tailwind.config.js',
26
- primaryColor: 'blue',
27
- colorFormat: 'hex',
28
- css: tailwindCssFile,
29
- prefix: '',
30
- },
31
- };
32
-
33
- return await resolveConfigPaths(cwd, config);
34
- }
35
-
36
- export async function getTailwindCssFile(cwd: string) {
37
- const files = await fg.glob('**/*.css', {
38
- cwd,
39
- deep: 3,
40
- ignore: PROJECT_SHARED_IGNORE,
41
- });
42
-
43
- if (!files.length) {
44
- return null;
45
- }
46
-
47
- for (const file of files) {
48
- const contents = await fs.readFile(path.resolve(cwd, file), 'utf8');
49
- // Assume that if the file contains `@tailwind base` it's the main css file.
50
- if (contents.includes('@tailwind base')) {
51
- return file;
52
- }
53
- }
54
-
55
- return null;
56
- }
57
-
58
- export async function isTypeScriptProject(cwd: string) {
59
- // Check if cwd has a tsconfig.json file.
60
- return pathExists(path.resolve(cwd, 'tsconfig.json'));
61
- }
62
-
63
- export async function preFlight(cwd: string) {
64
- // We need Tailwind CSS to be configured.
65
- const tailwindConfig = await fg.glob('tailwind.config.*', {
66
- cwd,
67
- deep: 3,
68
- ignore: PROJECT_SHARED_IGNORE,
69
- });
70
-
71
- if (!tailwindConfig.length) {
72
- throw new Error(
73
- 'Tailwind CSS is not installed. Visit https://tailwindcss.com/docs/installation to get started.',
74
- );
75
- }
76
-
77
- return true;
78
- }
@@ -1,16 +0,0 @@
1
- import { logger } from '@/src/utils/logger';
2
-
3
- export function handleError(error: unknown) {
4
- if (typeof error === 'string') {
5
- logger.error(error);
6
- process.exit(1);
7
- }
8
-
9
- if (error instanceof Error) {
10
- logger.error(error.message);
11
- process.exit(1);
12
- }
13
-
14
- logger.error('Something went wrong. Please try again.');
15
- process.exit(1);
16
- }
@@ -1,22 +0,0 @@
1
- import chalk from 'chalk';
2
-
3
- export const logger = {
4
- error(...args: unknown[]) {
5
- console.log(chalk.red(...args));
6
- },
7
- warn(...args: unknown[]) {
8
- console.log(chalk.yellow(...args));
9
- },
10
- info(...args: unknown[]) {
11
- console.log(chalk.hex('#97dcff')(...args));
12
- },
13
- white(...args: unknown[]) {
14
- console.log(chalk.white(...args));
15
- },
16
- success(...args: unknown[]) {
17
- console.log(chalk.green(...args));
18
- },
19
- break() {
20
- console.log('');
21
- },
22
- };
@@ -1,10 +0,0 @@
1
- import * as prettier from 'prettier';
2
-
3
- export const prettierFormat = (src: string) =>
4
- prettier.format(src, {
5
- singleQuote: true,
6
- jsxSingleQuote: true,
7
- tabWidth: 2,
8
- semi: true,
9
- parser: 'typescript',
10
- });