betterstart-cli 0.0.102 → 0.0.104

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 (147) hide show
  1. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/index.ts +0 -5
  2. package/dist/assets/adapters/next/templates/init/lib/actions/webhooks/send-test-webhook.ts +1 -1
  3. package/dist/assets/adapters/next/templates/renderers/commands/init/banner-art.ts +7 -0
  4. package/dist/assets/adapters/next/templates/renderers/commands/init/verify-database-reachable.ts +30 -0
  5. package/dist/assets/adapters/next/templates/renderers/commands/seed/build-seed-script.ts +171 -0
  6. package/dist/assets/adapters/next/templates/renderers/generators/actions/action-helpers/build-authorship-alias-block.ts +4 -0
  7. package/dist/assets/adapters/next/templates/renderers/generators/actions/action-helpers/build-authorship-data-fields.ts +4 -0
  8. package/dist/assets/adapters/next/templates/renderers/generators/actions/action-helpers/build-format-action-date-source.ts +18 -0
  9. package/dist/assets/adapters/next/templates/renderers/generators/actions/action-helpers/build-read-select-option-type.ts +6 -0
  10. package/dist/assets/adapters/next/templates/renderers/generators/actions/action-helpers/build-relationship-data-types.ts +25 -0
  11. package/dist/assets/adapters/next/templates/renderers/generators/actions/action-helpers/build-result-mapping.ts +62 -0
  12. package/dist/assets/adapters/next/templates/renderers/generators/actions/action-helpers/generate-populate-list-rels-function.ts +50 -0
  13. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/build-restore-many-to-many-statements.ts +27 -0
  14. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/build-select-option-types.ts +37 -0
  15. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/gen-bulk-sort-order-content.ts +93 -0
  16. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/gen-create-content.ts +157 -0
  17. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/gen-create-select-option-content.ts +134 -0
  18. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/gen-delete-bulk-content.ts +85 -0
  19. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/gen-delete-content.ts +66 -0
  20. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/gen-distinct-files.ts +45 -0
  21. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/gen-get-by-id-content.ts +55 -0
  22. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/gen-get-by-slug-content.ts +55 -0
  23. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/gen-get-plural-content.ts +106 -0
  24. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/gen-get-select-options-content.ts +55 -0
  25. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/gen-get-versions-content.ts +19 -0
  26. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/gen-m2m-files.ts +151 -0
  27. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/gen-restore-content.ts +123 -0
  28. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/gen-update-content.ts +187 -0
  29. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/generate-resolve-media-function.ts +40 -0
  30. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/generate-slug-helpers.ts +73 -0
  31. package/dist/assets/adapters/next/templates/renderers/generators/actions/entity-file-contents/generate-version-snapshot-helpers.ts +104 -0
  32. package/dist/assets/adapters/next/templates/renderers/generators/actions/lifecycle-hook-emissions/lifecycle-context.ts +22 -0
  33. package/dist/assets/adapters/next/templates/renderers/generators/actions/lifecycle-hook-emissions/lifecycle-hook-import.ts +4 -0
  34. package/dist/assets/adapters/next/templates/renderers/generators/actions/markdown-renderer.ts +411 -0
  35. package/dist/assets/adapters/next/templates/renderers/generators/actions/select-fields-resolver.ts +99 -0
  36. package/dist/assets/adapters/next/templates/renderers/generators/actions/single-actions/generate-single-actions.ts +292 -0
  37. package/dist/assets/adapters/next/templates/renderers/generators/columns/column-defs/generate-authorship-value.ts +8 -0
  38. package/dist/assets/adapters/next/templates/renderers/generators/columns/column-defs/generate-column-def.ts +297 -0
  39. package/dist/assets/adapters/next/templates/renderers/generators/columns/column-defs/generate-first-column-def.ts +483 -0
  40. package/dist/assets/adapters/next/templates/renderers/generators/columns/column-defs/generate-image-cell-media.ts +38 -0
  41. package/dist/assets/adapters/next/templates/renderers/generators/columns/column-defs/generate-image-element.ts +22 -0
  42. package/dist/assets/adapters/next/templates/renderers/generators/columns/column-defs/generate-relationship-label.ts +26 -0
  43. package/dist/assets/adapters/next/templates/renderers/generators/columns/column-defs/generate-select-label.ts +17 -0
  44. package/dist/assets/adapters/next/templates/renderers/generators/columns/custom-cell.ts +24 -0
  45. package/dist/assets/adapters/next/templates/renderers/generators/columns/generate-columns.ts +55 -0
  46. package/dist/assets/adapters/next/templates/renderers/generators/create-page.ts +16 -0
  47. package/dist/assets/adapters/next/templates/renderers/generators/database/generate-database.ts +5 -0
  48. package/dist/assets/adapters/next/templates/renderers/generators/database/generate-junction-table.ts +27 -0
  49. package/dist/assets/adapters/next/templates/renderers/generators/database/generate-select-options-table.ts +35 -0
  50. package/dist/assets/adapters/next/templates/renderers/generators/database/generate-table-definition.ts +25 -0
  51. package/dist/assets/adapters/next/templates/renderers/generators/dev-mode-integration/build-entity-dev-mode-snippets.ts +180 -0
  52. package/dist/assets/adapters/next/templates/renderers/generators/dev-mode-integration/build-form-dev-mode-snippets.ts +97 -0
  53. package/dist/assets/adapters/next/templates/renderers/generators/dev-mode-integration/build-single-dev-mode-snippets.ts +60 -0
  54. package/dist/assets/adapters/next/templates/renderers/generators/dev-mode-integration/create-dev-mode-integration-artifact.ts +89 -0
  55. package/dist/assets/adapters/next/templates/renderers/generators/dev-mode-integration/lifecycle-hook-code.ts +55 -0
  56. package/dist/assets/adapters/next/templates/renderers/generators/edit-page.ts +33 -0
  57. package/dist/assets/adapters/next/templates/renderers/generators/email-template/generate-email-template.ts +248 -0
  58. package/dist/assets/adapters/next/templates/renderers/generators/email-template/generate-field-value.ts +31 -0
  59. package/dist/assets/adapters/next/templates/renderers/generators/emitted-helpers.ts +16 -0
  60. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/generate-icon-postfix.ts +27 -0
  61. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-boolean-field.ts +47 -0
  62. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-creatable-select-field.ts +122 -0
  63. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-date-field.ts +47 -0
  64. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-default-field.ts +53 -0
  65. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-gallery-field.ts +46 -0
  66. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-group-field.ts +16 -0
  67. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-icon-field.ts +31 -0
  68. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-markdown-field.ts +50 -0
  69. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-media-field.ts +47 -0
  70. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-multi-relationship-field.ts +91 -0
  71. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-multi-select-field.ts +219 -0
  72. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-number-field.ts +48 -0
  73. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-richtext-field.ts +50 -0
  74. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-select-field.ts +61 -0
  75. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-separator-field.ts +16 -0
  76. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-single-relationship-field.ts +93 -0
  77. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx/render-textarea-field.ts +53 -0
  78. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx-nested/render-list-field.ts +163 -0
  79. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx-nested/render-nested-field.ts +164 -0
  80. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx-nested/render-nested-object-list-field.ts +59 -0
  81. package/dist/assets/adapters/next/templates/renderers/generators/form/field-jsx-nested/render-text-input-field.ts +27 -0
  82. package/dist/assets/adapters/next/templates/renderers/generators/form/form-entity/generate-form.ts +822 -0
  83. package/dist/assets/adapters/next/templates/renderers/generators/form/form-shared/build-default-value-from-sync-functions.ts +41 -0
  84. package/dist/assets/adapters/next/templates/renderers/generators/form/form-shared/build-ui-imports.ts +58 -0
  85. package/dist/assets/adapters/next/templates/renderers/generators/form/form-shared/generate-default-value.ts +67 -0
  86. package/dist/assets/adapters/next/templates/renderers/generators/form/form-shared/generate-nested-list-default-value.ts +13 -0
  87. package/dist/assets/adapters/next/templates/renderers/generators/form/form-shared/label-with-description.ts +14 -0
  88. package/dist/assets/adapters/next/templates/renderers/generators/form/form-shared/render-tabs-trigger.ts +18 -0
  89. package/dist/assets/adapters/next/templates/renderers/generators/form/form-shared/select-read-values-expression.ts +21 -0
  90. package/dist/assets/adapters/next/templates/renderers/generators/form/form-single/build-group-creatable-select-handlers.ts +67 -0
  91. package/dist/assets/adapters/next/templates/renderers/generators/form/form-single/build-group-creatable-select-state.ts +29 -0
  92. package/dist/assets/adapters/next/templates/renderers/generators/form/form-single/build-group-field-array-hooks.ts +13 -0
  93. package/dist/assets/adapters/next/templates/renderers/generators/form/form-single/build-group-fields-jsx.ts +30 -0
  94. package/dist/assets/adapters/next/templates/renderers/generators/form/form-single/generate-card-component.ts +129 -0
  95. package/dist/assets/adapters/next/templates/renderers/generators/form/form-single/generate-single-form.ts +66 -0
  96. package/dist/assets/adapters/next/templates/renderers/generators/form-admin/admin-columns/generate-column-def.ts +72 -0
  97. package/dist/assets/adapters/next/templates/renderers/generators/form-admin/admin-columns/generate-columns.ts +89 -0
  98. package/dist/assets/adapters/next/templates/renderers/generators/form-admin/admin-page/generate-page.ts +23 -0
  99. package/dist/assets/adapters/next/templates/renderers/generators/form-admin/admin-page-content.ts +246 -0
  100. package/dist/assets/adapters/next/templates/renderers/generators/form-admin/admin-submission-drawer.ts +216 -0
  101. package/dist/assets/adapters/next/templates/renderers/generators/form-admin/admin-table.ts +273 -0
  102. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-actions/exclusive-date-upper-bound-helper.ts +11 -0
  103. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-actions/generate-form-actions.ts +505 -0
  104. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-component-multistep/build-component-source.ts +197 -0
  105. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-component-shared/build-field-error-helper.ts +16 -0
  106. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-component-shared/error-message-line.ts +13 -0
  107. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-component-shared/generate-field-jsx.ts +226 -0
  108. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-component-shared/generate-file-upload-field-jsx.ts +41 -0
  109. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-component-shared/generate-list-field-jsx.ts +160 -0
  110. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-component-shared/generate-multiselect-field-jsx.ts +40 -0
  111. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-component-shared/generate-number-field-jsx.ts +41 -0
  112. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-component-shared/generate-text-field-jsx.ts +39 -0
  113. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-component-shared/label-with-description-line.ts +14 -0
  114. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-component-single/build-single-step-form-component-source.ts +100 -0
  115. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-database.ts +29 -0
  116. package/dist/assets/adapters/next/templates/renderers/generators/form-pipeline/form-hook.ts +142 -0
  117. package/dist/assets/adapters/next/templates/renderers/generators/hook/generate-hook.ts +169 -0
  118. package/dist/assets/adapters/next/templates/renderers/generators/hook/generate-single-hook.ts +30 -0
  119. package/dist/assets/adapters/next/templates/renderers/generators/navigation-extract.ts +19 -0
  120. package/dist/assets/adapters/next/templates/renderers/generators/page-content/generate-page-content.ts +419 -0
  121. package/dist/assets/adapters/next/templates/renderers/generators/page.ts +24 -0
  122. package/dist/assets/adapters/next/templates/renderers/generators/row-actions-emitters/build-delete-dialog-source.ts +108 -0
  123. package/dist/assets/adapters/next/templates/renderers/generators/row-actions-emitters/build-row-actions-source.ts +61 -0
  124. package/dist/assets/adapters/next/templates/renderers/generators/single-page.ts +59 -0
  125. package/dist/assets/adapters/next/templates/renderers/generators/sortable-header/build-sort-label-expr.ts +9 -0
  126. package/dist/assets/adapters/next/templates/renderers/generators/sortable-header/build-sortable-header-button-jsx.ts +20 -0
  127. package/dist/assets/adapters/next/templates/renderers/generators/sortable-header/build-sortable-header-def.ts +14 -0
  128. package/dist/assets/adapters/next/templates/renderers/generators/table.ts +284 -0
  129. package/dist/assets/adapters/next/templates/renderers/generators/thankyou-email-template.ts +110 -0
  130. package/dist/assets/adapters/next/templates/renderers/generators/webhook-events/render-extract.ts +14 -0
  131. package/dist/assets/adapters/next/templates/renderers/init/scaffolders/next-config/create-next-config-template.ts +48 -0
  132. package/dist/assets/adapters/next/templates/renderers/init/scaffolders/tailwind/admin-shadow-input-utility.ts +9 -0
  133. package/dist/assets/adapters/next/templates/renderers/init/scaffolders/tailwind/admin-theme-block.ts +42 -0
  134. package/dist/assets/adapters/next/templates/renderers/init/templates/app/admin.ts +12 -0
  135. package/dist/assets/adapters/next/templates/renderers/integration-runtime/render-core-email-provider.ts +27 -0
  136. package/dist/assets/adapters/next/templates/renderers/integration-runtime/render-core-storage-provider.ts +27 -0
  137. package/dist/assets/adapters/next/templates/renderers/snapshots/barrels/render-db-barrel.ts +8 -0
  138. package/dist/assets/adapters/next/templates/renderers/snapshots/barrels/render-navigation-barrel.ts +63 -0
  139. package/dist/assets/adapters/next/templates/renderers/snapshots/barrels/render-webhook-events-barrel.ts +16 -0
  140. package/dist/{chunk-TIJEHWRF.js → chunk-OYU73Q2W.js} +1 -50
  141. package/dist/chunk-OYU73Q2W.js.map +1 -0
  142. package/dist/cli.js +8903 -4025
  143. package/dist/cli.js.map +1 -1
  144. package/dist/{read-namespaced-template-UXU7OCY3.js → read-namespaced-template-EIH2NPDJ.js} +2 -2
  145. package/package.json +1 -1
  146. package/dist/chunk-TIJEHWRF.js.map +0 -1
  147. /package/dist/{read-namespaced-template-UXU7OCY3.js.map → read-namespaced-template-EIH2NPDJ.js.map} +0 -0
@@ -0,0 +1,483 @@
1
+ export function renderFirstColumnDefLayoutTemplate({
2
+ sortLabelExpr,
3
+ sortableHeaderButtonJsx
4
+ }: {
5
+ sortLabelExpr: string
6
+ sortableHeaderButtonJsx: string
7
+ }): string {
8
+ return `header: ({ table, column }) => {
9
+ ${sortLabelExpr}
10
+ return (
11
+ <div className="flex min-w-0 items-center gap-4 pl-1">
12
+ <Checkbox
13
+ checked={table.getIsAllPageRowsSelected()}
14
+ onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
15
+ aria-label="Select all"
16
+ />
17
+ ${sortableHeaderButtonJsx}
18
+ </div>
19
+ )
20
+ }`
21
+ }
22
+
23
+ export function renderFirstColumnDefLayoutDetailsTemplate({
24
+ columnHeader
25
+ }: {
26
+ columnHeader: string
27
+ }): string {
28
+ return `header: ({ table }) => (
29
+ <div className="flex items-center gap-4 pl-1">
30
+ <Checkbox
31
+ checked={table.getIsAllPageRowsSelected()}
32
+ onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
33
+ aria-label="Select all"
34
+ />
35
+ <span>${columnHeader}</span>
36
+ </div>
37
+ )`
38
+ }
39
+
40
+ export function renderFirstColumnDefLayoutGenerateAuthorshipValueTemplate({
41
+ generateAuthorshipValue
42
+ }: {
43
+ generateAuthorshipValue: string
44
+ }): string {
45
+ return `cell: ({ row }) => {
46
+ ${generateAuthorshipValue}
47
+ return (
48
+ <div className="flex items-center gap-4 h-full pl-1">
49
+ <Checkbox
50
+ checked={row.getIsSelected()}
51
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
52
+ aria-label="Select row"
53
+ />
54
+ {label ? (
55
+ <span className="text-sm font-medium truncate max-w-[300px]" title={actor?.email}>
56
+ {label}
57
+ </span>
58
+ ) : (
59
+ <span className="text-muted-foreground">Unavailable</span>
60
+ )}
61
+ </div>
62
+ )
63
+ }`
64
+ }
65
+
66
+ export function renderFirstColumnDefContentTemplate({
67
+ generateImageCellMedia
68
+ }: {
69
+ generateImageCellMedia: string
70
+ }): string {
71
+ return `cell: ({ row }) => {
72
+ ${generateImageCellMedia}
73
+ }`
74
+ }
75
+
76
+ export function renderFirstColumnDefLayoutGenerateSelectLabelTemplate({
77
+ columnAccessorKey,
78
+ generateSelectLabel
79
+ }: {
80
+ columnAccessorKey: string
81
+ generateSelectLabel: string
82
+ }): string {
83
+ return `cell: ({ row }) => {
84
+ const value = row.original.${columnAccessorKey}
85
+ ${generateSelectLabel}
86
+ return (
87
+ <div className="flex items-center gap-4 h-full pl-1">
88
+ <Checkbox
89
+ checked={row.getIsSelected()}
90
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
91
+ aria-label="Select row"
92
+ />
93
+ <Badge variant="outline">
94
+ {label || 'Unavailable'}
95
+ </Badge>
96
+ </div>
97
+ )
98
+ }`
99
+ }
100
+
101
+ export function renderFirstColumnDefLayoutGenerateRelationshipLabelTemplate({
102
+ columnAccessorKey,
103
+ generateRelationshipLabel
104
+ }: {
105
+ columnAccessorKey: string
106
+ generateRelationshipLabel: string
107
+ }): string {
108
+ return `cell: ({ row }) => {
109
+ const value = row.original.${columnAccessorKey}
110
+ ${generateRelationshipLabel}
111
+ return (
112
+ <div className="flex items-center gap-4 h-full pl-1">
113
+ <Checkbox
114
+ checked={row.getIsSelected()}
115
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
116
+ aria-label="Select row"
117
+ />
118
+ <Badge variant="outline">
119
+ {label || 'Unavailable'}
120
+ </Badge>
121
+ </div>
122
+ )
123
+ }`
124
+ }
125
+
126
+ export function renderFirstColumnDefLayoutDetailsBranchTemplate({
127
+ columnAccessorKey
128
+ }: {
129
+ columnAccessorKey: string
130
+ }): string {
131
+ return `cell: ({ row }) => {
132
+ const value = row.original.${columnAccessorKey}
133
+ return (
134
+ <div className="flex items-center gap-4 h-full pl-1">
135
+ <Checkbox
136
+ checked={row.getIsSelected()}
137
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
138
+ aria-label="Select row"
139
+ />
140
+ <Badge variant="outline">
141
+ {value === null || value === undefined ? 'Unavailable' : String(value)}
142
+ </Badge>
143
+ </div>
144
+ )
145
+ }`
146
+ }
147
+
148
+ export function renderFirstColumnDefLayoutDetailsBranchBodyTemplate({
149
+ columnAccessorKey
150
+ }: {
151
+ columnAccessorKey: string
152
+ }): string {
153
+ return `cell: ({ row }) => {
154
+ const date = new Date(row.original.${columnAccessorKey})
155
+ return (
156
+ <div className="flex items-center gap-4 h-full pl-1">
157
+ <Checkbox
158
+ checked={row.getIsSelected()}
159
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
160
+ aria-label="Select row"
161
+ />
162
+ <div className="text-sm">
163
+ {date.toLocaleDateString('en-US', {
164
+ month: 'short',
165
+ day: 'numeric',
166
+ year: 'numeric'
167
+ })}
168
+ </div>
169
+ </div>
170
+ )
171
+ }`
172
+ }
173
+
174
+ export function renderFirstColumnDefLayoutDetailsBranchBodyFragmentTemplate({
175
+ columnAccessorKey
176
+ }: {
177
+ columnAccessorKey: string
178
+ }): string {
179
+ return `cell: ({ row }) => {
180
+ const email = row.original.${columnAccessorKey} as string
181
+ return (
182
+ <div className="flex items-center gap-4 h-full pl-1">
183
+ <Checkbox
184
+ checked={row.getIsSelected()}
185
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
186
+ aria-label="Select row"
187
+ />
188
+ <span className="text-sm font-medium truncate max-w-[300px]">{email}</span>
189
+ </div>
190
+ )
191
+ }`
192
+ }
193
+
194
+ export function renderFirstColumnDefLayoutDetailsBranchBodyFragmentSectionTemplate({
195
+ columnAccessorKey
196
+ }: {
197
+ columnAccessorKey: string
198
+ }): string {
199
+ return `cell: ({ row }) => {
200
+ const amount = row.original.${columnAccessorKey} as number
201
+ return (
202
+ <div className="flex items-center gap-4 h-full pl-1">
203
+ <Checkbox
204
+ checked={row.getIsSelected()}
205
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
206
+ aria-label="Select row"
207
+ />
208
+ <div className="text-sm font-medium">
209
+ {new Intl.NumberFormat('en-US', {
210
+ style: 'currency',
211
+ currency: 'USD'
212
+ }).format(amount)}
213
+ </div>
214
+ </div>
215
+ )
216
+ }`
217
+ }
218
+
219
+ export function renderFirstColumnDefLayoutDetailsBranchBodyFragmentSectionVariantTemplate({
220
+ columnAccessorKey
221
+ }: {
222
+ columnAccessorKey: string
223
+ }): string {
224
+ return `cell: ({ row }) => {
225
+ const value = row.original.${columnAccessorKey} as number
226
+ return (
227
+ <div className="flex items-center gap-4 h-full pl-1">
228
+ <Checkbox
229
+ checked={row.getIsSelected()}
230
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
231
+ aria-label="Select row"
232
+ />
233
+ <div className="text-sm">{value}</div>
234
+ </div>
235
+ )
236
+ }`
237
+ }
238
+
239
+ export function renderFirstColumnDefLayoutDetailsBranchBodyFragmentSectionVariantContinuationTemplate({
240
+ columnAccessorKey,
241
+ trueLabel,
242
+ falseLabel
243
+ }: {
244
+ columnAccessorKey: string
245
+ trueLabel: string
246
+ falseLabel: string
247
+ }): string {
248
+ return `cell: ({ row }) => {
249
+ const value = row.original.${columnAccessorKey} as boolean
250
+ return (
251
+ <div className="flex items-center gap-4 h-full pl-1">
252
+ <Checkbox
253
+ checked={row.getIsSelected()}
254
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
255
+ aria-label="Select row"
256
+ />
257
+ <Badge variant={value ? 'outline' : 'secondary'}>
258
+ {value ? ${trueLabel} : ${falseLabel}}
259
+ </Badge>
260
+ </div>
261
+ )
262
+ }`
263
+ }
264
+
265
+ export function renderFirstColumnDefLayoutDetailsBranchBodyFragmentSectionVariantContinuationFragmentTemplate({
266
+ columnComponent
267
+ }: {
268
+ columnComponent: string
269
+ }): string {
270
+ return `cell: ({ row }) => {
271
+ return (
272
+ <div className="flex items-center gap-4 h-full pl-1">
273
+ <Checkbox
274
+ checked={row.getIsSelected()}
275
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
276
+ aria-label="Select row"
277
+ />
278
+ <${columnComponent} data={row.original} />
279
+ </div>
280
+ )
281
+ }`
282
+ }
283
+
284
+ export function renderFirstColumnDefLayoutGenerateSelectLabelValueTemplate({
285
+ columnAccessorKey,
286
+ generateSelectLabel
287
+ }: {
288
+ columnAccessorKey: string
289
+ generateSelectLabel: string
290
+ }): string {
291
+ return `cell: ({ row }) => {
292
+ const value = row.original.${columnAccessorKey}
293
+ ${generateSelectLabel}
294
+ return (
295
+ <div className="flex items-center gap-4 h-full pl-1">
296
+ <Checkbox
297
+ checked={row.getIsSelected()}
298
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
299
+ aria-label="Select row"
300
+ />
301
+ <span className="truncate max-w-[300px]">
302
+ {label || 'Unavailable'}
303
+ </span>
304
+ </div>
305
+ )
306
+ }`
307
+ }
308
+
309
+ export function renderFirstColumnDefLayoutGenerateRelationshipLabelValueTemplate({
310
+ columnAccessorKey,
311
+ generateRelationshipLabel
312
+ }: {
313
+ columnAccessorKey: string
314
+ generateRelationshipLabel: string
315
+ }): string {
316
+ return `cell: ({ row }) => {
317
+ const value = row.original.${columnAccessorKey}
318
+ ${generateRelationshipLabel}
319
+ return (
320
+ <div className="flex items-center gap-4 h-full pl-1">
321
+ <Checkbox
322
+ checked={row.getIsSelected()}
323
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
324
+ aria-label="Select row"
325
+ />
326
+ <span className="truncate max-w-[300px]">
327
+ {label || 'Unavailable'}
328
+ </span>
329
+ </div>
330
+ )
331
+ }`
332
+ }
333
+
334
+ export function renderFirstColumnDefLayoutDetailsBranchBodyFragmentSectionVariantContinuationFragmentFragmentTemplate({
335
+ columnAccessorKey
336
+ }: {
337
+ columnAccessorKey: string
338
+ }): string {
339
+ return `cell: ({ row }) => {
340
+ const value = row.original.${columnAccessorKey}
341
+ return (
342
+ <div className="flex items-center gap-4 h-full pl-1">
343
+ <Checkbox
344
+ checked={row.getIsSelected()}
345
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
346
+ aria-label="Select row"
347
+ />
348
+ <span className="truncate max-w-[300px]">
349
+ {value === null || value === undefined ? 'Unavailable' : String(value)}
350
+ </span>
351
+ </div>
352
+ )
353
+ }`
354
+ }
355
+
356
+ export function renderFirstColumnDefClickHandlerTemplate({
357
+ columnAccessorKey
358
+ }: {
359
+ columnAccessorKey: string
360
+ }): string {
361
+ return `cell: ({ row }) => {
362
+ const value = row.original.${columnAccessorKey} as string
363
+ return (
364
+ <div className="flex items-center gap-4 h-full pl-1">
365
+ <Checkbox
366
+ checked={row.getIsSelected()}
367
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
368
+ aria-label="Select row"
369
+ />
370
+ {value ? (
371
+ <a
372
+ href={value}
373
+ target="_blank"
374
+ rel="noopener noreferrer"
375
+ className="text-sm text-blue-600 hover:text-blue-800 hover:underline dark:text-blue-400 dark:hover:text-blue-300 truncate block max-w-[250px]"
376
+ title={value}
377
+ onClick={(e) => e.stopPropagation()}
378
+ >
379
+ {truncateText(value, 50)}
380
+ </a>
381
+ ) : (
382
+ <span className="text-muted-foreground">\u2014</span>
383
+ )}
384
+ </div>
385
+ )
386
+ }`
387
+ }
388
+
389
+ export function renderFirstColumnDefLayoutGenerateSelectLabelValueBodyTemplate({
390
+ columnAccessorKey,
391
+ generateSelectLabel
392
+ }: {
393
+ columnAccessorKey: string
394
+ generateSelectLabel: string
395
+ }): string {
396
+ return `cell: ({ row }) => {
397
+ const value = row.original.${columnAccessorKey}
398
+ ${generateSelectLabel}
399
+ return (
400
+ <div className="flex items-center gap-4 h-full pl-1">
401
+ <Checkbox
402
+ checked={row.getIsSelected()}
403
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
404
+ aria-label="Select row"
405
+ />
406
+ <span className="truncate max-w-[300px]">
407
+ {label || 'Unavailable'}
408
+ </span>
409
+ </div>
410
+ )
411
+ }`
412
+ }
413
+
414
+ export function renderFirstColumnDefLayoutGenerateRelationshipLabelValueBodyTemplate({
415
+ columnAccessorKey,
416
+ generateRelationshipLabel
417
+ }: {
418
+ columnAccessorKey: string
419
+ generateRelationshipLabel: string
420
+ }): string {
421
+ return `cell: ({ row }) => {
422
+ const value = row.original.${columnAccessorKey}
423
+ ${generateRelationshipLabel}
424
+ return (
425
+ <div className="flex items-center gap-4 h-full pl-1">
426
+ <Checkbox
427
+ checked={row.getIsSelected()}
428
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
429
+ aria-label="Select row"
430
+ />
431
+ <span className="truncate max-w-[300px]">
432
+ {label || 'Unavailable'}
433
+ </span>
434
+ </div>
435
+ )
436
+ }`
437
+ }
438
+
439
+ export function renderFirstColumnDefLayoutDetailsBranchBodyFragmentSectionVariantContinuationFragmentFragmentFragmentTemplate({
440
+ columnAccessorKey
441
+ }: {
442
+ columnAccessorKey: string
443
+ }): string {
444
+ return `cell: ({ row }) => {
445
+ const value = row.original.${columnAccessorKey}
446
+ return (
447
+ <div className="flex items-center gap-4 h-full pl-1">
448
+ <Checkbox
449
+ checked={row.getIsSelected()}
450
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
451
+ aria-label="Select row"
452
+ />
453
+ <span className="truncate max-w-[300px]">
454
+ {value === null || value === undefined ? 'Unavailable' : String(value)}
455
+ </span>
456
+ </div>
457
+ )
458
+ }`
459
+ }
460
+
461
+ export function renderFirstColumnDefContentEnabledTemplate({
462
+ columnAccessorKey,
463
+ columnSize,
464
+ meta,
465
+ headerDef,
466
+ cellDef,
467
+ sortableEnabled
468
+ }: {
469
+ columnAccessorKey: string
470
+ columnSize: string
471
+ meta: string
472
+ headerDef: string
473
+ cellDef: string
474
+ sortableEnabled: string
475
+ }): string {
476
+ return ` {
477
+ accessorKey: '${columnAccessorKey}',
478
+ ${columnSize}${meta}${headerDef},
479
+ ${cellDef},
480
+ enableSorting: ${sortableEnabled},
481
+ enableHiding: false
482
+ }`
483
+ }
@@ -0,0 +1,38 @@
1
+ export function renderImageCellMediaLayoutTemplate({
2
+ imageUrlExpression,
3
+ titleFallback,
4
+ split
5
+ }: {
6
+ imageUrlExpression: string
7
+ titleFallback: string
8
+ split: string
9
+ }): string {
10
+ return `const imageUrl = ${imageUrlExpression} ?? ''
11
+ const title = ${titleFallback}
12
+ return (
13
+ <div className="flex items-center gap-4 h-full pl-1">
14
+ <Checkbox
15
+ checked={row.getIsSelected()}
16
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
17
+ aria-label="Select row"
18
+ />
19
+ ${split}
20
+ </div>
21
+ )`
22
+ }
23
+
24
+ export function renderImageCellMediaTemplate({
25
+ imageUrlExpression,
26
+ titleFallback,
27
+ imageElement
28
+ }: {
29
+ imageUrlExpression: string
30
+ titleFallback: string
31
+ imageElement: string
32
+ }): string {
33
+ return `const imageUrl = ${imageUrlExpression} ?? ''
34
+ const title = ${titleFallback}
35
+ return (
36
+ ${imageElement}
37
+ )`
38
+ }
@@ -0,0 +1,22 @@
1
+ export function renderImageElementLayoutTemplate({
2
+ columnHeader
3
+ }: {
4
+ columnHeader: string
5
+ }): string {
6
+ return `<Avatar className="size-10 overflow-hidden border">
7
+ {imageUrl ? (
8
+ <Image
9
+ src={imageUrl}
10
+ alt={title ? \`${columnHeader} image for \${title}\` : '${columnHeader} image'}
11
+ fill
12
+ sizes="40px"
13
+ className="rounded-sm object-cover"
14
+ unoptimized
15
+ />
16
+ ) : (
17
+ <AvatarFallback>
18
+ {String(title || imageUrl).substring(0, 2).toUpperCase()}
19
+ </AvatarFallback>
20
+ )}
21
+ </Avatar>`
22
+ }
@@ -0,0 +1,26 @@
1
+ export function renderRelationshipLabelLabelTemplate({
2
+ valueExpression
3
+ }: {
4
+ valueExpression: string
5
+ }): string {
6
+ return `const label = (() => {
7
+ const toRelationshipLabel = (item: unknown): string | null => {
8
+ if (item && typeof item === 'object') {
9
+ const display =
10
+ ('name' in item && item.name) ||
11
+ ('title' in item && item.title) ||
12
+ ('label' in item && item.label) ||
13
+ ('email' in item && item.email) ||
14
+ ('id' in item && item.id)
15
+ return display === null || display === undefined || display === ''
16
+ ? null
17
+ : String(display)
18
+ }
19
+ return item === null || item === undefined ? null : String(item)
20
+ }
21
+
22
+ return Array.isArray(${valueExpression})
23
+ ? ${valueExpression}.map(toRelationshipLabel).filter(Boolean).join(', ')
24
+ : toRelationshipLabel(${valueExpression})
25
+ })()`
26
+ }
@@ -0,0 +1,17 @@
1
+ export function renderSelectLabelLabelTemplate({
2
+ valueExpression
3
+ }: {
4
+ valueExpression: string
5
+ }): string {
6
+ return `const label = Array.isArray(${valueExpression})
7
+ ? ${valueExpression}
8
+ .map((option) =>
9
+ typeof option === 'object' && option !== null && 'label' in option
10
+ ? String(option.label)
11
+ : String(option)
12
+ )
13
+ .join(', ')
14
+ : ${valueExpression} === null || ${valueExpression} === undefined
15
+ ? null
16
+ : String(${valueExpression})`
17
+ }
@@ -0,0 +1,24 @@
1
+ export function renderCreateCustomCellComponentComponentTemplate({
2
+ singular,
3
+ actionImportPath,
4
+ componentName
5
+ }: {
6
+ singular: string
7
+ actionImportPath: string
8
+ componentName: string
9
+ }): string {
10
+ return `import type { ${singular} } from '@admin/actions/${actionImportPath}'
11
+
12
+ interface ${componentName}Props {
13
+ data: ${singular}
14
+ }
15
+
16
+ export function ${componentName}({ data }: ${componentName}Props) {
17
+ return (
18
+ <div>
19
+ {JSON.stringify(data)}
20
+ </div>
21
+ )
22
+ }
23
+ `
24
+ }
@@ -0,0 +1,55 @@
1
+ export function renderColumnsLayoutTemplate({ actions }: { actions: string }): string {
2
+ return ` {
3
+ id: 'actions',
4
+ size: 64,
5
+ enableResizing: false,
6
+ meta: { width: '64px' },
7
+ header: () => <span className="sr-only">Actions</span>,
8
+ cell: ({ row }) => (
9
+ <div className="flex justify-end">
10
+ <${actions} id={row.original.id} />
11
+ </div>
12
+ )
13
+ }`
14
+ }
15
+
16
+ export function renderColumnsClientModuleTemplate({
17
+ lucideIconsLucide,
18
+ needsImageRendererImage,
19
+ join,
20
+ joinText,
21
+ singular,
22
+ actionImportPath,
23
+ joinContent,
24
+ hasDeleteActions,
25
+ firstColDef,
26
+ restColDefsContent,
27
+ actionsColumnContent
28
+ }: {
29
+ lucideIconsLucide: string
30
+ needsImageRendererImage: string
31
+ join: string
32
+ joinText: string
33
+ singular: string
34
+ actionImportPath: string
35
+ joinContent: string
36
+ hasDeleteActions: string
37
+ firstColDef: string
38
+ restColDefsContent: string
39
+ actionsColumnContent: string
40
+ }): string {
41
+ return `'use client'
42
+
43
+ import type { ColumnDef } from '@tanstack/react-table'
44
+ ${lucideIconsLucide}
45
+ ${needsImageRendererImage}
46
+ ${join}
47
+ ${joinText}
48
+ import type { ${singular} } from '@admin/actions/${actionImportPath}'
49
+ ${joinContent}
50
+ ${hasDeleteActions}
51
+ export const columns: ColumnDef<${singular}>[] = [
52
+ ${firstColDef}${restColDefsContent}${actionsColumnContent}
53
+ ]
54
+ `
55
+ }
@@ -0,0 +1,16 @@
1
+ export function renderCreatePageImportsTemplate({
2
+ singular,
3
+ kebabName,
4
+ singLabel
5
+ }: {
6
+ singular: string
7
+ kebabName: string
8
+ singLabel: string
9
+ }): string {
10
+ return `import { ${singular}Form } from '../${kebabName}-form'
11
+
12
+ export default function Create${singular}Page() {
13
+ return <${singular}Form pageTitle="Create ${singLabel}" />
14
+ }
15
+ `
16
+ }
@@ -0,0 +1,5 @@
1
+ export function renderDatabaseImportsTemplate({ join }: { join: string }): string {
2
+ return `import {
3
+ ${join}
4
+ } from 'drizzle-orm/pg-core'`
5
+ }