@persql/sdk 1.1.0 → 1.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  PerSQL
4
- } from "./chunk-YZEQFTCX.js";
4
+ } from "./chunk-GH75ERQ6.js";
5
5
 
6
6
  // src/cli.ts
7
7
  import { writeFile } from "fs/promises";
package/dist/index.cjs CHANGED
@@ -26,6 +26,7 @@ __export(index_exports, {
26
26
  PerSQLApprovals: () => PerSQLApprovals,
27
27
  PerSQLBranches: () => PerSQLBranches,
28
28
  PerSQLDatabase: () => PerSQLDatabase,
29
+ PerSQLDatabases: () => PerSQLDatabases,
29
30
  PerSQLError: () => PerSQLError,
30
31
  PerSQLProposals: () => PerSQLProposals,
31
32
  RateLimitError: () => RateLimitError,
@@ -316,8 +317,23 @@ var PerSQL = class _PerSQL {
316
317
  }
317
318
  return new PerSQLDatabase(this, ns, slug);
318
319
  }
320
+ /**
321
+ * Provision and list databases in the token's namespace. `create`
322
+ * needs an unscoped admin token; `database()` then gives you a handle
323
+ * to query the result.
324
+ */
325
+ get databases() {
326
+ return new PerSQLDatabases(this);
327
+ }
319
328
  /** @internal */
320
329
  async request(method, path, body, headers) {
330
+ return (await this.requestWithMeta(method, path, body, headers)).data;
331
+ }
332
+ /**
333
+ * @internal — like `request`, but also surfaces the response `meta`
334
+ * envelope (usage + `costUsd`) that the data-only `request` drops.
335
+ */
336
+ async requestWithMeta(method, path, body, headers) {
321
337
  const res = await this._fetch(`${this.baseURL}${path}`, {
322
338
  method,
323
339
  headers: {
@@ -349,7 +365,7 @@ var PerSQL = class _PerSQL {
349
365
  }
350
366
  throw new PerSQLError(res.status, message, envelope?.errorDetail);
351
367
  }
352
- return envelope.data;
368
+ return { data: envelope.data, meta: envelope.meta };
353
369
  }
354
370
  /** @internal — raw fetch returning the underlying Response. */
355
371
  fetchRaw(method, path) {
@@ -420,6 +436,44 @@ var SupportClient = class {
420
436
  );
421
437
  }
422
438
  };
439
+ var PerSQLDatabases = class {
440
+ constructor(client) {
441
+ this.client = client;
442
+ }
443
+ /**
444
+ * Provision a new isolated database and return its metadata. Requires
445
+ * an unscoped admin token (scoped tokens can't create databases).
446
+ */
447
+ async create(opts) {
448
+ if (this.client.local) {
449
+ throw new Error(
450
+ "PerSQL: databases.create() needs a server-mode token. Pass a real token to `new PerSQL({ token })` to provision databases."
451
+ );
452
+ }
453
+ return this.client.request("POST", "/v1/databases", {
454
+ name: opts.name,
455
+ slug: opts.slug,
456
+ region: opts.region,
457
+ ttlDays: opts.ttlDays
458
+ });
459
+ }
460
+ /** List databases in the token's namespace, newest first (paginated). */
461
+ async list(opts = {}) {
462
+ if (this.client.local) {
463
+ throw new Error("PerSQL: databases.list() needs a server-mode token.");
464
+ }
465
+ const qs = new URLSearchParams();
466
+ if (opts.cursor) qs.set("cursor", opts.cursor);
467
+ if (opts.pageSize) qs.set("pageSize", String(opts.pageSize));
468
+ const tail = qs.toString() ? `?${qs.toString()}` : "";
469
+ const res = await this.client.fetchRaw("GET", `/v1/databases${tail}`);
470
+ const body = await res.json();
471
+ if (!res.ok || !body.success) {
472
+ throw new PerSQLError(res.status, body.error ?? `Request failed (${res.status})`);
473
+ }
474
+ return { data: body.data ?? [], nextCursor: body.nextCursor ?? null };
475
+ }
476
+ };
423
477
  var PerSQLDatabase = class {
424
478
  constructor(client, namespace, slug) {
425
479
  this.client = client;
@@ -436,7 +490,7 @@ var PerSQLDatabase = class {
436
490
  if (options.idempotencyKey) headers["Idempotency-Key"] = options.idempotencyKey;
437
491
  if (options.planKey) headers["Plan-Key"] = options.planKey;
438
492
  if (options.planStep) headers["Plan-Step"] = options.planStep;
439
- const raw = await this.client.request(
493
+ const { data: raw, meta } = await this.client.requestWithMeta(
440
494
  "POST",
441
495
  `/v1/db/${this.namespace}/${this.slug}/query`,
442
496
  { sql, params },
@@ -444,7 +498,8 @@ var PerSQLDatabase = class {
444
498
  );
445
499
  return {
446
500
  ...raw,
447
- data: rowsToObjects(raw.columns, raw.rows)
501
+ data: rowsToObjects(raw.columns, raw.rows),
502
+ meta
448
503
  };
449
504
  }
450
505
  /** Run multiple statements in one round-trip, optionally in a transaction. */
@@ -2019,6 +2074,7 @@ function rowsToObjects(columns, rows) {
2019
2074
  PerSQLApprovals,
2020
2075
  PerSQLBranches,
2021
2076
  PerSQLDatabase,
2077
+ PerSQLDatabases,
2022
2078
  PerSQLError,
2023
2079
  PerSQLProposals,
2024
2080
  RateLimitError,