deploro 0.7.0 → 0.8.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/index.js +256 -19
- package/package.json +44 -44
package/dist/index.js
CHANGED
|
@@ -230,6 +230,10 @@ Downloading ${keys.length} file(s) to ${opts.storage} \u2026`);
|
|
|
230
230
|
}
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
+
// src/commands/gen.ts
|
|
234
|
+
import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
235
|
+
import { dirname as dirname3 } from "path";
|
|
236
|
+
|
|
233
237
|
// src/lib/api.ts
|
|
234
238
|
function errorMessage(status, body, statusText) {
|
|
235
239
|
const parts = [body.error ?? statusText];
|
|
@@ -268,6 +272,237 @@ async function apiRequestNoProject(path, options) {
|
|
|
268
272
|
return res.json();
|
|
269
273
|
}
|
|
270
274
|
|
|
275
|
+
// src/lib/gen-types.ts
|
|
276
|
+
var STRING_NUMERIC = /* @__PURE__ */ new Set(["int8", "numeric", "money"]);
|
|
277
|
+
var NUMBER = /* @__PURE__ */ new Set(["int2", "int4", "float4", "float8", "oid", "xid", "cid", "regclass", "regproc", "regtype"]);
|
|
278
|
+
var STRING = /* @__PURE__ */ new Set([
|
|
279
|
+
"text",
|
|
280
|
+
"varchar",
|
|
281
|
+
"bpchar",
|
|
282
|
+
"char",
|
|
283
|
+
"name",
|
|
284
|
+
"citext",
|
|
285
|
+
"uuid",
|
|
286
|
+
"inet",
|
|
287
|
+
"cidr",
|
|
288
|
+
"macaddr",
|
|
289
|
+
"macaddr8",
|
|
290
|
+
"date",
|
|
291
|
+
"time",
|
|
292
|
+
"timetz",
|
|
293
|
+
"timestamp",
|
|
294
|
+
"timestamptz",
|
|
295
|
+
"interval",
|
|
296
|
+
"xml",
|
|
297
|
+
"tsvector",
|
|
298
|
+
"tsquery",
|
|
299
|
+
"bit",
|
|
300
|
+
"varbit",
|
|
301
|
+
"point",
|
|
302
|
+
"line",
|
|
303
|
+
"lseg",
|
|
304
|
+
"box",
|
|
305
|
+
"path",
|
|
306
|
+
"polygon",
|
|
307
|
+
"circle",
|
|
308
|
+
"ltree"
|
|
309
|
+
]);
|
|
310
|
+
var DATA_TYPE_TO_UDT = {
|
|
311
|
+
smallint: "int2",
|
|
312
|
+
integer: "int4",
|
|
313
|
+
bigint: "int8",
|
|
314
|
+
real: "float4",
|
|
315
|
+
"double precision": "float8",
|
|
316
|
+
numeric: "numeric",
|
|
317
|
+
money: "money",
|
|
318
|
+
boolean: "bool",
|
|
319
|
+
text: "text",
|
|
320
|
+
"character varying": "varchar",
|
|
321
|
+
character: "bpchar",
|
|
322
|
+
uuid: "uuid",
|
|
323
|
+
json: "json",
|
|
324
|
+
jsonb: "jsonb",
|
|
325
|
+
date: "date",
|
|
326
|
+
bytea: "bytea",
|
|
327
|
+
"timestamp without time zone": "timestamp",
|
|
328
|
+
"timestamp with time zone": "timestamptz",
|
|
329
|
+
"time without time zone": "time",
|
|
330
|
+
"time with time zone": "timetz",
|
|
331
|
+
interval: "interval"
|
|
332
|
+
};
|
|
333
|
+
var IDENT_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
334
|
+
function key(name) {
|
|
335
|
+
return IDENT_RE.test(name) ? name : JSON.stringify(name);
|
|
336
|
+
}
|
|
337
|
+
function literal(value) {
|
|
338
|
+
return JSON.stringify(value);
|
|
339
|
+
}
|
|
340
|
+
function udtOf(prop) {
|
|
341
|
+
if (prop["x-pg-type"]) return prop["x-pg-type"];
|
|
342
|
+
const dataType = prop.description?.replace(/ NOT NULL$/, "");
|
|
343
|
+
return dataType ? DATA_TYPE_TO_UDT[dataType] ?? null : null;
|
|
344
|
+
}
|
|
345
|
+
function tsType(udt, enums, write, prop) {
|
|
346
|
+
if (udt?.startsWith("_")) {
|
|
347
|
+
const inner = tsType(udt.slice(1), enums, write);
|
|
348
|
+
return /[|\s]/.test(inner) ? `(${inner})[]` : `${inner}[]`;
|
|
349
|
+
}
|
|
350
|
+
if (udt && enums[udt]) return `Database["public"]["Enums"][${literal(udt)}]`;
|
|
351
|
+
if (udt === "bool") return "boolean";
|
|
352
|
+
if (udt === "json" || udt === "jsonb") return "Json";
|
|
353
|
+
if (udt && NUMBER.has(udt)) return "number";
|
|
354
|
+
if (udt && STRING_NUMERIC.has(udt)) return write ? "number | string" : "string";
|
|
355
|
+
if (udt && STRING.has(udt)) return "string";
|
|
356
|
+
if (udt === "void") return "undefined";
|
|
357
|
+
if (prop?.enum?.length) return prop.enum.map(literal).join(" | ");
|
|
358
|
+
const t = Array.isArray(prop?.type) ? null : prop?.type;
|
|
359
|
+
if (t === "number" || t === "integer") return "number";
|
|
360
|
+
if (t === "boolean") return "boolean";
|
|
361
|
+
if (t === "string") return "string";
|
|
362
|
+
if (t === "array") return "unknown[]";
|
|
363
|
+
return "unknown";
|
|
364
|
+
}
|
|
365
|
+
function generateTypes(spec) {
|
|
366
|
+
const schemas = spec.components?.schemas ?? {};
|
|
367
|
+
const enums = spec.components?.["x-pg-enums"] ?? {};
|
|
368
|
+
const tableNames = Object.keys(schemas).sort();
|
|
369
|
+
let legacySpec = false;
|
|
370
|
+
const tableBlocks = [];
|
|
371
|
+
for (const table2 of tableNames) {
|
|
372
|
+
const schema = schemas[table2];
|
|
373
|
+
const required = new Set(schema.required ?? []);
|
|
374
|
+
const row = [];
|
|
375
|
+
const insert = [];
|
|
376
|
+
const update = [];
|
|
377
|
+
for (const [col, prop] of Object.entries(schema.properties ?? {})) {
|
|
378
|
+
if (!("x-pg-type" in prop)) legacySpec = true;
|
|
379
|
+
const nullable = prop.nullable === true || !required.has(col);
|
|
380
|
+
const udt = udtOf(prop);
|
|
381
|
+
const readType = tsType(udt, enums, false, prop) + (nullable ? " | null" : "");
|
|
382
|
+
const writeType = tsType(udt, enums, true, prop) + (nullable ? " | null" : "");
|
|
383
|
+
const neverWritten = prop["x-pg-generated"] === true || prop["x-pg-identity"] === "always";
|
|
384
|
+
const optionalOnInsert = nullable || prop["x-pg-has-default"] === true;
|
|
385
|
+
row.push(` ${key(col)}: ${readType}`);
|
|
386
|
+
if (neverWritten) {
|
|
387
|
+
insert.push(` ${key(col)}?: never`);
|
|
388
|
+
update.push(` ${key(col)}?: never`);
|
|
389
|
+
} else {
|
|
390
|
+
insert.push(` ${key(col)}${optionalOnInsert ? "?" : ""}: ${writeType}`);
|
|
391
|
+
update.push(` ${key(col)}?: ${writeType}`);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
const body = (lines) => lines.length ? `{
|
|
395
|
+
${lines.join("\n")}
|
|
396
|
+
}` : "Record<string, never>";
|
|
397
|
+
tableBlocks.push(
|
|
398
|
+
` ${key(table2)}: {
|
|
399
|
+
Row: ${body(row)}
|
|
400
|
+
Insert: ${body(insert)}
|
|
401
|
+
Update: ${body(update)}
|
|
402
|
+
}`
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
const functionBlocks = [];
|
|
406
|
+
const fnEntries = Object.entries(spec.paths ?? {}).map(([path, ops]) => ({ name: path.match(/\/studio\/rpc\/([^/]+)$/)?.[1], op: ops.post })).filter((f) => !!f.name && !!f.op).filter((f) => !["trigger", "event_trigger"].includes(f.op["x-pg-returns"]?.type ?? "")).sort((a, b) => a.name.localeCompare(b.name));
|
|
407
|
+
for (const { name, op } of fnEntries) {
|
|
408
|
+
const props = op.requestBody?.content?.["application/json"]?.schema?.properties ?? {};
|
|
409
|
+
const args = Object.entries(props).map(([arg, prop]) => {
|
|
410
|
+
const optional = prop["x-pg-has-default"] === true;
|
|
411
|
+
return ` ${key(arg)}${optional ? "?" : ""}: ${tsType(udtOf(prop), enums, true, prop)}`;
|
|
412
|
+
});
|
|
413
|
+
const ret = op["x-pg-returns"];
|
|
414
|
+
let returns;
|
|
415
|
+
if (!ret) {
|
|
416
|
+
legacySpec = true;
|
|
417
|
+
returns = "unknown";
|
|
418
|
+
} else {
|
|
419
|
+
let single;
|
|
420
|
+
if (ret.columns?.length) {
|
|
421
|
+
single = `{
|
|
422
|
+
${ret.columns.map((c) => ` ${key(c.name)}: ${tsType(c.type, enums, false)} | null`).join("\n")}
|
|
423
|
+
}`;
|
|
424
|
+
} else if (ret.type && schemas[ret.type]) {
|
|
425
|
+
single = `Database["public"]["Tables"][${literal(ret.type)}]["Row"]`;
|
|
426
|
+
} else {
|
|
427
|
+
single = tsType(ret.type, enums, false);
|
|
428
|
+
}
|
|
429
|
+
returns = ret.set ? /[|\s]/.test(single) && !single.startsWith("{") ? `(${single})[]` : `${single}[]` : single;
|
|
430
|
+
}
|
|
431
|
+
functionBlocks.push(
|
|
432
|
+
` ${key(name)}: {
|
|
433
|
+
Args: ${args.length ? `{
|
|
434
|
+
${args.join("\n")}
|
|
435
|
+
}` : "Record<PropertyKey, never>"}
|
|
436
|
+
Returns: ${returns}
|
|
437
|
+
}`
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
const enumBlocks = Object.keys(enums).sort().map(
|
|
441
|
+
(name) => ` ${key(name)}: ${enums[name].length ? enums[name].map(literal).join(" | ") : "never"}`
|
|
442
|
+
);
|
|
443
|
+
const section = (blocks) => blocks.length ? `{
|
|
444
|
+
${blocks.join("\n")}
|
|
445
|
+
}` : "{\n [_ in never]: never\n }";
|
|
446
|
+
const source = `// Generated by \`deploro gen types\`. Do not edit by hand; re-run after each migration.
|
|
447
|
+
//
|
|
448
|
+
// bigint, numeric and money columns are strings in Row: Deploro returns them as
|
|
449
|
+
// strings so large values keep their precision. Insert and Update accept either.
|
|
450
|
+
|
|
451
|
+
export type Json =
|
|
452
|
+
| string
|
|
453
|
+
| number
|
|
454
|
+
| boolean
|
|
455
|
+
| null
|
|
456
|
+
| { [key: string]: Json | undefined }
|
|
457
|
+
| Json[]
|
|
458
|
+
|
|
459
|
+
export type Database = {
|
|
460
|
+
public: {
|
|
461
|
+
Tables: ${section(tableBlocks)}
|
|
462
|
+
Functions: ${section(functionBlocks)}
|
|
463
|
+
Enums: ${section(enumBlocks)}
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
type PublicSchema = Database["public"]
|
|
468
|
+
|
|
469
|
+
export type Tables<T extends keyof PublicSchema["Tables"]> = PublicSchema["Tables"][T]["Row"]
|
|
470
|
+
export type TablesInsert<T extends keyof PublicSchema["Tables"]> = PublicSchema["Tables"][T]["Insert"]
|
|
471
|
+
export type TablesUpdate<T extends keyof PublicSchema["Tables"]> = PublicSchema["Tables"][T]["Update"]
|
|
472
|
+
export type Enums<T extends keyof PublicSchema["Enums"]> = PublicSchema["Enums"][T]
|
|
473
|
+
export type FunctionArgs<T extends keyof PublicSchema["Functions"]> = PublicSchema["Functions"][T]["Args"]
|
|
474
|
+
export type FunctionReturns<T extends keyof PublicSchema["Functions"]> = PublicSchema["Functions"][T]["Returns"]
|
|
475
|
+
`;
|
|
476
|
+
return {
|
|
477
|
+
source,
|
|
478
|
+
tables: tableNames.length,
|
|
479
|
+
functions: fnEntries.length,
|
|
480
|
+
enums: enumBlocks.length,
|
|
481
|
+
legacySpec
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// src/commands/gen.ts
|
|
486
|
+
async function genTypesCommand(opts) {
|
|
487
|
+
const config = requireProject();
|
|
488
|
+
const spec = await apiRequest(`/api/projects/${config.projectId}/studio/spec`);
|
|
489
|
+
const result = generateTypes(spec);
|
|
490
|
+
if (opts.out) {
|
|
491
|
+
mkdirSync3(dirname3(opts.out) || ".", { recursive: true });
|
|
492
|
+
writeFileSync3(opts.out, result.source, "utf8");
|
|
493
|
+
console.error(
|
|
494
|
+
`Wrote ${opts.out}: ${result.tables} table(s), ${result.functions} function(s), ${result.enums} enum(s)`
|
|
495
|
+
);
|
|
496
|
+
} else {
|
|
497
|
+
process.stdout.write(result.source);
|
|
498
|
+
}
|
|
499
|
+
if (result.legacySpec) {
|
|
500
|
+
console.error(
|
|
501
|
+
"Warning: this server's spec has no column defaults or function return types, so every NOT NULL column is required in Insert and function Returns are `unknown`. They'll be exact once the server is updated."
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
271
506
|
// src/lib/confirm.ts
|
|
272
507
|
import { createInterface as createInterface2 } from "readline";
|
|
273
508
|
async function confirmOrDie(question, yes) {
|
|
@@ -905,7 +1140,7 @@ async function resolveDomainId(projectId, idOrHostname) {
|
|
|
905
1140
|
}
|
|
906
1141
|
|
|
907
1142
|
// src/commands/zones.ts
|
|
908
|
-
import { writeFileSync as
|
|
1143
|
+
import { writeFileSync as writeFileSync4 } from "fs";
|
|
909
1144
|
function zonesPath() {
|
|
910
1145
|
return `/api/projects/${requireProject().projectId}/zones`;
|
|
911
1146
|
}
|
|
@@ -975,7 +1210,7 @@ async function zonesRemoveCommand(domain, opts) {
|
|
|
975
1210
|
});
|
|
976
1211
|
if (data.zone_file) {
|
|
977
1212
|
const file = `${z.name}.zone.txt`;
|
|
978
|
-
|
|
1213
|
+
writeFileSync4(file, data.zone_file);
|
|
979
1214
|
console.log(`Saved its records to ${file}`);
|
|
980
1215
|
}
|
|
981
1216
|
console.log(`\u2713 ${z.name} removed`);
|
|
@@ -1170,7 +1405,7 @@ async function zonesUnforwardCommand(address) {
|
|
|
1170
1405
|
}
|
|
1171
1406
|
|
|
1172
1407
|
// src/commands/storage.ts
|
|
1173
|
-
import { readFileSync as readFileSync2, writeFileSync as
|
|
1408
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync5 } from "fs";
|
|
1174
1409
|
import { basename } from "path";
|
|
1175
1410
|
function authHeaders2(config) {
|
|
1176
1411
|
return { Authorization: `Bearer ${config.accessToken}` };
|
|
@@ -1213,27 +1448,27 @@ async function storageUploadCommand(filePath, opts) {
|
|
|
1213
1448
|
const data = await res.json();
|
|
1214
1449
|
console.log(`\u2713 Uploaded as ${data.key} (${data.size} bytes, ${data.contentType})`);
|
|
1215
1450
|
}
|
|
1216
|
-
async function storageDownloadCommand(
|
|
1451
|
+
async function storageDownloadCommand(key2, opts) {
|
|
1217
1452
|
const config = requireProject();
|
|
1218
1453
|
const res = await fetch(
|
|
1219
|
-
`${config.baseUrl}/api/projects/${config.projectId}/storage/download?key=${encodeURIComponent(
|
|
1454
|
+
`${config.baseUrl}/api/projects/${config.projectId}/storage/download?key=${encodeURIComponent(key2)}`,
|
|
1220
1455
|
{ headers: authHeaders2(config) }
|
|
1221
1456
|
);
|
|
1222
1457
|
await throwOnError2(res);
|
|
1223
1458
|
const bytes = new Uint8Array(await res.arrayBuffer());
|
|
1224
|
-
const outPath = opts.out ?? basename(
|
|
1225
|
-
|
|
1459
|
+
const outPath = opts.out ?? basename(key2);
|
|
1460
|
+
writeFileSync5(outPath, bytes);
|
|
1226
1461
|
console.log(`\u2713 Saved to ${outPath} (${bytes.length} bytes)`);
|
|
1227
1462
|
}
|
|
1228
|
-
async function storageDeleteCommand(
|
|
1463
|
+
async function storageDeleteCommand(key2, opts) {
|
|
1229
1464
|
const config = requireProject();
|
|
1230
|
-
await confirmOrDie(`Delete "${
|
|
1465
|
+
await confirmOrDie(`Delete "${key2}" from storage?`, opts.yes);
|
|
1231
1466
|
const res = await fetch(
|
|
1232
|
-
`${config.baseUrl}/api/projects/${config.projectId}/storage?key=${encodeURIComponent(
|
|
1467
|
+
`${config.baseUrl}/api/projects/${config.projectId}/storage?key=${encodeURIComponent(key2)}`,
|
|
1233
1468
|
{ method: "DELETE", headers: authHeaders2(config) }
|
|
1234
1469
|
);
|
|
1235
1470
|
await throwOnError2(res);
|
|
1236
|
-
console.log(`\u2713 Deleted ${
|
|
1471
|
+
console.log(`\u2713 Deleted ${key2}`);
|
|
1237
1472
|
}
|
|
1238
1473
|
async function storagePublicCommand(mode, opts) {
|
|
1239
1474
|
const config = requireProject();
|
|
@@ -1335,13 +1570,13 @@ function parseDuration(input) {
|
|
|
1335
1570
|
const mult = { s: 1, m: 60, h: 3600, d: 86400 }[unit] ?? 1;
|
|
1336
1571
|
return n * mult;
|
|
1337
1572
|
}
|
|
1338
|
-
async function storageSignCommand(
|
|
1573
|
+
async function storageSignCommand(key2, opts) {
|
|
1339
1574
|
const config = requireProject();
|
|
1340
1575
|
const expiresIn = opts.expires ? parseDuration(opts.expires) : void 0;
|
|
1341
1576
|
const res = await fetch(`${config.baseUrl}/api/projects/${config.projectId}/storage/signed-url`, {
|
|
1342
1577
|
method: "POST",
|
|
1343
1578
|
headers: { ...authHeaders2(config), "Content-Type": "application/json" },
|
|
1344
|
-
body: JSON.stringify({ key, expiresIn })
|
|
1579
|
+
body: JSON.stringify({ key: key2, expiresIn })
|
|
1345
1580
|
});
|
|
1346
1581
|
await throwOnError2(res);
|
|
1347
1582
|
const data = await res.json();
|
|
@@ -1598,13 +1833,13 @@ async function hostingStatusCommand() {
|
|
|
1598
1833
|
}
|
|
1599
1834
|
console.log("");
|
|
1600
1835
|
}
|
|
1601
|
-
async function hostingSetEnvCommand(
|
|
1836
|
+
async function hostingSetEnvCommand(key2, value) {
|
|
1602
1837
|
requireConfig();
|
|
1603
1838
|
await apiRequest("/api/hosting/env", {
|
|
1604
1839
|
method: "POST",
|
|
1605
|
-
body: JSON.stringify({ key, value })
|
|
1840
|
+
body: JSON.stringify({ key: key2, value })
|
|
1606
1841
|
});
|
|
1607
|
-
console.log(`\u2713 Secret '${
|
|
1842
|
+
console.log(`\u2713 Secret '${key2}' updated`);
|
|
1608
1843
|
}
|
|
1609
1844
|
async function hostingEnvCommand() {
|
|
1610
1845
|
requireConfig();
|
|
@@ -1942,13 +2177,13 @@ async function vpsEnvCommand() {
|
|
|
1942
2177
|
for (const v of data.vars) console.log(` ${v.key}`);
|
|
1943
2178
|
console.log("");
|
|
1944
2179
|
}
|
|
1945
|
-
async function vpsSetEnvCommand(
|
|
2180
|
+
async function vpsSetEnvCommand(key2, value) {
|
|
1946
2181
|
const config = requireProject();
|
|
1947
2182
|
await apiRequest(`/api/projects/${config.projectId}/vps/env`, {
|
|
1948
2183
|
method: "POST",
|
|
1949
|
-
body: JSON.stringify({ key, value })
|
|
2184
|
+
body: JSON.stringify({ key: key2, value })
|
|
1950
2185
|
});
|
|
1951
|
-
console.log(`\u2713 VPS env var '${
|
|
2186
|
+
console.log(`\u2713 VPS env var '${key2}' set \u2014 run 'deploro vps deploy' to apply it`);
|
|
1952
2187
|
}
|
|
1953
2188
|
async function vpsDeployCommand() {
|
|
1954
2189
|
const config = requireProject();
|
|
@@ -2086,6 +2321,8 @@ program.command("create <name>").description("Create a new project (and set it a
|
|
|
2086
2321
|
program.command("use <project>").description("Set the active project (accepts id, slug, or name)").action(useProjectCommand);
|
|
2087
2322
|
program.command("delete <project>").description("Delete a project and its database (accepts id, slug, or name)").option("-y, --yes", "Skip confirmation prompt").action(projectsDeleteCommand);
|
|
2088
2323
|
program.command("export").description("Export the active project's database and storage manifest (NDJSON)").option("--out <file>", "Where to write the export (default: deploro-export-<date>.ndjson)").option("--storage <dir>", "Also download stored files into this directory").option("--skip-storage", "Skip the object-storage listing entirely").action(exportCommand);
|
|
2324
|
+
var gen = program.command("gen").description("Generate code from the active project");
|
|
2325
|
+
gen.command("types").description("TypeScript types for the project's tables, functions and enums (prints to stdout)").option("--out <file>", "Write to this file instead of stdout").action(genTypesCommand);
|
|
2089
2326
|
var db = program.command("db").description("Database commands");
|
|
2090
2327
|
db.command("create").description("Provision the active project's database (idempotent)").action(dbCreateCommand);
|
|
2091
2328
|
db.command("info").description("Show database status and how to reach it from a deployed app").action(dbInfoCommand);
|
package/package.json
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "deploro",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Command-line interface for the Deploro developer platform — manage projects, databases, deployments, and hosting from your terminal.",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"deploro": "dist/index.js"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"dist"
|
|
11
|
-
],
|
|
12
|
-
"engines": {
|
|
13
|
-
"node": ">=18"
|
|
14
|
-
},
|
|
15
|
-
"keywords": [
|
|
16
|
-
"deploro",
|
|
17
|
-
"cli",
|
|
18
|
-
"cloudflare",
|
|
19
|
-
"postgres",
|
|
20
|
-
"deployment"
|
|
21
|
-
],
|
|
22
|
-
"license": "MIT",
|
|
23
|
-
"repository": {
|
|
24
|
-
"type": "git",
|
|
25
|
-
"url": "git+https://github.com/yawdeals1/deploro.git",
|
|
26
|
-
"directory": "packages/cli"
|
|
27
|
-
},
|
|
28
|
-
"homepage": "https://deploro.com",
|
|
29
|
-
"publishConfig": {
|
|
30
|
-
"access": "public"
|
|
31
|
-
},
|
|
32
|
-
"scripts": {
|
|
33
|
-
"build": "tsup src/index.ts --format esm --no-splitting --target node18 --out-dir dist",
|
|
34
|
-
"dev": "tsup src/index.ts --format esm --no-splitting --target node18 --out-dir dist --watch"
|
|
35
|
-
},
|
|
36
|
-
"dependencies": {
|
|
37
|
-
"commander": "^13.0.0"
|
|
38
|
-
},
|
|
39
|
-
"devDependencies": {
|
|
40
|
-
"@types/node": "^22.0.0",
|
|
41
|
-
"tsup": "^8.0.0",
|
|
42
|
-
"typescript": "^5.5.0"
|
|
43
|
-
}
|
|
44
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "deploro",
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "Command-line interface for the Deploro developer platform — manage projects, databases, deployments, and hosting from your terminal.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"deploro": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=18"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"deploro",
|
|
17
|
+
"cli",
|
|
18
|
+
"cloudflare",
|
|
19
|
+
"postgres",
|
|
20
|
+
"deployment"
|
|
21
|
+
],
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/yawdeals1/deploro.git",
|
|
26
|
+
"directory": "packages/cli"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://deploro.com",
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsup src/index.ts --format esm --no-splitting --target node18 --out-dir dist",
|
|
34
|
+
"dev": "tsup src/index.ts --format esm --no-splitting --target node18 --out-dir dist --watch"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"commander": "^13.0.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^22.0.0",
|
|
41
|
+
"tsup": "^8.0.0",
|
|
42
|
+
"typescript": "^5.5.0"
|
|
43
|
+
}
|
|
44
|
+
}
|