@svadmin/create 0.20.0 → 0.22.0

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/README.md CHANGED
@@ -134,3 +134,22 @@ overwriting local standards:
134
134
  bunx @svadmin/create guidance .
135
135
  bunx @svadmin/create guidance . --write
136
136
  ```
137
+
138
+ ## Add Lite routes to an existing SPA
139
+
140
+ Lite is an optional SvelteKit server-rendered route tree. It does not modify the
141
+ existing SPA or add IE11 branches to the SPA bundle. In a project that already
142
+ has a SvelteKit `src/routes` directory, run:
143
+
144
+ ```bash
145
+ # Preview the files first; nothing is written
146
+ bunx @svadmin/create lite init .
147
+
148
+ # Generate the shared adapter and dynamic CRUD routes
149
+ bunx @svadmin/create lite init . --write
150
+ ```
151
+
152
+ The generator creates one `[resource]` route for all resources plus the shared
153
+ `src/lib/svadmin-lite.ts` adapter. Your existing `$lib/admin` module only needs
154
+ to export `resources` and `dataProvider`; resources are resolved dynamically at
155
+ request time. Existing files are preserved, so rerunning the command is safe.
package/dist/index.js CHANGED
@@ -5024,9 +5024,9 @@ var require_picocolors = __commonJS(function(exports, module) {
5024
5024
 
5025
5025
  // src/index.ts
5026
5026
  var import_prompts2 = __toESM(require_prompts3(), 1);
5027
- var import_picocolors2 = __toESM(require_picocolors(), 1);
5028
- import fs2 from "node:fs";
5029
- import path2 from "node:path";
5027
+ var import_picocolors3 = __toESM(require_picocolors(), 1);
5028
+ import fs4 from "node:fs";
5029
+ import path4 from "node:path";
5030
5030
  import { fileURLToPath } from "node:url";
5031
5031
  import { createRequire as createRequire2 } from "node:module";
5032
5032
  import { spawnSync } from "node:child_process";
@@ -5998,6 +5998,10 @@ function parseInferArguments(args) {
5998
5998
  options.primaryKey = args[++i];
5999
5999
  } else if (arg.startsWith("--primary-key=")) {
6000
6000
  options.primaryKey = arg.slice(14);
6001
+ } else if (arg === "--fields") {
6002
+ options.fields = args[++i];
6003
+ } else if (arg.startsWith("--fields=")) {
6004
+ options.fields = arg.slice(9);
6001
6005
  } else if (arg === "--header" || arg === "-H") {
6002
6006
  const headerLine = args[++i] ?? "";
6003
6007
  const colonIndex = headerLine.indexOf(":");
@@ -6431,6 +6435,343 @@ function capitalize2(s) {
6431
6435
  return s.charAt(0).toUpperCase() + s.slice(1);
6432
6436
  }
6433
6437
 
6438
+ // src/generate-command.ts
6439
+ var import_picocolors2 = __toESM(require_picocolors(), 1);
6440
+ import fs2 from "node:fs";
6441
+ import path2 from "node:path";
6442
+ function parseGenerateArguments(args) {
6443
+ return parseInferArguments(args);
6444
+ }
6445
+ async function generateCommand(args) {
6446
+ const options = parseGenerateArguments(args);
6447
+ if (options.resource && options.fields) {
6448
+ const resourceName = options.resource;
6449
+ const primaryKey = options.primaryKey ?? "id";
6450
+ const fieldDefs = options.fields.split(",").map((f) => {
6451
+ const [key, typeRaw] = f.split(":");
6452
+ const type = typeRaw || "text";
6453
+ return {
6454
+ key: key.trim(),
6455
+ label: key.trim().charAt(0).toUpperCase() + key.trim().slice(1),
6456
+ type,
6457
+ required: key.trim() === primaryKey
6458
+ };
6459
+ });
6460
+ const mockSample = {};
6461
+ for (const f of fieldDefs) {
6462
+ mockSample[f.key] = f.type === "number" ? 1 : f.type === "boolean" ? true : `sample_${f.key}`;
6463
+ }
6464
+ const inferRes = inferResource(resourceName, [mockSample], { primaryKey });
6465
+ const resources = [
6466
+ {
6467
+ name: resourceName,
6468
+ label: resourceName.charAt(0).toUpperCase() + resourceName.slice(1),
6469
+ primaryKey,
6470
+ fields: fieldDefs
6471
+ }
6472
+ ];
6473
+ const bundles = new Map([[resourceName, inferRes]]);
6474
+ const files = planGeneratedFiles(resources, bundles, options.format);
6475
+ let wrote = false;
6476
+ if (options.outDir && options.write) {
6477
+ const targetDir = path2.resolve(process.cwd(), options.outDir);
6478
+ for (const file of files) {
6479
+ const fullPath = path2.join(targetDir, file.relativePath);
6480
+ fs2.mkdirSync(path2.dirname(fullPath), { recursive: true });
6481
+ fs2.writeFileSync(fullPath, file.content, "utf-8");
6482
+ }
6483
+ wrote = true;
6484
+ }
6485
+ printInferResult({
6486
+ resources,
6487
+ bundles,
6488
+ files,
6489
+ sourceDescription: `manual schema: ${options.fields}`,
6490
+ wrote,
6491
+ outDir: options.outDir
6492
+ });
6493
+ return;
6494
+ }
6495
+ if (options.url || options.file) {
6496
+ const result = await executeInfer(options);
6497
+ printInferResult(result);
6498
+ return;
6499
+ }
6500
+ console.log(`
6501
+ ${import_picocolors2.default.bold("svadmin generate")} — Generate complete Resource Definitions, Schemas, and CRUD pages.
6502
+
6503
+ ${import_picocolors2.default.bold("USAGE:")}
6504
+ svadmin generate --resource <name> --fields <field:type,...> [OPTIONS]
6505
+ svadmin generate --file <schema.json|openapi.yaml|schema.graphql> [OPTIONS]
6506
+ svadmin generate --url <api-url|openapi-url> [OPTIONS]
6507
+
6508
+ ${import_picocolors2.default.bold("EXAMPLES:")}
6509
+ svadmin generate --resource posts --fields "id:number,title:text,content:textarea,published:boolean" --out-dir src/resources --write
6510
+ svadmin generate --file openapi.json --out-dir src/resources --write
6511
+ `);
6512
+ }
6513
+
6514
+ // src/lite-init.ts
6515
+ import fs3 from "node:fs";
6516
+ import path3 from "node:path";
6517
+ var GENERATED_FILES = {
6518
+ "src/lib/svadmin-lite.ts": `import { dataProvider, resources } from '$lib/admin';
6519
+ import type { ResourceDefinition } from '@svadmin/core';
6520
+
6521
+ export { dataProvider, resources };
6522
+
6523
+ export function getResource(name: string): ResourceDefinition | undefined {
6524
+ return resources.find((resource) => resource.name === name);
6525
+ }
6526
+ `,
6527
+ "src/routes/lite/+layout.ts": `export const ssr = true;
6528
+ export const csr = false;
6529
+ `,
6530
+ "src/routes/lite/+layout.server.ts": `import { resources } from '$lib/svadmin-lite';
6531
+ import type { LayoutServerLoad } from './$types';
6532
+
6533
+ export const load = (({ url }) => {
6534
+ const segments = url.pathname.split('/').filter(Boolean);
6535
+ const currentResource = segments[1] ?? '';
6536
+
6537
+ return { resources, currentResource };
6538
+ }) satisfies LayoutServerLoad;
6539
+ `,
6540
+ "src/routes/lite/+layout.svelte": `<script lang="ts">
6541
+ import type { Snippet } from 'svelte';
6542
+ import { LiteLayout } from '@svadmin/lite';
6543
+ import '@svadmin/lite/lite.css';
6544
+ import type { LayoutData } from './$types';
6545
+
6546
+ let { data, children }: { data: LayoutData; children: Snippet } = $props();
6547
+ </script>
6548
+
6549
+ <LiteLayout
6550
+ resources={data.resources}
6551
+ currentResource={data.currentResource}
6552
+ brandName="Lite Admin"
6553
+ basePath="/lite"
6554
+ >
6555
+ {@render children()}
6556
+ </LiteLayout>
6557
+ `,
6558
+ "src/routes/lite/+page.server.ts": `import { error, redirect } from '@sveltejs/kit';
6559
+ import { resources } from '$lib/svadmin-lite';
6560
+ import type { PageServerLoad } from './$types';
6561
+
6562
+ export const load = (() => {
6563
+ const firstResource = resources[0];
6564
+ if (!firstResource) throw error(404, 'No Lite resources configured');
6565
+ throw redirect(302, \`/lite/\${firstResource.name}\`);
6566
+ }) satisfies PageServerLoad;
6567
+ `,
6568
+ "src/routes/lite/[resource]/+page.server.ts": `import { error } from '@sveltejs/kit';
6569
+ import { createCrudActions, createListLoader } from '@svadmin/lite';
6570
+ import { dataProvider, getResource } from '$lib/svadmin-lite';
6571
+ import type { Actions, PageServerLoad } from './$types';
6572
+
6573
+ export const load = ((event) => {
6574
+ const resource = getResource(event.params.resource);
6575
+ if (!resource) throw error(404, \`Resource "\${event.params.resource}" not found\`);
6576
+ return createListLoader(dataProvider, resource)(event);
6577
+ }) satisfies PageServerLoad;
6578
+
6579
+ export const actions = {
6580
+ delete: (event) => {
6581
+ const resource = getResource(event.params.resource);
6582
+ if (!resource) throw error(404, \`Resource "\${event.params.resource}" not found\`);
6583
+ return createCrudActions(dataProvider, resource).delete(event);
6584
+ },
6585
+ batchDelete: (event) => {
6586
+ const resource = getResource(event.params.resource);
6587
+ if (!resource) throw error(404, \`Resource "\${event.params.resource}" not found\`);
6588
+ return createCrudActions(dataProvider, resource).batchDelete(event);
6589
+ },
6590
+ } satisfies Actions;
6591
+ `,
6592
+ "src/routes/lite/[resource]/+page.svelte": `<script lang="ts">
6593
+ import { LiteListPage } from '@svadmin/lite';
6594
+ import type { PageProps } from './$types';
6595
+
6596
+ let { data }: PageProps = $props();
6597
+ </script>
6598
+
6599
+ <LiteListPage {...data} basePath="/lite" />
6600
+ `,
6601
+ "src/routes/lite/[resource]/create/+page.server.ts": `import { error, redirect } from '@sveltejs/kit';
6602
+ import { createCrudActions } from '@svadmin/lite';
6603
+ import { dataProvider, getResource } from '$lib/svadmin-lite';
6604
+ import type { Actions, PageServerLoad } from './$types';
6605
+
6606
+ export const load = (({ params }) => {
6607
+ const resource = getResource(params.resource);
6608
+ if (!resource) throw error(404, \`Resource "\${params.resource}" not found\`);
6609
+ return { resource };
6610
+ }) satisfies PageServerLoad;
6611
+
6612
+ export const actions = {
6613
+ create: async (event) => {
6614
+ const resource = getResource(event.params.resource);
6615
+ if (!resource) throw error(404, \`Resource "\${event.params.resource}" not found\`);
6616
+ const result = await createCrudActions(dataProvider, resource).create(event);
6617
+ if (result && 'success' in result && result.success) {
6618
+ throw redirect(303, \`/lite/\${resource.name}\`);
6619
+ }
6620
+ return result;
6621
+ },
6622
+ } satisfies Actions;
6623
+ `,
6624
+ "src/routes/lite/[resource]/create/+page.svelte": `<script lang="ts">
6625
+ import { LiteCreatePage } from '@svadmin/lite';
6626
+ import type { PageProps } from './$types';
6627
+
6628
+ let { data, form }: PageProps = $props();
6629
+ </script>
6630
+
6631
+ <LiteCreatePage
6632
+ resource={data.resource}
6633
+ errors={form?.errors}
6634
+ values={form?.values}
6635
+ basePath="/lite"
6636
+ />
6637
+ `,
6638
+ "src/routes/lite/[resource]/show/[id]/+page.server.ts": `import { error } from '@sveltejs/kit';
6639
+ import { createDetailLoader } from '@svadmin/lite';
6640
+ import { dataProvider, getResource } from '$lib/svadmin-lite';
6641
+ import type { PageServerLoad } from './$types';
6642
+
6643
+ export const load = ((event) => {
6644
+ const resource = getResource(event.params.resource);
6645
+ if (!resource) throw error(404, \`Resource "\${event.params.resource}" not found\`);
6646
+ return createDetailLoader(dataProvider, resource)(event);
6647
+ }) satisfies PageServerLoad;
6648
+ `,
6649
+ "src/routes/lite/[resource]/show/[id]/+page.svelte": `<script lang="ts">
6650
+ import { LiteShowPage } from '@svadmin/lite';
6651
+ import type { PageProps } from './$types';
6652
+
6653
+ let { data }: PageProps = $props();
6654
+ </script>
6655
+
6656
+ <LiteShowPage resource={data.resource} record={data.record} basePath="/lite" />
6657
+ `,
6658
+ "src/routes/lite/[resource]/edit/[id]/+page.server.ts": `import { error, redirect } from '@sveltejs/kit';
6659
+ import { createCrudActions, createDetailLoader } from '@svadmin/lite';
6660
+ import { dataProvider, getResource } from '$lib/svadmin-lite';
6661
+ import type { Actions, PageServerLoad } from './$types';
6662
+
6663
+ export const load = ((event) => {
6664
+ const resource = getResource(event.params.resource);
6665
+ if (!resource) throw error(404, \`Resource "\${event.params.resource}" not found\`);
6666
+ return createDetailLoader(dataProvider, resource)(event);
6667
+ }) satisfies PageServerLoad;
6668
+
6669
+ export const actions = {
6670
+ update: async (event) => {
6671
+ const resource = getResource(event.params.resource);
6672
+ if (!resource) throw error(404, \`Resource "\${event.params.resource}" not found\`);
6673
+ const result = await createCrudActions(dataProvider, resource).update(event);
6674
+ if (result && 'success' in result && result.success) {
6675
+ throw redirect(303, \`/lite/\${resource.name}/show/\${event.params.id}\`);
6676
+ }
6677
+ return result;
6678
+ },
6679
+ delete: (event) => {
6680
+ const resource = getResource(event.params.resource);
6681
+ if (!resource) throw error(404, \`Resource "\${event.params.resource}" not found\`);
6682
+ return createCrudActions(dataProvider, resource).delete(event);
6683
+ },
6684
+ } satisfies Actions;
6685
+ `,
6686
+ "src/routes/lite/[resource]/edit/[id]/+page.svelte": `<script lang="ts">
6687
+ import { LiteEditPage } from '@svadmin/lite';
6688
+ import type { PageProps } from './$types';
6689
+
6690
+ let { data, form }: PageProps = $props();
6691
+ </script>
6692
+
6693
+ <LiteEditPage
6694
+ resource={data.resource}
6695
+ record={data.record}
6696
+ errors={form?.errors}
6697
+ basePath="/lite"
6698
+ />
6699
+ `
6700
+ };
6701
+ function parseLiteInitArguments(args) {
6702
+ let write = false;
6703
+ const positional = [];
6704
+ for (const argument of args) {
6705
+ if (argument === "--write")
6706
+ write = true;
6707
+ else if (argument.startsWith("-"))
6708
+ throw new Error(`Unknown option: ${argument}`);
6709
+ else
6710
+ positional.push(argument);
6711
+ }
6712
+ if (positional.length > 1) {
6713
+ throw new Error(`Expected at most one project directory, received: ${positional.join(", ")}`);
6714
+ }
6715
+ return {
6716
+ projectDirectory: path3.resolve(process.cwd(), positional[0] ?? "."),
6717
+ write
6718
+ };
6719
+ }
6720
+ function assertLiteProject(projectDirectory) {
6721
+ if (!fs3.existsSync(projectDirectory)) {
6722
+ throw new Error(`Project directory does not exist: ${projectDirectory}`);
6723
+ }
6724
+ if (!fs3.existsSync(path3.join(projectDirectory, "package.json"))) {
6725
+ throw new Error(`Not a Node project: ${path3.join(projectDirectory, "package.json")} is missing`);
6726
+ }
6727
+ if (!fs3.existsSync(path3.join(projectDirectory, "src", "routes"))) {
6728
+ throw new Error("Lite routes require a SvelteKit project with src/routes. Keep the existing SPA and add a SvelteKit Lite app alongside it.");
6729
+ }
6730
+ const adminModuleExists = ["ts", "js", "svelte"].some((extension) => fs3.existsSync(path3.join(projectDirectory, "src", "lib", `admin.${extension}`)));
6731
+ if (!adminModuleExists) {
6732
+ throw new Error("Lite routes require src/lib/admin.ts (or .js/.svelte) exporting resources and dataProvider.");
6733
+ }
6734
+ }
6735
+ function planLiteInit(projectDirectory) {
6736
+ assertLiteProject(projectDirectory);
6737
+ const entries = Object.entries(GENERATED_FILES).map(([relativePath, content]) => {
6738
+ const filePath = path3.join(projectDirectory, relativePath);
6739
+ return { filePath, relativePath, content, exists: fs3.existsSync(filePath) };
6740
+ });
6741
+ return { projectDirectory, entries };
6742
+ }
6743
+ function writeLiteInit(plan) {
6744
+ const written = [];
6745
+ const preserved = [];
6746
+ for (const entry of plan.entries) {
6747
+ if (entry.exists || fs3.existsSync(entry.filePath)) {
6748
+ preserved.push(entry.relativePath);
6749
+ continue;
6750
+ }
6751
+ fs3.mkdirSync(path3.dirname(entry.filePath), { recursive: true });
6752
+ fs3.writeFileSync(entry.filePath, entry.content);
6753
+ written.push(entry.relativePath);
6754
+ }
6755
+ return { plan, written, preserved };
6756
+ }
6757
+ function liteInitCommand(args) {
6758
+ const options = parseLiteInitArguments(args);
6759
+ const plan = planLiteInit(options.projectDirectory);
6760
+ console.log(`
6761
+ svadmin lite init — ${options.projectDirectory}`);
6762
+ for (const entry of plan.entries) {
6763
+ console.log(` ${entry.exists ? "preserve" : "add"} ${entry.relativePath}`);
6764
+ }
6765
+ if (!options.write) {
6766
+ console.log(`
6767
+ Dry run only; re-run with --write to add missing Lite routes.`);
6768
+ return;
6769
+ }
6770
+ const result = writeLiteInit(plan);
6771
+ console.log(`
6772
+ Written ${result.written.length} file(s); preserved ${result.preserved.length} existing file(s).`);
6773
+ }
6774
+
6434
6775
  // src/project-maintenance.ts
6435
6776
  import {
6436
6777
  constants,
@@ -6440,10 +6781,10 @@ import {
6440
6781
  unlinkSync,
6441
6782
  writeFileSync
6442
6783
  } from "node:fs";
6443
- function parseDependencyMap(candidate, path2) {
6784
+ function parseDependencyMap(candidate, path4) {
6444
6785
  if (candidate === undefined)
6445
6786
  return;
6446
- assertStringRecord(candidate, path2);
6787
+ assertStringRecord(candidate, path4);
6447
6788
  return { ...candidate };
6448
6789
  }
6449
6790
  function parseMaintainedPackageJson(packageJsonCandidate) {
@@ -6719,15 +7060,15 @@ function writeProjectPackageJsonUpgrade(packagePath, scaffold, backupDate) {
6719
7060
 
6720
7061
  // src/index.ts
6721
7062
  var __filename2 = fileURLToPath(import.meta.url);
6722
- var __dirname2 = path2.dirname(__filename2);
7063
+ var __dirname2 = path4.dirname(__filename2);
6723
7064
  function loadShippedScaffoldManifest() {
6724
- return loadScaffoldManifest(path2.join(__dirname2, "..", "scaffold-manifest.json"));
7065
+ return loadScaffoldManifest(path4.join(__dirname2, "..", "scaffold-manifest.json"));
6725
7066
  }
6726
7067
  function projectDirectoryFromArguments(positional) {
6727
7068
  if (positional.length > 1) {
6728
7069
  throw new Error(`Expected at most one project directory, received: ${positional.join(", ")}`);
6729
7070
  }
6730
- return path2.resolve(process.cwd(), positional[0] ?? ".");
7071
+ return path4.resolve(process.cwd(), positional[0] ?? ".");
6731
7072
  }
6732
7073
  function doctorProjectDirectory(args) {
6733
7074
  const unknownOption = args.find((argument) => argument.startsWith("-"));
@@ -6763,52 +7104,52 @@ function upgradeChangeMessage(change) {
6763
7104
  return `update ${change.packageName} from ${change.from ?? "missing"} to ${change.to}`;
6764
7105
  }
6765
7106
  function printDoctorIssue(issue) {
6766
- const marker = issue.kind === "drift" || issue.kind === "section" ? import_picocolors2.default.yellow(" ⚠") : import_picocolors2.default.red(" ✗");
7107
+ const marker = issue.kind === "drift" || issue.kind === "section" ? import_picocolors3.default.yellow(" ⚠") : import_picocolors3.default.red(" ✗");
6767
7108
  console.log(`${marker} ${doctorIssueMessage(issue)}`);
6768
- console.log(import_picocolors2.default.dim(` → ${issue.action}`));
7109
+ console.log(import_picocolors3.default.dim(` → ${issue.action}`));
6769
7110
  }
6770
7111
  function printDoctorReport(report, projectDirectory) {
6771
7112
  console.log();
6772
- console.log(import_picocolors2.default.bold(`svadmin doctor — ${projectDirectory}`));
7113
+ console.log(import_picocolors3.default.bold(`svadmin doctor — ${projectDirectory}`));
6773
7114
  if (report.status === "clean") {
6774
- console.log(import_picocolors2.default.green(" ✔ Dependencies match the shipped svadmin scaffold."));
7115
+ console.log(import_picocolors3.default.green(" ✔ Dependencies match the shipped svadmin scaffold."));
6775
7116
  } else {
6776
7117
  for (const issue of report.issues)
6777
7118
  printDoctorIssue(issue);
6778
7119
  console.log();
6779
- console.log(import_picocolors2.default.yellow(` ${report.issues.length} actionable issue(s) found.`));
7120
+ console.log(import_picocolors3.default.yellow(` ${report.issues.length} actionable issue(s) found.`));
6780
7121
  }
6781
7122
  console.log();
6782
7123
  }
6783
7124
  function doctor(args) {
6784
7125
  const projectDirectory = doctorProjectDirectory(args);
6785
- const project = readMaintainedPackageJson(path2.join(projectDirectory, "package.json"));
7126
+ const project = readMaintainedPackageJson(path4.join(projectDirectory, "package.json"));
6786
7127
  const report = doctorProjectPackageJson(project, loadShippedScaffoldManifest());
6787
7128
  printDoctorReport(report, projectDirectory);
6788
7129
  process.exitCode = report.exitCode;
6789
7130
  }
6790
7131
  function printUpgradeChanges(upgradeExecution) {
6791
7132
  for (const change of upgradeExecution.plan.changes) {
6792
- console.log(` ${import_picocolors2.default.cyan("•")} ${upgradeChangeMessage(change)}`);
7133
+ console.log(` ${import_picocolors3.default.cyan("•")} ${upgradeChangeMessage(change)}`);
6793
7134
  }
6794
7135
  console.log();
6795
7136
  }
6796
7137
  function printUpgradeOutcome(upgradeExecution, packagePath) {
6797
7138
  if (upgradeExecution.wrote) {
6798
- console.log(import_picocolors2.default.green(" ✔ package.json updated."));
6799
- console.log(` Backup: ${import_picocolors2.default.cyan(upgradeExecution.backupPath)}`);
6800
- console.log(` Restore by copying the backup over: ${import_picocolors2.default.cyan(packagePath)}`);
7139
+ console.log(import_picocolors3.default.green(" ✔ package.json updated."));
7140
+ console.log(` Backup: ${import_picocolors3.default.cyan(upgradeExecution.backupPath)}`);
7141
+ console.log(` Restore by copying the backup over: ${import_picocolors3.default.cyan(packagePath)}`);
6801
7142
  } else {
6802
- console.log(import_picocolors2.default.yellow(" Dry run only; package.json was not changed."));
7143
+ console.log(import_picocolors3.default.yellow(" Dry run only; package.json was not changed."));
6803
7144
  console.log(" Re-run this command with --write to apply the plan.");
6804
7145
  }
6805
7146
  console.log();
6806
7147
  }
6807
7148
  function printUpgradeExecution(upgradeExecution, projectDirectory, packagePath) {
6808
7149
  console.log();
6809
- console.log(import_picocolors2.default.bold(`svadmin upgrade — ${projectDirectory}`));
7150
+ console.log(import_picocolors3.default.bold(`svadmin upgrade — ${projectDirectory}`));
6810
7151
  if (upgradeExecution.plan.changes.length === 0) {
6811
- console.log(import_picocolors2.default.green(" ✔ package.json already matches the shipped scaffold."));
7152
+ console.log(import_picocolors3.default.green(" ✔ package.json already matches the shipped scaffold."));
6812
7153
  console.log();
6813
7154
  return;
6814
7155
  }
@@ -6817,58 +7158,58 @@ function printUpgradeExecution(upgradeExecution, projectDirectory, packagePath)
6817
7158
  }
6818
7159
  function upgrade(args) {
6819
7160
  const commandArguments = parseUpgradeArguments(args);
6820
- const packagePath = path2.join(commandArguments.projectDirectory, "package.json");
7161
+ const packagePath = path4.join(commandArguments.projectDirectory, "package.json");
6821
7162
  const scaffoldManifest = loadShippedScaffoldManifest();
6822
7163
  const upgradeExecution = commandArguments.write ? writeProjectPackageJsonUpgrade(packagePath, scaffoldManifest, new Date) : planProjectPackageFileUpgrade(packagePath, scaffoldManifest);
6823
7164
  printUpgradeExecution(upgradeExecution, commandArguments.projectDirectory, packagePath);
6824
7165
  }
6825
7166
  var GUIDANCE_FILES = ["DESIGN.md", "AGENTS.md"];
6826
7167
  function missingGuidanceFiles(projectDirectory) {
6827
- return GUIDANCE_FILES.filter((fileName) => !fs2.existsSync(path2.join(projectDirectory, fileName)));
7168
+ return GUIDANCE_FILES.filter((fileName) => !fs4.existsSync(path4.join(projectDirectory, fileName)));
6828
7169
  }
6829
7170
  function printGuidancePlan(projectDirectory, missingFiles) {
6830
7171
  console.log();
6831
- console.log(import_picocolors2.default.bold(`svadmin guidance — ${projectDirectory}`));
7172
+ console.log(import_picocolors3.default.bold(`svadmin guidance — ${projectDirectory}`));
6832
7173
  for (const fileName of missingFiles) {
6833
- console.log(` ${import_picocolors2.default.cyan("•")} add ${fileName}`);
7174
+ console.log(` ${import_picocolors3.default.cyan("•")} add ${fileName}`);
6834
7175
  }
6835
7176
  console.log();
6836
7177
  }
6837
7178
  function installMissingGuidanceFiles(guidanceDirectory, projectDirectory, missingFiles) {
6838
7179
  for (const fileName of missingFiles) {
6839
- fs2.copyFileSync(path2.join(guidanceDirectory, fileName), path2.join(projectDirectory, fileName));
7180
+ fs4.copyFileSync(path4.join(guidanceDirectory, fileName), path4.join(projectDirectory, fileName));
6840
7181
  }
6841
7182
  }
6842
7183
  function guidance(args) {
6843
7184
  const { projectDirectory, write } = parseUpgradeArguments(args);
6844
- const guidanceDirectory = path2.join(__dirname2, "..", "guidance");
6845
- if (!fs2.existsSync(projectDirectory))
7185
+ const guidanceDirectory = path4.join(__dirname2, "..", "guidance");
7186
+ if (!fs4.existsSync(projectDirectory))
6846
7187
  throw new Error(`Project directory does not exist: ${projectDirectory}`);
6847
- if (!fs2.existsSync(guidanceDirectory))
7188
+ if (!fs4.existsSync(guidanceDirectory))
6848
7189
  throw new Error("Shipped svadmin guidance files are missing");
6849
7190
  const missingFiles = missingGuidanceFiles(projectDirectory);
6850
7191
  if (missingFiles.length === 0) {
6851
- console.log(import_picocolors2.default.green(`
7192
+ console.log(import_picocolors3.default.green(`
6852
7193
  ✔ DESIGN.md and AGENTS.md already exist; nothing was changed.
6853
7194
  `));
6854
7195
  return;
6855
7196
  }
6856
7197
  printGuidancePlan(projectDirectory, missingFiles);
6857
7198
  if (!write) {
6858
- console.log(import_picocolors2.default.yellow(` Dry run only; re-run with --write to add missing guidance files.
7199
+ console.log(import_picocolors3.default.yellow(` Dry run only; re-run with --write to add missing guidance files.
6859
7200
  `));
6860
7201
  return;
6861
7202
  }
6862
7203
  installMissingGuidanceFiles(guidanceDirectory, projectDirectory, missingFiles);
6863
- console.log(import_picocolors2.default.green(` ✔ Added ${missingFiles.length} guidance file(s); existing files were preserved.`));
7204
+ console.log(import_picocolors3.default.green(` ✔ Added ${missingFiles.length} guidance file(s); existing files were preserved.`));
6864
7205
  console.log();
6865
7206
  }
6866
7207
  async function init() {
6867
7208
  console.log();
6868
- console.log(import_picocolors2.default.cyan(" ╔═══════════════════════════════════╗"));
6869
- console.log(import_picocolors2.default.cyan(" ║ ") + import_picocolors2.default.bold("create-svadmin") + import_picocolors2.default.cyan(" ║"));
6870
- console.log(import_picocolors2.default.cyan(" ║ ") + import_picocolors2.default.dim("Headless Admin for Svelte 5") + import_picocolors2.default.cyan(" ║"));
6871
- console.log(import_picocolors2.default.cyan(" ╚═══════════════════════════════════╝"));
7209
+ console.log(import_picocolors3.default.cyan(" ╔═══════════════════════════════════╗"));
7210
+ console.log(import_picocolors3.default.cyan(" ║ ") + import_picocolors3.default.bold("create-svadmin") + import_picocolors3.default.cyan(" ║"));
7211
+ console.log(import_picocolors3.default.cyan(" ║ ") + import_picocolors3.default.dim("Headless Admin for Svelte 5") + import_picocolors3.default.cyan(" ║"));
7212
+ console.log(import_picocolors3.default.cyan(" ╚═══════════════════════════════════╝"));
6872
7213
  console.log();
6873
7214
  const response = await import_prompts2.default([
6874
7215
  {
@@ -6879,7 +7220,7 @@ async function init() {
6879
7220
  validate: (value) => {
6880
7221
  if (!value.trim())
6881
7222
  return "Project name is required";
6882
- if (fs2.existsSync(value.trim()) && fs2.readdirSync(value.trim()).length > 0) {
7223
+ if (fs4.existsSync(value.trim()) && fs4.readdirSync(value.trim()).length > 0) {
6883
7224
  return "Directory already exists and is not empty";
6884
7225
  }
6885
7226
  return true;
@@ -6917,61 +7258,61 @@ async function init() {
6917
7258
  }
6918
7259
  ]);
6919
7260
  if (!response.projectName) {
6920
- console.log(import_picocolors2.default.red(`
7261
+ console.log(import_picocolors3.default.red(`
6921
7262
  Operation cancelled.
6922
7263
  `));
6923
7264
  return;
6924
7265
  }
6925
- const projectDir = path2.resolve(process.cwd(), response.projectName.trim());
6926
- if (!fs2.existsSync(projectDir)) {
6927
- fs2.mkdirSync(projectDir, { recursive: true });
7266
+ const projectDir = path4.resolve(process.cwd(), response.projectName.trim());
7267
+ if (!fs4.existsSync(projectDir)) {
7268
+ fs4.mkdirSync(projectDir, { recursive: true });
6928
7269
  }
6929
7270
  console.log(`
6930
- ${import_picocolors2.default.bold("Scaffolding")} project in ${import_picocolors2.default.green(projectDir)}...
7271
+ ${import_picocolors3.default.bold("Scaffolding")} project in ${import_picocolors3.default.green(projectDir)}...
6931
7272
  `);
6932
- const templateDir = path2.join(__dirname2, "..", "template");
6933
- const guidanceDir = path2.join(__dirname2, "..", "guidance");
7273
+ const templateDir = path4.join(__dirname2, "..", "template");
7274
+ const guidanceDir = path4.join(__dirname2, "..", "guidance");
6934
7275
  const scaffoldManifest = loadShippedScaffoldManifest();
6935
7276
  function copyDir(src, dest) {
6936
- fs2.mkdirSync(dest, { recursive: true });
6937
- const entries = fs2.readdirSync(src, { withFileTypes: true });
7277
+ fs4.mkdirSync(dest, { recursive: true });
7278
+ const entries = fs4.readdirSync(src, { withFileTypes: true });
6938
7279
  for (const entry of entries) {
6939
- const srcPath = path2.join(src, entry.name);
6940
- const destPath = path2.join(dest, entry.name === "_gitignore" ? ".gitignore" : entry.name);
7280
+ const srcPath = path4.join(src, entry.name);
7281
+ const destPath = path4.join(dest, entry.name === "_gitignore" ? ".gitignore" : entry.name);
6941
7282
  if (entry.isDirectory()) {
6942
7283
  copyDir(srcPath, destPath);
6943
7284
  } else {
6944
- fs2.copyFileSync(srcPath, destPath);
7285
+ fs4.copyFileSync(srcPath, destPath);
6945
7286
  }
6946
7287
  }
6947
7288
  }
6948
- if (fs2.existsSync(templateDir)) {
7289
+ if (fs4.existsSync(templateDir)) {
6949
7290
  copyDir(templateDir, projectDir);
6950
- console.log(import_picocolors2.default.green(" ✔") + " Template files copied");
7291
+ console.log(import_picocolors3.default.green(" ✔") + " Template files copied");
6951
7292
  }
6952
- if (fs2.existsSync(guidanceDir)) {
7293
+ if (fs4.existsSync(guidanceDir)) {
6953
7294
  copyDir(guidanceDir, projectDir);
6954
- console.log(import_picocolors2.default.green(" ✔") + " AI and design guidance copied");
7295
+ console.log(import_picocolors3.default.green(" ✔") + " AI and design guidance copied");
6955
7296
  }
6956
7297
  const packageJson = createProjectPackageJson(scaffoldManifest, {
6957
7298
  projectName: response.projectName,
6958
7299
  dataProvider: response.dataProvider,
6959
7300
  authProvider: response.authProvider
6960
7301
  });
6961
- fs2.writeFileSync(path2.join(projectDir, "package.json"), `${JSON.stringify(packageJson, null, 2)}
7302
+ fs4.writeFileSync(path4.join(projectDir, "package.json"), `${JSON.stringify(packageJson, null, 2)}
6962
7303
  `);
6963
- console.log(import_picocolors2.default.green(" ✔") + " package.json generated");
6964
- fs2.writeFileSync(path2.join(projectDir, ".gitignore"), `node_modules
7304
+ console.log(import_picocolors3.default.green(" ✔") + " package.json generated");
7305
+ fs4.writeFileSync(path4.join(projectDir, ".gitignore"), `node_modules
6965
7306
  dist
6966
7307
  .svelte-kit
6967
7308
  .env
6968
7309
  .env.local
6969
7310
  *.local
6970
7311
  `);
6971
- console.log(import_picocolors2.default.green(" ✔") + " .gitignore generated");
7312
+ console.log(import_picocolors3.default.green(" ✔") + " .gitignore generated");
6972
7313
  const dpLabel = response.dataProvider === "simple-rest" ? "Simple REST" : response.dataProvider === "supabase" ? "Supabase" : response.dataProvider === "graphql" ? "GraphQL" : "Custom";
6973
7314
  const authLabel = response.authProvider === "mock" ? "Mock (demo)" : response.authProvider === "jwt" ? "JWT" : response.authProvider === "supabase" ? "Supabase Auth" : "None";
6974
- fs2.writeFileSync(path2.join(projectDir, "README.md"), `# ${response.projectName}
7315
+ fs4.writeFileSync(path4.join(projectDir, "README.md"), `# ${response.projectName}
6975
7316
 
6976
7317
  Built with [svadmin](https://github.com/vibeunion/svadmin) — Headless Admin Framework for Svelte 5.
6977
7318
 
@@ -6989,30 +7330,30 @@ bun run dev
6989
7330
  - **Auth**: ${authLabel}
6990
7331
  - **State**: TanStack Query v6
6991
7332
  `);
6992
- console.log(import_picocolors2.default.green(" ✔") + " README.md generated");
7333
+ console.log(import_picocolors3.default.green(" ✔") + " README.md generated");
6993
7334
  if (response.installDeps) {
6994
7335
  console.log(`
6995
- ${import_picocolors2.default.bold("Installing dependencies...")}
7336
+ ${import_picocolors3.default.bold("Installing dependencies...")}
6996
7337
  `);
6997
7338
  const bunInstall = spawnSync("bun", ["install"], { cwd: projectDir, stdio: "inherit" });
6998
7339
  if (bunInstall.status !== 0) {
6999
7340
  const npmInstall = spawnSync("npm", ["install"], { cwd: projectDir, stdio: "inherit" });
7000
7341
  if (npmInstall.status !== 0) {
7001
- console.log(import_picocolors2.default.yellow("\n ⚠ Auto-install failed. Run `bun install` or `npm install` manually."));
7342
+ console.log(import_picocolors3.default.yellow("\n ⚠ Auto-install failed. Run `bun install` or `npm install` manually."));
7002
7343
  }
7003
7344
  }
7004
7345
  }
7005
7346
  console.log();
7006
- console.log(import_picocolors2.default.green(import_picocolors2.default.bold(" ✔ Project ready!")));
7347
+ console.log(import_picocolors3.default.green(import_picocolors3.default.bold(" ✔ Project ready!")));
7007
7348
  console.log();
7008
7349
  console.log(" Next steps:");
7009
- console.log(` ${import_picocolors2.default.cyan(`cd ${response.projectName}`)}`);
7350
+ console.log(` ${import_picocolors3.default.cyan(`cd ${response.projectName}`)}`);
7010
7351
  if (!response.installDeps) {
7011
- console.log(` ${import_picocolors2.default.cyan("bun install")}`);
7352
+ console.log(` ${import_picocolors3.default.cyan("bun install")}`);
7012
7353
  }
7013
- console.log(` ${import_picocolors2.default.cyan("bun run dev")}`);
7354
+ console.log(` ${import_picocolors3.default.cyan("bun run dev")}`);
7014
7355
  console.log();
7015
- console.log(` Docs: ${import_picocolors2.default.blue("https://github.com/vibeunion/svadmin")}`);
7356
+ console.log(` Docs: ${import_picocolors3.default.blue("https://github.com/vibeunion/svadmin")}`);
7016
7357
  console.log();
7017
7358
  }
7018
7359
  var EJECT_COMPONENTS = [
@@ -7044,64 +7385,64 @@ var EJECT_COMPONENTS = [
7044
7385
  ];
7045
7386
  async function eject(args) {
7046
7387
  console.log();
7047
- console.log(import_picocolors2.default.cyan(" svadmin eject") + import_picocolors2.default.dim(" — copy internal components for deep customization"));
7388
+ console.log(import_picocolors3.default.cyan(" svadmin eject") + import_picocolors3.default.dim(" — copy internal components for deep customization"));
7048
7389
  console.log();
7049
7390
  const requested = args.filter((a) => !a.startsWith("-"));
7050
7391
  const toEject = requested.length > 0 ? requested.filter((name) => {
7051
7392
  if (!EJECT_COMPONENTS.includes(name)) {
7052
- console.log(import_picocolors2.default.yellow(` ⚠ Unknown component: ${name} (skipped)`));
7393
+ console.log(import_picocolors3.default.yellow(` ⚠ Unknown component: ${name} (skipped)`));
7053
7394
  return false;
7054
7395
  }
7055
7396
  return true;
7056
7397
  }) : [...EJECT_COMPONENTS];
7057
7398
  if (toEject.length === 0) {
7058
- console.log(import_picocolors2.default.red(" No valid components to eject."));
7399
+ console.log(import_picocolors3.default.red(" No valid components to eject."));
7059
7400
  console.log(` Available: ${EJECT_COMPONENTS.join(", ")}`);
7060
7401
  return;
7061
7402
  }
7062
7403
  let uiSrcDir;
7063
7404
  try {
7064
7405
  const require2 = createRequire2(import.meta.url);
7065
- const uiPkg = path2.dirname(require2.resolve("@svadmin/ui/package.json"));
7066
- uiSrcDir = path2.join(uiPkg, "src", "components");
7406
+ const uiPkg = path4.dirname(require2.resolve("@svadmin/ui/package.json"));
7407
+ uiSrcDir = path4.join(uiPkg, "src", "components");
7067
7408
  } catch {
7068
- const nm = path2.join(process.cwd(), "node_modules", "@svadmin", "ui", "src", "components");
7069
- if (fs2.existsSync(nm)) {
7409
+ const nm = path4.join(process.cwd(), "node_modules", "@svadmin", "ui", "src", "components");
7410
+ if (fs4.existsSync(nm)) {
7070
7411
  uiSrcDir = nm;
7071
7412
  } else {
7072
- console.log(import_picocolors2.default.red(" ✗ Cannot find @svadmin/ui. Run `bun install` first."));
7413
+ console.log(import_picocolors3.default.red(" ✗ Cannot find @svadmin/ui. Run `bun install` first."));
7073
7414
  return;
7074
7415
  }
7075
7416
  }
7076
- const destDir = path2.join(process.cwd(), "src", "components", "svadmin");
7077
- fs2.mkdirSync(destDir, { recursive: true });
7417
+ const destDir = path4.join(process.cwd(), "src", "components", "svadmin");
7418
+ fs4.mkdirSync(destDir, { recursive: true });
7078
7419
  let copied = 0;
7079
7420
  for (const name of toEject) {
7080
- const srcFile = path2.join(uiSrcDir, `${name}.svelte`);
7081
- const srcFileAlt = path2.join(uiSrcDir, "fields", `${name}.svelte`);
7082
- const src = fs2.existsSync(srcFile) ? srcFile : fs2.existsSync(srcFileAlt) ? srcFileAlt : null;
7421
+ const srcFile = path4.join(uiSrcDir, `${name}.svelte`);
7422
+ const srcFileAlt = path4.join(uiSrcDir, "fields", `${name}.svelte`);
7423
+ const src = fs4.existsSync(srcFile) ? srcFile : fs4.existsSync(srcFileAlt) ? srcFileAlt : null;
7083
7424
  if (!src) {
7084
- console.log(import_picocolors2.default.yellow(` ⚠ ${name}.svelte not found in @svadmin/ui (skipped)`));
7425
+ console.log(import_picocolors3.default.yellow(` ⚠ ${name}.svelte not found in @svadmin/ui (skipped)`));
7085
7426
  continue;
7086
7427
  }
7087
- let content = fs2.readFileSync(src, "utf-8");
7428
+ let content = fs4.readFileSync(src, "utf-8");
7088
7429
  content = content.replace(/from\s+['"]\.\/ui\//g, "from '@svadmin/ui/components/ui/");
7089
7430
  content = content.replace(/from\s+['"]\.\/((?!ui\/)[^'"]+)['"]/g, "from './$1'");
7090
- const destFile = path2.join(destDir, `${name}.svelte`);
7091
- fs2.writeFileSync(destFile, content);
7092
- console.log(import_picocolors2.default.green(" ✔") + ` ${name}.svelte → src/components/svadmin/`);
7431
+ const destFile = path4.join(destDir, `${name}.svelte`);
7432
+ fs4.writeFileSync(destFile, content);
7433
+ console.log(import_picocolors3.default.green(" ✔") + ` ${name}.svelte → src/components/svadmin/`);
7093
7434
  copied++;
7094
7435
  }
7095
7436
  console.log();
7096
7437
  if (copied > 0) {
7097
- console.log(import_picocolors2.default.green(import_picocolors2.default.bold(` ✔ Ejected ${copied} component(s)`)));
7438
+ console.log(import_picocolors3.default.green(import_picocolors3.default.bold(` ✔ Ejected ${copied} component(s)`)));
7098
7439
  console.log();
7099
7440
  console.log(" Usage: import overrides in your AdminApp and pass via `components` prop:");
7100
7441
  console.log();
7101
- console.log(import_picocolors2.default.dim(' import CustomLayout from "./components/svadmin/Layout.svelte";'));
7102
- console.log(import_picocolors2.default.dim(" <AdminApp components={{ Layout: CustomLayout }} ... />"));
7442
+ console.log(import_picocolors3.default.dim(' import CustomLayout from "./components/svadmin/Layout.svelte";'));
7443
+ console.log(import_picocolors3.default.dim(" <AdminApp components={{ Layout: CustomLayout }} ... />"));
7103
7444
  } else {
7104
- console.log(import_picocolors2.default.yellow(" No components were ejected."));
7445
+ console.log(import_picocolors3.default.yellow(" No components were ejected."));
7105
7446
  }
7106
7447
  console.log();
7107
7448
  }
@@ -7109,7 +7450,7 @@ var [, , subcommand, ...rest] = process.argv;
7109
7450
  var runCommand = (command) => {
7110
7451
  Promise.resolve().then(command).catch((error) => {
7111
7452
  const message = error instanceof Error ? error.message : String(error);
7112
- console.error(import_picocolors2.default.red(`
7453
+ console.error(import_picocolors3.default.red(`
7113
7454
  ✗ ${message}
7114
7455
  `));
7115
7456
  process.exitCode = 2;
@@ -7125,6 +7466,16 @@ if (subcommand === "eject") {
7125
7466
  runCommand(() => guidance(rest));
7126
7467
  } else if (subcommand === "infer") {
7127
7468
  runCommand(() => inferCommand(rest));
7469
+ } else if (subcommand === "generate" || subcommand === "gen") {
7470
+ runCommand(() => generateCommand(rest));
7471
+ } else if (subcommand === "lite") {
7472
+ if (rest[0] !== "init") {
7473
+ runCommand(() => {
7474
+ throw new Error("Usage: create-svadmin lite init [project-directory] [--write]");
7475
+ });
7476
+ } else {
7477
+ runCommand(() => liteInitCommand(rest.slice(1)));
7478
+ }
7128
7479
  } else {
7129
7480
  runCommand(init);
7130
7481
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svadmin/create",
3
- "version": "0.20.0",
3
+ "version": "0.22.0",
4
4
  "description": "Scaffolding tool for svadmin projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -27,7 +27,7 @@
27
27
  "@types/node": "^26.4.0",
28
28
  "@types/prompts": "^2.4.9",
29
29
  "typescript": "^7.0.2",
30
- "@svadmin/core": "^0.45.0"
30
+ "@svadmin/core": "^0.47.0"
31
31
  },
32
32
  "keywords": [
33
33
  "svadmin",
@@ -10,8 +10,8 @@
10
10
  "check": "svelte-check --tsconfig ./tsconfig.json"
11
11
  },
12
12
  "dependencies": {
13
- "@svadmin/core": "^0.45.0",
14
- "@svadmin/ui": "^0.63.0",
13
+ "@svadmin/core": "^0.47.0",
14
+ "@svadmin/ui": "^0.65.0",
15
15
  "@tanstack/svelte-query": "^6.1.48",
16
16
  "highlight.js": "^11.12.0",
17
17
  "@lucide/svelte": "^1.35.0"
@@ -32,16 +32,16 @@
32
32
  "@refinedev/core": "^5.0.12"
33
33
  },
34
34
  "simple-rest": {
35
- "@svadmin/simple-rest": "^0.9.18",
35
+ "@svadmin/simple-rest": "^0.9.20",
36
36
  "@refinedev/simple-rest": "^6.0.1"
37
37
  },
38
38
  "supabase": {
39
- "@svadmin/supabase": "^0.13.0",
39
+ "@svadmin/supabase": "^0.13.2",
40
40
  "@supabase/supabase-js": "^2.112.4",
41
41
  "@refinedev/supabase": "^6.0.2"
42
42
  },
43
43
  "graphql": {
44
- "@svadmin/graphql": "^0.9.18",
44
+ "@svadmin/graphql": "^0.9.20",
45
45
  "@refinedev/graphql": "^8.0.1",
46
46
  "graphql-request": "^7.4.0",
47
47
  "graphql": "^16.8.0"