@gravito/launchpad 1.2.1 → 1.2.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @gravito/launchpad
2
2
 
3
+ ## 1.2.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 905588f: fix: replace insecure Math.random() with crypto.randomUUID() for ID and temporary path generation (CWE-330)
8
+
3
9
  ## 1.2.1
4
10
 
5
11
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -9,6 +9,15 @@ interface MissionProps {
9
9
  branch: string;
10
10
  commitSha: string;
11
11
  }
12
+ /**
13
+ * Mission represents a deployment task for a specific code version.
14
+ *
15
+ * It is a Value Object containing information about the source repository,
16
+ * branch, and commit to be deployed.
17
+ *
18
+ * @public
19
+ * @since 3.0.0
20
+ */
12
21
  declare class Mission extends ValueObject<MissionProps> {
13
22
  get id(): string;
14
23
  get repoUrl(): string;
@@ -28,6 +37,16 @@ declare enum RocketStatus {
28
37
  DECOMMISSIONED = "DECOMMISSIONED"
29
38
  }
30
39
 
40
+ /**
41
+ * Rocket represents a managed application container within Launchpad.
42
+ *
43
+ * It acts as an Aggregate Root in the domain, maintaining its lifecycle state
44
+ * (IDLE, PREPARING, ORBITING, etc.) and emitting domain events when
45
+ * state transitions occur.
46
+ *
47
+ * @public
48
+ * @since 3.0.0
49
+ */
31
50
  declare class Rocket extends AggregateRoot<string> {
32
51
  private _status;
33
52
  private _currentMission;
@@ -140,6 +159,15 @@ interface IRocketRepository {
140
159
  delete(id: string): Promise<void>;
141
160
  }
142
161
 
162
+ /**
163
+ * PayloadInjector is responsible for deploying application code into Rocket containers.
164
+ *
165
+ * It clones the repository, copies files into the container, installs
166
+ * dependencies (using Bun), and starts the application.
167
+ *
168
+ * @public
169
+ * @since 3.0.0
170
+ */
143
171
  declare class PayloadInjector {
144
172
  private docker;
145
173
  private git;
@@ -147,6 +175,16 @@ declare class PayloadInjector {
147
175
  deploy(rocket: Rocket): Promise<void>;
148
176
  }
149
177
 
178
+ /**
179
+ * RefurbishUnit handles the cleaning and restoration of Rocket containers.
180
+ *
181
+ * After a mission is complete, this unit resets the container environment
182
+ * (clearing files, stopping processes) so the container can be returned
183
+ * to the idle pool for future reuse.
184
+ *
185
+ * @public
186
+ * @since 3.0.0
187
+ */
150
188
  declare class RefurbishUnit {
151
189
  private docker;
152
190
  constructor(docker: IDockerAdapter);
@@ -156,6 +194,15 @@ declare class RefurbishUnit {
156
194
  refurbish(rocket: Rocket): Promise<void>;
157
195
  }
158
196
 
197
+ /**
198
+ * PoolManager handles the lifecycle and pooling of Rocket containers.
199
+ *
200
+ * It manages a pool of pre-warmed containers to ensure fast deployment of
201
+ * new missions. It also handles rocket assignment and recycling (refurbishment).
202
+ *
203
+ * @public
204
+ * @since 3.0.0
205
+ */
159
206
  declare class PoolManager {
160
207
  private dockerAdapter;
161
208
  private rocketRepository;
@@ -176,6 +223,15 @@ declare class PoolManager {
176
223
  recycle(missionId: string): Promise<void>;
177
224
  }
178
225
 
226
+ /**
227
+ * MissionControl orchestrates the high-level process of launching missions.
228
+ *
229
+ * it coordinates between the `PoolManager`, `PayloadInjector`, and `DockerAdapter`
230
+ * to deploy code into containers, assign domains, and monitor execution.
231
+ *
232
+ * @public
233
+ * @since 3.0.0
234
+ */
179
235
  declare class MissionControl {
180
236
  private poolManager;
181
237
  private injector;
@@ -186,15 +242,33 @@ declare class MissionControl {
186
242
  }
187
243
 
188
244
  /**
189
- * Gravito Launchpad Orbit
245
+ * LaunchpadOrbit provides automated deployment and preview capabilities for Gravito.
246
+ * It integrates with Docker and GitHub to provide "Preview Deployments" for Pull Requests.
247
+ *
248
+ * @public
190
249
  */
191
250
  declare class LaunchpadOrbit implements GravitoOrbit {
192
251
  private ripple;
252
+ /**
253
+ * Create a new LaunchpadOrbit instance.
254
+ * @param ripple - Ripple instance for real-time telemetry communication.
255
+ */
193
256
  constructor(ripple: OrbitRipple);
257
+ /**
258
+ * Install the Launchpad orbit into PlanetCore.
259
+ * Registers the service provider and sets up webhook routes for deployment.
260
+ *
261
+ * @param core - The PlanetCore instance.
262
+ */
194
263
  install(core: PlanetCore): Promise<void>;
195
264
  }
196
265
  /**
197
- * 一鍵啟動 Launchpad 應用程式
266
+ * Bootstrap the Launchpad application.
267
+ * Initializes PlanetCore with necessary orbits (Cache, Ripple, Launchpad)
268
+ * and returns the configuration for the server entry point.
269
+ *
270
+ * @returns Server configuration object including port and fetch handler.
271
+ * @public
198
272
  */
199
273
  declare function bootstrapLaunchpad(): Promise<{
200
274
  port: number;
package/dist/index.d.ts CHANGED
@@ -9,6 +9,15 @@ interface MissionProps {
9
9
  branch: string;
10
10
  commitSha: string;
11
11
  }
12
+ /**
13
+ * Mission represents a deployment task for a specific code version.
14
+ *
15
+ * It is a Value Object containing information about the source repository,
16
+ * branch, and commit to be deployed.
17
+ *
18
+ * @public
19
+ * @since 3.0.0
20
+ */
12
21
  declare class Mission extends ValueObject<MissionProps> {
13
22
  get id(): string;
14
23
  get repoUrl(): string;
@@ -28,6 +37,16 @@ declare enum RocketStatus {
28
37
  DECOMMISSIONED = "DECOMMISSIONED"
29
38
  }
30
39
 
40
+ /**
41
+ * Rocket represents a managed application container within Launchpad.
42
+ *
43
+ * It acts as an Aggregate Root in the domain, maintaining its lifecycle state
44
+ * (IDLE, PREPARING, ORBITING, etc.) and emitting domain events when
45
+ * state transitions occur.
46
+ *
47
+ * @public
48
+ * @since 3.0.0
49
+ */
31
50
  declare class Rocket extends AggregateRoot<string> {
32
51
  private _status;
33
52
  private _currentMission;
@@ -140,6 +159,15 @@ interface IRocketRepository {
140
159
  delete(id: string): Promise<void>;
141
160
  }
142
161
 
162
+ /**
163
+ * PayloadInjector is responsible for deploying application code into Rocket containers.
164
+ *
165
+ * It clones the repository, copies files into the container, installs
166
+ * dependencies (using Bun), and starts the application.
167
+ *
168
+ * @public
169
+ * @since 3.0.0
170
+ */
143
171
  declare class PayloadInjector {
144
172
  private docker;
145
173
  private git;
@@ -147,6 +175,16 @@ declare class PayloadInjector {
147
175
  deploy(rocket: Rocket): Promise<void>;
148
176
  }
149
177
 
178
+ /**
179
+ * RefurbishUnit handles the cleaning and restoration of Rocket containers.
180
+ *
181
+ * After a mission is complete, this unit resets the container environment
182
+ * (clearing files, stopping processes) so the container can be returned
183
+ * to the idle pool for future reuse.
184
+ *
185
+ * @public
186
+ * @since 3.0.0
187
+ */
150
188
  declare class RefurbishUnit {
151
189
  private docker;
152
190
  constructor(docker: IDockerAdapter);
@@ -156,6 +194,15 @@ declare class RefurbishUnit {
156
194
  refurbish(rocket: Rocket): Promise<void>;
157
195
  }
158
196
 
197
+ /**
198
+ * PoolManager handles the lifecycle and pooling of Rocket containers.
199
+ *
200
+ * It manages a pool of pre-warmed containers to ensure fast deployment of
201
+ * new missions. It also handles rocket assignment and recycling (refurbishment).
202
+ *
203
+ * @public
204
+ * @since 3.0.0
205
+ */
159
206
  declare class PoolManager {
160
207
  private dockerAdapter;
161
208
  private rocketRepository;
@@ -176,6 +223,15 @@ declare class PoolManager {
176
223
  recycle(missionId: string): Promise<void>;
177
224
  }
178
225
 
226
+ /**
227
+ * MissionControl orchestrates the high-level process of launching missions.
228
+ *
229
+ * it coordinates between the `PoolManager`, `PayloadInjector`, and `DockerAdapter`
230
+ * to deploy code into containers, assign domains, and monitor execution.
231
+ *
232
+ * @public
233
+ * @since 3.0.0
234
+ */
179
235
  declare class MissionControl {
180
236
  private poolManager;
181
237
  private injector;
@@ -186,15 +242,33 @@ declare class MissionControl {
186
242
  }
187
243
 
188
244
  /**
189
- * Gravito Launchpad Orbit
245
+ * LaunchpadOrbit provides automated deployment and preview capabilities for Gravito.
246
+ * It integrates with Docker and GitHub to provide "Preview Deployments" for Pull Requests.
247
+ *
248
+ * @public
190
249
  */
191
250
  declare class LaunchpadOrbit implements GravitoOrbit {
192
251
  private ripple;
252
+ /**
253
+ * Create a new LaunchpadOrbit instance.
254
+ * @param ripple - Ripple instance for real-time telemetry communication.
255
+ */
193
256
  constructor(ripple: OrbitRipple);
257
+ /**
258
+ * Install the Launchpad orbit into PlanetCore.
259
+ * Registers the service provider and sets up webhook routes for deployment.
260
+ *
261
+ * @param core - The PlanetCore instance.
262
+ */
194
263
  install(core: PlanetCore): Promise<void>;
195
264
  }
196
265
  /**
197
- * 一鍵啟動 Launchpad 應用程式
266
+ * Bootstrap the Launchpad application.
267
+ * Initializes PlanetCore with necessary orbits (Cache, Ripple, Launchpad)
268
+ * and returns the configuration for the server entry point.
269
+ *
270
+ * @returns Server configuration object including port and fetch handler.
271
+ * @public
198
272
  */
199
273
  declare function bootstrapLaunchpad(): Promise<{
200
274
  port: number;
package/dist/index.js CHANGED
@@ -298,7 +298,7 @@ var PoolManager = class {
298
298
  console.log(`[LaunchPad] \u6B63\u5728\u71B1\u6A5F\uFF0C\u6E96\u5099\u767C\u5C04 ${needed} \u67B6\u65B0\u706B\u7BAD...`);
299
299
  for (let i = 0; i < needed; i++) {
300
300
  const containerId = await this.dockerAdapter.createBaseContainer();
301
- const rocketId = `rocket-${Math.random().toString(36).substring(2, 9)}`;
301
+ const rocketId = `rocket-${crypto.randomUUID()}`;
302
302
  const rocket = new Rocket(rocketId, containerId);
303
303
  await this.rocketRepository.save(rocket);
304
304
  }
@@ -394,7 +394,7 @@ var DockerAdapter = class {
394
394
  baseImage = "oven/bun:1.0-slim";
395
395
  runtime = (0, import_core.getRuntimeAdapter)();
396
396
  async createBaseContainer() {
397
- const rocketId = `rocket-${Math.random().toString(36).substring(2, 9)}`;
397
+ const rocketId = `rocket-${crypto.randomUUID()}`;
398
398
  const proc = this.runtime.spawn([
399
399
  "docker",
400
400
  "run",
@@ -509,7 +509,7 @@ var import_core2 = require("@gravito/core");
509
509
  var ShellGitAdapter = class {
510
510
  baseDir = "/tmp/gravito-launchpad-git";
511
511
  async clone(repoUrl, branch) {
512
- const dirName = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
512
+ const dirName = `${Date.now()}-${crypto.randomUUID()}`;
513
513
  const targetDir = `${this.baseDir}/${dirName}`;
514
514
  await (0, import_promises.mkdir)(this.baseDir, { recursive: true });
515
515
  const runtime = (0, import_core2.getRuntimeAdapter)();
@@ -704,9 +704,19 @@ var LaunchpadServiceProvider = class extends import_core4.ServiceProvider {
704
704
  }
705
705
  };
706
706
  var LaunchpadOrbit = class {
707
+ /**
708
+ * Create a new LaunchpadOrbit instance.
709
+ * @param ripple - Ripple instance for real-time telemetry communication.
710
+ */
707
711
  constructor(ripple) {
708
712
  this.ripple = ripple;
709
713
  }
714
+ /**
715
+ * Install the Launchpad orbit into PlanetCore.
716
+ * Registers the service provider and sets up webhook routes for deployment.
717
+ *
718
+ * @param core - The PlanetCore instance.
719
+ */
710
720
  async install(core) {
711
721
  core.register(new LaunchpadServiceProvider());
712
722
  core.router.post("/launch", async (c) => {
@@ -780,12 +790,7 @@ async function bootstrapLaunchpad() {
780
790
  PORT: 4e3,
781
791
  CACHE_DRIVER: "file"
782
792
  },
783
- orbits: [
784
- new import_stasis.OrbitCache(),
785
- ripple,
786
- new LaunchpadOrbit(ripple)
787
- // 傳入實例
788
- ]
793
+ orbits: [new import_stasis.OrbitCache(), ripple, new LaunchpadOrbit(ripple)]
789
794
  });
790
795
  await core.bootstrap();
791
796
  const liftoffConfig = core.liftoff();
package/dist/index.mjs CHANGED
@@ -266,7 +266,7 @@ var PoolManager = class {
266
266
  console.log(`[LaunchPad] \u6B63\u5728\u71B1\u6A5F\uFF0C\u6E96\u5099\u767C\u5C04 ${needed} \u67B6\u65B0\u706B\u7BAD...`);
267
267
  for (let i = 0; i < needed; i++) {
268
268
  const containerId = await this.dockerAdapter.createBaseContainer();
269
- const rocketId = `rocket-${Math.random().toString(36).substring(2, 9)}`;
269
+ const rocketId = `rocket-${crypto.randomUUID()}`;
270
270
  const rocket = new Rocket(rocketId, containerId);
271
271
  await this.rocketRepository.save(rocket);
272
272
  }
@@ -362,7 +362,7 @@ var DockerAdapter = class {
362
362
  baseImage = "oven/bun:1.0-slim";
363
363
  runtime = getRuntimeAdapter();
364
364
  async createBaseContainer() {
365
- const rocketId = `rocket-${Math.random().toString(36).substring(2, 9)}`;
365
+ const rocketId = `rocket-${crypto.randomUUID()}`;
366
366
  const proc = this.runtime.spawn([
367
367
  "docker",
368
368
  "run",
@@ -477,7 +477,7 @@ import { getRuntimeAdapter as getRuntimeAdapter2 } from "@gravito/core";
477
477
  var ShellGitAdapter = class {
478
478
  baseDir = "/tmp/gravito-launchpad-git";
479
479
  async clone(repoUrl, branch) {
480
- const dirName = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
480
+ const dirName = `${Date.now()}-${crypto.randomUUID()}`;
481
481
  const targetDir = `${this.baseDir}/${dirName}`;
482
482
  await mkdir(this.baseDir, { recursive: true });
483
483
  const runtime = getRuntimeAdapter2();
@@ -672,9 +672,19 @@ var LaunchpadServiceProvider = class extends ServiceProvider {
672
672
  }
673
673
  };
674
674
  var LaunchpadOrbit = class {
675
+ /**
676
+ * Create a new LaunchpadOrbit instance.
677
+ * @param ripple - Ripple instance for real-time telemetry communication.
678
+ */
675
679
  constructor(ripple) {
676
680
  this.ripple = ripple;
677
681
  }
682
+ /**
683
+ * Install the Launchpad orbit into PlanetCore.
684
+ * Registers the service provider and sets up webhook routes for deployment.
685
+ *
686
+ * @param core - The PlanetCore instance.
687
+ */
678
688
  async install(core) {
679
689
  core.register(new LaunchpadServiceProvider());
680
690
  core.router.post("/launch", async (c) => {
@@ -748,12 +758,7 @@ async function bootstrapLaunchpad() {
748
758
  PORT: 4e3,
749
759
  CACHE_DRIVER: "file"
750
760
  },
751
- orbits: [
752
- new OrbitCache(),
753
- ripple,
754
- new LaunchpadOrbit(ripple)
755
- // 傳入實例
756
- ]
761
+ orbits: [new OrbitCache(), ripple, new LaunchpadOrbit(ripple)]
757
762
  });
758
763
  await core.bootstrap();
759
764
  const liftoffConfig = core.liftoff();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravito/launchpad",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "Container lifecycle management system for flash deployments",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -35,7 +35,7 @@ export class PoolManager {
35
35
 
36
36
  for (let i = 0; i < needed; i++) {
37
37
  const containerId = await this.dockerAdapter.createBaseContainer()
38
- const rocketId = `rocket-${Math.random().toString(36).substring(2, 9)}`
38
+ const rocketId = `rocket-${crypto.randomUUID()}`
39
39
  const rocket = new Rocket(rocketId, containerId)
40
40
  await this.rocketRepository.save(rocket)
41
41
  }
@@ -15,7 +15,7 @@ export class DockerAdapter implements IDockerAdapter {
15
15
  private runtime = getRuntimeAdapter()
16
16
 
17
17
  async createBaseContainer(): Promise<string> {
18
- const rocketId = `rocket-${Math.random().toString(36).substring(2, 9)}`
18
+ const rocketId = `rocket-${crypto.randomUUID()}`
19
19
 
20
20
  const proc = this.runtime.spawn([
21
21
  'docker',
@@ -15,7 +15,7 @@ export class ShellGitAdapter implements IGitAdapter {
15
15
  private baseDir = '/tmp/gravito-launchpad-git'
16
16
 
17
17
  async clone(repoUrl: string, branch: string): Promise<string> {
18
- const dirName = `${Date.now()}-${Math.random().toString(36).slice(2)}`
18
+ const dirName = `${Date.now()}-${crypto.randomUUID()}`
19
19
  const targetDir = `${this.baseDir}/${dirName}`
20
20
 
21
21
  await mkdir(this.baseDir, { recursive: true })
@@ -1,18 +0,0 @@
1
-
2
- $ tsup src/index.ts --format cjs,esm --dts
3
- CLI Building entry: src/index.ts
4
- CLI Using tsconfig: tsconfig.json
5
- CLI tsup v8.5.1
6
- CLI Target: esnext
7
- CJS Build start
8
- ESM Build start
9
- CJS You have emitDecoratorMetadata enabled but @swc/core was not installed, skipping swc plugin
10
- ESM You have emitDecoratorMetadata enabled but @swc/core was not installed, skipping swc plugin
11
- CJS dist/index.js 27.01 KB
12
- CJS ⚡️ Build success in 24ms
13
- ESM dist/index.mjs 25.50 KB
14
- ESM ⚡️ Build success in 24ms
15
- DTS Build start
16
- DTS ⚡️ Build success in 1979ms
17
- DTS dist/index.d.ts 5.14 KB
18
- DTS dist/index.d.mts 5.14 KB
@@ -1,183 +0,0 @@
1
- $ bun test --coverage --coverage-threshold=80
2
- bun test v1.3.4 (5eb2145b)
3
-
4
- tests/mission.test.ts:
5
- (pass) Mission > exposes mission properties [0.31ms]
6
-
7
- tests/Telemetry.test.ts:
8
- [MissionControl] 準備發射任務: pr-1
9
- [MissionControl] 任務 pr-1 映射端口: 3000
10
- (pass) MissionControl Telemetry > 發射時應該能正確啟動日誌串流與效能監控 [6.79ms]
11
-
12
- tests/mission-control.test.ts:
13
- [MissionControl] 準備發射任務: mission-telemetry
14
- [MissionControl] 任務 mission-telemetry 映射端口: 3000
15
- [MissionControl] 任務 mission-telemetry TTL 已到期,執行自動回收...
16
- (pass) MissionControl timers > emits stats and schedules recycle [2.17ms]
17
-
18
- tests/pool-manager.test.ts:
19
- [LaunchPad] 正在熱機,準備發射 2 架新火箭...
20
- (pass) PoolManager > warms up the pool with base containers [1.23ms]
21
- [LaunchPad] 正在熱機,準備發射 1 架新火箭...
22
- [LaunchPad] 資源吃緊,正在緊急呼叫後援火箭...
23
- (pass) PoolManager > assigns missions to idle rockets or creates new ones [1.90ms]
24
- [LaunchPad] 正在熱機,準備發射 1 架新火箭...
25
- (pass) PoolManager > recycles rockets through refurbish flow [2.99ms]
26
-
27
- tests/enterprise-coverage.test.ts:
28
- (pass) Launchpad enterprise coverage > covers core enterprise primitives [0.56ms]
29
-
30
- tests/repository.test.ts:
31
- (pass) InMemoryRocketRepository > stores and retrieves rockets [0.75ms]
32
- (pass) InMemoryRocketRepository > finds idle rockets [0.19ms]
33
-
34
- tests/Rocket.test.ts:
35
- (pass) Rocket > transitions through mission lifecycle and emits events [0.17ms]
36
- (pass) Rocket > guards invalid transitions [0.19ms]
37
- (pass) Rocket > assigns domain and serializes/deserializes [0.15ms]
38
- (pass) Rocket > rejects assigning mission when not idle [0.06ms]
39
-
40
- tests/Refurbishment.test.ts:
41
- (pass) RefurbishUnit (Rocket Recovery) > 應該能執行深度清理並將火箭重置為 IDLE [1.11ms]
42
- [RefurbishUnit] 正在翻新火箭: r1 (容器: c1)
43
- [RefurbishUnit] 火箭 r1 翻新完成,已進入 IDLE 狀態。
44
- [RefurbishUnit] 正在翻新火箭: r2 (容器: c2)
45
- [RefurbishUnit] 清理失敗: Disk Full
46
- (pass) RefurbishUnit (Rocket Recovery) > 如果清理失敗應該將火箭除役 [0.28ms]
47
-
48
- tests/payload-injector.test.ts:
49
- (pass) PayloadInjector > throws when rocket has no mission [1.02ms]
50
- [PayloadInjector] 正在拉取代碼: https://example.com/repo.git (main)
51
- [PayloadInjector] 正在注入載荷至容器: container-10
52
- [PayloadInjector] 正在安裝依賴...
53
- [PayloadInjector] 點火!
54
- (pass) PayloadInjector > deploys payload and ignites rocket [0.78ms]
55
- [PayloadInjector] 正在拉取代碼: https://example.com/repo.git (main)
56
- [PayloadInjector] 正在注入載荷至容器: container-11
57
- [PayloadInjector] 正在安裝依賴...
58
- (pass) PayloadInjector > throws when install fails [4.37ms]
59
- [PayloadInjector] 正在拉取代碼: https://example.com/repo.git (main)
60
- [PayloadInjector] 正在注入載荷至容器: container-12
61
- [PayloadInjector] 正在安裝依賴...
62
- [PayloadInjector] 點火!
63
- (pass) PayloadInjector > logs when run command fails but still ignites [8.24ms]
64
-
65
- tests/docker-adapter.test.ts:
66
- (pass) DockerAdapter > creates base container when stdout has container id [8.90ms]
67
- (pass) DockerAdapter > returns container id even when exit code is zero but id is invalid [0.28ms]
68
- (pass) DockerAdapter > throws when container creation fails [0.70ms]
69
- (pass) DockerAdapter > getExposedPort parses the first line [1.64ms]
70
- (pass) DockerAdapter > getExposedPort throws on empty output [6.46ms]
71
- (pass) DockerAdapter > getExposedPort throws on invalid output [4.70ms]
72
- (pass) DockerAdapter > copyFiles throws on non-zero exit code [0.54ms]
73
- (pass) DockerAdapter > removeContainerByLabel removes containers when ids exist [0.72ms]
74
- (pass) DockerAdapter > executeCommand returns stdout and stderr [3.41ms]
75
- (pass) DockerAdapter > removeContainer executes docker rm [1.66ms]
76
- (pass) DockerAdapter > getStats parses cpu and memory output [0.39ms]
77
- (pass) DockerAdapter > streamLogs forwards stdout and stderr [43.53ms]
78
-
79
- tests/Integration.test.ts:
80
- [LaunchPad] 正在熱機,準備發射 1 架新火箭...
81
- [Test] 容器內 Bun 版本: 1.0.36
82
- (pass) LaunchPad 集成測試 (真實 Docker) > 應該能成功熱機並在容器內執行指令 [3201.00ms]
83
-
84
- tests/Deployment.test.ts:
85
- [LaunchPad] 資源吃緊,正在緊急呼叫後援火箭...
86
- [PayloadInjector] 正在拉取代碼: http://git (dev)
87
- [PayloadInjector] 正在注入載荷至容器: cid-1
88
- [PayloadInjector] 正在安裝依賴...
89
- [PayloadInjector] 點火!
90
- (pass) Payload Injection Flow > 應該能從指派任務到成功點火 [1.02ms]
91
-
92
- tests/PoolManager.test.ts:
93
- (pass) PoolManager (Application Service) > 應該能正確熱機並指派任務 [1.54ms]
94
- ------------------------------------------------------------|---------|---------|-------------------
95
- File | % Funcs | % Lines | Uncovered Line #s
96
- [LaunchPad] 正在熱機,準備發射 2 架新火箭...
97
- ------------------------------------------------------------|---------|---------|-------------------
98
- All files | 30.25 | 42.00 |
99
- ../core/src/Application.ts | 0.00 | 8.87 | 139-313,325-326,336-337,348,358,368,375,382
100
- ../core/src/ConfigManager.ts | 0.00 | 14.04 | 16-22,29-34,42-75,82
101
- ../core/src/Container.ts | 0.00 | 28.95 | 26,34,41,48-67,74,81-82
102
- ../core/src/ErrorHandler.ts | 0.00 | 3.45 | 23-41,49-75,101-297,304-325,332-357,365-381
103
- ../core/src/Event.ts | 100.00 | 100.00 |
104
- ../core/src/EventManager.ts | 0.00 | 7.01 | 78,85,108-126,136-243,250-256,263-271
105
- ../core/src/GlobalErrorHandlers.ts | 0.00 | 1.19 | 58-72,78-88,92-101,106-186,191-210,214-228,239-252
106
- ../core/src/GravitoServer.ts | 0.00 | 8.77 | 25-76
107
- ../core/src/HookManager.ts | 0.00 | 8.33 | 37-73,93-121
108
- ../core/src/Logger.ts | 0.00 | 55.56 | 17,21,25
109
- ../core/src/PlanetCore.ts | 0.00 | 10.53 | 117-131,162-208,218-227,237-269,273-390,394-443,453-468,485-501
110
- ../core/src/Route.ts | 0.00 | 44.44 | 18-22,28-29,44,55,66,77,88,92,96
111
- ../core/src/Router.ts | 0.00 | 7.68 | 68-121,131-154,182-184,190-193,201-205,212,224-232,243-251,262-270,281-289,300-308,312-354,365-380,414-459,466-471,478-505,512,522-524,531,538-553,557-600,607,614,622,636-644,658-666,680-688,702-710,724-732,743-758,765-803,810-892,899-913
112
- ../core/src/ServiceProvider.ts | 0.00 | 15.07 | 58,91,114-150,179-188,198-209
113
- ../core/src/adapters/GravitoEngineAdapter.ts | 0.00 | 30.43 | 27-31,35-44,48-50,54,58,62-65,69,73,78-81,85-86
114
- ../core/src/adapters/PhotonAdapter.ts | 0.00 | 13.93 | 46,53-55,62-108,112,116,120,124,130-163,167-168,191-195,203-207,214-257,261-262,266-269,273-276,280-283,287-298,302-309,313-318,322,326,330,334,341-355,359,363,367-446,462-467,471-473,487-492,501-512,521-528,564-584,592,596-612,616-626,630-635,639,643-651,656,660-675,683-695,708-710
115
- ../core/src/adapters/bun/BunContext.ts | 0.00 | 12.58 | 38-44,52-75,80-86,90-96,100-106,110-116,120-125,129-134,138,142,146,150-182,189-205,209,214,218-223
116
- ../core/src/adapters/bun/BunNativeAdapter.ts | 0.00 | 10.23 | 21-23,32-36,40-46,50,54,58-87,91,95,99-207
117
- ../core/src/adapters/bun/BunRequest.ts | 0.00 | 10.62 | 13-17,22-34,39,43,47-55,59-62,68-108,114,118-131,135-146
118
- ../core/src/adapters/bun/RadixNode.ts | 0.00 | 17.65 | 39-40,44-52,56-72
119
- ../core/src/adapters/bun/RadixRouter.ts | 0.00 | 8.13 | 17,24-62,69-84,88-148,152-162,169-175,182-193
120
- ../core/src/adapters/bun/types.ts | 100.00 | 100.00 |
121
- ../core/src/adapters/types.ts | 0.00 | 0.00 | 280-287
122
- ../core/src/engine/AOTRouter.ts | 0.00 | 10.78 | 67-85,93-133,144-145,157-159,172-208,215,228-272,279,294-306,320-327,334-345
123
- ../core/src/engine/FastContext.ts | 0.00 | 19.09 | 30,37-45,52-61,65-84,88-89,93-94,98-101,105-109,113-129,133-134,138-169,192-198,208-212,219-223,231-236,240-245,249-254,258-263,267-271,275-280,284,288,292,296-319,329-334,338,349,353,361-363
124
- ../core/src/engine/Gravito.ts | 0.00 | 14.67 | 38-52,82-103,118,125,132,139,146,153,160,167-171,184-197,208-214,225-226,233-255,293-322,330-367,374-391,398-410,417-421,428-456,463-519
125
- ../core/src/engine/MinimalContext.ts | 0.00 | 21.57 | 23-37,41,45,52-64,68,72-84,88,92-112,130,139-142,146-149,153-156,160-163,167-170,174-177,183-187,195-198,202,206,210,214-225,229,235-237
126
- ../core/src/engine/analyzer.ts | 0.00 | 2.08 | 25-49,56-77
127
- ../core/src/engine/constants.ts | 100.00 | 100.00 |
128
- ../core/src/engine/index.ts | 100.00 | 100.00 |
129
- ../core/src/engine/path.ts | 0.00 | 2.63 | 22-43,51-65
130
- ../core/src/engine/pool.ts | 0.00 | 16.67 | 44-46,58-64,76-79,89-103,114-119
131
- ../core/src/exceptions/AuthenticationException.ts | 0.00 | 42.86 | 8-11
132
- ../core/src/exceptions/AuthorizationException.ts | 0.00 | 42.86 | 8-11
133
- ../core/src/exceptions/GravitoException.ts | 0.00 | 19.05 | 24-34,39-44
134
- ../core/src/exceptions/HttpException.ts | 0.00 | 60.00 | 9-10
135
- ../core/src/exceptions/ModelNotFoundException.ts | 0.00 | 25.00 | 11-19
136
- ../core/src/exceptions/ValidationException.ts | 0.00 | 35.71 | 22-26,30-31,35-36
137
- ../core/src/exceptions/index.ts | 100.00 | 100.00 |
138
- ../core/src/helpers.ts | 0.00 | 23.14 | 19,54-59,81-82,107-108,133-139,143-147,176-196,218,222-228,248-253,272-277,306-308,323,335,356-359,381-384,403,417,438-441,461-463,483-489
139
- ../core/src/helpers/Arr.ts | 0.00 | 14.58 | 9-13,17,21,25-28,32-41,45-54,58-64,68-75,79-92,96-109,113-120
140
- ../core/src/helpers/Str.ts | 0.00 | 18.56 | 5-10,14-17,27,31,35-41,45-51,55-61,65-66,70-71,75-77,81-89,93-95,99-105,109-117,121-124,128-134
141
- ../core/src/helpers/data.ts | 0.00 | 2.17 | 13-30,34-47,51-64,68-88,96-113,121-134,142-177
142
- ../core/src/helpers/errors.ts | 0.00 | 7.69 | 26-43,51-53,61-63
143
- ../core/src/helpers/response.ts | 0.00 | 12.50 | 29,37-44,52-56,64-70
144
- ../core/src/http/CookieJar.ts | 0.00 | 12.33 | 33-46,53-74,81,88,95-117,124-126
145
- ../core/src/http/middleware/BodySizeLimit.ts | 0.00 | 2.70 | 20-55
146
- ../core/src/http/middleware/Cors.ts | 0.00 | 1.64 | 23-35,43-89
147
- ../core/src/http/middleware/Csrf.ts | 0.00 | 5.05 | 19-24,28-34,38,42-67,75-91,99-135
148
- ../core/src/http/middleware/HeaderTokenGate.ts | 0.00 | 4.55 | 25-35,45-54
149
- ../core/src/http/middleware/SecurityHeaders.ts | 0.00 | 1.67 | 28,32-35,39-46,54-99
150
- ../core/src/http/middleware/ThrottleRequests.ts | 0.00 | 8.51 | 31-73
151
- ../core/src/index.ts | 0.00 | 96.97 |
152
- ../core/src/runtime.ts | 21.05 | 11.87 | 118-131,138-145,149-166,175,188-190,193-216,221-225,230-325,330-420,425-448,467-470,481-518,526-533
153
- ../core/src/security/Encrypter.ts | 0.00 | 13.70 | 21-35,42-59,66-82,86-88,92-97,102-103,110-111
154
- ../core/src/security/Hasher.ts | 0.00 | 9.09 | 25-43
155
- ../core/src/testing/HttpTester.ts | 0.00 | 4.27 | 11-121
156
- ../core/src/testing/TestResponse.ts | 0.00 | 10.92 | 16-17,24,31,38,45,52,59-124,131-132,139-169
157
- ../core/src/testing/index.ts | 100.00 | 100.00 |
158
- ../core/src/types/events.ts | 0.00 | 14.29 | 91-93,101-104,111-125,132-139
159
- ../enterprise/src/Application/Command.ts | 100.00 | 100.00 |
160
- ../enterprise/src/Application/Query.ts | 100.00 | 100.00 |
161
- ../enterprise/src/Application/UseCase.ts | 100.00 | 100.00 |
162
- ../enterprise/src/Domain/AggregateRoot.ts | 50.00 | 55.56 | 1-8
163
- ../enterprise/src/Domain/DomainEvent.ts | 50.00 | 55.56 | 16-19
164
- ../enterprise/src/Domain/Entity.ts | 100.00 | 100.00 |
165
- ../enterprise/src/Domain/Repository.ts | 100.00 | 100.00 |
166
- ../enterprise/src/Domain/ValueObject.ts | 100.00 | 100.00 |
167
- ../enterprise/src/index.ts | 100.00 | 100.00 |
168
- src/Application/MissionControl.ts | 100.00 | 100.00 |
169
- src/Application/PayloadInjector.ts | 100.00 | 100.00 |
170
- src/Application/PoolManager.ts | 100.00 | 100.00 |
171
- src/Application/RefurbishUnit.ts | 100.00 | 100.00 |
172
- src/Domain/Events.ts | 100.00 | 100.00 |
173
- src/Domain/Mission.ts | 83.33 | 100.00 |
174
- src/Domain/Rocket.ts | 100.00 | 100.00 |
175
- src/Domain/RocketStatus.ts | 100.00 | 100.00 |
176
- src/Infrastructure/Docker/DockerAdapter.ts | 94.44 | 100.00 |
177
- src/Infrastructure/Persistence/InMemoryRocketRepository.ts | 90.91 | 100.00 |
178
- ------------------------------------------------------------|---------|---------|-------------------
179
-
180
- 34 pass
181
- 0 fail
182
- 99 expect() calls
183
- Ran 34 tests across 13 files. [4.34s]
@@ -1,100 +0,0 @@
1
-
2
- $ bun test
3
- bun test v1.3.4 (5eb2145b)
4
- 
5
- tests/mission.test.ts:
6
- ✓ Mission > exposes mission properties [0.45ms]
7
- 
8
- tests/Telemetry.test.ts:
9
- [MissionControl] 準備發射任務: pr-1
10
- [MissionControl] 任務 pr-1 映射端口: 3000
11
- ✓ MissionControl Telemetry > 發射時應該能正確啟動日誌串流與效能監控 [1.84ms]
12
- 
13
- tests/mission-control.test.ts:
14
- [MissionControl] 準備發射任務: mission-telemetry
15
- [MissionControl] 任務 mission-telemetry 映射端口: 3000
16
- [MissionControl] 任務 mission-telemetry TTL 已到期,執行自動回收...
17
- ✓ MissionControl timers > emits stats and schedules recycle [0.92ms]
18
- 
19
- tests/pool-manager.test.ts:
20
- [LaunchPad] 正在熱機,準備發射 2 架新火箭...
21
- ✓ PoolManager > warms up the pool with base containers [0.62ms]
22
- [LaunchPad] 正在熱機,準備發射 1 架新火箭...
23
- [LaunchPad] 資源吃緊,正在緊急呼叫後援火箭...
24
- ✓ PoolManager > assigns missions to idle rockets or creates new ones [1.08ms]
25
- [LaunchPad] 正在熱機,準備發射 1 架新火箭...
26
- ✓ PoolManager > recycles rockets through refurbish flow [0.34ms]
27
- 
28
- tests/enterprise-coverage.test.ts:
29
- ✓ Launchpad enterprise coverage > covers core enterprise primitives [0.20ms]
30
- 
31
- tests/repository.test.ts:
32
- ✓ InMemoryRocketRepository > stores and retrieves rockets [0.11ms]
33
- ✓ InMemoryRocketRepository > finds idle rockets [0.10ms]
34
- 
35
- tests/Rocket.test.ts:
36
- ✓ Rocket > transitions through mission lifecycle and emits events [0.25ms]
37
- ✓ Rocket > guards invalid transitions [0.12ms]
38
- ✓ Rocket > assigns domain and serializes/deserializes [0.04ms]
39
- ✓ Rocket > rejects assigning mission when not idle [0.12ms]
40
- 
41
- tests/Refurbishment.test.ts:
42
- [RefurbishUnit] 正在翻新火箭: r1 (容器: c1)
43
- [RefurbishUnit] 火箭 r1 翻新完成,已進入 IDLE 狀態。
44
- ✓ RefurbishUnit (Rocket Recovery) > 應該能執行深度清理並將火箭重置為 IDLE [0.66ms]
45
- [RefurbishUnit] 正在翻新火箭: r2 (容器: c2)
46
- [RefurbishUnit] 清理失敗: Disk Full
47
- ✓ RefurbishUnit (Rocket Recovery) > 如果清理失敗應該將火箭除役 [0.18ms]
48
- 
49
- tests/payload-injector.test.ts:
50
- ✓ PayloadInjector > throws when rocket has no mission [0.51ms]
51
- [PayloadInjector] 正在拉取代碼: https://example.com/repo.git (main)
52
- [PayloadInjector] 正在注入載荷至容器: container-10
53
- [PayloadInjector] 正在安裝依賴...
54
- [PayloadInjector] 點火!
55
- ✓ PayloadInjector > deploys payload and ignites rocket [0.28ms]
56
- [PayloadInjector] 正在拉取代碼: https://example.com/repo.git (main)
57
- [PayloadInjector] 正在注入載荷至容器: container-11
58
- [PayloadInjector] 正在安裝依賴...
59
- ✓ PayloadInjector > throws when install fails [0.14ms]
60
- [PayloadInjector] 正在拉取代碼: https://example.com/repo.git (main)
61
- [PayloadInjector] 正在注入載荷至容器: container-12
62
- [PayloadInjector] 正在安裝依賴...
63
- [PayloadInjector] 點火!
64
- ✓ PayloadInjector > logs when run command fails but still ignites [1.62ms]
65
- 
66
- tests/docker-adapter.test.ts:
67
- ✓ DockerAdapter > creates base container when stdout has container id [9.55ms]
68
- ✓ DockerAdapter > returns container id even when exit code is zero but id is invalid [0.19ms]
69
- ✓ DockerAdapter > throws when container creation fails [0.09ms]
70
- ✓ DockerAdapter > getExposedPort parses the first line [1.81ms]
71
- ✓ DockerAdapter > getExposedPort throws on empty output [3.29ms]
72
- ✓ DockerAdapter > getExposedPort throws on invalid output [1.47ms]
73
- ✓ DockerAdapter > copyFiles throws on non-zero exit code [0.33ms]
74
- ✓ DockerAdapter > removeContainerByLabel removes containers when ids exist [0.22ms]
75
- ✓ DockerAdapter > executeCommand returns stdout and stderr [0.12ms]
76
- ✓ DockerAdapter > removeContainer executes docker rm [0.09ms]
77
- ✓ DockerAdapter > getStats parses cpu and memory output [0.13ms]
78
- ✓ DockerAdapter > streamLogs forwards stdout and stderr [4.70ms]
79
- 
80
- tests/Integration.test.ts:
81
- [LaunchPad] 正在熱機,準備發射 1 架新火箭...
82
- [Test] 容器內 Bun 版本: 1.0.36
83
- ✓ LaunchPad 集成測試 (真實 Docker) > 應該能成功熱機並在容器內執行指令 [1171.83ms]
84
- 
85
- tests/Deployment.test.ts:
86
- [LaunchPad] 資源吃緊,正在緊急呼叫後援火箭...
87
- [PayloadInjector] 正在拉取代碼: http://git (dev)
88
- [PayloadInjector] 正在注入載荷至容器: cid-1
89
- [PayloadInjector] 正在安裝依賴...
90
- [PayloadInjector] 點火!
91
- ✓ Payload Injection Flow > 應該能從指派任務到成功點火 [0.29ms]
92
- 
93
- tests/PoolManager.test.ts:
94
- [LaunchPad] 正在熱機,準備發射 2 架新火箭...
95
- ✓ PoolManager (Application Service) > 應該能正確熱機並指派任務 [0.24ms]
96
-
97
-  34 pass
98
-  0 fail
99
- 99 expect() calls
100
- Ran 34 tests across 13 files. [1499.00ms]
@@ -1 +0,0 @@
1
- $ bun tsc -p tsconfig.json --noEmit --skipLibCheck