feat: Reinitialize frontend with SvelteKit and TypeScript

- Delete old Vite+Svelte frontend
- Initialize new SvelteKit project with TypeScript
- Configure Tailwind CSS v4 + DaisyUI
- Implement JWT authentication with auto-refresh
- Create login page with form validation (Zod)
- Add protected route guards
- Update Docker configuration for single-stage build
- Add E2E tests with Playwright (6/11 passing)
- Fix Svelte 5 reactivity with $state() runes

Known issues:
- 5 E2E tests failing (timing/async issues)
- Token refresh implementation needs debugging
- Validation error display timing
This commit is contained in:
2026-02-17 16:19:59 -05:00
parent 54df6018f5
commit de2d83092e
28274 changed files with 3816354 additions and 90 deletions

View File

@@ -0,0 +1,183 @@
{
".svelte-kit/generated/server/internal.js": {
"file": "internal.js",
"name": "internal",
"src": ".svelte-kit/generated/server/internal.js",
"isEntry": true,
"imports": [
"_root.js",
"_environment.js",
"_internal.js"
]
},
"_auth.js": {
"file": "chunks/auth.js",
"name": "auth",
"imports": [
"_exports.js"
]
},
"_environment.js": {
"file": "chunks/environment.js",
"name": "environment"
},
"_exports.js": {
"file": "chunks/exports.js",
"name": "exports",
"imports": [
"_root.js"
]
},
"_false.js": {
"file": "chunks/false.js",
"name": "false"
},
"_internal.js": {
"file": "chunks/internal.js",
"name": "internal",
"imports": [
"_root.js",
"_environment.js"
]
},
"_root.js": {
"file": "chunks/root.js",
"name": "root",
"imports": [
"_false.js"
]
},
"_shared.js": {
"file": "chunks/shared.js",
"name": "shared",
"imports": [
"_utils.js"
]
},
"_state.svelte.js": {
"file": "chunks/state.svelte.js",
"name": "state.svelte",
"imports": [
"_root.js",
"_exports.js"
]
},
"_utils.js": {
"file": "chunks/utils.js",
"name": "utils"
},
"node_modules/@sveltejs/kit/src/runtime/app/server/remote/index.js": {
"file": "remote-entry.js",
"name": "remote-entry",
"src": "node_modules/@sveltejs/kit/src/runtime/app/server/remote/index.js",
"isEntry": true,
"imports": [
"_shared.js",
"_false.js",
"_environment.js"
]
},
"node_modules/@sveltejs/kit/src/runtime/components/svelte-5/error.svelte": {
"file": "entries/fallbacks/error.svelte.js",
"name": "entries/fallbacks/error.svelte",
"src": "node_modules/@sveltejs/kit/src/runtime/components/svelte-5/error.svelte",
"isEntry": true,
"imports": [
"_root.js",
"_state.svelte.js",
"_exports.js",
"_utils.js"
]
},
"node_modules/@sveltejs/kit/src/runtime/components/svelte-5/layout.svelte": {
"file": "entries/fallbacks/layout.svelte.js",
"name": "entries/fallbacks/layout.svelte",
"src": "node_modules/@sveltejs/kit/src/runtime/components/svelte-5/layout.svelte",
"isEntry": true
},
"node_modules/@sveltejs/kit/src/runtime/server/index.js": {
"file": "index.js",
"name": "index",
"src": "node_modules/@sveltejs/kit/src/runtime/server/index.js",
"isEntry": true,
"imports": [
"_false.js",
"_environment.js",
"_shared.js",
"_exports.js",
"_utils.js",
"_internal.js"
]
},
"src/routes/+layout.svelte": {
"file": "entries/pages/_layout.svelte.js",
"name": "entries/pages/_layout.svelte",
"src": "src/routes/+layout.svelte",
"isEntry": true,
"imports": [
"_root.js",
"_auth.js",
"_exports.js",
"_utils.js",
"_state.svelte.js"
]
},
"src/routes/+page.svelte": {
"file": "entries/pages/_page.svelte.js",
"name": "entries/pages/_page.svelte",
"src": "src/routes/+page.svelte",
"isEntry": true,
"imports": [
"_exports.js",
"_utils.js",
"_root.js",
"_state.svelte.js",
"_auth.js"
]
},
"src/routes/dashboard/+layout.ts": {
"file": "entries/pages/dashboard/_layout.ts.js",
"name": "entries/pages/dashboard/_layout.ts",
"src": "src/routes/dashboard/+layout.ts",
"isEntry": true,
"imports": [
"_exports.js",
"_utils.js",
"_root.js",
"_state.svelte.js",
"_auth.js"
]
},
"src/routes/dashboard/+page.svelte": {
"file": "entries/pages/dashboard/_page.svelte.js",
"name": "entries/pages/dashboard/_page.svelte",
"src": "src/routes/dashboard/+page.svelte",
"isEntry": true,
"imports": [
"_root.js",
"_auth.js",
"_exports.js",
"_utils.js",
"_state.svelte.js"
]
},
"src/routes/login/+page.svelte": {
"file": "entries/pages/login/_page.svelte.js",
"name": "entries/pages/login/_page.svelte",
"src": "src/routes/login/+page.svelte",
"isEntry": true,
"imports": [
"_root.js",
"_exports.js",
"_utils.js",
"_state.svelte.js",
"_auth.js"
]
},
"src/routes/login/+page.ts": {
"file": "entries/pages/login/_page.ts.js",
"name": "entries/pages/login/_page.ts",
"src": "src/routes/login/+page.ts",
"isEntry": true
}
}

View File

@@ -0,0 +1,37 @@
import { i as derived, w as writable } from "./exports.js";
function createUserStore() {
const { subscribe, set, update } = writable(null);
return {
subscribe,
set,
update,
clear: () => set(null)
};
}
const user = createUserStore();
function createAuthStore() {
const { subscribe, set, update } = writable({
isAuthenticated: false,
isLoading: false,
error: null
});
return {
subscribe,
set,
update,
setLoading: (loading) => update((state) => ({ ...state, isLoading: loading })),
setError: (error) => update((state) => ({ ...state, error })),
clearError: () => update((state) => ({ ...state, error: null })),
setAuthenticated: (authenticated) => update((state) => ({ ...state, isAuthenticated: authenticated }))
};
}
const auth = createAuthStore();
derived(
[user, auth],
([$user, $auth]) => $user !== null && $auth.isAuthenticated
);
derived(user, ($user) => $user?.role || null);
export {
auth as a,
user as u
};

View File

@@ -0,0 +1,34 @@
let base = "";
let assets = base;
const app_dir = "_app";
const relative = true;
const initial = { base, assets };
function override(paths) {
base = paths.base;
assets = paths.assets;
}
function reset() {
base = initial.base;
assets = initial.assets;
}
function set_assets(path) {
assets = initial.assets = path;
}
let prerendering = false;
function set_building() {
}
function set_prerendering() {
prerendering = true;
}
export {
assets as a,
base as b,
app_dir as c,
reset as d,
set_building as e,
set_prerendering as f,
override as o,
prerendering as p,
relative as r,
set_assets as s
};

View File

@@ -0,0 +1,279 @@
import { n as noop, i as safe_not_equal, j as subscribe_to_store, k as run_all } from "./root.js";
const SCHEME = /^[a-z][a-z\d+\-.]+:/i;
const internal = new URL("sveltekit-internal://");
function resolve(base, path) {
if (path[0] === "/" && path[1] === "/") return path;
let url = new URL(base, internal);
url = new URL(path, url);
return url.protocol === internal.protocol ? url.pathname + url.search + url.hash : url.href;
}
function normalize_path(path, trailing_slash) {
if (path === "/" || trailing_slash === "ignore") return path;
if (trailing_slash === "never") {
return path.endsWith("/") ? path.slice(0, -1) : path;
} else if (trailing_slash === "always" && !path.endsWith("/")) {
return path + "/";
}
return path;
}
function decode_pathname(pathname) {
return pathname.split("%25").map(decodeURI).join("%25");
}
function decode_params(params) {
for (const key in params) {
params[key] = decodeURIComponent(params[key]);
}
return params;
}
function make_trackable(url, callback, search_params_callback, allow_hash = false) {
const tracked = new URL(url);
Object.defineProperty(tracked, "searchParams", {
value: new Proxy(tracked.searchParams, {
get(obj, key) {
if (key === "get" || key === "getAll" || key === "has") {
return (param, ...rest) => {
search_params_callback(param);
return obj[key](param, ...rest);
};
}
callback();
const value = Reflect.get(obj, key);
return typeof value === "function" ? value.bind(obj) : value;
}
}),
enumerable: true,
configurable: true
});
const tracked_url_properties = ["href", "pathname", "search", "toString", "toJSON"];
if (allow_hash) tracked_url_properties.push("hash");
for (const property of tracked_url_properties) {
Object.defineProperty(tracked, property, {
get() {
callback();
return url[property];
},
enumerable: true,
configurable: true
});
}
{
tracked[Symbol.for("nodejs.util.inspect.custom")] = (depth, opts, inspect) => {
return inspect(url, opts);
};
tracked.searchParams[Symbol.for("nodejs.util.inspect.custom")] = (depth, opts, inspect) => {
return inspect(url.searchParams, opts);
};
}
if (!allow_hash) {
disable_hash(tracked);
}
return tracked;
}
function disable_hash(url) {
allow_nodejs_console_log(url);
Object.defineProperty(url, "hash", {
get() {
throw new Error(
"Cannot access event.url.hash. Consider using `page.url.hash` inside a component instead"
);
}
});
}
function disable_search(url) {
allow_nodejs_console_log(url);
for (const property of ["search", "searchParams"]) {
Object.defineProperty(url, property, {
get() {
throw new Error(`Cannot access url.${property} on a page with prerendering enabled`);
}
});
}
}
function allow_nodejs_console_log(url) {
{
url[Symbol.for("nodejs.util.inspect.custom")] = (depth, opts, inspect) => {
return inspect(new URL(url), opts);
};
}
}
const subscriber_queue = [];
function readable(value, start) {
return {
subscribe: writable(value, start).subscribe
};
}
function writable(value, start = noop) {
let stop = null;
const subscribers = /* @__PURE__ */ new Set();
function set(new_value) {
if (safe_not_equal(value, new_value)) {
value = new_value;
if (stop) {
const run_queue = !subscriber_queue.length;
for (const subscriber of subscribers) {
subscriber[1]();
subscriber_queue.push(subscriber, value);
}
if (run_queue) {
for (let i = 0; i < subscriber_queue.length; i += 2) {
subscriber_queue[i][0](subscriber_queue[i + 1]);
}
subscriber_queue.length = 0;
}
}
}
}
function update(fn) {
set(fn(
/** @type {T} */
value
));
}
function subscribe(run, invalidate = noop) {
const subscriber = [run, invalidate];
subscribers.add(subscriber);
if (subscribers.size === 1) {
stop = start(set, update) || noop;
}
run(
/** @type {T} */
value
);
return () => {
subscribers.delete(subscriber);
if (subscribers.size === 0 && stop) {
stop();
stop = null;
}
};
}
return { set, update, subscribe };
}
function derived(stores, fn, initial_value) {
const single = !Array.isArray(stores);
const stores_array = single ? [stores] : stores;
if (!stores_array.every(Boolean)) {
throw new Error("derived() expects stores as input, got a falsy value");
}
const auto = fn.length < 2;
return readable(initial_value, (set, update) => {
let started = false;
const values = [];
let pending = 0;
let cleanup = noop;
const sync = () => {
if (pending) {
return;
}
cleanup();
const result = fn(single ? values[0] : values, set, update);
if (auto) {
set(result);
} else {
cleanup = typeof result === "function" ? result : noop;
}
};
const unsubscribers = stores_array.map(
(store, i) => subscribe_to_store(
store,
(value) => {
values[i] = value;
pending &= ~(1 << i);
if (started) {
sync();
}
},
() => {
pending |= 1 << i;
}
)
);
started = true;
sync();
return function stop() {
run_all(unsubscribers);
cleanup();
started = false;
};
});
}
function validator(expected) {
function validate(module, file) {
if (!module) return;
for (const key in module) {
if (key[0] === "_" || expected.has(key)) continue;
const values = [...expected.values()];
const hint = hint_for_supported_files(key, file?.slice(file.lastIndexOf("."))) ?? `valid exports are ${values.join(", ")}, or anything with a '_' prefix`;
throw new Error(`Invalid export '${key}'${file ? ` in ${file}` : ""} (${hint})`);
}
}
return validate;
}
function hint_for_supported_files(key, ext = ".js") {
const supported_files = [];
if (valid_layout_exports.has(key)) {
supported_files.push(`+layout${ext}`);
}
if (valid_page_exports.has(key)) {
supported_files.push(`+page${ext}`);
}
if (valid_layout_server_exports.has(key)) {
supported_files.push(`+layout.server${ext}`);
}
if (valid_page_server_exports.has(key)) {
supported_files.push(`+page.server${ext}`);
}
if (valid_server_exports.has(key)) {
supported_files.push(`+server${ext}`);
}
if (supported_files.length > 0) {
return `'${key}' is a valid export in ${supported_files.slice(0, -1).join(", ")}${supported_files.length > 1 ? " or " : ""}${supported_files.at(-1)}`;
}
}
const valid_layout_exports = /* @__PURE__ */ new Set([
"load",
"prerender",
"csr",
"ssr",
"trailingSlash",
"config"
]);
const valid_page_exports = /* @__PURE__ */ new Set([...valid_layout_exports, "entries"]);
const valid_layout_server_exports = /* @__PURE__ */ new Set([...valid_layout_exports]);
const valid_page_server_exports = /* @__PURE__ */ new Set([...valid_layout_server_exports, "actions", "entries"]);
const valid_server_exports = /* @__PURE__ */ new Set([
"GET",
"POST",
"PATCH",
"PUT",
"DELETE",
"OPTIONS",
"HEAD",
"fallback",
"prerender",
"trailingSlash",
"config",
"entries"
]);
const validate_layout_exports = validator(valid_layout_exports);
const validate_page_exports = validator(valid_page_exports);
const validate_layout_server_exports = validator(valid_layout_server_exports);
const validate_page_server_exports = validator(valid_page_server_exports);
const validate_server_exports = validator(valid_server_exports);
export {
SCHEME as S,
decode_params as a,
validate_layout_exports as b,
validate_page_server_exports as c,
disable_search as d,
validate_page_exports as e,
resolve as f,
decode_pathname as g,
validate_server_exports as h,
derived as i,
make_trackable as m,
normalize_path as n,
readable as r,
validate_layout_server_exports as v,
writable as w
};

View File

@@ -0,0 +1,4 @@
const browser = false;
export {
browser as b
};

View File

@@ -0,0 +1,133 @@
import { r as root } from "./root.js";
import "./environment.js";
let public_env = {};
function set_private_env(environment) {
}
function set_public_env(environment) {
public_env = environment;
}
let read_implementation = null;
function set_read_implementation(fn) {
read_implementation = fn;
}
function set_manifest(_) {
}
const options = {
app_template_contains_nonce: false,
async: false,
csp: { "mode": "auto", "directives": { "upgrade-insecure-requests": false, "block-all-mixed-content": false }, "reportOnly": { "upgrade-insecure-requests": false, "block-all-mixed-content": false } },
csrf_check_origin: true,
csrf_trusted_origins: [],
embedded: false,
env_public_prefix: "PUBLIC_",
env_private_prefix: "",
hash_routing: false,
hooks: null,
// added lazily, via `get_hooks`
preload_strategy: "modulepreload",
root,
service_worker: false,
service_worker_options: void 0,
templates: {
app: ({ head, body, assets, nonce, env }) => '<!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="utf-8" />\n <link rel="icon" href="' + assets + '/favicon.png" />\n <meta name="viewport" content="width=device-width, initial-scale=1" />\n ' + head + '\n </head>\n <body data-sveltekit-preload-data="hover">\n <div style="display: contents">' + body + "</div>\n </body>\n</html>\n",
error: ({ status, message }) => '<!doctype html>\n<html lang="en">\n <head>\n <meta charset="utf-8" />\n <title>' + message + `</title>
<style>
body {
--bg: white;
--fg: #222;
--divider: #ccc;
background: var(--bg);
color: var(--fg);
font-family:
system-ui,
-apple-system,
BlinkMacSystemFont,
'Segoe UI',
Roboto,
Oxygen,
Ubuntu,
Cantarell,
'Open Sans',
'Helvetica Neue',
sans-serif;
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
}
.error {
display: flex;
align-items: center;
max-width: 32rem;
margin: 0 1rem;
}
.status {
font-weight: 200;
font-size: 3rem;
line-height: 1;
position: relative;
top: -0.05rem;
}
.message {
border-left: 1px solid var(--divider);
padding: 0 0 0 1rem;
margin: 0 0 0 1rem;
min-height: 2.5rem;
display: flex;
align-items: center;
}
.message h1 {
font-weight: 400;
font-size: 1em;
margin: 0;
}
@media (prefers-color-scheme: dark) {
body {
--bg: #222;
--fg: #ddd;
--divider: #666;
}
}
</style>
</head>
<body>
<div class="error">
<span class="status">` + status + '</span>\n <div class="message">\n <h1>' + message + "</h1>\n </div>\n </div>\n </body>\n</html>\n"
},
version_hash: "1hqd1fi"
};
async function get_hooks() {
let handle;
let handleFetch;
let handleError;
let handleValidationError;
let init;
let reroute;
let transport;
return {
handle,
handleFetch,
handleError,
handleValidationError,
init,
reroute,
transport
};
}
export {
set_public_env as a,
set_read_implementation as b,
set_manifest as c,
get_hooks as g,
options as o,
public_env as p,
read_implementation as r,
set_private_env as s
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,770 @@
import { json, text } from "@sveltejs/kit";
import { SvelteKitError, HttpError } from "@sveltejs/kit/internal";
import { with_request_store } from "@sveltejs/kit/internal/server";
import * as devalue from "devalue";
import { t as text_decoder, b as base64_encode, c as base64_decode } from "./utils.js";
const SVELTE_KIT_ASSETS = "/_svelte_kit_assets";
const ENDPOINT_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"];
const PAGE_METHODS = ["GET", "POST", "HEAD"];
function set_nested_value(object, path_string, value) {
if (path_string.startsWith("n:")) {
path_string = path_string.slice(2);
value = value === "" ? void 0 : parseFloat(value);
} else if (path_string.startsWith("b:")) {
path_string = path_string.slice(2);
value = value === "on";
}
deep_set(object, split_path(path_string), value);
}
function convert_formdata(data) {
const result = {};
for (let key of data.keys()) {
const is_array = key.endsWith("[]");
let values = data.getAll(key);
if (is_array) key = key.slice(0, -2);
if (values.length > 1 && !is_array) {
throw new Error(`Form cannot contain duplicated keys — "${key}" has ${values.length} values`);
}
values = values.filter(
(entry) => typeof entry === "string" || entry.name !== "" || entry.size > 0
);
if (key.startsWith("n:")) {
key = key.slice(2);
values = values.map((v) => v === "" ? void 0 : parseFloat(
/** @type {string} */
v
));
} else if (key.startsWith("b:")) {
key = key.slice(2);
values = values.map((v) => v === "on");
}
set_nested_value(result, key, is_array ? values : values[0]);
}
return result;
}
const BINARY_FORM_CONTENT_TYPE = "application/x-sveltekit-formdata";
const BINARY_FORM_VERSION = 0;
const HEADER_BYTES = 1 + 4 + 2;
async function deserialize_binary_form(request) {
if (request.headers.get("content-type") !== BINARY_FORM_CONTENT_TYPE) {
const form_data = await request.formData();
return { data: convert_formdata(form_data), meta: {}, form_data };
}
if (!request.body) {
throw deserialize_error("no body");
}
const content_length = parseInt(request.headers.get("content-length") ?? "");
if (Number.isNaN(content_length)) {
throw deserialize_error("invalid Content-Length header");
}
const reader = request.body.getReader();
const chunks = [];
function get_chunk(index) {
if (index in chunks) return chunks[index];
let i = chunks.length;
while (i <= index) {
chunks[i] = reader.read().then((chunk) => chunk.value);
i++;
}
return chunks[index];
}
async function get_buffer(offset, length) {
let start_chunk;
let chunk_start = 0;
let chunk_index;
for (chunk_index = 0; ; chunk_index++) {
const chunk = await get_chunk(chunk_index);
if (!chunk) return null;
const chunk_end = chunk_start + chunk.byteLength;
if (offset >= chunk_start && offset < chunk_end) {
start_chunk = chunk;
break;
}
chunk_start = chunk_end;
}
if (offset + length <= chunk_start + start_chunk.byteLength) {
return start_chunk.subarray(offset - chunk_start, offset + length - chunk_start);
}
const chunks2 = [start_chunk.subarray(offset - chunk_start)];
let cursor = start_chunk.byteLength - offset + chunk_start;
while (cursor < length) {
chunk_index++;
let chunk = await get_chunk(chunk_index);
if (!chunk) return null;
if (chunk.byteLength > length - cursor) {
chunk = chunk.subarray(0, length - cursor);
}
chunks2.push(chunk);
cursor += chunk.byteLength;
}
const buffer = new Uint8Array(length);
cursor = 0;
for (const chunk of chunks2) {
buffer.set(chunk, cursor);
cursor += chunk.byteLength;
}
return buffer;
}
const header = await get_buffer(0, HEADER_BYTES);
if (!header) throw deserialize_error("too short");
if (header[0] !== BINARY_FORM_VERSION) {
throw deserialize_error(`got version ${header[0]}, expected version ${BINARY_FORM_VERSION}`);
}
const header_view = new DataView(header.buffer, header.byteOffset, header.byteLength);
const data_length = header_view.getUint32(1, true);
if (HEADER_BYTES + data_length > content_length) {
throw deserialize_error("data overflow");
}
const file_offsets_length = header_view.getUint16(5, true);
if (HEADER_BYTES + data_length + file_offsets_length > content_length) {
throw deserialize_error("file offset table overflow");
}
const data_buffer = await get_buffer(HEADER_BYTES, data_length);
if (!data_buffer) throw deserialize_error("data too short");
let file_offsets;
let files_start_offset;
if (file_offsets_length > 0) {
const file_offsets_buffer = await get_buffer(HEADER_BYTES + data_length, file_offsets_length);
if (!file_offsets_buffer) throw deserialize_error("file offset table too short");
file_offsets = /** @type {Array<number>} */
JSON.parse(text_decoder.decode(file_offsets_buffer));
files_start_offset = HEADER_BYTES + data_length + file_offsets_length;
}
const [data, meta] = devalue.parse(text_decoder.decode(data_buffer), {
File: ([name, type, size, last_modified, index]) => {
if (files_start_offset + file_offsets[index] + size > content_length) {
throw deserialize_error("file data overflow");
}
return new Proxy(
new LazyFile(
name,
type,
size,
last_modified,
get_chunk,
files_start_offset + file_offsets[index]
),
{
getPrototypeOf() {
return File.prototype;
}
}
);
}
});
void (async () => {
let has_more = true;
while (has_more) {
const chunk = await get_chunk(chunks.length);
has_more = !!chunk;
}
})();
return { data, meta, form_data: null };
}
function deserialize_error(message) {
return new SvelteKitError(400, "Bad Request", `Could not deserialize binary form: ${message}`);
}
class LazyFile {
/** @type {(index: number) => Promise<Uint8Array<ArrayBuffer> | undefined>} */
#get_chunk;
/** @type {number} */
#offset;
/**
* @param {string} name
* @param {string} type
* @param {number} size
* @param {number} last_modified
* @param {(index: number) => Promise<Uint8Array<ArrayBuffer> | undefined>} get_chunk
* @param {number} offset
*/
constructor(name, type, size, last_modified, get_chunk, offset) {
this.name = name;
this.type = type;
this.size = size;
this.lastModified = last_modified;
this.webkitRelativePath = "";
this.#get_chunk = get_chunk;
this.#offset = offset;
this.arrayBuffer = this.arrayBuffer.bind(this);
this.bytes = this.bytes.bind(this);
this.slice = this.slice.bind(this);
this.stream = this.stream.bind(this);
this.text = this.text.bind(this);
}
/** @type {ArrayBuffer | undefined} */
#buffer;
async arrayBuffer() {
this.#buffer ??= await new Response(this.stream()).arrayBuffer();
return this.#buffer;
}
async bytes() {
return new Uint8Array(await this.arrayBuffer());
}
/**
* @param {number=} start
* @param {number=} end
* @param {string=} contentType
*/
slice(start = 0, end = this.size, contentType = this.type) {
if (start < 0) {
start = Math.max(this.size + start, 0);
} else {
start = Math.min(start, this.size);
}
if (end < 0) {
end = Math.max(this.size + end, 0);
} else {
end = Math.min(end, this.size);
}
const size = Math.max(end - start, 0);
const file = new LazyFile(
this.name,
contentType,
size,
this.lastModified,
this.#get_chunk,
this.#offset + start
);
return file;
}
stream() {
let cursor = 0;
let chunk_index = 0;
return new ReadableStream({
start: async (controller) => {
let chunk_start = 0;
let start_chunk = null;
for (chunk_index = 0; ; chunk_index++) {
const chunk = await this.#get_chunk(chunk_index);
if (!chunk) return null;
const chunk_end = chunk_start + chunk.byteLength;
if (this.#offset >= chunk_start && this.#offset < chunk_end) {
start_chunk = chunk;
break;
}
chunk_start = chunk_end;
}
if (this.#offset + this.size <= chunk_start + start_chunk.byteLength) {
controller.enqueue(
start_chunk.subarray(this.#offset - chunk_start, this.#offset + this.size - chunk_start)
);
controller.close();
} else {
controller.enqueue(start_chunk.subarray(this.#offset - chunk_start));
cursor = start_chunk.byteLength - this.#offset + chunk_start;
}
},
pull: async (controller) => {
chunk_index++;
let chunk = await this.#get_chunk(chunk_index);
if (!chunk) {
controller.error("incomplete file data");
controller.close();
return;
}
if (chunk.byteLength > this.size - cursor) {
chunk = chunk.subarray(0, this.size - cursor);
}
controller.enqueue(chunk);
cursor += chunk.byteLength;
if (cursor >= this.size) {
controller.close();
}
}
});
}
async text() {
return text_decoder.decode(await this.arrayBuffer());
}
}
const path_regex = /^[a-zA-Z_$]\w*(\.[a-zA-Z_$]\w*|\[\d+\])*$/;
function split_path(path) {
if (!path_regex.test(path)) {
throw new Error(`Invalid path ${path}`);
}
return path.split(/\.|\[|\]/).filter(Boolean);
}
function check_prototype_pollution(key) {
if (key === "__proto__" || key === "constructor" || key === "prototype") {
throw new Error(
`Invalid key "${key}"`
);
}
}
function deep_set(object, keys, value) {
let current = object;
for (let i = 0; i < keys.length - 1; i += 1) {
const key = keys[i];
check_prototype_pollution(key);
const is_array = /^\d+$/.test(keys[i + 1]);
const exists = Object.hasOwn(current, key);
const inner = current[key];
if (exists && is_array !== Array.isArray(inner)) {
throw new Error(`Invalid array key ${keys[i + 1]}`);
}
if (!exists) {
current[key] = is_array ? [] : {};
}
current = current[key];
}
const final_key = keys[keys.length - 1];
check_prototype_pollution(final_key);
current[final_key] = value;
}
function normalize_issue(issue, server = false) {
const normalized = { name: "", path: [], message: issue.message, server };
if (issue.path !== void 0) {
let name = "";
for (const segment of issue.path) {
const key = (
/** @type {string | number} */
typeof segment === "object" ? segment.key : segment
);
normalized.path.push(key);
if (typeof key === "number") {
name += `[${key}]`;
} else if (typeof key === "string") {
name += name === "" ? key : "." + key;
}
}
normalized.name = name;
}
return normalized;
}
function flatten_issues(issues) {
const result = {};
for (const issue of issues) {
(result.$ ??= []).push(issue);
let name = "";
if (issue.path !== void 0) {
for (const key of issue.path) {
if (typeof key === "number") {
name += `[${key}]`;
} else if (typeof key === "string") {
name += name === "" ? key : "." + key;
}
(result[name] ??= []).push(issue);
}
}
}
return result;
}
function deep_get(object, path) {
let current = object;
for (const key of path) {
if (current == null || typeof current !== "object") {
return current;
}
current = current[key];
}
return current;
}
function create_field_proxy(target, get_input, set_input, get_issues, path = []) {
const get_value = () => {
return deep_get(get_input(), path);
};
return new Proxy(target, {
get(target2, prop) {
if (typeof prop === "symbol") return target2[prop];
if (/^\d+$/.test(prop)) {
return create_field_proxy({}, get_input, set_input, get_issues, [
...path,
parseInt(prop, 10)
]);
}
const key = build_path_string(path);
if (prop === "set") {
const set_func = function(newValue) {
set_input(path, newValue);
return newValue;
};
return create_field_proxy(set_func, get_input, set_input, get_issues, [...path, prop]);
}
if (prop === "value") {
return create_field_proxy(get_value, get_input, set_input, get_issues, [...path, prop]);
}
if (prop === "issues" || prop === "allIssues") {
const issues_func = () => {
const all_issues = get_issues()[key === "" ? "$" : key];
if (prop === "allIssues") {
return all_issues?.map((issue) => ({
path: issue.path,
message: issue.message
}));
}
return all_issues?.filter((issue) => issue.name === key)?.map((issue) => ({
path: issue.path,
message: issue.message
}));
};
return create_field_proxy(issues_func, get_input, set_input, get_issues, [...path, prop]);
}
if (prop === "as") {
const as_func = (type, input_value) => {
const is_array = type === "file multiple" || type === "select multiple" || type === "checkbox" && typeof input_value === "string";
const prefix = type === "number" || type === "range" ? "n:" : type === "checkbox" && !is_array ? "b:" : "";
const base_props = {
name: prefix + key + (is_array ? "[]" : ""),
get "aria-invalid"() {
const issues = get_issues();
return key in issues ? "true" : void 0;
}
};
if (type !== "text" && type !== "select" && type !== "select multiple") {
base_props.type = type === "file multiple" ? "file" : type;
}
if (type === "submit" || type === "hidden") {
return Object.defineProperties(base_props, {
value: { value: input_value, enumerable: true }
});
}
if (type === "select" || type === "select multiple") {
return Object.defineProperties(base_props, {
multiple: { value: is_array, enumerable: true },
value: {
enumerable: true,
get() {
return get_value();
}
}
});
}
if (type === "checkbox" || type === "radio") {
return Object.defineProperties(base_props, {
value: { value: input_value ?? "on", enumerable: true },
checked: {
enumerable: true,
get() {
const value = get_value();
if (type === "radio") {
return value === input_value;
}
if (is_array) {
return (value ?? []).includes(input_value);
}
return value;
}
}
});
}
if (type === "file" || type === "file multiple") {
return Object.defineProperties(base_props, {
multiple: { value: is_array, enumerable: true },
files: {
enumerable: true,
get() {
const value = get_value();
if (value instanceof File) {
if (typeof DataTransfer !== "undefined") {
const fileList = new DataTransfer();
fileList.items.add(value);
return fileList.files;
}
return { 0: value, length: 1 };
}
if (Array.isArray(value) && value.every((f) => f instanceof File)) {
if (typeof DataTransfer !== "undefined") {
const fileList = new DataTransfer();
value.forEach((file) => fileList.items.add(file));
return fileList.files;
}
const fileListLike = { length: value.length };
value.forEach((file, index) => {
fileListLike[index] = file;
});
return fileListLike;
}
return null;
}
}
});
}
return Object.defineProperties(base_props, {
value: {
enumerable: true,
get() {
const value = get_value();
return value != null ? String(value) : "";
}
}
});
};
return create_field_proxy(as_func, get_input, set_input, get_issues, [...path, "as"]);
}
return create_field_proxy({}, get_input, set_input, get_issues, [...path, prop]);
}
});
}
function build_path_string(path) {
let result = "";
for (const segment of path) {
if (typeof segment === "number") {
result += `[${segment}]`;
} else {
result += result === "" ? segment : "." + segment;
}
}
return result;
}
function negotiate(accept, types) {
const parts = [];
accept.split(",").forEach((str, i) => {
const match = /([^/ \t]+)\/([^; \t]+)[ \t]*(?:;[ \t]*q=([0-9.]+))?/.exec(str);
if (match) {
const [, type, subtype, q = "1"] = match;
parts.push({ type, subtype, q: +q, i });
}
});
parts.sort((a, b) => {
if (a.q !== b.q) {
return b.q - a.q;
}
if (a.subtype === "*" !== (b.subtype === "*")) {
return a.subtype === "*" ? 1 : -1;
}
if (a.type === "*" !== (b.type === "*")) {
return a.type === "*" ? 1 : -1;
}
return a.i - b.i;
});
let accepted;
let min_priority = Infinity;
for (const mimetype of types) {
const [type, subtype] = mimetype.split("/");
const priority = parts.findIndex(
(part) => (part.type === type || part.type === "*") && (part.subtype === subtype || part.subtype === "*")
);
if (priority !== -1 && priority < min_priority) {
accepted = mimetype;
min_priority = priority;
}
}
return accepted;
}
function is_content_type(request, ...types) {
const type = request.headers.get("content-type")?.split(";", 1)[0].trim() ?? "";
return types.includes(type.toLowerCase());
}
function is_form_content_type(request) {
return is_content_type(
request,
"application/x-www-form-urlencoded",
"multipart/form-data",
"text/plain",
BINARY_FORM_CONTENT_TYPE
);
}
function coalesce_to_error(err) {
return err instanceof Error || err && /** @type {any} */
err.name && /** @type {any} */
err.message ? (
/** @type {Error} */
err
) : new Error(JSON.stringify(err));
}
function normalize_error(error) {
return (
/** @type {import('../exports/internal/index.js').Redirect | HttpError | SvelteKitError | Error} */
error
);
}
function get_status(error) {
return error instanceof HttpError || error instanceof SvelteKitError ? error.status : 500;
}
function get_message(error) {
return error instanceof SvelteKitError ? error.text : "Internal Error";
}
const escape_html_attr_dict = {
"&": "&amp;",
'"': "&quot;"
// Svelte also escapes < because the escape function could be called inside a `noscript` there
// https://github.com/sveltejs/svelte/security/advisories/GHSA-8266-84wp-wv5c
// However, that doesn't apply in SvelteKit
};
const escape_html_dict = {
"&": "&amp;",
"<": "&lt;"
};
const surrogates = (
// high surrogate without paired low surrogate
"[\\ud800-\\udbff](?![\\udc00-\\udfff])|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\udc00-\\udfff]"
);
const escape_html_attr_regex = new RegExp(
`[${Object.keys(escape_html_attr_dict).join("")}]|` + surrogates,
"g"
);
const escape_html_regex = new RegExp(
`[${Object.keys(escape_html_dict).join("")}]|` + surrogates,
"g"
);
function escape_html(str, is_attr) {
const dict = is_attr ? escape_html_attr_dict : escape_html_dict;
const escaped_str = str.replace(is_attr ? escape_html_attr_regex : escape_html_regex, (match) => {
if (match.length === 2) {
return match;
}
return dict[match] ?? `&#${match.charCodeAt(0)};`;
});
return escaped_str;
}
function method_not_allowed(mod, method) {
return text(`${method} method not allowed`, {
status: 405,
headers: {
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/405
// "The server must generate an Allow header field in a 405 status code response"
allow: allowed_methods(mod).join(", ")
}
});
}
function allowed_methods(mod) {
const allowed = ENDPOINT_METHODS.filter((method) => method in mod);
if ("GET" in mod && !("HEAD" in mod)) {
allowed.push("HEAD");
}
return allowed;
}
function get_global_name(options) {
return `__sveltekit_${options.version_hash}`;
}
function static_error_page(options, status, message) {
let page = options.templates.error({ status, message: escape_html(message) });
return text(page, {
headers: { "content-type": "text/html; charset=utf-8" },
status
});
}
async function handle_fatal_error(event, state, options, error) {
error = error instanceof HttpError ? error : coalesce_to_error(error);
const status = get_status(error);
const body = await handle_error_and_jsonify(event, state, options, error);
const type = negotiate(event.request.headers.get("accept") || "text/html", [
"application/json",
"text/html"
]);
if (event.isDataRequest || type === "application/json") {
return json(body, {
status
});
}
return static_error_page(options, status, body.message);
}
async function handle_error_and_jsonify(event, state, options, error) {
if (error instanceof HttpError) {
return { message: "Unknown Error", ...error.body };
}
const status = get_status(error);
const message = get_message(error);
return await with_request_store(
{ event, state },
() => options.hooks.handleError({ error, event, status, message })
) ?? { message };
}
function redirect_response(status, location) {
const response = new Response(void 0, {
status,
headers: { location }
});
return response;
}
function clarify_devalue_error(event, error) {
if (error.path) {
return `Data returned from \`load\` while rendering ${event.route.id} is not serializable: ${error.message} (${error.path}). If you need to serialize/deserialize custom types, use transport hooks: https://svelte.dev/docs/kit/hooks#Universal-hooks-transport.`;
}
if (error.path === "") {
return `Data returned from \`load\` while rendering ${event.route.id} is not a plain object`;
}
return error.message;
}
function serialize_uses(node) {
const uses = {};
if (node.uses && node.uses.dependencies.size > 0) {
uses.dependencies = Array.from(node.uses.dependencies);
}
if (node.uses && node.uses.search_params.size > 0) {
uses.search_params = Array.from(node.uses.search_params);
}
if (node.uses && node.uses.params.size > 0) {
uses.params = Array.from(node.uses.params);
}
if (node.uses?.parent) uses.parent = 1;
if (node.uses?.route) uses.route = 1;
if (node.uses?.url) uses.url = 1;
return uses;
}
function has_prerendered_path(manifest, pathname) {
return manifest._.prerendered_routes.has(pathname) || pathname.at(-1) === "/" && manifest._.prerendered_routes.has(pathname.slice(0, -1));
}
function format_server_error(status, error, event) {
const formatted_text = `
\x1B[1;31m[${status}] ${event.request.method} ${event.url.pathname}\x1B[0m`;
if (status === 404) {
return formatted_text;
}
return `${formatted_text}
${error.stack}`;
}
function get_node_type(node_id) {
const parts = node_id?.split("/");
const filename = parts?.at(-1);
if (!filename) return "unknown";
const dot_parts = filename.split(".");
return dot_parts.slice(0, -1).join(".");
}
const INVALIDATED_PARAM = "x-sveltekit-invalidated";
const TRAILING_SLASH_PARAM = "x-sveltekit-trailing-slash";
function stringify(data, transport) {
const encoders = Object.fromEntries(Object.entries(transport).map(([k, v]) => [k, v.encode]));
return devalue.stringify(data, encoders);
}
function stringify_remote_arg(value, transport) {
if (value === void 0) return "";
const json_string = stringify(value, transport);
const bytes = new TextEncoder().encode(json_string);
return base64_encode(bytes).replaceAll("=", "").replaceAll("+", "-").replaceAll("/", "_");
}
function parse_remote_arg(string, transport) {
if (!string) return void 0;
const json_string = text_decoder.decode(
// no need to add back `=` characters, atob can handle it
base64_decode(string.replaceAll("-", "+").replaceAll("_", "/"))
);
const decoders = Object.fromEntries(Object.entries(transport).map(([k, v]) => [k, v.decode]));
return devalue.parse(json_string, decoders);
}
function create_remote_key(id, payload) {
return id + "/" + payload;
}
export {
ENDPOINT_METHODS as E,
INVALIDATED_PARAM as I,
PAGE_METHODS as P,
SVELTE_KIT_ASSETS as S,
TRAILING_SLASH_PARAM as T,
normalize_error as a,
get_global_name as b,
clarify_devalue_error as c,
get_node_type as d,
escape_html as e,
create_remote_key as f,
get_status as g,
handle_error_and_jsonify as h,
is_form_content_type as i,
static_error_page as j,
stringify as k,
deserialize_binary_form as l,
method_not_allowed as m,
negotiate as n,
has_prerendered_path as o,
parse_remote_arg as p,
handle_fatal_error as q,
redirect_response as r,
serialize_uses as s,
format_server_error as t,
stringify_remote_arg as u,
flatten_issues as v,
create_field_proxy as w,
normalize_issue as x,
set_nested_value as y,
deep_set as z
};

View File

@@ -0,0 +1,17 @@
import "clsx";
import { n as noop } from "./root.js";
import "./exports.js";
import "@sveltejs/kit/internal/server";
const is_legacy = noop.toString().includes("$$") || /function \w+\(\) \{\}/.test(noop.toString());
if (is_legacy) {
({
data: {},
form: null,
error: null,
params: {},
route: { id: null },
state: {},
status: -1,
url: new URL("https://example.com")
});
}

View File

@@ -0,0 +1,43 @@
const text_encoder = new TextEncoder();
const text_decoder = new TextDecoder();
function get_relative_path(from, to) {
const from_parts = from.split(/[/\\]/);
const to_parts = to.split(/[/\\]/);
from_parts.pop();
while (from_parts[0] === to_parts[0]) {
from_parts.shift();
to_parts.shift();
}
let i = from_parts.length;
while (i--) from_parts[i] = "..";
return from_parts.concat(to_parts).join("/");
}
function base64_encode(bytes) {
if (globalThis.Buffer) {
return globalThis.Buffer.from(bytes).toString("base64");
}
let binary = "";
for (let i = 0; i < bytes.length; i++) {
binary += String.fromCharCode(bytes[i]);
}
return btoa(binary);
}
function base64_decode(encoded) {
if (globalThis.Buffer) {
const buffer = globalThis.Buffer.from(encoded, "base64");
return new Uint8Array(buffer);
}
const binary = atob(encoded);
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
return bytes;
}
export {
text_encoder as a,
base64_encode as b,
base64_decode as c,
get_relative_path as g,
text_decoder as t
};

View File

@@ -0,0 +1,43 @@
import { g as getContext, e as escape_html } from "../../chunks/root.js";
import "clsx";
import "../../chunks/state.svelte.js";
import "@sveltejs/kit/internal";
import { w as writable } from "../../chunks/exports.js";
import "../../chunks/utils.js";
import "@sveltejs/kit/internal/server";
function create_updated_store() {
const { set, subscribe } = writable(false);
{
return {
subscribe,
// eslint-disable-next-line @typescript-eslint/require-await
check: async () => false
};
}
}
const stores = {
updated: /* @__PURE__ */ create_updated_store()
};
({
check: stores.updated.check
});
function context() {
return getContext("__request__");
}
const page$1 = {
get error() {
return context().page.error;
},
get status() {
return context().page.status;
}
};
const page = page$1;
function Error$1($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
$$renderer2.push(`<h1>${escape_html(page.status)}</h1> <p>${escape_html(page.error?.message)}</p>`);
});
}
export {
Error$1 as default
};

View File

@@ -0,0 +1,9 @@
import "clsx";
function Layout($$renderer, $$props) {
let { children } = $$props;
children($$renderer);
$$renderer.push(`<!---->`);
}
export {
Layout as default
};

View File

@@ -0,0 +1,42 @@
import { s as store_get, e as escape_html, u as unsubscribe_stores, a as slot } from "../../chunks/root.js";
import { u as user } from "../../chunks/auth.js";
import "@sveltejs/kit/internal";
import "../../chunks/exports.js";
import "../../chunks/utils.js";
import "clsx";
import "@sveltejs/kit/internal/server";
import "../../chunks/state.svelte.js";
function Navigation($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
var $$store_subs;
$$renderer2.push(`<nav class="navbar bg-base-100 shadow-lg"><div class="flex-1"><a href="/" class="btn btn-ghost normal-case text-xl">Headroom</a></div> <div class="flex-none gap-2">`);
if (store_get($$store_subs ??= {}, "$user", user)) {
$$renderer2.push("<!--[-->");
$$renderer2.push(`<div class="dropdown dropdown-end"><label tabindex="0" class="btn btn-ghost btn-circle avatar"><div class="w-10 rounded-full bg-primary"><span class="text-xl">${escape_html(store_get($$store_subs ??= {}, "$user", user).email?.charAt(0).toUpperCase())}</span></div></label> <ul tabindex="0" class="mt-3 p-2 shadow menu menu-compact dropdown-content bg-base-100 rounded-box w-52"><li><a href="/dashboard" class="justify-between">Dashboard</a></li> `);
if (store_get($$store_subs ??= {}, "$user", user).role === "superuser" || store_get($$store_subs ??= {}, "$user", user).role === "manager") {
$$renderer2.push("<!--[-->");
$$renderer2.push(`<li><a href="/team-members">Team Members</a></li> <li><a href="/projects">Projects</a></li>`);
} else {
$$renderer2.push("<!--[!-->");
}
$$renderer2.push(`<!--]--> <li><a href="/reports">Reports</a></li> <div class="divider"></div> <li><button class="text-error">Logout</button></li></ul></div>`);
} else {
$$renderer2.push("<!--[!-->");
$$renderer2.push(`<a href="/login" class="btn btn-primary btn-sm">Login</a>`);
}
$$renderer2.push(`<!--]--></div></nav>`);
if ($$store_subs) unsubscribe_stores($$store_subs);
});
}
function _layout($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
$$renderer2.push(`<div class="min-h-screen bg-base-200">`);
Navigation($$renderer2);
$$renderer2.push(`<!----> <main class="container mx-auto px-4 py-6"><!--[-->`);
slot($$renderer2, $$props, "default", {});
$$renderer2.push(`<!--]--></main></div>`);
});
}
export {
_layout as default
};

View File

@@ -0,0 +1,16 @@
import "clsx";
import "@sveltejs/kit/internal";
import "../../chunks/exports.js";
import "../../chunks/utils.js";
import "@sveltejs/kit/internal/server";
import "../../chunks/root.js";
import "../../chunks/state.svelte.js";
import "../../chunks/auth.js";
function _page($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
$$renderer2.push(`<div class="flex items-center justify-center min-h-screen"><div class="loading loading-spinner loading-lg text-primary"></div></div>`);
});
}
export {
_page as default
};

View File

@@ -0,0 +1,14 @@
import "clsx";
import "@sveltejs/kit/internal";
import "../../../chunks/exports.js";
import "../../../chunks/utils.js";
import "@sveltejs/kit/internal/server";
import "../../../chunks/root.js";
import "../../../chunks/state.svelte.js";
import "../../../chunks/auth.js";
const load = async () => {
return { authenticated: true };
};
export {
load
};

View File

@@ -0,0 +1,31 @@
import { h as head, s as store_get, e as escape_html, u as unsubscribe_stores } from "../../../chunks/root.js";
import { u as user } from "../../../chunks/auth.js";
import "@sveltejs/kit/internal";
import "../../../chunks/exports.js";
import "../../../chunks/utils.js";
import "clsx";
import "@sveltejs/kit/internal/server";
import "../../../chunks/state.svelte.js";
function _page($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
var $$store_subs;
head("x1i5gj", $$renderer2, ($$renderer3) => {
$$renderer3.title(($$renderer4) => {
$$renderer4.push(`<title>Dashboard - Headroom</title>`);
});
});
$$renderer2.push(`<div class="max-w-4xl mx-auto"><div class="card bg-base-100 shadow-xl"><div class="card-body"><h1 class="card-title text-3xl mb-4">Welcome to Headroom! 👋</h1> `);
if (store_get($$store_subs ??= {}, "$user", user)) {
$$renderer2.push("<!--[-->");
$$renderer2.push(`<div class="alert alert-info mb-4"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-current shrink-0 w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <span>Logged in as ${escape_html(store_get($$store_subs ??= {}, "$user", user).email)} (${escape_html(store_get($$store_subs ??= {}, "$user", user).role)})</span></div>`);
} else {
$$renderer2.push("<!--[!-->");
}
$$renderer2.push(`<!--]--> <p class="text-lg mb-4">You have successfully authenticated. This is a protected dashboard page
that requires a valid JWT token to access.</p> <div class="divider"></div> <h2 class="text-xl font-bold mb-2">Authentication Features Implemented:</h2> <ul class="list-disc list-inside space-y-2 mb-6"><li>✅ JWT Token Authentication</li> <li>✅ Token Auto-refresh on 401</li> <li>✅ Protected Route Guards</li> <li>✅ Form Validation with Zod</li> <li>✅ Role-based Access Control</li> <li>✅ Redis Token Storage</li></ul> <div class="card-actions"><button class="btn btn-error">Logout</button></div></div></div></div>`);
if ($$store_subs) unsubscribe_stores($$store_subs);
});
}
export {
_page as default
};

View File

@@ -0,0 +1,113 @@
import { f as fallback, e as escape_html, b as attr_class, c as attr, d as bind_props, h as head, s as store_get, u as unsubscribe_stores } from "../../../chunks/root.js";
import "@sveltejs/kit/internal";
import "../../../chunks/exports.js";
import "../../../chunks/utils.js";
import "clsx";
import "@sveltejs/kit/internal/server";
import "../../../chunks/state.svelte.js";
import { z } from "zod";
import "ts-deepmerge";
import "@sveltejs/kit";
import "memoize-weak";
import Type from "typebox";
import "zod-v3-to-json-schema";
import { a as auth } from "../../../chunks/auth.js";
var FetchStatus;
(function(FetchStatus2) {
FetchStatus2[FetchStatus2["Idle"] = 0] = "Idle";
FetchStatus2[FetchStatus2["Submitting"] = 1] = "Submitting";
FetchStatus2[FetchStatus2["Delayed"] = 2] = "Delayed";
FetchStatus2[FetchStatus2["Timeout"] = 3] = "Timeout";
})(FetchStatus || (FetchStatus = {}));
let LEGACY_MODE = false;
try {
if (SUPERFORMS_LEGACY)
LEGACY_MODE = true;
} catch {
}
let STORYBOOK_MODE = false;
try {
if (globalThis.STORIES)
STORYBOOK_MODE = true;
} catch {
}
let legacyMode = false;
try {
if (SUPERFORMS_LEGACY)
legacyMode = true;
} catch {
}
class TDate extends Type.Base {
Check(value) {
return value instanceof globalThis.Date;
}
Errors(value) {
return this.Check(value) ? [] : [{ message: "must be Date" }];
}
Create() {
return new globalThis.Date(0);
}
}
function LoginForm($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
let isLoading = fallback($$props["isLoading"], false);
let errorMessage = fallback($$props["errorMessage"], null);
z.object({
email: z.string().min(1, "Email is required").email("Invalid email format"),
password: z.string().min(1, "Password is required")
});
let formData = { email: "", password: "" };
let errors = {};
$$renderer2.push(`<form class="space-y-4">`);
if (errorMessage) {
$$renderer2.push("<!--[-->");
$$renderer2.push(`<div class="alert alert-error" role="alert"><svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 shrink-0 stroke-current" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg> <span>${escape_html(errorMessage)}</span></div>`);
} else {
$$renderer2.push("<!--[!-->");
}
$$renderer2.push(`<!--]--> <div class="form-control"><label class="label" for="email"><span class="label-text">Email</span></label> <input type="email" id="email"${attr_class("input input-bordered w-full", void 0, { "input-error": errors.email })} placeholder="admin@example.com"${attr("value", formData.email)}${attr("disabled", isLoading, true)}${attr("aria-invalid", errors.email ? "true" : "false")}${attr("aria-describedby", errors.email ? "email-error" : void 0)}/> `);
if (errors.email) {
$$renderer2.push("<!--[-->");
$$renderer2.push(`<span id="email-error" class="label-text-alt text-error">${escape_html(errors.email)}</span>`);
} else {
$$renderer2.push("<!--[!-->");
}
$$renderer2.push(`<!--]--></div> <div class="form-control"><label class="label" for="password"><span class="label-text">Password</span></label> <input type="password" id="password"${attr_class("input input-bordered w-full", void 0, { "input-error": errors.password })} placeholder="••••••••"${attr("value", formData.password)}${attr("disabled", isLoading, true)}${attr("aria-invalid", errors.password ? "true" : "false")}${attr("aria-describedby", errors.password ? "password-error" : void 0)}/> `);
if (errors.password) {
$$renderer2.push("<!--[-->");
$$renderer2.push(`<span id="password-error" class="label-text-alt text-error">${escape_html(errors.password)}</span>`);
} else {
$$renderer2.push("<!--[!-->");
}
$$renderer2.push(`<!--]--></div> <button type="submit" class="btn btn-primary w-full"${attr("disabled", isLoading, true)}>`);
if (isLoading) {
$$renderer2.push("<!--[-->");
$$renderer2.push(`<span class="loading loading-spinner loading-sm"></span> Logging in...`);
} else {
$$renderer2.push("<!--[!-->");
$$renderer2.push(`Login`);
}
$$renderer2.push(`<!--]--></button></form>`);
bind_props($$props, { isLoading, errorMessage });
});
}
function _page($$renderer, $$props) {
$$renderer.component(($$renderer2) => {
var $$store_subs;
head("1x05zx6", $$renderer2, ($$renderer3) => {
$$renderer3.title(($$renderer4) => {
$$renderer4.push(`<title>Login - Headroom</title>`);
});
});
$$renderer2.push(`<div class="min-h-screen flex items-center justify-center bg-base-200"><div class="card w-full max-w-md bg-base-100 shadow-xl"><div class="card-body"><h1 class="card-title text-2xl text-center justify-center mb-6">Welcome to Headroom</h1> <p class="text-center text-base-content/70 mb-6">Sign in to access your dashboard</p> `);
LoginForm($$renderer2, {
isLoading: store_get($$store_subs ??= {}, "$auth", auth).isLoading,
errorMessage: store_get($$store_subs ??= {}, "$auth", auth).error
});
$$renderer2.push(`<!----> <div class="divider"></div> <div class="text-center text-sm text-base-content/60"><p>Demo credentials:</p> <p class="font-mono mt-1">admin@example.com / password</p></div></div></div></div>`);
if ($$store_subs) unsubscribe_stores($$store_subs);
});
}
export {
_page as default
};

View File

@@ -0,0 +1,4 @@
const ssr = false;
export {
ssr
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
import "./chunks/root.js";
import { s, e, f } from "./chunks/environment.js";
import { g, o, c, s as s2, a, b } from "./chunks/internal.js";
export {
g as get_hooks,
o as options,
s as set_assets,
e as set_building,
c as set_manifest,
f as set_prerendering,
s2 as set_private_env,
a as set_public_env,
b as set_read_implementation
};

View File

@@ -0,0 +1,56 @@
export const manifest = (() => {
function __memo(fn) {
let value;
return () => value ??= (value = fn());
}
return {
appDir: "_app",
appPath: "_app",
assets: new Set([]),
mimeTypes: {},
_: {
client: {start:"_app/immutable/entry/start.BUON2f-J.js",app:"_app/immutable/entry/app.ClrUt5tN.js",imports:["_app/immutable/entry/start.BUON2f-J.js","_app/immutable/chunks/DBDqKY8A.js","_app/immutable/chunks/CCV2x70u.js","_app/immutable/entry/app.ClrUt5tN.js","_app/immutable/chunks/CCV2x70u.js","_app/immutable/chunks/Bx__7-vK.js","_app/immutable/chunks/pJd4F_Tq.js","_app/immutable/chunks/CC5oASRR.js","_app/immutable/chunks/BG30BmlR.js","_app/immutable/chunks/C62USj72.js","_app/immutable/chunks/JkAhLmb1.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},
nodes: [
__memo(() => import('./nodes/0.js')),
__memo(() => import('./nodes/1.js')),
__memo(() => import('./nodes/2.js')),
__memo(() => import('./nodes/3.js')),
__memo(() => import('./nodes/4.js')),
__memo(() => import('./nodes/5.js'))
],
remotes: {
},
routes: [
{
id: "/",
pattern: /^\/$/,
params: [],
page: { layouts: [0,], errors: [1,], leaf: 3 },
endpoint: null
},
{
id: "/dashboard",
pattern: /^\/dashboard\/?$/,
params: [],
page: { layouts: [0,2,], errors: [1,,], leaf: 4 },
endpoint: null
},
{
id: "/login",
pattern: /^\/login\/?$/,
params: [],
page: { layouts: [0,], errors: [1,], leaf: 5 },
endpoint: null
}
],
prerendered_routes: new Set([]),
matchers: async () => {
return { };
},
server_assets: {}
}
}
})();

View File

@@ -0,0 +1,56 @@
export const manifest = (() => {
function __memo(fn) {
let value;
return () => value ??= (value = fn());
}
return {
appDir: "_app",
appPath: "_app",
assets: new Set([]),
mimeTypes: {},
_: {
client: {start:"_app/immutable/entry/start.BUON2f-J.js",app:"_app/immutable/entry/app.ClrUt5tN.js",imports:["_app/immutable/entry/start.BUON2f-J.js","_app/immutable/chunks/DBDqKY8A.js","_app/immutable/chunks/CCV2x70u.js","_app/immutable/entry/app.ClrUt5tN.js","_app/immutable/chunks/CCV2x70u.js","_app/immutable/chunks/Bx__7-vK.js","_app/immutable/chunks/pJd4F_Tq.js","_app/immutable/chunks/CC5oASRR.js","_app/immutable/chunks/BG30BmlR.js","_app/immutable/chunks/C62USj72.js","_app/immutable/chunks/JkAhLmb1.js"],stylesheets:[],fonts:[],uses_env_dynamic_public:false},
nodes: [
__memo(() => import('./nodes/0.js')),
__memo(() => import('./nodes/1.js')),
__memo(() => import('./nodes/2.js')),
__memo(() => import('./nodes/3.js')),
__memo(() => import('./nodes/4.js')),
__memo(() => import('./nodes/5.js'))
],
remotes: {
},
routes: [
{
id: "/",
pattern: /^\/$/,
params: [],
page: { layouts: [0,], errors: [1,], leaf: 3 },
endpoint: null
},
{
id: "/dashboard",
pattern: /^\/dashboard\/?$/,
params: [],
page: { layouts: [0,2,], errors: [1,,], leaf: 4 },
endpoint: null
},
{
id: "/login",
pattern: /^\/login\/?$/,
params: [],
page: { layouts: [0,], errors: [1,], leaf: 5 },
endpoint: null
}
],
prerendered_routes: new Set([]),
matchers: async () => {
return { };
},
server_assets: {}
}
}
})();

View File

@@ -0,0 +1,8 @@
export const index = 0;
let component_cache;
export const component = async () => component_cache ??= (await import('../entries/pages/_layout.svelte.js')).default;
export const imports = ["_app/immutable/nodes/0.qcGNqz4K.js","_app/immutable/chunks/pJd4F_Tq.js","_app/immutable/chunks/CCV2x70u.js","_app/immutable/chunks/BgHfHpED.js","_app/immutable/chunks/CrZRXG6z.js","_app/immutable/chunks/Bx__7-vK.js","_app/immutable/chunks/CC5oASRR.js","_app/immutable/chunks/BG30BmlR.js","_app/immutable/chunks/JkAhLmb1.js","_app/immutable/chunks/DBDqKY8A.js"];
export const stylesheets = [];
export const fonts = [];

View File

@@ -0,0 +1,8 @@
export const index = 1;
let component_cache;
export const component = async () => component_cache ??= (await import('../entries/fallbacks/error.svelte.js')).default;
export const imports = ["_app/immutable/nodes/1.Do3BgeC5.js","_app/immutable/chunks/pJd4F_Tq.js","_app/immutable/chunks/CCV2x70u.js","_app/immutable/chunks/BgHfHpED.js","_app/immutable/chunks/Bx__7-vK.js","_app/immutable/chunks/DBDqKY8A.js"];
export const stylesheets = [];
export const fonts = [];

View File

@@ -0,0 +1,10 @@
import * as universal from '../entries/pages/dashboard/_layout.ts.js';
export const index = 2;
let component_cache;
export const component = async () => component_cache ??= (await import('../entries/fallbacks/layout.svelte.js')).default;
export { universal };
export const universal_id = "src/routes/dashboard/+layout.ts";
export const imports = ["_app/immutable/nodes/2.xkr5w2RY.js","_app/immutable/chunks/DBDqKY8A.js","_app/immutable/chunks/CCV2x70u.js","_app/immutable/chunks/CrZRXG6z.js","_app/immutable/chunks/pJd4F_Tq.js","_app/immutable/chunks/BG30BmlR.js"];
export const stylesheets = [];
export const fonts = [];

View File

@@ -0,0 +1,8 @@
export const index = 3;
let component_cache;
export const component = async () => component_cache ??= (await import('../entries/pages/_page.svelte.js')).default;
export const imports = ["_app/immutable/nodes/3.Ga_cDZpk.js","_app/immutable/chunks/pJd4F_Tq.js","_app/immutable/chunks/CCV2x70u.js","_app/immutable/chunks/BgHfHpED.js","_app/immutable/chunks/JkAhLmb1.js","_app/immutable/chunks/DBDqKY8A.js","_app/immutable/chunks/CrZRXG6z.js"];
export const stylesheets = [];
export const fonts = [];

View File

@@ -0,0 +1,8 @@
export const index = 4;
let component_cache;
export const component = async () => component_cache ??= (await import('../entries/pages/dashboard/_page.svelte.js')).default;
export const imports = ["_app/immutable/nodes/4.Dd_eVbye.js","_app/immutable/chunks/pJd4F_Tq.js","_app/immutable/chunks/CCV2x70u.js","_app/immutable/chunks/BgHfHpED.js","_app/immutable/chunks/Bx__7-vK.js","_app/immutable/chunks/CC5oASRR.js","_app/immutable/chunks/BG30BmlR.js","_app/immutable/chunks/DhYTxIvM.js","_app/immutable/chunks/JkAhLmb1.js","_app/immutable/chunks/CrZRXG6z.js","_app/immutable/chunks/DBDqKY8A.js"];
export const stylesheets = [];
export const fonts = [];

View File

@@ -0,0 +1,12 @@
export const index = 5;
let component_cache;
export const component = async () => component_cache ??= (await import('../entries/pages/login/_page.svelte.js')).default;
export const universal = {
"ssr": false
};
export const universal_id = "src/routes/login/+page.ts";
export const imports = ["_app/immutable/nodes/5.CW4-UM09.js","_app/immutable/chunks/pJd4F_Tq.js","_app/immutable/chunks/CCV2x70u.js","_app/immutable/chunks/BgHfHpED.js","_app/immutable/chunks/DhYTxIvM.js","_app/immutable/chunks/JkAhLmb1.js","_app/immutable/chunks/DBDqKY8A.js","_app/immutable/chunks/Bx__7-vK.js","_app/immutable/chunks/CC5oASRR.js","_app/immutable/chunks/BG30BmlR.js","_app/immutable/chunks/C62USj72.js","_app/immutable/chunks/CrZRXG6z.js"];
export const stylesheets = [];
export const fonts = [];

View File

@@ -0,0 +1,557 @@
import { get_request_store, with_request_store } from "@sveltejs/kit/internal/server";
import { parse } from "devalue";
import { error, json } from "@sveltejs/kit";
import { u as stringify_remote_arg, v as flatten_issues, w as create_field_proxy, x as normalize_issue, y as set_nested_value, z as deep_set, k as stringify, f as create_remote_key, h as handle_error_and_jsonify } from "./chunks/shared.js";
import { ValidationError, HttpError, SvelteKitError } from "@sveltejs/kit/internal";
import { b as browser } from "./chunks/false.js";
import { b as base, c as app_dir, p as prerendering } from "./chunks/environment.js";
function create_validator(validate_or_fn, maybe_fn) {
if (!maybe_fn) {
return (arg) => {
if (arg !== void 0) {
error(400, "Bad Request");
}
};
}
if (validate_or_fn === "unchecked") {
return (arg) => arg;
}
if ("~standard" in validate_or_fn) {
return async (arg) => {
const { event, state } = get_request_store();
const result = await validate_or_fn["~standard"].validate(arg);
if (result.issues) {
error(
400,
await state.handleValidationError({
issues: result.issues,
event
})
);
}
return result.value;
};
}
throw new Error(
'Invalid validator passed to remote function. Expected "unchecked" or a Standard Schema (https://standardschema.dev)'
);
}
async function get_response(info, arg, state, get_result) {
await 0;
const cache = get_cache(info, state);
return cache[stringify_remote_arg(arg, state.transport)] ??= get_result();
}
function parse_remote_response(data, transport) {
const revivers = {};
for (const key in transport) {
revivers[key] = transport[key].decode;
}
return parse(data, revivers);
}
async function run_remote_function(event, state, allow_cookies, get_input, fn) {
const store = {
event: {
...event,
setHeaders: () => {
throw new Error("setHeaders is not allowed in remote functions");
},
cookies: {
...event.cookies,
set: (name, value, opts) => {
if (!allow_cookies) {
throw new Error("Cannot set cookies in `query` or `prerender` functions");
}
if (opts.path && !opts.path.startsWith("/")) {
throw new Error("Cookies set in remote functions must have an absolute path");
}
return event.cookies.set(name, value, opts);
},
delete: (name, opts) => {
if (!allow_cookies) {
throw new Error("Cannot delete cookies in `query` or `prerender` functions");
}
if (opts.path && !opts.path.startsWith("/")) {
throw new Error("Cookies deleted in remote functions must have an absolute path");
}
return event.cookies.delete(name, opts);
}
}
},
state: {
...state,
is_in_remote_function: true
}
};
const input = await with_request_store(store, get_input);
return with_request_store(store, () => fn(input));
}
function get_cache(info, state = get_request_store().state) {
let cache = state.remote_data?.get(info);
if (cache === void 0) {
cache = {};
(state.remote_data ??= /* @__PURE__ */ new Map()).set(info, cache);
}
return cache;
}
// @__NO_SIDE_EFFECTS__
function command(validate_or_fn, maybe_fn) {
const fn = maybe_fn ?? validate_or_fn;
const validate = create_validator(validate_or_fn, maybe_fn);
const __ = { type: "command", id: "", name: "" };
const wrapper = (arg) => {
const { event, state } = get_request_store();
if (state.is_endpoint_request) {
if (!["POST", "PUT", "PATCH", "DELETE"].includes(event.request.method)) {
throw new Error(
`Cannot call a command (\`${__.name}(${maybe_fn ? "..." : ""})\`) from a ${event.request.method} handler`
);
}
} else if (!event.isRemoteRequest) {
throw new Error(
`Cannot call a command (\`${__.name}(${maybe_fn ? "..." : ""})\`) during server-side rendering`
);
}
state.refreshes ??= {};
const promise = Promise.resolve(
run_remote_function(event, state, true, () => validate(arg), fn)
);
promise.updates = () => {
throw new Error(`Cannot call '${__.name}(...).updates(...)' on the server`);
};
return (
/** @type {ReturnType<RemoteCommand<Input, Output>>} */
promise
);
};
Object.defineProperty(wrapper, "__", { value: __ });
Object.defineProperty(wrapper, "pending", {
get: () => 0
});
return wrapper;
}
// @__NO_SIDE_EFFECTS__
function form(validate_or_fn, maybe_fn) {
const fn = maybe_fn ?? validate_or_fn;
const schema = !maybe_fn || validate_or_fn === "unchecked" ? null : (
/** @type {any} */
validate_or_fn
);
function create_instance(key) {
const instance = {};
instance.method = "POST";
Object.defineProperty(instance, "enhance", {
value: () => {
return { action: instance.action, method: instance.method };
}
});
const __ = {
type: "form",
name: "",
id: "",
fn: async (data, meta, form_data) => {
const output = {};
output.submission = true;
const { event, state } = get_request_store();
const validated = await schema?.["~standard"].validate(data);
if (meta.validate_only) {
return validated?.issues?.map((issue) => normalize_issue(issue, true)) ?? [];
}
if (validated?.issues !== void 0) {
handle_issues(output, validated.issues, form_data);
} else {
if (validated !== void 0) {
data = validated.value;
}
state.refreshes ??= {};
const issue = create_issues();
try {
output.result = await run_remote_function(
event,
state,
true,
() => data,
(data2) => !maybe_fn ? fn() : fn(data2, issue)
);
} catch (e) {
if (e instanceof ValidationError) {
handle_issues(output, e.issues, form_data);
} else {
throw e;
}
}
}
if (!event.isRemoteRequest) {
get_cache(__, state)[""] ??= output;
}
return output;
}
};
Object.defineProperty(instance, "__", { value: __ });
Object.defineProperty(instance, "action", {
get: () => `?/remote=${__.id}`,
enumerable: true
});
Object.defineProperty(instance, "fields", {
get() {
const data = get_cache(__)?.[""];
const issues = flatten_issues(data?.issues ?? []);
return create_field_proxy(
{},
() => data?.input ?? {},
(path, value) => {
if (data?.submission) {
return;
}
const input = path.length === 0 ? value : deep_set(data?.input ?? {}, path.map(String), value);
(get_cache(__)[""] ??= {}).input = input;
},
() => issues
);
}
});
Object.defineProperty(instance, "result", {
get() {
try {
return get_cache(__)?.[""]?.result;
} catch {
return void 0;
}
}
});
Object.defineProperty(instance, "pending", {
get: () => 0
});
Object.defineProperty(instance, "preflight", {
// preflight is a noop on the server
value: () => instance
});
Object.defineProperty(instance, "validate", {
value: () => {
throw new Error("Cannot call validate() on the server");
}
});
if (key == void 0) {
Object.defineProperty(instance, "for", {
/** @type {RemoteForm<any, any>['for']} */
value: (key2) => {
const { state } = get_request_store();
const cache_key = __.id + "|" + JSON.stringify(key2);
let instance2 = (state.form_instances ??= /* @__PURE__ */ new Map()).get(cache_key);
if (!instance2) {
instance2 = create_instance(key2);
instance2.__.id = `${__.id}/${encodeURIComponent(JSON.stringify(key2))}`;
instance2.__.name = __.name;
state.form_instances.set(cache_key, instance2);
}
return instance2;
}
});
}
return instance;
}
return create_instance();
}
function handle_issues(output, issues, form_data) {
output.issues = issues.map((issue) => normalize_issue(issue, true));
if (form_data) {
output.input = {};
for (let key of form_data.keys()) {
if (/^[.\]]?_/.test(key)) continue;
const is_array = key.endsWith("[]");
const values = form_data.getAll(key).filter((value) => typeof value === "string");
if (is_array) key = key.slice(0, -2);
set_nested_value(
/** @type {Record<string, any>} */
output.input,
key,
is_array ? values : values[0]
);
}
}
}
function create_issues() {
return (
/** @type {InvalidField<any>} */
new Proxy(
/** @param {string} message */
(message) => {
if (typeof message !== "string") {
throw new Error(
"`invalid` should now be imported from `@sveltejs/kit` to throw validation issues. The second parameter provided to the form function (renamed to `issue`) is still used to construct issues, e.g. `invalid(issue.field('message'))`. For more info see https://github.com/sveltejs/kit/pulls/14768"
);
}
return create_issue(message);
},
{
get(target, prop) {
if (typeof prop === "symbol") return (
/** @type {any} */
target[prop]
);
return create_issue_proxy(prop, []);
}
}
)
);
function create_issue(message, path = []) {
return {
message,
path
};
}
function create_issue_proxy(key, path) {
const new_path = [...path, key];
const issue_func = (message) => create_issue(message, new_path);
return new Proxy(issue_func, {
get(target, prop) {
if (typeof prop === "symbol") return (
/** @type {any} */
target[prop]
);
if (/^\d+$/.test(prop)) {
return create_issue_proxy(parseInt(prop, 10), new_path);
}
return create_issue_proxy(prop, new_path);
}
});
}
}
// @__NO_SIDE_EFFECTS__
function prerender(validate_or_fn, fn_or_options, maybe_options) {
const maybe_fn = typeof fn_or_options === "function" ? fn_or_options : void 0;
const options = maybe_options ?? (maybe_fn ? void 0 : fn_or_options);
const fn = maybe_fn ?? validate_or_fn;
const validate = create_validator(validate_or_fn, maybe_fn);
const __ = {
type: "prerender",
id: "",
name: "",
has_arg: !!maybe_fn,
inputs: options?.inputs,
dynamic: options?.dynamic
};
const wrapper = (arg) => {
const promise = (async () => {
const { event, state } = get_request_store();
const payload = stringify_remote_arg(arg, state.transport);
const id = __.id;
const url = `${base}/${app_dir}/remote/${id}${payload ? `/${payload}` : ""}`;
if (!state.prerendering && !browser && !event.isRemoteRequest) {
try {
return await get_response(__, arg, state, async () => {
const key = stringify_remote_arg(arg, state.transport);
const cache = get_cache(__, state);
const promise3 = cache[key] ??= fetch(new URL(url, event.url.origin).href).then(
async (response) => {
if (!response.ok) {
throw new Error("Prerendered response not found");
}
const prerendered = await response.json();
if (prerendered.type === "error") {
error(prerendered.status, prerendered.error);
}
return prerendered.result;
}
);
return parse_remote_response(await promise3, state.transport);
});
} catch {
}
}
if (state.prerendering?.remote_responses.has(url)) {
return (
/** @type {Promise<any>} */
state.prerendering.remote_responses.get(url)
);
}
const promise2 = get_response(
__,
arg,
state,
() => run_remote_function(event, state, false, () => validate(arg), fn)
);
if (state.prerendering) {
state.prerendering.remote_responses.set(url, promise2);
}
const result = await promise2;
if (state.prerendering) {
const body = { type: "result", result: stringify(result, state.transport) };
state.prerendering.dependencies.set(url, {
body: JSON.stringify(body),
response: json(body)
});
}
return result;
})();
promise.catch(() => {
});
return (
/** @type {RemoteResource<Output>} */
promise
);
};
Object.defineProperty(wrapper, "__", { value: __ });
return wrapper;
}
// @__NO_SIDE_EFFECTS__
function query(validate_or_fn, maybe_fn) {
const fn = maybe_fn ?? validate_or_fn;
const validate = create_validator(validate_or_fn, maybe_fn);
const __ = { type: "query", id: "", name: "" };
const wrapper = (arg) => {
if (prerendering) {
throw new Error(
`Cannot call query '${__.name}' while prerendering, as prerendered pages need static data. Use 'prerender' from $app/server instead`
);
}
const { event, state } = get_request_store();
const get_remote_function_result = () => run_remote_function(event, state, false, () => validate(arg), fn);
const promise = get_response(__, arg, state, get_remote_function_result);
promise.catch(() => {
});
promise.set = (value) => update_refresh_value(get_refresh_context(__, "set", arg), value);
promise.refresh = () => {
const refresh_context = get_refresh_context(__, "refresh", arg);
const is_immediate_refresh = !refresh_context.cache[refresh_context.cache_key];
const value = is_immediate_refresh ? promise : get_remote_function_result();
return update_refresh_value(refresh_context, value, is_immediate_refresh);
};
promise.withOverride = () => {
throw new Error(`Cannot call '${__.name}.withOverride()' on the server`);
};
return (
/** @type {RemoteQuery<Output>} */
promise
);
};
Object.defineProperty(wrapper, "__", { value: __ });
return wrapper;
}
// @__NO_SIDE_EFFECTS__
function batch(validate_or_fn, maybe_fn) {
const fn = maybe_fn ?? validate_or_fn;
const validate = create_validator(validate_or_fn, maybe_fn);
const __ = {
type: "query_batch",
id: "",
name: "",
run: async (args, options) => {
const { event, state } = get_request_store();
return run_remote_function(
event,
state,
false,
async () => Promise.all(args.map(validate)),
async (input) => {
const get_result = await fn(input);
return Promise.all(
input.map(async (arg, i) => {
try {
return { type: "result", data: get_result(arg, i) };
} catch (error2) {
return {
type: "error",
error: await handle_error_and_jsonify(event, state, options, error2),
status: error2 instanceof HttpError || error2 instanceof SvelteKitError ? error2.status : 500
};
}
})
);
}
);
}
};
let batching = { args: [], resolvers: [] };
const wrapper = (arg) => {
if (prerendering) {
throw new Error(
`Cannot call query.batch '${__.name}' while prerendering, as prerendered pages need static data. Use 'prerender' from $app/server instead`
);
}
const { event, state } = get_request_store();
const get_remote_function_result = () => {
return new Promise((resolve, reject) => {
batching.args.push(arg);
batching.resolvers.push({ resolve, reject });
if (batching.args.length > 1) return;
setTimeout(async () => {
const batched = batching;
batching = { args: [], resolvers: [] };
try {
return await run_remote_function(
event,
state,
false,
async () => Promise.all(batched.args.map(validate)),
async (input) => {
const get_result = await fn(input);
for (let i = 0; i < batched.resolvers.length; i++) {
try {
batched.resolvers[i].resolve(get_result(input[i], i));
} catch (error2) {
batched.resolvers[i].reject(error2);
}
}
}
);
} catch (error2) {
for (const resolver of batched.resolvers) {
resolver.reject(error2);
}
}
}, 0);
});
};
const promise = get_response(__, arg, state, get_remote_function_result);
promise.catch(() => {
});
promise.set = (value) => update_refresh_value(get_refresh_context(__, "set", arg), value);
promise.refresh = () => {
const refresh_context = get_refresh_context(__, "refresh", arg);
const is_immediate_refresh = !refresh_context.cache[refresh_context.cache_key];
const value = is_immediate_refresh ? promise : get_remote_function_result();
return update_refresh_value(refresh_context, value, is_immediate_refresh);
};
promise.withOverride = () => {
throw new Error(`Cannot call '${__.name}.withOverride()' on the server`);
};
return (
/** @type {RemoteQuery<Output>} */
promise
);
};
Object.defineProperty(wrapper, "__", { value: __ });
return wrapper;
}
Object.defineProperty(query, "batch", { value: batch, enumerable: true });
function get_refresh_context(__, action, arg) {
const { state } = get_request_store();
const { refreshes } = state;
if (!refreshes) {
const name = __.type === "query_batch" ? `query.batch '${__.name}'` : `query '${__.name}'`;
throw new Error(
`Cannot call ${action} on ${name} because it is not executed in the context of a command/form remote function`
);
}
const cache = get_cache(__, state);
const cache_key = stringify_remote_arg(arg, state.transport);
const refreshes_key = create_remote_key(__.id, cache_key);
return { __, state, refreshes, refreshes_key, cache, cache_key };
}
function update_refresh_value({ __, refreshes, refreshes_key, cache, cache_key }, value, is_immediate_refresh = false) {
const promise = Promise.resolve(value);
if (!is_immediate_refresh) {
cache[cache_key] = promise;
}
if (__.id) {
refreshes[refreshes_key] = promise;
}
return promise.then(() => {
});
}
export {
command,
form,
prerender,
query
};