blocks-dusted 0.1.11 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/package.json +5 -2
  2. package/src/cli.js +39 -3
  3. package/src/commands/shop.js +59 -0
  4. package/src/commands/warehouse.js +73 -0
  5. package/templates/blocks/DD-BookCall/Component.tsx +535 -534
  6. package/templates/blocks/DD-CardTemplate01/Component.tsx +140 -139
  7. package/templates/blocks/DD-Carousel-A/Component.tsx +1 -1
  8. package/templates/blocks/DD-Carousel-B/Component.tsx +1 -1
  9. package/templates/blocks/DD-Chip/Component.tsx +14 -14
  10. package/templates/blocks/DD-ComparisonTable/Component.tsx +1 -1
  11. package/templates/blocks/DD-Contact/Component.tsx +8 -7
  12. package/templates/blocks/DD-Counter/Component.tsx +10 -10
  13. package/templates/blocks/DD-FeatCat/Component.tsx +1 -1
  14. package/templates/blocks/DD-FeatStrip/Component.tsx +1 -1
  15. package/templates/blocks/DD-Hero/Component.tsx +297 -320
  16. package/templates/blocks/DD-HorizontalScroll/Component.tsx +936 -938
  17. package/templates/blocks/DD-IframeMedia/Component.tsx +14 -10
  18. package/templates/blocks/DD-MasonaryMedia/Component.tsx +8 -10
  19. package/templates/blocks/DD-Pricing/Component.tsx +369 -372
  20. package/templates/blocks/DD-Process/Component.tsx +147 -149
  21. package/templates/blocks/DD-Progress/Component.tsx +156 -141
  22. package/templates/blocks/DD-ProjSlider/config.ts +2 -2
  23. package/templates/blocks/DD-Section/Component.tsx +1 -1
  24. package/templates/blocks/DD-Services/Component.tsx +1 -1
  25. package/templates/blocks/DD-ShowcaseGrid/Component.tsx +13 -13
  26. package/templates/blocks/DD-Slider-A/Component.tsx +237 -237
  27. package/templates/blocks/DD-StackCards/Component.tsx +473 -473
  28. package/templates/blocks/DD-Team/Component.tsx +1 -1
  29. package/templates/blocks/DD-TechStack/Component.tsx +22 -28
  30. package/templates/blocks/DD-Testimonials/Component.tsx +35 -43
  31. package/templates/blocks/DD-TextMarq/Component.tsx +157 -157
  32. package/templates/blocks/DD-Thanks/Component.tsx +501 -500
  33. package/templates/blocks/DD-Work/Component.tsx +4 -4
  34. package/templates/blocks/DD-Work-B/Component.tsx +1 -1
  35. package/templates/blocks/DDHG-CTASection2/Component.tsx +6 -6
  36. package/templates/blocks/DDHG-HighlightArc/Component.tsx +243 -243
  37. package/templates/blocks/DDHG-LogoMarquee/Component.tsx +143 -93
  38. package/templates/blocks/DDHG-LogoMarquee/config.ts +154 -66
  39. package/templates/blocks/DDHG-NavCodeGrid/Component.tsx +227 -213
  40. package/templates/blocks/DDHG-ProcessSec/Component.tsx +38 -39
  41. package/templates/blocks/DDHG-ServiceDetails/Component.tsx +11 -11
  42. package/templates/blocks/DDHG-ServiceDetails/ServiceDetailCard.tsx +24 -28
  43. package/templates/blocks/DDHG-ServiceHero/Component.tsx +1 -1
  44. package/templates/blocks/DDHG-ServiceOverview/Component.tsx +23 -23
  45. package/templates/blocks/DDHG-StatsFAQ/Component.tsx +40 -40
  46. package/templates/blocks/DDHG-TeamCards/Component.tsx +169 -131
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blocks-dusted",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "description": "Manifest-driven CLI for installing reusable Payload CMS blocks.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,7 +23,10 @@
23
23
  "test:add": "node ./bin/index.js add DD-Hero --dry-run",
24
24
  "test:list": "node ./bin/index.js list",
25
25
  "test:doctor": "node ./bin/index.js doctor",
26
- "convert:studio": "node ./scripts/convertStudioBlock.mjs"
26
+ "convert:studio": "node ./scripts/convertStudioBlock.mjs",
27
+ "warehouse:sync-lab": "node ./bin/index.js warehouse sync-lab",
28
+ "warehouse:sync-lab:dry-run": "node ./bin/index.js warehouse sync-lab --dry-run",
29
+ "shop:pull-sandbox:dry-run": "node ./bin/index.js shop pull-sandbox --dry-run"
27
30
  },
28
31
  "engines": {
29
32
  "node": ">=20"
package/src/cli.js CHANGED
@@ -1,9 +1,11 @@
1
- import { readFile } from 'node:fs/promises'
1
+ import { readFile } from 'node:fs/promises'
2
2
  import { resolve } from 'node:path'
3
3
  import { addTemplate } from './commands/add.js'
4
4
  import { doctor } from './commands/doctor.js'
5
5
  import { addHeader } from './commands/header.js'
6
- import { list } from './commands/list.js'
6
+ import { list } from './commands/list.js'
7
+ import { pullSandboxFromWarehouse } from './commands/shop.js'
8
+ import { syncLabToWarehouse } from './commands/warehouse.js'
7
9
  import { error, info } from './utils/logger.js'
8
10
  import { packageRoot } from './utils/paths.js'
9
11
 
@@ -14,7 +16,9 @@ function printHelp() {
14
16
  info(' blocks-dusted list')
15
17
  info(' blocks-dusted doctor [--cwd <path>]')
16
18
  info(' blocks-dusted add <TemplateName> [--dry-run] [--no-register] [--cwd <path>]')
17
- info(' blocks-dusted header add <HeaderName> [--dry-run] [--cwd <path>]')
19
+ info(' blocks-dusted header add <HeaderName> [--dry-run] [--cwd <path>]')
20
+ info(' blocks-dusted warehouse sync-lab [--dry-run] [--lab <path>]')
21
+ info(' blocks-dusted shop pull-sandbox [--dry-run] [--warehouse <path>] [--cwd <shop path>]')
18
22
  info(' blocks-dusted --version')
19
23
  }
20
24
 
@@ -57,11 +61,42 @@ export async function runCli(args, options = {}) {
57
61
  })
58
62
  }
59
63
 
64
+ if (command === 'warehouse') {
65
+ const [subcommand] = rest
66
+ if (subcommand !== 'sync-lab') throw new Error('Usage: blocks-dusted warehouse sync-lab [--dry-run] [--lab <path>]')
67
+ return syncLabToWarehouse({
68
+ labRoot: optionValue(rest, '--lab'),
69
+ dryRun: rest.includes('--dry-run'),
70
+ })
71
+ }
72
+
73
+ if (command === 'shop') {
74
+ const [subcommand] = rest
75
+ if (subcommand !== 'pull-sandbox') throw new Error('Usage: blocks-dusted shop pull-sandbox [--dry-run] [--warehouse <path>] [--cwd <shop path>]')
76
+ return pullSandboxFromWarehouse({
77
+ targetDirectory,
78
+ warehouseRoot: optionValue(rest, '--warehouse'),
79
+ dryRun: rest.includes('--dry-run'),
80
+ })
81
+ }
82
+
60
83
  error(`Unknown command: ${command}`)
61
84
  printHelp()
62
85
  process.exitCode = 1
63
86
  }
64
87
 
88
+ function optionValue(args, name) {
89
+ for (let index = 0; index < args.length; index += 1) {
90
+ const argument = args[index]
91
+ if (argument === name) {
92
+ const value = args[index + 1]
93
+ if (!value) throw new Error(`${name} requires a path`)
94
+ return value
95
+ }
96
+ if (argument.startsWith(`${name}=`)) return argument.slice(name.length + 1)
97
+ }
98
+ return undefined
99
+ }
65
100
  function parseGlobalOptions(args, originalDirectory) {
66
101
  const commandArgs = []
67
102
  let targetDirectory = originalDirectory
@@ -90,3 +125,4 @@ async function packageVersion() {
90
125
  return packageJson.version
91
126
  }
92
127
 
128
+
@@ -0,0 +1,59 @@
1
+ import { mkdir, readdir, readFile, stat, copyFile } from 'node:fs/promises'
2
+ import { dirname, join, relative, resolve } from 'node:path'
3
+ import { packageRoot } from '../utils/paths.js'
4
+
5
+ const defaultSandboxBlocks = join('src', 'sandbox', 'products', 'DDBlockProductSandboxes', 'blocks')
6
+ const excludedTemplateFiles = new Set(['config.ts', 'manifest.json', 'README.md'])
7
+
8
+ export async function pullSandboxFromWarehouse({ targetDirectory = process.cwd(), warehouseRoot = packageRoot, dryRun = false } = {}) {
9
+ const sourceRoot = join(resolve(warehouseRoot), 'templates', 'blocks')
10
+ const targetRoot = join(resolve(targetDirectory), defaultSandboxBlocks)
11
+ const blockEntries = await readdir(sourceRoot, { withFileTypes: true })
12
+ const results = []
13
+ const errors = []
14
+
15
+ for (const entry of blockEntries.sort((a, b) => a.name.localeCompare(b.name))) {
16
+ if (!entry.isDirectory()) continue
17
+ const blockName = entry.name
18
+ const manifestPath = join(sourceRoot, blockName, 'manifest.json')
19
+ let manifest
20
+ try {
21
+ manifest = JSON.parse(await readFile(manifestPath, 'utf8'))
22
+ } catch (error) {
23
+ errors.push(`${blockName}: unable to read manifest: ${error.message}`)
24
+ continue
25
+ }
26
+
27
+ for (const file of manifest.files ?? []) {
28
+ const from = String(file.from ?? '')
29
+ if (!from || excludedTemplateFiles.has(from.replace(/\\/g, '/'))) continue
30
+ const source = join(sourceRoot, blockName, from)
31
+ const target = join(targetRoot, blockName, from)
32
+ try {
33
+ const sourceStat = await stat(source)
34
+ if (!sourceStat.isFile()) {
35
+ errors.push(`${blockName}: source is not a file: ${relative(resolve(warehouseRoot), source)}`)
36
+ continue
37
+ }
38
+ results.push({ blockName, from: relative(resolve(warehouseRoot), source), to: relative(resolve(targetDirectory), target) })
39
+ if (!dryRun) {
40
+ await mkdir(dirname(target), { recursive: true })
41
+ await copyFile(source, target)
42
+ }
43
+ } catch (error) {
44
+ errors.push(`${blockName}: missing warehouse runtime file ${from}: ${error.message}`)
45
+ }
46
+ }
47
+ }
48
+
49
+ console.log(`Warehouse to Shop sandbox pull${dryRun ? ' dry run' : ''}`)
50
+ console.log(`Target: ${targetRoot}`)
51
+ console.log(`Files ${dryRun ? 'planned' : 'copied'}: ${results.length}`)
52
+ for (const row of results) console.log(`- ${row.blockName}: ${row.from} -> ${row.to}`)
53
+ if (errors.length > 0) {
54
+ console.error('Errors:')
55
+ for (const error of errors) console.error(`- ${error}`)
56
+ throw new Error(`Warehouse to Shop pull failed with ${errors.length} error(s).`)
57
+ }
58
+ return { results, errors }
59
+ }
@@ -0,0 +1,73 @@
1
+ import { mkdir, readdir, readFile, stat, copyFile } from 'node:fs/promises'
2
+ import { dirname, join, relative, resolve } from 'node:path'
3
+ import { fileURLToPath } from 'node:url'
4
+
5
+ const packageRoot = resolve(fileURLToPath(new URL('../..', import.meta.url)))
6
+ const defaultLabRoot = resolve(packageRoot, '..', 'CLI-TestGround', 'cli-testground')
7
+ const blockTemplateRoot = join(packageRoot, 'templates', 'blocks')
8
+
9
+ export async function syncLabToWarehouse({ labRoot = defaultLabRoot, dryRun = false } = {}) {
10
+ const labBlocksRoot = join(resolve(labRoot), 'src', 'blocks')
11
+ const manifests = await readBlockManifests(blockTemplateRoot)
12
+ const results = []
13
+ const errors = []
14
+
15
+ for (const { blockName, manifest, manifestDir } of manifests) {
16
+ for (const file of manifest.files ?? []) {
17
+ const from = String(file.from ?? '')
18
+ if (!from) continue
19
+ const source = join(labBlocksRoot, blockName, from)
20
+ const target = join(manifestDir, from)
21
+ try {
22
+ const sourceStat = await stat(source)
23
+ if (!sourceStat.isFile()) {
24
+ errors.push(`${blockName}: source is not a file: ${relative(resolve(labRoot), source)}`)
25
+ continue
26
+ }
27
+ results.push({ blockName, from: relative(resolve(labRoot), source), to: relative(packageRoot, target) })
28
+ if (!dryRun) {
29
+ await mkdir(dirname(target), { recursive: true })
30
+ await copyFile(source, target)
31
+ }
32
+ } catch (error) {
33
+ errors.push(`${blockName}: missing lab file for manifest entry ${from}: ${error.message}`)
34
+ }
35
+ }
36
+ }
37
+
38
+ printSyncResults({ title: 'Lab to Warehouse sync', dryRun, results, errors })
39
+ if (errors.length > 0) {
40
+ const error = new Error(`Lab to Warehouse sync failed with ${errors.length} error(s).`)
41
+ error.results = { results, errors }
42
+ throw error
43
+ }
44
+ return { results, errors }
45
+ }
46
+
47
+ async function readBlockManifests(root) {
48
+ const entries = await readdir(root, { withFileTypes: true })
49
+ const manifests = []
50
+ for (const entry of entries) {
51
+ if (!entry.isDirectory()) continue
52
+ const manifestDir = join(root, entry.name)
53
+ const manifestPath = join(manifestDir, 'manifest.json')
54
+ try {
55
+ const manifest = JSON.parse(await readFile(manifestPath, 'utf8'))
56
+ manifests.push({ blockName: entry.name, manifest, manifestDir })
57
+ } catch (error) {
58
+ throw new Error(`Unable to read ${relative(packageRoot, manifestPath)}: ${error.message}`)
59
+ }
60
+ }
61
+ manifests.sort((a, b) => a.blockName.localeCompare(b.blockName))
62
+ return manifests
63
+ }
64
+
65
+ function printSyncResults({ title, dryRun, results, errors }) {
66
+ console.log(`${title}${dryRun ? ' dry run' : ''}`)
67
+ console.log(`Files ${dryRun ? 'planned' : 'copied'}: ${results.length}`)
68
+ for (const row of results) console.log(`- ${row.blockName}: ${row.from} -> ${row.to}`)
69
+ if (errors.length > 0) {
70
+ console.error('Errors:')
71
+ for (const error of errors) console.error(`- ${error}`)
72
+ }
73
+ }