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

supabase / storage / 24654320181

20 Apr 2026 07:36AM UTC coverage: 69.897% (+1.8%) from 68.127%
24654320181

push

github

web-flow
feat: add admin pprof and its client (#1037)

3363 of 5337 branches covered (63.01%)

Branch coverage included in aggregate %.

570 of 640 new or added lines in 9 files covered. (89.06%)

7060 of 9575 relevant lines covered (73.73%)

379.42 hits per line

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

61.9
/src/scripts/pprof-client.ts
1
import { fetchPprofStream } from '@internal/monitoring/pprof/client-http'
2
import { writeMultipartPprofToFile } from '@internal/monitoring/pprof/download'
3
import { generateFlameArtifacts, resolveFlameMdFormat } from '@internal/monitoring/pprof/flame'
4
import type { PprofRequestTargetType } from '@internal/monitoring/pprof/types'
5
import path from 'path'
6

7
const ADMIN_URL = process.env.ADMIN_URL
1✔
8
const ADMIN_API_KEY = process.env.ADMIN_API_KEY
1✔
9
const PPROF_SECONDS = process.env.PPROF_SECONDS
1✔
10
const PPROF_GENERATE_FLAME = process.env.PPROF_GENERATE_FLAME
1✔
11
const PPROF_FLAME_MD_FORMAT = process.env.PPROF_FLAME_MD_FORMAT
1✔
12
const PPROF_WORKER_ID = process.env.PPROF_WORKER_ID
1✔
13
const PPROF_SOURCE_MAPS = process.env.PPROF_SOURCE_MAPS
1✔
14
const PPROF_NODE_MODULES_SOURCE_MAPS = process.env.PPROF_NODE_MODULES_SOURCE_MAPS
1✔
15
const PPROF_OUTPUT = process.env.PPROF_OUTPUT
1✔
16

17
export function parseBooleanEnv(value: string | undefined) {
18
  if (value === undefined) {
5✔
19
    return undefined
1✔
20
  }
21

22
  const normalized = value.trim().toLowerCase()
4✔
23
  if (['1', 'true', 'yes', 'on'].includes(normalized)) {
4✔
24
    return true
1✔
25
  }
26

27
  if (['0', 'false', 'no', 'off'].includes(normalized)) {
3✔
28
    return false
2✔
29
  }
30

31
  throw new Error(`Invalid boolean value: ${value}`)
1✔
32
}
33

34
export function parseBooleanEnvWithDefault(value: string | undefined, defaultValue: boolean) {
35
  if (value === undefined) {
3✔
36
    return defaultValue
2✔
37
  }
38

39
  return parseBooleanEnv(value) === true
1✔
40
}
41

42
function parseUnsignedInteger(value: string, errorMessage: string) {
43
  const normalized = value.trim()
12✔
44

45
  if (!/^\d+$/.test(normalized)) {
12✔
46
    throw new Error(errorMessage)
5✔
47
  }
48

49
  const parsed = Number.parseInt(normalized, 10)
7✔
50
  if (!Number.isSafeInteger(parsed)) {
7!
NEW
51
    throw new Error(errorMessage)
×
52
  }
53

54
  return parsed
7✔
55
}
56

57
export function parsePositiveIntegerEnv(
58
  value: string | undefined,
59
  envName: string,
60
  defaultValue: number
61
) {
62
  if (value === undefined) {
4✔
63
    return defaultValue
1✔
64
  }
65

66
  const parsed = parseUnsignedInteger(value, `${envName} must be a positive integer`)
3✔
67
  if (parsed <= 0) {
3✔
68
    throw new Error(`${envName} must be a positive integer`)
1✔
69
  }
70

71
  return parsed
1✔
72
}
73

74
export function parseNonNegativeIntegerEnv(value: string | undefined, envName: string) {
75
  if (value === undefined) {
5✔
76
    return undefined
1✔
77
  }
78

79
  return parseUnsignedInteger(value, `${envName} must be a non-negative integer`)
4✔
80
}
81

82
export function parsePprofTarget(
83
  value: string | undefined,
84
  defaultSeconds: number
85
): { seconds: number; type: PprofRequestTargetType } {
86
  if (!value) {
10✔
87
    throw new Error(
1✔
88
      'Usage: tsx src/scripts/pprof-client.ts <profile[:seconds]|heap[:seconds]> [output-file]'
89
    )
90
  }
91

92
  const [type, secondsValue, ...rest] = value.split(':')
9✔
93

94
  if (rest.length > 0 || (type !== 'profile' && type !== 'heap')) {
9✔
95
    throw new Error(
2✔
96
      'Usage: tsx src/scripts/pprof-client.ts <profile[:seconds]|heap[:seconds]> [output-file]'
97
    )
98
  }
99

100
  if (secondsValue === undefined || secondsValue === '') {
7✔
101
    return {
2✔
102
      seconds: defaultSeconds,
103
      type,
104
    }
105
  }
106

107
  const seconds = parseUnsignedInteger(secondsValue, 'seconds must be a positive integer')
5✔
108
  if (seconds <= 0) {
5✔
109
    throw new Error('seconds must be a positive integer')
1✔
110
  }
111

112
  return {
2✔
113
    seconds,
114
    type,
115
  }
116
}
117

118
function fail(message: string) {
NEW
119
  process.exitCode = 1
×
NEW
120
  console.error(message)
×
121
}
122

123
async function main() {
NEW
124
  const target = process.argv[2]
×
NEW
125
  const outputArg = process.argv[3]
×
126
  let parsedTarget: ReturnType<typeof parsePprofTarget>
127
  let pprofSeconds: number
128
  let sourceMaps: boolean | undefined
129
  let workerId: number | undefined
130
  let generateFlame: boolean
131

NEW
132
  if (!ADMIN_URL) {
×
NEW
133
    fail('Please provide ADMIN_URL')
×
NEW
134
    return
×
135
  }
136

NEW
137
  if (!ADMIN_API_KEY) {
×
NEW
138
    fail('Please provide ADMIN_API_KEY')
×
NEW
139
    return
×
140
  }
141

NEW
142
  try {
×
NEW
143
    pprofSeconds = parsePositiveIntegerEnv(PPROF_SECONDS, 'PPROF_SECONDS', 60)
×
NEW
144
    parsedTarget = parsePprofTarget(target, pprofSeconds)
×
NEW
145
    sourceMaps = parseBooleanEnv(PPROF_SOURCE_MAPS)
×
NEW
146
    workerId = parseNonNegativeIntegerEnv(PPROF_WORKER_ID, 'PPROF_WORKER_ID')
×
NEW
147
    generateFlame = parseBooleanEnvWithDefault(PPROF_GENERATE_FLAME, true)
×
148
  } catch (error) {
NEW
149
    process.exitCode = 1
×
NEW
150
    console.error(error instanceof Error ? error.message : error)
×
NEW
151
    return
×
152
  }
153

NEW
154
  const flameMdFormat = resolveFlameMdFormat(PPROF_FLAME_MD_FORMAT)
×
155

NEW
156
  const response = await fetchPprofStream({
×
157
    adminUrl: ADMIN_URL,
158
    apiKey: ADMIN_API_KEY,
159
    nodeModulesSourceMaps: PPROF_NODE_MODULES_SOURCE_MAPS || undefined,
×
160
    seconds: parsedTarget.seconds,
161
    sourceMaps,
162
    type: parsedTarget.type,
163
    workerId,
164
  })
165

NEW
166
  const outputPath = outputArg
×
167
    ? path.resolve(outputArg)
168
    : PPROF_OUTPUT
×
169
      ? path.resolve(PPROF_OUTPUT)
170
      : undefined
171

NEW
172
  const { outputPath: capturedProfilePath } = await writeMultipartPprofToFile(
×
173
    response.stream,
174
    response.contentType,
175
    {
176
      outputPath,
177
    }
178
  )
179

NEW
180
  if (!generateFlame) {
×
NEW
181
    return
×
182
  }
183

NEW
184
  await generateFlameArtifacts(capturedProfilePath, {
×
185
    env: {
186
      ...process.env,
187
      FLAME_SOURCEMAPS_DIRS: process.env.FLAME_SOURCEMAPS_DIRS || 'dist',
×
188
    },
189
    mdFormat: flameMdFormat,
190
  })
191
}
192

193
// Keep the CLI side effect behind a CommonJS-friendly main-module gate so tests can import
194
// the helpers without starting a capture.
195
if (require.main === module) {
1!
NEW
196
  main().catch((error) => {
×
NEW
197
    process.exitCode = 1
×
NEW
198
    console.error(error)
×
199
  })
200
}
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