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.
- package/package.json +5 -2
- package/src/cli.js +39 -3
- package/src/commands/shop.js +59 -0
- package/src/commands/warehouse.js +73 -0
- package/templates/blocks/DD-BookCall/Component.tsx +535 -534
- package/templates/blocks/DD-CardTemplate01/Component.tsx +140 -139
- package/templates/blocks/DD-Carousel-A/Component.tsx +1 -1
- package/templates/blocks/DD-Carousel-B/Component.tsx +1 -1
- package/templates/blocks/DD-Chip/Component.tsx +14 -14
- package/templates/blocks/DD-ComparisonTable/Component.tsx +1 -1
- package/templates/blocks/DD-Contact/Component.tsx +8 -7
- package/templates/blocks/DD-Counter/Component.tsx +10 -10
- package/templates/blocks/DD-FeatCat/Component.tsx +1 -1
- package/templates/blocks/DD-FeatStrip/Component.tsx +1 -1
- package/templates/blocks/DD-Hero/Component.tsx +297 -320
- package/templates/blocks/DD-HorizontalScroll/Component.tsx +936 -938
- package/templates/blocks/DD-IframeMedia/Component.tsx +14 -10
- package/templates/blocks/DD-MasonaryMedia/Component.tsx +8 -10
- package/templates/blocks/DD-Pricing/Component.tsx +369 -372
- package/templates/blocks/DD-Process/Component.tsx +147 -149
- package/templates/blocks/DD-Progress/Component.tsx +156 -141
- package/templates/blocks/DD-ProjSlider/config.ts +2 -2
- package/templates/blocks/DD-Section/Component.tsx +1 -1
- package/templates/blocks/DD-Services/Component.tsx +1 -1
- package/templates/blocks/DD-ShowcaseGrid/Component.tsx +13 -13
- package/templates/blocks/DD-Slider-A/Component.tsx +237 -237
- package/templates/blocks/DD-StackCards/Component.tsx +473 -473
- package/templates/blocks/DD-Team/Component.tsx +1 -1
- package/templates/blocks/DD-TechStack/Component.tsx +22 -28
- package/templates/blocks/DD-Testimonials/Component.tsx +35 -43
- package/templates/blocks/DD-TextMarq/Component.tsx +157 -157
- package/templates/blocks/DD-Thanks/Component.tsx +501 -500
- package/templates/blocks/DD-Work/Component.tsx +4 -4
- package/templates/blocks/DD-Work-B/Component.tsx +1 -1
- package/templates/blocks/DDHG-CTASection2/Component.tsx +6 -6
- package/templates/blocks/DDHG-HighlightArc/Component.tsx +243 -243
- package/templates/blocks/DDHG-LogoMarquee/Component.tsx +143 -93
- package/templates/blocks/DDHG-LogoMarquee/config.ts +154 -66
- package/templates/blocks/DDHG-NavCodeGrid/Component.tsx +227 -213
- package/templates/blocks/DDHG-ProcessSec/Component.tsx +38 -39
- package/templates/blocks/DDHG-ServiceDetails/Component.tsx +11 -11
- package/templates/blocks/DDHG-ServiceDetails/ServiceDetailCard.tsx +24 -28
- package/templates/blocks/DDHG-ServiceHero/Component.tsx +1 -1
- package/templates/blocks/DDHG-ServiceOverview/Component.tsx +23 -23
- package/templates/blocks/DDHG-StatsFAQ/Component.tsx +40 -40
- 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.
|
|
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
|
+
}
|