@elench/testkit 0.1.138 → 0.1.140

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.
@@ -25,8 +25,8 @@ export function resolveTargetConfig(configs, serviceName = null) {
25
25
  }
26
26
 
27
27
  if (configs.length === 1) return configs[0];
28
- const withLocalDb = configs.filter((config) => config.testkit.database?.provider === "local");
29
- if (withLocalDb.length === 1) return withLocalDb[0];
28
+ const withDatabase = configs.filter((config) => config.testkit.database);
29
+ if (withDatabase.length === 1) return withDatabase[0];
30
30
 
31
31
  const available = configs.map((config) => config.name).join(", ");
32
32
  throw new Error(`Multiple services available. Pass --service. Available: ${available}`);
@@ -31,7 +31,7 @@ export async function executeDatabaseSchemaRefreshOperation(options = {}) {
31
31
  try {
32
32
  for (const config of topologicallySortConfigs(resolvedConfigs)) {
33
33
  if (config.name === resolvedTarget.name) break;
34
- if (config.testkit.database?.provider === "local") {
34
+ if (config.testkit.database) {
35
35
  await prepareDatabaseRuntime(config, { reporter, logRegistry, setupRegistry });
36
36
  }
37
37
  }
@@ -29,7 +29,7 @@ export async function executeDatabaseSchemaVerifyOperation(options = {}) {
29
29
  const setupRegistry = createSetupOperationRegistry({ logRegistry });
30
30
  try {
31
31
  for (const config of topologicallySortConfigs(resolvedConfigs)) {
32
- if (config.testkit.database?.provider === "local") {
32
+ if (config.testkit.database) {
33
33
  await prepareDatabaseRuntime(config, {
34
34
  reporter,
35
35
  logRegistry,
@@ -12,26 +12,41 @@ export function normalizeDatabaseConfig(explicitService, serviceName) {
12
12
  if (explicitService.databaseFrom) return undefined;
13
13
  if (!explicitService.database) return undefined;
14
14
 
15
- const database =
16
- explicitService.database.provider === "local"
17
- ? explicitService.database
18
- : {
19
- provider: "local",
20
- ...explicitService.database,
21
- };
15
+ const rawDatabase = explicitService.database;
16
+ const provider = rawDatabase.provider || (rawDatabase.resource ? "resource" : "local");
17
+ if (!["local", "resource"].includes(provider)) {
18
+ throw new Error(`Service "${serviceName}" database.provider must be "local" or "resource"`);
19
+ }
20
+
21
+ const base = {
22
+ ...rawDatabase,
23
+ provider,
24
+ binding: normalizeDatabaseBinding(rawDatabase.binding || "per-runtime", `Service "${serviceName}" database.binding`),
25
+ reset: rawDatabase.reset !== false,
26
+ sourceSchema: normalizeSourceSchemaConfig(rawDatabase.sourceSchema, serviceName),
27
+ template: normalizeDatabaseTemplateConfig(rawDatabase.template, serviceName),
28
+ serviceName,
29
+ };
30
+
31
+ if (provider === "resource") {
32
+ const resource = String(rawDatabase.resource || "").trim();
33
+ if (!resource) {
34
+ throw new Error(`Service "${serviceName}" database.resource must be a non-empty string`);
35
+ }
36
+ return {
37
+ ...base,
38
+ resource,
39
+ selectedBackend: "resource",
40
+ };
41
+ }
22
42
 
23
43
  return {
24
- ...database,
25
- binding: normalizeDatabaseBinding(database.binding || "per-runtime", `Service "${serviceName}" database.binding`),
44
+ ...base,
26
45
  provider: "local",
27
46
  selectedBackend: "local",
28
- reset: database.reset !== false,
29
- image: database.image || DEFAULT_LOCAL_IMAGE,
30
- user: database.user || DEFAULT_LOCAL_USER,
31
- password: database.password || DEFAULT_LOCAL_PASSWORD,
32
- sourceSchema: normalizeSourceSchemaConfig(database.sourceSchema, serviceName),
33
- template: normalizeDatabaseTemplateConfig(database.template, serviceName),
34
- serviceName,
47
+ image: rawDatabase.image || DEFAULT_LOCAL_IMAGE,
48
+ user: rawDatabase.user || DEFAULT_LOCAL_USER,
49
+ password: rawDatabase.password || DEFAULT_LOCAL_PASSWORD,
35
50
  };
36
51
  }
37
52
 
@@ -96,6 +96,17 @@ export interface LocalDatabaseConfig {
96
96
  user?: string;
97
97
  }
98
98
 
99
+ export interface ResourceDatabaseConfig {
100
+ provider: "resource";
101
+ binding?: "shared" | "per-runtime";
102
+ reset?: boolean;
103
+ resource: string;
104
+ sourceSchema?: DatabaseSourceSchemaConfig | null;
105
+ template?: DatabaseTemplateConfig;
106
+ }
107
+
108
+ export type PostgresDatabaseConfig = LocalDatabaseConfig | ResourceDatabaseConfig;
109
+
99
110
  export interface SkipFileRule {
100
111
  path: string;
101
112
  reason: string;
@@ -250,7 +261,7 @@ export interface DiscoveryConfig {
250
261
  }
251
262
 
252
263
  export interface ServiceConfig {
253
- database?: LocalDatabaseConfig;
264
+ database?: PostgresDatabaseConfig;
254
265
  databaseFrom?: string;
255
266
  dependsOn?: string[];
256
267
  discovery?: DiscoveryConfig;
@@ -621,6 +632,15 @@ export declare const database: {
621
632
  verify?: TemplateLifecycleStepConfig | TemplateLifecycleStepConfig[] | string | string[];
622
633
  }
623
634
  ): LocalDatabaseConfig;
635
+ postgres(
636
+ options?: Omit<ResourceDatabaseConfig, "provider" | "template"> & {
637
+ inputs?: string[];
638
+ migrate?: TemplateLifecycleStepConfig | TemplateLifecycleStepConfig[] | string | string[];
639
+ seed?: TemplateLifecycleStepConfig | TemplateLifecycleStepConfig[] | string | string[];
640
+ template?: DatabaseTemplateOptions;
641
+ verify?: TemplateLifecycleStepConfig | TemplateLifecycleStepConfig[] | string | string[];
642
+ }
643
+ ): ResourceDatabaseConfig;
624
644
  fixture(
625
645
  options?: Omit<LocalDatabaseConfig, "provider" | "template"> & {
626
646
  inputs?: string[];
@@ -27,8 +27,9 @@ export function defineFile(metadata) {
27
27
  }
28
28
 
29
29
  function postgresDatabase(options = {}) {
30
+ const provider = options.resource ? "resource" : options.provider || "local";
30
31
  return {
31
- provider: "local",
32
+ provider,
32
33
  ...options,
33
34
  };
34
35
  }
@@ -19,6 +19,7 @@ import {
19
19
  getLocalInfraDir as getLocalInfraDirModel,
20
20
  getLocalLocksDir as getLocalLocksDirModel,
21
21
  getLocalServiceCacheDir as getLocalServiceCacheDirModel,
22
+ getResourceLocksDir as getResourceLocksDirModel,
22
23
  hasRemainingLocalArtifacts as hasRemainingLocalArtifactsModel,
23
24
  readStateValue as readStateValueModel,
24
25
  visitDirs as visitDirsModel,
@@ -56,6 +57,10 @@ export async function prepareDatabaseRuntime(config, options = {}) {
56
57
  await prepareLocalDatabase(config, options);
57
58
  return;
58
59
  }
60
+ if (db.provider === "resource") {
61
+ await prepareResourceDatabase(config, options);
62
+ return;
63
+ }
59
64
 
60
65
  throw new Error(`Unsupported database provider "${db.provider}"`);
61
66
  }
@@ -64,6 +69,8 @@ export async function destroyRuntimeDatabase({ productDir, stateDir }) {
64
69
  const backend = readStateValue(path.join(stateDir, "database_backend"));
65
70
  if (backend === "local") {
66
71
  await destroyLocalRuntimeDatabase(productDir, stateDir);
72
+ } else if (backend === "resource") {
73
+ await destroyResourceRuntimeDatabase(stateDir);
67
74
  }
68
75
  }
69
76
 
@@ -72,12 +79,26 @@ export async function destroyServiceDatabaseCache(productDir, serviceName) {
72
79
  if (!fs.existsSync(cacheDir)) return;
73
80
 
74
81
  const backend = readStateValue(path.join(cacheDir, "database_backend"));
82
+ const lockDir = getLocalLocksDir(productDir);
83
+ if (backend === "resource") {
84
+ const resourceName = readStateValue(path.join(cacheDir, "resource_name"));
85
+ const resourceLockDir = getResourceLocksDir(productDir, resourceName || "unknown");
86
+ fs.mkdirSync(resourceLockDir, { recursive: true });
87
+ await withLock(path.join(resourceLockDir, `template-${serviceName}.lock`), async () => {
88
+ const infra = resolveResourcePostgresInfraFromState(cacheDir);
89
+ const templateDbName = readStateValue(path.join(cacheDir, "template_database_name"));
90
+ if (infra && templateDbName) {
91
+ await dropDatabaseIfExists(infra, templateDbName);
92
+ }
93
+ fs.rmSync(cacheDir, { recursive: true, force: true });
94
+ });
95
+ return;
96
+ }
75
97
  if (backend !== "local") {
76
98
  fs.rmSync(cacheDir, { recursive: true, force: true });
77
99
  return;
78
100
  }
79
101
 
80
- const lockDir = getLocalLocksDir(productDir);
81
102
  fs.mkdirSync(lockDir, { recursive: true });
82
103
  await withLock(path.join(lockDir, `template-${serviceName}.lock`), async () => {
83
104
  const infra = await loadExistingLocalContainer(productDir);
@@ -165,6 +186,40 @@ async function prepareLocalDatabase(config, options = {}) {
165
186
  });
166
187
  }
167
188
 
189
+ async function prepareResourceDatabase(config, options = {}) {
190
+ const db = config.testkit.database;
191
+ const productDir = config.productDir;
192
+ const serviceName = config.name;
193
+ const bindingKey = resolveDatabaseBindingKey(config);
194
+ const lockDir = getResourceLocksDir(productDir, db.resource);
195
+ const cacheDir = getLocalServiceCacheDir(productDir, serviceName);
196
+ fs.mkdirSync(lockDir, { recursive: true });
197
+ fs.mkdirSync(cacheDir, { recursive: true });
198
+
199
+ const infra = resolveResourcePostgresInfra(config);
200
+ let templateFingerprint = null;
201
+
202
+ await waitForResourcePostgresReady(infra);
203
+ await withLock(path.join(lockDir, `template-${serviceName}.lock`), async () => {
204
+ const sourceSchemaState = await prepareSourceSchemaCache(config, options);
205
+ templateFingerprint = await computeTemplateFingerprint(config, { sourceSchemaState });
206
+ templateFingerprint = await ensureTemplateDatabase(
207
+ config,
208
+ infra,
209
+ cacheDir,
210
+ templateFingerprint,
211
+ {
212
+ ...options,
213
+ sourceSchemaState,
214
+ }
215
+ );
216
+ });
217
+
218
+ await withLock(path.join(lockDir, `runtime-${serviceName}-${hashString(bindingKey, 10)}.lock`), async () => {
219
+ await ensureRuntimeClone(config, infra, cacheDir, templateFingerprint, bindingKey);
220
+ });
221
+ }
222
+
168
223
  async function ensureTemplateDatabase(config, infra, cacheDir, templateFingerprint, options = {}) {
169
224
  const serviceName = config.name;
170
225
  let activeFingerprint = templateFingerprint;
@@ -187,7 +242,7 @@ async function ensureTemplateDatabase(config, infra, cacheDir, templateFingerpri
187
242
  kind: "database-template",
188
243
  summary: "template cache hit",
189
244
  });
190
- writeLocalCacheState(cacheDir, infra, existingDbName, activeFingerprint);
245
+ writeCacheState(cacheDir, config, infra, existingDbName, activeFingerprint);
191
246
  return activeFingerprint;
192
247
  }
193
248
 
@@ -213,7 +268,7 @@ async function ensureTemplateDatabase(config, infra, cacheDir, templateFingerpri
213
268
  continue;
214
269
  }
215
270
 
216
- writeLocalCacheState(cacheDir, infra, desiredDbName, activeFingerprint);
271
+ writeCacheState(cacheDir, config, infra, desiredDbName, activeFingerprint);
217
272
  return activeFingerprint;
218
273
  }
219
274
  }
@@ -320,8 +375,13 @@ async function ensureRuntimeClone(config, infra, cacheDir, templateFingerprint,
320
375
  }
321
376
 
322
377
  const desiredDbName = buildRuntimeDatabaseName(serviceName, bindingKey, templateFingerprint);
323
- const existingDbName = readStateValue(path.join(config.stateDir, "local_database_name"));
324
- const existingFingerprint = readStateValue(path.join(config.stateDir, "local_template_fingerprint"));
378
+ const backend = config.testkit.database.provider;
379
+ const existingDbName =
380
+ readStateValue(path.join(config.stateDir, `${backend}_database_name`)) ||
381
+ readStateValue(path.join(config.stateDir, "local_database_name"));
382
+ const existingFingerprint =
383
+ readStateValue(path.join(config.stateDir, `${backend}_template_fingerprint`)) ||
384
+ readStateValue(path.join(config.stateDir, "local_template_fingerprint"));
325
385
  const needsReset =
326
386
  config.testkit.database.reset !== false ||
327
387
  existingFingerprint !== templateFingerprint ||
@@ -338,12 +398,17 @@ async function ensureRuntimeClone(config, infra, cacheDir, templateFingerprint,
338
398
  }
339
399
 
340
400
  fs.mkdirSync(config.stateDir, { recursive: true });
341
- fs.writeFileSync(path.join(config.stateDir, "database_backend"), "local");
401
+ fs.writeFileSync(path.join(config.stateDir, "database_backend"), backend);
342
402
  fs.writeFileSync(path.join(config.stateDir, "database_url"), buildDatabaseUrl(infra, desiredDbName));
343
- fs.writeFileSync(path.join(config.stateDir, "local_database_name"), desiredDbName);
344
- fs.writeFileSync(path.join(config.stateDir, "local_template_fingerprint"), templateFingerprint);
345
- fs.writeFileSync(path.join(config.stateDir, "local_template_database_name"), templateDbName);
346
- fs.writeFileSync(path.join(config.stateDir, "local_container_name"), infra.containerName);
403
+ fs.writeFileSync(path.join(config.stateDir, `${backend}_database_name`), desiredDbName);
404
+ fs.writeFileSync(path.join(config.stateDir, `${backend}_template_fingerprint`), templateFingerprint);
405
+ fs.writeFileSync(path.join(config.stateDir, `${backend}_template_database_name`), templateDbName);
406
+ if (backend === "local") {
407
+ fs.writeFileSync(path.join(config.stateDir, "local_container_name"), infra.containerName);
408
+ } else {
409
+ fs.writeFileSync(path.join(config.stateDir, "resource_name"), infra.resourceName);
410
+ writeResourceConnectionState(config.stateDir, infra);
411
+ }
347
412
  }
348
413
 
349
414
  function resolveDatabaseBindingKey(config) {
@@ -366,6 +431,15 @@ async function destroyLocalRuntimeDatabase(productDir, stateDir) {
366
431
  await dropDatabaseIfExists(infra, dbName);
367
432
  }
368
433
 
434
+ async function destroyResourceRuntimeDatabase(stateDir) {
435
+ const dbName = readStateValue(path.join(stateDir, "resource_database_name"));
436
+ if (!dbName) return;
437
+
438
+ const infra = resolveResourcePostgresInfraFromState(stateDir);
439
+ if (!infra) return;
440
+ await dropDatabaseIfExists(infra, dbName);
441
+ }
442
+
369
443
  async function ensureLocalContainer(productDir, database = {}) {
370
444
  const infraDir = getLocalInfraDir(productDir);
371
445
  fs.mkdirSync(infraDir, { recursive: true });
@@ -476,6 +550,21 @@ async function waitForLocalContainerReady(infra) {
476
550
  throw new Error(`Timed out waiting for local database container ${infra.containerName}`);
477
551
  }
478
552
 
553
+ async function waitForResourcePostgresReady(infra) {
554
+ const startedAt = Date.now();
555
+ while (Date.now() - startedAt < LOCAL_READY_TIMEOUT_MS) {
556
+ try {
557
+ await runAdminQuery(infra, ["-tAc", "SELECT 1"]);
558
+ return;
559
+ } catch (error) {
560
+ if (!isTransientAdminQueryConnectionError(error)) throw error;
561
+ await sleep(LOCAL_POLL_INTERVAL_MS);
562
+ }
563
+ }
564
+
565
+ throw new Error(`Timed out waiting for Postgres resource "${infra.resourceName}" at ${infra.host}:${infra.port}`);
566
+ }
567
+
479
568
  async function inspectContainer(containerName) {
480
569
  try {
481
570
  const { stdout } = await execa("docker", ["inspect", containerName]);
@@ -589,24 +678,48 @@ export async function waitForDatabaseConnectionsToDrain(infra, dbName, hooks = {
589
678
  }
590
679
 
591
680
  async function runAdminQuery(infra, args) {
592
- const commandArgs = [
593
- "exec",
594
- "-e",
595
- `PGPASSWORD=${infra.password}`,
596
- infra.containerName,
597
- "psql",
598
- "-v",
599
- "ON_ERROR_STOP=1",
600
- "-U",
601
- infra.user,
602
- "-d",
603
- LOCAL_ADMIN_DB,
604
- ...args,
605
- ];
681
+ const command = infra.containerName ? "docker" : "psql";
682
+ const commandArgs = infra.containerName
683
+ ? [
684
+ "exec",
685
+ "-e",
686
+ `PGPASSWORD=${infra.password}`,
687
+ infra.containerName,
688
+ "psql",
689
+ "-v",
690
+ "ON_ERROR_STOP=1",
691
+ "-U",
692
+ infra.user,
693
+ "-d",
694
+ infra.adminDatabase || LOCAL_ADMIN_DB,
695
+ ...args,
696
+ ]
697
+ : [
698
+ "-v",
699
+ "ON_ERROR_STOP=1",
700
+ "-h",
701
+ infra.host,
702
+ "-p",
703
+ String(infra.port),
704
+ "-U",
705
+ infra.user,
706
+ "-d",
707
+ infra.adminDatabase || LOCAL_ADMIN_DB,
708
+ ...args,
709
+ ];
710
+ const commandOptions = infra.containerName
711
+ ? {}
712
+ : {
713
+ env: {
714
+ ...process.env,
715
+ PGPASSWORD: infra.password,
716
+ ...(infra.sslMode ? { PGSSLMODE: infra.sslMode } : {}),
717
+ },
718
+ };
606
719
  const startedAt = Date.now();
607
720
  while (true) {
608
721
  try {
609
- const { stdout } = await execa("docker", commandArgs);
722
+ const { stdout } = await execa(command, commandArgs, commandOptions);
610
723
  return stdout;
611
724
  } catch (error) {
612
725
  if (
@@ -669,6 +782,75 @@ function buildDatabaseUrl(infra, dbName) {
669
782
  return buildDatabaseUrlModel(infra, dbName);
670
783
  }
671
784
 
785
+ function resolveResourcePostgresInfra(config, processEnv = process.env) {
786
+ const resourceName = String(config.testkit?.database?.resource || "").trim();
787
+ if (!resourceName) {
788
+ throw new Error("Resource-backed Postgres database requires database.resource");
789
+ }
790
+ const connections = parseResourceConnections(processEnv.TESTKIT_RESOURCE_CONNECTIONS_JSON);
791
+ const connection = connections[resourceName];
792
+ if (!connection) {
793
+ const available = Object.keys(connections).sort().join(", ") || "none";
794
+ throw new Error(`Postgres resource "${resourceName}" is not available. Available resources: ${available}`);
795
+ }
796
+ return normalizeResourcePostgresConnection(resourceName, connection);
797
+ }
798
+
799
+ function resolveResourcePostgresInfraFromState(stateDir, processEnv = process.env) {
800
+ const resourceName = readStateValue(path.join(stateDir, "resource_name"));
801
+ if (!resourceName) return null;
802
+ const connections = parseResourceConnections(processEnv.TESTKIT_RESOURCE_CONNECTIONS_JSON);
803
+ const connection = connections[resourceName] || readResourceConnectionState(stateDir);
804
+ return connection ? normalizeResourcePostgresConnection(resourceName, connection) : null;
805
+ }
806
+
807
+ function parseResourceConnections(raw) {
808
+ if (!raw) return {};
809
+ try {
810
+ const parsed = JSON.parse(raw);
811
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
812
+ } catch (error) {
813
+ throw new Error(`Invalid TESTKIT_RESOURCE_CONNECTIONS_JSON: ${error.message}`);
814
+ }
815
+ }
816
+
817
+ function normalizeResourcePostgresConnection(resourceName, connection) {
818
+ const fromUrl = connection.url ? parsePostgresConnectionUrl(connection.url) : {};
819
+ const host = connection.host || fromUrl.host;
820
+ const port = Number(connection.port || fromUrl.port || 5432);
821
+ const user = connection.user || fromUrl.user;
822
+ const password = connection.password || fromUrl.password || "";
823
+ const adminDatabase = connection.adminDatabase || connection.admin_database || fromUrl.database || LOCAL_ADMIN_DB;
824
+ const sslMode = connection.sslMode || connection.sslmode || fromUrl.sslMode || "disable";
825
+ if (!host) throw new Error(`Postgres resource "${resourceName}" connection is missing host`);
826
+ if (!Number.isInteger(port) || port <= 0) {
827
+ throw new Error(`Postgres resource "${resourceName}" connection has invalid port`);
828
+ }
829
+ if (!user) throw new Error(`Postgres resource "${resourceName}" connection is missing user`);
830
+ return {
831
+ backend: "resource",
832
+ resourceName,
833
+ host,
834
+ port,
835
+ user,
836
+ password,
837
+ adminDatabase,
838
+ sslMode,
839
+ };
840
+ }
841
+
842
+ function parsePostgresConnectionUrl(rawUrl) {
843
+ const parsed = new URL(rawUrl);
844
+ return {
845
+ host: parsed.hostname,
846
+ port: parsed.port ? Number(parsed.port) : 5432,
847
+ database: decodeURIComponent(parsed.pathname.replace(/^\//, "")) || LOCAL_ADMIN_DB,
848
+ user: decodeURIComponent(parsed.username || ""),
849
+ password: decodeURIComponent(parsed.password || ""),
850
+ sslMode: parsed.searchParams.get("sslmode") || undefined,
851
+ };
852
+ }
853
+
672
854
  function buildContainerName(productDir) {
673
855
  return buildContainerNameModel(productDir);
674
856
  }
@@ -692,11 +874,40 @@ function writeLocalInfraState(infraDir, infra) {
692
874
  fs.writeFileSync(path.join(infraDir, "port"), String(infra.port));
693
875
  }
694
876
 
695
- function writeLocalCacheState(cacheDir, infra, templateDbName, fingerprint) {
696
- fs.writeFileSync(path.join(cacheDir, "database_backend"), "local");
877
+ function writeCacheState(cacheDir, config, infra, templateDbName, fingerprint) {
878
+ const backend = config.testkit.database.provider;
879
+ fs.writeFileSync(path.join(cacheDir, "database_backend"), backend);
697
880
  fs.writeFileSync(path.join(cacheDir, "template_database_name"), templateDbName);
698
881
  fs.writeFileSync(path.join(cacheDir, "template_fingerprint"), fingerprint);
699
- fs.writeFileSync(path.join(cacheDir, "container_name"), infra.containerName);
882
+ if (backend === "local") {
883
+ fs.writeFileSync(path.join(cacheDir, "container_name"), infra.containerName);
884
+ } else {
885
+ fs.writeFileSync(path.join(cacheDir, "resource_name"), infra.resourceName);
886
+ writeResourceConnectionState(cacheDir, infra);
887
+ }
888
+ }
889
+
890
+ function writeResourceConnectionState(stateDir, infra) {
891
+ fs.writeFileSync(path.join(stateDir, "resource_host"), infra.host);
892
+ fs.writeFileSync(path.join(stateDir, "resource_port"), String(infra.port));
893
+ fs.writeFileSync(path.join(stateDir, "resource_user"), infra.user);
894
+ fs.writeFileSync(path.join(stateDir, "resource_password"), infra.password);
895
+ fs.writeFileSync(path.join(stateDir, "resource_admin_database"), infra.adminDatabase || LOCAL_ADMIN_DB);
896
+ fs.writeFileSync(path.join(stateDir, "resource_sslmode"), infra.sslMode || "disable");
897
+ }
898
+
899
+ function readResourceConnectionState(stateDir) {
900
+ const host = readStateValue(path.join(stateDir, "resource_host"));
901
+ const user = readStateValue(path.join(stateDir, "resource_user"));
902
+ if (!host || !user) return null;
903
+ return {
904
+ host,
905
+ port: Number(readStateValue(path.join(stateDir, "resource_port")) || 5432),
906
+ user,
907
+ password: readStateValue(path.join(stateDir, "resource_password")) || "",
908
+ adminDatabase: readStateValue(path.join(stateDir, "resource_admin_database")) || LOCAL_ADMIN_DB,
909
+ sslMode: readStateValue(path.join(stateDir, "resource_sslmode")) || "disable",
910
+ };
700
911
  }
701
912
 
702
913
  function getLocalInfraDir(productDir) {
@@ -711,6 +922,10 @@ function getLocalServiceCacheDir(productDir, serviceName) {
711
922
  return getLocalServiceCacheDirModel(productDir, serviceName);
712
923
  }
713
924
 
925
+ function getResourceLocksDir(productDir, resourceName) {
926
+ return getResourceLocksDirModel(productDir, resourceName);
927
+ }
928
+
714
929
  function hasRemainingLocalArtifacts(productDir) {
715
930
  return hasRemainingLocalArtifactsModel(productDir, readStateValue);
716
931
  }
@@ -2,7 +2,8 @@ import crypto from "crypto";
2
2
  import path from "path";
3
3
 
4
4
  export function buildDatabaseUrl(infra, dbName) {
5
- return `postgresql://${encodeURIComponent(infra.user)}:${encodeURIComponent(infra.password)}@${infra.host}:${infra.port}/${dbName}?sslmode=disable`;
5
+ const sslMode = infra.sslMode || "disable";
6
+ return `postgresql://${encodeURIComponent(infra.user)}:${encodeURIComponent(infra.password)}@${infra.host}:${infra.port}/${dbName}?sslmode=${encodeURIComponent(sslMode)}`;
6
7
  }
7
8
 
8
9
  export function buildContainerName(productDir) {
@@ -13,6 +13,10 @@ export function getLocalServiceCacheDir(productDir, serviceName) {
13
13
  return path.join(productDir, ".testkit", "_dbcache", serviceName);
14
14
  }
15
15
 
16
+ export function getResourceLocksDir(productDir, resourceName) {
17
+ return path.join(productDir, ".testkit", "_infra", "resource-postgres", resourceName, "locks");
18
+ }
19
+
16
20
  export function hasRemainingLocalArtifacts(productDir, readStateValue) {
17
21
  const root = path.join(productDir, ".testkit");
18
22
  if (!fs.existsSync(root)) return false;
@@ -123,7 +123,12 @@ export async function kilnLocalDown(context, name, options = {}) {
123
123
  const ssh = await sshFromManifest(manifest);
124
124
  const args = ["local", "down", name, ...(options.destroyState ? ["--destroy-state"] : [])];
125
125
  try {
126
- const result = await remoteTestkit(ssh, manifest.remoteProductDir, args);
126
+ const resourceConnections = manifestResourceConnections(manifest);
127
+ const result = await remoteTestkit(ssh, manifest.remoteProductDir, args, {
128
+ ...(Object.keys(resourceConnections).length > 0
129
+ ? { TESTKIT_RESOURCE_CONNECTIONS_JSON: JSON.stringify(resourceConnections) }
130
+ : {}),
131
+ });
127
132
  if (result.exitCode !== 0) {
128
133
  throw new Error(`remote testkit local down failed\n${result.stdout}${result.stderr}`);
129
134
  }
@@ -621,6 +626,14 @@ function pickAppliance(appliance) {
621
626
  };
622
627
  }
623
628
 
629
+ function manifestResourceConnections(manifest) {
630
+ return Object.fromEntries(
631
+ Object.entries(manifest.resources || {})
632
+ .map(([name, resource]) => [name, resource?.connection || null])
633
+ .filter(([_name, connection]) => connection && typeof connection === "object")
634
+ );
635
+ }
636
+
624
637
  function pickAPIConfig(api) {
625
638
  return {
626
639
  ...(api.apiUrl ? { apiUrl: api.apiUrl } : {}),
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elench/next-analysis",
3
- "version": "0.1.138",
3
+ "version": "0.1.140",
4
4
  "description": "SWC-backed Next.js source analysis primitives for Erench tools",
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elench/testkit-bridge",
3
- "version": "0.1.138",
3
+ "version": "0.1.140",
4
4
  "description": "Browser bridge helpers for testkit",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -22,7 +22,7 @@
22
22
  "typecheck": "tsc -p tsconfig.json --noEmit"
23
23
  },
24
24
  "dependencies": {
25
- "@elench/testkit-protocol": "0.1.138"
25
+ "@elench/testkit-protocol": "0.1.140"
26
26
  },
27
27
  "private": false
28
28
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elench/testkit-protocol",
3
- "version": "0.1.138",
3
+ "version": "0.1.140",
4
4
  "description": "Shared browser protocol for testkit bridge and extension consumers",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elench/ts-analysis",
3
- "version": "0.1.138",
3
+ "version": "0.1.140",
4
4
  "description": "TypeScript compiler-backed source analysis primitives for Erench tools",
5
5
  "type": "module",
6
6
  "exports": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elench/testkit",
3
- "version": "0.1.138",
3
+ "version": "0.1.140",
4
4
  "description": "Assistant-first CLI for running, inspecting, and debugging local testkit suites",
5
5
  "type": "module",
6
6
  "workspaces": [
@@ -98,10 +98,10 @@
98
98
  },
99
99
  "dependencies": {
100
100
  "@babel/code-frame": "^7.29.0",
101
- "@elench/next-analysis": "0.1.138",
102
- "@elench/testkit-bridge": "0.1.138",
103
- "@elench/testkit-protocol": "0.1.138",
104
- "@elench/ts-analysis": "0.1.138",
101
+ "@elench/next-analysis": "0.1.140",
102
+ "@elench/testkit-bridge": "0.1.140",
103
+ "@elench/testkit-protocol": "0.1.140",
104
+ "@elench/ts-analysis": "0.1.140",
105
105
  "@oclif/core": "^4.10.6",
106
106
  "@playwright/test": "^1.52.0",
107
107
  "esbuild": "^0.25.11",
@@ -1,188 +0,0 @@
1
- export declare const TESTKIT_BROWSER_PROTOCOL_VERSION = 1;
2
- export declare const TESTKIT_COVERAGE_GRAPH_VERSION = 1;
3
- export type BrowserTargetKind = "testId" | "role" | "text" | "css" | "xpath" | "component";
4
- export type BrowserConfidence = "low" | "medium" | "high";
5
- export type BrowserFailureState = "failing" | "healthy" | "unavailable";
6
- export type BrowserCoverageState = "covered" | "missing" | "unavailable";
7
- export type BridgeSurfaceImportance = "critical" | "high" | "medium" | "low";
8
- export type BridgeCoverageSupportKind = "direct" | "indirect" | "mixed";
9
- export type CoverageNodeKind = "page_view" | "ui_surface" | "ui_action" | "client_request" | "api_route" | "server_action" | "server_capability" | "data_capability" | "test_file";
10
- export type CoverageEdgeKind = "contains" | "renders" | "triggers" | "requests" | "handles" | "delegates_to" | "covers";
11
- export type CoverageEvidenceSource = "convention" | "static" | "runtime";
12
- export type CoverageGraphDiagnosticLevel = "info" | "warn";
13
- export interface BrowserTarget {
14
- kind: BrowserTargetKind;
15
- value: string;
16
- label?: string;
17
- confidence?: BrowserConfidence;
18
- }
19
- export interface BrowserMetadata {
20
- label?: string;
21
- origins?: string[];
22
- routes?: string[];
23
- targets?: BrowserTarget[];
24
- }
25
- export interface BrowserMetadataDocument {
26
- schemaVersion: number;
27
- browser: BrowserMetadata;
28
- }
29
- export interface CoverageGraphNode {
30
- id: string;
31
- kind: CoverageNodeKind;
32
- service: string;
33
- label: string;
34
- filePath?: string;
35
- route?: string;
36
- method?: string;
37
- path?: string;
38
- target?: BrowserTarget | null;
39
- metadata?: Record<string, string | number | boolean | null>;
40
- }
41
- export interface CoverageGraphEdge {
42
- id: string;
43
- kind: CoverageEdgeKind;
44
- from: string;
45
- to: string;
46
- confidence?: BrowserConfidence;
47
- metadata?: Record<string, string | number | boolean | null>;
48
- }
49
- export interface CoverageEvidenceDetails {
50
- requestPaths?: string[];
51
- route?: string;
52
- targets?: BrowserTarget[];
53
- }
54
- export interface CoverageEvidence {
55
- id: string;
56
- source: CoverageEvidenceSource;
57
- confidence?: BrowserConfidence;
58
- service: string;
59
- suiteName: string;
60
- type: string;
61
- testFilePath: string;
62
- coveredNodeIds: string[];
63
- details?: CoverageEvidenceDetails;
64
- }
65
- export interface CoverageGraphDiagnostic {
66
- level: CoverageGraphDiagnosticLevel;
67
- code: string;
68
- filePath: string;
69
- service: string;
70
- message: string;
71
- }
72
- export interface CoverageGraph {
73
- schemaVersion: number;
74
- nodes: CoverageGraphNode[];
75
- edges: CoverageGraphEdge[];
76
- evidence: CoverageEvidence[];
77
- diagnostics: CoverageGraphDiagnostic[];
78
- }
79
- export interface BridgeProductRef {
80
- name: string;
81
- directory: string;
82
- }
83
- export interface BridgeServiceRef {
84
- name: string;
85
- baseUrl: string;
86
- origin: string;
87
- }
88
- export interface BrowserMatchResponse {
89
- protocolVersion: number;
90
- url: string;
91
- origin: string;
92
- route: string;
93
- matched: boolean;
94
- product: BridgeProductRef;
95
- service: BridgeServiceRef | null;
96
- }
97
- export interface BridgeRunSummary {
98
- artifactAvailable: boolean;
99
- generatedAt: string | null;
100
- status: string | null;
101
- }
102
- export interface BridgeSupportingTestRef {
103
- service: string;
104
- suite: string;
105
- type: string;
106
- filePath: string;
107
- label: string;
108
- status?: "passed" | "failed" | "skipped" | "not_run";
109
- error?: string | null;
110
- }
111
- export interface BridgeCoverageViaNodeRef {
112
- id: string;
113
- kind: CoverageNodeKind;
114
- label: string;
115
- route?: string;
116
- method?: string;
117
- path?: string;
118
- }
119
- export interface FailureOverlayEntry {
120
- id: string;
121
- kind: CoverageNodeKind;
122
- label: string;
123
- service: string;
124
- route?: string | null;
125
- targets: BrowserTarget[];
126
- failedTests: BridgeSupportingTestRef[];
127
- viaNodes: BridgeCoverageViaNodeRef[];
128
- importance?: BridgeSurfaceImportance;
129
- surfaceKind?: string | null;
130
- reason?: string | null;
131
- }
132
- export interface CoverageOverlayEntry {
133
- id: string;
134
- kind: CoverageNodeKind;
135
- label: string;
136
- service: string;
137
- route?: string | null;
138
- targets: BrowserTarget[];
139
- supportingTests: BridgeSupportingTestRef[];
140
- viaNodes: BridgeCoverageViaNodeRef[];
141
- confidence: BrowserConfidence;
142
- importance?: BridgeSurfaceImportance;
143
- surfaceKind?: string | null;
144
- supportKind?: BridgeCoverageSupportKind;
145
- reason?: string | null;
146
- }
147
- export interface PageOverlayResponse {
148
- protocolVersion: number;
149
- page: {
150
- url: string;
151
- origin: string;
152
- route: string;
153
- };
154
- match: BrowserMatchResponse;
155
- run: BridgeRunSummary;
156
- summary: {
157
- failureState: BrowserFailureState;
158
- coverageState: BrowserCoverageState;
159
- relatedFailureCount: number;
160
- relatedCoverageCount: number;
161
- coverageBreakdown?: {
162
- direct: number;
163
- indirect: number;
164
- mixed: number;
165
- };
166
- };
167
- failures: FailureOverlayEntry[];
168
- coverage: CoverageOverlayEntry[];
169
- }
170
- export interface BridgeErrorResponse {
171
- protocolVersion: number;
172
- error: {
173
- code: string;
174
- message: string;
175
- };
176
- }
177
- export declare function normalizeBrowserTarget(value: unknown): BrowserTarget | null;
178
- export declare function normalizeBrowserMetadata(value: unknown): BrowserMetadata | null;
179
- export declare function normalizeBrowserMetadataDocument(value: unknown): BrowserMetadataDocument | null;
180
- export declare function normalizeCoverageGraphNode(value: unknown): CoverageGraphNode | null;
181
- export declare function normalizeCoverageGraphEdge(value: unknown): CoverageGraphEdge | null;
182
- export declare function normalizeCoverageEvidence(value: unknown): CoverageEvidence | null;
183
- export declare function normalizeCoverageGraphDiagnostic(value: unknown): CoverageGraphDiagnostic | null;
184
- export declare function normalizeCoverageGraph(value: unknown): CoverageGraph | null;
185
- export declare function isPageOverlayResponse(value: unknown): value is PageOverlayResponse;
186
- export declare function normalizePageOverlayResponse(value: unknown): PageOverlayResponse | null;
187
- export declare function createBridgeErrorResponse(code: string, message: string): BridgeErrorResponse;
188
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,293 +0,0 @@
1
- export const TESTKIT_BROWSER_PROTOCOL_VERSION = 1;
2
- export const TESTKIT_COVERAGE_GRAPH_VERSION = 1;
3
- const TARGET_KINDS = new Set(["testId", "role", "text", "css", "xpath", "component"]);
4
- const CONFIDENCE_LEVELS = new Set(["low", "medium", "high"]);
5
- const FAILURE_STATES = new Set(["failing", "healthy", "unavailable"]);
6
- const COVERAGE_STATES = new Set(["covered", "missing", "unavailable"]);
7
- const NODE_KINDS = new Set([
8
- "page_view",
9
- "ui_surface",
10
- "ui_action",
11
- "client_request",
12
- "api_route",
13
- "server_action",
14
- "server_capability",
15
- "data_capability",
16
- "test_file",
17
- ]);
18
- const EDGE_KINDS = new Set([
19
- "contains",
20
- "renders",
21
- "triggers",
22
- "requests",
23
- "handles",
24
- "delegates_to",
25
- "covers",
26
- ]);
27
- const EVIDENCE_SOURCES = new Set(["convention", "static", "runtime"]);
28
- const DIAGNOSTIC_LEVELS = new Set(["info", "warn"]);
29
- export function normalizeBrowserTarget(value) {
30
- if (!value || typeof value !== "object" || Array.isArray(value))
31
- return null;
32
- const record = value;
33
- const kind = normalizeOptionalString(record.kind);
34
- const targetValue = normalizeOptionalString(record.value);
35
- if (!kind || !isSetValue(TARGET_KINDS, kind) || !targetValue)
36
- return null;
37
- const label = normalizeOptionalString(record.label);
38
- const confidence = normalizeOptionalString(record.confidence);
39
- return {
40
- kind,
41
- value: targetValue,
42
- ...(label ? { label } : {}),
43
- ...(confidence && isSetValue(CONFIDENCE_LEVELS, confidence) ? { confidence } : {}),
44
- };
45
- }
46
- export function normalizeBrowserMetadata(value) {
47
- if (!value || typeof value !== "object" || Array.isArray(value))
48
- return null;
49
- const record = value;
50
- const label = normalizeOptionalString(record.label);
51
- const origins = normalizeStringArray(record.origins);
52
- const routes = normalizeStringArray(record.routes);
53
- const targets = Array.isArray(record.targets)
54
- ? record.targets.map((entry) => normalizeBrowserTarget(entry)).filter((entry) => Boolean(entry))
55
- : [];
56
- if (!label && origins.length === 0 && routes.length === 0 && targets.length === 0) {
57
- return null;
58
- }
59
- return {
60
- ...(label ? { label } : {}),
61
- ...(origins.length > 0 ? { origins } : {}),
62
- ...(routes.length > 0 ? { routes } : {}),
63
- ...(targets.length > 0 ? { targets } : {}),
64
- };
65
- }
66
- export function normalizeBrowserMetadataDocument(value) {
67
- if (!value || typeof value !== "object" || Array.isArray(value))
68
- return null;
69
- const record = value;
70
- const schemaVersion = Number.isInteger(record.schemaVersion) && Number(record.schemaVersion) > 0
71
- ? Number(record.schemaVersion)
72
- : TESTKIT_BROWSER_PROTOCOL_VERSION;
73
- const browser = normalizeBrowserMetadata(record.browser);
74
- if (!browser)
75
- return null;
76
- return {
77
- schemaVersion,
78
- browser,
79
- };
80
- }
81
- export function normalizeCoverageGraphNode(value) {
82
- if (!value || typeof value !== "object" || Array.isArray(value))
83
- return null;
84
- const record = value;
85
- const id = normalizeOptionalString(record.id);
86
- const kind = normalizeOptionalString(record.kind);
87
- const service = normalizeOptionalString(record.service);
88
- const label = normalizeOptionalString(record.label);
89
- if (!id || !kind || !isSetValue(NODE_KINDS, kind) || !service || !label)
90
- return null;
91
- const filePath = normalizeOptionalString(record.filePath);
92
- const route = normalizeOptionalString(record.route);
93
- const method = normalizeOptionalString(record.method);
94
- const path = normalizeOptionalString(record.path);
95
- const target = normalizeBrowserTarget(record.target);
96
- const metadata = normalizeMetadataRecord(record.metadata);
97
- return {
98
- id,
99
- kind,
100
- service,
101
- label,
102
- ...(filePath ? { filePath } : {}),
103
- ...(route ? { route } : {}),
104
- ...(method ? { method } : {}),
105
- ...(path ? { path } : {}),
106
- ...(target ? { target } : {}),
107
- ...(metadata ? { metadata } : {}),
108
- };
109
- }
110
- export function normalizeCoverageGraphEdge(value) {
111
- if (!value || typeof value !== "object" || Array.isArray(value))
112
- return null;
113
- const record = value;
114
- const id = normalizeOptionalString(record.id);
115
- const kind = normalizeOptionalString(record.kind);
116
- const from = normalizeOptionalString(record.from);
117
- const to = normalizeOptionalString(record.to);
118
- if (!id || !kind || !isSetValue(EDGE_KINDS, kind) || !from || !to)
119
- return null;
120
- const confidence = normalizeOptionalString(record.confidence);
121
- const metadata = normalizeMetadataRecord(record.metadata);
122
- return {
123
- id,
124
- kind,
125
- from,
126
- to,
127
- ...(confidence && isSetValue(CONFIDENCE_LEVELS, confidence) ? { confidence } : {}),
128
- ...(metadata ? { metadata } : {}),
129
- };
130
- }
131
- export function normalizeCoverageEvidence(value) {
132
- if (!value || typeof value !== "object" || Array.isArray(value))
133
- return null;
134
- const record = value;
135
- const id = normalizeOptionalString(record.id);
136
- const source = normalizeOptionalString(record.source);
137
- const service = normalizeOptionalString(record.service);
138
- const suiteName = normalizeOptionalString(record.suiteName);
139
- const type = normalizeOptionalString(record.type) || normalizeOptionalString(record.selectionType);
140
- const testFilePath = normalizeOptionalString(record.testFilePath);
141
- const coveredNodeIds = normalizeStringArray(record.coveredNodeIds);
142
- if (!id ||
143
- !source ||
144
- !isSetValue(EVIDENCE_SOURCES, source) ||
145
- !service ||
146
- !suiteName ||
147
- !type ||
148
- !testFilePath ||
149
- coveredNodeIds.length === 0) {
150
- return null;
151
- }
152
- const confidence = normalizeOptionalString(record.confidence);
153
- const details = normalizeEvidenceDetails(record.details);
154
- return {
155
- id,
156
- source,
157
- service,
158
- suiteName,
159
- type,
160
- testFilePath,
161
- coveredNodeIds,
162
- ...(confidence && isSetValue(CONFIDENCE_LEVELS, confidence) ? { confidence } : {}),
163
- ...(details ? { details } : {}),
164
- };
165
- }
166
- export function normalizeCoverageGraphDiagnostic(value) {
167
- if (!value || typeof value !== "object" || Array.isArray(value))
168
- return null;
169
- const record = value;
170
- const level = normalizeOptionalString(record.level);
171
- const code = normalizeOptionalString(record.code);
172
- const filePath = normalizeOptionalString(record.filePath);
173
- const service = normalizeOptionalString(record.service);
174
- const message = normalizeOptionalString(record.message);
175
- if (!level || !code || !filePath || !service || !message)
176
- return null;
177
- if (!isSetValue(DIAGNOSTIC_LEVELS, level))
178
- return null;
179
- return { level, code, filePath, service, message };
180
- }
181
- export function normalizeCoverageGraph(value) {
182
- if (!value || typeof value !== "object" || Array.isArray(value))
183
- return null;
184
- const record = value;
185
- const schemaVersion = Number.isInteger(record.schemaVersion) && Number(record.schemaVersion) > 0
186
- ? Number(record.schemaVersion)
187
- : TESTKIT_COVERAGE_GRAPH_VERSION;
188
- const nodes = Array.isArray(record.nodes)
189
- ? record.nodes.map((entry) => normalizeCoverageGraphNode(entry)).filter((entry) => Boolean(entry))
190
- : [];
191
- const edges = Array.isArray(record.edges)
192
- ? record.edges.map((entry) => normalizeCoverageGraphEdge(entry)).filter((entry) => Boolean(entry))
193
- : [];
194
- const evidence = Array.isArray(record.evidence)
195
- ? record.evidence.map((entry) => normalizeCoverageEvidence(entry)).filter((entry) => Boolean(entry))
196
- : [];
197
- const diagnostics = Array.isArray(record.diagnostics)
198
- ? record.diagnostics
199
- .map((entry) => normalizeCoverageGraphDiagnostic(entry))
200
- .filter((entry) => Boolean(entry))
201
- : [];
202
- if (nodes.length === 0)
203
- return null;
204
- return {
205
- schemaVersion,
206
- nodes,
207
- edges,
208
- evidence,
209
- diagnostics,
210
- };
211
- }
212
- export function isPageOverlayResponse(value) {
213
- return Boolean(normalizePageOverlayResponse(value));
214
- }
215
- export function normalizePageOverlayResponse(value) {
216
- if (!value || typeof value !== "object" || Array.isArray(value))
217
- return null;
218
- const record = value;
219
- if (record.protocolVersion !== TESTKIT_BROWSER_PROTOCOL_VERSION)
220
- return null;
221
- if (!record.page || typeof record.page !== "object")
222
- return null;
223
- if (!record.match || typeof record.match !== "object")
224
- return null;
225
- if (!record.summary || typeof record.summary !== "object")
226
- return null;
227
- if (!Array.isArray(record.coverage) || !Array.isArray(record.failures))
228
- return null;
229
- const summary = record.summary;
230
- if (!isSetValue(FAILURE_STATES, summary.failureState))
231
- return null;
232
- if (!isSetValue(COVERAGE_STATES, summary.coverageState))
233
- return null;
234
- return record;
235
- }
236
- export function createBridgeErrorResponse(code, message) {
237
- return {
238
- protocolVersion: TESTKIT_BROWSER_PROTOCOL_VERSION,
239
- error: {
240
- code,
241
- message,
242
- },
243
- };
244
- }
245
- function normalizeEvidenceDetails(value) {
246
- if (!value || typeof value !== "object" || Array.isArray(value))
247
- return null;
248
- const record = value;
249
- const requestPaths = normalizeStringArray(record.requestPaths);
250
- const route = normalizeOptionalString(record.route);
251
- const targets = Array.isArray(record.targets)
252
- ? record.targets.map((entry) => normalizeBrowserTarget(entry)).filter((entry) => Boolean(entry))
253
- : [];
254
- if (requestPaths.length === 0 && !route && targets.length === 0)
255
- return null;
256
- return {
257
- ...(requestPaths.length > 0 ? { requestPaths } : {}),
258
- ...(route ? { route } : {}),
259
- ...(targets.length > 0 ? { targets } : {}),
260
- };
261
- }
262
- function normalizeMetadataRecord(value) {
263
- if (!value || typeof value !== "object" || Array.isArray(value))
264
- return null;
265
- const normalized = {};
266
- for (const [key, entry] of Object.entries(value)) {
267
- const normalizedKey = normalizeOptionalString(key);
268
- if (!normalizedKey)
269
- continue;
270
- if (entry === null ||
271
- typeof entry === "string" ||
272
- typeof entry === "number" ||
273
- typeof entry === "boolean") {
274
- normalized[normalizedKey] = entry;
275
- }
276
- }
277
- return Object.keys(normalized).length > 0 ? normalized : null;
278
- }
279
- function normalizeStringArray(value) {
280
- if (!Array.isArray(value))
281
- return [];
282
- return value.map((entry) => normalizeOptionalString(entry)).filter((entry) => Boolean(entry));
283
- }
284
- function normalizeOptionalString(value) {
285
- if (typeof value !== "string")
286
- return null;
287
- const normalized = value.trim();
288
- return normalized.length > 0 ? normalized : null;
289
- }
290
- function isSetValue(set, value) {
291
- return typeof value === "string" && set.has(value);
292
- }
293
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,25 +0,0 @@
1
- {
2
- "name": "@elench/testkit-protocol",
3
- "version": "0.1.137",
4
- "description": "Shared browser protocol for testkit bridge and extension consumers",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "types": "./dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "default": "./dist/index.js"
12
- },
13
- "./package.json": "./package.json"
14
- },
15
- "files": [
16
- "dist/",
17
- "package.json"
18
- ],
19
- "scripts": {
20
- "build": "tsc -p tsconfig.build.json",
21
- "clean": "rm -rf dist",
22
- "typecheck": "tsc -p tsconfig.json --noEmit"
23
- },
24
- "private": false
25
- }