• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / edge-runtime / 17781894351

16 Sep 2025 11:34PM UTC coverage: 51.948% (+0.02%) from 51.926%
17781894351

Pull #609

github

web-flow
Merge 0fe880f3b into 159fc1db5
Pull Request #609: fix: static files weren't extracted when running the unbundle

25 of 32 new or added lines in 3 files covered. (78.13%)

1 existing line in 1 file now uncovered.

18520 of 35651 relevant lines covered (51.95%)

5530.07 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/cli/src/flags.rs
1
use std::net::SocketAddr;
2
use std::path::PathBuf;
3

4
use clap::arg;
5
use clap::builder::BoolishValueParser;
6
use clap::builder::FalseyValueParser;
7
use clap::builder::TypedValueParser;
8
use clap::crate_version;
9
use clap::value_parser;
10
use clap::ArgAction;
11
use clap::ArgGroup;
12
use clap::Command;
13
use clap::ValueEnum;
14
use deno::deno_telemetry;
15
use deno_facade::Checksum;
16

17
#[derive(ValueEnum, Default, Clone, Copy)]
18
#[repr(u8)]
19
pub(super) enum EszipV2ChecksumKind {
20
  #[default]
21
  NoChecksum = 0,
22
  Sha256 = 1,
23
  XxHash3 = 2,
24
}
25

26
impl From<EszipV2ChecksumKind> for Option<Checksum> {
27
  fn from(value: EszipV2ChecksumKind) -> Self {
×
28
    Checksum::from_u8(value as u8)
×
29
  }
×
30
}
31

32
#[derive(ValueEnum, Clone, Copy)]
33
pub(super) enum OtelKind {
34
  Main,
35
  Event,
36
}
37

38
#[derive(ValueEnum, Default, Clone, Copy)]
39
pub(super) enum OtelConsoleConfig {
40
  #[default]
41
  Ignore,
42
  Capture,
43
  Replace,
44
}
45

46
impl From<OtelConsoleConfig> for deno_telemetry::OtelConsoleConfig {
47
  fn from(value: OtelConsoleConfig) -> Self {
×
48
    match value {
×
49
      OtelConsoleConfig::Ignore => Self::Ignore,
×
50
      OtelConsoleConfig::Capture => Self::Capture,
×
51
      OtelConsoleConfig::Replace => Self::Replace,
×
52
    }
53
  }
×
54
}
55

56
pub(super) fn get_cli() -> Command {
×
57
  Command::new(env!("CARGO_BIN_NAME"))
×
58
    .about(env!("CARGO_PKG_DESCRIPTION"))
×
59
    .version(format!(
×
60
      "{}\ndeno {} ({}, {})",
×
61
      crate_version!(),
×
62
      deno::version(),
×
63
      env!("PROFILE"),
×
64
      env!("TARGET")
×
65
    ))
×
66
    .arg_required_else_help(true)
×
67
    .arg(
×
68
      arg!(-v --verbose "Use verbose output")
×
69
        .conflicts_with("quiet")
×
70
        .global(true)
×
71
        .action(ArgAction::SetTrue),
×
72
    )
×
73
    .arg(
×
74
      arg!(-q --quiet "Do not print any log messages")
×
75
        .conflicts_with("verbose")
×
76
        .global(true)
×
77
        .action(ArgAction::SetTrue),
×
78
    )
×
79
    .arg(
×
80
      arg!(--"log-source")
×
81
        .help("Include source file and line in log messages")
×
82
        .global(true)
×
83
        .action(ArgAction::SetTrue),
×
84
    )
×
85
    .subcommand(get_start_command())
×
86
    .subcommand(get_bundle_command())
×
87
    .subcommand(get_unbundle_command())
×
88
}
×
89

90
fn get_start_command() -> Command {
×
91
  Command::new("start")
×
92
    .about("Start the server")
×
93
    .arg(
×
94
      arg!(-i --ip <HOST>)
×
95
        .help("Host IP address to listen on")
×
96
        .default_value("0.0.0.0"),
×
97
    )
×
98
    .arg(
×
99
      arg!(-p --port <PORT>)
×
100
        .help("Port to listen on")
×
101
        .env("EDGE_RUNTIME_PORT")
×
102
        .default_value("9000")
×
103
        .value_parser(value_parser!(u16)),
×
104
    )
×
105
    .arg(
×
106
      arg!(--tls[PORT])
×
107
        .env("EDGE_RUNTIME_TLS")
×
108
        .num_args(0..=1)
×
109
        .default_missing_value("443")
×
110
        .value_parser(value_parser!(u16))
×
111
        .requires("key")
×
112
        .requires("cert"),
×
113
    )
×
114
    .arg(
×
115
      arg!(--key <Path>)
×
116
        .help("Path to PEM-encoded key to be used to TLS")
×
117
        .env("EDGE_RUNTIME_TLS_KEY_PATH")
×
118
        .value_parser(value_parser!(PathBuf)),
×
119
    )
×
120
    .arg(
×
121
      arg!(--cert <Path>)
×
122
        .help("Path to PEM-encoded X.509 certificate to be used to TLS")
×
123
        .env("EDGE_RUNTIME_TLS_CERT_PATH")
×
124
        .value_parser(value_parser!(PathBuf)),
×
125
    )
×
126
    .arg(
×
127
      arg!(--"main-service" <DIR>)
×
128
        .help("Path to main service directory or eszip")
×
129
        .default_value("examples/main"),
×
130
    )
×
131
    .arg(
×
132
      arg!(--"disable-module-cache")
×
133
        .help("Disable using module cache")
×
134
        .default_value("false")
×
135
        .value_parser(FalseyValueParser::new()),
×
136
    )
×
137
    .arg(arg!(--"event-worker" <Path>).help("Path to event worker directory"))
×
138
    .arg(
×
139
      arg!(--"main-entrypoint" <Path>)
×
140
        .help("Path to entrypoint in main service (only for eszips)"),
×
141
    )
×
142
    .arg(
×
143
      arg!(--"events-entrypoint" <Path>)
×
144
        .help("Path to entrypoint in events worker (only for eszips)"),
×
145
    )
×
146
    .arg(
×
147
      arg!(--"policy" <POLICY>)
×
148
        .help("Policy to enforce in the worker pool")
×
149
        .default_value("per_worker")
×
150
        .value_parser(["per_worker", "per_request", "oneshot"]),
×
151
    )
×
152
    .arg(
×
153
      arg!(--"graceful-exit-timeout"[SECONDS])
×
154
        .help(concat!(
×
155
          "Maximum time in seconds that can wait for workers before ",
×
156
          "terminating forcibly. If providing zero value, the runtime will ",
×
157
          "not try a graceful exit."
×
158
        ))
×
159
        // NOTE(Nyannyacha): Default timeout value follows the
×
160
        // value[1] defined in moby.
×
161
        //
×
162
        // [1]: https://github.com/moby/moby/blob/master/daemon/config/config.go#L45-L47
×
163
        .default_value("15")
×
164
        .value_parser(value_parser!(u64).range(..u64::MAX)),
×
165
    )
×
166
    .arg(
×
167
      arg!(--"event-worker-exit-timeout"[SECONDS])
×
168
        .help(concat!(
×
169
          "Maximum time in seconds that can wait for the event worker before ",
×
170
          "terminating forcibly. (graceful exit)"
×
171
        ))
×
172
        .default_value("10")
×
173
        .value_parser(value_parser!(u64).range(..u64::MAX)),
×
174
    )
×
175
    .arg(
×
176
      arg!(
×
177
        --"experimental-graceful-exit-keepalive-deadline-ratio"
×
178
        <PERCENTAGE>
179
      )
180
      .help(concat!(
×
181
        "(Experimental) Maximum period of time that incoming requests ",
×
182
        "can be processed over a pre-established keep-alive HTTP connection. ",
×
183
        "This is specified as a percentage of the `--graceful-exit-timeout` ",
×
184
        "value. The percentage cannot be greater than 95."
×
185
      ))
×
186
      .value_parser(value_parser!(u64).range(..=95)),
×
187
    )
×
188
    .arg(
×
189
      arg!(--"max-parallelism" <COUNT>)
×
190
        .help(concat!(
×
191
          "Maximum count of workers that can exist in the worker pool ",
×
192
          "simultaneously"
×
193
        ))
×
194
        .value_parser(
×
195
          // NOTE: Acceptable bounds were chosen arbitrarily.
×
196
          value_parser!(u32)
×
197
            .range(1..9999)
×
198
            .map(|it| -> usize { it as usize }),
×
199
        ),
×
200
    )
×
201
    .arg(
×
202
      arg!(--"request-wait-timeout" <MILLISECONDS>)
×
203
        .help(concat!(
×
204
          "Maximum time in milliseconds that can wait to establish a ",
×
205
          "connection with a worker"
×
206
        ))
×
207
        .default_value("10000")
×
208
        .value_parser(value_parser!(u64)),
×
209
    )
×
210
    .arg(
×
211
      arg!(--"request-idle-timeout" <MILLISECONDS>)
×
212
        .help(concat!(
×
213
          "Maximum time in milliseconds that can be waited from when a ",
×
214
          "worker takes over the request (disabled by default)"
×
215
        ))
×
216
        .value_parser(value_parser!(u64)),
×
217
    )
×
218
    .arg(
×
219
      arg!(--"request-read-timeout" <MILLISECONDS>)
×
220
        .help(concat!(
×
221
          "Maximum time in milliseconds that can be waited from when the ",
×
222
          "connection is accepted until the request body is fully read ",
×
223
          "(disabled by default)"
×
224
        ))
×
225
        .value_parser(value_parser!(u64)),
×
226
    )
×
227
    .arg(
×
228
      arg!(--"inspect"[HOST_AND_PORT])
×
229
        .help("Activate inspector on host:port")
×
230
        .num_args(0..=1)
×
231
        .value_parser(value_parser!(SocketAddr))
×
232
        .require_equals(true)
×
233
        .default_missing_value("127.0.0.1:9229"),
×
234
    )
×
235
    .arg(
×
236
      arg!(--"inspect-brk"[HOST_AND_PORT])
×
237
        .help(concat!(
×
238
          "Activate inspector on host:port, wait for debugger to connect ",
×
239
          "and break at the start of user script"
×
240
        ))
×
241
        .num_args(0..=1)
×
242
        .value_parser(value_parser!(SocketAddr))
×
243
        .require_equals(true)
×
244
        .default_missing_value("127.0.0.1:9229"),
×
245
    )
×
246
    .arg(
×
247
      arg!(--"inspect-wait"[HOST_AND_PORT])
×
248
        .help(concat!(
×
249
          "Activate inspector on host:port and wait for debugger to ",
×
250
          "connect before running user code"
×
251
        ))
×
252
        .num_args(0..=1)
×
253
        .value_parser(value_parser!(SocketAddr))
×
254
        .require_equals(true)
×
255
        .default_missing_value("127.0.0.1:9229"),
×
256
    )
×
257
    .group(ArgGroup::new("inspector").args([
×
258
      "inspect",
×
259
      "inspect-brk",
×
260
      "inspect-wait",
×
261
    ]))
×
262
    .arg(
×
263
      arg!(--"inspect-main")
×
264
        .help("Allow creating inspector for main worker")
×
265
        .requires("inspector")
×
266
        .action(ArgAction::SetTrue),
×
267
    )
×
268
    .arg(
×
269
      arg!(--"static" <Path>)
×
270
        .help("Glob pattern for static files to be included")
×
271
        .action(ArgAction::Append),
×
272
    )
×
273
    .arg(
×
274
      arg!(--"tcp-nodelay"[BOOL])
×
275
        .help("Disables Nagle's algorithm")
×
276
        .num_args(0..=1)
×
277
        .value_parser(BoolishValueParser::new())
×
278
        .require_equals(true)
×
279
        .default_value("true")
×
280
        .default_missing_value("true"),
×
281
    )
×
282
    .arg(
×
283
      arg!(--"request-buffer-size" <BYTES>)
×
284
        .help(concat!(
×
285
          "The buffer size of the stream that is used to forward a request ",
×
286
          "to the worker"
×
287
        ))
×
288
        .value_parser(value_parser!(u64))
×
289
        .default_value("16384"),
×
290
    )
×
291
    .arg(
×
292
      arg!(--"dispatch-beforeunload-wall-clock-ratio" <PERCENTAGE>)
×
293
        .value_parser(value_parser!(u8).range(..=99))
×
294
        .default_value("90"),
×
295
    )
×
296
    .arg(
×
297
      arg!(--"dispatch-beforeunload-cpu-ratio" <PERCENTAGE>)
×
298
        .value_parser(value_parser!(u8).range(..=99))
×
299
        .default_value("90"),
×
300
    )
×
301
    .arg(
×
302
      arg!(--"dispatch-beforeunload-memory-ratio" <PERCENTAGE>)
×
303
        .value_parser(value_parser!(u8).range(..=99))
×
304
        .default_value("90"),
×
305
    )
×
306
    .arg(
×
307
      arg!(--"enable-otel")
×
308
        .help("Enable OpenTelemetry in the main and event workers")
×
309
        .value_delimiter(',')
×
310
        .value_parser(value_parser!(OtelKind))
×
311
        .num_args(0..=1)
×
312
        .default_missing_value("main,event")
×
313
        .action(ArgAction::Append),
×
314
    )
×
315
    .arg(
×
316
      arg!(--"otel-console" <MODE>)
×
317
        // .env("OTEL_DENO_CONSOLE")
318
        .help("Configure console auto instrumentation for OpenTelemetry Logs")
×
319
        .value_parser(value_parser!(OtelConsoleConfig)),
×
320
    )
×
321
}
×
322

323
fn get_bundle_command() -> Command {
×
324
  Command::new("bundle")
×
325
    .about(concat!(
×
326
      "Creates an 'eszip' file that can be executed by the EdgeRuntime. ",
×
327
      "Such file contains all the modules in contained in a single binary."
×
328
    ))
×
329
    .arg(
×
330
      arg!(--"output" <DIR>)
×
331
        .help("Path to output eszip file")
×
332
        .default_value("bin.eszip"),
×
333
    )
×
334
    .arg(
×
335
      arg!(--"entrypoint" <Path>)
×
336
        .help("Path to entrypoint to bundle as an eszip")
×
337
        .required(true),
×
338
    )
×
339
    .arg(
×
340
      arg!(--"static" <Path>)
×
341
        .help("Glob pattern for static files to be included")
×
342
        .action(ArgAction::Append),
×
343
    )
×
344
    .arg(
×
345
      arg!(--"import-map" <Path>).help("(DEPRECATED) Path to import map file"),
×
346
    )
×
347
    .arg(
×
348
      arg!(--"decorator" <TYPE>)
×
349
        .help(concat!(
×
350
          "(DEPRECATED) Type of decorator to use on the main worker and event worker. ",
×
351
          "If not specified, the decorator feature is disabled."
×
352
        ))
×
353
        .value_parser(["tc39", "typescript", "typescript_with_metadata"]),
×
354
    )
×
355
    .arg(
×
356
      arg!(--"checksum" <KIND>)
×
357
        .env("EDGE_RUNTIME_BUNDLE_CHECKSUM")
×
358
        .help("Hash function to use when checksum the contents")
×
359
        .value_parser(value_parser!(EszipV2ChecksumKind)),
×
360
    )
×
361
    .arg(
×
362
      arg!(--"disable-module-cache")
×
363
        .help("Disable using module cache")
×
364
        .default_value("false")
×
365
        .value_parser(FalseyValueParser::new()),
×
366
    )
×
367
    .arg(
×
368
      arg!(--"timeout" <SECONDS>)
×
369
        .help("Maximum time in seconds that can be waited for the bundle to complete.")
×
370
        .value_parser(value_parser!(u64).range(..u64::MAX))
×
371
    )
×
372
}
×
373

374
fn get_unbundle_command() -> Command {
×
375
  Command::new("unbundle")
×
376
    .about("Unbundles an .eszip file into the specified directory")
×
377
    .arg(
×
378
      arg!(--"output" <DIR>)
×
379
        .help("Path to extract the ESZIP content")
×
380
        .default_value("./"),
×
381
    )
×
382
    .arg(
×
NEW
383
      arg!(--"eszip" <Path>)
×
384
        .help("Path of eszip to extract")
×
385
        .required(true),
×
386
    )
×
387
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc