forgeos 0.1.0-alpha.0 → 0.1.0-alpha.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 (283) hide show
  1. package/.npmignore +9 -1
  2. package/AGENTS.md +6 -1
  3. package/CHANGELOG.md +30 -0
  4. package/CONTRIBUTING.md +22 -1
  5. package/README.md +30 -3
  6. package/bin/forge.mjs +4 -3
  7. package/package.json +3 -1
  8. package/packages/eslint-plugin-forge/index.ts +15 -15
  9. package/packages/eslint-plugin-forge/package.json +10 -10
  10. package/packages/eslint-plugin-forge/src/check-source.ts +95 -95
  11. package/packages/eslint-plugin-forge/src/load-artifacts.ts +24 -24
  12. package/packages/eslint-plugin-forge/src/rule-no-forge-guard-violation.ts +93 -93
  13. package/src/forge/_generated/actionSubscriptions.json +2 -2
  14. package/src/forge/_generated/actionSubscriptions.ts +3 -3
  15. package/src/forge/_generated/agentAdapterManifest.json +2 -2
  16. package/src/forge/_generated/agentAdapterManifest.ts +3 -3
  17. package/src/forge/_generated/agentContract.json +2 -2
  18. package/src/forge/_generated/agentContract.ts +6786 -2
  19. package/src/forge/_generated/agentQuickstart.md +1 -1
  20. package/src/forge/_generated/aiContext.ts +1 -1
  21. package/src/forge/_generated/aiModels.json +1 -1
  22. package/src/forge/_generated/aiModels.ts +1 -1
  23. package/src/forge/_generated/aiProviders.json +1 -1
  24. package/src/forge/_generated/aiProviders.ts +1 -1
  25. package/src/forge/_generated/aiRegistry.json +2 -2
  26. package/src/forge/_generated/aiRegistry.ts +3 -3
  27. package/src/forge/_generated/api.json +2 -2
  28. package/src/forge/_generated/api.ts +1 -1
  29. package/src/forge/_generated/appGraph.json +2 -2
  30. package/src/forge/_generated/appGraph.ts +1297 -1141
  31. package/src/forge/_generated/appMap.md +1 -1
  32. package/src/forge/_generated/artifactManifest.json +2 -2
  33. package/src/forge/_generated/artifactManifest.ts +2 -2
  34. package/src/forge/_generated/authClaims.json +1 -1
  35. package/src/forge/_generated/authClaims.ts +1 -1
  36. package/src/forge/_generated/authConfig.json +1 -1
  37. package/src/forge/_generated/authConfig.ts +1 -1
  38. package/src/forge/_generated/authContext.ts +1 -1
  39. package/src/forge/_generated/authRegistry.json +1 -1
  40. package/src/forge/_generated/authRegistry.ts +1 -1
  41. package/src/forge/_generated/buildInfo.json +2 -2
  42. package/src/forge/_generated/buildInfo.ts +4 -4
  43. package/src/forge/_generated/capabilityMap.json +2 -2
  44. package/src/forge/_generated/capabilityMap.md +1 -1
  45. package/src/forge/_generated/capabilityMap.ts +2 -2
  46. package/src/forge/_generated/client.ts +1 -1
  47. package/src/forge/_generated/clientApi.ts +1 -1
  48. package/src/forge/_generated/clientManifest.json +2 -2
  49. package/src/forge/_generated/clientManifest.ts +3 -3
  50. package/src/forge/_generated/clientTypes.ts +1 -1
  51. package/src/forge/_generated/configRegistry.json +1 -1
  52. package/src/forge/_generated/configRegistry.ts +1 -1
  53. package/src/forge/_generated/dataGraph.json +2 -2
  54. package/src/forge/_generated/dataGraph.ts +3 -3
  55. package/src/forge/_generated/db.json +1 -1
  56. package/src/forge/_generated/db.ts +1 -1
  57. package/src/forge/_generated/dbSecurityManifest.json +1 -1
  58. package/src/forge/_generated/dbSecurityManifest.ts +1 -1
  59. package/src/forge/_generated/dbSessionContext.json +1 -1
  60. package/src/forge/_generated/dbSessionContext.ts +1 -1
  61. package/src/forge/_generated/deployManifest.json +2 -2
  62. package/src/forge/_generated/deployManifest.ts +7 -7
  63. package/src/forge/_generated/devManifest.json +2 -2
  64. package/src/forge/_generated/devManifest.ts +3 -3
  65. package/src/forge/_generated/envSchema.json +1 -1
  66. package/src/forge/_generated/envSchema.ts +1 -1
  67. package/src/forge/_generated/frontendGraph.json +1 -1
  68. package/src/forge/_generated/frontendGraph.ts +1 -1
  69. package/src/forge/_generated/importGuards.json +2 -2
  70. package/src/forge/_generated/importGuards.ts +35 -1
  71. package/src/forge/_generated/index.ts +1 -1
  72. package/src/forge/_generated/liveProductionManifest.json +1 -1
  73. package/src/forge/_generated/liveProductionManifest.ts +1 -1
  74. package/src/forge/_generated/liveProtocol.json +1 -1
  75. package/src/forge/_generated/liveProtocol.ts +1 -1
  76. package/src/forge/_generated/liveQueryRegistry.json +2 -2
  77. package/src/forge/_generated/liveQueryRegistry.ts +3 -3
  78. package/src/forge/_generated/liveTransportConfig.json +1 -1
  79. package/src/forge/_generated/liveTransportConfig.ts +1 -1
  80. package/src/forge/_generated/makeRegistry.json +2 -2
  81. package/src/forge/_generated/makeRegistry.ts +2 -2
  82. package/src/forge/_generated/makeTemplates.json +1 -1
  83. package/src/forge/_generated/makeTemplates.ts +1 -1
  84. package/src/forge/_generated/mockMap.json +1 -1
  85. package/src/forge/_generated/mockMap.ts +1 -1
  86. package/src/forge/_generated/operationPlaybooks.md +7 -5
  87. package/src/forge/_generated/packageGraph.json +2 -2
  88. package/src/forge/_generated/packageGraph.ts +90964 -14284
  89. package/src/forge/_generated/packageUpgradeRegistry.json +2 -2
  90. package/src/forge/_generated/packageUpgradeRegistry.ts +2 -2
  91. package/src/forge/_generated/permissionMatrix.json +2 -2
  92. package/src/forge/_generated/permissionMatrix.ts +3 -3
  93. package/src/forge/_generated/policyRegistry.json +2 -2
  94. package/src/forge/_generated/policyRegistry.ts +3 -3
  95. package/src/forge/_generated/queryRegistry.json +2 -2
  96. package/src/forge/_generated/queryRegistry.ts +3 -3
  97. package/src/forge/_generated/react.d.ts +1 -1
  98. package/src/forge/_generated/react.ts +1 -1
  99. package/src/forge/_generated/reactManifest.json +2 -2
  100. package/src/forge/_generated/reactManifest.ts +3 -3
  101. package/src/forge/_generated/releaseManifest.json +2 -2
  102. package/src/forge/_generated/releaseManifest.ts +3 -3
  103. package/src/forge/_generated/rlsPolicies.json +1 -1
  104. package/src/forge/_generated/rlsPolicies.sql +1 -1
  105. package/src/forge/_generated/rlsPolicies.ts +1 -1
  106. package/src/forge/_generated/runtimeGraph.json +2 -2
  107. package/src/forge/_generated/runtimeGraph.ts +3 -3
  108. package/src/forge/_generated/runtimeMatrix.json +2 -2
  109. package/src/forge/_generated/runtimeMatrix.ts +106177 -7917
  110. package/src/forge/_generated/runtimeRegistry.ts +1 -1
  111. package/src/forge/_generated/runtimeRules.md +1 -1
  112. package/src/forge/_generated/secretRegistry.json +1 -1
  113. package/src/forge/_generated/secretRegistry.ts +1 -1
  114. package/src/forge/_generated/secretsContext.ts +1 -1
  115. package/src/forge/_generated/serverApi.ts +1 -1
  116. package/src/forge/_generated/sourceMapManifest.json +2 -2
  117. package/src/forge/_generated/sourceMapManifest.ts +2 -2
  118. package/src/forge/_generated/sqlPlan.json +1 -1
  119. package/src/forge/_generated/sqlPlan.ts +1 -1
  120. package/src/forge/_generated/subscriptionManifest.json +2 -2
  121. package/src/forge/_generated/subscriptionManifest.ts +3 -3
  122. package/src/forge/_generated/symbolicationManifest.json +2 -2
  123. package/src/forge/_generated/symbolicationManifest.ts +2 -2
  124. package/src/forge/_generated/telemetryRegistry.json +2 -2
  125. package/src/forge/_generated/telemetryRegistry.ts +3 -3
  126. package/src/forge/_generated/telemetrySinks.json +2 -2
  127. package/src/forge/_generated/telemetrySinks.ts +2 -2
  128. package/src/forge/_generated/tenantScope.json +2 -2
  129. package/src/forge/_generated/tenantScope.ts +3 -3
  130. package/src/forge/_generated/testGraph.json +2 -2
  131. package/src/forge/_generated/testGraph.ts +129 -75
  132. package/src/forge/_generated/testPlanRegistry.json +2 -2
  133. package/src/forge/_generated/testPlanRegistry.ts +2 -2
  134. package/src/forge/_generated/uiRoutes.json +1 -1
  135. package/src/forge/_generated/uiRoutes.ts +1 -1
  136. package/src/forge/_generated/uiScenarios.json +1 -1
  137. package/src/forge/_generated/uiScenarios.ts +1 -1
  138. package/src/forge/_generated/uiTestManifest.json +2 -2
  139. package/src/forge/_generated/uiTestManifest.ts +2 -2
  140. package/src/forge/_generated/workflowRegistry.json +2 -2
  141. package/src/forge/_generated/workflowRegistry.ts +3 -3
  142. package/src/forge/_generated/workflowSubscriptions.json +2 -2
  143. package/src/forge/_generated/workflowSubscriptions.ts +3 -3
  144. package/src/forge/cli/commands.ts +861 -861
  145. package/src/forge/cli/deps.ts +178 -11
  146. package/src/forge/cli/dev.ts +32 -5
  147. package/src/forge/cli/index.ts +7 -7
  148. package/src/forge/cli/main.ts +54 -54
  149. package/src/forge/cli/new.ts +29 -1
  150. package/src/forge/cli/output.ts +97 -97
  151. package/src/forge/cli/parse.ts +679 -673
  152. package/src/forge/cli/version.ts +1 -1
  153. package/src/forge/compiler/agent-contract/build.ts +28 -0
  154. package/src/forge/compiler/agent-contract/types.ts +16 -0
  155. package/src/forge/compiler/app-graph/build.ts +112 -112
  156. package/src/forge/compiler/app-graph/classify.ts +10 -10
  157. package/src/forge/compiler/app-graph/dup-symbol.ts +29 -29
  158. package/src/forge/compiler/app-graph/extract.ts +123 -123
  159. package/src/forge/compiler/app-graph/forge-apis.ts +29 -29
  160. package/src/forge/compiler/app-graph/index.ts +11 -11
  161. package/src/forge/compiler/app-graph/module-graph.ts +316 -316
  162. package/src/forge/compiler/app-graph/parser.ts +119 -119
  163. package/src/forge/compiler/app-graph/symbols.ts +48 -48
  164. package/src/forge/compiler/app-graph/tsconfig-hash.ts +62 -62
  165. package/src/forge/compiler/app-graph/types.ts +43 -43
  166. package/src/forge/compiler/app-graph/versions.ts +14 -14
  167. package/src/forge/compiler/cache/index.ts +17 -17
  168. package/src/forge/compiler/cache/key.ts +46 -46
  169. package/src/forge/compiler/cache/scheduler.ts +72 -72
  170. package/src/forge/compiler/cache/store.ts +78 -78
  171. package/src/forge/compiler/classifier/capabilities.ts +78 -78
  172. package/src/forge/compiler/classifier/classify.ts +113 -113
  173. package/src/forge/compiler/classifier/contexts.ts +188 -188
  174. package/src/forge/compiler/classifier/index.ts +18 -18
  175. package/src/forge/compiler/classifier/runtime-matrix.ts +45 -45
  176. package/src/forge/compiler/classifier/secrets.ts +41 -41
  177. package/src/forge/compiler/classifier/signals.ts +129 -129
  178. package/src/forge/compiler/diagnostics/codes.ts +125 -120
  179. package/src/forge/compiler/diagnostics/create.ts +87 -87
  180. package/src/forge/compiler/diagnostics/index.ts +41 -41
  181. package/src/forge/compiler/emitter/artifact-kind.ts +14 -14
  182. package/src/forge/compiler/emitter/barrel.ts +38 -38
  183. package/src/forge/compiler/emitter/constants.ts +7 -7
  184. package/src/forge/compiler/emitter/emit.ts +234 -237
  185. package/src/forge/compiler/emitter/index.ts +24 -24
  186. package/src/forge/compiler/emitter/lock.ts +61 -61
  187. package/src/forge/compiler/emitter/render.ts +73 -73
  188. package/src/forge/compiler/guards/artifacts.ts +96 -96
  189. package/src/forge/compiler/guards/check-import-guards.ts +106 -106
  190. package/src/forge/compiler/guards/index.ts +11 -11
  191. package/src/forge/compiler/guards/propagate-contexts.ts +57 -57
  192. package/src/forge/compiler/index.ts +17 -17
  193. package/src/forge/compiler/integration/add.ts +493 -493
  194. package/src/forge/compiler/integration/index.ts +17 -17
  195. package/src/forge/compiler/integration/plan.ts +279 -279
  196. package/src/forge/compiler/integration/render.ts +189 -189
  197. package/src/forge/compiler/integration/snapshot.ts +52 -52
  198. package/src/forge/compiler/orchestrator/discover.ts +214 -214
  199. package/src/forge/compiler/orchestrator/guards.ts +5 -5
  200. package/src/forge/compiler/orchestrator/index.ts +27 -27
  201. package/src/forge/compiler/orchestrator/manifest.ts +69 -69
  202. package/src/forge/compiler/orchestrator/orphans.ts +51 -51
  203. package/src/forge/compiler/orchestrator/plan.ts +804 -804
  204. package/src/forge/compiler/orchestrator/run.ts +178 -178
  205. package/src/forge/compiler/orchestrator/serialize.ts +859 -859
  206. package/src/forge/compiler/orchestrator/types.ts +23 -23
  207. package/src/forge/compiler/orchestrator/verify.ts +35 -35
  208. package/src/forge/compiler/package-graph/capabilities-stub.ts +33 -33
  209. package/src/forge/compiler/package-graph/checksum.ts +107 -97
  210. package/src/forge/compiler/package-graph/compiler.ts +444 -363
  211. package/src/forge/compiler/package-graph/constants.ts +4 -4
  212. package/src/forge/compiler/package-graph/exports-discovery.ts +91 -84
  213. package/src/forge/compiler/package-graph/extract-dts.ts +32 -32
  214. package/src/forge/compiler/package-graph/index.ts +24 -24
  215. package/src/forge/compiler/package-graph/jsdoc.ts +50 -50
  216. package/src/forge/compiler/package-graph/oracle.ts +326 -0
  217. package/src/forge/compiler/package-graph/read-file.ts +21 -21
  218. package/src/forge/compiler/package-graph/resolve.ts +131 -127
  219. package/src/forge/compiler/package-manager/adapter.ts +232 -232
  220. package/src/forge/compiler/package-manager/commands.ts +47 -47
  221. package/src/forge/compiler/package-manager/detect.ts +65 -65
  222. package/src/forge/compiler/package-manager/executor.ts +29 -29
  223. package/src/forge/compiler/package-manager/index.ts +22 -22
  224. package/src/forge/compiler/package-manager/parse-spec.ts +16 -16
  225. package/src/forge/compiler/package-manager/version.ts +20 -20
  226. package/src/forge/compiler/primitives/compare.ts +26 -26
  227. package/src/forge/compiler/primitives/hash.ts +42 -33
  228. package/src/forge/compiler/primitives/header.ts +43 -43
  229. package/src/forge/compiler/primitives/index.ts +45 -45
  230. package/src/forge/compiler/primitives/paths.ts +24 -24
  231. package/src/forge/compiler/primitives/serialize.ts +66 -66
  232. package/src/forge/compiler/primitives/sort.ts +87 -87
  233. package/src/forge/compiler/recipes/definitions.ts +269 -269
  234. package/src/forge/compiler/recipes/helpers.ts +37 -37
  235. package/src/forge/compiler/recipes/index.ts +21 -21
  236. package/src/forge/compiler/recipes/registry.ts +87 -87
  237. package/src/forge/compiler/sandbox/artifact-sanitize.ts +26 -26
  238. package/src/forge/compiler/sandbox/backends/child.ts +123 -123
  239. package/src/forge/compiler/sandbox/backends/docker.ts +173 -173
  240. package/src/forge/compiler/sandbox/index.ts +51 -51
  241. package/src/forge/compiler/sandbox/inspect.ts +143 -143
  242. package/src/forge/compiler/sandbox/inspector-entry.ts +115 -115
  243. package/src/forge/compiler/sandbox/limits.ts +31 -31
  244. package/src/forge/compiler/sandbox/scrub-env.ts +60 -60
  245. package/src/forge/compiler/sandbox/secret-scan.ts +54 -54
  246. package/src/forge/compiler/sandbox/serialize.ts +106 -106
  247. package/src/forge/compiler/sandbox/types.ts +7 -7
  248. package/src/forge/compiler/types/app-graph.ts +71 -71
  249. package/src/forge/compiler/types/capability.ts +29 -29
  250. package/src/forge/compiler/types/classification.ts +9 -9
  251. package/src/forge/compiler/types/cli.ts +85 -85
  252. package/src/forge/compiler/types/diagnostic.ts +2 -2
  253. package/src/forge/compiler/types/emit.ts +25 -25
  254. package/src/forge/compiler/types/import-guards.ts +19 -19
  255. package/src/forge/compiler/types/index.ts +98 -98
  256. package/src/forge/compiler/types/integration.ts +25 -25
  257. package/src/forge/compiler/types/json.ts +3 -3
  258. package/src/forge/compiler/types/lock.ts +37 -37
  259. package/src/forge/compiler/types/package-graph.ts +122 -77
  260. package/src/forge/compiler/types/runtime-matrix.ts +16 -16
  261. package/src/forge/compiler/types/runtime.ts +30 -30
  262. package/src/forge/compiler/types/sandbox.ts +24 -24
  263. package/src/forge/dev/server.ts +16 -2
  264. package/src/forge/refactor/index.ts +10 -2
  265. package/src/forge/refactor/runtime-rename.ts +598 -0
  266. package/src/forge/runtime/executor.ts +3 -2
  267. package/src/forge/runtime/live/live-query-runner.ts +2 -1
  268. package/src/forge/runtime/outbox/process.ts +2 -1
  269. package/src/forge/runtime/query/run-query.ts +2 -1
  270. package/src/forge/runtime/runner/run-entry.ts +2 -1
  271. package/src/forge/runtime/telemetry/sinks/posthog.ts +4 -5
  272. package/src/forge/runtime/telemetry/sinks/sentry.ts +4 -5
  273. package/src/forge/runtime/workflows/resolve-step.ts +2 -1
  274. package/src/forge/version.ts +3 -0
  275. package/templates/b2b-support-web/src/actions/captureTicketCreated.ts +7 -2
  276. package/templates/b2b-support-web/src/commands/closeTicket.ts +6 -1
  277. package/templates/b2b-support-web/src/commands/createTicket.ts +8 -2
  278. package/templates/b2b-support-web/src/queries/getTicket.ts +8 -1
  279. package/templates/b2b-support-web/web/components/CreateTicketForm.tsx +1 -2
  280. package/templates/b2b-support-web/web/components/PolicyDeniedDemo.tsx +1 -2
  281. package/templates/b2b-support-web/web/components/TicketList.tsx +1 -2
  282. package/templates/b2b-support-web/web/components/TraceDetails.tsx +1 -1
  283. package/templates/b2b-support-web/web/lib/forge.ts +1 -0
@@ -1,24 +1,24 @@
1
- import { compareBytes } from "./compare.ts";
2
-
3
- /**
4
- * Normalize a path to workspace-relative POSIX form with `/` separators.
5
- */
6
- export function normalizePath(path: string): string {
7
- let normalized = path.replace(/\\/g, "/");
8
-
9
- while (normalized.startsWith("./")) {
10
- normalized = normalized.slice(2);
11
- }
12
-
13
- normalized = normalized.replace(/\/+/g, "/");
14
-
15
- if (normalized.length > 1 && normalized.endsWith("/")) {
16
- normalized = normalized.slice(0, -1);
17
- }
18
-
19
- return normalized;
20
- }
21
-
22
- export function comparePaths(a: string, b: string): number {
23
- return compareBytes(normalizePath(a), normalizePath(b));
24
- }
1
+ import { compareBytes } from "./compare.ts";
2
+
3
+ /**
4
+ * Normalize a path to workspace-relative POSIX form with `/` separators.
5
+ */
6
+ export function normalizePath(path: string): string {
7
+ let normalized = path.replace(/\\/g, "/");
8
+
9
+ while (normalized.startsWith("./")) {
10
+ normalized = normalized.slice(2);
11
+ }
12
+
13
+ normalized = normalized.replace(/\/+/g, "/");
14
+
15
+ if (normalized.length > 1 && normalized.endsWith("/")) {
16
+ normalized = normalized.slice(0, -1);
17
+ }
18
+
19
+ return normalized;
20
+ }
21
+
22
+ export function comparePaths(a: string, b: string): number {
23
+ return compareBytes(normalizePath(a), normalizePath(b));
24
+ }
@@ -1,66 +1,66 @@
1
- import type { JsonValue } from "../types/json.ts";
2
- import { compareBytes } from "./compare.ts";
3
-
4
- /**
5
- * Normalize line endings to LF and ensure exactly one trailing newline.
6
- */
7
- export function normalizeNewlines(content: string): string {
8
- const normalized = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
9
- if (normalized.length === 0) {
10
- return "\n";
11
- }
12
- return normalized.endsWith("\n") ? normalized : `${normalized}\n`;
13
- }
14
-
15
- function isPlainObject(value: unknown): value is Record<string, unknown> {
16
- return (
17
- typeof value === "object" &&
18
- value !== null &&
19
- !Array.isArray(value) &&
20
- Object.getPrototypeOf(value) === Object.prototype
21
- );
22
- }
23
-
24
- function sortObjectKeys(value: Record<string, unknown>): Record<string, unknown> {
25
- const sorted: Record<string, unknown> = {};
26
- const keys = Object.keys(value).sort(compareBytes);
27
- for (const key of keys) {
28
- sorted[key] = canonicalizeValue(value[key]);
29
- }
30
- return sorted;
31
- }
32
-
33
- function canonicalizeValue(value: unknown): unknown {
34
- if (value === null || typeof value !== "object") {
35
- return value;
36
- }
37
-
38
- if (Array.isArray(value)) {
39
- return value.map(canonicalizeValue);
40
- }
41
-
42
- if (isPlainObject(value)) {
43
- return sortObjectKeys(value);
44
- }
45
-
46
- return value;
47
- }
48
-
49
- /**
50
- * Serialize a value to canonical JSON with stable key ordering.
51
- */
52
- export function canonicalJson(value: unknown): string {
53
- const canonical = canonicalizeValue(value);
54
- return JSON.stringify(canonical);
55
- }
56
-
57
- /**
58
- * Serialize to canonical JSON with normalized newlines and trailing newline.
59
- */
60
- export function serializeCanonical(value: unknown): string {
61
- return normalizeNewlines(canonicalJson(value));
62
- }
63
-
64
- export function serializeJsonValue(value: JsonValue): string {
65
- return serializeCanonical(value);
66
- }
1
+ import type { JsonValue } from "../types/json.ts";
2
+ import { compareBytes } from "./compare.ts";
3
+
4
+ /**
5
+ * Normalize line endings to LF and ensure exactly one trailing newline.
6
+ */
7
+ export function normalizeNewlines(content: string): string {
8
+ const normalized = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
9
+ if (normalized.length === 0) {
10
+ return "\n";
11
+ }
12
+ return normalized.endsWith("\n") ? normalized : `${normalized}\n`;
13
+ }
14
+
15
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
16
+ return (
17
+ typeof value === "object" &&
18
+ value !== null &&
19
+ !Array.isArray(value) &&
20
+ Object.getPrototypeOf(value) === Object.prototype
21
+ );
22
+ }
23
+
24
+ function sortObjectKeys(value: Record<string, unknown>): Record<string, unknown> {
25
+ const sorted: Record<string, unknown> = {};
26
+ const keys = Object.keys(value).sort(compareBytes);
27
+ for (const key of keys) {
28
+ sorted[key] = canonicalizeValue(value[key]);
29
+ }
30
+ return sorted;
31
+ }
32
+
33
+ function canonicalizeValue(value: unknown): unknown {
34
+ if (value === null || typeof value !== "object") {
35
+ return value;
36
+ }
37
+
38
+ if (Array.isArray(value)) {
39
+ return value.map(canonicalizeValue);
40
+ }
41
+
42
+ if (isPlainObject(value)) {
43
+ return sortObjectKeys(value);
44
+ }
45
+
46
+ return value;
47
+ }
48
+
49
+ /**
50
+ * Serialize a value to canonical JSON with stable key ordering.
51
+ */
52
+ export function canonicalJson(value: unknown): string {
53
+ const canonical = canonicalizeValue(value);
54
+ return JSON.stringify(canonical);
55
+ }
56
+
57
+ /**
58
+ * Serialize to canonical JSON with normalized newlines and trailing newline.
59
+ */
60
+ export function serializeCanonical(value: unknown): string {
61
+ return normalizeNewlines(canonicalJson(value));
62
+ }
63
+
64
+ export function serializeJsonValue(value: JsonValue): string {
65
+ return serializeCanonical(value);
66
+ }
@@ -1,87 +1,87 @@
1
- import type { ForgeEdge, ForgeSymbol } from "../types/app-graph.ts";
2
- import type { EmitFile } from "../types/emit.ts";
3
- import type {
4
- Entrypoint,
5
- ExportSignature,
6
- PackageApi,
7
- } from "../types/package-graph.ts";
8
- import { compareBytes } from "./compare.ts";
9
- import { comparePaths } from "./paths.ts";
10
-
11
- function stableSortInPlace<T>(items: T[], compare: (a: T, b: T) => number): T[] {
12
- items.sort(compare);
13
- return items;
14
- }
15
-
16
- export function compareSymbols(a: ForgeSymbol, b: ForgeSymbol): number {
17
- let cmp = compareBytes(a.kind, b.kind);
18
- if (cmp !== 0) return cmp;
19
-
20
- cmp = compareBytes(a.name, b.name);
21
- if (cmp !== 0) return cmp;
22
-
23
- cmp = comparePaths(a.file, b.file);
24
- if (cmp !== 0) return cmp;
25
-
26
- return a.span.start - b.span.start;
27
- }
28
-
29
- export function compareEdges(a: ForgeEdge, b: ForgeEdge): number {
30
- let cmp = compareBytes(a.from, b.from);
31
- if (cmp !== 0) return cmp;
32
-
33
- cmp = compareBytes(a.to, b.to);
34
- if (cmp !== 0) return cmp;
35
-
36
- return compareBytes(a.kind, b.kind);
37
- }
38
-
39
- export function comparePackages(a: PackageApi, b: PackageApi): number {
40
- return compareBytes(a.name, b.name);
41
- }
42
-
43
- export function compareEntrypoints(a: Entrypoint, b: Entrypoint): number {
44
- return compareBytes(a.subpath, b.subpath);
45
- }
46
-
47
- export function compareExports(a: ExportSignature, b: ExportSignature): number {
48
- return compareBytes(a.name, b.name);
49
- }
50
-
51
- export function compareEmitFiles(a: EmitFile, b: EmitFile): number {
52
- return comparePaths(a.path, b.path);
53
- }
54
-
55
- export function stableSortSymbols(symbols: ForgeSymbol[]): ForgeSymbol[] {
56
- return stableSortInPlace([...symbols], compareSymbols);
57
- }
58
-
59
- export function stableSortEdges(edges: ForgeEdge[]): ForgeEdge[] {
60
- return stableSortInPlace([...edges], compareEdges);
61
- }
62
-
63
- export function stableSortPackages(packages: PackageApi[]): PackageApi[] {
64
- return stableSortInPlace([...packages], comparePackages);
65
- }
66
-
67
- export function stableSortEntrypoints(
68
- entrypoints: Entrypoint[],
69
- ): Entrypoint[] {
70
- return stableSortInPlace([...entrypoints], compareEntrypoints);
71
- }
72
-
73
- export function stableSortExports(exports: ExportSignature[]): ExportSignature[] {
74
- return stableSortInPlace([...exports], compareExports);
75
- }
76
-
77
- export function stableSortEmitFiles(files: EmitFile[]): EmitFile[] {
78
- return stableSortInPlace([...files], compareEmitFiles);
79
- }
80
-
81
- export function stableSortStrings(items: string[]): string[] {
82
- return stableSortInPlace([...items], compareBytes);
83
- }
84
-
85
- export function stableSortByPath(items: string[]): string[] {
86
- return stableSortInPlace([...items], comparePaths);
87
- }
1
+ import type { ForgeEdge, ForgeSymbol } from "../types/app-graph.ts";
2
+ import type { EmitFile } from "../types/emit.ts";
3
+ import type {
4
+ Entrypoint,
5
+ ExportSignature,
6
+ PackageApi,
7
+ } from "../types/package-graph.ts";
8
+ import { compareBytes } from "./compare.ts";
9
+ import { comparePaths } from "./paths.ts";
10
+
11
+ function stableSortInPlace<T>(items: T[], compare: (a: T, b: T) => number): T[] {
12
+ items.sort(compare);
13
+ return items;
14
+ }
15
+
16
+ export function compareSymbols(a: ForgeSymbol, b: ForgeSymbol): number {
17
+ let cmp = compareBytes(a.kind, b.kind);
18
+ if (cmp !== 0) return cmp;
19
+
20
+ cmp = compareBytes(a.name, b.name);
21
+ if (cmp !== 0) return cmp;
22
+
23
+ cmp = comparePaths(a.file, b.file);
24
+ if (cmp !== 0) return cmp;
25
+
26
+ return a.span.start - b.span.start;
27
+ }
28
+
29
+ export function compareEdges(a: ForgeEdge, b: ForgeEdge): number {
30
+ let cmp = compareBytes(a.from, b.from);
31
+ if (cmp !== 0) return cmp;
32
+
33
+ cmp = compareBytes(a.to, b.to);
34
+ if (cmp !== 0) return cmp;
35
+
36
+ return compareBytes(a.kind, b.kind);
37
+ }
38
+
39
+ export function comparePackages(a: PackageApi, b: PackageApi): number {
40
+ return compareBytes(a.name, b.name);
41
+ }
42
+
43
+ export function compareEntrypoints(a: Entrypoint, b: Entrypoint): number {
44
+ return compareBytes(a.subpath, b.subpath);
45
+ }
46
+
47
+ export function compareExports(a: ExportSignature, b: ExportSignature): number {
48
+ return compareBytes(a.name, b.name);
49
+ }
50
+
51
+ export function compareEmitFiles(a: EmitFile, b: EmitFile): number {
52
+ return comparePaths(a.path, b.path);
53
+ }
54
+
55
+ export function stableSortSymbols(symbols: ForgeSymbol[]): ForgeSymbol[] {
56
+ return stableSortInPlace([...symbols], compareSymbols);
57
+ }
58
+
59
+ export function stableSortEdges(edges: ForgeEdge[]): ForgeEdge[] {
60
+ return stableSortInPlace([...edges], compareEdges);
61
+ }
62
+
63
+ export function stableSortPackages(packages: PackageApi[]): PackageApi[] {
64
+ return stableSortInPlace([...packages], comparePackages);
65
+ }
66
+
67
+ export function stableSortEntrypoints(
68
+ entrypoints: Entrypoint[],
69
+ ): Entrypoint[] {
70
+ return stableSortInPlace([...entrypoints], compareEntrypoints);
71
+ }
72
+
73
+ export function stableSortExports(exports: ExportSignature[]): ExportSignature[] {
74
+ return stableSortInPlace([...exports], compareExports);
75
+ }
76
+
77
+ export function stableSortEmitFiles(files: EmitFile[]): EmitFile[] {
78
+ return stableSortInPlace([...files], compareEmitFiles);
79
+ }
80
+
81
+ export function stableSortStrings(items: string[]): string[] {
82
+ return stableSortInPlace([...items], compareBytes);
83
+ }
84
+
85
+ export function stableSortByPath(items: string[]): string[] {
86
+ return stableSortInPlace([...items], comparePaths);
87
+ }