mirror of
https://github.com/HeyPuter/puter.git
synced 2026-08-28 08:56:58 +00:00
fix type errors
This commit is contained in:
@@ -244,9 +244,11 @@ export class SubdomainDriver extends PuterDriver {
|
||||
if (object.domain !== undefined)
|
||||
patch.domain = object.domain != null ? String(object.domain) : null;
|
||||
|
||||
const updated = await this.stores.subdomain.update(row.uuid, patch, {
|
||||
userId: row.user_id,
|
||||
});
|
||||
const updated = await this.stores.subdomain.update(
|
||||
String(row.uuid),
|
||||
patch,
|
||||
{ userId: row.user_id as number },
|
||||
);
|
||||
const [shaped] = await this.#hydrateRows(
|
||||
updated ? [updated as Record<string, unknown>] : [],
|
||||
);
|
||||
@@ -351,8 +353,8 @@ export class SubdomainDriver extends PuterDriver {
|
||||
}
|
||||
|
||||
await this.#checkWriteAccess(row, actor);
|
||||
await this.stores.subdomain.deleteByUuid(row.uuid, {
|
||||
userId: row.user_id,
|
||||
await this.stores.subdomain.deleteByUuid(String(row.uuid), {
|
||||
userId: row.user_id as number,
|
||||
});
|
||||
|
||||
try {
|
||||
|
||||
@@ -25,6 +25,7 @@ import { Context } from '../../core/context.js';
|
||||
import { HttpError, type LegacyErrorCodes } from '../../core/http/HttpError.js';
|
||||
import { assertVerifiedEmail } from '../../core/http/verifiedEmail.js';
|
||||
import type { FSEntry } from '../../stores/fs/FSEntry.js';
|
||||
import type { SubdomainRow } from '../../stores/subdomain/SubdomainStore.js';
|
||||
import { PuterDriver } from '../types.js';
|
||||
import { loadFileInput } from '../util/fileInput.js';
|
||||
|
||||
@@ -313,7 +314,7 @@ export class WorkerDriver extends PuterDriver {
|
||||
const actor = this.#requireActor();
|
||||
const workerName = args.workerName as string | undefined;
|
||||
|
||||
let rows: Array<Record<string, unknown>>;
|
||||
let rows: SubdomainRow[];
|
||||
if (typeof workerName === 'string' && workerName.length > 0) {
|
||||
const sub = await this.stores.subdomain.getBySubdomain(
|
||||
`${WORKER_SUBDOMAIN_PREFIX}${workerName}`,
|
||||
@@ -495,7 +496,7 @@ export class WorkerDriver extends PuterDriver {
|
||||
}
|
||||
|
||||
#checkWorkerWriteAccess(
|
||||
row: Record<string, unknown>,
|
||||
row: SubdomainRow,
|
||||
actor: Actor & { user: { id: number } },
|
||||
errorStatus: number,
|
||||
errorMessage: string,
|
||||
@@ -738,14 +739,12 @@ export class WorkerDriver extends PuterDriver {
|
||||
);
|
||||
}
|
||||
|
||||
async #listWorkerRowsForEntry(
|
||||
entry: FSEntry,
|
||||
): Promise<Array<Record<string, unknown>>> {
|
||||
async #listWorkerRowsForEntry(entry: FSEntry): Promise<SubdomainRow[]> {
|
||||
const workerSubs = await this.stores.subdomain.listByUserIdAndPrefix(
|
||||
entry.userId,
|
||||
WORKER_SUBDOMAIN_PREFIX,
|
||||
);
|
||||
return workerSubs.filter((r: Record<string, unknown>) => {
|
||||
return workerSubs.filter((r) => {
|
||||
return (
|
||||
String(r.root_dir_id) === String(entry.id) ||
|
||||
String(r.root_dir_id) === String(entry.uuid) ||
|
||||
@@ -757,17 +756,17 @@ export class WorkerDriver extends PuterDriver {
|
||||
async #listWorkerRowsUnderPath(
|
||||
userId: number,
|
||||
parentPath: string,
|
||||
): Promise<Array<Record<string, unknown>>> {
|
||||
): Promise<SubdomainRow[]> {
|
||||
const workerSubs = await this.stores.subdomain.listByUserIdAndPrefix(
|
||||
userId,
|
||||
WORKER_SUBDOMAIN_PREFIX,
|
||||
);
|
||||
const rootDirIds = workerSubs
|
||||
.map((r: Record<string, unknown>) => r.root_dir_id)
|
||||
.map((r) => r.root_dir_id)
|
||||
.filter((id): id is number => typeof id === 'number');
|
||||
const entriesById =
|
||||
await this.stores.fsEntry.getEntriesByIds(rootDirIds);
|
||||
return workerSubs.filter((row: Record<string, unknown>) => {
|
||||
return workerSubs.filter((row) => {
|
||||
const rootDirId = row.root_dir_id;
|
||||
if (typeof rootDirId !== 'number') return false;
|
||||
const entry = entriesById.get(rootDirId);
|
||||
@@ -784,7 +783,7 @@ export class WorkerDriver extends PuterDriver {
|
||||
}
|
||||
|
||||
async #deleteWorkerForSourceRow(
|
||||
row: Record<string, unknown>,
|
||||
row: SubdomainRow,
|
||||
userId: number,
|
||||
): Promise<void> {
|
||||
const workerFullName = String(row.subdomain ?? '');
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Actor } from '../../core';
|
||||
import { loadFileInput } from '../../drivers/util/fileInput';
|
||||
import { getWorkerPreamble } from '../../drivers/workers/WorkerDriver';
|
||||
import { puterStores } from '../../stores';
|
||||
import type { SubdomainRow } from '../../stores/subdomain/SubdomainStore';
|
||||
import { LayerInstances } from '../../types';
|
||||
import { PuterService } from '../types';
|
||||
|
||||
@@ -15,20 +16,6 @@ const MAX_SOURCE_SIZE = 10 * 1024 * 1024; // 10 MB
|
||||
const WORKER_IDLE_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
||||
const IDLE_SWEEP_INTERVAL_MS = 60 * 1000; // sweep cadence
|
||||
|
||||
interface SubdomainRow {
|
||||
id: number;
|
||||
uuid: string;
|
||||
ts: number | string; // system timestamp
|
||||
subdomain: string; // immutable name
|
||||
user_id: number; // owner
|
||||
app_owner: number | null; // owning app, if any
|
||||
protected: 0 | 1; // access gate
|
||||
database_id: string | null; // Cloudflare D1 binding
|
||||
root_dir_id: number | null; // editable
|
||||
associated_app_id: string | null; // editable
|
||||
domain: string | null; // custom domain, editable
|
||||
}
|
||||
|
||||
const activeWorkers = new Map<string, Miniflare>();
|
||||
// workerName -> last dispatch/deploy time (ms). Drives the idle sweep.
|
||||
const lastAccess = new Map<string, number>();
|
||||
|
||||
@@ -20,6 +20,29 @@
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { PuterStore } from '../types';
|
||||
|
||||
/**
|
||||
* A row from the `subdomains` table (the shape `getBySubdomain` / `getByUuid`
|
||||
* resolve to). Kept alongside the store so callers share one definition instead
|
||||
* of redeclaring it locally.
|
||||
*/
|
||||
export interface SubdomainRow {
|
||||
id: number;
|
||||
uuid: string;
|
||||
ts: number | string; // system timestamp
|
||||
subdomain: string; // immutable name
|
||||
user_id: number; // owner
|
||||
app_owner: number | null; // owning app, if any
|
||||
protected: 0 | 1; // access gate
|
||||
database_id: string | null; // Cloudflare D1 binding
|
||||
root_dir_id: number | null; // editable
|
||||
associated_app_id: string | null; // editable
|
||||
domain: string | null; // custom domain, editable
|
||||
// `SELECT *` may surface columns not modelled above (and callers still
|
||||
// treat rows as `Record<string, unknown>` in places). The index signature
|
||||
// keeps the named fields strongly typed while staying Record-compatible.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
// Columns that may not be set through an `update` patch map. Defence-in-depth
|
||||
// against future callers (admin routes, extensions, new REST handlers) that
|
||||
// might forward `req.body` straight into the store: the driver's update
|
||||
@@ -71,7 +94,7 @@ export class SubdomainStore extends PuterStore {
|
||||
userId?: number | undefined;
|
||||
primary?: boolean;
|
||||
} = {},
|
||||
) {
|
||||
): Promise<SubdomainRow | null> {
|
||||
const where =
|
||||
userId !== undefined
|
||||
? 'WHERE `uuid` = ? AND `user_id` = ?'
|
||||
@@ -81,10 +104,10 @@ export class SubdomainStore extends PuterStore {
|
||||
const rows = primary
|
||||
? await this.clients.db.pread(sql, params)
|
||||
: await this.clients.db.read(sql, params);
|
||||
return rows[0] ?? null;
|
||||
return (rows[0] as unknown as SubdomainRow) ?? null;
|
||||
}
|
||||
|
||||
async getBySubdomain(subdomain: string) {
|
||||
async getBySubdomain(subdomain: string): Promise<SubdomainRow | null> {
|
||||
if (!subdomain) return null;
|
||||
|
||||
const cacheKey = this.#cacheKey(subdomain);
|
||||
@@ -92,7 +115,7 @@ export class SubdomainStore extends PuterStore {
|
||||
const raw = await this.clients.redis.get(cacheKey);
|
||||
if (raw === NEGATIVE_CACHE_MARKER) return null;
|
||||
if (raw) {
|
||||
const parsed = JSON.parse(raw);
|
||||
const parsed = JSON.parse(raw) as SubdomainRow | null;
|
||||
if (parsed) return parsed;
|
||||
}
|
||||
} catch {
|
||||
@@ -103,7 +126,7 @@ export class SubdomainStore extends PuterStore {
|
||||
'SELECT * FROM `subdomains` WHERE `subdomain` = ? LIMIT 1',
|
||||
[subdomain],
|
||||
);
|
||||
const row = rows[0] ?? null;
|
||||
const row = (rows[0] as unknown as SubdomainRow | undefined) ?? null;
|
||||
|
||||
if (row) {
|
||||
this.clients.redis
|
||||
@@ -173,7 +196,7 @@ export class SubdomainStore extends PuterStore {
|
||||
userId: number,
|
||||
prefix: string,
|
||||
extra: { appId?: number } = {},
|
||||
) {
|
||||
): Promise<SubdomainRow[]> {
|
||||
if (!userId || prefix == null) return [];
|
||||
|
||||
const like = `${prefix}%`;
|
||||
@@ -190,7 +213,7 @@ export class SubdomainStore extends PuterStore {
|
||||
);
|
||||
}
|
||||
|
||||
return rows;
|
||||
return rows as unknown as SubdomainRow[];
|
||||
}
|
||||
|
||||
// -- Writes -------------------------------------------------------
|
||||
@@ -248,14 +271,14 @@ export class SubdomainStore extends PuterStore {
|
||||
|
||||
async update(
|
||||
uuid: string,
|
||||
patch: unknown,
|
||||
patch: Record<string, unknown>,
|
||||
{
|
||||
userId,
|
||||
}: {
|
||||
userId?: number | undefined;
|
||||
} = {},
|
||||
) {
|
||||
const allowed: unknown = {};
|
||||
const allowed: Record<string, unknown> = {};
|
||||
for (const [k, v] of Object.entries(patch)) {
|
||||
if (READ_ONLY_COLUMNS.has(k)) continue;
|
||||
allowed[k] = v;
|
||||
|
||||
Reference in New Issue
Block a user