@promptbook/cli 0.112.0-88 → 0.112.0-90
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apps/agents-server/next.config.ts +58 -3
- package/apps/agents-server/src/database/ensureAutomaticDatabaseMigrations.ts +8 -1
- package/apps/agents-server/src/database/runDatabaseMigrations.ts +31 -1
- package/apps/agents-server/src/database/sqlite/$provideLocalSqliteSupabase.ts +2 -2
- package/apps/agents-server/src/middleware/createMiddlewareRequestContext.ts +1 -1
- package/apps/agents-server/src/tools/$provideServer.ts +27 -0
- package/apps/agents-server/src/utils/serverRegistry.ts +117 -3
- package/esm/apps/agents-server/src/utils/serverRegistry.d.ts +6 -0
- package/esm/index.es.js +348 -17
- package/esm/index.es.js.map +1 -1
- package/esm/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +31 -0
- package/esm/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +6 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +5 -3
- package/src/cli/cli-commands/agents-server/buildAgentsServer.ts +330 -8
- package/src/cli/cli-commands/agents-server/run.ts +2 -1
- package/src/cli/cli-commands/agents-server/startAgentsServer.ts +40 -16
- package/src/other/templates/getTemplatesPipelineCollection.ts +691 -794
- package/src/version.ts +2 -2
- package/src/versions.txt +2 -0
- package/umd/apps/agents-server/src/utils/serverRegistry.d.ts +6 -0
- package/umd/index.umd.js +346 -15
- package/umd/index.umd.js.map +1 -1
- package/umd/src/cli/cli-commands/agents-server/buildAgentsServer.d.ts +31 -0
- package/umd/src/cli/cli-commands/agents-server/startAgentsServer.d.ts +6 -0
- package/umd/src/version.d.ts +1 -1
- package/src/wizard/test/sub/subsub/subsubsub/.promptbook/executions-cache/8/c/report-whoami-6e340b9cffb37a98.json +0 -104
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NextConfig } from 'next';
|
|
2
|
+
import { readdirSync } from 'fs';
|
|
2
3
|
import path from 'path';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -9,6 +10,21 @@ import path from 'path';
|
|
|
9
10
|
*/
|
|
10
11
|
const nextDistDir = process.env.NEXT_DIST_DIR || '.next';
|
|
11
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Dependency root passed by `ptbk agents-server` when the bundled app is copied into a project cache.
|
|
15
|
+
*/
|
|
16
|
+
const agentsServerNodeModulesPath = process.env.PTBK_AGENTS_SERVER_NODE_MODULES_PATH;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Whether the CLI-owned build should skip duplicate validation already covered by repository tests.
|
|
20
|
+
*/
|
|
21
|
+
const isNextValidationIgnored = process.env.PTBK_AGENTS_SERVER_IGNORE_NEXT_VALIDATION === 'true';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Exact aliases for local generated Promptbook package entrypoints.
|
|
25
|
+
*/
|
|
26
|
+
const promptbookLocalPackageAliases = createPromptbookLocalPackageAliases();
|
|
27
|
+
|
|
12
28
|
/**
|
|
13
29
|
* Map of next config.
|
|
14
30
|
*/
|
|
@@ -17,7 +33,13 @@ const nextConfig: NextConfig = {
|
|
|
17
33
|
// <- TODO: [🐱🚀][🧠] How to properly build Next.js app, for both Vercel and Doceker?
|
|
18
34
|
|
|
19
35
|
distDir: nextDistDir,
|
|
20
|
-
|
|
36
|
+
eslint: {
|
|
37
|
+
ignoreDuringBuilds: isNextValidationIgnored,
|
|
38
|
+
},
|
|
39
|
+
serverExternalPackages: ['pg', '@napi-rs/canvas', 'playwright', 'playwright-core'],
|
|
40
|
+
typescript: {
|
|
41
|
+
ignoreBuildErrors: isNextValidationIgnored,
|
|
42
|
+
},
|
|
21
43
|
|
|
22
44
|
experimental: {
|
|
23
45
|
externalDir: true,
|
|
@@ -29,12 +51,25 @@ const nextConfig: NextConfig = {
|
|
|
29
51
|
|
|
30
52
|
resolveAlias: {
|
|
31
53
|
'@': path.resolve(__dirname),
|
|
32
|
-
'@common': path.resolve(__dirname, '../
|
|
33
|
-
|
|
54
|
+
'@common': path.resolve(__dirname, '../_common'),
|
|
55
|
+
...promptbookLocalPackageAliases,
|
|
34
56
|
},
|
|
35
57
|
},
|
|
36
58
|
|
|
37
59
|
webpack(config, { isServer }) {
|
|
60
|
+
config.resolve.alias = {
|
|
61
|
+
...config.resolve.alias,
|
|
62
|
+
'@': path.resolve(__dirname),
|
|
63
|
+
'@common': path.resolve(__dirname, '../_common'),
|
|
64
|
+
...promptbookLocalPackageAliases,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
if (agentsServerNodeModulesPath) {
|
|
68
|
+
config.resolve.modules = Array.from(
|
|
69
|
+
new Set([...(config.resolve.modules || ['node_modules']), agentsServerNodeModulesPath]),
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
38
73
|
// Exclude Node.js-only modules from client bundle
|
|
39
74
|
if (!isServer) {
|
|
40
75
|
config.resolve.fallback = {
|
|
@@ -81,3 +116,23 @@ const nextConfig: NextConfig = {
|
|
|
81
116
|
};
|
|
82
117
|
|
|
83
118
|
export default nextConfig;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Creates webpack/Turbopack aliases from imports like `@promptbook-local/core` to generated local sources.
|
|
122
|
+
*/
|
|
123
|
+
function createPromptbookLocalPackageAliases(): Record<string, string> {
|
|
124
|
+
const packagesIndexPath = path.resolve(__dirname, '../../src/_packages');
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
return Object.fromEntries(
|
|
128
|
+
readdirSync(packagesIndexPath)
|
|
129
|
+
.filter((filename) => filename.endsWith('.index.ts'))
|
|
130
|
+
.map((filename) => [
|
|
131
|
+
`@promptbook-local/${filename.replace(/\.index\.ts$/u, '')}`,
|
|
132
|
+
path.resolve(packagesIndexPath, filename),
|
|
133
|
+
]),
|
|
134
|
+
);
|
|
135
|
+
} catch {
|
|
136
|
+
return {};
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
resolveDatabaseMigrationConnectionStringFromEnvironment,
|
|
4
4
|
runDatabaseMigrations,
|
|
5
5
|
} from './runDatabaseMigrations';
|
|
6
|
+
import { listEnvironmentRegisteredServers } from '../utils/serverRegistry';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Opt-out environment flag for automatic runtime migrations.
|
|
@@ -24,7 +25,13 @@ const automaticDatabaseMigrationPromiseByPrefix = new Map<string, Promise<void>>
|
|
|
24
25
|
* @private internal startup helper for Agents Server runtime
|
|
25
26
|
*/
|
|
26
27
|
export async function ensureAutomaticDatabaseMigrations(): Promise<void> {
|
|
27
|
-
|
|
28
|
+
const environmentServerPrefixes = listEnvironmentRegisteredServers().map((server) => server.tablePrefix);
|
|
29
|
+
|
|
30
|
+
if (environmentServerPrefixes.length === 0) {
|
|
31
|
+
return ensureAutomaticDatabaseMigrationsForPrefix(process.env.SUPABASE_TABLE_PREFIX || '');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
await Promise.all(environmentServerPrefixes.map((prefix) => ensureAutomaticDatabaseMigrationsForPrefix(prefix)));
|
|
28
35
|
}
|
|
29
36
|
|
|
30
37
|
/**
|
|
@@ -16,6 +16,7 @@ import { listRegisteredServersFromDatabase } from './listRegisteredServersFromDa
|
|
|
16
16
|
import { migratePrefix } from './migratePrefix';
|
|
17
17
|
import { readMigrationFiles, resolveMigrationsDirectory } from './resolveMigrationsDirectory';
|
|
18
18
|
import { selectPrefixesForMigration } from './selectPrefixesForMigration';
|
|
19
|
+
import { listEnvironmentRegisteredServers } from '../utils/serverRegistry';
|
|
19
20
|
|
|
20
21
|
/**
|
|
21
22
|
* Allowed values describing who applied a migration record.
|
|
@@ -175,7 +176,10 @@ export async function resolveDatabaseMigrationRuntimeConfiguration(
|
|
|
175
176
|
try {
|
|
176
177
|
await client.connect();
|
|
177
178
|
|
|
178
|
-
const registeredServers =
|
|
179
|
+
const registeredServers = mergeRegisteredServers(
|
|
180
|
+
await listRegisteredServersFromDatabase(client),
|
|
181
|
+
listEnvironmentRegisteredServers(),
|
|
182
|
+
);
|
|
179
183
|
const hasExplicitDefaultPrefix = process.env[SUPABASE_TABLE_PREFIX_ENV_NAME] !== undefined;
|
|
180
184
|
const configuredPrefixes = uniquePrefixes([
|
|
181
185
|
...(hasExplicitDefaultPrefix
|
|
@@ -355,6 +359,32 @@ function uniquePrefixes(prefixes: ReadonlyArray<string>): Array<string> {
|
|
|
355
359
|
return result;
|
|
356
360
|
}
|
|
357
361
|
|
|
362
|
+
/**
|
|
363
|
+
* Combines database and environment registry rows, keeping database rows authoritative.
|
|
364
|
+
*
|
|
365
|
+
* @param databaseServers - Persistent `_Server` rows.
|
|
366
|
+
* @param environmentServers - Virtual rows derived from `SERVERS`.
|
|
367
|
+
* @returns Merged rows without duplicate domains.
|
|
368
|
+
*/
|
|
369
|
+
function mergeRegisteredServers(
|
|
370
|
+
databaseServers: ReadonlyArray<ServerRecord>,
|
|
371
|
+
environmentServers: ReadonlyArray<ServerRecord>,
|
|
372
|
+
): Array<ServerRecord> {
|
|
373
|
+
const seenDomains = new Set(databaseServers.map((server) => server.domain));
|
|
374
|
+
const mergedServers = [...databaseServers];
|
|
375
|
+
|
|
376
|
+
for (const environmentServer of environmentServers) {
|
|
377
|
+
if (seenDomains.has(environmentServer.domain)) {
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
mergedServers.push(environmentServer);
|
|
382
|
+
seenDomains.add(environmentServer.domain);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return mergedServers;
|
|
386
|
+
}
|
|
387
|
+
|
|
358
388
|
/**
|
|
359
389
|
* Creates one PostgreSQL client using the lazily loaded `pg` package.
|
|
360
390
|
*
|
|
@@ -750,11 +750,11 @@ class LocalSqliteQueryBuilder implements PromiseLike<LocalSqliteQueryResult> {
|
|
|
750
750
|
*/
|
|
751
751
|
private selectMatchingRowids(): Array<number | bigint> {
|
|
752
752
|
const where = this.createWhereClause();
|
|
753
|
-
const sql = `SELECT rowid FROM ${quoteIdentifier(this.tableName)} ${where.sql}`;
|
|
753
|
+
const sql = `SELECT rowid AS "__rowid" FROM ${quoteIdentifier(this.tableName)} ${where.sql}`;
|
|
754
754
|
return this.database
|
|
755
755
|
.prepare(sql)
|
|
756
756
|
.all(...where.values)
|
|
757
|
-
.map((row) => row.
|
|
757
|
+
.map((row) => row.__rowid as number | bigint);
|
|
758
758
|
}
|
|
759
759
|
|
|
760
760
|
/**
|
|
@@ -37,7 +37,7 @@ export async function createMiddlewareRequestContext(request: NextRequest): Prom
|
|
|
37
37
|
const requestIp = getRequestIp(request);
|
|
38
38
|
const host = request.headers.get('host');
|
|
39
39
|
const supabase = getMiddlewareSupabase();
|
|
40
|
-
const registeredServers = supabase ? await loadRegisteredServers() : [];
|
|
40
|
+
const registeredServers = supabase || process.env.SERVERS ? await loadRegisteredServers() : [];
|
|
41
41
|
const { canQueryServerTables, customDomainResolution, tablePrefixForRequest } = await resolveMiddlewareServerRouting(
|
|
42
42
|
{
|
|
43
43
|
host,
|
|
@@ -38,6 +38,33 @@ const getCachedProvidedServer = cache(async (): Promise<ProvidedServer> => {
|
|
|
38
38
|
const xPromptbookServer = headersList.get('x-promptbook-server');
|
|
39
39
|
|
|
40
40
|
if (isAgentsServerSqliteMode()) {
|
|
41
|
+
if (isLocalDevelopmentHost(requestHost)) {
|
|
42
|
+
return {
|
|
43
|
+
id: null,
|
|
44
|
+
publicUrl: resolveFallbackPublicUrl(requestHost),
|
|
45
|
+
tablePrefix: SUPABASE_TABLE_PREFIX,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const registeredServers = await listRegisteredServersUsingServiceRole();
|
|
50
|
+
if (registeredServers.length > 0) {
|
|
51
|
+
const { currentServer: resolvedSqliteServer } = resolveServerSelection({
|
|
52
|
+
host: requestHost,
|
|
53
|
+
forwardedServerHost: xPromptbookServer,
|
|
54
|
+
registeredServers,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (!resolvedSqliteServer) {
|
|
58
|
+
throw new Error(`Server with host "${requestHost}" is not registered in SERVERS`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
id: resolvedSqliteServer.id,
|
|
63
|
+
publicUrl: createServerPublicUrl(resolvedSqliteServer.domain),
|
|
64
|
+
tablePrefix: resolvedSqliteServer.tablePrefix,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
41
68
|
return {
|
|
42
69
|
id: null,
|
|
43
70
|
publicUrl: resolveFallbackPublicUrl(requestHost),
|
|
@@ -62,6 +62,16 @@ const SERVER_REGISTRY_SELECT = 'id,name,environment,domain,tablePrefix,createdAt
|
|
|
62
62
|
*/
|
|
63
63
|
const SERVER_REGISTRY_TABLE_NAME = '_Server';
|
|
64
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Environment variable with comma-separated standalone server domains.
|
|
67
|
+
*/
|
|
68
|
+
const SERVERS_ENV_NAME = 'SERVERS';
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Stable timestamp used by virtual server records derived from environment variables.
|
|
72
|
+
*/
|
|
73
|
+
const ENVIRONMENT_SERVER_TIMESTAMP = '1970-01-01T00:00:00.000Z';
|
|
74
|
+
|
|
65
75
|
/**
|
|
66
76
|
* In-memory cache TTL for repeated registry lookups inside one runtime process.
|
|
67
77
|
*/
|
|
@@ -127,8 +137,10 @@ export async function listRegisteredServers(supabase: Pick<SupabaseClient, 'from
|
|
|
127
137
|
export async function listRegisteredServersUsingServiceRole(options?: {
|
|
128
138
|
readonly forceRefresh?: boolean;
|
|
129
139
|
}): Promise<Array<ServerRecord>> {
|
|
140
|
+
const environmentServers = listEnvironmentRegisteredServers();
|
|
141
|
+
|
|
130
142
|
if (isAgentsServerSqliteMode()) {
|
|
131
|
-
return
|
|
143
|
+
return environmentServers;
|
|
132
144
|
}
|
|
133
145
|
|
|
134
146
|
const shouldReuseCache =
|
|
@@ -137,7 +149,7 @@ export async function listRegisteredServersUsingServiceRole(options?: {
|
|
|
137
149
|
Date.now() - cachedServerRegistry.loadedAt < SERVER_REGISTRY_CACHE_TTL_MS;
|
|
138
150
|
|
|
139
151
|
if (shouldReuseCache) {
|
|
140
|
-
return cachedServerRegistry!.serversPromise;
|
|
152
|
+
return mergeRegisteredServers(await cachedServerRegistry!.serversPromise, environmentServers);
|
|
141
153
|
}
|
|
142
154
|
|
|
143
155
|
const serversPromise = listRegisteredServers(getServerRegistryClient());
|
|
@@ -147,7 +159,7 @@ export async function listRegisteredServersUsingServiceRole(options?: {
|
|
|
147
159
|
};
|
|
148
160
|
|
|
149
161
|
try {
|
|
150
|
-
return await serversPromise;
|
|
162
|
+
return mergeRegisteredServers(await serversPromise, environmentServers);
|
|
151
163
|
} catch (error) {
|
|
152
164
|
if (cachedServerRegistry?.serversPromise === serversPromise) {
|
|
153
165
|
cachedServerRegistry = null;
|
|
@@ -156,6 +168,35 @@ export async function listRegisteredServersUsingServiceRole(options?: {
|
|
|
156
168
|
}
|
|
157
169
|
}
|
|
158
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Loads virtual server records from the comma-separated `SERVERS` environment variable.
|
|
173
|
+
*
|
|
174
|
+
* @returns Server records with deterministic table prefixes derived from normalized domains.
|
|
175
|
+
*/
|
|
176
|
+
export function listEnvironmentRegisteredServers(): Array<ServerRecord> {
|
|
177
|
+
const rawServers = process.env[SERVERS_ENV_NAME];
|
|
178
|
+
if (!rawServers) {
|
|
179
|
+
return [];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const normalizedDomains = uniqueStrings(
|
|
183
|
+
rawServers
|
|
184
|
+
.split(',')
|
|
185
|
+
.map((server) => normalizeServerDomain(server))
|
|
186
|
+
.filter((server): server is string => Boolean(server)),
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
return normalizedDomains.map((domain, index) => ({
|
|
190
|
+
id: -(index + 1),
|
|
191
|
+
name: domain,
|
|
192
|
+
environment: SERVER_ENVIRONMENT.PRODUCTION,
|
|
193
|
+
domain,
|
|
194
|
+
tablePrefix: buildEnvironmentServerTablePrefix(domain),
|
|
195
|
+
createdAt: ENVIRONMENT_SERVER_TIMESTAMP,
|
|
196
|
+
updatedAt: ENVIRONMENT_SERVER_TIMESTAMP,
|
|
197
|
+
}));
|
|
198
|
+
}
|
|
199
|
+
|
|
159
200
|
/**
|
|
160
201
|
* Finds one registered server by incoming host header.
|
|
161
202
|
*
|
|
@@ -404,3 +445,76 @@ function hasHttpProtocol(value: string): boolean {
|
|
|
404
445
|
function isDefaultPortForProtocol(protocol: string, port: string): boolean {
|
|
405
446
|
return (protocol === 'http:' && port === '80') || (protocol === 'https:' && port === '443');
|
|
406
447
|
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Combines database and environment registry rows, keeping database rows authoritative.
|
|
451
|
+
*
|
|
452
|
+
* @param databaseServers - Persistent `_Server` rows.
|
|
453
|
+
* @param environmentServers - Virtual rows derived from `SERVERS`.
|
|
454
|
+
* @returns Merged rows without duplicate domains.
|
|
455
|
+
*/
|
|
456
|
+
function mergeRegisteredServers(
|
|
457
|
+
databaseServers: ReadonlyArray<ServerRecord>,
|
|
458
|
+
environmentServers: ReadonlyArray<ServerRecord>,
|
|
459
|
+
): Array<ServerRecord> {
|
|
460
|
+
const seenDomains = new Set<string>();
|
|
461
|
+
const mergedServers = [...databaseServers];
|
|
462
|
+
|
|
463
|
+
for (const databaseServer of databaseServers) {
|
|
464
|
+
const normalizedDomain = normalizeServerDomain(databaseServer.domain);
|
|
465
|
+
if (normalizedDomain) {
|
|
466
|
+
seenDomains.add(normalizedDomain);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
for (const environmentServer of environmentServers) {
|
|
471
|
+
const normalizedDomain = normalizeServerDomain(environmentServer.domain);
|
|
472
|
+
if (!normalizedDomain || seenDomains.has(normalizedDomain)) {
|
|
473
|
+
continue;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
mergedServers.push(environmentServer);
|
|
477
|
+
seenDomains.add(normalizedDomain);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
return mergedServers;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Builds a deterministic table prefix from a normalized domain.
|
|
485
|
+
*
|
|
486
|
+
* @param domain - Normalized server domain.
|
|
487
|
+
* @returns Prefix such as `server_www_example_com_`.
|
|
488
|
+
*/
|
|
489
|
+
function buildEnvironmentServerTablePrefix(domain: string): string {
|
|
490
|
+
const prefixSuffix = domain
|
|
491
|
+
.toLowerCase()
|
|
492
|
+
.replace(/-/gu, '_dash_')
|
|
493
|
+
.replace(/\./gu, '_')
|
|
494
|
+
.replace(/:/gu, '_port_')
|
|
495
|
+
.replace(/[^a-z0-9_]/gu, '_')
|
|
496
|
+
.replace(/_+/gu, '_')
|
|
497
|
+
.replace(/^_+|_+$/gu, '');
|
|
498
|
+
|
|
499
|
+
return `server_${prefixSuffix}_`;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Deduplicates non-empty strings while preserving input order.
|
|
504
|
+
*
|
|
505
|
+
* @param values - Raw string values.
|
|
506
|
+
* @returns Unique non-empty strings.
|
|
507
|
+
*/
|
|
508
|
+
function uniqueStrings(values: ReadonlyArray<string>): Array<string> {
|
|
509
|
+
const uniqueValues: Array<string> = [];
|
|
510
|
+
|
|
511
|
+
for (const value of values) {
|
|
512
|
+
if (!value || uniqueValues.includes(value)) {
|
|
513
|
+
continue;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
uniqueValues.push(value);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return uniqueValues;
|
|
520
|
+
}
|
|
@@ -65,6 +65,12 @@ export declare function listRegisteredServers(supabase: Pick<SupabaseClient, 'fr
|
|
|
65
65
|
export declare function listRegisteredServersUsingServiceRole(options?: {
|
|
66
66
|
readonly forceRefresh?: boolean;
|
|
67
67
|
}): Promise<Array<ServerRecord>>;
|
|
68
|
+
/**
|
|
69
|
+
* Loads virtual server records from the comma-separated `SERVERS` environment variable.
|
|
70
|
+
*
|
|
71
|
+
* @returns Server records with deterministic table prefixes derived from normalized domains.
|
|
72
|
+
*/
|
|
73
|
+
export declare function listEnvironmentRegisteredServers(): Array<ServerRecord>;
|
|
68
74
|
/**
|
|
69
75
|
* Finds one registered server by incoming host header.
|
|
70
76
|
*
|