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,27 @@
1
+ export function renderJunctionTableGeneratedValueTemplate({
2
+ toCamelCase,
3
+ junctionPascal,
4
+ schemaIdCol,
5
+ schemaTableRef,
6
+ relationIdCol,
7
+ relationIdType,
8
+ relationTableRef
9
+ }: {
10
+ toCamelCase: string
11
+ junctionPascal: string
12
+ schemaIdCol: string
13
+ schemaTableRef: string
14
+ relationIdCol: string
15
+ relationIdType: string
16
+ relationTableRef: string
17
+ }): string {
18
+ return `export const ${toCamelCase} = pgTable(
19
+ '${junctionPascal}',
20
+ {
21
+ ${schemaIdCol}: uuid().notNull().references(() => ${schemaTableRef}.id, { onDelete: 'cascade' }),
22
+ ${relationIdCol}: ${relationIdType}().notNull().references(() => ${relationTableRef}.id, { onDelete: 'cascade' })
23
+ },
24
+ (table) => [primaryKey({ columns: [table.${schemaIdCol}, table.${relationIdCol}] })]
25
+ )
26
+ `
27
+ }
@@ -0,0 +1,35 @@
1
+ export function renderSelectOptionsTableGeneratedValueTemplate({
2
+ variableName,
3
+ tableName,
4
+ indexName
5
+ }: {
6
+ variableName: string
7
+ tableName: string
8
+ indexName: string
9
+ }): string {
10
+ return `export const ${variableName} = pgTable(
11
+ '${tableName}',
12
+ {
13
+ id: uuid().defaultRandom().primaryKey().notNull(),
14
+ fieldName: varchar('fieldName', { length: 100 }).notNull(),
15
+ label: varchar('label', { length: 255 }).notNull(),
16
+ value: varchar('value', { length: 255 }).notNull(),
17
+ createdAt: timestamp('createdAt', { precision: 3, mode: 'string' })
18
+ .default(sql\`CURRENT_TIMESTAMP\`)
19
+ .notNull(),
20
+ updatedAt: timestamp('updatedAt', { precision: 3, mode: 'string' })
21
+ .default(sql\`CURRENT_TIMESTAMP\`)
22
+ .notNull(),
23
+ createdBy: text('createdBy').references(() => user.id, { onDelete: 'set null' }),
24
+ updatedBy: text('updatedBy').references(() => user.id, { onDelete: 'set null' })
25
+ },
26
+ (table) => [
27
+ uniqueIndex('${indexName}').using(
28
+ 'btree',
29
+ table.fieldName.asc().nullsLast().op('text_ops'),
30
+ table.value.asc().nullsLast().op('text_ops')
31
+ )
32
+ ]
33
+ )
34
+ `
35
+ }
@@ -0,0 +1,25 @@
1
+ export function renderTableDefinitionGeneratedValueTemplate({
2
+ variableName,
3
+ tableName,
4
+ fieldDefs,
5
+ publishedField,
6
+ generatedFields,
7
+ sortOrderField,
8
+ indexes
9
+ }: {
10
+ variableName: string
11
+ tableName: string
12
+ fieldDefs: string
13
+ publishedField: string
14
+ generatedFields: string
15
+ sortOrderField: string
16
+ indexes: string
17
+ }): string {
18
+ return `export const ${variableName} = pgTable(
19
+ '${tableName}',
20
+ {
21
+ ${fieldDefs}${publishedField}${generatedFields}${sortOrderField}
22
+ }${indexes}
23
+ )
24
+ `
25
+ }
@@ -0,0 +1,180 @@
1
+ export function renderBuildEntityDevModeSnippetsImportsTemplate({
2
+ singular,
3
+ actionModulePath,
4
+ camelSingular
5
+ }: {
6
+ singular: string
7
+ actionModulePath: string
8
+ camelSingular: string
9
+ }): string {
10
+ return `import { get${singular}ById } from '${actionModulePath}'
11
+
12
+ export default async function ${singular}Detail({ id }: { id: string }) {
13
+ const ${camelSingular} = await get${singular}ById(id)
14
+
15
+ if (!${camelSingular}) {
16
+ return null
17
+ }
18
+
19
+ return <pre>{JSON.stringify(${camelSingular}, null, 2)}</pre>
20
+ }
21
+ `
22
+ }
23
+
24
+ export function renderBuildEntityDevModeSnippetsImportsDetailsTemplate({
25
+ singular,
26
+ actionModulePath,
27
+ camelSingular
28
+ }: {
29
+ singular: string
30
+ actionModulePath: string
31
+ camelSingular: string
32
+ }): string {
33
+ return `import { get${singular}BySlug } from '${actionModulePath}'
34
+
35
+ export default async function ${singular}Detail({ slug }: { slug: string }) {
36
+ const ${camelSingular} = await get${singular}BySlug(slug)
37
+
38
+ if (!${camelSingular}) {
39
+ return null
40
+ }
41
+
42
+ return <pre>{JSON.stringify(${camelSingular}, null, 2)}</pre>
43
+ }
44
+ `
45
+ }
46
+
47
+ export function renderBuildEntityDevModeSnippetsImportsLabelTemplate({
48
+ plural,
49
+ actionModulePath,
50
+ camelPlural,
51
+ toLowerCase
52
+ }: {
53
+ plural: string
54
+ actionModulePath: string
55
+ camelPlural: string
56
+ toLowerCase: string
57
+ }): string {
58
+ return `import { get${plural} } from '${actionModulePath}'
59
+
60
+ export default async function ${plural}List() {
61
+ const { ${camelPlural}, total } = await get${plural}({ limit: 10, offset: 0 })
62
+
63
+ return (
64
+ <section>
65
+ <h2>{total} ${toLowerCase}</h2>
66
+ <pre>{JSON.stringify(${camelPlural}, null, 2)}</pre>
67
+ </section>
68
+ )
69
+ }
70
+ `
71
+ }
72
+
73
+ export function renderBuildEntityDevModeSnippetsClientModuleTemplate({
74
+ singular,
75
+ actionModulePath,
76
+ tsObject,
77
+ toLowerCase
78
+ }: {
79
+ singular: string
80
+ actionModulePath: string
81
+ tsObject: string
82
+ toLowerCase: string
83
+ }): string {
84
+ return `'use client'
85
+
86
+ import * as React from 'react'
87
+ import { create${singular}, type ${singular}CreateInput } from '${actionModulePath}'
88
+
89
+ const input: ${singular}CreateInput = ${tsObject}
90
+
91
+ export function Create${singular}Button() {
92
+ const [isPending, startTransition] = React.useTransition()
93
+
94
+ return (
95
+ <button
96
+ type="button"
97
+ disabled={isPending}
98
+ onClick={() => {
99
+ startTransition(async () => {
100
+ await create${singular}(input)
101
+ })
102
+ }}
103
+ >
104
+ Create ${toLowerCase}
105
+ </button>
106
+ )
107
+ }
108
+ `
109
+ }
110
+
111
+ export function renderBuildEntityDevModeSnippetsClientModuleSampleTemplate({
112
+ singular,
113
+ actionModulePath,
114
+ tsObject,
115
+ toLowerCase
116
+ }: {
117
+ singular: string
118
+ actionModulePath: string
119
+ tsObject: string
120
+ toLowerCase: string
121
+ }): string {
122
+ return `'use client'
123
+
124
+ import * as React from 'react'
125
+ import { update${singular}, type ${singular}UpdateInput } from '${actionModulePath}'
126
+
127
+ export function Update${singular}Button({ id }: { id: string }) {
128
+ const [isPending, startTransition] = React.useTransition()
129
+ const input: ${singular}UpdateInput = ${tsObject}
130
+
131
+ return (
132
+ <button
133
+ type="button"
134
+ disabled={isPending}
135
+ onClick={() => {
136
+ startTransition(async () => {
137
+ await update${singular}(input)
138
+ })
139
+ }}
140
+ >
141
+ Update ${toLowerCase}
142
+ </button>
143
+ )
144
+ }
145
+ `
146
+ }
147
+
148
+ export function renderBuildEntityDevModeSnippetsClientModuleDetailsTemplate({
149
+ singular,
150
+ actionModulePath,
151
+ toLowerCase
152
+ }: {
153
+ singular: string
154
+ actionModulePath: string
155
+ toLowerCase: string
156
+ }): string {
157
+ return `'use client'
158
+
159
+ import * as React from 'react'
160
+ import { delete${singular} } from '${actionModulePath}'
161
+
162
+ export function Delete${singular}Button({ id }: { id: string }) {
163
+ const [isPending, startTransition] = React.useTransition()
164
+
165
+ return (
166
+ <button
167
+ type="button"
168
+ disabled={isPending}
169
+ onClick={() => {
170
+ startTransition(async () => {
171
+ await delete${singular}(id)
172
+ })
173
+ }}
174
+ >
175
+ Delete ${toLowerCase}
176
+ </button>
177
+ )
178
+ }
179
+ `
180
+ }
@@ -0,0 +1,97 @@
1
+ export function renderBuildFormDevModeSnippetsClientModuleTemplate({
2
+ pascal,
3
+ actionModulePath,
4
+ tsObject,
5
+ toLowerCase
6
+ }: {
7
+ pascal: string
8
+ actionModulePath: string
9
+ tsObject: string
10
+ toLowerCase: string
11
+ }): string {
12
+ return `'use client'
13
+
14
+ import * as React from 'react'
15
+ import {
16
+ create${pascal}Submission,
17
+ type Create${pascal}SubmissionInput
18
+ } from '${actionModulePath}'
19
+
20
+ const input: Create${pascal}SubmissionInput = ${tsObject}
21
+
22
+ export function ${pascal}SubmitButton() {
23
+ const [isPending, startTransition] = React.useTransition()
24
+
25
+ return (
26
+ <button
27
+ type="button"
28
+ disabled={isPending}
29
+ onClick={() => {
30
+ startTransition(async () => {
31
+ await create${pascal}Submission(input)
32
+ })
33
+ }}
34
+ >
35
+ Submit ${toLowerCase}
36
+ </button>
37
+ )
38
+ }
39
+ `
40
+ }
41
+
42
+ export function renderBuildFormDevModeSnippetsImportsTemplate({
43
+ pascal,
44
+ actionModulePath,
45
+ toLowerCase
46
+ }: {
47
+ pascal: string
48
+ actionModulePath: string
49
+ toLowerCase: string
50
+ }): string {
51
+ return `import { get${pascal}Submissions } from '${actionModulePath}'
52
+
53
+ export default async function ${pascal}Submissions() {
54
+ const { submissions, total } = await get${pascal}Submissions({ limit: 10, offset: 0 })
55
+
56
+ return (
57
+ <section>
58
+ <h2>{total} ${toLowerCase} submissions</h2>
59
+ <pre>{JSON.stringify(submissions, null, 2)}</pre>
60
+ </section>
61
+ )
62
+ }
63
+ `
64
+ }
65
+
66
+ export function renderBuildFormDevModeSnippetsClientModuleDetailsTemplate({
67
+ pascal,
68
+ actionModulePath
69
+ }: {
70
+ pascal: string
71
+ actionModulePath: string
72
+ }): string {
73
+ return `'use client'
74
+
75
+ import * as React from 'react'
76
+ import { delete${pascal}Submission } from '${actionModulePath}'
77
+
78
+ import { DEFAULT_ADMIN_IMPORT_ALIAS, ENTITY_ACTION_FIELD_EXCLUSIONS, SAMPLE_FORMATTED_TIMESTAMP, SAMPLE_UUID, SINGLETON_ID, SINGLE_ACTION_FIELD_EXCLUSIONS } from '@cli-constants/generators.js'
79
+ export function Delete${pascal}SubmissionButton({ id }: { id: string }) {
80
+ const [isPending, startTransition] = React.useTransition()
81
+
82
+ return (
83
+ <button
84
+ type="button"
85
+ disabled={isPending}
86
+ onClick={() => {
87
+ startTransition(async () => {
88
+ await delete${pascal}Submission(id)
89
+ })
90
+ }}
91
+ >
92
+ Delete submission
93
+ </button>
94
+ )
95
+ }
96
+ `
97
+ }
@@ -0,0 +1,60 @@
1
+ export function renderBuildSingleDevModeSnippetsImportsTemplate({
2
+ singular,
3
+ actionModulePath,
4
+ camelSingular
5
+ }: {
6
+ singular: string
7
+ actionModulePath: string
8
+ camelSingular: string
9
+ }): string {
10
+ return `import { get${singular} } from '${actionModulePath}'
11
+
12
+ export default async function ${singular}Summary() {
13
+ const ${camelSingular} = await get${singular}()
14
+
15
+ if (!${camelSingular}) {
16
+ return null
17
+ }
18
+
19
+ return <pre>{JSON.stringify(${camelSingular}, null, 2)}</pre>
20
+ }
21
+ `
22
+ }
23
+
24
+ export function renderBuildSingleDevModeSnippetsClientModuleTemplate({
25
+ singular,
26
+ actionModulePath,
27
+ tsObject,
28
+ toLowerCase
29
+ }: {
30
+ singular: string
31
+ actionModulePath: string
32
+ tsObject: string
33
+ toLowerCase: string
34
+ }): string {
35
+ return `'use client'
36
+
37
+ import * as React from 'react'
38
+ import { upsert${singular}, type ${singular}UpsertInput } from '${actionModulePath}'
39
+
40
+ const input: ${singular}UpsertInput = ${tsObject}
41
+
42
+ export function Save${singular}Button() {
43
+ const [isPending, startTransition] = React.useTransition()
44
+
45
+ return (
46
+ <button
47
+ type="button"
48
+ disabled={isPending}
49
+ onClick={() => {
50
+ startTransition(async () => {
51
+ await upsert${singular}(input)
52
+ })
53
+ }}
54
+ >
55
+ Save ${toLowerCase}
56
+ </button>
57
+ )
58
+ }
59
+ `
60
+ }
@@ -0,0 +1,89 @@
1
+ export function renderCreateDevModeIntegrationArtifactImportsTemplate({
2
+ adminImportAlias,
3
+ exportName,
4
+ stringify,
5
+ stringifySerializedValue,
6
+ stringifyText,
7
+ loadExportName,
8
+ join,
9
+ dynamicImports,
10
+ snippetValues,
11
+ lifecycleHookValues
12
+ }: {
13
+ adminImportAlias: string
14
+ exportName: string
15
+ stringify: string
16
+ stringifySerializedValue: string
17
+ stringifyText: string
18
+ loadExportName: string
19
+ join: string
20
+ dynamicImports: string
21
+ snippetValues: string
22
+ lifecycleHookValues: string
23
+ }): string {
24
+ return `import type {
25
+ DevModeIntegration,
26
+ DevModeIntegrationMetadata,
27
+ DevModeLifecycleHookExample,
28
+ DevModeSnippet
29
+ } from '${adminImportAlias}/components/shared/dev-mode/dev-mode-types'
30
+
31
+ export const ${exportName} = {
32
+ schemaName: ${stringify},
33
+ schemaLabel: ${stringifySerializedValue},
34
+ schemaType: ${stringifyText}
35
+ } satisfies DevModeIntegrationMetadata
36
+
37
+ export async function ${loadExportName}(): Promise<DevModeIntegration> {
38
+ const [${join}] = await Promise.all([
39
+ ${dynamicImports}
40
+ ])
41
+ const snippets = [
42
+ ${snippetValues}
43
+ ] as DevModeSnippet[]
44
+ const lifecycleHooks = [
45
+ ${lifecycleHookValues}
46
+ ] as DevModeLifecycleHookExample[]
47
+
48
+ return {
49
+ ...${exportName},
50
+ schemaJson: JSON.stringify(schemaModule.default, null, 2),
51
+ snippets,
52
+ lifecycleHooks
53
+ }
54
+ }
55
+ `
56
+ }
57
+
58
+ export function renderCreateDevModeIntegrationArtifactClientModuleTemplate({
59
+ adminImportAlias,
60
+ exportName,
61
+ loadExportName,
62
+ buttonExportName
63
+ }: {
64
+ adminImportAlias: string
65
+ exportName: string
66
+ loadExportName: string
67
+ buttonExportName: string
68
+ }): string {
69
+ return `'use client'
70
+
71
+ import type { Setting } from '${adminImportAlias}/actions/settings'
72
+ import { DevModeIntegrateButton } from '${adminImportAlias}/components/shared/dev-mode-integrate'
73
+ import { ${exportName}, ${loadExportName} } from './integration'
74
+
75
+ interface ${buttonExportName}Props {
76
+ initialSettings?: Setting | null
77
+ }
78
+
79
+ export function ${buttonExportName}({ initialSettings }: ${buttonExportName}Props) {
80
+ return (
81
+ <DevModeIntegrateButton
82
+ integration={${exportName}}
83
+ loadIntegration={${loadExportName}}
84
+ initialSettings={initialSettings}
85
+ />
86
+ )
87
+ }
88
+ `
89
+ }
@@ -0,0 +1,55 @@
1
+ export function renderLifecycleHookCodeImportsTemplate({
2
+ adminImportAlias,
3
+ schemaName,
4
+ event,
5
+ entityLabel,
6
+ actionLabel
7
+ }: {
8
+ adminImportAlias: string
9
+ schemaName: string
10
+ event: string
11
+ entityLabel: string
12
+ actionLabel: string
13
+ }): string {
14
+ return `import { registerHook } from '${adminImportAlias}/lib/lifecycle-hooks'
15
+
16
+ registerHook('${schemaName}', '${event}', async (ctx) => {
17
+ console.log('${entityLabel} ${actionLabel} requested', {
18
+ actorId: ctx.user?.id ?? null,
19
+ entityId: ctx.entityId,
20
+ input: ctx.input
21
+ })
22
+
23
+ // Return an abort result to stop this mutation.
24
+ // return { abort: true, reason: '${entityLabel} is not ready for this change' }
25
+ })
26
+ `
27
+ }
28
+
29
+ export function renderLifecycleHookCodeImportsDetailsTemplate({
30
+ adminImportAlias,
31
+ schemaName,
32
+ event,
33
+ lifecycleHookId
34
+ }: {
35
+ adminImportAlias: string
36
+ schemaName: string
37
+ event: string
38
+ lifecycleHookId: string
39
+ }): string {
40
+ return `import { registerHook } from '${adminImportAlias}/lib/lifecycle-hooks'
41
+
42
+ registerHook('${schemaName}', '${event}', async (ctx) => {
43
+ await fetch('https://example.com/webhooks/${schemaName}/${lifecycleHookId}', {
44
+ method: 'POST',
45
+ headers: { 'Content-Type': 'application/json' },
46
+ body: JSON.stringify({
47
+ actorId: ctx.user?.id ?? null,
48
+ entityType: ctx.entityType,
49
+ entityId: ctx.entityId,
50
+ data: ctx.data
51
+ })
52
+ })
53
+ })
54
+ `
55
+ }
@@ -0,0 +1,33 @@
1
+ export function renderEditPageComponentTemplate({
2
+ singular,
3
+ actionImportPath,
4
+ kebabName,
5
+ camelSingular
6
+ }: {
7
+ singular: string
8
+ actionImportPath: string
9
+ kebabName: string
10
+ camelSingular: string
11
+ }): string {
12
+ return `import { notFound } from 'next/navigation'
13
+ import { get${singular}ById } from '@admin/actions/${actionImportPath}'
14
+ import { ${singular}Form } from '../../${kebabName}-form'
15
+
16
+ interface PageProps {
17
+ params: Promise<{
18
+ id: string
19
+ }>
20
+ }
21
+
22
+ export default async function Edit${singular}Page({ params }: PageProps) {
23
+ const { id } = await params
24
+ const ${camelSingular} = await get${singular}ById(id)
25
+
26
+ if (!${camelSingular}) {
27
+ notFound()
28
+ }
29
+
30
+ return <${singular}Form key={\`\${${camelSingular}.id}-\${${camelSingular}.updatedAt}\`} initialData={${camelSingular}} pageTitle="Edit ${singular}" />
31
+ }
32
+ `
33
+ }