cromatica-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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cromática Media
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,183 @@
1
+ # Cromatica — CLI
2
+
3
+ > Official CLI toolkit for [Cromatica Media](https://cromatica.media) projects.
4
+
5
+ Fetch and scaffold blocks, templates and components directly from the
6
+ [Cromatica Block Bank](https://bank.cromatica.media) into your project
7
+ with a single command.
8
+
9
+ ---
10
+
11
+ ## Requirements
12
+
13
+ - Node.js 18+
14
+ - A project based on `cm-template-website`
15
+ - pnpm (recommended) or npm
16
+
17
+ ---
18
+
19
+ ## Usage
20
+
21
+ No installation needed. Run directly with `npx`:
22
+
23
+ ```bash
24
+ npx cromatica <command> <subcommand> [arguments]
25
+ ```
26
+
27
+ > ⚠️ This command must be run from the root of a `cm-template-website` project.
28
+ > Running it in any other directory will abort with an error.
29
+
30
+ ---
31
+
32
+ ## Commands
33
+
34
+ ### `add block`
35
+
36
+ Fetches a block from the Cromatica Block Bank and scaffolds it into your
37
+ `cm-template-website` project.
38
+
39
+ ```bash
40
+ npx cromatica add block [block-name]
41
+ ```
42
+
43
+ **Example:**
44
+
45
+ ```bash
46
+ npx cromatica add block hero-cards
47
+ ```
48
+
49
+ **What it does:**
50
+
51
+ 1. Validates that the current directory is a valid `cm-template-website` project
52
+ 2. Fetches `hero-cards` from the Block Bank API
53
+ 3. Creates the React component:
54
+
55
+ ```
56
+ src/components/blocks/HeroCards/
57
+ ├── HeroCards.tsx
58
+ └── index.ts
59
+ ```
60
+
61
+ 4. Creates the Payload CMS schema:
62
+
63
+ ```
64
+ src/blocks/HeroCards/
65
+ ├── HeroCards.block.ts
66
+ └── index.ts
67
+ ```
68
+
69
+ 5. Injects the block into `src/fields/Blocks/Blocks.field.ts`:
70
+
71
+ ```ts
72
+ import HeroCardsBlock from '@/blocks/HeroCards'
73
+ // and adds HeroCardsBlock to the blocks array
74
+ ```
75
+
76
+ 6. Injects the block into `src/components/blocks/RenderBlocks.tsx`:
77
+
78
+ ```tsx
79
+ import HeroCards from '@/components/blocks/HeroCards'
80
+ // and adds the case to the switch statement
81
+ case 'hero-cards':
82
+ return <HeroCards key={index} {...block} locale={locale} />
83
+ ```
84
+
85
+ 7. Regenerates Payload types by running `pnpm payload generate:types` automatically
86
+
87
+ ---
88
+
89
+ ## Block naming convention
90
+
91
+ Blocks use `kebab-case` slugs in the Bank and are automatically converted
92
+ to `PascalCase` for folders, filenames and import names:
93
+
94
+ | Bank slug | Folder & files | Import name |
95
+ | ------------------ | ----------------- | --------------------- |
96
+ | `hero-cards` | `HeroCards/` | `HeroCardsBlock` |
97
+ | `perks-grid` | `PerksGrid/` | `PerksGridBlock` |
98
+ | `cta-split` | `CtaSplit/` | `CtaSplitBlock` |
99
+ | `perks-cards-grid` | `PerksCardsGrid/` | `PerksCardsGridBlock` |
100
+
101
+ ---
102
+
103
+ ## Project validation
104
+
105
+ Before doing anything, the CLI verifies that the following paths exist in the current directory:
106
+
107
+ ```
108
+ src/fields/Blocks/Blocks.field.ts
109
+ src/components/blocks/RenderBlocks.tsx
110
+ src/blocks/
111
+ ```
112
+
113
+ If any of these are missing, the CLI aborts immediately with a clear error:
114
+
115
+ ```
116
+ ✖ This command must be run inside a cm-template-website project or in a fork of itself.
117
+ Missing: /your/path/src/fields/Blocks/Blocks.field.ts
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Project structure expected
123
+
124
+ The CLI assumes your project follows the `cm-template-website` structure:
125
+
126
+ ```
127
+ src/
128
+ ├── components/
129
+ │ └── blocks/
130
+ │ ├── RenderBlocks.tsx ← auto-updated by the CLI
131
+ │ └── HeroCards/ ← React components land here
132
+ │ ├── HeroCards.tsx
133
+ │ └── index.ts
134
+ ├── blocks/
135
+ │ └── HeroCards/ ← Payload schemas land here
136
+ │ ├── HeroCards.block.ts
137
+ │ └── index.ts
138
+ └── fields/
139
+ └── Blocks/
140
+ └── Blocks.field.ts ← auto-updated by the CLI
141
+ ```
142
+
143
+ ---
144
+
145
+ ## How it works
146
+
147
+ The CLI fetches block data from the public Cromatica Block Bank API:
148
+
149
+ ```
150
+ GET https://bank.cromatica.media/api/blocks?where[name][equals]=hero-cards&depth=0&limit=1
151
+ ```
152
+
153
+ The API response contains:
154
+
155
+ - `files.componentTsx` — the React component source
156
+ - `files.blockTs` — the Payload CMS block schema source
157
+
158
+ ---
159
+
160
+ ## Roadmap
161
+
162
+ - [x] `add block [name]` — scaffold a block from the Bank
163
+ - [x] Project structure validation before scaffolding
164
+ - [x] Auto-inject into `Blocks.field.ts`
165
+ - [x] Auto-inject into `RenderBlocks.tsx`
166
+ - [x] Auto-regenerate Payload types after scaffolding
167
+ - [ ] `add template [name]` — scaffold a full page template
168
+ - [ ] `list blocks` — list all available blocks in the Bank
169
+ - [ ] `list templates` — list all available templates
170
+ - [ ] `update block [name]` — update a block to its latest version
171
+
172
+ ---
173
+
174
+ ## Contributing
175
+
176
+ This CLI is maintained by [Cromatica Media](https://cromatica.media).
177
+ Internal use and open contributions welcome.
178
+
179
+ ---
180
+
181
+ ## License
182
+
183
+ [MIT](./LICENSE) © Cromatica Media
@@ -0,0 +1,2 @@
1
+ export declare function addBlock(blockName: string): Promise<void>;
2
+ //# sourceMappingURL=block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../../src/commands/add/block.ts"],"names":[],"mappings":"AAgPA,wBAAsB,QAAQ,CAAC,SAAS,EAAE,MAAM,iBAuG/C"}
@@ -0,0 +1,259 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import fs from 'fs/promises';
4
+ import { execSync } from 'child_process';
5
+ import path from 'path';
6
+ const BANK_API_URL = 'https://bank.cromatica.media/api';
7
+ // ── Utils ─────────────────────────────────────────────────────────────────────
8
+ function toPascalCase(kebab) {
9
+ return kebab
10
+ .split('-')
11
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
12
+ .join('');
13
+ }
14
+ async function fileExists(filePath) {
15
+ try {
16
+ await fs.access(filePath);
17
+ return true;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ }
23
+ // ── Validate project structure ────────────────────────────────────────────────
24
+ async function validateProject() {
25
+ const requiredPaths = [
26
+ path.join(process.cwd(), 'src', 'fields', 'Blocks', 'Blocks.field.ts'),
27
+ path.join(process.cwd(), 'src', 'components', 'blocks', 'RenderBlocks.tsx'),
28
+ path.join(process.cwd(), 'src', 'blocks'),
29
+ ];
30
+ for (const requiredPath of requiredPaths) {
31
+ const exists = await fileExists(requiredPath);
32
+ if (!exists) {
33
+ throw new Error(`This command must be run inside a cm-template-website project or in a fork of itself.\n Missing: ${requiredPath}`);
34
+ }
35
+ }
36
+ }
37
+ // ── Fetch block from Bank API ─────────────────────────────────────────────────
38
+ async function fetchBlock(blockName) {
39
+ const url = `${BANK_API_URL}/blocks?where[slug][equals]=${blockName}&depth=0&limit=1`;
40
+ const response = await fetch(url);
41
+ if (!response.ok) {
42
+ throw new Error(`Bank API responded with status ${response.status}`);
43
+ }
44
+ const data = (await response.json());
45
+ if (!data.docs.length) {
46
+ throw new Error(`Block "${blockName}" not found in the Block Bank`);
47
+ }
48
+ return data.docs[0];
49
+ }
50
+ async function fetchPreviewImageUrl(previewId) {
51
+ try {
52
+ const url = `${BANK_API_URL}/media/${previewId}`;
53
+ const response = await fetch(url);
54
+ if (!response.ok)
55
+ return null;
56
+ const data = (await response.json());
57
+ const relativePath = data.sizes?.thumbnail?.url ?? data.url ?? null;
58
+ if (!relativePath)
59
+ return null;
60
+ return `https://bank.cromatica.media${relativePath}`;
61
+ }
62
+ catch {
63
+ return null;
64
+ }
65
+ }
66
+ // ── Create component files ────────────────────────────────────────────────────
67
+ async function createComponentFiles(pascalName, componentTsx) {
68
+ const componentDir = path.join(process.cwd(), 'src', 'components', 'blocks', pascalName);
69
+ await fs.mkdir(componentDir, { recursive: true });
70
+ await fs.writeFile(path.join(componentDir, `${pascalName}.tsx`), componentTsx, 'utf-8');
71
+ await fs.writeFile(path.join(componentDir, 'index.ts'), `export { default } from './${pascalName}'\n`, 'utf-8');
72
+ }
73
+ // ── Create block schema files ─────────────────────────────────────────────────
74
+ async function createBlockFiles(pascalName, blockTs, previewImageUrl) {
75
+ const blockDir = path.join(process.cwd(), 'src', 'blocks', pascalName);
76
+ await fs.mkdir(blockDir, { recursive: true });
77
+ let finalBlockTs = blockTs;
78
+ if (previewImageUrl) {
79
+ finalBlockTs = blockTs.replace(/admin:\s*\{/, `admin: {\n images: { thumbnail: '${previewImageUrl}' },`);
80
+ }
81
+ await fs.writeFile(path.join(blockDir, `${pascalName}.block.ts`), finalBlockTs, 'utf-8');
82
+ await fs.writeFile(path.join(blockDir, 'index.ts'), `export { default } from './${pascalName}.block'\n`, 'utf-8');
83
+ }
84
+ // ── Inject block into Blocks.field.ts ─────────────────────────────────────────
85
+ async function injectIntoBlocksField(pascalName) {
86
+ const blocksFieldPath = path.join(process.cwd(), 'src', 'fields', 'Blocks', 'Blocks.field.ts');
87
+ const exists = await fileExists(blocksFieldPath);
88
+ if (!exists) {
89
+ throw new Error(`Blocks.field.ts not found at ${blocksFieldPath}`);
90
+ }
91
+ let content = await fs.readFile(blocksFieldPath, 'utf-8');
92
+ const importLine = `import ${pascalName}Block from '@/blocks/${pascalName}'`;
93
+ if (content.includes(importLine)) {
94
+ return false;
95
+ }
96
+ // Insert import after last import line
97
+ const lastImportIndex = content.lastIndexOf('import ');
98
+ const endOfLastImport = content.indexOf('\n', lastImportIndex);
99
+ content =
100
+ content.slice(0, endOfLastImport + 1) + importLine + '\n' + content.slice(endOfLastImport + 1);
101
+ // Inject into blocks array — handles multiline and existing entries
102
+ content = content.replace(/blocks:\s*\[([^\]]*)\]/s, (_, inner) => `blocks: [${inner.trimEnd()}, ${pascalName}Block]`);
103
+ content = normalizeBlankLines(content);
104
+ await fs.writeFile(blocksFieldPath, content, 'utf-8');
105
+ return true;
106
+ }
107
+ // ── Inject block into RenderBlocks.tsx ───────────────────────────────────────
108
+ async function injectIntoRenderBlocks(blockName, pascalName) {
109
+ const renderBlocksPath = path.join(process.cwd(), 'src', 'components', 'blocks', 'RenderBlocks.tsx');
110
+ const exists = await fileExists(renderBlocksPath);
111
+ if (!exists) {
112
+ throw new Error(`RenderBlocks.tsx not found at ${renderBlocksPath}`);
113
+ }
114
+ let content = await fs.readFile(renderBlocksPath, 'utf-8');
115
+ const importLine = `import ${pascalName} from '@/components/blocks/${pascalName}'`;
116
+ if (content.includes(importLine)) {
117
+ return false;
118
+ }
119
+ // Insert import after last import line
120
+ const lastImportIndex = content.lastIndexOf('import ');
121
+ const endOfLastImport = content.indexOf('\n', lastImportIndex);
122
+ content =
123
+ content.slice(0, endOfLastImport + 1) + importLine + '\n' + content.slice(endOfLastImport + 1);
124
+ // Insert extracted type before "type Layout"
125
+ const typeLine = `type ${pascalName}Type = Extract<Layout[number], { blockType: '${blockName}' }>`;
126
+ content = content.replace(/^(type Layout)/m, `${typeLine}\n\n$1`);
127
+ // Add case to switch
128
+ const caseLine = ` case '${blockName}':\n return <${pascalName} key={index} {...(block as ${pascalName}Type)} locale={locale} />`;
129
+ content = content.replace(/(default:\s*\n\s*return null)/, `${caseLine}\n $1`);
130
+ content = normalizeBlankLines(content);
131
+ await fs.writeFile(renderBlocksPath, content, 'utf-8');
132
+ return true;
133
+ }
134
+ // ── Generate Payload types ────────────────────────────────────────────────────
135
+ function generateTypes() {
136
+ const hasPnpm = (() => {
137
+ try {
138
+ execSync('pnpm --version', { stdio: 'ignore' });
139
+ return true;
140
+ }
141
+ catch {
142
+ return false;
143
+ }
144
+ })();
145
+ const cmd = hasPnpm ? 'pnpm payload generate:types' : 'npx payload generate:types';
146
+ execSync(cmd, { stdio: 'inherit', cwd: process.cwd() });
147
+ }
148
+ // Normalize blank lines
149
+ function normalizeBlankLines(content) {
150
+ // Collapse all blank lines between import block and type/export block to exactly one
151
+ content = content.replace(/((?:^import [^\n]+\n)+)\n+((?:type |export ))/m, '$1\n$2');
152
+ // Max 1 blank line between consecutive imports
153
+ content = content.replace(/^(import [^\n]+\n)\n+(?=import )/gm, '$1');
154
+ // Max 2 consecutive newlines everywhere else
155
+ content = content.replace(/\n{3,}/g, '\n\n');
156
+ return content;
157
+ }
158
+ // ── Main ──────────────────────────────────────────────────────────────────────
159
+ export async function addBlock(blockName) {
160
+ const pascalName = toPascalCase(blockName);
161
+ console.log('');
162
+ console.log(chalk.bold.blue(` cromatica`) + chalk.gray(` — add block`));
163
+ console.log(chalk.gray(` Fetching "${blockName}" from the Block Bank...\n`));
164
+ // 0. Validate project
165
+ const validateSpinner = ora(`Validating project structure`).start();
166
+ try {
167
+ await validateProject();
168
+ validateSpinner.succeed(`Valid cm-template-website project detected`);
169
+ }
170
+ catch (err) {
171
+ validateSpinner.fail(chalk.red(err.message));
172
+ process.exit(1);
173
+ }
174
+ // 1. Fetch
175
+ const spinner = ora(`Fetching ${chalk.cyan(blockName)} from Block Bank`).start();
176
+ let block;
177
+ let previewImageUrl = null;
178
+ try {
179
+ block = await fetchBlock(blockName);
180
+ if (block.preview) {
181
+ previewImageUrl = await fetchPreviewImageUrl(block.preview);
182
+ }
183
+ spinner.succeed(`Block ${chalk.cyan(blockName)} found`);
184
+ }
185
+ catch (err) {
186
+ spinner.fail(chalk.red(err.message));
187
+ process.exit(1);
188
+ }
189
+ // 2. Create component files
190
+ const componentSpinner = ora(`Creating component files`).start();
191
+ try {
192
+ await createComponentFiles(pascalName, block.files.componentTsx);
193
+ componentSpinner.succeed(`Created ${chalk.green(`src/components/blocks/${pascalName}/`)}`);
194
+ }
195
+ catch (err) {
196
+ componentSpinner.fail(chalk.red(err.message));
197
+ process.exit(1);
198
+ }
199
+ // 3. Create block schema files
200
+ const schemaSpinner = ora(`Creating Payload schema files`).start();
201
+ try {
202
+ await createBlockFiles(pascalName, block.files.blockTs, previewImageUrl);
203
+ schemaSpinner.succeed(`Created ${chalk.green(`src/blocks/${pascalName}/`)}`);
204
+ }
205
+ catch (err) {
206
+ schemaSpinner.fail(chalk.red(err.message));
207
+ process.exit(1);
208
+ }
209
+ // 4. Inject into Blocks.field.ts
210
+ const injectSpinner = ora(`Injecting block into Blocks.field.ts`).start();
211
+ try {
212
+ const injected = await injectIntoBlocksField(pascalName);
213
+ if (injected) {
214
+ injectSpinner.succeed(`Injected ${chalk.green(`${pascalName}Block`)} into Blocks.field.ts`);
215
+ }
216
+ else {
217
+ injectSpinner.warn(`${chalk.yellow(`${pascalName}Block`)} was already in Blocks.field.ts`);
218
+ }
219
+ }
220
+ catch (err) {
221
+ injectSpinner.fail(chalk.red(err.message));
222
+ process.exit(1);
223
+ }
224
+ // 5. Inject into RenderBlocks.tsx
225
+ const renderSpinner = ora(`Injecting block into RenderBlocks.tsx`).start();
226
+ try {
227
+ const injected = await injectIntoRenderBlocks(blockName, pascalName);
228
+ if (injected) {
229
+ renderSpinner.succeed(`Injected ${chalk.green(`${pascalName}`)} into RenderBlocks.tsx`);
230
+ }
231
+ else {
232
+ renderSpinner.warn(`${chalk.yellow(`${pascalName}`)} was already in RenderBlocks.tsx`);
233
+ }
234
+ }
235
+ catch (err) {
236
+ renderSpinner.fail(chalk.red(err.message));
237
+ process.exit(1);
238
+ }
239
+ // 6. Generate Payload types
240
+ const typesSpinner = ora(`Generating Payload types`).start();
241
+ try {
242
+ generateTypes();
243
+ typesSpinner.succeed(`Payload types regenerated`);
244
+ }
245
+ catch (err) {
246
+ typesSpinner.fail(chalk.red(`Failed to generate types — run "pnpm payload generate:types" manually`));
247
+ }
248
+ // Done
249
+ console.log('');
250
+ console.log(chalk.bold.green(' ✔ Block added successfully'));
251
+ console.log('');
252
+ console.log(` ${chalk.gray('Component')} src/components/blocks/${pascalName}/${pascalName}.tsx`);
253
+ console.log(` ${chalk.gray('Schema')} src/blocks/${pascalName}/${pascalName}.block.ts`);
254
+ console.log(` ${chalk.gray('Injected')} src/fields/Blocks/Blocks.field.ts`);
255
+ console.log(` ${chalk.gray('Injected')} src/components/blocks/RenderBlocks.tsx`);
256
+ console.log(` ${chalk.gray('Types')} src/payload-types.ts`);
257
+ console.log('');
258
+ }
259
+ //# sourceMappingURL=block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block.js","sourceRoot":"","sources":["../../../src/commands/add/block.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function deleteBlock(blockName: string): Promise<void>;
2
+ //# sourceMappingURL=block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../../src/commands/delete/block.ts"],"names":[],"mappings":"AAkJA,wBAAsB,WAAW,CAAC,SAAS,EAAE,MAAM,iBAgGlD"}
@@ -0,0 +1,201 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import fs from 'fs/promises';
4
+ import { execSync } from 'child_process';
5
+ import path from 'path';
6
+ // ── Utils ─────────────────────────────────────────────────────────────────────
7
+ function toPascalCase(kebab) {
8
+ return kebab
9
+ .split('-')
10
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
11
+ .join('');
12
+ }
13
+ async function fileExists(filePath) {
14
+ try {
15
+ await fs.access(filePath);
16
+ return true;
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
22
+ // ── Validate project structure ────────────────────────────────────────────────
23
+ async function validateProject() {
24
+ const requiredPaths = [
25
+ path.join(process.cwd(), 'src', 'fields', 'Blocks', 'Blocks.field.ts'),
26
+ path.join(process.cwd(), 'src', 'components', 'blocks', 'RenderBlocks.tsx'),
27
+ path.join(process.cwd(), 'src', 'blocks'),
28
+ ];
29
+ for (const requiredPath of requiredPaths) {
30
+ const exists = await fileExists(requiredPath);
31
+ if (!exists) {
32
+ throw new Error(`This command must be run inside a cm-template-website project or in a fork of itself.\n Missing: ${requiredPath}`);
33
+ }
34
+ }
35
+ }
36
+ // ── Remove component files ────────────────────────────────────────────────────
37
+ async function removeComponentFiles(pascalName) {
38
+ const componentDir = path.join(process.cwd(), 'src', 'components', 'blocks', pascalName);
39
+ const exists = await fileExists(componentDir);
40
+ if (!exists)
41
+ return false;
42
+ await fs.rm(componentDir, { recursive: true, force: true });
43
+ return true;
44
+ }
45
+ // ── Remove block schema files ─────────────────────────────────────────────────
46
+ async function removeBlockFiles(pascalName) {
47
+ const blockDir = path.join(process.cwd(), 'src', 'blocks', pascalName);
48
+ const exists = await fileExists(blockDir);
49
+ if (!exists)
50
+ return false;
51
+ await fs.rm(blockDir, { recursive: true, force: true });
52
+ return true;
53
+ }
54
+ // ── Remove block from Blocks.field.ts ────────────────────────────────────────
55
+ async function removeFromBlocksField(pascalName) {
56
+ const blocksFieldPath = path.join(process.cwd(), 'src', 'fields', 'Blocks', 'Blocks.field.ts');
57
+ const exists = await fileExists(blocksFieldPath);
58
+ if (!exists)
59
+ throw new Error(`Blocks.field.ts not found at ${blocksFieldPath}`);
60
+ let content = await fs.readFile(blocksFieldPath, 'utf-8');
61
+ const importLine = `import ${pascalName}Block from '@/blocks/${pascalName}'`;
62
+ if (!content.includes(importLine))
63
+ return false;
64
+ // Remove import line
65
+ content = content.replace(importLine + '\n', '');
66
+ // Remove from blocks array — handles ", BlockName" or "BlockName, " patterns
67
+ content = content.replace(new RegExp(`,\\s*${pascalName}Block`, 'g'), '');
68
+ content = content.replace(new RegExp(`${pascalName}Block,\\s*`, 'g'), '');
69
+ await fs.writeFile(blocksFieldPath, content, 'utf-8');
70
+ return true;
71
+ }
72
+ // ── Remove block from RenderBlocks.tsx ───────────────────────────────────────
73
+ async function removeFromRenderBlocks(blockName, pascalName) {
74
+ const renderBlocksPath = path.join(process.cwd(), 'src', 'components', 'blocks', 'RenderBlocks.tsx');
75
+ const exists = await fileExists(renderBlocksPath);
76
+ if (!exists)
77
+ throw new Error(`RenderBlocks.tsx not found at ${renderBlocksPath}`);
78
+ let content = await fs.readFile(renderBlocksPath, 'utf-8');
79
+ const importLine = `import ${pascalName} from '@/components/blocks/${pascalName}'`;
80
+ if (!content.includes(importLine))
81
+ return false;
82
+ // Remove import line
83
+ content = content.replace(importLine + '\n', '');
84
+ // Remove Extract type line
85
+ content = content.replace(new RegExp(`type ${pascalName}Type = Extract<Layout\\[number\\], \\{ blockType: '${blockName}' \\}>\\n`, 'g'), '');
86
+ // Remove case block (case + return + newline)
87
+ content = content.replace(new RegExp(`\\s*case '${blockName}':\\n\\s*return <${pascalName}[^\\n]*\\n`, 'g'), '\n');
88
+ await fs.writeFile(renderBlocksPath, content, 'utf-8');
89
+ return true;
90
+ }
91
+ // ── Generate Payload types ────────────────────────────────────────────────────
92
+ function generateTypes() {
93
+ const hasPnpm = (() => {
94
+ try {
95
+ execSync('pnpm --version', { stdio: 'ignore' });
96
+ return true;
97
+ }
98
+ catch {
99
+ return false;
100
+ }
101
+ })();
102
+ const cmd = hasPnpm ? 'pnpm payload generate:types' : 'npx payload generate:types';
103
+ execSync(cmd, { stdio: 'inherit', cwd: process.cwd() });
104
+ }
105
+ // ── Main ──────────────────────────────────────────────────────────────────────
106
+ export async function deleteBlock(blockName) {
107
+ const pascalName = toPascalCase(blockName);
108
+ console.log('');
109
+ console.log(chalk.bold.blue(` cromatica`) + chalk.gray(` — delete block`));
110
+ console.log(chalk.gray(` Removing "${blockName}" from the project...\n`));
111
+ // 0. Validate project
112
+ const validateSpinner = ora(`Validating project structure`).start();
113
+ try {
114
+ await validateProject();
115
+ validateSpinner.succeed(`Valid cm-template-website project detected`);
116
+ }
117
+ catch (err) {
118
+ validateSpinner.fail(chalk.red(err.message));
119
+ process.exit(1);
120
+ }
121
+ // 1. Remove component files
122
+ const componentSpinner = ora(`Removing component files`).start();
123
+ try {
124
+ const removed = await removeComponentFiles(pascalName);
125
+ if (removed) {
126
+ componentSpinner.succeed(`Removed ${chalk.green(`src/components/blocks/${pascalName}/`)}`);
127
+ }
128
+ else {
129
+ componentSpinner.warn(`${chalk.yellow(`src/components/blocks/${pascalName}/`)} not found, skipping`);
130
+ }
131
+ }
132
+ catch (err) {
133
+ componentSpinner.fail(chalk.red(err.message));
134
+ process.exit(1);
135
+ }
136
+ // 2. Remove block schema files
137
+ const schemaSpinner = ora(`Removing Payload schema files`).start();
138
+ try {
139
+ const removed = await removeBlockFiles(pascalName);
140
+ if (removed) {
141
+ schemaSpinner.succeed(`Removed ${chalk.green(`src/blocks/${pascalName}/`)}`);
142
+ }
143
+ else {
144
+ schemaSpinner.warn(`${chalk.yellow(`src/blocks/${pascalName}/`)} not found, skipping`);
145
+ }
146
+ }
147
+ catch (err) {
148
+ schemaSpinner.fail(chalk.red(err.message));
149
+ process.exit(1);
150
+ }
151
+ // 3. Remove from Blocks.field.ts
152
+ const injectSpinner = ora(`Removing block from Blocks.field.ts`).start();
153
+ try {
154
+ const removed = await removeFromBlocksField(pascalName);
155
+ if (removed) {
156
+ injectSpinner.succeed(`Removed ${chalk.green(`${pascalName}Block`)} from Blocks.field.ts`);
157
+ }
158
+ else {
159
+ injectSpinner.warn(`${chalk.yellow(`${pascalName}Block`)} was not found in Blocks.field.ts`);
160
+ }
161
+ }
162
+ catch (err) {
163
+ injectSpinner.fail(chalk.red(err.message));
164
+ process.exit(1);
165
+ }
166
+ // 4. Remove from RenderBlocks.tsx
167
+ const renderSpinner = ora(`Removing block from RenderBlocks.tsx`).start();
168
+ try {
169
+ const removed = await removeFromRenderBlocks(blockName, pascalName);
170
+ if (removed) {
171
+ renderSpinner.succeed(`Removed ${chalk.green(`${pascalName}`)} from RenderBlocks.tsx`);
172
+ }
173
+ else {
174
+ renderSpinner.warn(`${chalk.yellow(`${pascalName}`)} was not found in RenderBlocks.tsx`);
175
+ }
176
+ }
177
+ catch (err) {
178
+ renderSpinner.fail(chalk.red(err.message));
179
+ process.exit(1);
180
+ }
181
+ // 5. Generate Payload types
182
+ const typesSpinner = ora(`Generating Payload types`).start();
183
+ try {
184
+ generateTypes();
185
+ typesSpinner.succeed(`Payload types regenerated`);
186
+ }
187
+ catch (err) {
188
+ typesSpinner.fail(chalk.red(`Failed to generate types — run "pnpm payload generate:types" manually`));
189
+ }
190
+ // Done
191
+ console.log('');
192
+ console.log(chalk.bold.green(' ✔ Block removed successfully'));
193
+ console.log('');
194
+ console.log(` ${chalk.gray('Removed')} src/components/blocks/${pascalName}/`);
195
+ console.log(` ${chalk.gray('Removed')} src/blocks/${pascalName}/`);
196
+ console.log(` ${chalk.gray('Updated')} src/fields/Blocks/Blocks.field.ts`);
197
+ console.log(` ${chalk.gray('Updated')} src/components/blocks/RenderBlocks.tsx`);
198
+ console.log(` ${chalk.gray('Types')} src/payload-types.ts`);
199
+ console.log('');
200
+ }
201
+ //# sourceMappingURL=block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block.js","sourceRoot":"","sources":["../../../src/commands/delete/block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,GAAG,MAAM,KAAK,CAAA;AACrB,OAAO,EAAE,MAAM,aAAa,CAAA;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,iFAAiF;AAEjF,SAAS,YAAY,CAAC,KAAa;IACjC,OAAO,KAAK;SACT,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;SAC3D,IAAI,CAAC,EAAE,CAAC,CAAA;AACb,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,QAAgB;IACxC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACzB,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,iFAAiF;AAEjF,KAAK,UAAU,eAAe;IAC5B,MAAM,aAAa,GAAG;QACpB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,CAAC;QACtE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,kBAAkB,CAAC;QAC3E,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC;KAC1C,CAAA;IAED,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,YAAY,CAAC,CAAA;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,qGAAqG,YAAY,EAAE,CACpH,CAAA;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,iFAAiF;AAEjF,KAAK,UAAU,oBAAoB,CAAC,UAAkB;IACpD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;IACxF,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,YAAY,CAAC,CAAA;IAC7C,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IACzB,MAAM,EAAE,CAAC,EAAE,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IAC3D,OAAO,IAAI,CAAA;AACb,CAAC;AAED,iFAAiF;AAEjF,KAAK,UAAU,gBAAgB,CAAC,UAAkB;IAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;IACtE,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAA;IACzC,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IACzB,MAAM,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;IACvD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,gFAAgF;AAEhF,KAAK,UAAU,qBAAqB,CAAC,UAAkB;IACrD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAA;IAE9F,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,eAAe,CAAC,CAAA;IAChD,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,eAAe,EAAE,CAAC,CAAA;IAE/E,IAAI,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAA;IAEzD,MAAM,UAAU,GAAG,UAAU,UAAU,wBAAwB,UAAU,GAAG,CAAA;IAC5E,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAA;IAE/C,qBAAqB;IACrB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,GAAG,IAAI,EAAE,EAAE,CAAC,CAAA;IAEhD,6EAA6E;IAC7E,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,QAAQ,UAAU,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAA;IACzE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,GAAG,UAAU,YAAY,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAA;IAEzE,MAAM,EAAE,CAAC,SAAS,CAAC,eAAe,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACrD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,gFAAgF;AAEhF,KAAK,UAAU,sBAAsB,CAAC,SAAiB,EAAE,UAAkB;IACzE,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAChC,OAAO,CAAC,GAAG,EAAE,EACb,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,kBAAkB,CACnB,CAAA;IAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,gBAAgB,CAAC,CAAA;IACjD,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,gBAAgB,EAAE,CAAC,CAAA;IAEjF,IAAI,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAA;IAE1D,MAAM,UAAU,GAAG,UAAU,UAAU,8BAA8B,UAAU,GAAG,CAAA;IAClF,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAA;IAE/C,qBAAqB;IACrB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,GAAG,IAAI,EAAE,EAAE,CAAC,CAAA;IAEhD,2BAA2B;IAC3B,OAAO,GAAG,OAAO,CAAC,OAAO,CACvB,IAAI,MAAM,CACR,QAAQ,UAAU,sDAAsD,SAAS,WAAW,EAC5F,GAAG,CACJ,EACD,EAAE,CACH,CAAA;IAED,8CAA8C;IAC9C,OAAO,GAAG,OAAO,CAAC,OAAO,CACvB,IAAI,MAAM,CAAC,aAAa,SAAS,oBAAoB,UAAU,YAAY,EAAE,GAAG,CAAC,EACjF,IAAI,CACL,CAAA;IAED,MAAM,EAAE,CAAC,SAAS,CAAC,gBAAgB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;IACtD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,iFAAiF;AAEjF,SAAS,aAAa;IACpB,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE;QACpB,IAAI,CAAC;YACH,QAAQ,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;YAC/C,OAAO,IAAI,CAAA;QACb,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAA;QACd,CAAC;IACH,CAAC,CAAC,EAAE,CAAA;IAEJ,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,4BAA4B,CAAA;IAClF,QAAQ,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;AACzD,CAAC;AAED,iFAAiF;AAEjF,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,SAAiB;IACjD,MAAM,UAAU,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;IAE1C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAA;IAC3E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,SAAS,yBAAyB,CAAC,CAAC,CAAA;IAE1E,sBAAsB;IACtB,MAAM,eAAe,GAAG,GAAG,CAAC,8BAA8B,CAAC,CAAC,KAAK,EAAE,CAAA;IACnE,IAAI,CAAC;QACH,MAAM,eAAe,EAAE,CAAA;QACvB,eAAe,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAA;IACvE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC,CAAA;QACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,4BAA4B;IAC5B,MAAM,gBAAgB,GAAG,GAAG,CAAC,0BAA0B,CAAC,CAAC,KAAK,EAAE,CAAA;IAChE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,UAAU,CAAC,CAAA;QACtD,IAAI,OAAO,EAAE,CAAC;YACZ,gBAAgB,CAAC,OAAO,CAAC,WAAW,KAAK,CAAC,KAAK,CAAC,yBAAyB,UAAU,GAAG,CAAC,EAAE,CAAC,CAAA;QAC5F,CAAC;aAAM,CAAC;YACN,gBAAgB,CAAC,IAAI,CACnB,GAAG,KAAK,CAAC,MAAM,CAAC,yBAAyB,UAAU,GAAG,CAAC,sBAAsB,CAC9E,CAAA;QACH,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC,CAAA;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,+BAA+B;IAC/B,MAAM,aAAa,GAAG,GAAG,CAAC,+BAA+B,CAAC,CAAC,KAAK,EAAE,CAAA;IAClE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAA;QAClD,IAAI,OAAO,EAAE,CAAC;YACZ,aAAa,CAAC,OAAO,CAAC,WAAW,KAAK,CAAC,KAAK,CAAC,cAAc,UAAU,GAAG,CAAC,EAAE,CAAC,CAAA;QAC9E,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,cAAc,UAAU,GAAG,CAAC,sBAAsB,CAAC,CAAA;QACxF,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC,CAAA;QACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,iCAAiC;IACjC,MAAM,aAAa,GAAG,GAAG,CAAC,qCAAqC,CAAC,CAAC,KAAK,EAAE,CAAA;IACxE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,UAAU,CAAC,CAAA;QACvD,IAAI,OAAO,EAAE,CAAC;YACZ,aAAa,CAAC,OAAO,CAAC,WAAW,KAAK,CAAC,KAAK,CAAC,GAAG,UAAU,OAAO,CAAC,uBAAuB,CAAC,CAAA;QAC5F,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,UAAU,OAAO,CAAC,mCAAmC,CAAC,CAAA;QAC9F,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC,CAAA;QACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,kCAAkC;IAClC,MAAM,aAAa,GAAG,GAAG,CAAC,sCAAsC,CAAC,CAAC,KAAK,EAAE,CAAA;IACzE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAA;QACnE,IAAI,OAAO,EAAE,CAAC;YACZ,aAAa,CAAC,OAAO,CAAC,WAAW,KAAK,CAAC,KAAK,CAAC,GAAG,UAAU,EAAE,CAAC,wBAAwB,CAAC,CAAA;QACxF,CAAC;aAAM,CAAC;YACN,aAAa,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC,oCAAoC,CAAC,CAAA;QAC1F,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAE,GAAa,CAAC,OAAO,CAAC,CAAC,CAAA;QACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,4BAA4B;IAC5B,MAAM,YAAY,GAAG,GAAG,CAAC,0BAA0B,CAAC,CAAC,KAAK,EAAE,CAAA;IAC5D,IAAI,CAAC;QACH,aAAa,EAAE,CAAA;QACf,YAAY,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAA;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,YAAY,CAAC,IAAI,CACf,KAAK,CAAC,GAAG,CAAC,uEAAuE,CAAC,CACnF,CAAA;IACH,CAAC;IAED,OAAO;IACP,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC,CAAA;IAC/D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IACf,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,8BAA8B,UAAU,GAAG,CAAC,CAAA;IAClF,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,mBAAmB,UAAU,GAAG,CAAC,CAAA;IACvE,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,wCAAwC,CAAC,CAAA;IAC/E,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,6CAA6C,CAAC,CAAA;IACpF,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAA;IAClE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function listBlocks(): Promise<void>;
2
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAkFA,wBAAsB,UAAU,kBA6E/B"}
@@ -0,0 +1,133 @@
1
+ import chalk from 'chalk';
2
+ import ora from 'ora';
3
+ import fs from 'fs/promises';
4
+ import path from 'path';
5
+ const BANK_API_URL = 'https://bank.cromatica.media/api';
6
+ const SYSTEM_BLOCKS = ['Fallback'];
7
+ // ── Utils ─────────────────────────────────────────────────────────────────────
8
+ function toKebabCase(pascal) {
9
+ return pascal.replace(/([A-Z])/g, (_, letter, offset) => (offset > 0 ? '-' : '') + letter.toLowerCase());
10
+ }
11
+ async function fileExists(filePath) {
12
+ try {
13
+ await fs.access(filePath);
14
+ return true;
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ }
20
+ // ── Validate project structure ────────────────────────────────────────────────
21
+ async function validateProject() {
22
+ const requiredPaths = [
23
+ path.join(process.cwd(), 'src', 'fields', 'Blocks', 'Blocks.field.ts'),
24
+ path.join(process.cwd(), 'src', 'blocks'),
25
+ ];
26
+ for (const requiredPath of requiredPaths) {
27
+ const exists = await fileExists(requiredPath);
28
+ if (!exists) {
29
+ throw new Error(`This command must be run inside a cm-template-website project or in a fork of itself.\n Missing: ${requiredPath}`);
30
+ }
31
+ }
32
+ }
33
+ // ── Parse installed blocks from Blocks.field.ts ───────────────────────────────
34
+ async function getInstalledBlocks() {
35
+ const blocksFieldPath = path.join(process.cwd(), 'src', 'fields', 'Blocks', 'Blocks.field.ts');
36
+ const content = await fs.readFile(blocksFieldPath, 'utf-8');
37
+ const importRegex = /^import\s+\w+\s+from\s+'@\/blocks\/(\w+)'/gm;
38
+ const blocks = [];
39
+ let match;
40
+ while ((match = importRegex.exec(content)) !== null) {
41
+ blocks.push(match[1]); // captura el nombre de la carpeta: "Fallback", "HeroCardsGrid"
42
+ }
43
+ return blocks;
44
+ }
45
+ // ── Fetch block status from Bank API ─────────────────────────────────────────
46
+ async function fetchBlockStatus(kebabName) {
47
+ try {
48
+ const url = `${BANK_API_URL}/blocks?where[slug][equals]=${kebabName}&depth=0&limit=1`;
49
+ const response = await fetch(url);
50
+ if (!response.ok)
51
+ return null;
52
+ const data = (await response.json());
53
+ if (!data.docs.length)
54
+ return null;
55
+ return data.docs[0];
56
+ }
57
+ catch {
58
+ return null;
59
+ }
60
+ }
61
+ // ── Main ──────────────────────────────────────────────────────────────────────
62
+ export async function listBlocks() {
63
+ console.log('');
64
+ console.log(chalk.bold.blue(` cromatica`) + chalk.gray(` — list blocks`));
65
+ console.log('');
66
+ // 0. Validate project
67
+ const validateSpinner = ora(`Validating project structure`).start();
68
+ try {
69
+ await validateProject();
70
+ validateSpinner.succeed(`Valid cm-template-website project detected`);
71
+ }
72
+ catch (err) {
73
+ validateSpinner.fail(chalk.red(err.message));
74
+ process.exit(1);
75
+ }
76
+ // 1. Parse installed blocks
77
+ const installedSpinner = ora(`Reading installed blocks`).start();
78
+ let installedBlocks = [];
79
+ try {
80
+ installedBlocks = await getInstalledBlocks();
81
+ installedSpinner.succeed(`Found ${chalk.cyan(installedBlocks.length)} installed block(s)`);
82
+ }
83
+ catch (err) {
84
+ installedSpinner.fail(chalk.red(err.message));
85
+ process.exit(1);
86
+ }
87
+ if (installedBlocks.length === 0) {
88
+ console.log(chalk.gray('\n No blocks installed yet.\n'));
89
+ return;
90
+ }
91
+ // 2. Fetch status from Bank for each block
92
+ console.log('');
93
+ const fetchSpinner = ora(`Checking block status on Bank`).start();
94
+ const results = await Promise.all(installedBlocks.map(async (pascalName) => {
95
+ const kebabName = toKebabCase(pascalName);
96
+ const bankData = await fetchBlockStatus(kebabName);
97
+ return { pascalName, kebabName, bankData };
98
+ }));
99
+ fetchSpinner.succeed(`Block status fetched`);
100
+ console.log('');
101
+ // 3. Print results
102
+ const labelCol = 28;
103
+ console.log(chalk.gray(` ${'Block'.padEnd(labelCol)}${'Slug'.padEnd(labelCol)}Status`));
104
+ console.log(chalk.gray(` ${'─'.repeat(labelCol + labelCol + 10)}`));
105
+ for (const { pascalName, kebabName, bankData } of results) {
106
+ const isSystem = SYSTEM_BLOCKS.includes(pascalName);
107
+ const label = isSystem
108
+ ? chalk.gray(pascalName.padEnd(labelCol))
109
+ : chalk.white(pascalName.padEnd(labelCol));
110
+ const slug = isSystem
111
+ ? chalk.gray(kebabName.padEnd(labelCol))
112
+ : chalk.cyan(kebabName.padEnd(labelCol));
113
+ let status;
114
+ if (isSystem) {
115
+ status = chalk.gray('system');
116
+ }
117
+ else if (!bankData) {
118
+ status = chalk.yellow('not found in Bank');
119
+ }
120
+ else if (bankData.status === 'stable') {
121
+ status = chalk.green('stable');
122
+ }
123
+ else if (bankData.status === 'beta') {
124
+ status = chalk.yellow('beta');
125
+ }
126
+ else {
127
+ status = chalk.gray(bankData.status);
128
+ }
129
+ console.log(` ${label}${slug}${status}`);
130
+ }
131
+ console.log('');
132
+ }
133
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ import { program } from 'commander';
3
+ import chalk from 'chalk';
4
+ import { addBlock } from './commands/add/block.js';
5
+ import { deleteBlock } from './commands/delete/block.js';
6
+ import { listBlocks } from './commands/list.js';
7
+ program
8
+ .name('cromatica')
9
+ .description('Official CLI toolkit for Cromatica Media projects')
10
+ .version('0.1.0');
11
+ program
12
+ .command('list')
13
+ .description('List installed blocks and their status')
14
+ .action(() => {
15
+ listBlocks();
16
+ });
17
+ program
18
+ .command('add')
19
+ .argument('<subcommand>', 'Subcommand to run (block)')
20
+ .argument('<name>', 'Name of the resource to add')
21
+ .description('Add a resource from the Block Bank')
22
+ .action((subcommand, name) => {
23
+ if (subcommand === 'block') {
24
+ addBlock(name);
25
+ }
26
+ else {
27
+ console.log(chalk.red(` Unknown subcommand: ${subcommand}`));
28
+ process.exit(1);
29
+ }
30
+ });
31
+ program
32
+ .command('delete')
33
+ .argument('<subcommand>', 'Subcommand to run (block)')
34
+ .argument('<name>', 'Name of the resource to delete')
35
+ .description('Delete a block from the project')
36
+ .action((subcommand, name) => {
37
+ if (subcommand === 'block') {
38
+ deleteBlock(name);
39
+ }
40
+ else {
41
+ console.log(chalk.red(` Unknown subcommand: ${subcommand}`));
42
+ process.exit(1);
43
+ }
44
+ });
45
+ program.parse();
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAE/C,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,mDAAmD,CAAC;KAChE,OAAO,CAAC,OAAO,CAAC,CAAA;AAEnB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,wCAAwC,CAAC;KACrD,MAAM,CAAC,GAAG,EAAE;IACX,UAAU,EAAE,CAAA;AACd,CAAC,CAAC,CAAA;AACJ,OAAO;KACJ,OAAO,CAAC,KAAK,CAAC;KACd,QAAQ,CAAC,cAAc,EAAE,2BAA2B,CAAC;KACrD,QAAQ,CAAC,QAAQ,EAAE,6BAA6B,CAAC;KACjD,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,CAAC,UAAkB,EAAE,IAAY,EAAE,EAAE;IAC3C,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC,CAAA;IAChB,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,UAAU,EAAE,CAAC,CAAC,CAAA;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC,CAAC,CAAA;AAEJ,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,QAAQ,CAAC,cAAc,EAAE,2BAA2B,CAAC;KACrD,QAAQ,CAAC,QAAQ,EAAE,gCAAgC,CAAC;KACpD,WAAW,CAAC,iCAAiC,CAAC;KAC9C,MAAM,CAAC,CAAC,UAAkB,EAAE,IAAY,EAAE,EAAE;IAC3C,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QAC3B,WAAW,CAAC,IAAI,CAAC,CAAA;IACnB,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,UAAU,EAAE,CAAC,CAAC,CAAA;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC,CAAC,CAAA;AAEJ,OAAO,CAAC,KAAK,EAAE,CAAA"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "cromatica-cli",
3
+ "version": "0.1.0",
4
+ "description": "Official CLI toolkit for Cromatica Media projects. Fetch and scaffold blocks from the Cromatica Block Bank into your cm-template-website project.",
5
+ "author": "Leonardo Risco",
6
+ "type": "module",
7
+ "bin": {
8
+ "cromatica": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "start": "node dist/index.js",
14
+ "format": "prettier --write ."
15
+ },
16
+ "keywords": [
17
+ "cromatica",
18
+ "cli",
19
+ "blocks",
20
+ "payload",
21
+ "nextjs",
22
+ "scaffold"
23
+ ],
24
+ "license": "MIT",
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "https://github.com/cromatica-media/cm-cli.git"
28
+ },
29
+ "homepage": "https://bank.cromatica.media",
30
+ "dependencies": {
31
+ "chalk": "^5.3.0",
32
+ "commander": "^12.1.0",
33
+ "ora": "^8.1.1"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^22.0.0",
37
+ "prettier": "^3.8.3",
38
+ "typescript": "^5.5.0"
39
+ },
40
+ "engines": {
41
+ "node": ">=18.0.0"
42
+ },
43
+ "files": [
44
+ "dist"
45
+ ],
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "main": "./dist/index.js",
50
+ "exports": {
51
+ ".": "./dist/index.js"
52
+ },
53
+ "preferGlobal": true,
54
+ "bugs": {
55
+ "url": "https://github.com/cromatica-media/cm-cli/issues"
56
+ },
57
+ "funding": {
58
+ "type": "other",
59
+ "url": "https://cromatica.media"
60
+ }
61
+ }