@isentinel/jest-roblox 0.2.5 → 0.2.6

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.
@@ -60,37 +60,12 @@ function extractJsonFromOutput(output) {
60
60
  }
61
61
  function parseJestOutput(output) {
62
62
  const trimmed = output.trim();
63
- if (trimmed.startsWith("{")) {
64
- const parsed = JSON.parse(trimmed);
65
- const coverageData = extractCoverageData(parsed);
66
- const luauTiming = extractLuauTiming(parsed);
67
- const setupSeconds = extractSetupSeconds(parsed);
68
- const snapshotWrites = extractSnapshotWrites(parsed);
69
- const unwrapped = unwrapResult(parsed);
70
- if (unwrapped["kind"] === "ExecutionError") {
71
- const errorMessage = extractExecutionError(unwrapped);
72
- throw new Error(`Jest execution failed: ${errorMessage}`);
73
- }
74
- if (unwrapped["results"] !== void 0 && typeof unwrapped["results"] === "object") return {
75
- coverageData,
76
- luauTiming,
77
- result: validateJestResult(unwrapped["results"]),
78
- setupSeconds,
79
- snapshotWrites
80
- };
81
- try {
82
- return {
83
- coverageData,
84
- luauTiming,
85
- result: validateJestResult(unwrapped),
86
- setupSeconds,
87
- snapshotWrites
88
- };
89
- } catch {}
90
- }
63
+ if (trimmed.startsWith("{")) try {
64
+ return parseParsedOutput(JSON.parse(trimmed));
65
+ } catch {}
91
66
  const jsonString = extractJsonFromOutput(output);
92
67
  if (jsonString === void 0) throw new Error(`No valid Jest result JSON found in output, output was:\n${output}`);
93
- return { result: validateJestResult(JSON.parse(jsonString)) };
68
+ return parseParsedOutput(JSON.parse(jsonString));
94
69
  }
95
70
  function countBraces(line) {
96
71
  let count = 0;
@@ -201,6 +176,31 @@ function extractSetupSeconds(parsed) {
201
176
  if (typeof setup !== "number") return;
202
177
  return setup;
203
178
  }
179
+ function parseParsedOutput(parsed) {
180
+ const coverageData = extractCoverageData(parsed);
181
+ const luauTiming = extractLuauTiming(parsed);
182
+ const setupSeconds = extractSetupSeconds(parsed);
183
+ const snapshotWrites = extractSnapshotWrites(parsed);
184
+ const unwrapped = unwrapResult(parsed);
185
+ if (unwrapped["kind"] === "ExecutionError") {
186
+ const errorMessage = extractExecutionError(unwrapped);
187
+ throw new Error(`Jest execution failed: ${errorMessage}`);
188
+ }
189
+ if (unwrapped["results"] !== void 0 && typeof unwrapped["results"] === "object") return {
190
+ coverageData,
191
+ luauTiming,
192
+ result: validateJestResult(unwrapped["results"]),
193
+ setupSeconds,
194
+ snapshotWrites
195
+ };
196
+ return {
197
+ coverageData,
198
+ luauTiming,
199
+ result: validateJestResult(unwrapped),
200
+ setupSeconds,
201
+ snapshotWrites
202
+ };
203
+ }
204
204
  //#endregion
205
205
  //#region packages/roblox-runner/dist/index.mjs
206
206
  const CACHE_DIR_NAME = "jest-roblox";
@@ -520,7 +520,7 @@ function generateTestScript(options) {
520
520
  //#endregion
521
521
  //#region src/backends/open-cloud.ts
522
522
  const PARALLEL_AUTO_CAP = 3;
523
- const OPEN_CLOUD_BASE_URL = "https://apis.roblox.com";
523
+ const DEFAULT_OPEN_CLOUD_BASE_URL = "https://apis.roblox.com";
524
524
  const RATE_LIMIT_DEFAULT_WAIT_MS = 5e3;
525
525
  const MAX_RATE_LIMIT_RETRIES = 5;
526
526
  const taskResponse = type({ path: "string" });
@@ -535,12 +535,14 @@ const envelopeSchema$1 = type({ entries: type({
535
535
  "jestOutput": "string"
536
536
  }).array() });
537
537
  var OpenCloudBackend = class {
538
+ baseUrl;
538
539
  credentials;
539
540
  http;
540
541
  readFile;
541
542
  sleepFn;
542
543
  kind = "open-cloud";
543
544
  constructor(credentials, options) {
545
+ this.baseUrl = resolveOpenCloudBaseUrl();
544
546
  this.credentials = credentials;
545
547
  this.http = options?.http ?? createFetchClient({ "x-api-key": credentials.apiKey });
546
548
  this.readFile = options?.readFile ?? ((filePath) => fs$1.readFileSync(filePath));
@@ -587,7 +589,7 @@ var OpenCloudBackend = class {
587
589
  };
588
590
  }
589
591
  async createExecutionTask(inputs, timeoutMs) {
590
- const url = `${OPEN_CLOUD_BASE_URL}/cloud/v2/universes/${this.credentials.universeId}/places/${this.credentials.placeId}/luau-execution-session-tasks`;
592
+ const url = `${this.baseUrl}/cloud/v2/universes/${this.credentials.universeId}/places/${this.credentials.placeId}/luau-execution-session-tasks`;
591
593
  const script = generateTestScript(inputs);
592
594
  const response = await this.http.request("POST", url, { body: {
593
595
  script,
@@ -597,7 +599,7 @@ var OpenCloudBackend = class {
597
599
  return taskResponse.assert(response.body).path;
598
600
  }
599
601
  async pollForCompletion(taskPath, timeoutMs, pollIntervalMs) {
600
- const url = `${OPEN_CLOUD_BASE_URL}/cloud/v2/${taskPath}`;
602
+ const url = `${this.baseUrl}/cloud/v2/${taskPath}`;
601
603
  const startTime = Date.now();
602
604
  let rateLimitRetries = 0;
603
605
  while (Date.now() - startTime < timeoutMs) {
@@ -657,7 +659,7 @@ var OpenCloudBackend = class {
657
659
  return false;
658
660
  }
659
661
  async uploadPlaceData(placeData) {
660
- const url = `${OPEN_CLOUD_BASE_URL}/universes/v1/${this.credentials.universeId}/places/${this.credentials.placeId}/versions?versionType=Saved`;
662
+ const url = `${this.baseUrl}/universes/v1/${this.credentials.universeId}/places/${this.credentials.placeId}/versions?versionType=Saved`;
661
663
  const response = await this.http.request("POST", url, {
662
664
  body: placeData,
663
665
  headers: { "Content-Type": "application/octet-stream" }
@@ -678,6 +680,11 @@ function createOpenCloudBackend() {
678
680
  universeId
679
681
  });
680
682
  }
683
+ function resolveOpenCloudBaseUrl() {
684
+ const override = process.env["JEST_ROBLOX_OPEN_CLOUD_BASE_URL"];
685
+ if (override === void 0 || override.trim() === "") return DEFAULT_OPEN_CLOUD_BASE_URL;
686
+ return override.replace(/\/+$/, "");
687
+ }
681
688
  function resolveBucketCount(parallel, jobCount) {
682
689
  if (parallel === void 0) return 1;
683
690
  if (parallel === "auto") return Math.min(jobCount, PARALLEL_AUTO_CAP);
@@ -995,6 +1002,35 @@ function resolveTree(node, currentDirectory, originalRoot, visited) {
995
1002
  }
996
1003
  return resolved;
997
1004
  }
1005
+ function collectMounts(node, currentDataModelPath, classify) {
1006
+ const result = [];
1007
+ walk(node, currentDataModelPath, classify, result);
1008
+ return result;
1009
+ }
1010
+ function pruneAncestors(paths) {
1011
+ return paths.filter((candidate) => !paths.some((other) => other !== candidate && candidate.startsWith(`${other}/`)));
1012
+ }
1013
+ function addDirectoryMount(node, dataModelPath, classify, result) {
1014
+ const rawPath = node.$path;
1015
+ if (typeof rawPath !== "string") return;
1016
+ if (rawPath.endsWith(".project.json")) return;
1017
+ const fsPath = rawPath.replace(/\/$/, "");
1018
+ if (classify(fsPath) === "directory") result.push({
1019
+ dataModelPath,
1020
+ fsPath
1021
+ });
1022
+ }
1023
+ function isTreeChild(value) {
1024
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1025
+ }
1026
+ function walk(node, currentDataModelPath, classify, result) {
1027
+ for (const [key, value] of Object.entries(node)) {
1028
+ if (key.startsWith("$") || !isTreeChild(value)) continue;
1029
+ const childDataModelPath = currentDataModelPath === "" ? key : `${currentDataModelPath}/${key}`;
1030
+ addDirectoryMount(value, childDataModelPath, classify, result);
1031
+ walk(value, childDataModelPath, classify, result);
1032
+ }
1033
+ }
998
1034
  function matchNodePath(childNode, targetPath, childDataModelPath) {
999
1035
  const nodePath = childNode.$path;
1000
1036
  if (typeof nodePath !== "string") return;
@@ -3604,4 +3640,4 @@ function writeGameOutput(filePath, entries) {
3604
3640
  fs$1.writeFileSync(absolutePath, JSON.stringify(entries, null, 2));
3605
3641
  }
3606
3642
  //#endregion
3607
- export { collectPaths as A, generateTestScript as B, formatFailure as C, formatTypecheckSummary as D, formatTestSummary as E, StudioBackend as F, defineProject as G, ROOT_ONLY_KEYS as H, createStudioBackend as I, LuauScriptError as J, isValidBackend as K, OpenCloudBackend as L, resolveNestedProjects as M, loadConfig$1 as N, formatBanner as O, resolveConfig as P, createOpenCloudBackend as R, formatAgentMultiProject as S, formatResult as T, VALID_BACKENDS as U, DEFAULT_CONFIG as V, defineConfig as W, parseJestOutput as X, extractJsonFromOutput as Y, resolveTsconfigDirectories as _, formatAnnotations as a, formatJson as b, visitBlock as c, buildProjectJob as d, execute as f, processProjectResult as g, loadCoverageManifest as h, runTypecheck as i, findInTree as j, combineSourceMappers as k, visitExpression as l, formatExecuteOutput as m, parseGameOutput as n, formatJobSummary as o, executeBackend as p, hashBuffer as q, writeGameOutput as r, resolveGitHubActionsOptions as s, formatGameOutputNotice as t, visitStatement as u, rojoProjectSchema as v, formatMultiProjectResult as w, writeJsonFile as x, findFormatterOptions as y, buildJestArgv as z };
3643
+ export { collectMounts as A, createOpenCloudBackend as B, formatFailure as C, formatTypecheckSummary as D, formatTestSummary as E, loadConfig$1 as F, VALID_BACKENDS as G, generateTestScript as H, resolveConfig as I, isValidBackend as J, defineConfig as K, StudioBackend as L, findInTree as M, pruneAncestors as N, formatBanner as O, resolveNestedProjects as P, parseJestOutput as Q, createStudioBackend as R, formatAgentMultiProject as S, formatResult as T, DEFAULT_CONFIG as U, buildJestArgv as V, ROOT_ONLY_KEYS as W, LuauScriptError as X, hashBuffer as Y, extractJsonFromOutput as Z, resolveTsconfigDirectories as _, formatAnnotations as a, formatJson as b, visitBlock as c, buildProjectJob as d, execute as f, processProjectResult as g, loadCoverageManifest as h, runTypecheck as i, collectPaths as j, combineSourceMappers as k, visitExpression as l, formatExecuteOutput as m, parseGameOutput as n, formatJobSummary as o, executeBackend as p, defineProject as q, writeGameOutput as r, resolveGitHubActionsOptions as s, formatGameOutputNotice as t, visitStatement as u, rojoProjectSchema as v, formatMultiProjectResult as w, writeJsonFile as x, findFormatterOptions as y, OpenCloudBackend as z };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as defineConfig, C as FormatterEntry, D as ROOT_ONLY_KEYS, E as ProjectTestConfig, M as Argv, O as ResolvedConfig, S as DisplayName, T as ProjectEntry, _ as ResolvedProjectConfig, a as formatExecuteOutput, b as ConfigInput, c as Backend, d as extractJsonFromOutput, f as parseJestOutput, g as TestStatus, h as TestFileResult, i as execute, j as defineProject, k as SnapshotFormatOptions, l as BackendOptions, m as TestCaseResult, n as ExecuteResult, o as TimingResult, p as JestResult, r as FormatOutputOptions, s as SourceMapper, t as ExecuteOptions, u as BackendResult, v as CliOptions, w as InlineProjectConfig, x as DEFAULT_CONFIG, y as Config } from "./executor-B2IDh6bH.mjs";
1
+ import { A as defineConfig, C as FormatterEntry, D as ROOT_ONLY_KEYS, E as ProjectTestConfig, M as Argv, O as ResolvedConfig, S as DisplayName, T as ProjectEntry, _ as ResolvedProjectConfig, a as formatExecuteOutput, b as ConfigInput, c as Backend, d as extractJsonFromOutput, f as parseJestOutput, g as TestStatus, h as TestFileResult, i as execute, j as defineProject, k as SnapshotFormatOptions, l as BackendOptions, m as TestCaseResult, n as ExecuteResult, o as TimingResult, p as JestResult, r as FormatOutputOptions, s as SourceMapper, t as ExecuteOptions, u as BackendResult, v as CliOptions, w as InlineProjectConfig, x as DEFAULT_CONFIG, y as Config } from "./executor-COuwZJJX.mjs";
2
2
  import { WebSocket, WebSocketServer } from "ws";
3
3
  import buffer from "node:buffer";
4
4
 
@@ -31,6 +31,7 @@ interface OpenCloudOptions {
31
31
  }
32
32
  type FileReader = (path: string) => buffer.Buffer;
33
33
  declare class OpenCloudBackend implements Backend {
34
+ private readonly baseUrl;
34
35
  private readonly credentials;
35
36
  private readonly http;
36
37
  private readonly readFile;
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { B as generateTestScript, C as formatFailure, E as formatTestSummary, F as StudioBackend, G as defineProject, H as ROOT_ONLY_KEYS, I as createStudioBackend, L as OpenCloudBackend, N as loadConfig, P as resolveConfig, R as createOpenCloudBackend, T as formatResult, V as DEFAULT_CONFIG, W as defineConfig, X as parseJestOutput, Y as extractJsonFromOutput, a as formatAnnotations, b as formatJson, c as visitBlock, f as execute, i as runTypecheck, l as visitExpression, m as formatExecuteOutput, n as parseGameOutput, o as formatJobSummary, r as writeGameOutput, t as formatGameOutputNotice, u as visitStatement, x as writeJsonFile, z as buildJestArgv } from "./game-output-BtWj32M8.mjs";
1
+ import { B as createOpenCloudBackend, C as formatFailure, E as formatTestSummary, F as loadConfig, H as generateTestScript, I as resolveConfig, K as defineConfig, L as StudioBackend, Q as parseJestOutput, R as createStudioBackend, T as formatResult, U as DEFAULT_CONFIG, V as buildJestArgv, W as ROOT_ONLY_KEYS, Z as extractJsonFromOutput, a as formatAnnotations, b as formatJson, c as visitBlock, f as execute, i as runTypecheck, l as visitExpression, m as formatExecuteOutput, n as parseGameOutput, o as formatJobSummary, q as defineProject, r as writeGameOutput, t as formatGameOutputNotice, u as visitStatement, x as writeJsonFile, z as OpenCloudBackend } from "./game-output-CCPIQMWm.mjs";
2
2
  export { DEFAULT_CONFIG, OpenCloudBackend, ROOT_ONLY_KEYS, StudioBackend, buildJestArgv, createOpenCloudBackend, createStudioBackend, defineConfig, defineProject, execute, extractJsonFromOutput, formatAnnotations, formatExecuteOutput, formatFailure, formatGameOutputNotice, formatJobSummary, formatJson, formatResult, formatTestSummary, generateTestScript, loadConfig, parseGameOutput, parseJestOutput, resolveConfig, runTypecheck, visitBlock, visitExpression, visitStatement, writeGameOutput, writeJsonFile };
Binary file