@svgrid/studio 0.4.0 → 0.6.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/dist/cli.js +70 -20
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -14,7 +14,7 @@ import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
|
14
14
|
import { spawnSync } from 'node:child_process';
|
|
15
15
|
import { createInterface } from 'node:readline/promises';
|
|
16
16
|
import { dirname, resolve } from 'node:path';
|
|
17
|
-
import { buildStudioBugReport, createProject, deployCommands, emitStudioAppBundle, emitStudioFragment, introspectDatabase, introspectOpenApi, runtimeDeps, listDatabaseTables, missingEnvKeys, parseProject, resolveDeployTarget, resolveSchemas, runStudioAdd, runStudioAddApp, runStudioInit, serializeProject, setEntityDataSource, summarizeVerify, } from '@svgrid/enterprise/studio';
|
|
17
|
+
import { buildStudioBugReport, createProject, deployCommands, emitStudioAppBundle, emitStudioFragment, introspectDatabase, introspectOpenApi, isUserError, runtimeDeps, listDatabaseTables, missingEnvKeys, parseProject, resolveDeployTarget, resolveSchemas, runStudioAdd, runStudioAddApp, runStudioInit, sampleApps, serializeProject, setEntityDataSource, summarizeVerify, UserError, } from '@svgrid/enterprise/studio';
|
|
18
18
|
import { connect } from './db-connect.js';
|
|
19
19
|
import { ensureDriverInstalled } from './driver-install.js';
|
|
20
20
|
import { startDesignerServer } from './designer-server.js';
|
|
@@ -36,56 +36,73 @@ const io = {
|
|
|
36
36
|
function parse(args) {
|
|
37
37
|
const out = {};
|
|
38
38
|
const positional = [];
|
|
39
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Read the value that follows a flag. A missing or flag-shaped value used to
|
|
41
|
+
* come back as `undefined` and read as "not passed", so `--url` at the end of
|
|
42
|
+
* the line silently fell through to a different code path instead of saying
|
|
43
|
+
* what was wrong.
|
|
44
|
+
*/
|
|
45
|
+
let i = 0;
|
|
46
|
+
const value = (flag) => {
|
|
47
|
+
const next = args[i + 1];
|
|
48
|
+
if (next === undefined || next.startsWith('-')) {
|
|
49
|
+
throw new UserError(`${flag} needs a value.`, 'Run `svgrid-studio --help` to see what each flag expects.');
|
|
50
|
+
}
|
|
51
|
+
i++;
|
|
52
|
+
return next;
|
|
53
|
+
};
|
|
54
|
+
for (i = 0; i < args.length; i++) {
|
|
40
55
|
const a = args[i];
|
|
41
56
|
if (a === '--from')
|
|
42
|
-
out.from =
|
|
57
|
+
out.from = value(a);
|
|
43
58
|
else if (a === '--table')
|
|
44
|
-
out.table =
|
|
59
|
+
out.table = value(a);
|
|
45
60
|
else if (a === '--route')
|
|
46
|
-
out.route =
|
|
61
|
+
out.route = value(a);
|
|
47
62
|
else if (a === '--api')
|
|
48
|
-
out.apiRoute =
|
|
63
|
+
out.apiRoute = value(a);
|
|
49
64
|
else if (a === '--sql')
|
|
50
65
|
out.dataSource = 'sql';
|
|
51
66
|
else if (a === '--db')
|
|
52
|
-
out.db =
|
|
67
|
+
out.db = value(a);
|
|
53
68
|
else if (a === '--url')
|
|
54
|
-
out.url =
|
|
69
|
+
out.url = value(a);
|
|
55
70
|
else if (a === '--all')
|
|
56
71
|
out.all = true;
|
|
57
72
|
else if (a === '--config')
|
|
58
|
-
out.config =
|
|
73
|
+
out.config = value(a);
|
|
59
74
|
else if (a === '--out')
|
|
60
|
-
out.outDir =
|
|
75
|
+
out.outDir = value(a);
|
|
61
76
|
else if (a === '--port')
|
|
62
|
-
out.port = Number(
|
|
77
|
+
out.port = Number(value(a));
|
|
63
78
|
else if (a === '--template')
|
|
64
|
-
out.template =
|
|
79
|
+
out.template = value(a);
|
|
65
80
|
else if (a === '--no-open')
|
|
66
81
|
out.noOpen = true;
|
|
67
82
|
else if (a === '--target')
|
|
68
|
-
out.target =
|
|
83
|
+
out.target = value(a);
|
|
69
84
|
else if (a === '--dry-run')
|
|
70
85
|
out.dryRun = true;
|
|
71
86
|
else if (a === '--ai')
|
|
72
87
|
out.ai = true;
|
|
73
88
|
else if (a === '--app-port')
|
|
74
|
-
out.appPort = Number(
|
|
89
|
+
out.appPort = Number(value(a));
|
|
75
90
|
else if (a === '--fragment')
|
|
76
91
|
out.fragment = true;
|
|
77
92
|
else if (a === '--supabase-url')
|
|
78
|
-
out.supabaseUrl =
|
|
93
|
+
out.supabaseUrl = value(a);
|
|
79
94
|
else if (a === '--supabase-key')
|
|
80
|
-
out.supabaseKey =
|
|
95
|
+
out.supabaseKey = value(a);
|
|
81
96
|
else if (a === '--dataset')
|
|
82
|
-
out.dataset =
|
|
97
|
+
out.dataset = value(a);
|
|
83
98
|
else if (a === '--theme')
|
|
84
|
-
out.theme =
|
|
99
|
+
out.theme = value(a);
|
|
85
100
|
else if (a === '--dark')
|
|
86
101
|
out.dark = true;
|
|
87
102
|
else if (a === '--title')
|
|
88
|
-
out.title =
|
|
103
|
+
out.title = value(a);
|
|
104
|
+
else if (a === '-f' || a === '--force')
|
|
105
|
+
out.force = true;
|
|
89
106
|
else if (a === '-y' || a === '--yes')
|
|
90
107
|
out.yes = true;
|
|
91
108
|
else if (a === '-h' || a === '--help')
|
|
@@ -100,6 +117,28 @@ function parse(args) {
|
|
|
100
117
|
out.table = name;
|
|
101
118
|
return out;
|
|
102
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Every sample id, wrapped so the help stays readable. Built from the registry
|
|
122
|
+
* rather than a hand-kept list: a new sample used to be invisible here until
|
|
123
|
+
* someone remembered to update the sentence.
|
|
124
|
+
*/
|
|
125
|
+
function templateIds(width = 62) {
|
|
126
|
+
const lines = [];
|
|
127
|
+
let line = '';
|
|
128
|
+
for (const id of sampleApps.map((s) => s.id)) {
|
|
129
|
+
const next = line ? `${line} | ${id}` : id;
|
|
130
|
+
if (next.length > width) {
|
|
131
|
+
lines.push(line);
|
|
132
|
+
line = id;
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
line = next;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (line)
|
|
139
|
+
lines.push(line);
|
|
140
|
+
return lines.join('\n ');
|
|
141
|
+
}
|
|
103
142
|
const HELP = `svgrid-studio - scaffold CRUD screens from a schema file or a live database
|
|
104
143
|
|
|
105
144
|
Usage:
|
|
@@ -126,6 +165,7 @@ Running \`svgrid-studio\` with no arguments starts it too.
|
|
|
126
165
|
--out <dir> folder to write the app into (default: .)
|
|
127
166
|
--theme <id> design-system preset --dark dark mode
|
|
128
167
|
-y, --yes take every default, ask nothing
|
|
168
|
+
-f, --force write into a folder that already holds another app
|
|
129
169
|
|
|
130
170
|
Deploy (build first, then the provider CLI; target from --target, else
|
|
131
171
|
studio.config.json, else the adapter in svelte.config.js):
|
|
@@ -133,7 +173,8 @@ studio.config.json, else the adapter in svelte.config.js):
|
|
|
133
173
|
--dry-run print the resolved commands without running anything
|
|
134
174
|
|
|
135
175
|
Designer (visual app builder, auto-saves to studio.config.json):
|
|
136
|
-
--template <id> open a ready-made sample app
|
|
176
|
+
--template <id> open a ready-made sample app:
|
|
177
|
+
${templateIds()}
|
|
137
178
|
--config <path> studio.config.json to load + auto-save (default: ./studio.config.json)
|
|
138
179
|
--out <dir> folder to write the generated app into (default: .)
|
|
139
180
|
--port <n> port to serve on (default: 4321)
|
|
@@ -255,6 +296,7 @@ async function main() {
|
|
|
255
296
|
...(opts.dark ? { dark: true } : {}),
|
|
256
297
|
...(opts.title ? { title: opts.title } : {}),
|
|
257
298
|
...(opts.yes ? { yes: true } : {}),
|
|
299
|
+
...(opts.force ? { force: true } : {}),
|
|
258
300
|
});
|
|
259
301
|
return;
|
|
260
302
|
}
|
|
@@ -494,6 +536,14 @@ async function writeCrashReport(err) {
|
|
|
494
536
|
}
|
|
495
537
|
main().catch(async (err) => {
|
|
496
538
|
process.stderr.write(`svgrid-studio: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
539
|
+
// A mistyped connection string is not a bug. Only real crashes earn a report -
|
|
540
|
+
// otherwise ordinary fat-fingering ends with "report this on GitHub", which
|
|
541
|
+
// teaches people to distrust the message and file noise.
|
|
542
|
+
if (isUserError(err)) {
|
|
543
|
+
if (err.hint)
|
|
544
|
+
process.stderr.write(` ${err.hint}\n`);
|
|
545
|
+
process.exit(1);
|
|
546
|
+
}
|
|
497
547
|
try {
|
|
498
548
|
await writeCrashReport(err);
|
|
499
549
|
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"type": "commercial",
|
|
5
5
|
"url": "https://svgrid.com/pricing"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.6.0",
|
|
8
8
|
"description": "SvGrid Studio CLI: scaffold a full CRUD screen (grid + edit panel + SvelteKit API route) from a Drizzle schema in one command.",
|
|
9
9
|
"license": "SEE LICENSE IN LICENSE",
|
|
10
10
|
"author": "jQWidgets <sales@jqwidgets.com>",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"access": "public"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@svgrid/enterprise": "^2.
|
|
30
|
+
"@svgrid/enterprise": "^2.6.1"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@types/node": "^22.10.7",
|