catalyst-core 1.0.2-canary.1 → 1.0.2

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 (90) hide show
  1. package/bin/catalyst.js +105 -1
  2. package/changelog.md +34 -0
  3. package/dist/cli/README.md +119 -0
  4. package/dist/cli/appConfig.js +51 -0
  5. package/dist/cli/buildErrors.js +170 -0
  6. package/dist/cli/buildWarnings.js +28 -0
  7. package/dist/cli/devOutput.js +524 -0
  8. package/dist/cli/diagnostic.js +388 -0
  9. package/dist/cli/hints.js +69 -0
  10. package/dist/cli/package.json +3 -0
  11. package/dist/cli/spinner.js +141 -0
  12. package/dist/cli/theme.js +155 -0
  13. package/dist/errors/index.js +7 -3
  14. package/dist/logger.js +61 -6
  15. package/dist/native/androidProject/app/build.gradle.kts +2 -1
  16. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/CustomWebview.kt +2 -0
  17. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/MainActivity.kt +9 -0
  18. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/SplashActivity.kt +65 -34
  19. package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/SplashOverlay.kt +109 -0
  20. package/dist/native/androidSetup.js +46 -57
  21. package/dist/native/buildAndroid/assets.js +22 -13
  22. package/dist/native/buildAndroid/build.js +98 -26
  23. package/dist/native/buildAndroid/config.js +43 -12
  24. package/dist/native/buildAndroid/index.js +49 -191
  25. package/dist/native/buildAppAndroid.js +19 -8
  26. package/dist/native/buildAppIos.js +35 -16
  27. package/dist/native/buildIos/assets.js +1 -6
  28. package/dist/native/buildIos/build.js +66 -95
  29. package/dist/native/buildIos/config.js +26 -8
  30. package/dist/native/buildIos/index.js +143 -64
  31. package/dist/native/buildIos/plugins.js +12 -15
  32. package/dist/native/internalPluginUtils.js +0 -1
  33. package/dist/native/iosnativeWebView/CoreLogic/Sources/CatalystCoreLogic/Constants/ConfigConstants.swift +2 -0
  34. package/dist/native/iosnativeWebView/Sources/Core/WebView/SplashHTMLView.swift +31 -0
  35. package/dist/native/iosnativeWebView/Sources/Core/WebView/SplashView.swift +17 -1
  36. package/dist/native/iosnativeWebView/Sources/Core/WebView/SplashViewModel.swift +41 -1
  37. package/dist/native/iosnativeWebView/Sources/Core/WebView/WebViewModel.swift +2 -0
  38. package/dist/native/iosnativeWebView/Sources/Core/WebView/WebViewNavigationDelegate.swift +3 -0
  39. package/dist/native/pluginComposerAndroid.js +2 -3
  40. package/dist/native/renameAndroidProject.js +42 -20
  41. package/dist/native/setupEmulatorIos.js +28 -49
  42. package/dist/native/setupServer.js +12 -15
  43. package/dist/native/terminalProgress.js +186 -147
  44. package/dist/native/utils.js +340 -54
  45. package/dist/otel.js +15 -9
  46. package/dist/scripts/build.js +313 -42
  47. package/dist/scripts/generateOfflineManifest.js +11 -1
  48. package/dist/scripts/loadEnvironmentVariables.js +24 -2
  49. package/dist/scripts/preServerInit.js +32 -10
  50. package/dist/scripts/preflight.js +35 -11
  51. package/dist/scripts/scriptUtils.js +34 -0
  52. package/dist/scripts/serve.js +64 -15
  53. package/dist/scripts/start.js +58 -21
  54. package/dist/server/expressServer.js +167 -32
  55. package/dist/server/renderer/handler.jsx +87 -11
  56. package/dist/server/utils/validator.js +14 -11
  57. package/dist/vite/manifest-categorization-plugin.js +7 -5
  58. package/dist/vite/resolveDevServerConfig.js +9 -2
  59. package/dist/vite/vite.config.client.js +18 -0
  60. package/dist/vite/vite.config.js +73 -13
  61. package/dist/vite/vite.config.server.js +21 -0
  62. package/dist/web-router/components/MetaTag.jsx +15 -2
  63. package/dist/web-router/components/MetaTag.test.jsx +71 -2
  64. package/dist/webmcp/WebMcpProvider.jsx +3 -2
  65. package/dist/webmcp/useTool.js +4 -1
  66. package/mcp_v2/conversion-tasks.json +6 -5
  67. package/mcp_v2/knowledge-base.json +124 -7
  68. package/mcp_v2/test/config.test.ts +59 -0
  69. package/mcp_v2/tools/build.js +6 -6
  70. package/mcp_v2/tools/config.js +35 -18
  71. package/mcp_v2/tools/conversion.js +7 -13
  72. package/package.json +5 -5
  73. package/test/cli/buildErrors.test.ts +173 -0
  74. package/test/cli/buildWarnings.test.cjs +62 -0
  75. package/test/cli/devOutput.test.ts +549 -0
  76. package/test/cli/diagnostic.test.ts +434 -0
  77. package/test/cli/output.test.cjs +90 -0
  78. package/test/cli/spinner.test.ts +177 -0
  79. package/test/cli/theme.test.ts +163 -0
  80. package/test/native/redactSecrets.test.ts +72 -0
  81. package/test/native/utils.test.ts +532 -0
  82. package/test/scripts/build.test.ts +275 -0
  83. package/test/scripts/serve.test.ts +102 -0
  84. package/test/server/fixtures/template/src/js/routes/index.jsx +8 -0
  85. package/test/server/handler.test.ts +17 -0
  86. package/test/server/logger.test.ts +185 -0
  87. package/test/server/otel.test.ts +556 -0
  88. package/test/server/validator.test.ts +19 -8
  89. package/dist/scripts/checkVersion.js +0 -3
  90. package/dist/scripts/cleanCache.js +0 -30
@@ -0,0 +1,173 @@
1
+ import { createRequire } from "module"
2
+ import { describe, expect, it } from "vitest"
3
+
4
+ import type buildErrorsModule from "../../src/cli/buildErrors.js"
5
+ import type hintsModule from "../../src/cli/hints.js"
6
+
7
+ // buildErrors.js pulls the real compiler errors out of a native or Vite build
8
+ // transcript; hints.js maps the failures we understand to a next step. Both
9
+ // are CommonJS and required by diagnostic.js, so they are required here too
10
+ // (one copy per file for v8 coverage).
11
+ const load = createRequire(import.meta.url)
12
+ const { extractBuildErrors, outputTail, MAX_ERRORS }: typeof buildErrorsModule = load(
13
+ "../../src/cli/buildErrors.js"
14
+ )
15
+ const { hintFor }: typeof hintsModule = load("../../src/cli/hints.js")
16
+
17
+ const ESC = String.fromCharCode(27)
18
+
19
+ describe("extractBuildErrors (native)", () => {
20
+ it("reads Kotlin, Swift/clang, javac and linker errors with their positions", () => {
21
+ const output = [
22
+ "> Task :app:compileDebugKotlin",
23
+ "e: file:///app/android/Main.kt:12:5 Unresolved reference: bar",
24
+ "/app/ios/View.swift:7:3: error: cannot find 'baz' in scope",
25
+ "/app/android/Main.java:40: error: ';' expected",
26
+ "ld: error: undefined symbol _main",
27
+ ].join("\n")
28
+ expect(extractBuildErrors(output)).toEqual([
29
+ { file: "/app/android/Main.kt", line: 12, column: 5, message: "Unresolved reference: bar" },
30
+ { file: "/app/ios/View.swift", line: 7, column: 3, message: "cannot find 'baz' in scope" },
31
+ { file: "/app/android/Main.java", line: 40, column: undefined, message: "';' expected" },
32
+ {
33
+ file: undefined,
34
+ line: undefined,
35
+ column: undefined,
36
+ message: "ld: error: undefined symbol _main",
37
+ },
38
+ ])
39
+ })
40
+
41
+ it("skips summary noise, strips colour and reports a repeated error once", () => {
42
+ const output = [
43
+ "FAILURE: Build failed with an exception.",
44
+ "Execution failed for task ':app:compileDebugKotlin'.",
45
+ `${ESC}[31me: /app/Main.kt:1:1 Boom${ESC}[0m`,
46
+ "e: /app/Main.kt:1:1 Boom",
47
+ "",
48
+ ].join("\n")
49
+ expect(extractBuildErrors(output)).toEqual([
50
+ { file: "/app/Main.kt", line: 1, column: 1, message: "Boom" },
51
+ ])
52
+ })
53
+
54
+ it("stops at the cap", () => {
55
+ const output = Array.from(
56
+ { length: MAX_ERRORS + 3 },
57
+ (_, i) => `/a/F${i}.swift:1:1: error: e${i}`
58
+ ).join("\n")
59
+ expect(extractBuildErrors(output)).toHaveLength(MAX_ERRORS)
60
+ })
61
+
62
+ it("falls back to gradle's What went wrong block, preferring the innermost cause", () => {
63
+ const output = [
64
+ "* What went wrong:",
65
+ "Could not determine the dependencies of task ':app:compileDebugJavaWithJavac'.",
66
+ "> Could not resolve all task dependencies.",
67
+ " > SDK location not found. Define a valid SDK location with ANDROID_HOME.",
68
+ "",
69
+ "* Try:",
70
+ ].join("\n")
71
+ expect(extractBuildErrors(output)).toEqual([{ message: "SDK location not found." }])
72
+ })
73
+
74
+ it("uses the first line of the block when there is no > cause", () => {
75
+ const output = "* What went wrong:\nA problem occurred configuring project ':app'.\n* Try:\n"
76
+ expect(extractBuildErrors(output)).toEqual([
77
+ { message: "A problem occurred configuring project ':app'." },
78
+ ])
79
+ })
80
+
81
+ it("finds nothing in empty output or an empty What went wrong block", () => {
82
+ expect(extractBuildErrors("")).toEqual([])
83
+ expect(extractBuildErrors(undefined)).toEqual([])
84
+ expect(extractBuildErrors("* What went wrong:\n\n* Try:")).toEqual([])
85
+ expect(extractBuildErrors("BUILD SUCCESSFUL in 2s")).toEqual([])
86
+ })
87
+ })
88
+
89
+ describe("extractBuildErrors (vite)", () => {
90
+ it("points an unresolvable import at the file that imported it", () => {
91
+ const output =
92
+ "[vite]: Rollup failed. [plugin:vite:load-fallback] Could not load /app/src/missing.js (imported by src/App.js): ENOENT"
93
+ expect(extractBuildErrors(output, { toolchain: "vite" })).toEqual([
94
+ {
95
+ file: "src/App.js",
96
+ line: undefined,
97
+ column: undefined,
98
+ message: "Could not load /app/src/missing.js",
99
+ },
100
+ ])
101
+ })
102
+
103
+ it("reads resolve and esbuild transform failures", () => {
104
+ const output = [
105
+ 'Failed to resolve entry for package "lodash".',
106
+ "src/Home.js:3:14: ERROR: Unexpected token",
107
+ ].join("\n")
108
+ expect(extractBuildErrors(output, { toolchain: "vite" })).toEqual([
109
+ {
110
+ file: undefined,
111
+ line: undefined,
112
+ column: undefined,
113
+ message: 'Failed to resolve entry for package "lodash"',
114
+ },
115
+ { file: "src/Home.js", line: 3, column: 14, message: "Unexpected token" },
116
+ ])
117
+ })
118
+ })
119
+
120
+ describe("outputTail", () => {
121
+ it("keeps the last lines that carry evidence, without gradle's boilerplate", () => {
122
+ const output = [
123
+ "line 1",
124
+ "line 2",
125
+ `${ESC}[33mline 3${ESC}[0m`,
126
+ "* Try:",
127
+ "> Run with --stacktrace option to get the stack trace.",
128
+ "> Get more help at https://help.gradle.org.",
129
+ "BUILD FAILED in 4s",
130
+ "",
131
+ ].join("\n")
132
+ expect(outputTail(output)).toBe("line 1\nline 2\nline 3")
133
+ expect(outputTail(output, 1)).toBe("line 3")
134
+ expect(outputTail("")).toBe("")
135
+ })
136
+ })
137
+
138
+ describe("hintFor", () => {
139
+ it("explains an unresolved import as a missing alias or package", () => {
140
+ expect(hintFor('Failed to resolve import "@api/client" from "src/App.js"')).toEqual({
141
+ hint: "The alias @api is not defined in package.json _moduleAliases. Add it, or import with a relative path.",
142
+ docs: "https://catalyst.1mg.com/errors/unresolved-import",
143
+ })
144
+ expect(hintFor("Failed to resolve import 'lodash'").hint).toBe(
145
+ "Check the path, or install the package with npm install lodash."
146
+ )
147
+ })
148
+
149
+ it("names the busy port when it can, and still helps when it cannot", () => {
150
+ expect(hintFor("listen EADDRINUSE: address already in use :::3005").hint).toBe(
151
+ "Something is already on port 3005. Free it with `lsof -ti :3005 | xargs kill`, or set NODE_SERVER_PORT in config/config.json."
152
+ )
153
+ expect(hintFor("EADDRINUSE").hint).toBe(
154
+ "Something is already on that port. Stop it, or set NODE_SERVER_PORT in config/config.json."
155
+ )
156
+ })
157
+
158
+ it("covers the native setup failures it understands", () => {
159
+ expect(hintFor("Unknown AVD name [Pixel_9]").hint).toMatch(/emulator -list-avds/)
160
+ expect(hintFor("Command not found: adb ").hint).toBe(
161
+ "adb is not on PATH. Install it, or correct the path in config/config.json."
162
+ )
163
+ expect(hintFor("No provisioning profile matches").hint).toMatch(/signing team/)
164
+ expect(hintFor("No booted simulator found").hint).toMatch(/boot a device/)
165
+ expect(hintFor("ANDROID_HOME is not set").hint).toMatch(/sdkPath/)
166
+ })
167
+
168
+ it("stays silent rather than guess", () => {
169
+ expect(hintFor("Something unexpected happened")).toBeNull()
170
+ expect(hintFor("")).toBeNull()
171
+ expect(hintFor(undefined)).toBeNull()
172
+ })
173
+ })
@@ -0,0 +1,62 @@
1
+ "use strict"
2
+
3
+ const assert = require("node:assert/strict")
4
+ const { test } = require("node:test")
5
+
6
+ const { bundleWarnings } = require("../../src/cli/buildWarnings.js")
7
+
8
+ // Real shapes, copied from Vite/Rollup output rather than invented: the point
9
+ // of this function is that a warning survived the config filters and would
10
+ // otherwise be discarded on a green build.
11
+ const ROLLUP_CHUNK_SIZE = "(!) Some chunks are larger than 500 kB after minification."
12
+ const ROLLUP_CIRCULAR = "(!) Circular dependency: src/a.js -> src/b.js -> src/a.js"
13
+ const ROLLUP_PLAIN = 'Warning: "foo" is imported but never used'
14
+
15
+ test("keeps warnings and labels them with the bundle that produced them", () => {
16
+ const output = [
17
+ "vite v5.0.0 building for production...",
18
+ ROLLUP_CHUNK_SIZE,
19
+ "transforming (42) src/js/app.jsx",
20
+ ROLLUP_CIRCULAR,
21
+ "✓ built in 1.2s",
22
+ ].join("\n")
23
+
24
+ assert.deepEqual(bundleWarnings(output, "client"), [
25
+ "client Some chunks are larger than 500 kB after minification.",
26
+ "client Circular dependency: src/a.js -> src/b.js -> src/a.js",
27
+ ])
28
+ })
29
+
30
+ test("strips the marker prefix but keeps the message", () => {
31
+ assert.deepEqual(bundleWarnings(ROLLUP_PLAIN, "server"), ['server "foo" is imported but never used'])
32
+ })
33
+
34
+ test("ignores ordinary progress output", () => {
35
+ const output = [
36
+ "vite v5.0.0 building for production...",
37
+ "transforming (12) src/x.js",
38
+ "✓ built in 900ms",
39
+ ].join("\n")
40
+ assert.deepEqual(bundleWarnings(output, "client"), [])
41
+ })
42
+
43
+ test("sees through colour codes", () => {
44
+ // Vite colours its warnings, so matching the raw line would silently stop
45
+ // working the moment the child emits colour -- the exact bug that made the
46
+ // dev-server line classifier fail once already.
47
+ const esc = String.fromCharCode(27)
48
+ const coloured = `${esc}[33m${ROLLUP_CHUNK_SIZE}${esc}[39m`
49
+ assert.deepEqual(bundleWarnings(coloured, "client"), [
50
+ "client Some chunks are larger than 500 kB after minification.",
51
+ ])
52
+ })
53
+
54
+ test("reports each distinct warning once", () => {
55
+ const output = [ROLLUP_CHUNK_SIZE, ROLLUP_CHUNK_SIZE, ROLLUP_CIRCULAR].join("\n")
56
+ assert.equal(bundleWarnings(output, "client").length, 2)
57
+ })
58
+
59
+ test("returns nothing for empty or missing output", () => {
60
+ assert.deepEqual(bundleWarnings("", "client"), [])
61
+ assert.deepEqual(bundleWarnings(undefined, "client"), [])
62
+ })