@hasna/shortlinks 0.2.7 → 0.2.10

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.
@@ -94,19 +94,19 @@ export interface DomainDeleteResponse {
94
94
  export interface HealthStatus {
95
95
  "status": string;
96
96
  "version": string;
97
- "mode": string;
97
+ "backend": string;
98
98
  "db_latency_ms"?: number;
99
99
  }
100
100
  export interface ReadyStatus {
101
101
  "status": string;
102
102
  "version": string;
103
- "mode": string;
103
+ "backend": string;
104
104
  "pending_migrations"?: Array<string>;
105
105
  }
106
106
  export interface VersionInfo {
107
107
  "status": string;
108
108
  "version": string;
109
- "mode": string;
109
+ "backend": string;
110
110
  "name"?: string;
111
111
  }
112
112
  export interface ErrorResponse {
@@ -179,6 +179,6 @@ export declare class ShortlinksApiClient {
179
179
  }, init?: RequestInit): Promise<Link>;
180
180
  /** Total domains/links/clicks counts. */
181
181
  getStats(init?: RequestInit): Promise<TotalStats>;
182
- /** Service version and mode. */
182
+ /** Service version and data backend. */
183
183
  getVersion(init?: RequestInit): Promise<VersionInfo>;
184
184
  }
@@ -5,8 +5,7 @@
5
5
  * OpenAPI document (src/serve/openapi.ts) by `bun run sdk:generate`. It is the
6
6
  * canonical client for the versioned `/v1` API with API-key auth.
7
7
  *
8
- * Client self_hosted mode reads `SHORTLINKS_API_URL` + `SHORTLINKS_API_KEY`
9
- * (never a DSN).
8
+ * The client reads `SHORTLINKS_API_URL` + `SHORTLINKS_API_KEY` (never a DSN).
10
9
  */
11
10
  export * from "./generated.js";
12
11
  export { buildOpenApiDocument } from "../serve/openapi.js";
package/dist/sdk/index.js CHANGED
@@ -61,8 +61,16 @@ class ShortlinksApiClient {
61
61
  const url = new URL(this.baseUrl + path);
62
62
  if (opts.query) {
63
63
  for (const [key, value] of Object.entries(opts.query)) {
64
- if (value !== undefined && value !== null)
64
+ if (value === undefined || value === null)
65
+ continue;
66
+ if (Array.isArray(value)) {
67
+ for (const item of value) {
68
+ if (item !== undefined && item !== null)
69
+ url.searchParams.append(key, String(item));
70
+ }
71
+ } else {
65
72
  url.searchParams.set(key, String(value));
73
+ }
66
74
  }
67
75
  }
68
76
  const headers = { Accept: "application/json", ...this.baseHeaders, ...opts.init?.headers };
@@ -256,17 +264,17 @@ function buildOpenApiDocument(version) {
256
264
  properties: {
257
265
  status: { type: "string" },
258
266
  version: { type: "string" },
259
- mode: { type: "string" },
267
+ backend: { type: "string" },
260
268
  ...extra
261
269
  },
262
- required: ["status", "version", "mode"]
270
+ required: ["status", "version", "backend"]
263
271
  });
264
272
  return {
265
273
  openapi: "3.0.3",
266
274
  info: {
267
275
  title: "ShortlinksApi",
268
276
  version,
269
- description: "Shortlink manager \u2014 custom domains, click tracking, and shortlink CRUD with API-key auth. PURE REMOTE (Amendment A1): reads/writes RDS Postgres directly."
277
+ description: "Shortlink manager \u2014 custom domains, click tracking, and shortlink CRUD with API-key auth. The server data backend (sqlite | postgresql) is selected by the DATABASE_URL environment contract."
270
278
  },
271
279
  servers: [{ url: "/" }],
272
280
  components: {
@@ -355,7 +363,7 @@ function buildOpenApiDocument(version) {
355
363
  "/version": {
356
364
  get: {
357
365
  operationId: "getVersion",
358
- summary: "Service version and mode.",
366
+ summary: "Service version and data backend.",
359
367
  responses: {
360
368
  "200": { content: { "application/json": { schema: { $ref: "#/components/schemas/VersionInfo" } } } }
361
369
  }
@@ -2,20 +2,23 @@
2
2
  * Shortlinks serve HTTP app.
3
3
  *
4
4
  * Surfaces the standard health/ready/version probes plus a versioned `/v1`
5
- * REST API guarded by @hasna/contracts API-key auth. PURE REMOTE (Amendment
6
- * A1): all reads/writes go through the injected Postgres store over the shared
7
- * RDS — there is no sync engine or cache in the service.
5
+ * REST API guarded by @hasna/contracts API-key auth. All reads/writes go
6
+ * through the injected Postgres store there is no sync engine or cache in
7
+ * the service.
8
8
  */
9
9
  import { Hono } from "hono";
10
+ import { type KeyStatusResolver } from "@hasna/contracts/auth";
10
11
  import type { PoolQueryClient } from "../generated/storage-kit/query.js";
11
12
  import { PgShortlinksStore } from "../pg-store.js";
12
13
  export interface ServeAppDeps {
13
14
  client: PoolQueryClient;
14
15
  store: PgShortlinksStore;
15
16
  version: string;
16
- mode: string;
17
+ /** Server data backend label (`sqlite` | `postgresql`) for probe payloads. */
18
+ backend: string;
17
19
  signingSecret: string;
18
- isRevoked?: (kid: string) => boolean | Promise<boolean>;
20
+ /** Lifecycle lookup for presented API keys (wire `store.keyStatus`). */
21
+ keyStatus?: KeyStatusResolver;
19
22
  audit?: (event: unknown) => void;
20
23
  }
21
24
  export declare function createServeApp(deps: ServeAppDeps): Hono;
@@ -1,10 +1,11 @@
1
1
  #!/usr/bin/env bun
2
2
  /**
3
- * `shortlinks-serve` — the cloud HTTP service entrypoint.
3
+ * `shortlinks-serve` — the hosted HTTP service entrypoint.
4
4
  *
5
- * PURE REMOTE (Amendment A1): reads/writes the shared RDS Postgres directly via
6
- * the vendored storage kit. No sync engine, cache, or local database in the
7
- * service.
5
+ * Reads/writes PostgreSQL directly via the vendored storage kit: the server
6
+ * data backend is selected by `HASNA_SHORTLINKS_DATABASE_URL` (present
7
+ * postgresql, absent → the pool factory fails closed). No sync engine, cache,
8
+ * or local database in the service.
8
9
  *
9
10
  * Usage:
10
11
  * shortlinks-serve Run migrations (idempotent) then serve.