betterstart-cli 0.0.21 → 0.0.22

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.
@@ -62,7 +62,7 @@ export function DevModeIntegrateButton({
62
62
  </DrawerHeader>
63
63
 
64
64
  {loadedIntegration ? (
65
- <Tabs defaultValue="snippets" className="min-h-0 flex-1 overflow-hidden px-4 pb-4 gap-4">
65
+ <Tabs defaultValue="snippets" className="min-h-0 flex-1 overflow-hidden px-6 pb-4 gap-4">
66
66
  <TabsList className="w-full">
67
67
  <TabsTrigger value="snippets">Snippets</TabsTrigger>
68
68
  <TabsTrigger value="lifecycle-hooks">Lifecycle Hooks</TabsTrigger>
@@ -95,7 +95,7 @@ export function EditMediaDialogContent({
95
95
  ref={handleDrawerContainerRef}
96
96
  className="pointer-events-none absolute inset-3 z-20 overflow-hidden rounded-lg"
97
97
  />
98
- <div className="relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden">
98
+ <div className="relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden gap-3">
99
99
  <DrawerHeader>
100
100
  <DrawerTitle>Media file</DrawerTitle>
101
101
  </DrawerHeader>
@@ -103,7 +103,7 @@ export function EditMediaDialogContent({
103
103
  <form
104
104
  id={formId}
105
105
  onSubmit={form.handleSubmit(handleSave)}
106
- className="flex flex-1 flex-col gap-4 overflow-y-auto px-4 pb-4 pt-px"
106
+ className="flex flex-1 flex-col gap-4 overflow-y-auto px-6 pb-4 pt-px"
107
107
  >
108
108
  <Card>
109
109
  <CardContent className="p-0">
@@ -194,7 +194,7 @@ export function SortOrderDialog({
194
194
  onAnimationEnd={handleDrawerAnimationEnd}
195
195
  >
196
196
  <DrawerContent className="h-full w-full overflow-hidden">
197
- <div className="relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden">
197
+ <div className="relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden gap-3">
198
198
  <DrawerHeader>
199
199
  <DrawerTitle>{title}</DrawerTitle>
200
200
  {description ? <DrawerDescription>{description}</DrawerDescription> : null}
@@ -205,7 +205,7 @@ export function SortOrderDialog({
205
205
  </div>
206
206
  ) : (
207
207
  <ScrollArea className="min-h-0 flex-1">
208
- <div className="flex flex-col gap-1 px-4 py-1">
208
+ <div className="flex flex-col gap-1 px-6 py-1">
209
209
  <SortableContext
210
210
  items={orderedItems.map((i) => i.id)}
211
211
  strategy={verticalListSortingStrategy}
@@ -9,7 +9,7 @@ export function DragOverlayItem({ label }: { label: string }) {
9
9
  className="shrink-0 w-full justify-start gap-2 px-2 font-normal touch-none cursor-grabbing"
10
10
  >
11
11
  <GripVertical strokeWidth={1} />
12
- <span className="truncate text-sm">{label}</span>
12
+ <span className="min-w-0 truncate text-sm">{label}</span>
13
13
  </Button>
14
14
  )
15
15
  }
@@ -25,7 +25,7 @@ export function SortableItem({ id, label }: SortOrderItemData) {
25
25
  {...listeners}
26
26
  >
27
27
  <GripVertical strokeWidth={1} />
28
- <span className="truncate text-sm">{label}</span>
28
+ <span className="min-w-0 truncate text-sm">{label}</span>
29
29
  </Button>
30
30
  </div>
31
31
  )
@@ -21,7 +21,7 @@ import { useAuditLogs, useCleanupAuditLogs } from '@admin/hooks/use-audit-log'
21
21
  import { useTableUtils } from '@admin/hooks/use-table-utils'
22
22
  import { cn } from '@admin/utils/shared/cn'
23
23
  import { type ColumnDef, flexRender, getCoreRowModel, useReactTable } from '@tanstack/react-table'
24
- import { GripVertical, LoaderCircle, Trash2 } from 'lucide-react'
24
+ import { GripVertical } from 'lucide-react'
25
25
  import { parseAsInteger, parseAsString, useQueryStates } from 'nuqs'
26
26
  import * as React from 'react'
27
27
  import { toast } from 'sonner'
@@ -341,7 +341,7 @@ export function AuditLogPageContent() {
341
341
  })
342
342
  }, [setFilters])
343
343
 
344
- const runCleanup = React.useCallback(() => {
344
+ const _runCleanup = React.useCallback(() => {
345
345
  cleanupMutation.mutate(undefined, {
346
346
  onSuccess: (result) => {
347
347
  if (!result.success) {
@@ -386,22 +386,7 @@ export function AuditLogPageContent() {
386
386
 
387
387
  return (
388
388
  <React.Fragment>
389
- <PageHeader
390
- title="Audit Log"
391
- actions={
392
- <div className="flex items-center gap-1">
393
- <Button
394
- type="button"
395
- variant="outline"
396
- disabled={cleanupMutation.isPending}
397
- onClick={runCleanup}
398
- >
399
- {cleanupMutation.isPending ? <LoaderCircle className="animate-spin" /> : <Trash2 />}
400
- Cleanup
401
- </Button>
402
- </div>
403
- }
404
- />
389
+ <PageHeader title="Audit Log" />
405
390
 
406
391
  <EntityFiltersBar
407
392
  filters={filtersConfig}
@@ -136,7 +136,7 @@ export function ContentEditor({
136
136
  <EditorContent
137
137
  editor={editor}
138
138
  role="presentation"
139
- className="simple-editor-content min-h-0 flex-1 cursor-text p-10 overflow-y-auto bg-background [&_.ProseMirror]:min-h-full"
139
+ className="simple-editor-content min-h-0 flex-1 cursor-text p-10 overflow-y-auto bg-input [&_.ProseMirror]:min-h-full"
140
140
  />
141
141
  </div>
142
142
  </>
@@ -346,7 +346,7 @@ export function SourceMode({
346
346
  highlightActiveLineGutter: false
347
347
  }}
348
348
  className={cn(
349
- 'flex min-h-0 flex-1 flex-col overflow-hidden font-mono text-sm font-normal leading-6 [&_.cm-content]:!bg-transparent [&_.cm-editor]:!bg-background [&_.cm-gutters]:!bg-background [&_.cm-scroller]:!bg-background',
349
+ 'flex min-h-0 flex-1 flex-col overflow-hidden font-mono text-sm font-normal leading-6 [&_.cm-content]:!bg-transparent [&_.cm-editor]:!bg-input [&_.cm-gutters]:!bg-input [&_.cm-scroller]:!bg-input',
350
350
  {
351
351
  'opacity-50 cursor-not-allowed': disabled
352
352
  }
@@ -17,7 +17,7 @@ function ScrollArea({
17
17
  >
18
18
  <ScrollAreaPrimitive.Viewport
19
19
  data-slot="scroll-area-viewport"
20
- className="size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1"
20
+ className="size-full rounded-[inherit] transition-[color,box-shadow] outline-none [&>div]:block! focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1"
21
21
  >
22
22
  {children}
23
23
  </ScrollAreaPrimitive.Viewport>
package/dist/cli.js CHANGED
@@ -3120,7 +3120,7 @@ async function collectR2Config(cwd) {
3120
3120
  const accessKeyId = await resolveTextEnvValue({
3121
3121
  cwd,
3122
3122
  key: "BETTERSTART_R2_ACCESS_KEY_ID",
3123
- message: "R2 access key ID",
3123
+ message: "Cloudflare R2 access key ID",
3124
3124
  cancelMessage: "R2 configuration cancelled.",
3125
3125
  overwriteEnvKeys,
3126
3126
  validate(value) {
@@ -3130,7 +3130,7 @@ async function collectR2Config(cwd) {
3130
3130
  const secretAccessKey = await resolvePasswordEnvValue({
3131
3131
  cwd,
3132
3132
  key: "BETTERSTART_R2_SECRET_ACCESS_KEY",
3133
- message: "R2 secret access key",
3133
+ message: "Cloudflare R2 secret access key",
3134
3134
  cancelMessage: "R2 configuration cancelled.",
3135
3135
  overwriteEnvKeys,
3136
3136
  validate(value) {
@@ -3140,7 +3140,7 @@ async function collectR2Config(cwd) {
3140
3140
  const bucketName = await resolveTextEnvValue({
3141
3141
  cwd,
3142
3142
  key: "BETTERSTART_R2_BUCKET_NAME",
3143
- message: "R2 bucket name",
3143
+ message: "Cloudflare R2 bucket name",
3144
3144
  defaultValue: "betterstart-uploads",
3145
3145
  cancelMessage: "R2 configuration cancelled.",
3146
3146
  overwriteEnvKeys,
@@ -3151,7 +3151,7 @@ async function collectR2Config(cwd) {
3151
3151
  const publicUrl = await resolveTextEnvValue({
3152
3152
  cwd,
3153
3153
  key: "BETTERSTART_R2_PUBLIC_URL",
3154
- message: "R2 public URL",
3154
+ message: "Cloudflare R2 public URL",
3155
3155
  cancelMessage: "R2 configuration cancelled.",
3156
3156
  overwriteEnvKeys,
3157
3157
  validate(value) {
@@ -21103,7 +21103,32 @@ function openBrowser(url) {
21103
21103
  // adapters/next/init/prompts/plugins.ts
21104
21104
  import { styleText } from "util";
21105
21105
  import * as p8 from "@clack/prompts";
21106
- async function promptPlugins() {
21106
+ async function promptPlugins(cwd) {
21107
+ const sections = [];
21108
+ const overwriteKeys = /* @__PURE__ */ new Set();
21109
+ const mergeIntegrationConfig = (collected) => {
21110
+ sections.push(...collected.sections);
21111
+ for (const key of collected.overwriteKeys) {
21112
+ overwriteKeys.add(key);
21113
+ }
21114
+ };
21115
+ const selectedPlugins = await p8.multiselect({
21116
+ message: `Select presets
21117
+ ${styleText("dim", "Press [Spacebar] to select/unselect")}`,
21118
+ options: [
21119
+ {
21120
+ value: "blog",
21121
+ label: "Blog",
21122
+ hint: "Posts"
21123
+ }
21124
+ ],
21125
+ required: false,
21126
+ initialValues: ["blog"]
21127
+ });
21128
+ if (p8.isCancel(selectedPlugins)) {
21129
+ p8.cancel("Setup cancelled.");
21130
+ process.exit(0);
21131
+ }
21107
21132
  const storage = await p8.select({
21108
21133
  message: "Choose a file storage mode",
21109
21134
  options: [
@@ -21124,22 +21149,8 @@ async function promptPlugins() {
21124
21149
  p8.cancel("Setup cancelled.");
21125
21150
  process.exit(0);
21126
21151
  }
21127
- const selectedPlugins = await p8.multiselect({
21128
- message: `Select presets
21129
- ${styleText("dim", "Press [Spacebar] to select/unselect")}`,
21130
- options: [
21131
- {
21132
- value: "blog",
21133
- label: "Blog",
21134
- hint: "Posts"
21135
- }
21136
- ],
21137
- required: false,
21138
- initialValues: ["blog"]
21139
- });
21140
- if (p8.isCancel(selectedPlugins)) {
21141
- p8.cancel("Setup cancelled.");
21142
- process.exit(0);
21152
+ if (storage === "r2") {
21153
+ mergeIntegrationConfig(await collectIntegrationConfig(cwd, ["r2"]));
21143
21154
  }
21144
21155
  const selectedEmailProvider = await p8.select({
21145
21156
  message: `Which email provider do you want to set up?
@@ -21152,14 +21163,14 @@ ${styleText(
21152
21163
  value: "resend",
21153
21164
  label: "Resend"
21154
21165
  },
21166
+ {
21167
+ value: "skip",
21168
+ label: "Skip"
21169
+ },
21155
21170
  {
21156
21171
  value: "cloudflare",
21157
21172
  label: `Cloudflare ${styleText("dim", "(coming soon)")}`,
21158
21173
  disabled: true
21159
- },
21160
- {
21161
- value: "skip",
21162
- label: "Skip"
21163
21174
  }
21164
21175
  ],
21165
21176
  initialValue: "resend"
@@ -21168,12 +21179,19 @@ ${styleText(
21168
21179
  p8.cancel("Setup cancelled.");
21169
21180
  process.exit(0);
21170
21181
  }
21171
- const selectedIntegrations = selectedEmailProvider === "resend" ? ["resend"] : [];
21172
- const integrations = storage === "r2" ? [...selectedIntegrations, "r2"] : selectedIntegrations;
21182
+ const integrations = [];
21183
+ if (selectedEmailProvider === "resend") {
21184
+ integrations.push("resend");
21185
+ mergeIntegrationConfig(await collectIntegrationConfig(cwd, ["resend"]));
21186
+ }
21187
+ if (storage === "r2") {
21188
+ integrations.push("r2");
21189
+ }
21173
21190
  return {
21174
21191
  plugins: selectedPlugins,
21175
21192
  integrations,
21176
- storage
21193
+ storage,
21194
+ integrationConfig: { sections, overwriteKeys }
21177
21195
  };
21178
21196
  }
21179
21197
 
@@ -23632,16 +23650,28 @@ async function runInitCommand(name, options) {
23632
23650
  }
23633
23651
  return [];
23634
23652
  })();
23635
- const pluginSelection = selectedPlugins.length > 0 || selectedIntegrations.length > 0 ? {
23636
- plugins: selectedPlugins,
23637
- integrations: selectedIntegrations,
23638
- storage: selectedIntegrations.includes("r2") ? "r2" : "local"
23639
- } : options.yes ? {
23640
- plugins: [],
23641
- integrations: [],
23642
- storage: "local"
23643
- } : await promptPlugins();
23644
- const collectedIntegrationConfig = !options.yes && pluginSelection.integrations.length > 0 ? await collectIntegrationConfig(cwd, pluginSelection.integrations) : { sections: [], overwriteKeys: /* @__PURE__ */ new Set() };
23653
+ let collectedIntegrationConfig = {
23654
+ sections: [],
23655
+ overwriteKeys: /* @__PURE__ */ new Set()
23656
+ };
23657
+ let pluginSelection;
23658
+ if (selectedPlugins.length > 0 || selectedIntegrations.length > 0) {
23659
+ pluginSelection = {
23660
+ plugins: selectedPlugins,
23661
+ integrations: selectedIntegrations,
23662
+ storage: selectedIntegrations.includes("r2") ? "r2" : "local"
23663
+ };
23664
+ } else if (options.yes) {
23665
+ pluginSelection = { plugins: [], integrations: [], storage: "local" };
23666
+ } else {
23667
+ const promptResult = await promptPlugins(cwd);
23668
+ collectedIntegrationConfig = promptResult.integrationConfig;
23669
+ pluginSelection = {
23670
+ plugins: promptResult.plugins,
23671
+ integrations: promptResult.integrations,
23672
+ storage: promptResult.storage
23673
+ };
23674
+ }
23645
23675
  let databaseUrl;
23646
23676
  const existingDbUrl = readExistingDbUrl(cwd);
23647
23677
  if (options.yes) {