f4b404's picture
Upload folder using huggingface_hub
f55c62a verified
Raw
History Blame Contribute Delete
5.57 kB
import { z } from 'zod';
import { commaSeparatedList, seconds } from './helpers.js';
import type { RuntimeConfigSection } from '../types.js';
const nullableString = z.string().nullable();
const UUID_REGEX =
/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
const aliasEntry = z.object({
uuid: z.string().regex(UUID_REGEX, 'Invalid UUID'),
password: z.string(),
});
/**
* Accepts either:
* - a `Record<string, { uuid, password }>` (DB-stored shape), or
* - the comma-separated env string format `alias:uuid:password,alias:uuid:password,...`.
*/
const aliasedConfigurations = z.union([
z.record(z.string(), aliasEntry),
z.string().transform((value, ctx) => {
const out: Record<string, { uuid: string; password: string }> = {};
if (!value.trim()) return out;
for (const entry of value.split(',').map((e) => e.trim())) {
if (!entry) continue;
const [alias, uuid, password] = entry.split(':');
if (!alias || !uuid || !password) {
ctx.addIssue({
code: 'custom',
message: `Invalid alias entry "${entry}". Expected alias:uuid:password.`,
});
return z.NEVER;
}
if (!UUID_REGEX.test(uuid)) {
ctx.addIssue({
code: 'custom',
message: `Invalid UUID for alias "${alias}".`,
});
return z.NEVER;
}
out[alias] = { uuid, password };
}
return out;
}),
]);
const provideStreamData = z.union([
z.boolean(),
z.array(z.string()),
z.null(),
z.string().transform((value) => {
const lower = value.trim().toLowerCase();
if (lower === 'true' || lower === '1') return true;
if (lower === 'false' || lower === '0') return false;
return value
.split(',')
.map((ip) => ip.trim())
.filter((ip) => ip.length > 0);
}),
]);
export const apiSchema = {
authRequired: {
schema: z.boolean(),
default: false,
label: 'Require authentication for the config page',
description:
'When true, /stremio/configure requires a valid login session (any user in AIOSTREAMS_AUTH) and the config-write gate (CONFIG_ACCESS_KEY) is enforced. When false, the config page is public.',
env: 'AIOSTREAMS_AUTH_REQUIRED',
requiresRestart: false,
secret: false,
},
configAccessKey: {
schema: nullableString,
default: null,
label: 'Config access key',
description:
'Single key embedded in a config and checked on create/update/serve. If unset while authRequired is true, one is generated and persisted automatically. Rotating it invalidates every existing config until re-saved.',
env: 'CONFIG_ACCESS_KEY',
requiresRestart: false,
secret: true,
},
sessionTtlSeconds: {
schema: seconds,
default: 86400,
label: 'Session lifetime',
description:
'Lifetime of a login session before the user must log in again. Defaults to 24 hours (1d).',
env: 'SESSION_TTL_SECONDS',
requiresRestart: false,
secret: false,
},
aliasedConfigurations: {
schema: aliasedConfigurations,
default: {} as Record<string, { uuid: string; password: string }>,
label: 'Aliased configurations',
description:
'Map of aliases to {uuid, password} accessible at /stremio/u/<alias>/manifest.json. Env-supplied form: comma-separated `alias:uuid:password` entries.',
env: 'ALIASED_CONFIGURATIONS',
requiresRestart: false,
secret: true,
},
enableSearchApi: {
schema: z.boolean(),
default: true,
label: 'Enable search API',
description:
'When true, the /api/search endpoint is mounted and reachable.',
env: 'ENABLE_SEARCH_API',
requiresRestart: true,
secret: false,
},
provideStreamData: {
schema: provideStreamData,
default: null,
label: 'Provide stream data',
description:
'Whether stream metadata is included in Stremio stream responses. `null` (default) auto-detects from User-Agent (AIOStreams/* always gets it). `true`/`false` overrides for everyone. An IP list enables it only for matching request IPs.',
env: 'PROVIDE_STREAM_DATA',
requiresRestart: false,
secret: false,
},
exposeUserCount: {
schema: z.boolean(),
default: false,
label: 'Expose user count',
description: 'Include the total user count on the public status endpoint.',
env: 'EXPOSE_USER_COUNT',
requiresRestart: false,
secret: false,
},
stremioAddonsConfigIssuer: {
schema: nullableString,
default: 'https://stremio-addons.net',
label: 'Stremio Addons Config issuer',
description:
'Issuer URL declared in the manifest for the Stremio Addons Config integration.',
env: 'STREMIO_ADDONS_CONFIG_ISSUER',
requiresRestart: false,
secret: false,
},
stremioAddonsConfigSignature: {
schema: nullableString,
default: null,
label: 'Stremio Addons Config signature',
description:
'Signed JWT for the Stremio Addons Config integration. Both issuer and signature must be set for the manifest field to be emitted.',
env: 'STREMIO_ADDONS_CONFIG_SIGNATURE',
requiresRestart: false,
secret: true,
},
trustedIps: {
schema: commaSeparatedList,
default: ['172.17.0.0/16', '127.0.0.1/32', '::1/128'],
label: 'Trusted IPs',
description:
'Comma-separated list of trusted IPs / CIDR ranges. Used when determining the requesting IP. User IP is always trusted via headers regardless of this setting.',
env: 'TRUSTED_IPS',
requiresRestart: false,
secret: false,
},
} as const satisfies RuntimeConfigSection;