fix type errors

This commit is contained in:
Neal Shah
2026-07-15 00:53:18 -04:00
parent 18dc9e22b1
commit 74bf5962d9
4 changed files with 49 additions and 38 deletions
@@ -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 {
+9 -10
View File
@@ -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>();
+32 -9
View File
@@ -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;