@datamagik/cli 0.1.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/LICENSE +21 -0
- package/assets/dm-script-globals.d.ts +181 -0
- package/dist/api.d.ts +247 -0
- package/dist/api.js +200 -0
- package/dist/api.js.map +1 -0
- package/dist/commands/add.d.ts +28 -0
- package/dist/commands/add.js +260 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/dev.d.ts +25 -0
- package/dist/commands/dev.js +113 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/init.d.ts +23 -0
- package/dist/commands/init.js +136 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +16 -0
- package/dist/commands/login.js +42 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/publish.d.ts +23 -0
- package/dist/commands/publish.js +113 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/script.d.ts +69 -0
- package/dist/commands/script.js +289 -0
- package/dist/commands/script.js.map +1 -0
- package/dist/commands/sql.d.ts +28 -0
- package/dist/commands/sql.js +124 -0
- package/dist/commands/sql.js.map +1 -0
- package/dist/commands/typegen.d.ts +13 -0
- package/dist/commands/typegen.js +50 -0
- package/dist/commands/typegen.js.map +1 -0
- package/dist/config.d.ts +45 -0
- package/dist/config.js +118 -0
- package/dist/config.js.map +1 -0
- package/dist/credentials.d.ts +17 -0
- package/dist/credentials.js +49 -0
- package/dist/credentials.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +268 -0
- package/dist/index.js.map +1 -0
- package/dist/scriptfile.d.ts +10 -0
- package/dist/scriptfile.js +91 -0
- package/dist/scriptfile.js.map +1 -0
- package/dist/sqlfile.d.ts +9 -0
- package/dist/sqlfile.js +75 -0
- package/dist/sqlfile.js.map +1 -0
- package/dist/typegen/emit.d.ts +22 -0
- package/dist/typegen/emit.js +255 -0
- package/dist/typegen/emit.js.map +1 -0
- package/dist/typegen/meta.d.ts +84 -0
- package/dist/typegen/meta.js +209 -0
- package/dist/typegen/meta.js.map +1 -0
- package/package.json +35 -0
- package/templates/showcase/README.md +55 -0
- package/templates/showcase/_gitignore +4 -0
- package/templates/showcase/dm.config.json +16 -0
- package/templates/showcase/env.d.ts +7 -0
- package/templates/showcase/index.html +12 -0
- package/templates/showcase/package.json +25 -0
- package/templates/showcase/src/App.vue +67 -0
- package/templates/showcase/src/assets/datamagik-logo.png +0 -0
- package/templates/showcase/src/components/ShowcasePanel.vue +47 -0
- package/templates/showcase/src/components/panels/ContextPanel.vue +35 -0
- package/templates/showcase/src/components/panels/NavigatePanel.vue +38 -0
- package/templates/showcase/src/components/panels/OutputPanel.vue +50 -0
- package/templates/showcase/src/components/panels/PrintPanel.vue +68 -0
- package/templates/showcase/src/components/panels/QueryPanel.vue +52 -0
- package/templates/showcase/src/components/panels/ScriptPanel.vue +55 -0
- package/templates/showcase/src/components/panels/SerialPanel.vue +64 -0
- package/templates/showcase/src/dm-script-types.d.ts +13 -0
- package/templates/showcase/src/dm.generated.ts +65 -0
- package/templates/showcase/src/format.ts +13 -0
- package/templates/showcase/src/main.ts +5 -0
- package/templates/showcase/src/style.css +134 -0
- package/templates/showcase/tsconfig.json +17 -0
- package/templates/showcase/vite.config.ts +9 -0
- package/templates/simple/README.md +37 -0
- package/templates/simple/_gitignore +4 -0
- package/templates/simple/dm.config.json +10 -0
- package/templates/simple/env.d.ts +7 -0
- package/templates/simple/index.html +12 -0
- package/templates/simple/package.json +25 -0
- package/templates/simple/src/App.vue +71 -0
- package/templates/simple/src/dm.generated.ts +32 -0
- package/templates/simple/src/main.ts +5 -0
- package/templates/simple/src/style.css +63 -0
- package/templates/simple/tsconfig.json +17 -0
- package/templates/simple/vite.config.ts +9 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { initCommand } from './commands/init.js';
|
|
4
|
+
import { addCommand } from './commands/add.js';
|
|
5
|
+
import { pullCommand, runCommand, pushCommand, commitCommand, statusCommand } from './commands/script.js';
|
|
6
|
+
import { pullSqlCommand, runSqlCommand, pushSqlCommand } from './commands/sql.js';
|
|
7
|
+
import { loginCommand } from './commands/login.js';
|
|
8
|
+
import { typegenCommand } from './commands/typegen.js';
|
|
9
|
+
import { devCommand } from './commands/dev.js';
|
|
10
|
+
import { publishCommand } from './commands/publish.js';
|
|
11
|
+
const program = new Command();
|
|
12
|
+
program
|
|
13
|
+
.name('dm')
|
|
14
|
+
.description(`DataMagik CLI — build, type, run, and ship custom Vue SPA apps for the DataMagik Application Designer.
|
|
15
|
+
|
|
16
|
+
Typical lifecycle:
|
|
17
|
+
dm init my-app scaffold a starter (simple or showcase)
|
|
18
|
+
cd my-app && npm install
|
|
19
|
+
dm login --url <platform> store a builder API key
|
|
20
|
+
dm add search the tenant and declare a resource
|
|
21
|
+
dm typegen generate typed src/dm.generated.ts
|
|
22
|
+
dm dev hot-reload dev server against live data
|
|
23
|
+
dm publish build + ship a new version (goes live)
|
|
24
|
+
|
|
25
|
+
Config & state:
|
|
26
|
+
dm.config.json your app id + declared resources (commit it)
|
|
27
|
+
src/dm.generated.ts typed alias surface (regenerated by typegen; commit it)
|
|
28
|
+
~/.config/datamagik/credentials.json stored { url, token } (0600)`)
|
|
29
|
+
.version('0.1.0')
|
|
30
|
+
.showHelpAfterError('(run `dm <command> --help` for usage)');
|
|
31
|
+
program
|
|
32
|
+
.command('init')
|
|
33
|
+
.summary('scaffold a new SPA starter project')
|
|
34
|
+
.description(`Scaffold a Vue 3 + Vite starter wired to @datamagik/app-sdk.
|
|
35
|
+
|
|
36
|
+
Templates:
|
|
37
|
+
showcase platform-styled app with a working example for every SDK area
|
|
38
|
+
(context, data query, scripts, serials, printing, navigation,
|
|
39
|
+
output events) — recommended for learning the framework.
|
|
40
|
+
simple minimal app: connect, show context, run one data query.
|
|
41
|
+
|
|
42
|
+
The generated dm.config.json uses placeholder resource ids. Set "appId" and
|
|
43
|
+
add real resources with \`dm add\`, then run \`dm typegen\`.`)
|
|
44
|
+
.argument('[dir]', 'target directory (defaults to the current directory)')
|
|
45
|
+
.option('--template <kind>', 'starter template: simple | showcase (prompts when omitted)')
|
|
46
|
+
.option('--app <id>', 'application id to write into dm.config.json')
|
|
47
|
+
.option('--force', 'scaffold into a non-empty directory')
|
|
48
|
+
.addHelpText('after', `
|
|
49
|
+
Examples:
|
|
50
|
+
dm init my-app # prompt for template, scaffold ./my-app
|
|
51
|
+
dm init my-app --template showcase # full showcase app
|
|
52
|
+
dm init . --template simple --app 12 # minimal app in the current dir, appId 12`)
|
|
53
|
+
.action(async (dir, opts) => {
|
|
54
|
+
await initCommand({ dir, ...opts });
|
|
55
|
+
});
|
|
56
|
+
program
|
|
57
|
+
.command('add')
|
|
58
|
+
.summary('search the tenant and declare a resource in dm.config.json')
|
|
59
|
+
.description(`Browse the active tenant's resources, pick one, declare it in dm.config.json
|
|
60
|
+
with a chosen alias, and regenerate src/dm.generated.ts.
|
|
61
|
+
|
|
62
|
+
Resource types: lookup_table, odbc_query, script, serial_series, printer
|
|
63
|
+
(synonyms accepted: table, odbc/sql/query, series/serial, printer).
|
|
64
|
+
|
|
65
|
+
Interactive on a TTY (prompts for type, selection, and alias). Fully scriptable
|
|
66
|
+
by passing the type and an id (or unique search term) as arguments. Requires
|
|
67
|
+
\`dm login\` first.`)
|
|
68
|
+
.argument('[type]', 'resource type (prompts when omitted)')
|
|
69
|
+
.argument('[id-or-search]', 'numeric id (selects directly) or a name search term')
|
|
70
|
+
.option('--alias <name>', 'alias to declare (derived from the resource name when omitted)')
|
|
71
|
+
.option('--no-typegen', 'do not run dm typegen after adding')
|
|
72
|
+
.option('--yes', 'assume yes / non-interactive (no prompts)')
|
|
73
|
+
.addHelpText('after', `
|
|
74
|
+
Examples:
|
|
75
|
+
dm add # fully interactive: pick type, search, alias
|
|
76
|
+
dm add lookup_table # list lookup tables, then pick one
|
|
77
|
+
dm add script receipt # search scripts matching "receipt"
|
|
78
|
+
dm add printer 11 --alias line1Zebra # declare printer #11 as line1Zebra
|
|
79
|
+
dm add odbc 7 --alias openOrders --no-typegen`)
|
|
80
|
+
.action(async (type, query, opts) => {
|
|
81
|
+
await addCommand({ type, query, alias: opts.alias, noTypegen: opts.typegen === false, yes: opts.yes });
|
|
82
|
+
});
|
|
83
|
+
const script = program
|
|
84
|
+
.command('script')
|
|
85
|
+
.summary('author script-engine scripts locally (pull / run / push / commit / status)')
|
|
86
|
+
.description(`Local-first authoring for script-engine scripts: pull a script to a .js file
|
|
87
|
+
with full frontmatter + autocomplete for the V8 sandbox globals (plex, odbc,
|
|
88
|
+
context, …), edit locally, and dry-run it against the cloud engine. Requires
|
|
89
|
+
\`dm login\`. See \`dm script <sub> --help\`.`);
|
|
90
|
+
script
|
|
91
|
+
.command('pull')
|
|
92
|
+
.summary('pull script(s) to local .js files with frontmatter + types')
|
|
93
|
+
.description(`Write each script to <dir>/<slug>.js with a @dm-script frontmatter block (its
|
|
94
|
+
full attribute set) and drop the ambient types + jsconfig so the V8 globals
|
|
95
|
+
autocomplete. Pulls all scripts unless an id is given.`)
|
|
96
|
+
.argument('[id]', 'script id to pull (pulls all when omitted)')
|
|
97
|
+
.option('--dir <dir>', 'output directory', 'scripts')
|
|
98
|
+
.addHelpText('after', `
|
|
99
|
+
Examples:
|
|
100
|
+
dm script pull # pull every script into ./scripts
|
|
101
|
+
dm script pull 1107 # pull one script
|
|
102
|
+
dm script pull --dir src/scripts`)
|
|
103
|
+
.action(async (id, opts) => {
|
|
104
|
+
await pullCommand({ id, dir: opts.dir });
|
|
105
|
+
});
|
|
106
|
+
script
|
|
107
|
+
.command('run')
|
|
108
|
+
.summary('dry-run a local script against the engine (read-only)')
|
|
109
|
+
.description(`Send a local script's code to the engine's read-only test-run with a simulated
|
|
110
|
+
context and print the console logs + output. Never saves a version. The scriptId
|
|
111
|
+
comes from the file's @dm-script frontmatter (or --id).`)
|
|
112
|
+
.argument('<file>', 'path to the local script .js file')
|
|
113
|
+
.option('--id <id>', 'script id (overrides the frontmatter scriptId)')
|
|
114
|
+
.option('--context <key=val...>', 'simulated context params (repeatable)', collect, [])
|
|
115
|
+
.addHelpText('after', `
|
|
116
|
+
Examples:
|
|
117
|
+
dm script run scripts/milton-ar-daily.js
|
|
118
|
+
dm script run scripts/milton-ar-daily.js --context order=42 --context line=L1`)
|
|
119
|
+
.action(async (file, opts) => {
|
|
120
|
+
await runCommand(file, { id: opts.id, context: opts.context });
|
|
121
|
+
});
|
|
122
|
+
script
|
|
123
|
+
.command('push')
|
|
124
|
+
.summary('save a script’s metadata to the platform (no code version)')
|
|
125
|
+
.description(`Update an existing script's attributes (name, description, tags, timeout, …)
|
|
126
|
+
from the file's frontmatter via PUT. Does NOT save code — use \`dm script commit\`
|
|
127
|
+
to deploy code as a new version. Requires a scriptId in the frontmatter.`)
|
|
128
|
+
.argument('<file>', 'path to the local script .js file')
|
|
129
|
+
.option('--id <id>', 'script id (overrides the frontmatter scriptId)')
|
|
130
|
+
.addHelpText('after', '\nExample:\n dm script push scripts/milton-ar-daily.js')
|
|
131
|
+
.action(async (file, opts) => {
|
|
132
|
+
await pushCommand(file, opts);
|
|
133
|
+
});
|
|
134
|
+
script
|
|
135
|
+
.command('commit')
|
|
136
|
+
.summary('deploy: save metadata + code as a new version (goes live)')
|
|
137
|
+
.description(`Create the script if it has no id (writing the new id back to the file), sync
|
|
138
|
+
its metadata, and save the code as a new version — the current/live version.`)
|
|
139
|
+
.argument('<file>', 'path to the local script .js file')
|
|
140
|
+
.option('--id <id>', 'script id (overrides the frontmatter scriptId)')
|
|
141
|
+
.option('-m, --message <text>', 'version notes')
|
|
142
|
+
.addHelpText('after', '\nExample:\n dm script commit scripts/milton-ar-daily.js -m "fix rounding"')
|
|
143
|
+
.action(async (file, opts) => {
|
|
144
|
+
await commitCommand(file, opts);
|
|
145
|
+
});
|
|
146
|
+
script
|
|
147
|
+
.command('status')
|
|
148
|
+
.summary('show how a local script differs from the engine')
|
|
149
|
+
.description('Compare the local file’s attributes + code against the current version on the platform.')
|
|
150
|
+
.argument('<file>', 'path to the local script .js file')
|
|
151
|
+
.option('--id <id>', 'script id (overrides the frontmatter scriptId)')
|
|
152
|
+
.action(async (file, opts) => {
|
|
153
|
+
await statusCommand(file, opts);
|
|
154
|
+
});
|
|
155
|
+
const sql = program
|
|
156
|
+
.command('sql')
|
|
157
|
+
.summary('author ODBC/SQL queries locally (pull / run / push)')
|
|
158
|
+
.description(`Local-first authoring for ODBC queries: pull a query to a .sql file with
|
|
159
|
+
@dm-sql frontmatter, dry-run it against the engine, and push changes back.
|
|
160
|
+
ODBC queries are not versioned, so push updates in place. Requires \`dm login\`.`);
|
|
161
|
+
sql
|
|
162
|
+
.command('pull')
|
|
163
|
+
.summary('pull SQL query/queries to local .sql files')
|
|
164
|
+
.description('Write each ODBC query to <dir>/<slug>.sql with @dm-sql frontmatter. Pulls all unless an id is given.')
|
|
165
|
+
.argument('[id]', 'query id to pull (pulls all when omitted)')
|
|
166
|
+
.option('--dir <dir>', 'output directory', 'sql')
|
|
167
|
+
.addHelpText('after', '\nExamples:\n dm sql pull\n dm sql pull 7 --dir src/sql')
|
|
168
|
+
.action(async (id, opts) => {
|
|
169
|
+
await pullSqlCommand({ id, dir: opts.dir });
|
|
170
|
+
});
|
|
171
|
+
sql
|
|
172
|
+
.command('run')
|
|
173
|
+
.summary('dry-run a local SQL query against the engine (read-only)')
|
|
174
|
+
.description('Send the local SQL to the engine’s read-only test-run and print rows. Uses the frontmatter credentialId (or --credential-id).')
|
|
175
|
+
.argument('<file>', 'path to the local .sql file')
|
|
176
|
+
.option('--id <id>', 'query id (overrides the frontmatter queryId)')
|
|
177
|
+
.option('--credential-id <id>', 'ODBC credential id (overrides the frontmatter credentialId)')
|
|
178
|
+
.option('--param <key=val...>', 'query parameters (repeatable)', collect, [])
|
|
179
|
+
.addHelpText('after', '\nExample:\n dm sql run sql/open-orders.sql --param status=OPEN')
|
|
180
|
+
.action(async (file, opts) => {
|
|
181
|
+
await runSqlCommand(file, { id: opts.id, credentialId: opts.credentialId, param: opts.param });
|
|
182
|
+
});
|
|
183
|
+
sql
|
|
184
|
+
.command('push')
|
|
185
|
+
.summary('create or update a SQL query in place')
|
|
186
|
+
.description('Save the local .sql file’s frontmatter + text to the platform (creates if no queryId, else updates). ODBC queries are not versioned.')
|
|
187
|
+
.argument('<file>', 'path to the local .sql file')
|
|
188
|
+
.option('--id <id>', 'query id (overrides the frontmatter queryId)')
|
|
189
|
+
.addHelpText('after', '\nExample:\n dm sql push sql/open-orders.sql')
|
|
190
|
+
.action(async (file, opts) => {
|
|
191
|
+
await pushSqlCommand(file, opts);
|
|
192
|
+
});
|
|
193
|
+
program
|
|
194
|
+
.command('login')
|
|
195
|
+
.summary('store platform credentials')
|
|
196
|
+
.description(`Store { url, token } in ~/.config/datamagik/credentials.json (mode 0600).
|
|
197
|
+
|
|
198
|
+
Create an API key in the platform UI (Settings → API Keys) and paste it when
|
|
199
|
+
prompted, or pass it with --token. The url is remembered and used by add,
|
|
200
|
+
typegen, dev, and publish.`)
|
|
201
|
+
.option('--url <platform>', 'platform base URL', 'https://data-magik.com')
|
|
202
|
+
.option('--token <token>', 'API key (dcp_...) created in the platform UI (prompted when omitted)')
|
|
203
|
+
.addHelpText('after', `
|
|
204
|
+
Examples:
|
|
205
|
+
dm login --url https://staging.data-magik.com
|
|
206
|
+
dm login --url https://data-magik.com --token dcp_xxxxxxxx`)
|
|
207
|
+
.action(async (opts) => {
|
|
208
|
+
await loginCommand(opts);
|
|
209
|
+
});
|
|
210
|
+
program
|
|
211
|
+
.command('typegen')
|
|
212
|
+
.summary('generate the typed dm.generated.ts module')
|
|
213
|
+
.description(`Read dm.config.json, fetch metadata for every declared resource from the
|
|
214
|
+
platform, and emit the typed module src/dm.generated.ts (deterministic — commit
|
|
215
|
+
it). Re-run after changing dm.config.json (or use --watch). Requires \`dm login\`.`)
|
|
216
|
+
.option('--watch', 're-generate when dm.config.json changes')
|
|
217
|
+
.option('--out <file>', 'output file', 'src/dm.generated.ts')
|
|
218
|
+
.addHelpText('after', `
|
|
219
|
+
Examples:
|
|
220
|
+
dm typegen
|
|
221
|
+
dm typegen --watch
|
|
222
|
+
dm typegen --out src/types/dm.generated.ts`)
|
|
223
|
+
.action(async (opts) => {
|
|
224
|
+
await typegenCommand(opts);
|
|
225
|
+
});
|
|
226
|
+
program
|
|
227
|
+
.command('dev')
|
|
228
|
+
.summary('run the dev server against live platform data')
|
|
229
|
+
.description(`Start the project's Vite dev server with the DataMagik auth proxy and a
|
|
230
|
+
simulated host context. /api/* calls are proxied to the platform with your
|
|
231
|
+
builder bearer; --context flags become context.params. Prints an in-platform
|
|
232
|
+
dev URL you open to test inside the real shell. Requires \`dm login\`.`)
|
|
233
|
+
.option('--app <id>', 'app id (defaults to dm.config.json appId)')
|
|
234
|
+
.option('--port <port>', 'dev server port', '5173')
|
|
235
|
+
.option('--context <key=val...>', 'simulated context params (repeatable)', collect, [])
|
|
236
|
+
.addHelpText('after', `
|
|
237
|
+
Examples:
|
|
238
|
+
dm dev
|
|
239
|
+
dm dev --app 12 --port 5174
|
|
240
|
+
dm dev --context order=42 --context line=L1`)
|
|
241
|
+
.action(async (opts) => {
|
|
242
|
+
await devCommand(opts);
|
|
243
|
+
});
|
|
244
|
+
program
|
|
245
|
+
.command('publish')
|
|
246
|
+
.summary('build and ship a new version (goes live)')
|
|
247
|
+
.description(`Run vite build, zip dist/, and publish a new SPA version to the platform.
|
|
248
|
+
The new version goes live immediately. Use --skip-build to publish an existing
|
|
249
|
+
dist/ as-is. Requires \`dm login\`.`)
|
|
250
|
+
.option('--app <id>', 'app id (defaults to dm.config.json appId)')
|
|
251
|
+
.option('--message <text>', 'change description for the new version')
|
|
252
|
+
.option('--skip-build', 'skip vite build and publish the existing dist/')
|
|
253
|
+
.addHelpText('after', `
|
|
254
|
+
Examples:
|
|
255
|
+
dm publish --message "first version"
|
|
256
|
+
dm publish --app 12 --message "fix label layout"
|
|
257
|
+
dm publish --skip-build --message "re-publish current dist"`)
|
|
258
|
+
.action(async (opts) => {
|
|
259
|
+
await publishCommand(opts);
|
|
260
|
+
});
|
|
261
|
+
function collect(value, previous) {
|
|
262
|
+
return [...previous, value];
|
|
263
|
+
}
|
|
264
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
265
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
266
|
+
process.exit(1);
|
|
267
|
+
});
|
|
268
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type MetaValue = string | number | boolean | string[];
|
|
2
|
+
export type ScriptMeta = Record<string, MetaValue>;
|
|
3
|
+
export interface ScriptFile {
|
|
4
|
+
meta: ScriptMeta;
|
|
5
|
+
code: string;
|
|
6
|
+
}
|
|
7
|
+
/** Parses a `@dm-script` file into `{ meta, code }`. Missing block → empty meta. */
|
|
8
|
+
export declare function parseScriptFile(text: string): ScriptFile;
|
|
9
|
+
/** Serializes `{ meta, code }` back into a `@dm-script` file. */
|
|
10
|
+
export declare function serializeScriptFile(meta: ScriptMeta, code: string): string;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Parse/serialize the single-file frontmatter that carries a script's full
|
|
2
|
+
// attribute set (see docs/design/script-engine-local-dev.md). A script file is
|
|
3
|
+
// a `/* @dm-script ... */` block (key: value lines) followed by the code body.
|
|
4
|
+
const MARKER = '@dm-script';
|
|
5
|
+
// Stable emit order; only keys that are present are written.
|
|
6
|
+
const FIELD_ORDER = [
|
|
7
|
+
'name', 'description', 'category', 'tags', 'active', 'timeoutSeconds',
|
|
8
|
+
'maxMemoryMB', 'priority', 'isReportGenerator', 'reportType',
|
|
9
|
+
'generateDocuments', 'outputFormat', 'titleJsonPath', 'summaryJsonPath',
|
|
10
|
+
'waitForGeneration', 'credentials', 'allowedDomains', 'schedule', 'scriptId',
|
|
11
|
+
];
|
|
12
|
+
const SAFE_BARE = /^[A-Za-z0-9_$./\-*]+$/;
|
|
13
|
+
function parseValue(raw) {
|
|
14
|
+
const v = raw.trim();
|
|
15
|
+
if (v.startsWith('[') && v.endsWith(']')) {
|
|
16
|
+
const inner = v.slice(1, -1).trim();
|
|
17
|
+
if (inner === '')
|
|
18
|
+
return [];
|
|
19
|
+
return inner.split(',').map((s) => unquote(s.trim()));
|
|
20
|
+
}
|
|
21
|
+
if (v === 'true')
|
|
22
|
+
return true;
|
|
23
|
+
if (v === 'false')
|
|
24
|
+
return false;
|
|
25
|
+
if (/^-?\d+$/.test(v))
|
|
26
|
+
return Number(v);
|
|
27
|
+
return unquote(v);
|
|
28
|
+
}
|
|
29
|
+
function unquote(s) {
|
|
30
|
+
if (s.startsWith('"')) {
|
|
31
|
+
try {
|
|
32
|
+
return JSON.parse(s);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return s.slice(1, -1);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return s;
|
|
39
|
+
}
|
|
40
|
+
function serializeScalar(v) {
|
|
41
|
+
if (typeof v === 'string')
|
|
42
|
+
return SAFE_BARE.test(v) ? v : JSON.stringify(v);
|
|
43
|
+
return String(v);
|
|
44
|
+
}
|
|
45
|
+
function serializeValue(v) {
|
|
46
|
+
if (Array.isArray(v))
|
|
47
|
+
return `[${v.map((s) => serializeScalar(s)).join(', ')}]`;
|
|
48
|
+
return serializeScalar(v);
|
|
49
|
+
}
|
|
50
|
+
/** Parses a `@dm-script` file into `{ meta, code }`. Missing block → empty meta. */
|
|
51
|
+
export function parseScriptFile(text) {
|
|
52
|
+
const start = text.indexOf(`/* ${MARKER}`);
|
|
53
|
+
if (start === -1)
|
|
54
|
+
return { meta: {}, code: text };
|
|
55
|
+
const end = text.indexOf('*/', start);
|
|
56
|
+
if (end === -1)
|
|
57
|
+
return { meta: {}, code: text };
|
|
58
|
+
const block = text.slice(start + `/* ${MARKER}`.length, end);
|
|
59
|
+
const meta = {};
|
|
60
|
+
for (const line of block.split('\n')) {
|
|
61
|
+
const trimmed = line.trim();
|
|
62
|
+
if (trimmed === '' || trimmed.startsWith('#'))
|
|
63
|
+
continue;
|
|
64
|
+
const colon = trimmed.indexOf(':');
|
|
65
|
+
if (colon === -1)
|
|
66
|
+
continue;
|
|
67
|
+
const key = trimmed.slice(0, colon).trim();
|
|
68
|
+
let value = trimmed.slice(colon + 1).trim();
|
|
69
|
+
// Strip a trailing `# comment`, but never inside a quoted string.
|
|
70
|
+
if (!value.startsWith('"'))
|
|
71
|
+
value = value.replace(/\s+#.*$/, '');
|
|
72
|
+
if (key)
|
|
73
|
+
meta[key] = parseValue(value);
|
|
74
|
+
}
|
|
75
|
+
// Code is everything after the closing `*/` (drop the immediate newline).
|
|
76
|
+
const code = text.slice(end + 2).replace(/^\r?\n/, '');
|
|
77
|
+
return { meta, code };
|
|
78
|
+
}
|
|
79
|
+
/** Serializes `{ meta, code }` back into a `@dm-script` file. */
|
|
80
|
+
export function serializeScriptFile(meta, code) {
|
|
81
|
+
const keys = [
|
|
82
|
+
...FIELD_ORDER.filter((k) => k in meta),
|
|
83
|
+
...Object.keys(meta).filter((k) => !FIELD_ORDER.includes(k)),
|
|
84
|
+
];
|
|
85
|
+
const lines = [`/* ${MARKER}`];
|
|
86
|
+
for (const k of keys)
|
|
87
|
+
lines.push(` ${k}: ${serializeValue(meta[k])}`);
|
|
88
|
+
lines.push('*/');
|
|
89
|
+
return `${lines.join('\n')}\n${code.replace(/^\r?\n/, '')}`;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=scriptfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scriptfile.js","sourceRoot":"","sources":["../src/scriptfile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export type SqlMeta = Record<string, unknown>;
|
|
2
|
+
export interface SqlFile {
|
|
3
|
+
meta: SqlMeta;
|
|
4
|
+
sql: string;
|
|
5
|
+
}
|
|
6
|
+
/** Parses a `@dm-sql` file into `{ meta, sql }`. No frontmatter → all SQL. */
|
|
7
|
+
export declare function parseSqlFile(text: string): SqlFile;
|
|
8
|
+
/** Serializes `{ meta, sql }` back into a `@dm-sql` file. */
|
|
9
|
+
export declare function serializeSqlFile(meta: SqlMeta, sql: string): string;
|
package/dist/sqlfile.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// Parse/serialize the `@dm-sql` frontmatter for ODBC/SQL queries: a leading
|
|
2
|
+
// block of `-- key: value` line comments followed by the raw SQL body. Values
|
|
3
|
+
// may be JSON (arrays/objects) — used for the `parameters` list.
|
|
4
|
+
const MARKER = '-- @dm-sql';
|
|
5
|
+
const FIELD_ORDER = ['name', 'description', 'timeoutSeconds', 'credential', 'credentialId', 'parameters', 'queryId'];
|
|
6
|
+
const SAFE_BARE = /^[A-Za-z0-9_$./\-*]+$/;
|
|
7
|
+
function parseValue(raw) {
|
|
8
|
+
const v = raw.trim();
|
|
9
|
+
if (v.startsWith('[') || v.startsWith('{')) {
|
|
10
|
+
try {
|
|
11
|
+
return JSON.parse(v);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return v;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (v === 'true')
|
|
18
|
+
return true;
|
|
19
|
+
if (v === 'false')
|
|
20
|
+
return false;
|
|
21
|
+
if (/^-?\d+$/.test(v))
|
|
22
|
+
return Number(v);
|
|
23
|
+
if (v.startsWith('"')) {
|
|
24
|
+
try {
|
|
25
|
+
return JSON.parse(v);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return v.slice(1, -1);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return v;
|
|
32
|
+
}
|
|
33
|
+
function serializeValue(v) {
|
|
34
|
+
if (v === null)
|
|
35
|
+
return 'null';
|
|
36
|
+
if (typeof v === 'object')
|
|
37
|
+
return JSON.stringify(v);
|
|
38
|
+
if (typeof v === 'string')
|
|
39
|
+
return SAFE_BARE.test(v) ? v : JSON.stringify(v);
|
|
40
|
+
return String(v);
|
|
41
|
+
}
|
|
42
|
+
/** Parses a `@dm-sql` file into `{ meta, sql }`. No frontmatter → all SQL. */
|
|
43
|
+
export function parseSqlFile(text) {
|
|
44
|
+
const lines = text.split('\n');
|
|
45
|
+
if (lines[0]?.trim() !== MARKER)
|
|
46
|
+
return { meta: {}, sql: text };
|
|
47
|
+
const meta = {};
|
|
48
|
+
let i = 1;
|
|
49
|
+
for (; i < lines.length; i++) {
|
|
50
|
+
const line = lines[i] ?? '';
|
|
51
|
+
if (!line.trimStart().startsWith('--'))
|
|
52
|
+
break;
|
|
53
|
+
const body = line.trimStart().replace(/^--\s?/, '');
|
|
54
|
+
const colon = body.indexOf(':');
|
|
55
|
+
if (colon === -1)
|
|
56
|
+
continue;
|
|
57
|
+
const key = body.slice(0, colon).trim();
|
|
58
|
+
const value = body.slice(colon + 1).trim();
|
|
59
|
+
if (key)
|
|
60
|
+
meta[key] = parseValue(value);
|
|
61
|
+
}
|
|
62
|
+
return { meta, sql: lines.slice(i).join('\n').replace(/^\r?\n/, '') };
|
|
63
|
+
}
|
|
64
|
+
/** Serializes `{ meta, sql }` back into a `@dm-sql` file. */
|
|
65
|
+
export function serializeSqlFile(meta, sql) {
|
|
66
|
+
const keys = [
|
|
67
|
+
...FIELD_ORDER.filter((k) => k in meta),
|
|
68
|
+
...Object.keys(meta).filter((k) => !FIELD_ORDER.includes(k)),
|
|
69
|
+
];
|
|
70
|
+
const lines = [MARKER];
|
|
71
|
+
for (const k of keys)
|
|
72
|
+
lines.push(`-- ${k}: ${serializeValue(meta[k])}`);
|
|
73
|
+
return `${lines.join('\n')}\n${sql.replace(/^\r?\n/, '')}`;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=sqlfile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlfile.js","sourceRoot":"","sources":["../src/sqlfile.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,8EAA8E;AAC9E,iEAAiE;AASjE,MAAM,MAAM,GAAG,YAAY,CAAC;AAC5B,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;AACrH,MAAM,SAAS,GAAG,uBAAuB,CAAC;AAE1C,SAAS,UAAU,CAAC,GAAW;IAC7B,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACrB,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IACD,IAAI,CAAC,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAC9B,IAAI,CAAC,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACxC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAW,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,cAAc,CAAC,CAAU;IAChC,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAC9B,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACpD,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC5E,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;AACnB,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,MAAM;QAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IAEhE,MAAM,IAAI,GAAY,EAAE,CAAC;IACzB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,MAAM;QAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,SAAS;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3C,IAAI,GAAG;YAAE,IAAI,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC;AACxE,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,gBAAgB,CAAC,IAAa,EAAE,GAAW;IACzD,MAAM,IAAI,GAAG;QACX,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC;QACvC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;KAC7D,CAAC;IACF,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC;IACvB,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxE,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC;AAC7D,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { TypegenMeta } from './meta.js';
|
|
2
|
+
/**
|
|
3
|
+
* Emits the `dm.generated.ts` module from fetched metadata.
|
|
4
|
+
*
|
|
5
|
+
* Deterministic: aliases are sorted within each category, the output carries
|
|
6
|
+
* no timestamps, and identical inputs always produce byte-identical output —
|
|
7
|
+
* the file is meant to be committed.
|
|
8
|
+
*/
|
|
9
|
+
export declare function emitGeneratedModule(meta: TypegenMeta): string;
|
|
10
|
+
/** `parts` → `PartsRow`-style Pascal case. */
|
|
11
|
+
export declare function pascal(alias: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Maps a lookup-table `value_schema` field type to TypeScript
|
|
14
|
+
* (design §8.1): text→string, number→number, date→string (ISO 8601),
|
|
15
|
+
* boolean→boolean, picture→DmImageRef, lookup_table→number (FK).
|
|
16
|
+
*/
|
|
17
|
+
export declare function lookupFieldType(type: string): {
|
|
18
|
+
ts: string;
|
|
19
|
+
note?: string;
|
|
20
|
+
};
|
|
21
|
+
/** Maps an ODBC parameter type to TypeScript: string|int|float|bool. */
|
|
22
|
+
export declare function odbcParamType(type: string): string;
|