@sansavision/aurora 0.1.0-alpha.20260212.4

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 (150) hide show
  1. package/README.md +4 -0
  2. package/package.json +17 -0
  3. package/src/ai-diagnostics.ts +156 -0
  4. package/src/ai.ts +574 -0
  5. package/src/analyze.ts +669 -0
  6. package/src/bin/aurora.ts +15 -0
  7. package/src/build.ts +431 -0
  8. package/src/bun-test-shims.d.ts +17 -0
  9. package/src/create-feature.ts +419 -0
  10. package/src/create-route.ts +581 -0
  11. package/src/create.ts +425 -0
  12. package/src/dev.ts +126 -0
  13. package/src/devtools.ts +1143 -0
  14. package/src/doctor.ts +611 -0
  15. package/src/explain.ts +855 -0
  16. package/src/help.ts +39 -0
  17. package/src/index.ts +34 -0
  18. package/src/init.ts +1011 -0
  19. package/src/inspect-cache.ts +464 -0
  20. package/src/lsp-inline-hints.ts +254 -0
  21. package/src/node-shims.d.ts +26 -0
  22. package/src/process.d.ts +11 -0
  23. package/src/query-profiler.ts +520 -0
  24. package/src/realtime-monitor.ts +389 -0
  25. package/src/registry.ts +303 -0
  26. package/src/run.ts +37 -0
  27. package/src/start.ts +56 -0
  28. package/src/test.ts +289 -0
  29. package/templates/basic/README.md +16 -0
  30. package/templates/basic/package.json +10 -0
  31. package/templates/basic/src/actions/createMessage.action.server.ts +22 -0
  32. package/templates/basic/src/lib/auth.server.ts +11 -0
  33. package/templates/basic/src/queries/listMessages.server.ts +17 -0
  34. package/templates/basic/src/routes/index.tsx +12 -0
  35. package/templates/blog/README.md +17 -0
  36. package/templates/blog/package.json +12 -0
  37. package/templates/blog/public/assets/og-default.svg +17 -0
  38. package/templates/blog/src/content/loadPosts.server.ts +22 -0
  39. package/templates/blog/src/content/posts/hello-world.md +11 -0
  40. package/templates/blog/src/content/posts/release-notes.md +9 -0
  41. package/templates/blog/src/routes/index.tsx +22 -0
  42. package/templates/blog/src/routes/posts/[slug].tsx +19 -0
  43. package/templates/blog/src/seo/meta.ts +19 -0
  44. package/templates/dashboard/README.md +18 -0
  45. package/templates/dashboard/package.json +10 -0
  46. package/templates/dashboard/src/actions/acknowledgeAlert.action.server.ts +6 -0
  47. package/templates/dashboard/src/queries/getDashboardMetrics.server.ts +30 -0
  48. package/templates/dashboard/src/realtime/useDashboardRealtime.client.ts +13 -0
  49. package/templates/dashboard/src/routes/index.tsx +19 -0
  50. package/templates/dashboard/src/widgets/DataGrid.client.ts +8 -0
  51. package/templates/dashboard/src/widgets/MetricChart.client.ts +8 -0
  52. package/templates/desktop/README.md +18 -0
  53. package/templates/desktop/package.json +11 -0
  54. package/templates/desktop/src/actions/saveDesktopPreference.action.server.ts +28 -0
  55. package/templates/desktop/src/desktop/secureStorage.client.ts +20 -0
  56. package/templates/desktop/src/desktop/tauriBridge.client.ts +14 -0
  57. package/templates/desktop/src/queries/getDesktopSyncStatus.server.ts +9 -0
  58. package/templates/desktop/src/routes/index.tsx +27 -0
  59. package/templates/desktop/src/sync/offlineSyncBoundary.server.ts +27 -0
  60. package/templates/feature-skeleton/README.md +13 -0
  61. package/templates/feature-skeleton/actions/createFeature.action.server.ts +19 -0
  62. package/templates/feature-skeleton/index.ts +8 -0
  63. package/templates/feature-skeleton/queries/listFeature.server.ts +15 -0
  64. package/templates/feature-skeleton/realtime/useFeatureRealtime.client.ts +16 -0
  65. package/templates/feature-skeleton/template.manifest.json +15 -0
  66. package/templates/feature-skeleton/ui/FeatureView.client.tsx +14 -0
  67. package/templates/mobile/README.md +17 -0
  68. package/templates/mobile/package.json +11 -0
  69. package/templates/mobile/src/mobile/auth/session-handoff.client.ts +69 -0
  70. package/templates/mobile/src/mobile/generated/mobile-api-sdk.ts +62 -0
  71. package/templates/mobile/src/mobile/transport/mobile-api-transport.client.ts +122 -0
  72. package/templates/mobile/src/routes/index.tsx +134 -0
  73. package/templates/monorepo/README.md +18 -0
  74. package/templates/monorepo/apps/web/package.json +9 -0
  75. package/templates/monorepo/apps/web/src/routes/index.tsx +1 -0
  76. package/templates/monorepo/package.json +13 -0
  77. package/templates/monorepo/packages/shared/README.md +3 -0
  78. package/templates/monorepo/packages/ui/README.md +3 -0
  79. package/templates/saas/README.md +17 -0
  80. package/templates/saas/package.json +10 -0
  81. package/templates/saas/src/admin/getDashboard.server.ts +18 -0
  82. package/templates/saas/src/auth/session.server.ts +13 -0
  83. package/templates/saas/src/billing/checkout.server.ts +11 -0
  84. package/templates/saas/src/email/sendWelcome.server.ts +8 -0
  85. package/templates/saas/src/realtime/notifications.server.ts +8 -0
  86. package/templates/saas/src/routes/index.tsx +20 -0
  87. package/test/ai.test.ts +94 -0
  88. package/test/analyze.test.ts +301 -0
  89. package/test/build.test.ts +135 -0
  90. package/test/create-feature.test.ts +145 -0
  91. package/test/create-route.test.ts +117 -0
  92. package/test/create.test.ts +222 -0
  93. package/test/dev.test.ts +52 -0
  94. package/test/devtools.test.ts +130 -0
  95. package/test/doctor.test.ts +129 -0
  96. package/test/explain.test.ts +232 -0
  97. package/test/feature-skeleton.test.ts +53 -0
  98. package/test/fixtures/analyze/cache-input.invalid.json +1 -0
  99. package/test/fixtures/analyze/cache-input.missing-keyhash.v1.json +10 -0
  100. package/test/fixtures/analyze/cache-input.unsupported-version.v2.json +10 -0
  101. package/test/fixtures/analyze/cache-input.v1.json +12 -0
  102. package/test/fixtures/analyze/compiler-manifest/manifest.json +11 -0
  103. package/test/fixtures/analyze/guardrails-input.unsupported-version.v2.json +4 -0
  104. package/test/fixtures/analyze/guardrails-input.v1.json +49 -0
  105. package/test/fixtures/analyze/query-input.invalid-cache-status.v1.json +11 -0
  106. package/test/fixtures/analyze/query-input.unsupported-version.v2.json +11 -0
  107. package/test/fixtures/analyze/query-input.v1.json +18 -0
  108. package/test/fixtures/analyze/realtime-input.missing-lag-p95.v1.json +10 -0
  109. package/test/fixtures/analyze/realtime-input.unsupported-version.v2.json +8 -0
  110. package/test/fixtures/analyze/realtime-input.v1.json +12 -0
  111. package/test/fixtures/cache-inspector/cache-input.v1.json +23 -0
  112. package/test/fixtures/cache-inspector/invalid.json +1 -0
  113. package/test/fixtures/cache-inspector/snapshot.v1.json +34 -0
  114. package/test/fixtures/cache-inspector/unsupported-version.v2.json +13 -0
  115. package/test/fixtures/devtools/healthy.v1.json +130 -0
  116. package/test/fixtures/devtools/invalid.json +1 -0
  117. package/test/fixtures/devtools/unsupported-version.v2.json +8 -0
  118. package/test/fixtures/devtools/warn.v1.json +114 -0
  119. package/test/fixtures/doctor/clean/src/page.tsx +3 -0
  120. package/test/fixtures/doctor/findings/src/accessibility.client.tsx +7 -0
  121. package/test/fixtures/doctor/findings/src/migration.config.ts +3 -0
  122. package/test/fixtures/doctor/findings/src/page.client.tsx +5 -0
  123. package/test/fixtures/doctor/findings/src/perf.server.ts +15 -0
  124. package/test/fixtures/doctor/findings/src/routes.js +3 -0
  125. package/test/fixtures/doctor/findings/src/security.server.ts +7 -0
  126. package/test/fixtures/doctor/findings/src/users.server.ts +3 -0
  127. package/test/fixtures/doctor/governance/src/features/analytics/OWNERS.ts +2 -0
  128. package/test/fixtures/doctor/governance/src/features/analytics/page.tsx +3 -0
  129. package/test/fixtures/doctor/governance/src/features/billing/page.tsx +3 -0
  130. package/test/fixtures/explain/invalid.json +1 -0
  131. package/test/fixtures/explain/module-report.unsupported-version.v2.json +6 -0
  132. package/test/fixtures/explain/module-report.v1.json +72 -0
  133. package/test/fixtures/query-profiler/healthy.v1.json +11 -0
  134. package/test/fixtures/query-profiler/invalid.json +1 -0
  135. package/test/fixtures/query-profiler/unsupported-version.v2.json +6 -0
  136. package/test/fixtures/query-profiler/warning.v1.json +10 -0
  137. package/test/fixtures/realtime-monitor/healthy.v1.json +8 -0
  138. package/test/fixtures/realtime-monitor/invalid.json +1 -0
  139. package/test/fixtures/realtime-monitor/unsupported-version.v2.json +8 -0
  140. package/test/fixtures/realtime-monitor/warning.v1.json +8 -0
  141. package/test/help-parity.test.ts +104 -0
  142. package/test/init.test.ts +164 -0
  143. package/test/inspect-cache.test.ts +112 -0
  144. package/test/lsp-inline-hints.test.ts +65 -0
  145. package/test/query-profiler.test.ts +123 -0
  146. package/test/realtime-monitor.test.ts +115 -0
  147. package/test/registry.test.ts +41 -0
  148. package/test/start.test.ts +23 -0
  149. package/test/test-command.test.ts +65 -0
  150. package/tsconfig.json +19 -0
package/src/build.ts ADDED
@@ -0,0 +1,431 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+
4
+ import { type CommandContext, type CommandResult } from "./registry";
5
+
6
+ type BuildTarget = "node" | "edge" | "static";
7
+ type AuditSeverity = "low" | "moderate" | "high" | "critical";
8
+
9
+ interface BuildOptions {
10
+ target: BuildTarget;
11
+ analyze: boolean;
12
+ auditEnabled: boolean;
13
+ auditSeverity: AuditSeverity;
14
+ auditReportPath?: string;
15
+ }
16
+
17
+ interface DependencyAuditVulnerability {
18
+ package: string;
19
+ severity: AuditSeverity;
20
+ advisory?: string;
21
+ }
22
+
23
+ type DependencyAuditStatus =
24
+ | "passed"
25
+ | "failed"
26
+ | "skipped-disabled"
27
+ | "skipped-no-lockfile"
28
+ | "skipped-no-report";
29
+
30
+ interface DependencyAuditResult {
31
+ status: DependencyAuditStatus;
32
+ threshold: AuditSeverity;
33
+ lockfilePath?: string;
34
+ reportPath?: string;
35
+ vulnerabilities: readonly DependencyAuditVulnerability[];
36
+ violations: readonly DependencyAuditVulnerability[];
37
+ error?: string;
38
+ }
39
+
40
+ interface BuildBootstrapReport {
41
+ mode: "build";
42
+ cwd: string;
43
+ target: BuildTarget;
44
+ analyze: boolean;
45
+ compilerManifestPath: string;
46
+ outputPath: string;
47
+ securityDefaults: {
48
+ headersAndCspAutomation: "enabled";
49
+ rawSqlTaggedTemplate: "enforced";
50
+ dependencyAuditGate: "enabled" | "disabled";
51
+ };
52
+ dependencyAudit: DependencyAuditResult;
53
+ }
54
+
55
+ const AUDIT_SEVERITY_ORDER: Record<AuditSeverity, number> = {
56
+ low: 0,
57
+ moderate: 1,
58
+ high: 2,
59
+ critical: 3,
60
+ };
61
+
62
+ const LOCKFILE_CANDIDATES = [
63
+ "package-lock.json",
64
+ "pnpm-lock.yaml",
65
+ "yarn.lock",
66
+ "bun.lock",
67
+ "bun.lockb",
68
+ ] as const;
69
+
70
+ function parseBuildTarget(rawValue: string | undefined): BuildTarget | CommandResult {
71
+ if (!rawValue) {
72
+ return {
73
+ exitCode: 2,
74
+ stderr: "aurora build: --target requires one of 'node', 'edge', or 'static'",
75
+ };
76
+ }
77
+
78
+ if (rawValue === "node" || rawValue === "edge" || rawValue === "static") {
79
+ return rawValue;
80
+ }
81
+
82
+ return {
83
+ exitCode: 2,
84
+ stderr: `aurora build: invalid target '${rawValue}'. Expected 'node', 'edge', or 'static'`,
85
+ };
86
+ }
87
+
88
+ function parseAuditSeverity(rawValue: string | undefined): AuditSeverity | CommandResult {
89
+ if (!rawValue) {
90
+ return {
91
+ exitCode: 2,
92
+ stderr:
93
+ "aurora build: --audit-severity requires one of 'low', 'moderate', 'high', or 'critical'",
94
+ };
95
+ }
96
+
97
+ if (
98
+ rawValue === "low" ||
99
+ rawValue === "moderate" ||
100
+ rawValue === "high" ||
101
+ rawValue === "critical"
102
+ ) {
103
+ return rawValue;
104
+ }
105
+
106
+ return {
107
+ exitCode: 2,
108
+ stderr:
109
+ `aurora build: invalid audit severity '${rawValue}'. Expected ` +
110
+ "'low', 'moderate', 'high', or 'critical'",
111
+ };
112
+ }
113
+
114
+ function parseBuildOptions(args: ReadonlyArray<string>): BuildOptions | CommandResult {
115
+ const options: BuildOptions = {
116
+ target: "node",
117
+ analyze: false,
118
+ auditEnabled: true,
119
+ auditSeverity: "high",
120
+ };
121
+
122
+ for (let i = 0; i < args.length; i += 1) {
123
+ const arg = args[i];
124
+
125
+ if (arg === "--target") {
126
+ const parsedTarget = parseBuildTarget(args[i + 1]);
127
+ if (typeof parsedTarget !== "string") {
128
+ return parsedTarget;
129
+ }
130
+
131
+ options.target = parsedTarget;
132
+ i += 1;
133
+ continue;
134
+ }
135
+
136
+ if (arg === "--analyze") {
137
+ options.analyze = true;
138
+ continue;
139
+ }
140
+
141
+ if (arg === "--skip-audit") {
142
+ options.auditEnabled = false;
143
+ continue;
144
+ }
145
+
146
+ if (arg === "--audit-severity") {
147
+ const parsedSeverity = parseAuditSeverity(args[i + 1]);
148
+ if (typeof parsedSeverity !== "string") {
149
+ return parsedSeverity;
150
+ }
151
+
152
+ options.auditSeverity = parsedSeverity;
153
+ i += 1;
154
+ continue;
155
+ }
156
+
157
+ if (arg === "--audit-report") {
158
+ const reportPath = args[i + 1];
159
+ if (!reportPath) {
160
+ return {
161
+ exitCode: 2,
162
+ stderr: "aurora build: --audit-report requires a path",
163
+ };
164
+ }
165
+
166
+ options.auditReportPath = reportPath;
167
+ i += 1;
168
+ continue;
169
+ }
170
+
171
+ return {
172
+ exitCode: 2,
173
+ stderr: `aurora build: unknown option '${arg}'`,
174
+ };
175
+ }
176
+
177
+ return options;
178
+ }
179
+
180
+ function resolveOutputPath(cwd: string, target: BuildTarget): string {
181
+ if (target === "node") {
182
+ return resolve(cwd, ".aurora/build/node/server.mjs");
183
+ }
184
+
185
+ if (target === "edge") {
186
+ return resolve(cwd, ".aurora/build/edge/worker.mjs");
187
+ }
188
+
189
+ return resolve(cwd, ".aurora/build/static");
190
+ }
191
+
192
+ function buildBootstrapReport(
193
+ options: BuildOptions,
194
+ context: CommandContext,
195
+ dependencyAudit: DependencyAuditResult,
196
+ ): BuildBootstrapReport {
197
+ return {
198
+ mode: "build",
199
+ cwd: context.cwd,
200
+ target: options.target,
201
+ analyze: options.analyze,
202
+ compilerManifestPath: resolve(context.cwd, ".aurora/compiler/manifest.json"),
203
+ outputPath: resolveOutputPath(context.cwd, options.target),
204
+ securityDefaults: {
205
+ headersAndCspAutomation: "enabled",
206
+ rawSqlTaggedTemplate: "enforced",
207
+ dependencyAuditGate: options.auditEnabled ? "enabled" : "disabled",
208
+ },
209
+ dependencyAudit,
210
+ };
211
+ }
212
+
213
+ function renderBuildBootstrapReport(report: BuildBootstrapReport): string {
214
+ const lines = [
215
+ "aurora build bootstrap",
216
+ `cwd: ${report.cwd}`,
217
+ `target: ${report.target}`,
218
+ `compiler_manifest: ${report.compilerManifestPath}`,
219
+ `output_path: ${report.outputPath}`,
220
+ `analyze: ${report.analyze ? "enabled" : "disabled"}`,
221
+ `security_headers: ${report.securityDefaults.headersAndCspAutomation}`,
222
+ `raw_sql_tagged_template: ${report.securityDefaults.rawSqlTaggedTemplate}`,
223
+ `dependency_audit_gate: ${report.securityDefaults.dependencyAuditGate}`,
224
+ `dependency_audit_status: ${report.dependencyAudit.status}`,
225
+ `dependency_audit_threshold: ${report.dependencyAudit.threshold}`,
226
+ ];
227
+
228
+ if (report.dependencyAudit.lockfilePath) {
229
+ lines.push(`dependency_lockfile: ${report.dependencyAudit.lockfilePath}`);
230
+ }
231
+
232
+ if (report.dependencyAudit.reportPath) {
233
+ lines.push(`dependency_audit_report: ${report.dependencyAudit.reportPath}`);
234
+ }
235
+
236
+ if (report.dependencyAudit.violations.length > 0) {
237
+ lines.push(`dependency_audit_violations: ${report.dependencyAudit.violations.length}`);
238
+ }
239
+
240
+ return lines.join("\n");
241
+ }
242
+
243
+ function runDependencyAuditGate(
244
+ options: BuildOptions,
245
+ context: CommandContext,
246
+ ): DependencyAuditResult {
247
+ if (!options.auditEnabled) {
248
+ return {
249
+ status: "skipped-disabled",
250
+ threshold: options.auditSeverity,
251
+ vulnerabilities: [],
252
+ violations: [],
253
+ };
254
+ }
255
+
256
+ const lockfilePath = findDependencyLockfile(context.cwd);
257
+ if (!lockfilePath) {
258
+ return {
259
+ status: "skipped-no-lockfile",
260
+ threshold: options.auditSeverity,
261
+ vulnerabilities: [],
262
+ violations: [],
263
+ };
264
+ }
265
+
266
+ const reportPath = resolve(
267
+ context.cwd,
268
+ options.auditReportPath ?? ".aurora/security/dependency-audit.json",
269
+ );
270
+
271
+ if (!existsSync(reportPath)) {
272
+ return {
273
+ status: "skipped-no-report",
274
+ threshold: options.auditSeverity,
275
+ lockfilePath,
276
+ reportPath,
277
+ vulnerabilities: [],
278
+ violations: [],
279
+ };
280
+ }
281
+
282
+ try {
283
+ const parsed = JSON.parse(readFileSync(reportPath, "utf8")) as {
284
+ vulnerabilities?: unknown;
285
+ };
286
+
287
+ const vulnerabilities = normalizeAuditVulnerabilities(
288
+ parsed.vulnerabilities,
289
+ );
290
+ const violations = vulnerabilities.filter((entry) =>
291
+ isSeverityAtOrAbove(entry.severity, options.auditSeverity),
292
+ );
293
+
294
+ return {
295
+ status: violations.length > 0 ? "failed" : "passed",
296
+ threshold: options.auditSeverity,
297
+ lockfilePath,
298
+ reportPath,
299
+ vulnerabilities,
300
+ violations,
301
+ };
302
+ } catch (error) {
303
+ return {
304
+ status: "failed",
305
+ threshold: options.auditSeverity,
306
+ lockfilePath,
307
+ reportPath,
308
+ vulnerabilities: [],
309
+ violations: [],
310
+ error:
311
+ error instanceof Error
312
+ ? error.message
313
+ : "unable to parse dependency audit report",
314
+ };
315
+ }
316
+ }
317
+
318
+ function normalizeAuditVulnerabilities(
319
+ input: unknown,
320
+ ): readonly DependencyAuditVulnerability[] {
321
+ if (!Array.isArray(input)) {
322
+ return [];
323
+ }
324
+
325
+ const vulnerabilities: DependencyAuditVulnerability[] = [];
326
+
327
+ for (const entry of input) {
328
+ if (!entry || typeof entry !== "object") {
329
+ continue;
330
+ }
331
+
332
+ const packageName = sanitizeNonEmpty(
333
+ (entry as Record<string, unknown>)["package"],
334
+ );
335
+ const severity = sanitizeNonEmpty(
336
+ (entry as Record<string, unknown>)["severity"],
337
+ );
338
+
339
+ if (!packageName || severity === undefined || !isAuditSeverity(severity)) {
340
+ continue;
341
+ }
342
+
343
+ const advisory = sanitizeNonEmpty(
344
+ (entry as Record<string, unknown>)["advisory"],
345
+ );
346
+
347
+ vulnerabilities.push({
348
+ package: packageName,
349
+ severity,
350
+ advisory,
351
+ });
352
+ }
353
+
354
+ return vulnerabilities;
355
+ }
356
+
357
+ function sanitizeNonEmpty(value: unknown): string | undefined {
358
+ if (typeof value !== "string") {
359
+ return undefined;
360
+ }
361
+
362
+ const normalized = value.trim();
363
+ return normalized.length > 0 ? normalized : undefined;
364
+ }
365
+
366
+ function isAuditSeverity(value: string): value is AuditSeverity {
367
+ return (
368
+ value === "low" ||
369
+ value === "moderate" ||
370
+ value === "high" ||
371
+ value === "critical"
372
+ );
373
+ }
374
+
375
+ function isSeverityAtOrAbove(
376
+ value: AuditSeverity,
377
+ threshold: AuditSeverity,
378
+ ): boolean {
379
+ return AUDIT_SEVERITY_ORDER[value] >= AUDIT_SEVERITY_ORDER[threshold];
380
+ }
381
+
382
+ function findDependencyLockfile(cwd: string): string | undefined {
383
+ for (const lockfile of LOCKFILE_CANDIDATES) {
384
+ const resolved = resolve(cwd, lockfile);
385
+ if (existsSync(resolved)) {
386
+ return resolved;
387
+ }
388
+ }
389
+
390
+ return undefined;
391
+ }
392
+
393
+ function renderAuditFailure(result: DependencyAuditResult): string {
394
+ if (result.error) {
395
+ return `aurora build: dependency audit failed (${result.error})`;
396
+ }
397
+
398
+ const violations = result.violations
399
+ .map((entry) => `${entry.package}:${entry.severity}`)
400
+ .join(", ");
401
+
402
+ return (
403
+ "aurora build: dependency audit failed for severity >= " +
404
+ `'${result.threshold}'` +
405
+ (violations.length > 0 ? ` (${violations})` : "")
406
+ );
407
+ }
408
+
409
+ export function runBuildCommand(
410
+ args: ReadonlyArray<string>,
411
+ context: CommandContext,
412
+ ): CommandResult {
413
+ const options = parseBuildOptions(args);
414
+ if ("exitCode" in options) {
415
+ return options;
416
+ }
417
+
418
+ const dependencyAudit = runDependencyAuditGate(options, context);
419
+ if (dependencyAudit.status === "failed") {
420
+ return {
421
+ exitCode: 1,
422
+ stderr: renderAuditFailure(dependencyAudit),
423
+ };
424
+ }
425
+
426
+ const report = buildBootstrapReport(options, context, dependencyAudit);
427
+ return {
428
+ exitCode: 0,
429
+ stdout: renderBuildBootstrapReport(report),
430
+ };
431
+ }
@@ -0,0 +1,17 @@
1
+ declare module "bun:test" {
2
+ export function describe(name: string, fn: () => void): void;
3
+ export function it(name: string, fn: () => void): void;
4
+
5
+ interface Matchers {
6
+ toBe(value: unknown): void;
7
+ toContain(value: string): void;
8
+ toEqual(value: unknown): void;
9
+ toBeDefined(): void;
10
+ }
11
+
12
+ export function expect(value: unknown): Matchers;
13
+ }
14
+
15
+ interface ImportMeta {
16
+ dir: string;
17
+ }