betterstart-cli 0.0.107 → 0.0.109

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 (70) hide show
  1. package/dist/assets/adapters/next/templates/init/admin-globals.css +2 -62
  2. package/dist/assets/adapters/next/templates/init/components/layouts/admin-header.tsx +2 -19
  3. package/dist/assets/adapters/next/templates/init/components/layouts/admin-providers.tsx +4 -7
  4. package/dist/assets/adapters/next/templates/init/components/layouts/admin-sidebar-user-menu.tsx +0 -1
  5. package/dist/assets/adapters/next/templates/init/components/shared/data-table/data-table-pagination.tsx +3 -1
  6. package/dist/assets/adapters/next/templates/init/components/shared/dev-mode/copyable-code-block.tsx +2 -5
  7. package/dist/assets/adapters/next/templates/init/components/shared/dev-mode/dev-mode-code-mirror.tsx +4 -5
  8. package/dist/assets/adapters/next/templates/init/components/shared/dev-mode/dev-mode-types.ts +0 -1
  9. package/dist/assets/adapters/next/templates/init/components/shared/media/edit-media-dialog-content.tsx +1 -0
  10. package/dist/assets/adapters/next/templates/init/components/shared/media/media-grid-pagination.tsx +3 -1
  11. package/dist/assets/adapters/next/templates/init/components/shared/media/media-url-importer.tsx +89 -78
  12. package/dist/assets/adapters/next/templates/init/components/shared/search-input.tsx +5 -1
  13. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor-source-mode.tsx +2 -11
  14. package/dist/assets/adapters/next/templates/init/hooks/content-editor/use-content-editor.ts +1 -2
  15. package/dist/assets/adapters/next/templates/init/pages/forgot-password-form.tsx +42 -37
  16. package/dist/assets/adapters/next/templates/init/pages/login-form.tsx +95 -71
  17. package/dist/assets/adapters/next/templates/init/pages/profile/profile-form.tsx +7 -7
  18. package/dist/assets/adapters/next/templates/init/pages/reset-password-form.tsx +88 -69
  19. package/dist/assets/adapters/next/templates/init/pages/settings/forms/form-notifications-drawer.tsx +1 -0
  20. package/dist/assets/adapters/next/templates/init/pages/settings/webhooks/webhook-endpoint-dialog.tsx +26 -8
  21. package/dist/assets/adapters/next/templates/init/pages/users/change-password-dialog.tsx +8 -10
  22. package/dist/assets/adapters/next/templates/init/pages/users/create-user-dialog.tsx +8 -5
  23. package/dist/assets/adapters/next/templates/init/pages/users/delete-user-dialog.tsx +1 -1
  24. package/dist/assets/adapters/next/templates/init/pages/users/edit-role-dialog.tsx +76 -33
  25. package/dist/assets/shared-assets/react-admin/custom/content-editor/main-toolbar-content.tsx +3 -3
  26. package/dist/assets/shared-assets/react-admin/custom/content-editor/mobile-toolbar-content.tsx +1 -1
  27. package/dist/assets/shared-assets/react-admin/custom/content-editor/selection-bubble-menu.tsx +1 -5
  28. package/dist/assets/shared-assets/react-admin/custom/content-editor/source-mode.tsx +3 -15
  29. package/dist/assets/shared-assets/react-admin/custom/content-editor/table-bubble-menu.tsx +0 -1
  30. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/blockquote-button/blockquote-button.tsx +2 -1
  31. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/code-block-button/code-block-button.tsx +2 -1
  32. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/color-highlight-button/color-highlight-button.tsx +2 -1
  33. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/heading-dropdown-menu/heading-dropdown-menu.tsx +1 -1
  34. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/link-popover/link-control-popover.tsx +2 -1
  35. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/list-dropdown-menu/list-dropdown-menu.tsx +1 -1
  36. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/mark-button/mark-button.tsx +2 -1
  37. package/dist/assets/shared-assets/react-admin/custom/content-editor/tiptap-ui/undo-redo-button/undo-redo-button.tsx +2 -1
  38. package/dist/assets/shared-assets/react-admin/ui/avatar.tsx +1 -1
  39. package/dist/assets/shared-assets/react-admin/ui/badge.tsx +5 -3
  40. package/dist/assets/shared-assets/react-admin/ui/button.tsx +4 -4
  41. package/dist/assets/shared-assets/react-admin/ui/calendar.tsx +1 -1
  42. package/dist/assets/shared-assets/react-admin/ui/chart.tsx +5 -16
  43. package/dist/assets/shared-assets/react-admin/ui/checkbox.tsx +1 -1
  44. package/dist/assets/shared-assets/react-admin/ui/combobox.tsx +12 -2
  45. package/dist/assets/shared-assets/react-admin/ui/context-menu.tsx +1 -1
  46. package/dist/assets/shared-assets/react-admin/ui/drawer.tsx +1 -1
  47. package/dist/assets/shared-assets/react-admin/ui/dropdown-menu.tsx +24 -21
  48. package/dist/assets/shared-assets/react-admin/ui/field.tsx +1 -1
  49. package/dist/assets/shared-assets/react-admin/ui/input-group.tsx +9 -3
  50. package/dist/assets/shared-assets/react-admin/ui/input-otp.tsx +2 -2
  51. package/dist/assets/shared-assets/react-admin/ui/input.tsx +1 -1
  52. package/dist/assets/shared-assets/react-admin/ui/kbd.tsx +1 -1
  53. package/dist/assets/shared-assets/react-admin/ui/menubar.tsx +1 -1
  54. package/dist/assets/shared-assets/react-admin/ui/native-select.tsx +1 -1
  55. package/dist/assets/shared-assets/react-admin/ui/radio-group.tsx +1 -1
  56. package/dist/assets/shared-assets/react-admin/ui/select.tsx +1 -1
  57. package/dist/assets/shared-assets/react-admin/ui/sonner.tsx +2 -5
  58. package/dist/assets/shared-assets/react-admin/ui/switch.tsx +2 -2
  59. package/dist/assets/shared-assets/react-admin/ui/tabs.tsx +3 -3
  60. package/dist/assets/shared-assets/react-admin/ui/textarea.tsx +1 -1
  61. package/dist/assets/shared-assets/react-admin/ui/toggle.tsx +1 -1
  62. package/dist/{chunk-OYU73Q2W.js → chunk-PSDUGFMD.js} +2 -2
  63. package/dist/{chunk-OYU73Q2W.js.map → chunk-PSDUGFMD.js.map} +1 -1
  64. package/dist/cli.js +240 -193
  65. package/dist/cli.js.map +1 -1
  66. package/dist/{read-namespaced-template-EIH2NPDJ.js → read-namespaced-template-TSATYQPP.js} +2 -2
  67. package/package.json +1 -1
  68. package/dist/assets/adapters/next/templates/init/hooks/use-admin-theme.tsx +0 -72
  69. package/dist/assets/adapters/next/templates/init/utils/theme/system.ts +0 -6
  70. /package/dist/{read-namespaced-template-EIH2NPDJ.js.map → read-namespaced-template-TSATYQPP.js.map} +0 -0
package/dist/cli.js CHANGED
@@ -83,7 +83,7 @@ import {
83
83
  trimDotSlash,
84
84
  usesIdentifier,
85
85
  validateAdminNamespace
86
- } from "./chunk-OYU73Q2W.js";
86
+ } from "./chunk-PSDUGFMD.js";
87
87
 
88
88
  // cli.ts
89
89
  import * as p66 from "@clack/prompts";
@@ -2794,7 +2794,6 @@ var REACT_ADMIN_DEPS = [
2794
2794
  "katex",
2795
2795
  "lodash.throttle",
2796
2796
  "motion",
2797
- "next-themes",
2798
2797
  "react-day-picker",
2799
2798
  "react-hotkeys-hook",
2800
2799
  "react-resizable-panels",
@@ -2852,7 +2851,6 @@ var STATIC_CUSTOM_DEPENDENCIES = {
2852
2851
  "use-content-editor-source-mode",
2853
2852
  "use-content-editor-mobile-toolbar",
2854
2853
  "use-content-editor-slash-menu",
2855
- "use-admin-theme",
2856
2854
  "use-mobile",
2857
2855
  "tiptap",
2858
2856
  "tiptap-utils"
@@ -13443,7 +13441,7 @@ function renderLinkColumnCell({ columnAccessorKey }) {
13443
13441
  href={value}
13444
13442
  target="_blank"
13445
13443
  rel="noopener noreferrer"
13446
- className="text-sm text-blue-600 hover:text-blue-800 hover:underline dark:text-blue-400 dark:hover:text-blue-300"
13444
+ className="text-sm text-blue-600 hover:text-blue-800 hover:underline"
13447
13445
  title={value}
13448
13446
  >
13449
13447
  {truncateText(value, 50)}
@@ -14208,7 +14206,7 @@ function renderFirstColumnDefClickHandlerTemplate({
14208
14206
  href={value}
14209
14207
  target="_blank"
14210
14208
  rel="noopener noreferrer"
14211
- 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]"
14209
+ className="text-sm text-blue-600 hover:text-blue-800 hover:underline truncate block max-w-[250px]"
14212
14210
  title={value}
14213
14211
  onClick={(e) => e.stopPropagation()}
14214
14212
  >
@@ -16119,9 +16117,11 @@ ${contentStateDestructure}
16119
16117
  } = state
16120
16118
  ${contentSidebarVisibilityState}
16121
16119
  return (
16122
- <form id="${schemaName}-form" onSubmit={form.handleSubmit((values) => onSubmit(values${hasDraftInitialData}), handleErrors)} ${topLevelTabsFieldClassName}>
16123
- ${formBodyJsx}
16124
- </form>
16120
+ <Form {...form}>
16121
+ <form autoComplete="off" id="${schemaName}-form" onSubmit={form.handleSubmit((values) => onSubmit(values${hasDraftInitialData}), handleErrors)} ${topLevelTabsFieldClassName}>
16122
+ ${formBodyJsx}
16123
+ </form>
16124
+ </Form>
16125
16125
  )
16126
16126
  }
16127
16127
  `;
@@ -16347,7 +16347,7 @@ ${defaultValues}
16347
16347
 
16348
16348
  const form = useForm<FormValues>({
16349
16349
  resolver: standardSchemaResolver(formSchema),
16350
- mode: 'onBlur',
16350
+ mode: 'onChange',
16351
16351
  reValidateMode: 'onChange',
16352
16352
  defaultValues
16353
16353
  })
@@ -16524,16 +16524,12 @@ function renderFormTabContentDetailsTemplate({
16524
16524
  contentComponentName
16525
16525
  }) {
16526
16526
  return ` <TabsContent value="${tabName}" className="h-full min-h-0 w-full flex-1">
16527
- <Form {...entityForm.form}>
16528
- <${contentComponentName} state={entityForm} tab="${tabName}" />
16529
- </Form>
16527
+ <${contentComponentName} state={entityForm} tab="${tabName}" />
16530
16528
  </TabsContent>`;
16531
16529
  }
16532
16530
  function renderEntityFormBody({ contentComponentName }) {
16533
16531
  return ` <main className="w-full p-4 h-full">
16534
- <Form {...entityForm.form}>
16535
- <${contentComponentName} state={entityForm} />
16536
- </Form>
16532
+ <${contentComponentName} state={entityForm} />
16537
16533
  </main>`;
16538
16534
  }
16539
16535
  function renderEntityFormPage({
@@ -16559,7 +16555,6 @@ function renderEntityFormPage({
16559
16555
  ${showMetadataWidgetScrollThresholdImport}
16560
16556
  ${topLevelTabIconNamesLucide}
16561
16557
  import { Button } from '@admin/components/ui/button'
16562
- import { Form } from '@admin/components/ui/form'
16563
16558
  ${topLevelTabsFieldTabs}import { PageHeader } from '@admin/components/shared/page-header'${showMetadataWidgetEntityMetadataImport}
16564
16559
  import type { ${singular} } from '@admin/actions/${actionImportPath}'
16565
16560
  ${showMetadataWidgetAdmin}
@@ -16720,7 +16715,8 @@ function buildEntityFormArtifacts({
16720
16715
  });
16721
16716
  const shellBody = topLevelTabsField ? topLevelTabsShell : defaultShellBody;
16722
16717
  const topLevelTabComponentImports = topLevelTabComponents.map((spec) => `import { ${spec.componentName} } from './${spec.fileBaseName}'`).join("\n");
16723
- const contentImports = topLevelTabsField ? `import type { TabValue, ${hookName} } from '${hookImportPath}'${topLevelTabComponentImports ? `
16718
+ const contentImports = topLevelTabsField ? `import { Form } from '@admin/components/ui/form'
16719
+ import type { TabValue, ${hookName} } from '${hookImportPath}'${topLevelTabComponentImports ? `
16724
16720
  ${topLevelTabComponentImports}` : ""}` : renderEntityFormContentRenderer({
16725
16721
  kind: "renderFormContentLucideTemplate",
16726
16722
  props: {
@@ -18707,6 +18703,7 @@ ${indent} ) : null}`;
18707
18703
  function renderMultiSelectFieldActionButtonsSerializedValueTemplate({
18708
18704
  indent,
18709
18705
  fieldName,
18706
+ optionsId,
18710
18707
  optionsDeclaration,
18711
18708
  createState,
18712
18709
  previewLimit,
@@ -18749,6 +18746,7 @@ ${indent} type="button"
18749
18746
  ${indent} variant="outline"
18750
18747
  ${indent} role="combobox"
18751
18748
  ${indent} aria-expanded={${openVar}}
18749
+ ${indent} aria-controls="${optionsId}"
18752
18750
  ${indent} className={cn("w-full justify-between gap-2", {
18753
18751
  ${indent} "text-muted-foreground": selectedOptions.length === 0
18754
18752
  ${indent} })}
@@ -18790,7 +18788,7 @@ ${indent} </Button>
18790
18788
  ${indent} </FormControl>
18791
18789
  ${indent} }
18792
18790
  ${indent} />
18793
- ${indent} <PopoverContent className="w-(--anchor-width) p-0" align="start">
18791
+ ${indent} <PopoverContent id="${optionsId}" className="w-(--anchor-width) p-0" align="start">
18794
18792
  ${indent} <Command>
18795
18793
  ${indent} ${searchInput}
18796
18794
  ${indent} <CommandList>
@@ -18860,6 +18858,7 @@ function renderMultiSelectField(field, indent, label, hintJSX, context) {
18860
18858
  const placeholder = field.placeholder || `Select ${label.toLowerCase()}`;
18861
18859
  const previewLimit = Math.max(1, Math.floor(field.previewLimit ?? 1));
18862
18860
  const lowerLabel = label.toLowerCase();
18861
+ const optionsId = `${context.schemaName ? `${toKebabCase(singularize(context.schemaName))}-` : ""}${toKebabCase(field.name)}-options`;
18863
18862
  const optionsDeclaration = isCreatable ? `const options = ${optionsVar}` : renderMultiSelectFieldRenderer({
18864
18863
  kind: "renderMultiSelectFieldStaticOptionsTemplate",
18865
18864
  props: {
@@ -18898,6 +18897,7 @@ ${indent} ${setSearchVar}('')` : "";
18898
18897
  props: {
18899
18898
  indent,
18900
18899
  fieldName: field.name,
18900
+ optionsId,
18901
18901
  optionsDeclaration,
18902
18902
  createState,
18903
18903
  previewLimit,
@@ -19212,6 +19212,7 @@ function buildEntityFormLayout({
19212
19212
  (tabField) => generateFieldJSX2(tabField, `${cardFieldIndent} `, {
19213
19213
  creatableSelectFieldNames,
19214
19214
  defaultValueFromSourceNames,
19215
+ schemaName,
19215
19216
  ...childContext
19216
19217
  })
19217
19218
  ).filter(Boolean).join("\n");
@@ -19258,6 +19259,7 @@ function buildEntityFormLayout({
19258
19259
  return generateFieldJSX2(field, cardFieldIndent, {
19259
19260
  creatableSelectFieldNames,
19260
19261
  defaultValueFromSourceNames,
19262
+ schemaName,
19261
19263
  slotFilter: "main"
19262
19264
  });
19263
19265
  };
@@ -19265,7 +19267,8 @@ function buildEntityFormLayout({
19265
19267
  if (field.type === "tabs") return renderNestedTabsField(field);
19266
19268
  return generateFieldJSX2(field, cardFieldIndent, {
19267
19269
  creatableSelectFieldNames,
19268
- defaultValueFromSourceNames
19270
+ defaultValueFromSourceNames,
19271
+ schemaName
19269
19272
  });
19270
19273
  };
19271
19274
  const renderConditionalSidebarEntry = ({
@@ -19373,6 +19376,7 @@ function buildEntityFormLayout({
19373
19376
  (field) => generateFieldJSX2(field, cardFieldIndent, {
19374
19377
  creatableSelectFieldNames,
19375
19378
  defaultValueFromSourceNames,
19379
+ schemaName,
19376
19380
  slotFilter: "main"
19377
19381
  })
19378
19382
  ).filter(Boolean).join("\n");
@@ -19707,7 +19711,7 @@ function generateForm(schema, pagesDir, options = {}) {
19707
19711
  hasNestedObjectList,
19708
19712
  hasCardContent: true,
19709
19713
  hasSectionCardHeading,
19710
- hasFormRoot: false,
19714
+ hasFormRoot: true,
19711
19715
  hasButton: hasRelationship || hasSelectCombobox || hasNestedList,
19712
19716
  hasFormControls: contentUsesFormControls || contentHasRenderedIconPostfix,
19713
19717
  hasInput: contentUsesInput
@@ -22402,37 +22406,24 @@ function renderSingleFormImportsTemplate({ map }) {
22402
22406
  ${map}
22403
22407
  } from '@admin/components/ui/card'`;
22404
22408
  }
22405
- function renderSingleFormClientModuleTemplate({
22406
- needsReactImport,
22407
- hasCreatableSelectUseQuery,
22408
- lucideIconsLucide,
22409
- hasNestedListUseFieldArray,
22410
- hasTabsFieldImport,
22411
- hasRelationshipImport,
22412
- relHookImportsContent,
22413
- join,
22409
+ function renderSingleFormCardModuleTemplate({
22410
+ imports,
22411
+ content
22412
+ }) {
22413
+ return `'use client'
22414
+ ${imports}
22415
+
22416
+ ${content}
22417
+ `;
22418
+ }
22419
+ function renderSingleFormEntryModuleTemplate({
22414
22420
  singular,
22415
- hasCreatableSelectContent,
22416
22421
  actionImportPath,
22417
- hasCreatableSelectContentText,
22418
- joinText,
22422
+ cardImports,
22419
22423
  cardRenders
22420
22424
  }) {
22421
- return `'use client'
22422
- ${needsReactImport}
22423
- import { standardSchemaResolver } from '@hookform/resolvers/standard-schema'
22424
- import { useMutation, ${hasCreatableSelectUseQuery}useQueryClient } from '@tanstack/react-query'${lucideIconsLucide}
22425
- import {${hasNestedListUseFieldArray} useForm } from 'react-hook-form'
22426
- import { toast } from 'sonner'
22427
- import { z } from 'zod/v3'${hasTabsFieldImport}${hasRelationshipImport}
22428
- ${relHookImportsContent}${join}
22429
- import type {
22430
- ${singular},
22431
- ${hasCreatableSelectContent}${singular}UpsertInput
22432
- } from '@admin/actions/${actionImportPath}'
22433
- import { ${hasCreatableSelectContentText}upsert${singular} } from '@admin/actions/${actionImportPath}'
22434
-
22435
- ${joinText}
22425
+ return `import type { ${singular} } from '@admin/actions/${actionImportPath}'
22426
+ ${cardImports}
22436
22427
 
22437
22428
  interface ${singular}FormProps {
22438
22429
  initialData?: ${singular} | null
@@ -22451,8 +22442,10 @@ function renderSingleFormRenderer(request) {
22451
22442
  switch (request.kind) {
22452
22443
  case "renderSingleFormImportsTemplate":
22453
22444
  return renderSingleFormImportsTemplate(request.props);
22454
- case "renderSingleFormClientModuleTemplate":
22455
- return renderSingleFormClientModuleTemplate(request.props);
22445
+ case "renderSingleFormCardModuleTemplate":
22446
+ return renderSingleFormCardModuleTemplate(request.props);
22447
+ case "renderSingleFormEntryModuleTemplate":
22448
+ return renderSingleFormEntryModuleTemplate(request.props);
22456
22449
  }
22457
22450
  throw new Error("Unsupported renderer request");
22458
22451
  }
@@ -22538,12 +22531,12 @@ ${zodFields}
22538
22531
  })
22539
22532
  ${tabParserConst}
22540
22533
 
22541
- function ${groupComponentName}({ initialData }: { initialData?: ${singular} | null }) {
22534
+ export function ${groupComponentName}({ initialData }: { initialData?: ${singular} | null }) {
22542
22535
  const queryClient = useQueryClient()${analysisHasTabsFieldTab}${relStateContent}${creatableSelectStateContent}${selectStateContent}
22543
22536
 
22544
22537
  const form = useForm<z.infer<typeof ${groupVarPrefix}Schema>>({
22545
22538
  resolver: standardSchemaResolver(${groupVarPrefix}Schema),
22546
- mode: 'onBlur',
22539
+ mode: 'onChange',
22547
22540
  reValidateMode: 'onChange',
22548
22541
  defaultValues: {
22549
22542
  ${defaultValues}
@@ -22573,7 +22566,7 @@ ${fieldArrayHooksContent}
22573
22566
  ${creatableSelectHandlersContent}
22574
22567
  return (
22575
22568
  <Form {...form}>
22576
- <form onSubmit={form.handleSubmit((values) => {
22569
+ <form autoComplete="off" onSubmit={form.handleSubmit((values) => {
22577
22570
  mutation.mutate(values as ${singular}UpsertInput)
22578
22571
  })}>
22579
22572
  <Card >
@@ -22807,7 +22800,7 @@ function renderSingleFormBuildGroupFieldsJsxRenderer(request) {
22807
22800
  }
22808
22801
 
22809
22802
  // adapters/next/generators/form/form-single/build-group-fields-jsx.ts
22810
- function buildGroupFieldsJSX(group2, analysis, defaultValueFromSourceNames, creatableSelectFieldNames) {
22803
+ function buildGroupFieldsJSX(group2, analysis, defaultValueFromSourceNames, creatableSelectFieldNames, schemaName) {
22811
22804
  const indent = " ";
22812
22805
  return group2.fields.map((f) => {
22813
22806
  if (f.type === "tabs" && f.tabs) {
@@ -22816,7 +22809,8 @@ function buildGroupFieldsJSX(group2, analysis, defaultValueFromSourceNames, crea
22816
22809
  const tabFields = (t.fields || []).map(
22817
22810
  (tf) => generateFieldJSX2(tf, " ", {
22818
22811
  creatableSelectFieldNames,
22819
- defaultValueFromSourceNames
22812
+ defaultValueFromSourceNames,
22813
+ schemaName
22820
22814
  })
22821
22815
  ).join("\n");
22822
22816
  return renderSingleFormBuildGroupFieldsJsxRenderer({
@@ -22840,7 +22834,8 @@ function buildGroupFieldsJSX(group2, analysis, defaultValueFromSourceNames, crea
22840
22834
  if (analysis.tabFieldNames.has(f.name)) return "";
22841
22835
  return generateFieldJSX2(f, indent, {
22842
22836
  creatableSelectFieldNames,
22843
- defaultValueFromSourceNames
22837
+ defaultValueFromSourceNames,
22838
+ schemaName
22844
22839
  });
22845
22840
  }).filter(Boolean).join("\n");
22846
22841
  }
@@ -22882,7 +22877,8 @@ function generateCardComponent(group2, schema, analysis, allFlatFields) {
22882
22877
  group2,
22883
22878
  analysis,
22884
22879
  defaultValueFromSourceNames,
22885
- creatableSelectFieldNames
22880
+ creatableSelectFieldNames,
22881
+ schema.name
22886
22882
  );
22887
22883
  const relState = buildGroupRelState(analysis);
22888
22884
  const selectState = buildGroupSelectState(
@@ -23045,135 +23041,179 @@ function generateSingleForm(schema, pagesDir, options = {}) {
23045
23041
  (f) => !f.primaryKey && f.name !== "createdAt" && f.name !== "updatedAt" && !isAuthorshipFieldName(f.name)
23046
23042
  );
23047
23043
  const cardGroups = parseCardGroups(allFormFields, schema.label);
23048
- const hasBoolean = hasFieldType(schema.fields, "boolean");
23049
- const hasImage = hasFieldType(schema.fields, "image");
23050
- const hasVideo = hasFieldType(schema.fields, "video");
23051
- const hasMedia = hasFieldType(schema.fields, "media");
23052
- const hasGallery = hasFieldType(schema.fields, "gallery");
23053
- const hasIcon = hasFieldType(schema.fields, "icon");
23054
- const hasIconPostfix = hasRenderedIconPostfix(allFormFields);
23055
- const hasDate = hasFieldType(schema.fields, "date");
23056
23044
  const flatFields = flattenFields(allFormFields);
23057
- const hasMultiSelect = flatFields.some((f) => f.type === "select" && f.multiple === true);
23058
- const hasCreatableSelect = flatFields.some((f) => f.type === "select" && f.creatable === true);
23059
- const hasSelectCombobox = hasMultiSelect || hasCreatableSelect;
23060
- const hasSelect = flatFields.some(
23061
- (f) => f.type === "select" && f.multiple !== true && f.creatable !== true
23062
- );
23063
- const hasMarkdown = hasFieldType(schema.fields, "markdown");
23064
- const hasRichtext = hasFieldType(schema.fields, "richtext");
23065
- const hasTextarea = hasFieldType(schema.fields, "text");
23066
- const hasSeparator = hasFieldType(schema.fields, "separator");
23067
- const hasRelationship = hasFieldType(schema.fields, "relationship");
23068
- const hasTabsField = cardGroups.some((group2) => analyzeGroup(group2.fields).hasTabsField);
23069
- const hasList = hasFieldType(schema.fields, "list");
23070
- const hasNestedList = cardGroups.some(
23071
- (g) => analyzeGroup(g.fields).listFieldsWithNested.length > 0
23072
- );
23073
- const hasNestedObjectList = cardGroups.some(
23074
- (group2) => analyzeGroup(group2.fields).hasNestedObjectList
23075
- );
23076
- const hasSimpleList = hasList && hasSimpleListField(allFormFields);
23077
- const tabIconNames = collectTabIconNames(allFormFields);
23078
- const allRelFields = [];
23079
- for (const g of cardGroups) {
23080
- const a = analyzeGroup(g.fields);
23081
- for (const rf of a.relFields) {
23082
- if (!allRelFields.some((e) => e.relationship === rf.relationship)) {
23083
- allRelFields.push(rf);
23045
+ const inputFreeFieldTypes = /* @__PURE__ */ new Set([
23046
+ "boolean",
23047
+ "image",
23048
+ "video",
23049
+ "media",
23050
+ "gallery",
23051
+ "icon",
23052
+ "date",
23053
+ "select",
23054
+ "richtext",
23055
+ "markdown",
23056
+ "text",
23057
+ "relationship",
23058
+ "list",
23059
+ "separator",
23060
+ "tabs"
23061
+ ]);
23062
+ const formControlFreeFieldTypes = /* @__PURE__ */ new Set(["separator", "tabs"]);
23063
+ const cardArtifacts = cardGroups.map((group2) => {
23064
+ const analysis = analyzeGroup(group2.fields);
23065
+ const groupFlatFields = group2.flatFields;
23066
+ const creatableSelectFields = groupFlatFields.filter(
23067
+ (field) => field.type === "select" && field.creatable === true
23068
+ );
23069
+ const hasCreatableSelect = creatableSelectFields.length > 0;
23070
+ const hasMultiSelect = analysis.multiSelectFields.length > 0;
23071
+ const hasRelationship = analysis.relFields.length > 0;
23072
+ const hasSelectCombobox = hasRelationship || hasMultiSelect || hasCreatableSelect;
23073
+ const hasSelect = groupFlatFields.some(
23074
+ (field) => field.type === "select" && field.multiple !== true && field.creatable !== true
23075
+ );
23076
+ const hasIconPostfix = hasRenderedIconPostfix(group2.fields);
23077
+ const hasNestedList = analysis.listFieldsWithNested.length > 0;
23078
+ const hasInput = analysis.listFieldsWithNested.some(
23079
+ (field) => field.fields?.some(
23080
+ (nestedField) => !["boolean", "image", "video", "media"].includes(nestedField.type)
23081
+ )
23082
+ ) || groupFlatFields.some(
23083
+ (field) => !field.primaryKey && !field.hidden && !inputFreeFieldTypes.has(field.type)
23084
+ );
23085
+ const hasFormControls = groupFlatFields.some((field) => {
23086
+ if (field.primaryKey || field.hidden) return false;
23087
+ if (field.hasIcon && !["group", "section", "tabs", "separator"].includes(field.type)) {
23088
+ return true;
23084
23089
  }
23090
+ if (field.type === "list" && (!field.fields || field.fields.length === 0)) return false;
23091
+ return !formControlFreeFieldTypes.has(field.type);
23092
+ }) || hasIconPostfix;
23093
+ const groupUiImports = buildUiImports({
23094
+ hasBoolean: hasFieldType(group2.fields, "boolean"),
23095
+ hasTextarea: hasFieldType(group2.fields, "text"),
23096
+ hasImage: hasFieldType(group2.fields, "image"),
23097
+ hasVideo: hasFieldType(group2.fields, "video"),
23098
+ hasMedia: hasFieldType(group2.fields, "media"),
23099
+ hasGallery: hasFieldType(group2.fields, "gallery"),
23100
+ hasIcon: hasFieldType(group2.fields, "icon"),
23101
+ hasIconPostfix,
23102
+ hasDate: hasFieldType(group2.fields, "date"),
23103
+ hasMarkdown: hasFieldType(group2.fields, "markdown"),
23104
+ hasRichtext: hasFieldType(group2.fields, "richtext"),
23105
+ hasSeparator: hasFieldType(group2.fields, "separator"),
23106
+ hasSelect,
23107
+ hasSelectCombobox,
23108
+ hasCreatableSelect,
23109
+ hasMultiSelect,
23110
+ hasTabsField: analysis.hasTabsField,
23111
+ hasRelationship,
23112
+ hasSimpleList: hasSimpleListField(group2.fields),
23113
+ hasNestedList,
23114
+ hasNestedObjectList: analysis.hasNestedObjectList,
23115
+ hasCardContent: true,
23116
+ hasSectionCardHeading: true,
23117
+ hasFormRoot: true,
23118
+ hasButton: true,
23119
+ hasFormControls,
23120
+ hasInput
23121
+ });
23122
+ const cardImportIndex = groupUiImports.findIndex(
23123
+ (value) => value.includes("from '@admin/components/ui/card'")
23124
+ );
23125
+ if (cardImportIndex !== -1) {
23126
+ const cardImportNames = [
23127
+ "Card",
23128
+ "CardContent",
23129
+ ...group2.description ? ["CardDescription"] : [],
23130
+ "CardFooter",
23131
+ "CardHeader",
23132
+ "CardTitle"
23133
+ ];
23134
+ groupUiImports[cardImportIndex] = renderSingleFormRenderer({
23135
+ kind: "renderSingleFormImportsTemplate",
23136
+ props: {
23137
+ map: cardImportNames.map((name) => ` ${name}`).join(",\n")
23138
+ }
23139
+ });
23085
23140
  }
23086
- }
23087
- const needsReact = allRelFields.length > 0 || hasNestedList || hasSelectCombobox;
23088
- const uiImports = buildUiImports({
23089
- hasBoolean,
23090
- hasTextarea,
23091
- hasImage,
23092
- hasVideo,
23093
- hasMedia,
23094
- hasGallery,
23095
- hasIcon,
23096
- hasIconPostfix,
23097
- hasDate,
23098
- hasMarkdown,
23099
- hasRichtext,
23100
- hasSeparator,
23101
- hasSelect,
23102
- hasSelectCombobox,
23103
- hasCreatableSelect,
23104
- hasMultiSelect,
23105
- hasTabsField,
23106
- hasRelationship,
23107
- hasSimpleList,
23108
- hasNestedList,
23109
- hasNestedObjectList
23110
- });
23111
- const cardImportIndex = uiImports.indexOf("import { Card } from '@admin/components/ui/card'");
23112
- if (cardImportIndex !== -1) {
23113
- uiImports.splice(cardImportIndex, 1);
23114
- }
23115
- const cardImportNames = [
23116
- "Card",
23117
- "CardContent",
23118
- ...cardGroups.some((group2) => group2.description) ? ["CardDescription"] : [],
23119
- "CardFooter",
23120
- "CardHeader",
23121
- "CardTitle"
23122
- ];
23123
- uiImports.push(
23124
- renderSingleFormRenderer({
23125
- kind: "renderSingleFormImportsTemplate",
23141
+ groupUiImports.push("import { Spinner } from '@admin/components/ui/spinner'");
23142
+ const lucideIcons = [];
23143
+ const addLucideIcons = (...icons) => {
23144
+ for (const icon of icons) {
23145
+ if (!lucideIcons.includes(icon)) lucideIcons.push(icon);
23146
+ }
23147
+ };
23148
+ addLucideIcons(...collectTabIconNames(group2.fields));
23149
+ if (hasSelectCombobox) addLucideIcons("Check", "ChevronsUpDown");
23150
+ if (hasCreatableSelect || hasNestedList) addLucideIcons("Plus");
23151
+ if (hasNestedList) addLucideIcons("X");
23152
+ const relationshipImports = Array.from(
23153
+ new Set(analysis.relFields.map((field) => field.relationship).filter(Boolean))
23154
+ ).map((relationship) => {
23155
+ const relationshipPlural = toPascalCase(pluralize(relationship || ""));
23156
+ return `import { use${relationshipPlural} } from '@admin/hooks/use-${relationship}'`;
23157
+ }).join("\n");
23158
+ const needsReact = hasRelationship || hasMultiSelect || hasCreatableSelect || analysis.listFieldsWithNested.length > 0;
23159
+ const hookImports = ["useForm"];
23160
+ if (hasNestedList) hookImports.unshift("useFieldArray");
23161
+ const actionTypeImports = [
23162
+ Singular,
23163
+ ...hasCreatableSelect ? [`${Singular}SelectOption`] : [],
23164
+ `${Singular}UpsertInput`
23165
+ ];
23166
+ const actionImports = [
23167
+ ...hasCreatableSelect ? [`create${Singular}SelectOption`, `get${Singular}SelectOptions`] : [],
23168
+ `upsert${Singular}`
23169
+ ];
23170
+ const cardImports = [
23171
+ needsReact ? "import * as React from 'react'" : "",
23172
+ "import { standardSchemaResolver } from '@hookform/resolvers/standard-schema'",
23173
+ `import { useMutation, ${hasCreatableSelect ? "useQuery, " : ""}useQueryClient } from '@tanstack/react-query'`,
23174
+ lucideIcons.length > 0 ? `import { ${lucideIcons.join(", ")} } from 'lucide-react'` : "",
23175
+ `import { ${hookImports.join(", ")} } from 'react-hook-form'`,
23176
+ "import { toast } from 'sonner'",
23177
+ "import { z } from 'zod/v3'",
23178
+ analysis.hasTabsField ? "import { parseAsStringLiteral, useQueryState } from 'nuqs'" : "",
23179
+ hasSelectCombobox ? "import { cn } from '@admin/utils/shared/cn'" : "",
23180
+ relationshipImports,
23181
+ groupUiImports.join("\n"),
23182
+ `import type { ${actionTypeImports.join(",\n ")} } from '@admin/actions/${actionImportPath}'`,
23183
+ `import { ${actionImports.join(", ")} } from '@admin/actions/${actionImportPath}'`
23184
+ ].filter(Boolean).join("\n");
23185
+ const content2 = renderSingleFormRenderer({
23186
+ kind: "renderSingleFormCardModuleTemplate",
23126
23187
  props: {
23127
- map: cardImportNames.map((name) => ` ${name}`).join(",\n")
23188
+ imports: cardImports,
23189
+ content: generateCardComponent(group2, schema, analysis, flatFields)
23128
23190
  }
23129
- })
23130
- );
23131
- uiImports.push("import { Spinner } from '@admin/components/ui/spinner'");
23132
- const lucideIcons = [];
23133
- const addLucideIcons = (...icons) => {
23134
- for (const icon of icons) {
23135
- if (!lucideIcons.includes(icon)) lucideIcons.push(icon);
23136
- }
23137
- };
23138
- addLucideIcons(...tabIconNames);
23139
- if (hasRelationship || hasSelectCombobox) addLucideIcons("Check", "ChevronsUpDown");
23140
- if (hasCreatableSelect) addLucideIcons("Plus");
23141
- if (hasNestedList) {
23142
- addLucideIcons("Plus", "X");
23143
- }
23144
- const relHookImports = allRelFields.map((f) => {
23145
- const relPlural = toPascalCase(pluralize(f.relationship || ""));
23146
- return `import { use${relPlural} } from '@admin/hooks/use-${f.relationship}'`;
23147
- }).filter((v, i, a) => a.indexOf(v) === i).join("\n");
23148
- const cardComponents = cardGroups.map((group2) => {
23149
- const analysis = analyzeGroup(group2.fields);
23150
- return generateCardComponent(group2, schema, analysis, flatFields);
23191
+ });
23192
+ return {
23193
+ content: content2,
23194
+ fileName: `${toKebabCase(group2.componentName)}.tsx`,
23195
+ group: group2
23196
+ };
23151
23197
  });
23152
- const cardRenders = cardGroups.map((g) => ` <${g.componentName} initialData={initialData} />`).join("\n");
23198
+ const cardRenders = cardArtifacts.map(({ group: group2 }) => ` <${group2.componentName} initialData={initialData} />`).join("\n");
23153
23199
  const content = renderSingleFormRenderer({
23154
- kind: "renderSingleFormClientModuleTemplate",
23200
+ kind: "renderSingleFormEntryModuleTemplate",
23155
23201
  props: {
23156
- needsReactImport: needsReact ? "\nimport * as React from 'react'" : "",
23157
- hasCreatableSelectUseQuery: hasCreatableSelect ? "useQuery, " : "",
23158
- lucideIconsLucide: lucideIcons.length > 0 ? `
23159
- import { ${lucideIcons.join(", ")} } from 'lucide-react'` : "",
23160
- hasNestedListUseFieldArray: hasNestedList ? " useFieldArray," : "",
23161
- hasTabsFieldImport: hasTabsField ? "\nimport { parseAsStringLiteral, useQueryState } from 'nuqs'" : "",
23162
- hasRelationshipImport: hasRelationship || hasSelectCombobox ? "\nimport { cn } from '@admin/utils/shared/cn'" : "",
23163
- relHookImportsContent: relHookImports ? `${relHookImports}
23164
- ` : "",
23165
- join: uiImports.join("\n"),
23166
23202
  singular: Singular,
23167
- hasCreatableSelectContent: hasCreatableSelect ? `${Singular}SelectOption,
23168
- ` : "",
23169
23203
  actionImportPath,
23170
- hasCreatableSelectContentText: hasCreatableSelect ? `create${Singular}SelectOption, get${Singular}SelectOptions, ` : "",
23171
- joinText: cardComponents.join("\n\n"),
23204
+ cardImports: cardArtifacts.map(
23205
+ ({ fileName, group: group2 }) => `import { ${group2.componentName} } from './${fileName.slice(0, -4)}'`
23206
+ ).join("\n"),
23172
23207
  cardRenders
23173
23208
  }
23174
23209
  });
23175
23210
  return {
23176
- files: [createGeneratedFile(`${pagesDir}/${schema.name}/${schema.name}-form.tsx`, content)]
23211
+ files: [
23212
+ createGeneratedFile(`${pagesDir}/${schema.name}/${schema.name}-form.tsx`, content),
23213
+ ...cardArtifacts.map(
23214
+ ({ content: cardContent, fileName }) => createGeneratedFile(`${pagesDir}/${schema.name}/${fileName}`, cardContent)
23215
+ )
23216
+ ]
23177
23217
  };
23178
23218
  }
23179
23219
 
@@ -31671,7 +31711,6 @@ function scaffoldComponents({ cwd, config }) {
31671
31711
  "utils/table/default-get-id.ts",
31672
31712
  "utils/table/is-string.ts",
31673
31713
  "utils/text/text.ts",
31674
- "utils/theme/system.ts",
31675
31714
  "utils/upload/default-remote-accept.ts",
31676
31715
  "utils/upload/dropzone-accept.ts",
31677
31716
  "utils/upload/get-fallback-extension.ts",
@@ -31775,7 +31814,6 @@ function scaffoldComponents({ cwd, config }) {
31775
31814
  write("hooks/use-copy-to-clipboard.ts", readTemplate("hooks/use-copy-to-clipboard.ts"));
31776
31815
  write("hooks/use-dev-mode-integration.ts", readTemplate("hooks/use-dev-mode-integration.ts"));
31777
31816
  write("hooks/use-local-storage.ts", readTemplate("hooks/use-local-storage.ts"));
31778
- write("hooks/use-admin-theme.tsx", readTemplate("hooks/use-admin-theme.tsx"));
31779
31817
  write("hooks/use-audit-log.ts", readTemplate("hooks/use-audit-log.ts"));
31780
31818
  write("hooks/use-users.ts", readTemplate("hooks/use-users.ts"));
31781
31819
  write("hooks/use-webhooks.ts", readTemplate("hooks/use-webhooks.ts"));
@@ -32424,6 +32462,7 @@ function renderCreateNextConfigTemplateImportsTemplate({
32424
32462
 
32425
32463
  const nextConfig: NextConfig = {
32426
32464
  cacheComponents: true,
32465
+ partialPrefetching: true,
32427
32466
  devIndicators: false,
32428
32467
  images: {
32429
32468
  remotePatterns: [
@@ -32885,6 +32924,11 @@ ${propertyIndent}useCache: true,` + updatedContent.slice(experimentalObjectStart
32885
32924
  };
32886
32925
  }
32887
32926
 
32927
+ // adapters/next/init/scaffolders/next-config/ensure-partial-prefetching.ts
32928
+ function ensurePartialPrefetching(content, configObject) {
32929
+ return upsertTopLevelBooleanProperty(content, configObject, "partialPrefetching");
32930
+ }
32931
+
32888
32932
  // adapters/next/init/scaffolders/next-config/resolve-cache-config-mode.ts
32889
32933
  function resolveCacheConfigMode(nextMajorVersion) {
32890
32934
  if (nextMajorVersion >= 16) return "cache-components";
@@ -32924,18 +32968,32 @@ function scaffoldNextConfig({
32924
32968
  if (cacheUpdateResult.unsupported) {
32925
32969
  return { status: "unsupported" };
32926
32970
  }
32927
- const updatedConfigObject = findConfigObject(cacheUpdateResult.content);
32971
+ let updatedContent = cacheUpdateResult.content;
32972
+ let changed = cacheUpdateResult.changed;
32973
+ if (cacheConfigMode === "cache-components") {
32974
+ const cacheConfigObject = findConfigObject(updatedContent);
32975
+ if (!cacheConfigObject) {
32976
+ return { status: "unsupported" };
32977
+ }
32978
+ const partialPrefetchingUpdateResult = ensurePartialPrefetching(
32979
+ updatedContent,
32980
+ cacheConfigObject
32981
+ );
32982
+ if (partialPrefetchingUpdateResult.unsupported) {
32983
+ return { status: "unsupported" };
32984
+ }
32985
+ updatedContent = partialPrefetchingUpdateResult.content;
32986
+ changed ||= partialPrefetchingUpdateResult.changed;
32987
+ }
32988
+ const updatedConfigObject = findConfigObject(updatedContent);
32928
32989
  if (!updatedConfigObject) {
32929
32990
  return { status: "unsupported" };
32930
32991
  }
32931
- const imagesUpdateResult = ensureBetterStartImageHost(
32932
- cacheUpdateResult.content,
32933
- updatedConfigObject
32934
- );
32992
+ const imagesUpdateResult = ensureBetterStartImageHost(updatedContent, updatedConfigObject);
32935
32993
  if (imagesUpdateResult.unsupported) {
32936
32994
  return { status: "unsupported" };
32937
32995
  }
32938
- const changed = cacheUpdateResult.changed || imagesUpdateResult.changed;
32996
+ changed ||= imagesUpdateResult.changed;
32939
32997
  if (!changed) {
32940
32998
  return { status: "already-set" };
32941
32999
  }
@@ -35707,7 +35765,7 @@ async function runInitCommandInternal(name, options, jsonContext) {
35707
35765
  const drizzleConfigPath = path91.join(cwd, "drizzle.config.ts");
35708
35766
  if (!dbFiles.includes("drizzle.config.ts") && fs78.existsSync(drizzleConfigPath)) {
35709
35767
  if (forceMode) {
35710
- const { readNamespacedTemplate } = await import("./read-namespaced-template-EIH2NPDJ.js");
35768
+ const { readNamespacedTemplate } = await import("./read-namespaced-template-TSATYQPP.js");
35711
35769
  fs78.writeFileSync(
35712
35770
  drizzleConfigPath,
35713
35771
  readNamespacedTemplate("drizzle.config.ts", namespace),
@@ -35720,7 +35778,7 @@ async function runInitCommandInternal(name, options, jsonContext) {
35720
35778
  initialValue: true
35721
35779
  });
35722
35780
  if (!p61.isCancel(overwrite) && overwrite) {
35723
- const { readNamespacedTemplate } = await import("./read-namespaced-template-EIH2NPDJ.js");
35781
+ const { readNamespacedTemplate } = await import("./read-namespaced-template-TSATYQPP.js");
35724
35782
  fs78.writeFileSync(
35725
35783
  drizzleConfigPath,
35726
35784
  readNamespacedTemplate("drizzle.config.ts", namespace),
@@ -36414,8 +36472,7 @@ var TEMPLATE_REGISTRY = {
36414
36472
  "dev-mode-plain-code-fallback",
36415
36473
  "dev-mode-types",
36416
36474
  "tabs",
36417
- "use-copy-to-clipboard",
36418
- "use-admin-theme"
36475
+ "use-copy-to-clipboard"
36419
36476
  ]
36420
36477
  },
36421
36478
  "dev-mode-code-mirror": {
@@ -36637,7 +36694,6 @@ var TEMPLATE_REGISTRY = {
36637
36694
  content: () => readTemplate("hooks/content-editor/use-content-editor-source-mode.tsx"),
36638
36695
  dependencies: [
36639
36696
  "media-field",
36640
- "use-admin-theme",
36641
36697
  "markdown-utils",
36642
36698
  "content-editor-source-media-utils",
36643
36699
  "tiptap-utils"
@@ -36767,11 +36823,6 @@ var TEMPLATE_REGISTRY = {
36767
36823
  relPath: "hooks/use-local-storage.ts",
36768
36824
  content: () => readTemplate("hooks/use-local-storage.ts")
36769
36825
  },
36770
- "use-admin-theme": {
36771
- relPath: "hooks/use-admin-theme.tsx",
36772
- content: () => readTemplate("hooks/use-admin-theme.tsx"),
36773
- dependencies: ["theme-system-utils"]
36774
- },
36775
36826
  "use-audit-log": {
36776
36827
  relPath: "hooks/use-audit-log.ts",
36777
36828
  content: () => readTemplate("hooks/use-audit-log.ts"),
@@ -37796,10 +37847,6 @@ var TEMPLATE_REGISTRY = {
37796
37847
  relPath: "utils/text/text.ts",
37797
37848
  content: () => readTemplate("utils/text/text.ts")
37798
37849
  },
37799
- "theme-system-utils": {
37800
- relPath: "utils/theme/system.ts",
37801
- content: () => readTemplate("utils/theme/system.ts")
37802
- },
37803
37850
  "upload-default-remote-accept": {
37804
37851
  relPath: "utils/upload/default-remote-accept.ts",
37805
37852
  content: () => readTemplate("utils/upload/default-remote-accept.ts")