stellar-drive 1.0.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/README.md +607 -0
- package/dist/actions/remoteChange.d.ts +204 -0
- package/dist/actions/remoteChange.d.ts.map +1 -0
- package/dist/actions/remoteChange.js +424 -0
- package/dist/actions/remoteChange.js.map +1 -0
- package/dist/actions/truncateTooltip.d.ts +56 -0
- package/dist/actions/truncateTooltip.d.ts.map +1 -0
- package/dist/actions/truncateTooltip.js +312 -0
- package/dist/actions/truncateTooltip.js.map +1 -0
- package/dist/auth/crypto.d.ts +41 -0
- package/dist/auth/crypto.d.ts.map +1 -0
- package/dist/auth/crypto.js +50 -0
- package/dist/auth/crypto.js.map +1 -0
- package/dist/auth/deviceVerification.d.ts +283 -0
- package/dist/auth/deviceVerification.d.ts.map +1 -0
- package/dist/auth/deviceVerification.js +575 -0
- package/dist/auth/deviceVerification.js.map +1 -0
- package/dist/auth/displayUtils.d.ts +98 -0
- package/dist/auth/displayUtils.d.ts.map +1 -0
- package/dist/auth/displayUtils.js +145 -0
- package/dist/auth/displayUtils.js.map +1 -0
- package/dist/auth/loginGuard.d.ts +134 -0
- package/dist/auth/loginGuard.d.ts.map +1 -0
- package/dist/auth/loginGuard.js +276 -0
- package/dist/auth/loginGuard.js.map +1 -0
- package/dist/auth/offlineCredentials.d.ts +105 -0
- package/dist/auth/offlineCredentials.d.ts.map +1 -0
- package/dist/auth/offlineCredentials.js +176 -0
- package/dist/auth/offlineCredentials.js.map +1 -0
- package/dist/auth/offlineSession.d.ts +96 -0
- package/dist/auth/offlineSession.d.ts.map +1 -0
- package/dist/auth/offlineSession.js +145 -0
- package/dist/auth/offlineSession.js.map +1 -0
- package/dist/auth/resolveAuthState.d.ts +85 -0
- package/dist/auth/resolveAuthState.d.ts.map +1 -0
- package/dist/auth/resolveAuthState.js +249 -0
- package/dist/auth/resolveAuthState.js.map +1 -0
- package/dist/auth/singleUser.d.ts +498 -0
- package/dist/auth/singleUser.d.ts.map +1 -0
- package/dist/auth/singleUser.js +1282 -0
- package/dist/auth/singleUser.js.map +1 -0
- package/dist/bin/commands.d.ts +14 -0
- package/dist/bin/commands.d.ts.map +1 -0
- package/dist/bin/commands.js +68 -0
- package/dist/bin/commands.js.map +1 -0
- package/dist/bin/install-pwa.d.ts +41 -0
- package/dist/bin/install-pwa.d.ts.map +1 -0
- package/dist/bin/install-pwa.js +4594 -0
- package/dist/bin/install-pwa.js.map +1 -0
- package/dist/config.d.ts +249 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +395 -0
- package/dist/config.js.map +1 -0
- package/dist/conflicts.d.ts +306 -0
- package/dist/conflicts.d.ts.map +1 -0
- package/dist/conflicts.js +807 -0
- package/dist/conflicts.js.map +1 -0
- package/dist/crdt/awareness.d.ts +128 -0
- package/dist/crdt/awareness.d.ts.map +1 -0
- package/dist/crdt/awareness.js +284 -0
- package/dist/crdt/awareness.js.map +1 -0
- package/dist/crdt/channel.d.ts +165 -0
- package/dist/crdt/channel.d.ts.map +1 -0
- package/dist/crdt/channel.js +522 -0
- package/dist/crdt/channel.js.map +1 -0
- package/dist/crdt/config.d.ts +58 -0
- package/dist/crdt/config.d.ts.map +1 -0
- package/dist/crdt/config.js +123 -0
- package/dist/crdt/config.js.map +1 -0
- package/dist/crdt/helpers.d.ts +104 -0
- package/dist/crdt/helpers.d.ts.map +1 -0
- package/dist/crdt/helpers.js +116 -0
- package/dist/crdt/helpers.js.map +1 -0
- package/dist/crdt/offline.d.ts +58 -0
- package/dist/crdt/offline.d.ts.map +1 -0
- package/dist/crdt/offline.js +130 -0
- package/dist/crdt/offline.js.map +1 -0
- package/dist/crdt/persistence.d.ts +65 -0
- package/dist/crdt/persistence.d.ts.map +1 -0
- package/dist/crdt/persistence.js +171 -0
- package/dist/crdt/persistence.js.map +1 -0
- package/dist/crdt/provider.d.ts +109 -0
- package/dist/crdt/provider.d.ts.map +1 -0
- package/dist/crdt/provider.js +543 -0
- package/dist/crdt/provider.js.map +1 -0
- package/dist/crdt/store.d.ts +111 -0
- package/dist/crdt/store.d.ts.map +1 -0
- package/dist/crdt/store.js +158 -0
- package/dist/crdt/store.js.map +1 -0
- package/dist/crdt/types.d.ts +281 -0
- package/dist/crdt/types.d.ts.map +1 -0
- package/dist/crdt/types.js +26 -0
- package/dist/crdt/types.js.map +1 -0
- package/dist/data.d.ts +502 -0
- package/dist/data.d.ts.map +1 -0
- package/dist/data.js +862 -0
- package/dist/data.js.map +1 -0
- package/dist/database.d.ts +153 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +325 -0
- package/dist/database.js.map +1 -0
- package/dist/debug.d.ts +87 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +135 -0
- package/dist/debug.js.map +1 -0
- package/dist/demo.d.ts +131 -0
- package/dist/demo.d.ts.map +1 -0
- package/dist/demo.js +168 -0
- package/dist/demo.js.map +1 -0
- package/dist/deviceId.d.ts +47 -0
- package/dist/deviceId.d.ts.map +1 -0
- package/dist/deviceId.js +106 -0
- package/dist/deviceId.js.map +1 -0
- package/dist/diagnostics.d.ts +292 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +378 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/engine.d.ts +230 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +2636 -0
- package/dist/engine.js.map +1 -0
- package/dist/entries/actions.d.ts +16 -0
- package/dist/entries/actions.d.ts.map +1 -0
- package/dist/entries/actions.js +29 -0
- package/dist/entries/actions.js.map +1 -0
- package/dist/entries/auth.d.ts +19 -0
- package/dist/entries/auth.d.ts.map +1 -0
- package/dist/entries/auth.js +50 -0
- package/dist/entries/auth.js.map +1 -0
- package/dist/entries/config.d.ts +15 -0
- package/dist/entries/config.d.ts.map +1 -0
- package/dist/entries/config.js +20 -0
- package/dist/entries/config.js.map +1 -0
- package/dist/entries/crdt.d.ts +32 -0
- package/dist/entries/crdt.d.ts.map +1 -0
- package/dist/entries/crdt.js +52 -0
- package/dist/entries/crdt.js.map +1 -0
- package/dist/entries/kit.d.ts +22 -0
- package/dist/entries/kit.d.ts.map +1 -0
- package/dist/entries/kit.js +58 -0
- package/dist/entries/kit.js.map +1 -0
- package/dist/entries/stores.d.ts +22 -0
- package/dist/entries/stores.d.ts.map +1 -0
- package/dist/entries/stores.js +57 -0
- package/dist/entries/stores.js.map +1 -0
- package/dist/entries/types.d.ts +23 -0
- package/dist/entries/types.d.ts.map +1 -0
- package/dist/entries/types.js +12 -0
- package/dist/entries/types.js.map +1 -0
- package/dist/entries/utils.d.ts +12 -0
- package/dist/entries/utils.d.ts.map +1 -0
- package/dist/entries/utils.js +42 -0
- package/dist/entries/utils.js.map +1 -0
- package/dist/entries/vite.d.ts +20 -0
- package/dist/entries/vite.d.ts.map +1 -0
- package/dist/entries/vite.js +26 -0
- package/dist/entries/vite.js.map +1 -0
- package/dist/index.d.ts +77 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +234 -0
- package/dist/index.js.map +1 -0
- package/dist/kit/auth.d.ts +80 -0
- package/dist/kit/auth.d.ts.map +1 -0
- package/dist/kit/auth.js +75 -0
- package/dist/kit/auth.js.map +1 -0
- package/dist/kit/confirm.d.ts +111 -0
- package/dist/kit/confirm.d.ts.map +1 -0
- package/dist/kit/confirm.js +169 -0
- package/dist/kit/confirm.js.map +1 -0
- package/dist/kit/loads.d.ts +187 -0
- package/dist/kit/loads.d.ts.map +1 -0
- package/dist/kit/loads.js +208 -0
- package/dist/kit/loads.js.map +1 -0
- package/dist/kit/server.d.ts +175 -0
- package/dist/kit/server.d.ts.map +1 -0
- package/dist/kit/server.js +297 -0
- package/dist/kit/server.js.map +1 -0
- package/dist/kit/sw.d.ts +176 -0
- package/dist/kit/sw.d.ts.map +1 -0
- package/dist/kit/sw.js +320 -0
- package/dist/kit/sw.js.map +1 -0
- package/dist/queue.d.ts +306 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +925 -0
- package/dist/queue.js.map +1 -0
- package/dist/realtime.d.ts +280 -0
- package/dist/realtime.d.ts.map +1 -0
- package/dist/realtime.js +1031 -0
- package/dist/realtime.js.map +1 -0
- package/dist/runtime/runtimeConfig.d.ts +110 -0
- package/dist/runtime/runtimeConfig.d.ts.map +1 -0
- package/dist/runtime/runtimeConfig.js +260 -0
- package/dist/runtime/runtimeConfig.js.map +1 -0
- package/dist/schema.d.ts +150 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +891 -0
- package/dist/schema.js.map +1 -0
- package/dist/stores/authState.d.ts +204 -0
- package/dist/stores/authState.d.ts.map +1 -0
- package/dist/stores/authState.js +336 -0
- package/dist/stores/authState.js.map +1 -0
- package/dist/stores/factories.d.ts +140 -0
- package/dist/stores/factories.d.ts.map +1 -0
- package/dist/stores/factories.js +157 -0
- package/dist/stores/factories.js.map +1 -0
- package/dist/stores/network.d.ts +48 -0
- package/dist/stores/network.d.ts.map +1 -0
- package/dist/stores/network.js +261 -0
- package/dist/stores/network.js.map +1 -0
- package/dist/stores/remoteChanges.d.ts +417 -0
- package/dist/stores/remoteChanges.d.ts.map +1 -0
- package/dist/stores/remoteChanges.js +626 -0
- package/dist/stores/remoteChanges.js.map +1 -0
- package/dist/stores/sync.d.ts +165 -0
- package/dist/stores/sync.d.ts.map +1 -0
- package/dist/stores/sync.js +275 -0
- package/dist/stores/sync.js.map +1 -0
- package/dist/supabase/auth.d.ts +219 -0
- package/dist/supabase/auth.d.ts.map +1 -0
- package/dist/supabase/auth.js +459 -0
- package/dist/supabase/auth.js.map +1 -0
- package/dist/supabase/client.d.ts +88 -0
- package/dist/supabase/client.d.ts.map +1 -0
- package/dist/supabase/client.js +313 -0
- package/dist/supabase/client.js.map +1 -0
- package/dist/supabase/validate.d.ts +118 -0
- package/dist/supabase/validate.d.ts.map +1 -0
- package/dist/supabase/validate.js +208 -0
- package/dist/supabase/validate.js.map +1 -0
- package/dist/sw/build/vite-plugin.d.ts +149 -0
- package/dist/sw/build/vite-plugin.d.ts.map +1 -0
- package/dist/sw/build/vite-plugin.js +517 -0
- package/dist/sw/build/vite-plugin.js.map +1 -0
- package/dist/sw/sw.js +664 -0
- package/dist/types.d.ts +363 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +18 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +85 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +156 -0
- package/dist/utils.js.map +1 -0
- package/package.json +117 -0
- package/src/components/DeferredChangesBanner.svelte +477 -0
- package/src/components/DemoBanner.svelte +110 -0
- package/src/components/SyncStatus.svelte +1732 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Server-side API helpers for SvelteKit route handlers.
|
|
3
|
+
*
|
|
4
|
+
* This module extracts reusable backend logic so scaffolded API routes can be
|
|
5
|
+
* thin wrappers around these helpers. It provides three main capabilities:
|
|
6
|
+
*
|
|
7
|
+
* - **Server config reading** — reads Supabase credentials from environment
|
|
8
|
+
* variables at runtime (`getServerConfig`)
|
|
9
|
+
* - **Vercel deployment** — upserts env vars and triggers production
|
|
10
|
+
* redeployments via the Vercel REST API (`deployToVercel`)
|
|
11
|
+
* - **Credential validation** — factory for a SvelteKit POST handler that
|
|
12
|
+
* validates Supabase credentials (`createValidateHandler`)
|
|
13
|
+
*
|
|
14
|
+
* All Vercel API interactions use a create-or-update (upsert) strategy for
|
|
15
|
+
* environment variables, and support both git-based and clone-based
|
|
16
|
+
* redeployment strategies for maximum compatibility.
|
|
17
|
+
*
|
|
18
|
+
* @module kit/server
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* // In /api/config/+server.ts
|
|
23
|
+
* import { getServerConfig } from 'stellar-drive/kit/server';
|
|
24
|
+
* export function GET() {
|
|
25
|
+
* return new Response(JSON.stringify(getServerConfig()));
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @see {@link https://vercel.com/docs/rest-api} for Vercel API reference
|
|
30
|
+
* @see {@link validateSupabaseCredentials} in `supabase/validate.ts`
|
|
31
|
+
*/
|
|
32
|
+
// =============================================================================
|
|
33
|
+
// HELPERS — Vercel API Utilities
|
|
34
|
+
// =============================================================================
|
|
35
|
+
/**
|
|
36
|
+
* Low-level wrapper around the Vercel REST API.
|
|
37
|
+
*
|
|
38
|
+
* Handles authentication headers and JSON body serialization for all
|
|
39
|
+
* Vercel API calls. This is an internal helper — not exported.
|
|
40
|
+
*
|
|
41
|
+
* @param path - The API path (appended to `https://api.vercel.com`).
|
|
42
|
+
* @param token - The Vercel bearer token for authorization.
|
|
43
|
+
* @param method - HTTP method (defaults to `'GET'`).
|
|
44
|
+
* @param body - Optional request body, serialized to JSON.
|
|
45
|
+
*
|
|
46
|
+
* @returns The raw `Response` from the Vercel API.
|
|
47
|
+
*
|
|
48
|
+
* @throws {TypeError} If the `fetch` call itself fails (e.g. network error).
|
|
49
|
+
*/
|
|
50
|
+
async function vercelApi(path, token, method = 'GET', body) {
|
|
51
|
+
return fetch(`https://api.vercel.com${path}`, {
|
|
52
|
+
method,
|
|
53
|
+
headers: {
|
|
54
|
+
Authorization: `Bearer ${token}`,
|
|
55
|
+
'Content-Type': 'application/json'
|
|
56
|
+
},
|
|
57
|
+
body: body ? JSON.stringify(body) : undefined
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Creates or updates a single environment variable on a Vercel project.
|
|
62
|
+
*
|
|
63
|
+
* Implements an upsert strategy:
|
|
64
|
+
* 1. Attempt to create via `POST /v10/projects/:id/env`.
|
|
65
|
+
* 2. If Vercel returns `ENV_ALREADY_EXISTS`, list all env vars to find
|
|
66
|
+
* the existing entry's ID, then patch it with the new value.
|
|
67
|
+
*
|
|
68
|
+
* This two-step approach is necessary because Vercel's create endpoint
|
|
69
|
+
* does not support an "upsert" mode — it always fails if the key exists.
|
|
70
|
+
*
|
|
71
|
+
* @param projectId - The Vercel project ID.
|
|
72
|
+
* @param token - The Vercel bearer token.
|
|
73
|
+
* @param key - The environment variable name to set.
|
|
74
|
+
* @param value - The environment variable value.
|
|
75
|
+
*
|
|
76
|
+
* @throws {Error} If the create fails for a reason other than already-exists,
|
|
77
|
+
* or if the list/patch fallback also fails.
|
|
78
|
+
*/
|
|
79
|
+
async function setEnvVar(projectId, token, key, value) {
|
|
80
|
+
const createRes = await vercelApi(`/v10/projects/${projectId}/env`, token, 'POST', {
|
|
81
|
+
key,
|
|
82
|
+
value,
|
|
83
|
+
target: ['production', 'preview', 'development'],
|
|
84
|
+
type: 'plain'
|
|
85
|
+
});
|
|
86
|
+
if (createRes.ok)
|
|
87
|
+
return;
|
|
88
|
+
const createData = await createRes.json();
|
|
89
|
+
const errorCode = createData.error?.code || '';
|
|
90
|
+
const errorMessage = createData.error?.message || '';
|
|
91
|
+
/* If the variable already exists, fall through to the update path.
|
|
92
|
+
Vercel may report this via error code or message text depending
|
|
93
|
+
on the API version, so we check both. */
|
|
94
|
+
if (errorCode === 'ENV_ALREADY_EXISTS' || errorMessage.includes('already exists')) {
|
|
95
|
+
/* List all env vars to find the existing entry's ID — Vercel requires
|
|
96
|
+
the entry ID for PATCH operations, not the key name. */
|
|
97
|
+
const listRes = await vercelApi(`/v9/projects/${projectId}/env`, token);
|
|
98
|
+
if (!listRes.ok) {
|
|
99
|
+
throw new Error(`Failed to list env vars: ${listRes.statusText}`);
|
|
100
|
+
}
|
|
101
|
+
const listData = await listRes.json();
|
|
102
|
+
const existing = listData.envs?.find((e) => e.key === key);
|
|
103
|
+
if (existing) {
|
|
104
|
+
const updateRes = await vercelApi(`/v9/projects/${projectId}/env/${existing.id}`, token, 'PATCH', { value });
|
|
105
|
+
if (!updateRes.ok) {
|
|
106
|
+
throw new Error(`Failed to update env var ${key}: ${updateRes.statusText}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
/* Edge case: Vercel says the var exists but it's not in the list.
|
|
111
|
+
This can happen with env var scoping issues. */
|
|
112
|
+
throw new Error(`Env var ${key} reported as existing but not found in list`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
throw new Error(`Failed to create env var ${key}: ${createData.error?.message || createRes.statusText}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// =============================================================================
|
|
120
|
+
// PUBLIC API
|
|
121
|
+
// =============================================================================
|
|
122
|
+
/**
|
|
123
|
+
* Reads Supabase configuration from `process.env` at runtime.
|
|
124
|
+
*
|
|
125
|
+
* Checks for the presence of both `PUBLIC_SUPABASE_URL` and
|
|
126
|
+
* `PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY` environment variables.
|
|
127
|
+
* Returns `{ configured: true }` with the values when both exist,
|
|
128
|
+
* or `{ configured: false }` otherwise.
|
|
129
|
+
*
|
|
130
|
+
* This is intended for use in SvelteKit server routes (e.g. `+server.ts`)
|
|
131
|
+
* to report configuration status to the client during the setup flow.
|
|
132
|
+
*
|
|
133
|
+
* @returns The server config status with optional Supabase credentials.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```ts
|
|
137
|
+
* // In /api/config/+server.ts
|
|
138
|
+
* import { getServerConfig } from 'stellar-drive/kit/server';
|
|
139
|
+
* export function GET() {
|
|
140
|
+
* return new Response(JSON.stringify(getServerConfig()), {
|
|
141
|
+
* headers: { 'Content-Type': 'application/json' }
|
|
142
|
+
* });
|
|
143
|
+
* }
|
|
144
|
+
* ```
|
|
145
|
+
*
|
|
146
|
+
* @see {@link ServerConfig} for the return type shape
|
|
147
|
+
*/
|
|
148
|
+
export function getServerConfig() {
|
|
149
|
+
const supabaseUrl = process.env.PUBLIC_SUPABASE_URL || '';
|
|
150
|
+
const supabaseAnonKey = process.env.PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY || '';
|
|
151
|
+
if (supabaseUrl && supabaseAnonKey) {
|
|
152
|
+
return { configured: true, supabaseUrl, supabaseAnonKey };
|
|
153
|
+
}
|
|
154
|
+
return { configured: false };
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Full Vercel deployment flow: upserts Supabase environment variables,
|
|
158
|
+
* then triggers a production redeployment.
|
|
159
|
+
*
|
|
160
|
+
* The deployment uses a two-strategy approach:
|
|
161
|
+
* - **Strategy A (preferred)**: Git-based redeployment using the repo
|
|
162
|
+
* metadata from Vercel's environment (`VERCEL_GIT_REPO_SLUG`, etc.).
|
|
163
|
+
* This triggers a fresh build from the source branch.
|
|
164
|
+
* - **Strategy B (fallback)**: Clone-based redeployment using an existing
|
|
165
|
+
* deployment ID (`VERCEL_DEPLOYMENT_ID` or `VERCEL_URL`). This
|
|
166
|
+
* reuses the last build artifacts with updated env vars.
|
|
167
|
+
*
|
|
168
|
+
* Both strategies target the `production` environment.
|
|
169
|
+
*
|
|
170
|
+
* @param config - The deployment configuration containing Vercel auth
|
|
171
|
+
* credentials, project ID, and Supabase connection values.
|
|
172
|
+
*
|
|
173
|
+
* @returns A result object indicating success/failure with an optional
|
|
174
|
+
* deployment URL or error message.
|
|
175
|
+
*
|
|
176
|
+
* @example
|
|
177
|
+
* ```ts
|
|
178
|
+
* const result = await deployToVercel({
|
|
179
|
+
* vercelToken: 'tok_...',
|
|
180
|
+
* projectId: 'prj_...',
|
|
181
|
+
* supabaseUrl: 'https://abc.supabase.co',
|
|
182
|
+
* supabaseAnonKey: 'eyJ...'
|
|
183
|
+
* });
|
|
184
|
+
* if (!result.success) console.error(result.error);
|
|
185
|
+
* ```
|
|
186
|
+
*
|
|
187
|
+
* @see {@link DeployConfig} for the input configuration shape
|
|
188
|
+
* @see {@link DeployResult} for the return type shape
|
|
189
|
+
* @see {@link setEnvVar} for the upsert strategy used for env vars
|
|
190
|
+
*/
|
|
191
|
+
export async function deployToVercel(config) {
|
|
192
|
+
try {
|
|
193
|
+
// -------------------------------------------------------------------------
|
|
194
|
+
// Phase 1 — Upsert environment variables
|
|
195
|
+
// -------------------------------------------------------------------------
|
|
196
|
+
await setEnvVar(config.projectId, config.vercelToken, 'PUBLIC_SUPABASE_URL', config.supabaseUrl);
|
|
197
|
+
await setEnvVar(config.projectId, config.vercelToken, 'PUBLIC_SUPABASE_PUBLISHABLE_DEFAULT_KEY', config.supabaseAnonKey);
|
|
198
|
+
// -------------------------------------------------------------------------
|
|
199
|
+
// Phase 2 — Trigger production redeployment
|
|
200
|
+
// -------------------------------------------------------------------------
|
|
201
|
+
const deploymentId = process.env.VERCEL_DEPLOYMENT_ID || process.env.VERCEL_URL;
|
|
202
|
+
const gitRepo = process.env.VERCEL_GIT_REPO_SLUG;
|
|
203
|
+
const gitOwner = process.env.VERCEL_GIT_REPO_OWNER;
|
|
204
|
+
const gitRef = process.env.VERCEL_GIT_COMMIT_REF || 'main';
|
|
205
|
+
let deploymentUrl = '';
|
|
206
|
+
/* Strategy A — Git-based redeployment (preferred).
|
|
207
|
+
Uses the connected GitHub repo to trigger a fresh build from source.
|
|
208
|
+
Only available when Vercel has git integration metadata. */
|
|
209
|
+
if (gitRepo && gitOwner) {
|
|
210
|
+
const deployRes = await vercelApi(`/v13/deployments`, config.vercelToken, 'POST', {
|
|
211
|
+
name: config.projectId,
|
|
212
|
+
project: config.projectId,
|
|
213
|
+
target: 'production',
|
|
214
|
+
gitSource: {
|
|
215
|
+
type: 'github',
|
|
216
|
+
repoId: `${gitOwner}/${gitRepo}`,
|
|
217
|
+
ref: gitRef
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
if (deployRes.ok) {
|
|
221
|
+
const deployData = await deployRes.json();
|
|
222
|
+
deploymentUrl = deployData.url || '';
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/* Strategy B — Clone current deployment (fallback).
|
|
226
|
+
Reuses the most recent deployment's build output with the newly
|
|
227
|
+
updated env vars. Used when git metadata is unavailable (e.g.
|
|
228
|
+
manual deploys or Vercel CLI uploads). */
|
|
229
|
+
if (!deploymentUrl && deploymentId) {
|
|
230
|
+
const redeployRes = await vercelApi(`/v13/deployments`, config.vercelToken, 'POST', {
|
|
231
|
+
name: config.projectId,
|
|
232
|
+
project: config.projectId,
|
|
233
|
+
target: 'production',
|
|
234
|
+
deploymentId
|
|
235
|
+
});
|
|
236
|
+
if (redeployRes.ok) {
|
|
237
|
+
const redeployData = await redeployRes.json();
|
|
238
|
+
deploymentUrl = redeployData.url || '';
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return { success: true, deploymentUrl };
|
|
242
|
+
}
|
|
243
|
+
catch (e) {
|
|
244
|
+
const message = e instanceof Error ? e.message : 'Unknown error';
|
|
245
|
+
return { success: false, error: message };
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Factory returning a SvelteKit POST handler that validates Supabase
|
|
250
|
+
* credentials by attempting to connect to the provided Supabase instance.
|
|
251
|
+
*
|
|
252
|
+
* The returned handler:
|
|
253
|
+
* 1. Parses the JSON request body for `supabaseUrl` and `supabaseAnonKey`
|
|
254
|
+
* 2. Validates that both fields are present (returns 400 if not)
|
|
255
|
+
* 3. Delegates to `validateSupabaseCredentials` for the actual check
|
|
256
|
+
* 4. Returns a JSON response with the validation result
|
|
257
|
+
*
|
|
258
|
+
* The `validateSupabaseCredentials` import is dynamic (`await import(...)`)
|
|
259
|
+
* to keep this module's dependency footprint minimal — the validation logic
|
|
260
|
+
* and its Supabase client dependency are only loaded when the endpoint is
|
|
261
|
+
* actually called.
|
|
262
|
+
*
|
|
263
|
+
* @returns An async handler function compatible with SvelteKit's
|
|
264
|
+
* `RequestHandler` signature for POST endpoints.
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* ```ts
|
|
268
|
+
* // In /api/validate-supabase/+server.ts
|
|
269
|
+
* import { createValidateHandler } from 'stellar-drive/kit/server';
|
|
270
|
+
* export const POST = createValidateHandler();
|
|
271
|
+
* ```
|
|
272
|
+
*
|
|
273
|
+
* @see {@link validateSupabaseCredentials} in `supabase/validate.ts`
|
|
274
|
+
*/
|
|
275
|
+
export function createValidateHandler() {
|
|
276
|
+
return async ({ request }) => {
|
|
277
|
+
/* Dynamic import keeps the Supabase client out of the module graph
|
|
278
|
+
until this handler is actually invoked — reduces cold start time
|
|
279
|
+
for routes that don't need validation. */
|
|
280
|
+
const { validateSupabaseCredentials } = await import('../supabase/validate.js');
|
|
281
|
+
try {
|
|
282
|
+
const { supabaseUrl, supabaseAnonKey } = await request.json();
|
|
283
|
+
if (!supabaseUrl || !supabaseAnonKey) {
|
|
284
|
+
return new Response(JSON.stringify({ valid: false, error: 'Supabase URL and Anon Key are required' }), { status: 400, headers: { 'Content-Type': 'application/json' } });
|
|
285
|
+
}
|
|
286
|
+
const result = await validateSupabaseCredentials(supabaseUrl, supabaseAnonKey);
|
|
287
|
+
return new Response(JSON.stringify(result), {
|
|
288
|
+
headers: { 'Content-Type': 'application/json' }
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
catch (e) {
|
|
292
|
+
const message = e instanceof Error ? e.message : 'Unknown error';
|
|
293
|
+
return new Response(JSON.stringify({ valid: false, error: `Could not connect to Supabase: ${message}` }), { headers: { 'Content-Type': 'application/json' } });
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/kit/server.ts"],"names":[],"mappings":"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"}
|
package/dist/kit/sw.d.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Service worker lifecycle helpers.
|
|
3
|
+
*
|
|
4
|
+
* This module extracts SW monitoring and update logic so components and pages
|
|
5
|
+
* can use clean APIs without duplicating browser-specific service worker code.
|
|
6
|
+
* It provides three main functions:
|
|
7
|
+
*
|
|
8
|
+
* - `pollForNewServiceWorker` — active polling for a new SW after a
|
|
9
|
+
* deployment, useful for "checking for updates..." UI flows
|
|
10
|
+
* - `handleSwUpdate` — triggers `SKIP_WAITING` on a waiting SW
|
|
11
|
+
* and reloads the page when the new controller activates
|
|
12
|
+
* - `monitorSwLifecycle` — comprehensive passive monitoring that covers
|
|
13
|
+
* six different detection strategies for maximum reliability across
|
|
14
|
+
* browsers and platforms (including iOS PWA quirks)
|
|
15
|
+
*
|
|
16
|
+
* All functions include SSR guards (`typeof navigator === 'undefined'`) so
|
|
17
|
+
* they can be safely imported in universal (shared) SvelteKit code without
|
|
18
|
+
* causing server-side errors.
|
|
19
|
+
*
|
|
20
|
+
* @module kit/sw
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* // In a Svelte component
|
|
25
|
+
* import { monitorSwLifecycle, handleSwUpdate } from 'stellar-drive/kit/sw';
|
|
26
|
+
*
|
|
27
|
+
* let showBanner = $state(false);
|
|
28
|
+
* const cleanup = monitorSwLifecycle({
|
|
29
|
+
* onUpdateAvailable: () => { showBanner = true; }
|
|
30
|
+
* });
|
|
31
|
+
* // When user clicks "Update Now":
|
|
32
|
+
* await handleSwUpdate();
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API}
|
|
36
|
+
* @see {@link debug} in `debug.ts` for the logging utility used throughout
|
|
37
|
+
*/
|
|
38
|
+
/**
|
|
39
|
+
* Options for `pollForNewServiceWorker`.
|
|
40
|
+
*
|
|
41
|
+
* All fields are optional with sensible defaults for typical deployment
|
|
42
|
+
* detection scenarios.
|
|
43
|
+
*/
|
|
44
|
+
export interface PollOptions {
|
|
45
|
+
/**
|
|
46
|
+
* Polling interval in milliseconds.
|
|
47
|
+
* @default 5000
|
|
48
|
+
*/
|
|
49
|
+
intervalMs?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Maximum number of polling attempts before giving up.
|
|
52
|
+
* With the default interval of 5s and 60 attempts, polling runs for ~5 minutes.
|
|
53
|
+
* @default 60
|
|
54
|
+
*/
|
|
55
|
+
maxAttempts?: number;
|
|
56
|
+
/**
|
|
57
|
+
* Callback invoked when a new service worker is detected in the
|
|
58
|
+
* `waiting` state. Called exactly once, then polling stops automatically.
|
|
59
|
+
*/
|
|
60
|
+
onFound?: () => void;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Callbacks for `monitorSwLifecycle`.
|
|
64
|
+
*
|
|
65
|
+
* Provides hooks into the service worker lifecycle events that the
|
|
66
|
+
* monitoring system detects.
|
|
67
|
+
*/
|
|
68
|
+
export interface SwLifecycleCallbacks {
|
|
69
|
+
/**
|
|
70
|
+
* Called whenever an update-available condition is detected through
|
|
71
|
+
* any of the six monitoring strategies. May be called multiple times
|
|
72
|
+
* if different strategies detect the same update independently.
|
|
73
|
+
*/
|
|
74
|
+
onUpdateAvailable: () => void;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Polls `registration.update()` until a new service worker is detected
|
|
78
|
+
* in the `waiting` state. Useful after triggering a deployment to detect
|
|
79
|
+
* when the new build is live and ready to activate.
|
|
80
|
+
*
|
|
81
|
+
* The polling loop calls `registration.update()` on each tick, which
|
|
82
|
+
* forces the browser to check the server for a new SW script. When a
|
|
83
|
+
* waiting worker is found, the `onFound` callback fires and polling
|
|
84
|
+
* stops automatically.
|
|
85
|
+
*
|
|
86
|
+
* @param options - Optional configuration for interval, max attempts,
|
|
87
|
+
* and the detection callback.
|
|
88
|
+
*
|
|
89
|
+
* @returns A cleanup function that stops polling when called. Useful
|
|
90
|
+
* for cleanup in Svelte's `onDestroy` or `$effect` teardown.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* const stopPolling = pollForNewServiceWorker({
|
|
95
|
+
* intervalMs: 3000,
|
|
96
|
+
* maxAttempts: 100,
|
|
97
|
+
* onFound: () => showUpdateBanner()
|
|
98
|
+
* });
|
|
99
|
+
*
|
|
100
|
+
* // Later, to stop polling early:
|
|
101
|
+
* stopPolling();
|
|
102
|
+
* ```
|
|
103
|
+
*
|
|
104
|
+
* @see {@link handleSwUpdate} for activating the waiting SW once found
|
|
105
|
+
*/
|
|
106
|
+
export declare function pollForNewServiceWorker(options?: PollOptions): () => void;
|
|
107
|
+
/**
|
|
108
|
+
* Sends `SKIP_WAITING` to the waiting service worker, listens for the
|
|
109
|
+
* `controllerchange` event, then reloads the page to activate the new
|
|
110
|
+
* version.
|
|
111
|
+
*
|
|
112
|
+
* If no waiting worker is found (e.g. the update was already applied),
|
|
113
|
+
* falls back to a simple page reload. The `{ once: true }` listener
|
|
114
|
+
* option acts as a double-reload guard — the handler fires exactly once
|
|
115
|
+
* even if `controllerchange` is emitted multiple times during activation.
|
|
116
|
+
*
|
|
117
|
+
* @returns A promise that resolves just before the page reloads.
|
|
118
|
+
* In practice, the caller won't observe the resolution since
|
|
119
|
+
* `window.location.reload()` interrupts execution.
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```ts
|
|
123
|
+
* // In an "Update Now" button handler
|
|
124
|
+
* async function onUpdateClick() {
|
|
125
|
+
* await handleSwUpdate();
|
|
126
|
+
* // Page will have reloaded by this point
|
|
127
|
+
* }
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* @see {@link pollForNewServiceWorker} for detecting when an update is available
|
|
131
|
+
* @see {@link monitorSwLifecycle} for passive update detection
|
|
132
|
+
*/
|
|
133
|
+
export declare function handleSwUpdate(): Promise<void>;
|
|
134
|
+
/**
|
|
135
|
+
* Comprehensive service worker monitoring covering all detection strategies
|
|
136
|
+
* for maximum reliability across browsers and platforms:
|
|
137
|
+
*
|
|
138
|
+
* 1. **Immediate check** — inspects the current registration for a
|
|
139
|
+
* waiting worker right away
|
|
140
|
+
* 2. **Delayed retries at 1s/3s** — iOS PWA sometimes needs extra time
|
|
141
|
+
* after app launch before the SW registration is fully populated
|
|
142
|
+
* 3. **`SW_INSTALLED` message listener** — listens for a custom message
|
|
143
|
+
* from the SW itself, posted after the `install` event completes
|
|
144
|
+
* 4. **`updatefound` + `statechange` tracking** — monitors the standard
|
|
145
|
+
* SW lifecycle events for newly installing workers
|
|
146
|
+
* 5. **`visibilitychange` re-check** — triggers an update check when the
|
|
147
|
+
* app resumes from the background (critical for iOS PWA resume)
|
|
148
|
+
* 6. **2-minute polling interval** — periodic fallback for long-running
|
|
149
|
+
* sessions where none of the event-based strategies would fire
|
|
150
|
+
*
|
|
151
|
+
* @param callbacks - Object containing the `onUpdateAvailable` callback,
|
|
152
|
+
* which fires whenever any strategy detects a waiting
|
|
153
|
+
* service worker.
|
|
154
|
+
*
|
|
155
|
+
* @returns A cleanup function that removes all event listeners, clears all
|
|
156
|
+
* intervals and timeouts, and stops monitoring. Should be called
|
|
157
|
+
* in Svelte's `onDestroy` or `$effect` teardown to prevent leaks.
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* ```ts
|
|
161
|
+
* // In a Svelte component's $effect
|
|
162
|
+
* $effect(() => {
|
|
163
|
+
* const cleanup = monitorSwLifecycle({
|
|
164
|
+
* onUpdateAvailable: () => {
|
|
165
|
+
* updateAvailable = true;
|
|
166
|
+
* }
|
|
167
|
+
* });
|
|
168
|
+
* return cleanup;
|
|
169
|
+
* });
|
|
170
|
+
* ```
|
|
171
|
+
*
|
|
172
|
+
* @see {@link handleSwUpdate} for activating the detected update
|
|
173
|
+
* @see {@link SwLifecycleCallbacks} for the callback interface
|
|
174
|
+
*/
|
|
175
|
+
export declare function monitorSwLifecycle(callbacks: SwLifecycleCallbacks): () => void;
|
|
176
|
+
//# sourceMappingURL=sw.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sw.d.ts","sourceRoot":"","sources":["../../src/kit/sw.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAQH;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,iBAAiB,EAAE,MAAM,IAAI,CAAC;CAC/B;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,MAAM,IAAI,CAqCzE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAuBpD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAuI9E"}
|