@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 +57 -1
- package/guidance/DESIGN.md +6 -3
- package/package.json +3 -3
- package/scaffold-manifest.json +21 -21
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 {
|
|
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),
|
package/guidance/DESIGN.md
CHANGED
|
@@ -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`:
|
|
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
|
-
-
|
|
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.
|
|
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.
|
|
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.
|
|
33
|
+
"@svadmin/core": "^0.60.0"
|
|
34
34
|
},
|
|
35
35
|
"keywords": [
|
|
36
36
|
"svadmin",
|
package/scaffold-manifest.json
CHANGED
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
"check": "svelte-check --tsconfig ./tsconfig.json"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@svadmin/core": "^0.
|
|
14
|
-
"@svadmin/app": "^0.2.
|
|
15
|
-
"@svadmin/ai-elements": "^0.11.
|
|
16
|
-
"@svadmin/ui": "^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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
65
|
+
"@svadmin/airtable": "^0.12.4",
|
|
66
66
|
"@refinedev/airtable": "^5.0.1"
|
|
67
67
|
},
|
|
68
68
|
"appwrite": {
|
|
69
|
-
"@svadmin/appwrite": "^0.11.
|
|
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.
|
|
74
|
+
"@svadmin/directus": "^0.11.4"
|
|
75
75
|
},
|
|
76
76
|
"drizzle": {
|
|
77
|
-
"@svadmin/drizzle": "^0.14.
|
|
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.
|
|
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.
|
|
87
|
+
"@svadmin/firebase": "^0.12.4"
|
|
88
88
|
},
|
|
89
89
|
"hasura": {
|
|
90
|
-
"@svadmin/hasura": "^0.12.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
107
|
+
"@svadmin/pocketbase": "^0.13.1",
|
|
108
108
|
"pocketbase": ">=0.28.0"
|
|
109
109
|
},
|
|
110
110
|
"sanity": {
|
|
111
|
-
"@svadmin/sanity": "^0.11.
|
|
111
|
+
"@svadmin/sanity": "^0.11.4"
|
|
112
112
|
},
|
|
113
113
|
"strapi": {
|
|
114
|
-
"@svadmin/strapi": "^0.12.
|
|
114
|
+
"@svadmin/strapi": "^0.12.4",
|
|
115
115
|
"@refinedev/strapi-v4": "^7.0.1"
|
|
116
116
|
}
|
|
117
117
|
},
|