blocks-dusted 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.
Files changed (102) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +68 -0
  3. package/bin/index.js +8 -0
  4. package/package.json +40 -0
  5. package/src/cli.js +79 -0
  6. package/src/commands/add.js +327 -0
  7. package/src/commands/doctor.js +21 -0
  8. package/src/commands/list.js +18 -0
  9. package/src/installers/checkRequirements.js +101 -0
  10. package/src/installers/copyTemplateFiles.js +79 -0
  11. package/src/installers/installDependencies.js +69 -0
  12. package/src/installers/patchPayloadBlocksArray.js +122 -0
  13. package/src/installers/patchRenderBlocks.js +110 -0
  14. package/src/installers/runGenerators.js +3 -0
  15. package/src/installers/writeInstalledBlockReadme.js +117 -0
  16. package/src/registry/listTemplates.js +17 -0
  17. package/src/registry/loadTemplateManifest.js +20 -0
  18. package/src/registry/validateTemplateManifest.js +69 -0
  19. package/src/utils/logger.js +8 -0
  20. package/src/utils/packageManager.js +42 -0
  21. package/src/utils/paths.js +7 -0
  22. package/src/utils/project.js +122 -0
  23. package/src/utils/strings.js +7 -0
  24. package/templates/blocks/DD-BookCall/Component.tsx +573 -0
  25. package/templates/blocks/DD-BookCall/config.ts +239 -0
  26. package/templates/blocks/DD-BookCall/manifest.json +112 -0
  27. package/templates/blocks/DD-CardTemplate01/Component.tsx +144 -0
  28. package/templates/blocks/DD-CardTemplate01/config.ts +106 -0
  29. package/templates/blocks/DD-CardTemplate01/manifest.json +84 -0
  30. package/templates/blocks/DD-Carousel-A/Component.tsx +266 -0
  31. package/templates/blocks/DD-Carousel-A/config.ts +163 -0
  32. package/templates/blocks/DD-Carousel-A/manifest.json +86 -0
  33. package/templates/blocks/DD-Carousel-B/Component.tsx +432 -0
  34. package/templates/blocks/DD-Carousel-B/config.ts +176 -0
  35. package/templates/blocks/DD-Carousel-B/manifest.json +86 -0
  36. package/templates/blocks/DD-ComparisonTable/Component.tsx +272 -0
  37. package/templates/blocks/DD-ComparisonTable/config.ts +105 -0
  38. package/templates/blocks/DD-ComparisonTable/manifest.json +78 -0
  39. package/templates/blocks/DD-Contact/Component.tsx +439 -0
  40. package/templates/blocks/DD-Contact/config.ts +217 -0
  41. package/templates/blocks/DD-Contact/manifest.json +107 -0
  42. package/templates/blocks/DD-FeatCat/Component.tsx +361 -0
  43. package/templates/blocks/DD-FeatCat/config.ts +204 -0
  44. package/templates/blocks/DD-FeatCat/manifest.json +87 -0
  45. package/templates/blocks/DD-FeatStrip/Component.tsx +615 -0
  46. package/templates/blocks/DD-FeatStrip/config.ts +134 -0
  47. package/templates/blocks/DD-FeatStrip/manifest.json +82 -0
  48. package/templates/blocks/DD-Hero/Component.tsx +317 -0
  49. package/templates/blocks/DD-Hero/config.ts +267 -0
  50. package/templates/blocks/DD-Hero/manifest.json +92 -0
  51. package/templates/blocks/DD-HorizontalScroll/Component.tsx +995 -0
  52. package/templates/blocks/DD-HorizontalScroll/config.ts +231 -0
  53. package/templates/blocks/DD-HorizontalScroll/manifest.json +85 -0
  54. package/templates/blocks/DD-MasonaryMedia/Component.tsx +571 -0
  55. package/templates/blocks/DD-MasonaryMedia/config.ts +390 -0
  56. package/templates/blocks/DD-MasonaryMedia/manifest.json +101 -0
  57. package/templates/blocks/DD-MasonaryMedia/vendor.d.ts +2 -0
  58. package/templates/blocks/DD-Pricing/Component.tsx +380 -0
  59. package/templates/blocks/DD-Pricing/config.ts +215 -0
  60. package/templates/blocks/DD-Pricing/manifest.json +78 -0
  61. package/templates/blocks/DD-Process/Component.tsx +155 -0
  62. package/templates/blocks/DD-Process/config.ts +150 -0
  63. package/templates/blocks/DD-Process/manifest.json +82 -0
  64. package/templates/blocks/DD-Section/Component.tsx +327 -0
  65. package/templates/blocks/DD-Section/config.ts +214 -0
  66. package/templates/blocks/DD-Section/manifest.json +85 -0
  67. package/templates/blocks/DD-Services/Component.tsx +188 -0
  68. package/templates/blocks/DD-Services/config.ts +149 -0
  69. package/templates/blocks/DD-Services/manifest.json +95 -0
  70. package/templates/blocks/DD-ShowcaseGrid/Component.tsx +317 -0
  71. package/templates/blocks/DD-ShowcaseGrid/config.ts +197 -0
  72. package/templates/blocks/DD-ShowcaseGrid/manifest.json +80 -0
  73. package/templates/blocks/DD-Slider-A/Component.tsx +252 -0
  74. package/templates/blocks/DD-Slider-A/config.ts +118 -0
  75. package/templates/blocks/DD-Slider-A/manifest.json +86 -0
  76. package/templates/blocks/DD-StackCards/Component.tsx +496 -0
  77. package/templates/blocks/DD-StackCards/config.ts +399 -0
  78. package/templates/blocks/DD-StackCards/manifest.json +87 -0
  79. package/templates/blocks/DD-Team/Component.tsx +265 -0
  80. package/templates/blocks/DD-Team/config.ts +173 -0
  81. package/templates/blocks/DD-Team/manifest.json +82 -0
  82. package/templates/blocks/DD-TechStack/Component.tsx +189 -0
  83. package/templates/blocks/DD-TechStack/config.ts +153 -0
  84. package/templates/blocks/DD-TechStack/manifest.json +118 -0
  85. package/templates/blocks/DD-Testimonials/Component.tsx +147 -0
  86. package/templates/blocks/DD-Testimonials/config.ts +120 -0
  87. package/templates/blocks/DD-Testimonials/manifest.json +87 -0
  88. package/templates/blocks/DD-Work/Component.tsx +328 -0
  89. package/templates/blocks/DD-Work/config.ts +165 -0
  90. package/templates/blocks/DD-Work/manifest.json +87 -0
  91. package/templates/blocks/DD-Work-B/Component.tsx +320 -0
  92. package/templates/blocks/DD-Work-B/config.ts +165 -0
  93. package/templates/blocks/DD-Work-B/manifest.json +75 -0
  94. package/templates/shared/components/ui/anims/fade.tsx +83 -0
  95. package/templates/shared/components/ui/button.tsx +233 -0
  96. package/templates/shared/components/ui/input.tsx +41 -0
  97. package/templates/shared/fields/lucide-icon-picker/Cell.tsx +24 -0
  98. package/templates/shared/fields/lucide-icon-picker/README.md +160 -0
  99. package/templates/shared/fields/lucide-icon-picker/field.ts +40 -0
  100. package/templates/shared/fields/lucide-icon-picker/index.tsx +203 -0
  101. package/templates/shared/utilities/canUseDOM.ts +1 -0
  102. package/templates/shared/utilities/getURL.ts +31 -0
@@ -0,0 +1,122 @@
1
+ import { access, readFile } from 'node:fs/promises'
2
+ import { constants } from 'node:fs'
3
+ import { join, resolve } from 'node:path'
4
+ import { detectPackageManager } from './packageManager.js'
5
+ import { packageRoot } from './paths.js'
6
+
7
+ export const PAYLOAD_CONFIG_FILES = [
8
+ 'src/payload.config.ts',
9
+ 'payload.config.ts',
10
+ 'src/payload.config.js',
11
+ 'payload.config.js',
12
+ 'src/payload.config.mjs',
13
+ 'payload.config.mjs',
14
+ ]
15
+
16
+ const PAYLOAD_SOURCE_MARKERS = [
17
+ ['src', 'blocks'],
18
+ ['src', 'collections'],
19
+ ['src', 'app'],
20
+ ]
21
+
22
+ export async function inspectProject(targetDirectory) {
23
+ const resolvedTarget = resolve(targetDirectory)
24
+ const hasPackageJson = await fileExists(join(resolvedTarget, 'package.json'))
25
+ const packageJson = hasPackageJson ? await readJson(join(resolvedTarget, 'package.json')) : {}
26
+ const hasPayloadDependency = Boolean(
27
+ packageJson.dependencies?.payload ||
28
+ packageJson.devDependencies?.payload ||
29
+ packageJson.peerDependencies?.payload,
30
+ )
31
+ const hasBlocksDirectory = await fileExists(join(resolvedTarget, 'src', 'blocks'))
32
+ const hasSupportedSourceStructure = await hasAnyMarker(resolvedTarget, PAYLOAD_SOURCE_MARKERS)
33
+ let payloadConfigPath = null
34
+
35
+ for (const candidate of PAYLOAD_CONFIG_FILES) {
36
+ if (await fileExists(join(resolvedTarget, candidate))) {
37
+ payloadConfigPath = candidate
38
+ break
39
+ }
40
+ }
41
+
42
+ const isWritable = await canWrite(resolvedTarget)
43
+ const isCliRepository = resolve(resolvedTarget) === resolve(packageRoot)
44
+
45
+ return {
46
+ targetDirectory: resolvedTarget,
47
+ hasPackageJson,
48
+ hasPayloadDependency,
49
+ hasBlocksDirectory,
50
+ hasSupportedSourceStructure,
51
+ payloadConfigPath,
52
+ packageManager: await detectPackageManager(resolvedTarget),
53
+ isWritable,
54
+ isCliRepository,
55
+ isPayloadProject:
56
+ hasPackageJson && hasPayloadDependency && hasSupportedSourceStructure && payloadConfigPath !== null,
57
+ }
58
+ }
59
+
60
+ export async function validateTargetProject(targetDirectory) {
61
+ const project = await inspectProject(targetDirectory)
62
+ const failures = []
63
+
64
+ if (!(await directoryExists(project.targetDirectory))) failures.push('Target directory does not exist.')
65
+ if (!project.hasPackageJson) failures.push('package.json was not found.')
66
+ if (!project.hasPayloadDependency) failures.push('package.json must declare payload in dependencies, devDependencies, or peerDependencies.')
67
+ if (!project.hasSupportedSourceStructure) failures.push('No supported Payload source structure was found under src/.')
68
+ if (!project.payloadConfigPath) failures.push('No supported Payload config file was found.')
69
+ if (!project.isWritable) failures.push('Target directory is not writable.')
70
+ if (project.isCliRepository) failures.push('Refusing to install into the blocks-dusted source repository.')
71
+
72
+ if (failures.length > 0) {
73
+ const message = [`Invalid Payload target: ${project.targetDirectory}`, ...failures.map((failure) => `- ${failure}`)].join('\n')
74
+ const error = new Error(message)
75
+ error.project = project
76
+ throw error
77
+ }
78
+
79
+ return project
80
+ }
81
+
82
+ export async function fileExists(filePath) {
83
+ try {
84
+ await access(filePath)
85
+ return true
86
+ } catch {
87
+ return false
88
+ }
89
+ }
90
+
91
+ async function directoryExists(directory) {
92
+ try {
93
+ await access(directory, constants.R_OK | constants.X_OK)
94
+ return true
95
+ } catch {
96
+ return false
97
+ }
98
+ }
99
+
100
+ async function canWrite(directory) {
101
+ try {
102
+ await access(directory, constants.W_OK)
103
+ return true
104
+ } catch {
105
+ return false
106
+ }
107
+ }
108
+
109
+ async function hasAnyMarker(targetDirectory, markers) {
110
+ for (const marker of markers) {
111
+ if (await fileExists(join(targetDirectory, ...marker))) return true
112
+ }
113
+ return false
114
+ }
115
+
116
+ async function readJson(path) {
117
+ try {
118
+ return JSON.parse(await readFile(path, 'utf8'))
119
+ } catch {
120
+ return {}
121
+ }
122
+ }
@@ -0,0 +1,7 @@
1
+ export function isSafeTemplateName(value) {
2
+ return typeof value === 'string' && /^[A-Za-z0-9_-]+$/.test(value)
3
+ }
4
+
5
+ export function quote(value) {
6
+ return JSON.stringify(String(value))
7
+ }