@foss.global/codefeed 1.9.0 → 1.10.0

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.
@@ -0,0 +1,648 @@
1
+ import * as plugins from './plugins.js';
2
+ export class GitManagerPublicReadClient {
3
+ constructor(optionsArg) {
4
+ if (!optionsArg.allowAllRepositories && !optionsArg.isRepositoryPublic) {
5
+ throw new Error('GitManagerPublicReadClient requires allowAllRepositories or an authoritative isRepositoryPublic predicate');
6
+ }
7
+ this.gitManager = optionsArg.gitManager;
8
+ this.publicBaseUrl = this.normalizeBaseUrl(optionsArg.publicBaseUrl ?? 'https://foss.global', ['http:', 'https:']);
9
+ this.smartHttpBaseUrl = this.normalizeBaseUrl(optionsArg.smartHttpBaseUrl ?? this.publicBaseUrl, ['http:', 'https:']);
10
+ this.sshBaseUrl = this.normalizeBaseUrl(optionsArg.sshBaseUrl ?? 'ssh://git@code.foss.global:29419', ['ssh:']);
11
+ this.allowAllRepositories = optionsArg.allowAllRepositories ?? false;
12
+ this.isRepositoryPublic = optionsArg.isRepositoryPublic;
13
+ this.organizationMetadata = optionsArg.organizationMetadata;
14
+ this.repositoryMetadata = optionsArg.repositoryMetadata;
15
+ this.newsProvider = optionsArg.newsProvider;
16
+ this.maxCommits = this.validateLimit(optionsArg.maxCommits ?? 40, 'maxCommits', 1, 1000);
17
+ this.maxReleases = this.validateLimit(optionsArg.maxReleases ?? 50, 'maxReleases', 1, 1000);
18
+ this.maxLanguageFiles = this.validateLimit(optionsArg.maxLanguageFiles ?? 1000, 'maxLanguageFiles', 1, 10_000);
19
+ this.maxConcurrency = this.validateLimit(optionsArg.maxConcurrency ?? 8, 'maxConcurrency', 1, 32);
20
+ }
21
+ async getOverview(queryArg = '') {
22
+ const query = queryArg.trim().toLowerCase();
23
+ if (query.length > 160) {
24
+ throw new Error('Query exceeds maximum length of 160');
25
+ }
26
+ const repositoryInfos = await this.listVisibleRepositories();
27
+ const filteredInfos = query
28
+ ? repositoryInfos.filter((repository) => `${repository.org}/${repository.repo}`.toLowerCase().includes(query))
29
+ : repositoryInfos;
30
+ const repos = await this.mapWithConcurrency(filteredInfos.slice(0, query ? 100 : 36), (repository) => this.mapRepository(repository));
31
+ const orgs = await this.mapOrganizations(repositoryInfos);
32
+ const commitFeed = await this.getCommitFeed(filteredInfos.slice(0, 12), 3);
33
+ const activity = commitFeed.slice(0, 24).map((commit) => this.mapActivity(commit));
34
+ const news = query ? [] : ((await this.newsProvider?.(6)) ?? []);
35
+ return {
36
+ orgs: query
37
+ ? orgs.filter((org) => org.name.toLowerCase().includes(query))
38
+ : orgs,
39
+ repos,
40
+ activity,
41
+ commitFeed,
42
+ news,
43
+ stats: this.getStats(orgs, repos),
44
+ };
45
+ }
46
+ async getOrg(orgArg) {
47
+ const org = this.validateSlug(orgArg, 'organization', 120);
48
+ const repositoryInfos = (await this.listVisibleRepositories()).filter((repository) => repository.org === org);
49
+ if (repositoryInfos.length === 0) {
50
+ return {
51
+ org: null,
52
+ repos: [],
53
+ members: [],
54
+ activity: [],
55
+ commitFeed: [],
56
+ stats: {
57
+ orgCount: 0,
58
+ repoCount: 0,
59
+ releaseCount: 0,
60
+ openIssueCount: 0,
61
+ },
62
+ };
63
+ }
64
+ const repos = await this.mapWithConcurrency(repositoryInfos, (repository) => this.mapRepository(repository));
65
+ const [mappedOrg] = await this.mapOrganizations(repositoryInfos, [org]);
66
+ const commitFeed = await this.getCommitFeed(repositoryInfos.slice(0, 12), 3);
67
+ const activity = commitFeed.slice(0, 24).map((commit) => this.mapActivity(commit));
68
+ return {
69
+ org: mappedOrg ?? null,
70
+ repos,
71
+ members: [],
72
+ activity,
73
+ commitFeed,
74
+ stats: this.getStats(mappedOrg ? [mappedOrg] : [], repos),
75
+ };
76
+ }
77
+ async getRepo(orgArg, repoArg, pathArg = '', _issueNumberArg = 0) {
78
+ const repository = await this.findVisibleRepository(orgArg, repoArg);
79
+ if (!repository) {
80
+ return {
81
+ repo: null,
82
+ contents: [],
83
+ readme: '',
84
+ releases: [],
85
+ activity: [],
86
+ issues: [],
87
+ selectedIssue: null,
88
+ selectedIssueComments: [],
89
+ commits: [],
90
+ languages: {},
91
+ };
92
+ }
93
+ const path = this.validatePath(pathArg);
94
+ const [tree, readme, tags, commitSummaries, languages] = await Promise.all([
95
+ this.withFallback(() => this.gitManager.listTree({
96
+ org: repository.org,
97
+ repo: repository.repo,
98
+ ref: repository.defaultBranch,
99
+ path: path || undefined,
100
+ }), []),
101
+ path ? Promise.resolve('') : this.readReadme(repository),
102
+ this.withFallback(() => this.gitManager.listTags({
103
+ org: repository.org,
104
+ repo: repository.repo,
105
+ limit: this.maxReleases,
106
+ }), []),
107
+ this.withFallback(() => this.gitManager.listCommits({
108
+ org: repository.org,
109
+ repo: repository.repo,
110
+ ref: repository.defaultBranch,
111
+ limit: Math.min(this.maxCommits, 12),
112
+ }), []),
113
+ this.scanLanguages(repository),
114
+ ]);
115
+ const commits = commitSummaries.map((commit) => this.mapCommit(commit));
116
+ const latestCommit = commits[0];
117
+ const releases = tags.map((tag) => this.mapRelease(repository, tag));
118
+ const repo = await this.mapRepository(repository);
119
+ repo.releaseCount = releases.length;
120
+ repo.language = this.getPrimaryLanguage(languages);
121
+ return {
122
+ repo,
123
+ contents: tree
124
+ .filter((entry) => entry.entryType !== 'other')
125
+ .map((entry) => this.mapContent(repository, entry, latestCommit)),
126
+ readme,
127
+ releases,
128
+ activity: commits.map((commit) => this.mapActivity(commit)),
129
+ issues: [],
130
+ selectedIssue: null,
131
+ selectedIssueComments: [],
132
+ commits,
133
+ languages,
134
+ };
135
+ }
136
+ async getFile(orgArg, repoArg, pathArg) {
137
+ const repository = await this.findVisibleRepository(orgArg, repoArg);
138
+ if (!repository) {
139
+ return { repo: null, file: null, activity: [], commits: [] };
140
+ }
141
+ const path = this.validatePath(pathArg, false);
142
+ const [file, commitSummaries, repo] = await Promise.all([
143
+ this.withFallback(() => this.gitManager.readFile({
144
+ org: repository.org,
145
+ repo: repository.repo,
146
+ ref: repository.defaultBranch,
147
+ path,
148
+ }), null),
149
+ this.withFallback(() => this.gitManager.listCommits({
150
+ org: repository.org,
151
+ repo: repository.repo,
152
+ ref: repository.defaultBranch,
153
+ limit: Math.min(this.maxCommits, 8),
154
+ }), []),
155
+ this.mapRepository(repository),
156
+ ]);
157
+ const commits = commitSummaries.map((commit) => this.mapCommit(commit));
158
+ return {
159
+ repo,
160
+ file: file
161
+ ? {
162
+ path: file.path,
163
+ name: file.path.split('/').pop() ?? file.path,
164
+ size: file.size,
165
+ htmlUrl: this.repoPathUrl(repository, `src/${repository.defaultBranch}/${file.path}`),
166
+ downloadUrl: '',
167
+ content: file.isBinary
168
+ ? ''
169
+ : Buffer.from(file.contentBase64, 'base64').toString('utf8'),
170
+ isBinary: file.isBinary,
171
+ truncated: false,
172
+ }
173
+ : null,
174
+ activity: commits.map((commit) => this.mapActivity(commit)),
175
+ commits,
176
+ };
177
+ }
178
+ async getCommits(orgArg, repoArg, shaArg = '') {
179
+ const repository = await this.findVisibleRepository(orgArg, repoArg);
180
+ if (!repository) {
181
+ return { repo: null, commits: [], selectedCommit: null };
182
+ }
183
+ const sha = shaArg.trim();
184
+ if (sha && !/^[0-9a-fA-F]{40,64}$/.test(sha)) {
185
+ throw new Error('Invalid commit SHA');
186
+ }
187
+ const [repo, commitSummaries, selectedCommit] = await Promise.all([
188
+ this.mapRepository(repository),
189
+ this.withFallback(() => this.gitManager.listCommits({
190
+ org: repository.org,
191
+ repo: repository.repo,
192
+ ref: repository.defaultBranch,
193
+ limit: this.maxCommits,
194
+ }), []),
195
+ sha
196
+ ? this.withFallback(() => this.getCommitDetail(repository, sha), null)
197
+ : Promise.resolve(null),
198
+ ]);
199
+ return {
200
+ repo,
201
+ commits: commitSummaries.map((commit) => this.mapCommit(commit)),
202
+ selectedCommit,
203
+ };
204
+ }
205
+ async listVisibleRepositories() {
206
+ const repositories = await this.gitManager.listRepositories();
207
+ if (this.allowAllRepositories) {
208
+ return repositories;
209
+ }
210
+ const visibility = await this.mapWithConcurrency(repositories, async (repository) => ({
211
+ repository,
212
+ visible: await this.isRepositoryPublic(repository),
213
+ }));
214
+ return visibility
215
+ .filter((entry) => entry.visible)
216
+ .map((entry) => entry.repository);
217
+ }
218
+ async findVisibleRepository(orgArg, repoArg) {
219
+ const org = this.validateSlug(orgArg, 'organization', 120);
220
+ const repo = this.validateSlug(repoArg, 'repository', 160);
221
+ return (await this.listVisibleRepositories()).find((repository) => repository.org === org && repository.repo === repo);
222
+ }
223
+ async mapOrganizations(repositoriesArg, explicitOrgsArg) {
224
+ const orgNames = explicitOrgsArg
225
+ ?? [...new Set(repositoriesArg.map((repository) => repository.org))];
226
+ const orgs = await this.mapWithConcurrency(orgNames, async (name) => {
227
+ const repositories = repositoriesArg.filter((repository) => repository.org === name);
228
+ const metadata = await this.organizationMetadata?.(name);
229
+ const base = {
230
+ name,
231
+ fullName: name,
232
+ description: '',
233
+ website: '',
234
+ location: '',
235
+ avatarUrl: '',
236
+ htmlUrl: `${this.publicBaseUrl}/${name}`,
237
+ repoCount: repositories.length,
238
+ starsCount: 0,
239
+ memberCount: 0,
240
+ languages: {},
241
+ };
242
+ return {
243
+ ...base,
244
+ ...metadata,
245
+ name,
246
+ repoCount: repositories.length,
247
+ };
248
+ });
249
+ return orgs.sort((orgA, orgB) => orgA.name.localeCompare(orgB.name));
250
+ }
251
+ async mapRepository(repositoryArg) {
252
+ const [latestCommit] = await this.withFallback(() => this.gitManager.listCommits({
253
+ org: repositoryArg.org,
254
+ repo: repositoryArg.repo,
255
+ ref: repositoryArg.defaultBranch,
256
+ limit: 1,
257
+ }), []);
258
+ const metadata = await this.repositoryMetadata?.(repositoryArg);
259
+ const slug = `${repositoryArg.org}/${repositoryArg.repo}`;
260
+ const base = {
261
+ id: this.stableId(slug),
262
+ org: repositoryArg.org,
263
+ name: repositoryArg.repo,
264
+ slug,
265
+ orgAvatarUrl: '',
266
+ description: '',
267
+ language: '',
268
+ htmlUrl: `${this.publicBaseUrl}/${slug}`,
269
+ cloneUrl: `${this.smartHttpBaseUrl}/${slug}.git`,
270
+ sshUrl: `${this.sshBaseUrl}/${slug}.git`,
271
+ starsCount: 0,
272
+ forksCount: 0,
273
+ watchersCount: 0,
274
+ openIssuesCount: 0,
275
+ openPrCount: 0,
276
+ releaseCount: 0,
277
+ size: 0,
278
+ defaultBranch: repositoryArg.defaultBranch,
279
+ updatedAt: latestCommit?.createdAt ?? '',
280
+ createdAt: latestCommit?.createdAt ?? '',
281
+ archived: false,
282
+ topics: [],
283
+ };
284
+ return {
285
+ ...base,
286
+ ...metadata,
287
+ id: this.stableId(slug),
288
+ org: repositoryArg.org,
289
+ name: repositoryArg.repo,
290
+ slug,
291
+ defaultBranch: repositoryArg.defaultBranch,
292
+ };
293
+ }
294
+ async getCommitFeed(repositoriesArg, perRepositoryLimitArg) {
295
+ const groups = await this.mapWithConcurrency(repositoriesArg, async (repository) => {
296
+ const commits = await this.withFallback(() => this.gitManager.listCommits({
297
+ org: repository.org,
298
+ repo: repository.repo,
299
+ ref: repository.defaultBranch,
300
+ limit: Math.min(this.maxCommits, perRepositoryLimitArg),
301
+ }), []);
302
+ return commits.map((commit) => this.mapCommit(commit));
303
+ });
304
+ return groups
305
+ .flat()
306
+ .sort((commitA, commitB) => commitB.createdAt.localeCompare(commitA.createdAt))
307
+ .slice(0, this.maxCommits);
308
+ }
309
+ mapCommit(commitArg) {
310
+ return {
311
+ sha: commitArg.sha,
312
+ shortSha: commitArg.shortSha,
313
+ message: commitArg.subject,
314
+ title: commitArg.subject,
315
+ body: '',
316
+ htmlUrl: this.repoPathUrl({ org: commitArg.org, repo: commitArg.repo }, `commit/${commitArg.sha}`),
317
+ createdAt: commitArg.createdAt,
318
+ authorName: commitArg.authorName,
319
+ authorLogin: '',
320
+ authorAvatarUrl: '',
321
+ repoSlug: `${commitArg.org}/${commitArg.repo}`,
322
+ files: [],
323
+ additions: 0,
324
+ deletions: 0,
325
+ verified: false,
326
+ kind: this.getActivityKind(commitArg.subject),
327
+ };
328
+ }
329
+ async getCommitDetail(repositoryArg, shaArg) {
330
+ const [commit, diff] = await Promise.all([
331
+ this.gitManager.getCommit({
332
+ org: repositoryArg.org,
333
+ repo: repositoryArg.repo,
334
+ ref: shaArg,
335
+ }),
336
+ this.gitManager.getDiff({
337
+ org: repositoryArg.org,
338
+ repo: repositoryArg.repo,
339
+ headRef: shaArg,
340
+ }),
341
+ ]);
342
+ return {
343
+ sha: commit.sha,
344
+ shortSha: commit.shortSha,
345
+ message: commit.message,
346
+ title: commit.subject,
347
+ body: commit.body,
348
+ htmlUrl: this.repoPathUrl(repositoryArg, `commit/${commit.sha}`),
349
+ createdAt: commit.createdAt,
350
+ authorName: commit.author.name,
351
+ authorLogin: '',
352
+ authorAvatarUrl: '',
353
+ verified: false,
354
+ parents: commit.parents.map((parent) => parent.sha),
355
+ additions: diff.additions,
356
+ deletions: diff.deletions,
357
+ files: diff.files.map((file) => ({
358
+ path: file.newPath || file.oldPath,
359
+ previousPath: file.oldPath,
360
+ status: this.mapDiffStatus(file.status),
361
+ language: this.languageForPath(file.newPath || file.oldPath),
362
+ additions: file.additions,
363
+ deletions: file.deletions,
364
+ isBinary: file.isBinary,
365
+ hunks: file.hunks.map((hunk) => ({
366
+ header: hunk.header,
367
+ lines: hunk.lines.map((line) => ({
368
+ kind: line.kind,
369
+ content: line.content,
370
+ oldNumber: line.oldNumber,
371
+ newNumber: line.newNumber,
372
+ })),
373
+ })),
374
+ })),
375
+ diffTruncated: diff.truncated,
376
+ };
377
+ }
378
+ mapContent(repositoryArg, entryArg, latestCommitArg) {
379
+ const type = entryArg.entryType === 'other' ? 'file' : entryArg.entryType;
380
+ return {
381
+ name: entryArg.name,
382
+ path: entryArg.path,
383
+ type,
384
+ size: entryArg.size ?? 0,
385
+ htmlUrl: this.repoPathUrl(repositoryArg, `src/${repositoryArg.defaultBranch}/${entryArg.path}`),
386
+ downloadUrl: '',
387
+ lastCommitSha: latestCommitArg?.sha ?? '',
388
+ lastAuthorDate: latestCommitArg?.createdAt ?? '',
389
+ lastCommitMessage: latestCommitArg?.title ?? '',
390
+ };
391
+ }
392
+ mapRelease(repositoryArg, tagArg) {
393
+ return {
394
+ tagName: tagArg.name,
395
+ name: tagArg.subject || tagArg.name,
396
+ body: tagArg.message,
397
+ htmlUrl: this.repoPathUrl(repositoryArg, `releases/tag/${tagArg.name}`),
398
+ publishedAt: tagArg.taggedAt,
399
+ prerelease: /(?:^|[-.])(alpha|beta|rc)(?:[-.]|$)/i.test(tagArg.name),
400
+ draft: false,
401
+ author: {
402
+ login: '',
403
+ fullName: tagArg.taggerName,
404
+ description: '',
405
+ website: '',
406
+ location: '',
407
+ avatarUrl: '',
408
+ htmlUrl: '',
409
+ createdAt: '',
410
+ },
411
+ assets: [],
412
+ };
413
+ }
414
+ mapActivity(commitArg) {
415
+ return {
416
+ id: commitArg.sha,
417
+ org: commitArg.repoSlug.split('/')[0] ?? '',
418
+ repo: commitArg.repoSlug.split('/')[1] ?? '',
419
+ repoSlug: commitArg.repoSlug,
420
+ tagName: '',
421
+ version: '',
422
+ kind: commitArg.kind,
423
+ title: commitArg.title,
424
+ body: commitArg.body,
425
+ createdAt: commitArg.createdAt,
426
+ };
427
+ }
428
+ async readReadme(repositoryArg) {
429
+ for (const path of ['README.md', 'readme.md', 'Readme.md']) {
430
+ try {
431
+ const file = await this.gitManager.readFile({
432
+ org: repositoryArg.org,
433
+ repo: repositoryArg.repo,
434
+ ref: repositoryArg.defaultBranch,
435
+ path,
436
+ });
437
+ if (!file.isBinary) {
438
+ return Buffer.from(file.contentBase64, 'base64').toString('utf8');
439
+ }
440
+ }
441
+ catch {
442
+ continue;
443
+ }
444
+ }
445
+ return '';
446
+ }
447
+ async scanLanguages(repositoryArg) {
448
+ const languages = {};
449
+ const pendingPaths = [''];
450
+ let fileCount = 0;
451
+ let scannedEntryCount = 0;
452
+ while (pendingPaths.length > 0 && scannedEntryCount < this.maxLanguageFiles) {
453
+ const path = pendingPaths.shift();
454
+ const entries = await this.withFallback(() => this.gitManager.listTree({
455
+ org: repositoryArg.org,
456
+ repo: repositoryArg.repo,
457
+ ref: repositoryArg.defaultBranch,
458
+ path: path || undefined,
459
+ }), []);
460
+ for (const entry of entries) {
461
+ if (scannedEntryCount >= this.maxLanguageFiles) {
462
+ break;
463
+ }
464
+ scannedEntryCount += 1;
465
+ if (entry.entryType === 'dir') {
466
+ if (entry.path.split('/').length <= 20) {
467
+ pendingPaths.push(entry.path);
468
+ }
469
+ continue;
470
+ }
471
+ if (entry.entryType !== 'file' || fileCount >= this.maxLanguageFiles) {
472
+ continue;
473
+ }
474
+ fileCount += 1;
475
+ const language = this.languageForPath(entry.path);
476
+ languages[language] = (languages[language] ?? 0) + (entry.size ?? 0);
477
+ }
478
+ }
479
+ return languages;
480
+ }
481
+ getStats(orgsArg, reposArg) {
482
+ return {
483
+ orgCount: orgsArg.length,
484
+ repoCount: reposArg.length,
485
+ releaseCount: reposArg.reduce((sum, repo) => sum + repo.releaseCount, 0),
486
+ openIssueCount: reposArg.reduce((sum, repo) => sum + repo.openIssuesCount, 0),
487
+ };
488
+ }
489
+ getPrimaryLanguage(languagesArg) {
490
+ return Object.entries(languagesArg)
491
+ .sort((entryA, entryB) => entryB[1] - entryA[1] || entryA[0].localeCompare(entryB[0]))[0]?.[0] ?? '';
492
+ }
493
+ languageForPath(pathArg) {
494
+ const extension = pathArg.toLowerCase().split('.').pop() ?? '';
495
+ const languages = {
496
+ ts: 'TypeScript',
497
+ tsx: 'TypeScript',
498
+ js: 'JavaScript',
499
+ jsx: 'JavaScript',
500
+ mjs: 'JavaScript',
501
+ cjs: 'JavaScript',
502
+ rs: 'Rust',
503
+ go: 'Go',
504
+ py: 'Python',
505
+ java: 'Java',
506
+ kt: 'Kotlin',
507
+ rb: 'Ruby',
508
+ php: 'PHP',
509
+ c: 'C',
510
+ h: 'C',
511
+ cc: 'C++',
512
+ cpp: 'C++',
513
+ hpp: 'C++',
514
+ cs: 'C#',
515
+ swift: 'Swift',
516
+ sh: 'Shell',
517
+ bash: 'Shell',
518
+ zsh: 'Shell',
519
+ html: 'HTML',
520
+ css: 'CSS',
521
+ scss: 'SCSS',
522
+ vue: 'Vue',
523
+ svelte: 'Svelte',
524
+ };
525
+ return languages[extension] ?? 'Other';
526
+ }
527
+ getActivityKind(messageArg) {
528
+ const prefix = messageArg.trim().toLowerCase().match(/^([a-z]+)(?:\([^)]*\))?[!:]/)?.[1];
529
+ switch (prefix) {
530
+ case 'feat':
531
+ case 'fix':
532
+ case 'perf':
533
+ case 'docs':
534
+ case 'test':
535
+ case 'refactor':
536
+ case 'build':
537
+ case 'ci':
538
+ case 'chore':
539
+ return prefix;
540
+ case 'release':
541
+ case 'rel':
542
+ return 'rel';
543
+ default:
544
+ return 'code';
545
+ }
546
+ }
547
+ mapDiffStatus(statusArg) {
548
+ switch (statusArg) {
549
+ case 'added':
550
+ case 'deleted':
551
+ case 'renamed':
552
+ return statusArg;
553
+ default:
554
+ return 'modified';
555
+ }
556
+ }
557
+ repoPathUrl(repositoryArg, suffixArg) {
558
+ const encodedSuffix = suffixArg
559
+ .split('/')
560
+ .map((segment) => encodeURIComponent(segment))
561
+ .join('/');
562
+ return `${this.publicBaseUrl}/${repositoryArg.org}/${repositoryArg.repo}/${encodedSuffix}`;
563
+ }
564
+ stableId(valueArg) {
565
+ let hash = 2166136261;
566
+ for (const char of valueArg) {
567
+ hash ^= char.charCodeAt(0);
568
+ hash = Math.imul(hash, 16777619);
569
+ }
570
+ return hash >>> 0;
571
+ }
572
+ normalizeBaseUrl(valueArg, allowedProtocolsArg) {
573
+ const value = valueArg.trim().replace(/\/+$/, '');
574
+ if (!value
575
+ || value.length > 2048
576
+ || /[\u0000-\u0020\u007f]/.test(value)) {
577
+ throw new Error('Invalid base URL');
578
+ }
579
+ let parsed;
580
+ try {
581
+ parsed = new URL(value);
582
+ }
583
+ catch {
584
+ throw new Error('Invalid base URL');
585
+ }
586
+ if (!allowedProtocolsArg.includes(parsed.protocol)
587
+ || parsed.password
588
+ || parsed.search
589
+ || parsed.hash) {
590
+ throw new Error('Invalid base URL');
591
+ }
592
+ return value;
593
+ }
594
+ validateSlug(valueArg, labelArg, maxLengthArg) {
595
+ const value = valueArg.trim();
596
+ if (!value
597
+ || value.length > maxLengthArg
598
+ || value === '.'
599
+ || value === '..'
600
+ || !/^[A-Za-z0-9._-]+$/.test(value)) {
601
+ throw new Error(`Invalid ${labelArg}`);
602
+ }
603
+ return value;
604
+ }
605
+ validatePath(valueArg, allowEmptyArg = true) {
606
+ const path = valueArg.trim().replace(/^\/+|\/+$/g, '');
607
+ if (!path) {
608
+ if (allowEmptyArg) {
609
+ return '';
610
+ }
611
+ throw new Error('Path is required');
612
+ }
613
+ if (path.length > 500
614
+ || path.includes('\\')
615
+ || path.split('/').some((segment) => !segment || segment === '.' || segment === '..')) {
616
+ throw new Error('Invalid path');
617
+ }
618
+ return path;
619
+ }
620
+ validateLimit(valueArg, labelArg, minimumArg, maximumArg) {
621
+ if (!Number.isSafeInteger(valueArg) || valueArg < minimumArg || valueArg > maximumArg) {
622
+ throw new Error(`${labelArg} must be an integer between ${minimumArg} and ${maximumArg}`);
623
+ }
624
+ return valueArg;
625
+ }
626
+ async withFallback(operationArg, fallbackArg) {
627
+ try {
628
+ return await operationArg();
629
+ }
630
+ catch {
631
+ return fallbackArg;
632
+ }
633
+ }
634
+ async mapWithConcurrency(itemsArg, mapperArg) {
635
+ const results = new Array(itemsArg.length);
636
+ let nextIndex = 0;
637
+ const workers = Array.from({ length: Math.min(this.maxConcurrency, itemsArg.length) }, async () => {
638
+ while (nextIndex < itemsArg.length) {
639
+ const index = nextIndex;
640
+ nextIndex += 1;
641
+ results[index] = await mapperArg(itemsArg[index]);
642
+ }
643
+ });
644
+ await Promise.all(workers);
645
+ return results;
646
+ }
647
+ }
648
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5naXRtYW5hZ2VycHVibGljY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5naXRtYW5hZ2VycHVibGljY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBc0J4QyxNQUFNLE9BQU8sMEJBQTBCO0lBdUJyQyxZQUFZLFVBQThDO1FBQ3hELElBQUksQ0FBQyxVQUFVLENBQUMsb0JBQW9CLElBQUksQ0FBQyxVQUFVLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUN2RSxNQUFNLElBQUksS0FBSyxDQUNiLDJHQUEyRyxDQUM1RyxDQUFDO1FBQ0osQ0FBQztRQUNELElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDLFVBQVUsQ0FBQztRQUN4QyxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FDeEMsVUFBVSxDQUFDLGFBQWEsSUFBSSxxQkFBcUIsRUFDakQsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQ3BCLENBQUM7UUFDRixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUMzQyxVQUFVLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDLGFBQWEsRUFDakQsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQ3BCLENBQUM7UUFDRixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FDckMsVUFBVSxDQUFDLFVBQVUsSUFBSSxrQ0FBa0MsRUFDM0QsQ0FBQyxNQUFNLENBQUMsQ0FDVCxDQUFDO1FBQ0YsSUFBSSxDQUFDLG9CQUFvQixHQUFHLFVBQVUsQ0FBQyxvQkFBb0IsSUFBSSxLQUFLLENBQUM7UUFDckUsSUFBSSxDQUFDLGtCQUFrQixHQUFHLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQztRQUN4RCxJQUFJLENBQUMsb0JBQW9CLEdBQUcsVUFBVSxDQUFDLG9CQUFv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