@quenty/studio-bridge 0.18.1 → 0.19.0

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.
Files changed (66) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/src/bridge/bridge-session.d.ts.map +1 -1
  3. package/dist/src/bridge/bridge-session.js +1 -0
  4. package/dist/src/bridge/bridge-session.js.map +1 -1
  5. package/dist/src/bridge/bridge-session.test.js +36 -0
  6. package/dist/src/bridge/bridge-session.test.js.map +1 -1
  7. package/dist/src/bridge/types.d.ts +8 -2
  8. package/dist/src/bridge/types.d.ts.map +1 -1
  9. package/dist/src/bridge/types.js.map +1 -1
  10. package/dist/src/commands/framework/action-loader.d.ts +5 -5
  11. package/dist/src/commands/framework/action-loader.js +7 -7
  12. package/dist/src/commands/framework/action-loader.js.map +1 -1
  13. package/dist/src/commands/framework/action-loader.test.d.ts +1 -1
  14. package/dist/src/commands/framework/action-loader.test.js +15 -15
  15. package/dist/src/commands/framework/action-loader.test.js.map +1 -1
  16. package/dist/src/index.d.ts +1 -1
  17. package/dist/src/index.d.ts.map +1 -1
  18. package/dist/src/index.js.map +1 -1
  19. package/dist/src/server/plugin-detection.test.js +1 -1
  20. package/dist/src/server/plugin-detection.test.js.map +1 -1
  21. package/dist/src/server/studio-bridge-server.d.ts +10 -2
  22. package/dist/src/server/studio-bridge-server.d.ts.map +1 -1
  23. package/dist/src/server/studio-bridge-server.js +3 -2
  24. package/dist/src/server/studio-bridge-server.js.map +1 -1
  25. package/dist/src/server/studio-bridge-server.test.js +39 -1
  26. package/dist/src/server/studio-bridge-server.test.js.map +1 -1
  27. package/dist/src/server/web-socket-protocol.d.ts +22 -0
  28. package/dist/src/server/web-socket-protocol.d.ts.map +1 -1
  29. package/dist/src/server/web-socket-protocol.js +6 -0
  30. package/dist/src/server/web-socket-protocol.js.map +1 -1
  31. package/dist/src/server/web-socket-protocol.test.js +52 -0
  32. package/dist/src/server/web-socket-protocol.test.js.map +1 -1
  33. package/dist/tsconfig.tsbuildinfo +1 -1
  34. package/package.json +5 -5
  35. package/src/bridge/bridge-session.test.ts +45 -0
  36. package/src/bridge/bridge-session.ts +1 -0
  37. package/src/bridge/types.ts +14 -1
  38. package/src/commands/console/exec/{execute.luau → execute.lua} +118 -3
  39. package/src/commands/framework/action-loader.test.ts +15 -15
  40. package/src/commands/framework/action-loader.ts +7 -7
  41. package/src/index.ts +1 -0
  42. package/src/server/plugin-detection.test.ts +1 -1
  43. package/src/server/studio-bridge-server.test.ts +50 -1
  44. package/src/server/studio-bridge-server.ts +12 -2
  45. package/src/server/web-socket-protocol.test.ts +64 -0
  46. package/src/server/web-socket-protocol.ts +29 -0
  47. package/templates/studio-bridge-plugin-test/test/{execute-handler.test.luau → execute-handler.test.lua} +111 -0
  48. package/templates/studio-bridge-plugin-test/test/{test-runner.luau → test-runner.lua} +10 -10
  49. /package/build-scripts/{transform-add-session-attribute.luau → transform-add-session-attribute.lua} +0 -0
  50. /package/src/commands/console/logs/{query-logs.luau → query-logs.lua} +0 -0
  51. /package/src/commands/explorer/query/{query-data-model.luau → query-data-model.lua} +0 -0
  52. /package/src/commands/process/info/{query-state.luau → query-state.lua} +0 -0
  53. /package/src/commands/viewport/screenshot/{capture-screenshot.luau → capture-screenshot.lua} +0 -0
  54. /package/templates/studio-bridge-plugin/src/Shared/{ActionRouter.luau → ActionRouter.lua} +0 -0
  55. /package/templates/studio-bridge-plugin/src/Shared/{DiscoveryStateMachine.luau → DiscoveryStateMachine.lua} +0 -0
  56. /package/templates/studio-bridge-plugin/src/Shared/{MessageBuffer.luau → MessageBuffer.lua} +0 -0
  57. /package/templates/studio-bridge-plugin/src/Shared/{Protocol.luau → Protocol.lua} +0 -0
  58. /package/templates/studio-bridge-plugin/src/Vendor/{png.luau → png.lua} +0 -0
  59. /package/templates/studio-bridge-plugin-test/test/{actions.test.luau → actions.test.lua} +0 -0
  60. /package/templates/studio-bridge-plugin-test/test/{discovery.test.luau → discovery.test.lua} +0 -0
  61. /package/templates/studio-bridge-plugin-test/test/{hash-lifecycle.test.luau → hash-lifecycle.test.lua} +0 -0
  62. /package/templates/studio-bridge-plugin-test/test/{integration.test.luau → integration.test.lua} +0 -0
  63. /package/templates/studio-bridge-plugin-test/test/{new-actions.test.luau → new-actions.test.lua} +0 -0
  64. /package/templates/studio-bridge-plugin-test/test/{plugin-entry.test.luau → plugin-entry.test.lua} +0 -0
  65. /package/templates/studio-bridge-plugin-test/test/{protocol.test.luau → protocol.test.lua} +0 -0
  66. /package/templates/studio-bridge-plugin-test/test/{roblox-mocks.luau → roblox-mocks.lua} +0 -0
@@ -403,4 +403,115 @@ table.insert(tests, {
403
403
  end,
404
404
  })
405
405
 
406
+ -- ===========================================================================
407
+ -- Return value marshalling
408
+ -- ===========================================================================
409
+
410
+ table.insert(tests, {
411
+ name = "returnValues: empty when the script returns nothing",
412
+ fn = function()
413
+ local result = ExecuteAction.handleExecute({ code = "local x = 1" }, "req-rv0", "sess-rv0")
414
+ assertNotNil(result.returnValues, "returnValues should be present on a successful run")
415
+ assertEqual(#result.returnValues, 0, "no values returned")
416
+ end,
417
+ })
418
+
419
+ table.insert(tests, {
420
+ name = "returnValues: carries every returned value in order",
421
+ fn = function()
422
+ local result = ExecuteAction.handleExecute({ code = "return 'str', 42, true" }, "req-rv1", "sess-rv1")
423
+ assertEqual(#result.returnValues, 3, "three values returned")
424
+ assertEqual(result.returnValues[1], "str")
425
+ assertEqual(result.returnValues[2], 42)
426
+ assertEqual(result.returnValues[3], true)
427
+ end,
428
+ })
429
+
430
+ table.insert(tests, {
431
+ name = "returnValues: nested tables survive as tables",
432
+ fn = function()
433
+ local result = ExecuteAction.handleExecute(
434
+ { code = "return { slug = 'maid', counts = { passed = 1014, failed = 0 } }" },
435
+ "req-rv2",
436
+ "sess-rv2"
437
+ )
438
+ assertEqual(#result.returnValues, 1, "one value returned")
439
+ local value = result.returnValues[1]
440
+ assertEqual(value.slug, "maid")
441
+ assertEqual(value.counts.passed, 1014)
442
+ assertEqual(value.counts.failed, 0)
443
+ end,
444
+ })
445
+
446
+ table.insert(tests, {
447
+ name = "returnValues: array-like tables stay arrays",
448
+ fn = function()
449
+ local result = ExecuteAction.handleExecute({ code = "return { 10, 20, 30 }" }, "req-rv3", "sess-rv3")
450
+ local value = result.returnValues[1]
451
+ assertEqual(#value, 3, "array length")
452
+ assertEqual(value[1], 10)
453
+ assertEqual(value[3], 30)
454
+ end,
455
+ })
456
+
457
+ table.insert(tests, {
458
+ name = "returnValues: non-string keys become strings so the table can be encoded",
459
+ fn = function()
460
+ local result = ExecuteAction.handleExecute({ code = "return { [1] = 'a', name = 'b' }" }, "req-rv4", "sess-rv4")
461
+ local value = result.returnValues[1]
462
+ assertEqual(value["1"], "a", "numeric key stringified")
463
+ assertEqual(value.name, "b")
464
+ end,
465
+ })
466
+
467
+ table.insert(tests, {
468
+ name = "returnValues: a returned nil keeps its position",
469
+ fn = function()
470
+ local result = ExecuteAction.handleExecute({ code = "return nil, 7" }, "req-rv5", "sess-rv5")
471
+ assertEqual(#result.returnValues, 2, "two values returned")
472
+ assertEqual(result.returnValues[1].type, "Nil", "nil marker")
473
+ assertEqual(result.returnValues[2], 7)
474
+ end,
475
+ })
476
+
477
+ table.insert(tests, {
478
+ name = "returnValues: a cycle is reported instead of recursing forever",
479
+ fn = function()
480
+ local result =
481
+ ExecuteAction.handleExecute({ code = "local t = {}; t.self = t; return t" }, "req-rv6", "sess-rv6")
482
+ local value = result.returnValues[1]
483
+ assertEqual(value.self.type, "Unsupported", "cycle is marked unsupported")
484
+ assertContains(value.self.toString, "cycle")
485
+ end,
486
+ })
487
+
488
+ table.insert(tests, {
489
+ name = "returnValues: non-finite numbers are marked, not emitted as invalid JSON",
490
+ fn = function()
491
+ local result = ExecuteAction.handleExecute({ code = "return math.huge, 0 / 0" }, "req-rv7", "sess-rv7")
492
+ assertEqual(result.returnValues[1].type, "Unsupported", "inf is marked")
493
+ assertEqual(result.returnValues[1].typeName, "number")
494
+ assertEqual(result.returnValues[2].type, "Unsupported", "nan is marked")
495
+ end,
496
+ })
497
+
498
+ table.insert(tests, {
499
+ name = "returnValues: functions are marked unsupported rather than dropped",
500
+ fn = function()
501
+ local result = ExecuteAction.handleExecute({ code = "return function() end" }, "req-rv8", "sess-rv8")
502
+ assertEqual(#result.returnValues, 1, "one value returned")
503
+ assertEqual(result.returnValues[1].type, "Unsupported")
504
+ assertEqual(result.returnValues[1].typeName, "function")
505
+ end,
506
+ })
507
+
508
+ table.insert(tests, {
509
+ name = "returnValues: absent on a failed run",
510
+ fn = function()
511
+ local result = ExecuteAction.handleExecute({ code = "error('boom')" }, "req-rv9", "sess-rv9")
512
+ assertFalse(result.success)
513
+ assertNil(result.returnValues, "a failed run reports no return values")
514
+ end,
515
+ })
516
+
406
517
  return tests
@@ -2,7 +2,7 @@
2
2
  Simple Lune test runner for studio-bridge plugin modules.
3
3
 
4
4
  Usage:
5
- lune run test/test-runner -- discover all *.test.luau in test/
5
+ lune run test/test-runner -- discover all *.test.lua in test/
6
6
  lune run test/test-runner test/protocol.test -- run specific test file(s)
7
7
 
8
8
  Each test file must return a list of { name: string, fn: () -> () } entries.
@@ -27,25 +27,25 @@ local testRequirePaths: { string } = {}
27
27
 
28
28
  if #process.args > 0 then
29
29
  for _, arg in process.args do
30
- -- Allow both "test/foo.test" and "test/foo.test.luau"
30
+ -- Allow both "test/foo.test" and "test/foo.test.lua"
31
31
  local path = arg
32
- if not string.match(path, "%.luau$") then
33
- path = path .. ".luau"
32
+ if not string.match(path, "%.lua$") then
33
+ path = path .. ".lua"
34
34
  end
35
35
  table.insert(testFiles, path)
36
36
 
37
- -- Build a require path relative to this runner (./ prefix, no .luau)
38
- local name = string.match(path, "([^/]+)%.luau$") or path
39
- table.insert(testRequirePaths, "./" .. string.gsub(name, "%.luau$", ""))
37
+ -- Build a require path relative to this runner (./ prefix, no .lua)
38
+ local name = string.match(path, "([^/]+)%.lua$") or path
39
+ table.insert(testRequirePaths, "./" .. string.gsub(name, "%.lua$", ""))
40
40
  end
41
41
  else
42
- -- Discover all *.test.luau files in the test/ directory (non-recursive).
42
+ -- Discover all *.test.lua files in the test/ directory (non-recursive).
43
43
  local entries = fs.readDir(scriptDir)
44
44
  for _, entry in entries do
45
- if string.match(entry, "%.test%.luau$") then
45
+ if string.match(entry, "%.test%.lua$") then
46
46
  table.insert(testFiles, scriptDir .. entry)
47
47
  -- require path relative to this script: ./filename (no extension)
48
- local name = string.gsub(entry, "%.luau$", "")
48
+ local name = string.gsub(entry, "%.lua$", "")
49
49
  table.insert(testRequirePaths, "./" .. name)
50
50
  end
51
51
  end