@micropage-sh/mcp 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.
Files changed (111) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -0
  3. package/dist/annotations.d.ts +20 -0
  4. package/dist/annotations.js +36 -0
  5. package/dist/annotations.js.map +1 -0
  6. package/dist/client/assets.d.ts +85 -0
  7. package/dist/client/assets.js +473 -0
  8. package/dist/client/assets.js.map +1 -0
  9. package/dist/client/auth-provider.d.ts +24 -0
  10. package/dist/client/auth-provider.js +10 -0
  11. package/dist/client/auth-provider.js.map +1 -0
  12. package/dist/client/builds.d.ts +82 -0
  13. package/dist/client/builds.js +166 -0
  14. package/dist/client/builds.js.map +1 -0
  15. package/dist/client/config.d.ts +18 -0
  16. package/dist/client/config.js +29 -0
  17. package/dist/client/config.js.map +1 -0
  18. package/dist/client/deploy-events.d.ts +98 -0
  19. package/dist/client/deploy-events.js +170 -0
  20. package/dist/client/deploy-events.js.map +1 -0
  21. package/dist/client/deploy-token.d.ts +48 -0
  22. package/dist/client/deploy-token.js +130 -0
  23. package/dist/client/deploy-token.js.map +1 -0
  24. package/dist/client/errors.d.ts +18 -0
  25. package/dist/client/errors.js +21 -0
  26. package/dist/client/errors.js.map +1 -0
  27. package/dist/client/http.d.ts +68 -0
  28. package/dist/client/http.js +191 -0
  29. package/dist/client/http.js.map +1 -0
  30. package/dist/client/jwt.d.ts +13 -0
  31. package/dist/client/jwt.js +23 -0
  32. package/dist/client/jwt.js.map +1 -0
  33. package/dist/client/lock.d.ts +16 -0
  34. package/dist/client/lock.js +67 -0
  35. package/dist/client/lock.js.map +1 -0
  36. package/dist/client/pages.d.ts +47 -0
  37. package/dist/client/pages.js +131 -0
  38. package/dist/client/pages.js.map +1 -0
  39. package/dist/client/posts.d.ts +108 -0
  40. package/dist/client/posts.js +187 -0
  41. package/dist/client/posts.js.map +1 -0
  42. package/dist/client/project-ref.d.ts +68 -0
  43. package/dist/client/project-ref.js +118 -0
  44. package/dist/client/project-ref.js.map +1 -0
  45. package/dist/client/session-store.d.ts +81 -0
  46. package/dist/client/session-store.js +271 -0
  47. package/dist/client/session-store.js.map +1 -0
  48. package/dist/client/submissions.d.ts +59 -0
  49. package/dist/client/submissions.js +111 -0
  50. package/dist/client/submissions.js.map +1 -0
  51. package/dist/client/tier.d.ts +42 -0
  52. package/dist/client/tier.js +76 -0
  53. package/dist/client/tier.js.map +1 -0
  54. package/dist/content/index.d.ts +5 -0
  55. package/dist/content/index.js +28 -0
  56. package/dist/content/index.js.map +1 -0
  57. package/dist/context.d.ts +30 -0
  58. package/dist/context.js +2 -0
  59. package/dist/context.js.map +1 -0
  60. package/dist/guards.d.ts +55 -0
  61. package/dist/guards.js +168 -0
  62. package/dist/guards.js.map +1 -0
  63. package/dist/index.d.ts +2 -0
  64. package/dist/index.js +16 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/progress.d.ts +7 -0
  67. package/dist/progress.js +25 -0
  68. package/dist/progress.js.map +1 -0
  69. package/dist/reference/prompts.d.ts +6 -0
  70. package/dist/reference/prompts.js +110 -0
  71. package/dist/reference/prompts.js.map +1 -0
  72. package/dist/reference/resources.d.ts +2 -0
  73. package/dist/reference/resources.js +41 -0
  74. package/dist/reference/resources.js.map +1 -0
  75. package/dist/reference/tool.d.ts +21 -0
  76. package/dist/reference/tool.js +50 -0
  77. package/dist/reference/tool.js.map +1 -0
  78. package/dist/reference/topics.d.ts +29 -0
  79. package/dist/reference/topics.js +91 -0
  80. package/dist/reference/topics.js.map +1 -0
  81. package/dist/reference.d.ts +9 -0
  82. package/dist/reference.js +20 -0
  83. package/dist/reference.js.map +1 -0
  84. package/dist/server.d.ts +29 -0
  85. package/dist/server.js +75 -0
  86. package/dist/server.js.map +1 -0
  87. package/dist/tools/account.d.ts +34 -0
  88. package/dist/tools/account.js +128 -0
  89. package/dist/tools/account.js.map +1 -0
  90. package/dist/tools/builds.d.ts +95 -0
  91. package/dist/tools/builds.js +403 -0
  92. package/dist/tools/builds.js.map +1 -0
  93. package/dist/tools/files.d.ts +71 -0
  94. package/dist/tools/files.js +205 -0
  95. package/dist/tools/files.js.map +1 -0
  96. package/dist/tools/forms.d.ts +59 -0
  97. package/dist/tools/forms.js +177 -0
  98. package/dist/tools/forms.js.map +1 -0
  99. package/dist/tools/posts.d.ts +191 -0
  100. package/dist/tools/posts.js +600 -0
  101. package/dist/tools/posts.js.map +1 -0
  102. package/dist/tools/projects.d.ts +201 -0
  103. package/dist/tools/projects.js +553 -0
  104. package/dist/tools/projects.js.map +1 -0
  105. package/dist/tools/shared.d.ts +33 -0
  106. package/dist/tools/shared.js +41 -0
  107. package/dist/tools/shared.js.map +1 -0
  108. package/dist/version.d.ts +2 -0
  109. package/dist/version.js +8 -0
  110. package/dist/version.js.map +1 -0
  111. package/package.json +67 -0
@@ -0,0 +1,170 @@
1
+ import { IN_PROGRESS_STATUSES } from "./builds.js";
2
+ import { MicropageError } from "./errors.js";
3
+ import { eq, gt } from "./http.js";
4
+ /** Same set as the CLI's stream (cli/src/supabase.js). */
5
+ export const TERMINAL_DEPLOY_EVENTS = new Set([
6
+ "build.failed",
7
+ "deployment.completed",
8
+ "archive.completed",
9
+ "archive.failed",
10
+ ]);
11
+ /**
12
+ * The events that end a publish. archive.* events belong to the zip export,
13
+ * which runs on the same build, so they must not end a publish wait.
14
+ */
15
+ export const PUBLISH_TERMINAL_EVENTS = new Set(["build.failed", "deployment.completed"]);
16
+ function truncate(str, max = 200) {
17
+ const oneLine = String(str).replace(/\s+/g, " ").trim();
18
+ return oneLine.length > max ? `${oneLine.slice(0, max)}…` : oneLine;
19
+ }
20
+ /** Port of the CLI's formatDeployEventForConsole, so both read the same. */
21
+ export function formatDeployEvent(ev) {
22
+ const eventType = ev.event_type ?? "";
23
+ const payload = ev.payload && typeof ev.payload === "object" && !Array.isArray(ev.payload)
24
+ ? ev.payload
25
+ : null;
26
+ if (eventType === "deployment.domain_wiring" && payload) {
27
+ const host = typeof payload.hostname === "string" ? payload.hostname : "";
28
+ const https = host ? `https://${host}` : "";
29
+ switch (payload.step) {
30
+ case "started":
31
+ return `${eventType}: preparing ${host || "platform hostname"}`;
32
+ case "dns_ok":
33
+ return `${eventType}: DNS CNAME ready (${host})`;
34
+ case "dns_resolve_ok":
35
+ return payload.skipped ? `${eventType}: skipped public DNS wait` : `${eventType}: hostname resolves (${host})`;
36
+ case "attach_ok":
37
+ return `${eventType}: registered on Cloudflare Pages (${host})`;
38
+ case "polling":
39
+ return `${eventType}: Pages status "${typeof payload.pages_status === "string" && payload.pages_status ? payload.pages_status : "…"}" (${host})`;
40
+ case "active":
41
+ return `${eventType}: live — ${https}`;
42
+ case "failed":
43
+ return `${eventType}: failed — ${truncate(payload.error ?? "unknown", 160)}`;
44
+ case "timeout":
45
+ return `${eventType}: still pending after wait (try ${https || "URL"} shortly)`;
46
+ default:
47
+ break;
48
+ }
49
+ }
50
+ const extra = ev.payload ? ` ${truncate(JSON.stringify(ev.payload))}` : "";
51
+ return `${eventType}${extra}`;
52
+ }
53
+ export function toDeployEvent(row) {
54
+ return { id: row.id, type: row.event_type ?? "", message: formatDeployEvent(row), created_at: row.created_at ?? null };
55
+ }
56
+ /** Highest build_deploy_events.id for the build, 0 when none: the cursor taken before publishing. */
57
+ export async function getMaxDeployEventId(http, buildId) {
58
+ const row = await http.selectOne("build_deploy_events", {
59
+ select: "id",
60
+ filters: { build_id: eq(buildId) },
61
+ order: "id.desc",
62
+ });
63
+ const n = Number(row?.id);
64
+ return Number.isFinite(n) ? n : 0;
65
+ }
66
+ /**
67
+ * Highest build_deploy_events.id across the project, 0 when none. Taken
68
+ * before a post change, when the build the server will rebuild is not known
69
+ * yet: event ids are global and polling filters by build, so any later event
70
+ * of whichever build gets rebuilt lands after it.
71
+ */
72
+ export async function getMaxProjectDeployEventId(http, projectId) {
73
+ const row = await http.selectOne("build_deploy_events", {
74
+ select: "id",
75
+ filters: { project_id: eq(projectId) },
76
+ order: "id.desc",
77
+ });
78
+ const n = Number(row?.id);
79
+ return Number.isFinite(n) ? n : 0;
80
+ }
81
+ /** created_at of the build's newest deploy event, null when it has none. */
82
+ export async function getLatestDeployEventAt(http, buildId) {
83
+ const row = await http.selectOne("build_deploy_events", {
84
+ select: "created_at",
85
+ filters: { build_id: eq(buildId) },
86
+ order: "id.desc",
87
+ });
88
+ return row?.created_at ?? null;
89
+ }
90
+ export const EVENTS_PAGE = 100;
91
+ export async function fetchDeployEventsAfter(http, buildId, afterId) {
92
+ return http.select("build_deploy_events", {
93
+ select: "id,event_type,payload,created_at",
94
+ filters: { build_id: eq(buildId), id: gt(afterId) },
95
+ order: "id.asc",
96
+ limit: EVENTS_PAGE,
97
+ });
98
+ }
99
+ export const realClock = {
100
+ now: () => Date.now(),
101
+ sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
102
+ };
103
+ export const POLL_INTERVAL_MS = 2_000;
104
+ /**
105
+ * Polls builds.status and build_deploy_events (id > cursor) until the deploy
106
+ * ends (see PollOptions.trustEvents) or waitMs runs out. Always polls at
107
+ * least once, so waitMs 0 is a single snapshot. Never sleeps past the
108
+ * deadline and does not start a poll it would have to finish after it.
109
+ */
110
+ export async function pollDeployStatus(options) {
111
+ const { http, projectId, buildId } = options;
112
+ const clock = options.clock ?? realClock;
113
+ const interval = options.intervalMs ?? POLL_INTERVAL_MS;
114
+ const cursorMode = options.trustEvents !== false;
115
+ const start = clock.now();
116
+ const deadline = start + Math.max(0, options.waitMs);
117
+ let cursor = options.afterId;
118
+ const events = [];
119
+ let terminal = null;
120
+ let sawInProgress = false;
121
+ for (;;) {
122
+ // Status before events: the publisher writes the status first, so the
123
+ // event that goes with a terminal status is normally already visible.
124
+ const build = await http.selectOne("builds", {
125
+ select: "id,number,status,failure_reason,updated_at",
126
+ filters: { id: eq(buildId), project_id: eq(projectId) },
127
+ });
128
+ if (!build) {
129
+ throw new MicropageError("BUILD_NOT_FOUND", `Build id ${buildId} is not in this project. Call list_builds to see its builds.`);
130
+ }
131
+ const rows = await fetchDeployEventsAfter(http, buildId, cursor);
132
+ const fresh = rows.map(toDeployEvent);
133
+ for (const ev of fresh)
134
+ cursor = Math.max(cursor, ev.id);
135
+ events.push(...fresh);
136
+ const inProgress = IN_PROGRESS_STATUSES.has(build.status ?? "");
137
+ if (cursorMode) {
138
+ terminal ??= fresh.find((e) => PUBLISH_TERMINAL_EVENTS.has(e.type)) ?? null;
139
+ }
140
+ const settledByStatus = !inProgress && (!cursorMode || sawInProgress);
141
+ if (inProgress)
142
+ sawInProgress = true;
143
+ const done = terminal !== null || settledByStatus;
144
+ if (options.onPoll) {
145
+ try {
146
+ await options.onPoll({ elapsedMs: clock.now() - start, status: build.status, newEvents: fresh });
147
+ }
148
+ catch {
149
+ // progress is best effort
150
+ }
151
+ }
152
+ const now = clock.now();
153
+ // A full page means more events are waiting: drain them while time allows.
154
+ const more = rows.length >= EVENTS_PAGE && now < deadline;
155
+ if (!more && (done || deadline - now <= interval)) {
156
+ return {
157
+ build,
158
+ events,
159
+ after_event_id: cursor,
160
+ done,
161
+ terminal_event: terminal,
162
+ timed_out: !done,
163
+ waiting_for_start: cursorMode && !done && !inProgress,
164
+ };
165
+ }
166
+ if (!more)
167
+ await clock.sleep(interval);
168
+ }
169
+ }
170
+ //# sourceMappingURL=deploy-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy-events.js","sourceRoot":"","sources":["../../src/client/deploy-events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import type { AuthProvider } from "./auth-provider.js";
2
+ import type { MicropageConfig } from "./config.js";
3
+ import type { FetchLike } from "./http.js";
4
+ /** TTL requested from exchange-deploy-token (the function clamps to 60-3600 s). */
5
+ export declare const DEPLOY_TOKEN_TTL_SECONDS = 1800;
6
+ export interface DeployTokenEnv {
7
+ token: string;
8
+ projectUuid: string;
9
+ }
10
+ /**
11
+ * MICROPAGE_DEPLOY_TOKEN + MICROPAGE_DEPLOY_PROJECT, or null when neither is
12
+ * set. Exactly one set, or a project that is not a uuid, is a config mistake
13
+ * the user must fix, so it throws rather than silently falling back to the
14
+ * CLI session (which would act with broader access than they configured).
15
+ */
16
+ export declare function readDeployTokenEnv(env?: NodeJS.ProcessEnv): DeployTokenEnv | null;
17
+ export interface DeployTokenAuthOptions extends DeployTokenEnv {
18
+ config: Pick<MicropageConfig, "supabaseUrl" | "supabaseAnonKey">;
19
+ fetch?: FetchLike;
20
+ now?: () => number;
21
+ ttlSeconds?: number;
22
+ timeoutMs?: number;
23
+ }
24
+ /**
25
+ * Exchanges a project deploy token for a short-lived owner JWT
26
+ * (supabase/functions/exchange-deploy-token), re-exchanging shortly before it
27
+ * expires. The JWT is a full owner token server-side; the pin to one project
28
+ * is enforced client-side (project-ref + guards).
29
+ */
30
+ export declare class DeployTokenAuthProvider implements AuthProvider {
31
+ readonly mode: "deploy_token";
32
+ readonly pinnedProjectUuid: string;
33
+ /** Internal numeric id of the pinned project, known after the first exchange. */
34
+ projectId: number | undefined;
35
+ private readonly token;
36
+ private readonly config;
37
+ private readonly fetchImpl;
38
+ private readonly now;
39
+ private readonly ttlSeconds;
40
+ private readonly timeoutMs;
41
+ private cached;
42
+ private inflight;
43
+ constructor(options: DeployTokenAuthOptions);
44
+ getAccessToken(options?: {
45
+ forceRefresh?: boolean;
46
+ }): Promise<string>;
47
+ private exchange;
48
+ }
@@ -0,0 +1,130 @@
1
+ import { VERSION } from "../version.js";
2
+ import { MicropageError } from "./errors.js";
3
+ import { isProjectUuid } from "./project-ref.js";
4
+ /** TTL requested from exchange-deploy-token (the function clamps to 60-3600 s). */
5
+ export const DEPLOY_TOKEN_TTL_SECONDS = 1800;
6
+ /** Re-exchange this long before the minted JWT expires. */
7
+ const REEXCHANGE_SKEW_MS = 60_000;
8
+ /**
9
+ * MICROPAGE_DEPLOY_TOKEN + MICROPAGE_DEPLOY_PROJECT, or null when neither is
10
+ * set. Exactly one set, or a project that is not a uuid, is a config mistake
11
+ * the user must fix, so it throws rather than silently falling back to the
12
+ * CLI session (which would act with broader access than they configured).
13
+ */
14
+ export function readDeployTokenEnv(env = process.env) {
15
+ const token = env.MICROPAGE_DEPLOY_TOKEN?.trim() ?? "";
16
+ const projectUuid = env.MICROPAGE_DEPLOY_PROJECT?.trim() ?? "";
17
+ if (!token && !projectUuid)
18
+ return null;
19
+ if (!token || !projectUuid) {
20
+ const missing = token ? "MICROPAGE_DEPLOY_PROJECT" : "MICROPAGE_DEPLOY_TOKEN";
21
+ const present = token ? "MICROPAGE_DEPLOY_TOKEN" : "MICROPAGE_DEPLOY_PROJECT";
22
+ throw new MicropageError("DEPLOY_TOKEN_CONFIG", `${present} is set but ${missing} is not. Set both (the deploy token and the project's uuid) ` +
23
+ `or neither (to use the \`micropage login\` session).`);
24
+ }
25
+ if (!isProjectUuid(projectUuid)) {
26
+ throw new MicropageError("DEPLOY_TOKEN_CONFIG", `MICROPAGE_DEPLOY_PROJECT must be the project's uuid (e.g. 1b4e28ba-2fa1-11d2-883f-0016d3cca427), got "${projectUuid}".`);
27
+ }
28
+ return { token, projectUuid: projectUuid.toLowerCase() };
29
+ }
30
+ /**
31
+ * Exchanges a project deploy token for a short-lived owner JWT
32
+ * (supabase/functions/exchange-deploy-token), re-exchanging shortly before it
33
+ * expires. The JWT is a full owner token server-side; the pin to one project
34
+ * is enforced client-side (project-ref + guards).
35
+ */
36
+ export class DeployTokenAuthProvider {
37
+ mode = "deploy_token";
38
+ pinnedProjectUuid;
39
+ /** Internal numeric id of the pinned project, known after the first exchange. */
40
+ projectId;
41
+ token;
42
+ config;
43
+ fetchImpl;
44
+ now;
45
+ ttlSeconds;
46
+ timeoutMs;
47
+ cached = null;
48
+ inflight = null;
49
+ constructor(options) {
50
+ this.token = options.token;
51
+ this.pinnedProjectUuid = options.projectUuid.toLowerCase();
52
+ this.config = options.config;
53
+ this.fetchImpl = options.fetch ?? ((input, init) => fetch(input, init));
54
+ this.now = options.now ?? Date.now;
55
+ this.ttlSeconds = options.ttlSeconds ?? DEPLOY_TOKEN_TTL_SECONDS;
56
+ this.timeoutMs = options.timeoutMs ?? 20_000;
57
+ }
58
+ async getAccessToken(options = {}) {
59
+ const cached = this.cached;
60
+ if (!options.forceRefresh && cached && cached.expiresAtMs - REEXCHANGE_SKEW_MS > this.now()) {
61
+ return cached.accessToken;
62
+ }
63
+ this.inflight ??= this.exchange(options.forceRefresh ? cached?.accessToken : undefined).finally(() => {
64
+ this.inflight = null;
65
+ });
66
+ return this.inflight;
67
+ }
68
+ async exchange(rejected) {
69
+ let res;
70
+ try {
71
+ res = await this.fetchImpl(`${this.config.supabaseUrl}/functions/v1/exchange-deploy-token`, {
72
+ method: "POST",
73
+ headers: {
74
+ apikey: this.config.supabaseAnonKey,
75
+ Authorization: `Bearer ${this.token}`,
76
+ "Content-Type": "application/json",
77
+ "User-Agent": `micropage-mcp/${VERSION}`,
78
+ },
79
+ body: JSON.stringify({ projectUuid: this.pinnedProjectUuid, expiresInSeconds: this.ttlSeconds }),
80
+ signal: AbortSignal.timeout(this.timeoutMs),
81
+ });
82
+ }
83
+ catch (err) {
84
+ throw new MicropageError("NETWORK", `Exchanging the deploy token failed before a response arrived (${err instanceof Error ? err.message : String(err)}). Check the network and retry.`, { cause: err });
85
+ }
86
+ const text = await res.text().catch(() => "");
87
+ let data = null;
88
+ try {
89
+ data = text ? JSON.parse(text) : null;
90
+ }
91
+ catch {
92
+ data = null;
93
+ }
94
+ const detail = (typeof data?.error === "string" && data.error) ||
95
+ (typeof data?.message === "string" && data.message) ||
96
+ `HTTP ${res.status}`;
97
+ if (res.status === 401 || res.status === 403) {
98
+ throw new MicropageError("DEPLOY_TOKEN_INVALID", `The deploy token was rejected (${detail}). Ask the user to check MICROPAGE_DEPLOY_TOKEN, or to create a new ` +
99
+ `token in the micropage editor under Settings > Deploy tokens.`, { status: res.status, data });
100
+ }
101
+ if (res.status === 404) {
102
+ throw new MicropageError("DEPLOY_TOKEN_INVALID", `No project with uuid ${this.pinnedProjectUuid} exists (${detail}). Ask the user to check MICROPAGE_DEPLOY_PROJECT.`, { status: 404, data });
103
+ }
104
+ if (!res.ok) {
105
+ throw new MicropageError("HTTP", `Exchanging the deploy token failed (HTTP ${res.status}): ${detail}`, {
106
+ status: res.status,
107
+ data,
108
+ });
109
+ }
110
+ if (typeof data?.access_token !== "string" || !data.access_token) {
111
+ throw new MicropageError("HTTP", "exchange-deploy-token answered without an access_token.", { data });
112
+ }
113
+ if (rejected !== undefined && data.access_token === rejected) {
114
+ // Minted twice in the same second with identical claims: the server
115
+ // rejected a token it would mint again, so retrying cannot help.
116
+ throw new MicropageError("DEPLOY_TOKEN_INVALID", "micropage rejected a freshly exchanged deploy-token session. Ask the user to check the deploy token, then retry.");
117
+ }
118
+ const expiresAtMs = typeof data.expires_at === "number"
119
+ ? data.expires_at * 1000
120
+ : this.now() + (typeof data.expires_in === "number" ? data.expires_in : this.ttlSeconds) * 1000;
121
+ if (typeof data.project_id === "number" || typeof data.project_id === "string") {
122
+ const id = Number(data.project_id);
123
+ if (Number.isFinite(id))
124
+ this.projectId = id;
125
+ }
126
+ this.cached = { accessToken: data.access_token, expiresAtMs };
127
+ return data.access_token;
128
+ }
129
+ }
130
+ //# sourceMappingURL=deploy-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy-token.js","sourceRoot":"","sources":["../../src/client/deploy-token.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export type MicropageErrorCode = "NOT_LOGGED_IN" | "SESSION_EXPIRED" | "HTTP" | "TIMEOUT" | "NETWORK" | "CONFIRM_REQUIRED" | "CONFIRM_INVALID" | "DISABLED" | "NOT_ALLOWED_IN_DEPLOY_TOKEN_MODE" | (string & {});
2
+ export interface MicropageErrorOptions {
3
+ status?: number;
4
+ data?: unknown;
5
+ cause?: unknown;
6
+ }
7
+ /**
8
+ * The one error type the client and guards throw. `message` is written for
9
+ * the model: it says what went wrong and names the call or argument that
10
+ * fixes it, because the model sees nothing else.
11
+ */
12
+ export declare class MicropageError extends Error {
13
+ readonly code: MicropageErrorCode;
14
+ readonly status: number | undefined;
15
+ readonly data: unknown;
16
+ constructor(code: MicropageErrorCode, message: string, options?: MicropageErrorOptions);
17
+ }
18
+ export declare function isMicropageError(err: unknown): err is MicropageError;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The one error type the client and guards throw. `message` is written for
3
+ * the model: it says what went wrong and names the call or argument that
4
+ * fixes it, because the model sees nothing else.
5
+ */
6
+ export class MicropageError extends Error {
7
+ code;
8
+ status;
9
+ data;
10
+ constructor(code, message, options = {}) {
11
+ super(message, options.cause === undefined ? undefined : { cause: options.cause });
12
+ this.name = "MicropageError";
13
+ this.code = code;
14
+ this.status = options.status;
15
+ this.data = options.data;
16
+ }
17
+ }
18
+ export function isMicropageError(err) {
19
+ return err instanceof MicropageError;
20
+ }
21
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/client/errors.ts"],"names":[],"mappings":"AAkBA;;;;GAIG;AACH,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,IAAI,CAAqB;IACzB,MAAM,CAAqB;IAC3B,IAAI,CAAU;IAEvB,YAAY,IAAwB,EAAE,OAAe,EAAE,UAAiC,EAAE;QACxF,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,OAAO,GAAG,YAAY,cAAc,CAAC;AACvC,CAAC"}
@@ -0,0 +1,68 @@
1
+ import type { AuthProvider } from "./auth-provider.js";
2
+ import type { MicropageConfig } from "./config.js";
3
+ export type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
4
+ export interface HttpOptions {
5
+ config: MicropageConfig;
6
+ auth: AuthProvider;
7
+ fetch?: FetchLike;
8
+ timeoutMs?: number;
9
+ userAgent?: string;
10
+ }
11
+ export interface RequestOptions {
12
+ /** JSON-serialised into the request body. */
13
+ body?: unknown;
14
+ /** Sent as-is (uploads). Takes precedence over `body`. */
15
+ rawBody?: NonNullable<RequestInit["body"]>;
16
+ headers?: Record<string, string>;
17
+ /**
18
+ * When false the anon key is sent as the bearer instead of a user token —
19
+ * for endpoints that run before the user is known (deploy-token exchange).
20
+ */
21
+ auth?: boolean;
22
+ }
23
+ /** PostgREST filter expressions keyed by column, e.g. `{ id: eq(42) }`. */
24
+ export type Filters = Record<string, string>;
25
+ export declare const eq: (v: string | number | boolean) => string;
26
+ export declare const neq: (v: string | number | boolean) => string;
27
+ export declare const is: (v: "null" | "true" | "false") => string;
28
+ export declare const inList: (vs: ReadonlyArray<string | number>) => string;
29
+ export declare const gt: (v: string | number) => string;
30
+ export interface SelectOptions {
31
+ select?: string;
32
+ filters?: Filters;
33
+ order?: string;
34
+ limit?: number;
35
+ }
36
+ export declare const DEFAULT_TIMEOUT_MS = 20000;
37
+ /**
38
+ * fetch wrapper for Supabase (PostgREST + edge functions) and the build
39
+ * compiler. Mirrors the CLI's request() (cli/src/supabase.js): apikey header
40
+ * plus a user bearer, and one forced refresh + retry on 401 to cover tokens
41
+ * that expired server-side before the local expiry check caught them.
42
+ */
43
+ export declare class Http {
44
+ readonly config: MicropageConfig;
45
+ readonly auth: AuthProvider;
46
+ private readonly fetchImpl;
47
+ private readonly timeoutMs;
48
+ private readonly userAgent;
49
+ constructor(options: HttpOptions);
50
+ request<T = unknown>(method: string, url: string, options?: RequestOptions): Promise<T>;
51
+ /** The response after auth and the one 401 retry; the caller reads (or cancels) the body. */
52
+ private exchange;
53
+ /**
54
+ * Exact row count from PostgREST's Content-Range (a HEAD with
55
+ * Prefer: count=exact). Selecting rows to count them would stop at the
56
+ * server's max_rows cap and undercount silently.
57
+ */
58
+ count(table: string, filters?: Filters): Promise<number>;
59
+ select<T = unknown>(table: string, options?: SelectOptions): Promise<T[]>;
60
+ selectOne<T = unknown>(table: string, options?: SelectOptions): Promise<T | null>;
61
+ insert<T = unknown>(table: string, rows: object | object[]): Promise<T[]>;
62
+ patch<T = unknown>(table: string, filters: Filters, values: object): Promise<T[]>;
63
+ invoke<T = unknown>(name: string, body?: unknown): Promise<T>;
64
+ invokeGet<T = unknown>(name: string, params?: Record<string, string>): Promise<T>;
65
+ restUrl(table: string, params?: URLSearchParams): string;
66
+ functionUrl(name: string): string;
67
+ private send;
68
+ }