@betterstart/cli 0.1.71 → 0.1.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -84,7 +84,7 @@ function walkFields(fields, callback, options = DEFAULT_WALK_OPTIONS) {
84
84
  function walk(fieldsToWalk, depth, parent) {
85
85
  for (const field of fieldsToWalk) {
86
86
  callback(field, depth, parent);
87
- if (options.includeGroups && field.type === "group" && field.fields) {
87
+ if (options.includeGroups && (field.type === "group" || field.type === "section") && field.fields) {
88
88
  walk(field.fields, depth + 1, field);
89
89
  }
90
90
  if (options.includeLists && field.type === "list" && field.fields) {
@@ -140,7 +140,7 @@ function flattenFields(fields) {
140
140
  function flattenFieldsWithoutIdCheck(fields) {
141
141
  const flattened = [];
142
142
  for (const field of fields) {
143
- if (field.type === "group" && field.fields) {
143
+ if ((field.type === "group" || field.type === "section") && field.fields) {
144
144
  flattened.push(...flattenFieldsWithoutIdCheck(field.fields));
145
145
  } else if (field.type === "tabs" && field.tabs) {
146
146
  for (const tab of field.tabs) {
@@ -3353,12 +3353,12 @@ var FIELD_TYPES = {
3353
3353
  TABS: "tabs",
3354
3354
  LIST: "list",
3355
3355
  SEPARATOR: "separator",
3356
- BREAK: "break",
3356
+ SECTION: "section",
3357
3357
  SELECT: "select",
3358
3358
  RELATIONSHIP: "relationship",
3359
3359
  CURRICULUM: "curriculum"
3360
3360
  };
3361
- var LAYOUT_FIELD_TYPES = [FIELD_TYPES.SEPARATOR, FIELD_TYPES.BREAK];
3361
+ var LAYOUT_FIELD_TYPES = [FIELD_TYPES.SEPARATOR];
3362
3362
  var NESTED_FIELD_TYPES = [FIELD_TYPES.GROUP, FIELD_TYPES.TABS, FIELD_TYPES.LIST];
3363
3363
  var RICH_TEXT_FIELD_TYPES = [FIELD_TYPES.MARKDOWN, FIELD_TYPES.TEXT];
3364
3364
  var LONG_TEXT_FIELD_TYPES = [
@@ -6139,7 +6139,7 @@ function generateFieldJSXCore(field, indent = " ") {
6139
6139
  const fieldType = getFormFieldType(field);
6140
6140
  const label = field.label || field.name;
6141
6141
  const hintJSX = field.hint ? `${indent} <FormDescription>${field.hint}</FormDescription>` : "";
6142
- if (field.type === "group" && field.fields) return renderGroupField(field, indent, label);
6142
+ if ((field.type === "group" || field.type === "section") && field.fields) return renderGroupField(field, indent, label);
6143
6143
  if (field.type === "separator") return renderSeparatorField(field, indent);
6144
6144
  if (field.type === "boolean") return renderBooleanField(field, indent, label, hintJSX);
6145
6145
  if (field.type === "image") return renderImageField(field, indent, label, hintJSX);
@@ -6969,42 +6969,47 @@ ${hasDraft ? ` <Button
6969
6969
  // src/generators/form/form-single.ts
6970
6970
  import fs21 from "fs";
6971
6971
  import path21 from "path";
6972
- function parseCardGroups(allFormFields) {
6972
+ function parseCardGroups(allFormFields, schemaLabel) {
6973
+ const sections = allFormFields.filter((f) => f.type === "section" && f.fields);
6974
+ const nonSections = allFormFields.filter((f) => f.type !== "section" && !isLayoutField(f.type));
6975
+ if (sections.length === 0) {
6976
+ const title = nonSections[0]?.label || nonSections[0]?.name || schemaLabel;
6977
+ return [
6978
+ {
6979
+ title,
6980
+ description: "",
6981
+ varPrefix: toCamelCase(nonSections[0]?.name || "form"),
6982
+ componentName: `${toPascalCase(nonSections[0]?.name || "form")}Card`,
6983
+ fields: nonSections,
6984
+ flatFields: flattenFields(nonSections).filter((f) => !isLayoutField(f.type))
6985
+ }
6986
+ ];
6987
+ }
6973
6988
  const groups = [];
6974
- let currentFields = [];
6975
- let nextTitle = "";
6976
- let nextDescription = "";
6977
- for (const field of allFormFields) {
6978
- if (field.type === "break") {
6979
- if (currentFields.length > 0) {
6980
- groups.push(buildGroup(currentFields, nextTitle, nextDescription));
6981
- }
6982
- nextTitle = field.label || "";
6983
- nextDescription = field.hint || "";
6984
- currentFields = [];
6985
- continue;
6986
- }
6987
- if (field.type === "separator") continue;
6988
- currentFields.push(field);
6989
+ for (const section of sections) {
6990
+ const innerFields = section.fields || [];
6991
+ groups.push({
6992
+ title: section.label || section.name,
6993
+ description: section.description || section.hint || "",
6994
+ varPrefix: toCamelCase(section.name),
6995
+ componentName: `${toPascalCase(section.name)}Card`,
6996
+ fields: innerFields,
6997
+ flatFields: flattenFields(innerFields).filter((f) => !isLayoutField(f.type))
6998
+ });
6989
6999
  }
6990
- if (currentFields.length > 0) {
6991
- groups.push(buildGroup(currentFields, nextTitle, nextDescription));
7000
+ if (nonSections.length > 0) {
7001
+ const title = nonSections[0]?.label || nonSections[0]?.name || "General";
7002
+ groups.unshift({
7003
+ title,
7004
+ description: "",
7005
+ varPrefix: toCamelCase(nonSections[0]?.name || "general"),
7006
+ componentName: `${toPascalCase(nonSections[0]?.name || "General")}Card`,
7007
+ fields: nonSections,
7008
+ flatFields: flattenFields(nonSections).filter((f) => !isLayoutField(f.type))
7009
+ });
6992
7010
  }
6993
7011
  return groups;
6994
7012
  }
6995
- function buildGroup(fields, titleOverride, description) {
6996
- const firstField = fields[0];
6997
- const title = titleOverride || firstField.label || firstField.name;
6998
- const varPrefix = toCamelCase(firstField.name);
6999
- return {
7000
- title,
7001
- description,
7002
- varPrefix,
7003
- componentName: `${toPascalCase(firstField.name)}Card`,
7004
- fields,
7005
- flatFields: flattenFields(fields).filter((f) => !isLayoutField(f.type))
7006
- };
7007
- }
7008
7013
  function analyzeGroup(fields) {
7009
7014
  const tabFieldNames = /* @__PURE__ */ new Set();
7010
7015
  for (const f of fields) {
@@ -7033,7 +7038,7 @@ function analyzeGroup(fields) {
7033
7038
  const hasTabsField = fields.some((f) => f.type === "tabs");
7034
7039
  const tabsField = fields.find((f) => f.type === "tabs");
7035
7040
  const firstTabName = tabsField?.tabs?.[0]?.name || "";
7036
- return { relFields, listFieldsWithNested, hasTabsField, tabsField, firstTabName, tabFieldNames };
7041
+ return { relFields, listFieldsWithNested, hasTabsField, firstTabName, tabFieldNames };
7037
7042
  }
7038
7043
  function buildGroupFieldsJSX(group3, analysis, skipLabel) {
7039
7044
  const indent = " ";
@@ -7083,7 +7088,6 @@ function generateCardComponent(group3, schema, analysis) {
7083
7088
  const fieldsJSX = buildGroupFieldsJSX(group3, analysis, isSingleField);
7084
7089
  const relState = buildGroupRelState(analysis);
7085
7090
  const fieldArrayHooks = buildGroupFieldArrayHooks(analysis);
7086
- const needsReact = analysis.relFields.length > 0 || analysis.listFieldsWithNested.length > 0;
7087
7091
  const descriptionLine = group3.description ? `
7088
7092
  <CardDescription>${group3.description}</CardDescription>` : "";
7089
7093
  return `const ${group3.varPrefix}Schema = z.object({
@@ -7125,7 +7129,7 @@ ${fieldArrayHooks}
7125
7129
  )
7126
7130
  mutation.mutate(cleaned as Upsert${Singular}Input)
7127
7131
  })}>
7128
- <Card>
7132
+ <Card className="material-sm!">
7129
7133
  <CardHeader>
7130
7134
  <CardTitle>${group3.title}</CardTitle>${descriptionLine}
7131
7135
  </CardHeader>
@@ -7154,7 +7158,7 @@ function generateSingleForm(schema, cwd, pagesDir, options = {}) {
7154
7158
  const allFormFields = schema.fields.filter(
7155
7159
  (f) => !f.primaryKey && f.name !== "createdAt" && f.name !== "updatedAt"
7156
7160
  );
7157
- const cardGroups = parseCardGroups(allFormFields);
7161
+ const cardGroups = parseCardGroups(allFormFields, schema.label);
7158
7162
  const hasBoolean = hasFieldType(schema.fields, "boolean");
7159
7163
  const hasImage = hasFieldType(schema.fields, "image");
7160
7164
  const hasVideo = hasFieldType(schema.fields, "video");
@@ -10080,9 +10084,25 @@ function defaultSettingsSchema() {
10080
10084
  description: "General Settings",
10081
10085
  icon: "Settings",
10082
10086
  fields: [
10083
- { name: "siteName", type: "string", label: "Site Name", default: "BetterStart" },
10084
- { name: "break1", type: "break" },
10085
- { name: "logo", type: "image", label: "Logo" }
10087
+ {
10088
+ type: "section",
10089
+ name: "siteSettings",
10090
+ label: "Site Settings",
10091
+ description: "General settings for the site",
10092
+ fields: [
10093
+ { name: "appName", type: "string", label: "App Name", hint: "Displayed in the sidebar and throughout the dashboard", default: "BetterStart" },
10094
+ { name: "appDescription", type: "text", label: "App Description", hint: "A brief description of the application" }
10095
+ ]
10096
+ },
10097
+ {
10098
+ type: "section",
10099
+ name: "branding",
10100
+ label: "Branding",
10101
+ description: "Logo and visual identity",
10102
+ fields: [
10103
+ { name: "logo", type: "image", label: "Logo" }
10104
+ ]
10105
+ }
10086
10106
  ]
10087
10107
  },
10088
10108
  null,