@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
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type PlatformListClient } from '../api.js';
|
|
2
|
+
/** The resource kinds `dm add` can declare. */
|
|
3
|
+
export type ResourceType = 'lookup_table' | 'odbc_query' | 'script' | 'serial_series' | 'printer';
|
|
4
|
+
export interface AddOptions {
|
|
5
|
+
/** Resource type (positional). Prompts when omitted on a TTY. */
|
|
6
|
+
type?: string;
|
|
7
|
+
/** Numeric id (selects directly) or a search term (filters the list). */
|
|
8
|
+
query?: string;
|
|
9
|
+
/** Alias to declare; derived from the resource name when omitted. */
|
|
10
|
+
alias?: string;
|
|
11
|
+
/** Skip the post-add `dm typegen`. */
|
|
12
|
+
noTypegen?: boolean;
|
|
13
|
+
/** Assume "yes" for prompts (non-interactive). */
|
|
14
|
+
yes?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/** `Open Orders` → `openOrders`; falls back to `resource` when empty. */
|
|
17
|
+
export declare function toAlias(name: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* `dm add [type] [id|search] [--alias <a>] [--no-typegen]`
|
|
20
|
+
*
|
|
21
|
+
* Browses the active tenant's resources, lets you pick one, declares it in
|
|
22
|
+
* dm.config.json with a chosen alias, and re-runs `dm typegen`. Interactive
|
|
23
|
+
* when run on a TTY; fully scriptable via positional args and `--yes`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function addCommand(opts: AddOptions, deps?: {
|
|
26
|
+
client?: PlatformListClient;
|
|
27
|
+
cwd?: string;
|
|
28
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline/promises';
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { requireCredentials } from '../credentials.js';
|
|
5
|
+
import { PlatformClient } from '../api.js';
|
|
6
|
+
import { ALIAS_RE } from '../config.js';
|
|
7
|
+
import { typegenCommand } from './typegen.js';
|
|
8
|
+
const num = (v) => (typeof v === 'number' ? v : Number(v));
|
|
9
|
+
const KINDS = {
|
|
10
|
+
lookup_table: {
|
|
11
|
+
type: 'lookup_table',
|
|
12
|
+
label: 'Lookup table',
|
|
13
|
+
configArray: 'sources',
|
|
14
|
+
idKey: 'sourceId',
|
|
15
|
+
async fetch(c) {
|
|
16
|
+
return (await c.listLookupTables()).map((t) => ({ id: t.lookup_table_id, name: t.table_name, description: t.description ?? undefined }));
|
|
17
|
+
},
|
|
18
|
+
decl: (id, alias) => ({ sourceId: id, type: 'lookup_table', alias }),
|
|
19
|
+
},
|
|
20
|
+
odbc_query: {
|
|
21
|
+
type: 'odbc_query',
|
|
22
|
+
label: 'ODBC query',
|
|
23
|
+
configArray: 'sources',
|
|
24
|
+
idKey: 'sourceId',
|
|
25
|
+
async fetch(c) {
|
|
26
|
+
return (await c.listOdbcQueries()).map((q) => ({ id: num(q.query_id), name: q.query_name, description: q.description ?? undefined }));
|
|
27
|
+
},
|
|
28
|
+
decl: (id, alias) => ({ sourceId: id, type: 'odbc_query', alias }),
|
|
29
|
+
},
|
|
30
|
+
script: {
|
|
31
|
+
type: 'script',
|
|
32
|
+
label: 'Script',
|
|
33
|
+
configArray: 'sources',
|
|
34
|
+
idKey: 'sourceId',
|
|
35
|
+
async fetch(c) {
|
|
36
|
+
return (await c.listScripts()).map((s) => ({ id: s.script_id, name: s.script_name, description: s.description ?? undefined }));
|
|
37
|
+
},
|
|
38
|
+
decl: (id, alias) => ({ sourceId: id, type: 'script', alias }),
|
|
39
|
+
},
|
|
40
|
+
serial_series: {
|
|
41
|
+
type: 'serial_series',
|
|
42
|
+
label: 'Serial series',
|
|
43
|
+
configArray: 'serialSeries',
|
|
44
|
+
idKey: 'seriesId',
|
|
45
|
+
async fetch(c) {
|
|
46
|
+
return (await c.listSeries()).map((s) => ({ id: num(s.seriesId), name: s.name }));
|
|
47
|
+
},
|
|
48
|
+
decl: (id, alias) => ({ seriesId: id, alias }),
|
|
49
|
+
},
|
|
50
|
+
printer: {
|
|
51
|
+
type: 'printer',
|
|
52
|
+
label: 'Printer',
|
|
53
|
+
configArray: 'printers',
|
|
54
|
+
idKey: 'printerId',
|
|
55
|
+
async fetch(c) {
|
|
56
|
+
return (await c.listPrinters()).map((p) => ({ id: num(p.printerId), name: p.name, description: p.type }));
|
|
57
|
+
},
|
|
58
|
+
decl: (id, alias) => ({ printerId: id, alias }),
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
/** Accepts the canonical type or a friendly synonym. */
|
|
62
|
+
const TYPE_SYNONYMS = {
|
|
63
|
+
lookup_table: 'lookup_table', lookup: 'lookup_table', table: 'lookup_table',
|
|
64
|
+
odbc_query: 'odbc_query', odbc: 'odbc_query', query: 'odbc_query', sql: 'odbc_query',
|
|
65
|
+
script: 'script',
|
|
66
|
+
serial_series: 'serial_series', serial: 'serial_series', series: 'serial_series',
|
|
67
|
+
printer: 'printer', printers: 'printer',
|
|
68
|
+
};
|
|
69
|
+
/** `Open Orders` → `openOrders`; falls back to `resource` when empty. */
|
|
70
|
+
export function toAlias(name) {
|
|
71
|
+
const words = name.replace(/[^A-Za-z0-9]+/g, ' ').trim().split(/\s+/).filter(Boolean);
|
|
72
|
+
if (words.length === 0)
|
|
73
|
+
return 'resource';
|
|
74
|
+
const camel = words
|
|
75
|
+
.map((w, i) => (i === 0 ? w.toLowerCase() : w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()))
|
|
76
|
+
.join('');
|
|
77
|
+
return /^[0-9]/.test(camel) ? `r${camel}` : camel;
|
|
78
|
+
}
|
|
79
|
+
function resolveType(raw) {
|
|
80
|
+
const key = raw.trim().toLowerCase();
|
|
81
|
+
const t = TYPE_SYNONYMS[key];
|
|
82
|
+
if (!t) {
|
|
83
|
+
throw new Error(`Unknown resource type "${raw}". Use one of: lookup_table, odbc_query, script, serial_series, printer.`);
|
|
84
|
+
}
|
|
85
|
+
return t;
|
|
86
|
+
}
|
|
87
|
+
async function promptType(rl) {
|
|
88
|
+
const order = ['lookup_table', 'odbc_query', 'script', 'serial_series', 'printer'];
|
|
89
|
+
console.log('What kind of resource do you want to add?');
|
|
90
|
+
order.forEach((t, i) => console.log(` ${i + 1}) ${KINDS[t].label}`));
|
|
91
|
+
const ans = (await rl.question('Choose [1]: ')).trim().toLowerCase();
|
|
92
|
+
if (ans === '')
|
|
93
|
+
return 'lookup_table';
|
|
94
|
+
const n = Number(ans);
|
|
95
|
+
if (Number.isInteger(n) && n >= 1 && n <= order.length)
|
|
96
|
+
return order[n - 1];
|
|
97
|
+
return resolveType(ans);
|
|
98
|
+
}
|
|
99
|
+
function readRawConfig(dir) {
|
|
100
|
+
const file = path.join(dir, 'dm.config.json');
|
|
101
|
+
if (!existsSync(file)) {
|
|
102
|
+
throw new Error(`No dm.config.json in ${dir}. Run \`dm init\` first, or create one.`);
|
|
103
|
+
}
|
|
104
|
+
let obj;
|
|
105
|
+
try {
|
|
106
|
+
obj = JSON.parse(readFileSync(file, 'utf8'));
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
throw new Error(`dm.config.json is not valid JSON: ${String(err)}`);
|
|
110
|
+
}
|
|
111
|
+
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {
|
|
112
|
+
throw new Error('dm.config.json must be a JSON object');
|
|
113
|
+
}
|
|
114
|
+
return { file, obj: obj };
|
|
115
|
+
}
|
|
116
|
+
/** Every alias already declared, across all categories (they share a registry). */
|
|
117
|
+
function existingAliases(obj) {
|
|
118
|
+
const out = new Set();
|
|
119
|
+
for (const key of ['sources', 'serialSeries', 'printers']) {
|
|
120
|
+
const arr = obj[key];
|
|
121
|
+
if (!Array.isArray(arr))
|
|
122
|
+
continue;
|
|
123
|
+
for (const d of arr) {
|
|
124
|
+
const alias = d?.['alias'];
|
|
125
|
+
if (typeof alias === 'string')
|
|
126
|
+
out.add(alias);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
function filterRows(rows, term) {
|
|
132
|
+
if (!term)
|
|
133
|
+
return rows;
|
|
134
|
+
const t = term.toLowerCase();
|
|
135
|
+
return rows.filter((r) => r.name.toLowerCase().includes(t) || String(r.id) === term);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* `dm add [type] [id|search] [--alias <a>] [--no-typegen]`
|
|
139
|
+
*
|
|
140
|
+
* Browses the active tenant's resources, lets you pick one, declares it in
|
|
141
|
+
* dm.config.json with a chosen alias, and re-runs `dm typegen`. Interactive
|
|
142
|
+
* when run on a TTY; fully scriptable via positional args and `--yes`.
|
|
143
|
+
*/
|
|
144
|
+
export async function addCommand(opts, deps = {}) {
|
|
145
|
+
const cwd = deps.cwd ?? process.cwd();
|
|
146
|
+
const { file, obj } = readRawConfig(cwd);
|
|
147
|
+
const creds = requireCredentials();
|
|
148
|
+
const client = deps.client ?? new PlatformClient(creds.url, creds.token);
|
|
149
|
+
const tty = !!process.stdin.isTTY && !opts.yes;
|
|
150
|
+
const rl = tty ? createInterface({ input: process.stdin, output: process.stdout }) : null;
|
|
151
|
+
try {
|
|
152
|
+
let type;
|
|
153
|
+
if (opts.type)
|
|
154
|
+
type = resolveType(opts.type);
|
|
155
|
+
else if (rl)
|
|
156
|
+
type = await promptType(rl);
|
|
157
|
+
else
|
|
158
|
+
throw new Error('Resource type required in non-interactive mode (e.g. `dm add lookup_table 17`).');
|
|
159
|
+
const kind = KINDS[type];
|
|
160
|
+
const rows = await kind.fetch(client);
|
|
161
|
+
if (rows.length === 0) {
|
|
162
|
+
console.log(`No ${kind.label.toLowerCase()}s found in this tenant (${creds.url}).`);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
// Direct id match short-circuits selection.
|
|
166
|
+
let chosen;
|
|
167
|
+
if (opts.query !== undefined && /^[0-9]+$/.test(opts.query.trim())) {
|
|
168
|
+
chosen = rows.find((r) => r.id === Number(opts.query));
|
|
169
|
+
if (!chosen)
|
|
170
|
+
throw new Error(`No ${kind.label.toLowerCase()} with id ${opts.query} in this tenant.`);
|
|
171
|
+
}
|
|
172
|
+
if (!chosen) {
|
|
173
|
+
let candidates = filterRows(rows, opts.query);
|
|
174
|
+
if (candidates.length === 0) {
|
|
175
|
+
console.log(`No ${kind.label.toLowerCase()} matches "${opts.query}".`);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (candidates.length === 1) {
|
|
179
|
+
chosen = candidates[0];
|
|
180
|
+
}
|
|
181
|
+
else if (rl) {
|
|
182
|
+
// Optional interactive search to narrow a long list.
|
|
183
|
+
if (opts.query === undefined && candidates.length > 12) {
|
|
184
|
+
const term = (await rl.question(`Search ${kind.label.toLowerCase()}s (blank = list all): `)).trim();
|
|
185
|
+
if (term)
|
|
186
|
+
candidates = filterRows(rows, term);
|
|
187
|
+
}
|
|
188
|
+
console.log(`\n${kind.label}s (${creds.url}):`);
|
|
189
|
+
candidates.slice(0, 50).forEach((r, i) => {
|
|
190
|
+
const desc = r.description ? ` — ${r.description}` : '';
|
|
191
|
+
console.log(` ${String(i + 1).padStart(2)}) [#${r.id}] ${r.name}${desc}`);
|
|
192
|
+
});
|
|
193
|
+
if (candidates.length > 50)
|
|
194
|
+
console.log(` … and ${candidates.length - 50} more (refine with a search term)`);
|
|
195
|
+
const pick = Number((await rl.question('Select #: ')).trim());
|
|
196
|
+
if (!Number.isInteger(pick) || pick < 1 || pick > Math.min(candidates.length, 50)) {
|
|
197
|
+
throw new Error('No valid selection made.');
|
|
198
|
+
}
|
|
199
|
+
chosen = candidates[pick - 1];
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
throw new Error(`"${opts.query ?? ''}" matched ${candidates.length} ${kind.label.toLowerCase()}s; pass an id or a unique search term.`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const selected = chosen;
|
|
206
|
+
// Resolve the alias (suggest from name; ensure uniqueness). An explicit
|
|
207
|
+
// blank --alias falls back to the derived name, same as omitting it.
|
|
208
|
+
const taken = existingAliases(obj);
|
|
209
|
+
let alias = opts.alias?.trim() || toAlias(selected.name);
|
|
210
|
+
if (rl && !opts.alias) {
|
|
211
|
+
const ans = (await rl.question(`Alias [${alias}]: `)).trim();
|
|
212
|
+
if (ans)
|
|
213
|
+
alias = ans;
|
|
214
|
+
}
|
|
215
|
+
if (!ALIAS_RE.test(alias)) {
|
|
216
|
+
throw new Error(`Alias "${alias}" is not a valid identifier (letters, digits, _, $; not starting with a digit).`);
|
|
217
|
+
}
|
|
218
|
+
if (taken.has(alias)) {
|
|
219
|
+
throw new Error(`Alias "${alias}" is already declared in dm.config.json (aliases are unique across all resources).`);
|
|
220
|
+
}
|
|
221
|
+
// Locate the target array, guarding hand-edited / malformed config.
|
|
222
|
+
const current = obj[kind.configArray];
|
|
223
|
+
if (kind.type === 'printer' && current === 'all') {
|
|
224
|
+
console.log('printers is set to "all" — every printer is already available. Nothing to add.');
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (current !== undefined && !Array.isArray(current)) {
|
|
228
|
+
throw new Error(`dm.config.json: "${kind.configArray}" must be an array; refusing to overwrite it.`);
|
|
229
|
+
}
|
|
230
|
+
const arr = Array.isArray(current) ? current : [];
|
|
231
|
+
if (arr.some((d) => Number(d?.[kind.idKey]) === selected.id)) {
|
|
232
|
+
console.log(`[#${selected.id}] ${selected.name} is already declared. Nothing to add.`);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
arr.push(kind.decl(selected.id, alias));
|
|
236
|
+
obj[kind.configArray] = arr;
|
|
237
|
+
writeFileSync(file, JSON.stringify(obj, null, 2) + '\n');
|
|
238
|
+
console.log(`Added ${kind.label.toLowerCase()} [#${selected.id}] "${selected.name}" as alias \`${alias}\` to dm.config.json.`);
|
|
239
|
+
// Regenerate types so the new alias is immediately usable.
|
|
240
|
+
if (!opts.noTypegen) {
|
|
241
|
+
let run = true;
|
|
242
|
+
if (rl) {
|
|
243
|
+
const ans = (await rl.question('Run `dm typegen` now to update src/dm.generated.ts? [Y/n]: ')).trim().toLowerCase();
|
|
244
|
+
run = ans === '' || ans === 'y' || ans === 'yes';
|
|
245
|
+
}
|
|
246
|
+
if (run) {
|
|
247
|
+
rl?.close();
|
|
248
|
+
await typegenCommand({});
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
console.log('Run `dm typegen` to regenerate src/dm.generated.ts.');
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
finally {
|
|
257
|
+
rl?.close();
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface DevOptions {
|
|
2
|
+
app?: string;
|
|
3
|
+
context?: string[];
|
|
4
|
+
port?: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* `dm dev [--app <id>] [--context key=val ...]`
|
|
8
|
+
*
|
|
9
|
+
* Runs the user project's Vite dev server (via the Vite JS API) with an
|
|
10
|
+
* injected plugin that:
|
|
11
|
+
* - proxies `/api/*` to the platform URL, adding the builder bearer;
|
|
12
|
+
* - serves `GET /__dm/context` with a simulated `dm-context-init` payload
|
|
13
|
+
* (`surface: 'dev'`, `--context key=val` flags become `context.params`);
|
|
14
|
+
* - forces `base: './'` so built asset URLs stay relative (token-path serving).
|
|
15
|
+
*
|
|
16
|
+
* Also prints the in-platform dev URL
|
|
17
|
+
* `<url>/datamagik/app-designer/<id>/view?dev_server=http://localhost:5173`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function devCommand(opts: DevOptions): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* The injected Vite plugin: serves the simulated context and pins `base`.
|
|
22
|
+
* Defined as a plain object so it works with whatever Vite major the user
|
|
23
|
+
* project has installed (the plugin API surface used here is stable).
|
|
24
|
+
*/
|
|
25
|
+
export declare function dmDevPlugin(contextInit: unknown): Record<string, unknown>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { pathToFileURL } from 'node:url';
|
|
3
|
+
import { loadDmConfig } from '../config.js';
|
|
4
|
+
import { requireCredentials } from '../credentials.js';
|
|
5
|
+
import { typegenCommand } from './typegen.js';
|
|
6
|
+
/**
|
|
7
|
+
* `dm dev [--app <id>] [--context key=val ...]`
|
|
8
|
+
*
|
|
9
|
+
* Runs the user project's Vite dev server (via the Vite JS API) with an
|
|
10
|
+
* injected plugin that:
|
|
11
|
+
* - proxies `/api/*` to the platform URL, adding the builder bearer;
|
|
12
|
+
* - serves `GET /__dm/context` with a simulated `dm-context-init` payload
|
|
13
|
+
* (`surface: 'dev'`, `--context key=val` flags become `context.params`);
|
|
14
|
+
* - forces `base: './'` so built asset URLs stay relative (token-path serving).
|
|
15
|
+
*
|
|
16
|
+
* Also prints the in-platform dev URL
|
|
17
|
+
* `<url>/datamagik/app-designer/<id>/view?dev_server=http://localhost:5173`.
|
|
18
|
+
*/
|
|
19
|
+
export async function devCommand(opts) {
|
|
20
|
+
const cwd = process.cwd();
|
|
21
|
+
const config = loadDmConfig(cwd);
|
|
22
|
+
const creds = requireCredentials();
|
|
23
|
+
const appId = opts.app ? Number(opts.app) : config.appId;
|
|
24
|
+
if (!Number.isInteger(appId) || appId <= 0) {
|
|
25
|
+
console.error(`Invalid app id: ${opts.app ?? config.appId}`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const port = opts.port ? Number(opts.port) : 5173;
|
|
29
|
+
// Best-effort typegen on start (design §7.2) — dev keeps working offline.
|
|
30
|
+
try {
|
|
31
|
+
await typegenCommand({});
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
console.warn(`typegen on start failed (continuing): ${String(err)}`);
|
|
35
|
+
}
|
|
36
|
+
const params = {};
|
|
37
|
+
for (const kv of opts.context ?? []) {
|
|
38
|
+
const eq = kv.indexOf('=');
|
|
39
|
+
if (eq <= 0) {
|
|
40
|
+
console.error(`Invalid --context value '${kv}' — expected key=val`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
params[kv.slice(0, eq)] = kv.slice(eq + 1);
|
|
44
|
+
}
|
|
45
|
+
const contextInit = {
|
|
46
|
+
context: {
|
|
47
|
+
appId,
|
|
48
|
+
appName: `App ${appId} (dev)`,
|
|
49
|
+
version: 0,
|
|
50
|
+
surface: 'dev',
|
|
51
|
+
params,
|
|
52
|
+
user: { id: 0, name: 'dev' },
|
|
53
|
+
company: { id: 0, name: 'dev' },
|
|
54
|
+
},
|
|
55
|
+
sdkProtocolVersion: 1,
|
|
56
|
+
};
|
|
57
|
+
// Resolve vite from the USER's project, not the CLI's own dependencies.
|
|
58
|
+
let viteUrl;
|
|
59
|
+
try {
|
|
60
|
+
const require = createRequire(`${cwd}/package.json`);
|
|
61
|
+
viteUrl = pathToFileURL(require.resolve('vite')).href;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
console.error('Could not resolve `vite` from this project. `dm dev` wraps your project’s Vite dev server —\n' +
|
|
65
|
+
'install it first: npm install -D vite');
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
const vite = (await import(viteUrl));
|
|
69
|
+
const server = await vite.createServer({
|
|
70
|
+
root: cwd,
|
|
71
|
+
base: './',
|
|
72
|
+
server: {
|
|
73
|
+
port,
|
|
74
|
+
strictPort: true,
|
|
75
|
+
proxy: {
|
|
76
|
+
'/api': {
|
|
77
|
+
target: creds.url,
|
|
78
|
+
changeOrigin: true,
|
|
79
|
+
headers: { Authorization: `Bearer ${creds.token}` },
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
plugins: [dmDevPlugin(contextInit)],
|
|
84
|
+
});
|
|
85
|
+
await server.listen();
|
|
86
|
+
server.printUrls();
|
|
87
|
+
console.log('');
|
|
88
|
+
console.log(` dm context: http://localhost:${port}/__dm/context (surface: dev)`);
|
|
89
|
+
console.log(` In-platform dev URL:`);
|
|
90
|
+
console.log(` ${creds.url}/datamagik/app-designer/${appId}/view?dev_server=http://localhost:${port}`);
|
|
91
|
+
console.log(' (requires Builder permission and ALLOW_SPA_DEV_SERVER=true on a non-production env)');
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* The injected Vite plugin: serves the simulated context and pins `base`.
|
|
95
|
+
* Defined as a plain object so it works with whatever Vite major the user
|
|
96
|
+
* project has installed (the plugin API surface used here is stable).
|
|
97
|
+
*/
|
|
98
|
+
export function dmDevPlugin(contextInit) {
|
|
99
|
+
return {
|
|
100
|
+
name: 'datamagik:dev',
|
|
101
|
+
config() {
|
|
102
|
+
return { base: './' };
|
|
103
|
+
},
|
|
104
|
+
configureServer(server) {
|
|
105
|
+
server.middlewares.use('/__dm/context', (_req, res) => {
|
|
106
|
+
res.setHeader('Content-Type', 'application/json');
|
|
107
|
+
res.setHeader('Cache-Control', 'no-store');
|
|
108
|
+
res.end(JSON.stringify(contextInit));
|
|
109
|
+
});
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=dev.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** The two scaffolds `dm init` can produce. */
|
|
2
|
+
export type StarterTemplate = 'simple' | 'showcase';
|
|
3
|
+
export interface InitOptions {
|
|
4
|
+
/** Target directory (positional arg). Defaults to the current directory. */
|
|
5
|
+
dir?: string;
|
|
6
|
+
/** Which starter to scaffold; prompts when omitted on a TTY. */
|
|
7
|
+
template?: string;
|
|
8
|
+
/** Application id to write into dm.config.json. */
|
|
9
|
+
app?: string;
|
|
10
|
+
/** Overwrite / merge into a non-empty directory. */
|
|
11
|
+
force?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* `dm init [dir] [--template simple|showcase] [--app <id>]`
|
|
15
|
+
*
|
|
16
|
+
* Scaffolds a Vue 3 + Vite starter for the app SDK. `showcase` is a
|
|
17
|
+
* platform-styled app with working examples for every SDK area (context, data
|
|
18
|
+
* query, scripts, serials, printing, navigation, output events); `simple` is a
|
|
19
|
+
* minimal connect-and-query starter. The generated `dm.config.json` carries
|
|
20
|
+
* placeholder resource ids — set `appId` and the real ids, then run
|
|
21
|
+
* `dm typegen` / `dm dev`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function initCommand(opts: InitOptions): Promise<void>;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline/promises';
|
|
2
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
const TEMPLATES = ['simple', 'showcase'];
|
|
6
|
+
/** Files copied verbatim apart from the leading-underscore rename below. */
|
|
7
|
+
const RENAME_ON_COPY = {
|
|
8
|
+
// npm refuses to publish a file literally named `.gitignore`, so the
|
|
9
|
+
// template stores it as `_gitignore` and we restore the dotfile on copy.
|
|
10
|
+
_gitignore: '.gitignore',
|
|
11
|
+
};
|
|
12
|
+
/** Extensions copied byte-for-byte (no text token substitution). */
|
|
13
|
+
const BINARY_EXT = new Set([
|
|
14
|
+
'.png', '.jpg', '.jpeg', '.gif', '.webp', '.ico',
|
|
15
|
+
'.woff', '.woff2', '.ttf', '.otf', '.pdf', '.zip',
|
|
16
|
+
]);
|
|
17
|
+
/** Token replacements applied to every copied text file. */
|
|
18
|
+
function render(contents, vars) {
|
|
19
|
+
return contents
|
|
20
|
+
.replaceAll('__APP_NAME__', vars.appName)
|
|
21
|
+
.replaceAll('__PKG_NAME__', vars.pkgName)
|
|
22
|
+
.replaceAll('__APP_ID__', String(vars.appId));
|
|
23
|
+
}
|
|
24
|
+
/** Coerces a directory name into a valid npm package name. */
|
|
25
|
+
function toPackageName(name) {
|
|
26
|
+
const slug = name
|
|
27
|
+
.toLowerCase()
|
|
28
|
+
.replace(/[^a-z0-9._-]+/g, '-')
|
|
29
|
+
.replace(/^[._-]+|[._-]+$/g, '');
|
|
30
|
+
return slug || 'datamagik-app';
|
|
31
|
+
}
|
|
32
|
+
/** Locates the bundled template tree (works from both src/ and dist/). */
|
|
33
|
+
function templateRoot(template) {
|
|
34
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
35
|
+
return path.resolve(here, '..', '..', 'templates', template);
|
|
36
|
+
}
|
|
37
|
+
function copyTree(src, dest, vars) {
|
|
38
|
+
const written = [];
|
|
39
|
+
for (const entry of readdirSync(src, { withFileTypes: true })) {
|
|
40
|
+
const from = path.join(src, entry.name);
|
|
41
|
+
const targetName = RENAME_ON_COPY[entry.name] ?? entry.name;
|
|
42
|
+
const to = path.join(dest, targetName);
|
|
43
|
+
if (entry.isDirectory()) {
|
|
44
|
+
mkdirSync(to, { recursive: true });
|
|
45
|
+
written.push(...copyTree(from, to, vars));
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
mkdirSync(path.dirname(to), { recursive: true });
|
|
49
|
+
if (BINARY_EXT.has(path.extname(entry.name).toLowerCase())) {
|
|
50
|
+
writeFileSync(to, readFileSync(from)); // copy bytes verbatim
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
writeFileSync(to, render(readFileSync(from, 'utf8'), vars));
|
|
54
|
+
}
|
|
55
|
+
written.push(to);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return written;
|
|
59
|
+
}
|
|
60
|
+
/** Resolves the template from the flag, or prompts on a TTY (default: showcase). */
|
|
61
|
+
async function resolveTemplate(flag) {
|
|
62
|
+
if (flag !== undefined) {
|
|
63
|
+
if (!TEMPLATES.includes(flag)) {
|
|
64
|
+
throw new Error(`--template must be one of ${TEMPLATES.join(', ')} (got "${flag}")`);
|
|
65
|
+
}
|
|
66
|
+
return flag;
|
|
67
|
+
}
|
|
68
|
+
if (!process.stdin.isTTY)
|
|
69
|
+
return 'showcase';
|
|
70
|
+
console.log('Which starter would you like?');
|
|
71
|
+
console.log(' 1) showcase — platform-styled app demonstrating every SDK area (recommended)');
|
|
72
|
+
console.log(' 2) simple — minimal app: connect, show context, one data query');
|
|
73
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
74
|
+
try {
|
|
75
|
+
const answer = (await rl.question('Choose [1]: ')).trim().toLowerCase();
|
|
76
|
+
if (answer === '2' || answer === 'simple')
|
|
77
|
+
return 'simple';
|
|
78
|
+
return 'showcase';
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
rl.close();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* `dm init [dir] [--template simple|showcase] [--app <id>]`
|
|
86
|
+
*
|
|
87
|
+
* Scaffolds a Vue 3 + Vite starter for the app SDK. `showcase` is a
|
|
88
|
+
* platform-styled app with working examples for every SDK area (context, data
|
|
89
|
+
* query, scripts, serials, printing, navigation, output events); `simple` is a
|
|
90
|
+
* minimal connect-and-query starter. The generated `dm.config.json` carries
|
|
91
|
+
* placeholder resource ids — set `appId` and the real ids, then run
|
|
92
|
+
* `dm typegen` / `dm dev`.
|
|
93
|
+
*/
|
|
94
|
+
export async function initCommand(opts) {
|
|
95
|
+
const targetDir = path.resolve(opts.dir ?? '.');
|
|
96
|
+
const appName = path.basename(targetDir);
|
|
97
|
+
const appId = opts.app !== undefined ? Number(opts.app) : 0;
|
|
98
|
+
if (opts.app !== undefined && (!Number.isInteger(appId) || appId <= 0)) {
|
|
99
|
+
throw new Error(`--app must be a positive integer (got "${opts.app}")`);
|
|
100
|
+
}
|
|
101
|
+
const template = await resolveTemplate(opts.template);
|
|
102
|
+
if (existsSync(targetDir)) {
|
|
103
|
+
if (!statSync(targetDir).isDirectory()) {
|
|
104
|
+
throw new Error(`${targetDir} exists and is not a directory.`);
|
|
105
|
+
}
|
|
106
|
+
const existing = readdirSync(targetDir);
|
|
107
|
+
if (existing.length > 0 && !opts.force) {
|
|
108
|
+
throw new Error(`${targetDir} is not empty. Re-run with --force to scaffold into it anyway.`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
mkdirSync(targetDir, { recursive: true });
|
|
112
|
+
const root = templateRoot(template);
|
|
113
|
+
if (!existsSync(root)) {
|
|
114
|
+
throw new Error(`Starter template "${template}" not found at ${root} (corrupt installation?)`);
|
|
115
|
+
}
|
|
116
|
+
const written = copyTree(root, targetDir, { appName, pkgName: toPackageName(appName), appId });
|
|
117
|
+
const rel = opts.dir && opts.dir !== '.' ? opts.dir : '.';
|
|
118
|
+
console.log(`Scaffolded the ${template} starter in ${targetDir} (${written.length} files).`);
|
|
119
|
+
console.log('');
|
|
120
|
+
console.log('Next steps:');
|
|
121
|
+
if (rel !== '.')
|
|
122
|
+
console.log(` cd ${rel}`);
|
|
123
|
+
console.log(' npm install');
|
|
124
|
+
console.log(' npx dm login --url https://staging.data-magik.com # or https://data-magik.com');
|
|
125
|
+
if (appId <= 0) {
|
|
126
|
+
console.log(' # set "appId" in dm.config.json to your application id (App Studio header)');
|
|
127
|
+
}
|
|
128
|
+
console.log(' npx dm dev # run it now — uses the bundled demo types');
|
|
129
|
+
console.log('');
|
|
130
|
+
console.log('Then wire your own platform resources (the starter ships placeholders):');
|
|
131
|
+
console.log(' npx dm add # search this tenant and declare a real resource');
|
|
132
|
+
console.log(' npx dm typegen # regenerate src/dm.generated.ts from your resources');
|
|
133
|
+
console.log(' # tip: remove the unused placeholder entries from dm.config.json so');
|
|
134
|
+
console.log(' # dm typegen does not try to fetch ids that do not exist.');
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface LoginOptions {
|
|
2
|
+
url?: string;
|
|
3
|
+
token?: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* `dm login [--url <platform>] [--token <dcp_...>]`
|
|
7
|
+
*
|
|
8
|
+
* Stores `{ url, token }` in `~/.config/datamagik/credentials.json` (0600).
|
|
9
|
+
* When `--token` is omitted, prompts on stdin for an API key created in the
|
|
10
|
+
* platform UI (Settings → API Keys).
|
|
11
|
+
*
|
|
12
|
+
* TODO(browser OAuth): the design (§7.2) calls for a browser flow where the
|
|
13
|
+
* server mints a builder bearer via `CreateSystemAPIKey` and delivers it to a
|
|
14
|
+
* localhost callback. Until that endpoint ships, paste a `dcp_` API key.
|
|
15
|
+
*/
|
|
16
|
+
export declare function loginCommand(opts: LoginOptions): Promise<void>;
|