@svadmin/create 0.40.0 → 0.40.2

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/index.js CHANGED
@@ -15967,6 +15967,15 @@ function inferResource(resourceName, sampleData, options = {}) {
15967
15967
  resource: emptyResource,
15968
15968
  code: `// No data available to infer fields for "${resourceName}".`,
15969
15969
  typeboxCode: generateTypeBoxSchemaCode(emptyResource),
15970
+ review: {
15971
+ needsReview: true,
15972
+ confidence: "low",
15973
+ sampleSize: 0,
15974
+ warnings: [{
15975
+ code: "empty-sample",
15976
+ message: `No sample records were available for "${resourceName}".`
15977
+ }]
15978
+ },
15970
15979
  componentCode: {
15971
15980
  list: generateListPageCode(emptyResource),
15972
15981
  create: generateCreatePageCode(emptyResource),
@@ -15981,10 +15990,18 @@ function inferResource(resourceName, sampleData, options = {}) {
15981
15990
  keySet.add(k);
15982
15991
  }
15983
15992
  const fields = [];
15993
+ const warnings = [];
15984
15994
  for (const key of keySet) {
15985
15995
  const values = sampleData.map((r) => r[key]).filter((v) => v !== null && v !== undefined);
15986
15996
  const sampleValue = values[0];
15987
15997
  let inferredType = inferFieldType(key, sampleValue);
15998
+ if (values.length === 0) {
15999
+ warnings.push({
16000
+ code: "nullable-field",
16001
+ field: key,
16002
+ message: `Field "${key}" contains only null or undefined values in the sample.`
16003
+ });
16004
+ }
15988
16005
  const typeCounts = new Map;
15989
16006
  for (const v of values) {
15990
16007
  const t = inferFieldType(key, v);
@@ -15997,9 +16014,30 @@ function inferResource(resourceName, sampleData, options = {}) {
15997
16014
  inferredType = t;
15998
16015
  }
15999
16016
  }
16017
+ if (typeCounts.size > 1) {
16018
+ warnings.push({
16019
+ code: "mixed-types",
16020
+ field: key,
16021
+ message: `Field "${key}" contains multiple inferred types; the majority type was selected.`
16022
+ });
16023
+ }
16000
16024
  const relatedResource = isLikelyRelation(key);
16025
+ if (relatedResource) {
16026
+ warnings.push({
16027
+ code: "heuristic-relation",
16028
+ field: key,
16029
+ message: `Relation "${key}" was inferred from its field name.`
16030
+ });
16031
+ }
16001
16032
  const uniqueStrings = new Set(values.filter((v) => typeof v === "string"));
16002
16033
  const isSelect = inferredType === "text" && uniqueStrings.size > 1 && uniqueStrings.size <= 10 && values.length >= 5;
16034
+ if (isSelect) {
16035
+ warnings.push({
16036
+ code: "heuristic-select",
16037
+ field: key,
16038
+ message: `Select options for "${key}" were inferred from repeated sample values.`
16039
+ });
16040
+ }
16003
16041
  const field = {
16004
16042
  key,
16005
16043
  label: humanize3(key),
@@ -16044,7 +16082,19 @@ function inferResource(resourceName, sampleData, options = {}) {
16044
16082
  edit: generateEditPageCode(resource),
16045
16083
  show: generateShowPageCode(resource)
16046
16084
  };
16047
- return { fields, resource, code, typeboxCode, componentCode };
16085
+ return {
16086
+ fields,
16087
+ resource,
16088
+ code,
16089
+ typeboxCode,
16090
+ review: {
16091
+ needsReview: warnings.length > 0,
16092
+ confidence: warnings.some((warning) => warning.code === "mixed-types" || warning.code === "nullable-field") ? "low" : warnings.length > 0 ? "medium" : "high",
16093
+ sampleSize: sampleData.length,
16094
+ warnings
16095
+ },
16096
+ componentCode
16097
+ };
16048
16098
  }
16049
16099
  function generateCode(resource) {
16050
16100
  const esc = (s) => s.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
@@ -16230,6 +16280,12 @@ function generateResourceBundle(resource) {
16230
16280
  resource,
16231
16281
  code: generateResourceCode(resource),
16232
16282
  typeboxCode: generateTypeBoxSchemaCode(resource),
16283
+ review: {
16284
+ needsReview: false,
16285
+ confidence: "high",
16286
+ sampleSize: 0,
16287
+ warnings: []
16288
+ },
16233
16289
  componentCode: {
16234
16290
  list: generateListPageCode(resource),
16235
16291
  create: generateCreatePageCode(resource),
@@ -300,10 +300,10 @@ Use `PagePattern` for custom business compositions that do not fit those
300
300
  resource routes. It supplies layout only, not querying, permissions, form
301
301
  submission, or loading/error handling:
302
302
 
303
- - `list`: compact title, toolbar, table/list content, and list empty states.
303
+ - `list`: comfortable title, toolbar, table/list content, and list empty states.
304
304
  - `form`: narrow reading width, comfortable grouped fields and a single save area.
305
305
  - `detail`: read-only summary and related content.
306
- - `workspace`: primary work area plus an optional secondary panel.
306
+ - `workspace`: comfortable primary work area plus an optional secondary panel.
307
307
  - `dashboard`: wide layout with optional metrics and secondary context.
308
308
 
309
309
  Optional `secondary` content renders beside the primary content for every kind.
@@ -357,7 +357,10 @@ cards, repeated title bars, or unrestricted two-column fields.
357
357
  persistence request succeeds; preserve edits after failure.
358
358
  - Separate initial-empty content from filtered-no-results content. Offer
359
359
  creation only when permitted, and clearing filters only when filters exist.
360
- - Use compact density for operational work and comfortable density for forms.
360
+ - Page patterns default to comfortable density so generated and custom pages
361
+ have a consistent baseline. Use compact density explicitly for operational
362
+ work that prioritizes scanning speed; use comfortable density for forms and
363
+ general-purpose pages.
361
364
  - Reference `packages/ui/stories/ConfigurationExample.svelte` in the SVAdmin
362
365
  source for a working composition; its save action is in-memory demo state,
363
366
  not a persistence implementation.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svadmin/create",
3
- "version": "0.40.0",
3
+ "version": "0.40.2",
4
4
  "description": "Scaffolding tool for svadmin projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -21,7 +21,7 @@
21
21
  "prepublishOnly": "bun run build"
22
22
  },
23
23
  "dependencies": {
24
- "@modelcontextprotocol/sdk": "1.30.1",
24
+ "@modelcontextprotocol/sdk": "1.32.1",
25
25
  "typebox": "^1.3.34",
26
26
  "prompts": "^2.4.2",
27
27
  "picocolors": "^1.1.1"
@@ -30,7 +30,7 @@
30
30
  "@types/node": "^26.4.0",
31
31
  "@types/prompts": "^2.4.9",
32
32
  "typescript": "^7.0.2",
33
- "@svadmin/core": "^0.59.0"
33
+ "@svadmin/core": "^0.60.0"
34
34
  },
35
35
  "keywords": [
36
36
  "svadmin",
@@ -10,10 +10,10 @@
10
10
  "check": "svelte-check --tsconfig ./tsconfig.json"
11
11
  },
12
12
  "dependencies": {
13
- "@svadmin/core": "^0.59.0",
14
- "@svadmin/app": "^0.2.2",
15
- "@svadmin/ai-elements": "^0.11.0",
16
- "@svadmin/ui": "^0.82.0",
13
+ "@svadmin/core": "^0.60.0",
14
+ "@svadmin/app": "^0.2.3",
15
+ "@svadmin/ai-elements": "^0.11.1",
16
+ "@svadmin/ui": "^0.83.1",
17
17
  "typebox": "^1.3.34",
18
18
  "@tanstack/svelte-query": "^6.1.48",
19
19
  "@lucide/svelte": "^1.35.0"
@@ -42,76 +42,76 @@
42
42
  "graphql": "^16.8.0"
43
43
  },
44
44
  "simple-rest": {
45
- "@svadmin/simple-rest": "^0.12.3",
45
+ "@svadmin/simple-rest": "^0.12.4",
46
46
  "@refinedev/simple-rest": "^6.0.1"
47
47
  },
48
48
  "supabase": {
49
- "@svadmin/supabase": "^0.19.0",
49
+ "@svadmin/supabase": "^0.19.1",
50
50
  "@supabase/supabase-js": "^2.112.4",
51
51
  "@refinedev/supabase": "^6.0.2"
52
52
  },
53
53
  "graphql": {
54
- "@svadmin/graphql": "^0.12.3",
54
+ "@svadmin/graphql": "^0.12.4",
55
55
  "@refinedev/graphql": "^8.0.1",
56
56
  "graphql-request": "^7.4.0",
57
57
  "graphql": "^16.8.0"
58
58
  },
59
59
  "rest": {
60
- "@svadmin/rest": "^0.2.2",
60
+ "@svadmin/rest": "^0.2.3",
61
61
  "@refinedev/rest": "^2.1.1",
62
62
  "@nestjsx/crud-request": "^5.0.0-alpha.3"
63
63
  },
64
64
  "airtable": {
65
- "@svadmin/airtable": "^0.12.3",
65
+ "@svadmin/airtable": "^0.12.4",
66
66
  "@refinedev/airtable": "^5.0.1"
67
67
  },
68
68
  "appwrite": {
69
- "@svadmin/appwrite": "^0.11.3",
69
+ "@svadmin/appwrite": "^0.11.4",
70
70
  "appwrite": ">=26.2.0",
71
71
  "@refinedev/appwrite": "^8.0.1"
72
72
  },
73
73
  "directus": {
74
- "@svadmin/directus": "^0.11.3"
74
+ "@svadmin/directus": "^0.11.4"
75
75
  },
76
76
  "drizzle": {
77
- "@svadmin/drizzle": "^0.14.0",
77
+ "@svadmin/drizzle": "^0.14.1",
78
78
  "drizzle-orm": "^1.0.0-rc.1",
79
79
  "refine-sqlx": "^0.10.3"
80
80
  },
81
81
  "elysia": {
82
- "@svadmin/elysia": "^0.14.3",
82
+ "@svadmin/elysia": "^0.14.4",
83
83
  "elysia": ">=1.4.30",
84
84
  "@elysiajs/eden": ">=1.4.9"
85
85
  },
86
86
  "firebase": {
87
- "@svadmin/firebase": "^0.12.3"
87
+ "@svadmin/firebase": "^0.12.4"
88
88
  },
89
89
  "hasura": {
90
- "@svadmin/hasura": "^0.12.3",
90
+ "@svadmin/hasura": "^0.12.4",
91
91
  "@refinedev/hasura": "^7.0.1",
92
92
  "graphql-request": "^7.4.0"
93
93
  },
94
94
  "medusa": {
95
- "@svadmin/medusa": "^0.12.3",
95
+ "@svadmin/medusa": "^0.12.4",
96
96
  "@refinedev/medusa": "^5.0.0"
97
97
  },
98
98
  "nestjs-query": {
99
- "@svadmin/nestjs-query": "^0.12.3",
99
+ "@svadmin/nestjs-query": "^0.12.4",
100
100
  "@refinedev/nestjs-query": "^5.0.0"
101
101
  },
102
102
  "nestjsx-crud": {
103
- "@svadmin/nestjsx-crud": "^0.12.3",
103
+ "@svadmin/nestjsx-crud": "^0.12.4",
104
104
  "@refinedev/nestjsx-crud": "^6.0.1"
105
105
  },
106
106
  "pocketbase": {
107
- "@svadmin/pocketbase": "^0.13.0",
107
+ "@svadmin/pocketbase": "^0.13.1",
108
108
  "pocketbase": ">=0.28.0"
109
109
  },
110
110
  "sanity": {
111
- "@svadmin/sanity": "^0.11.3"
111
+ "@svadmin/sanity": "^0.11.4"
112
112
  },
113
113
  "strapi": {
114
- "@svadmin/strapi": "^0.12.3",
114
+ "@svadmin/strapi": "^0.12.4",
115
115
  "@refinedev/strapi-v4": "^7.0.1"
116
116
  }
117
117
  },