@ankhorage/repository 0.5.0 → 0.5.1
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 +6 -0
- package/README.md +1 -1
- package/dist/github/index.d.ts +1 -1
- package/dist/github/index.d.ts.map +1 -1
- package/dist/github/index.js.map +1 -1
- package/dist/providers/github/definitions/GitHubRepositoryMaterializationResult.d.ts +7 -0
- package/dist/providers/github/definitions/GitHubRepositoryMaterializationResult.d.ts.map +1 -1
- package/dist/providers/github/services/materializeGitHubRepositoryWithGatewayAsync.d.ts.map +1 -1
- package/dist/providers/github/services/materializeGitHubRepositoryWithGatewayAsync.js +90 -27
- package/dist/providers/github/services/materializeGitHubRepositoryWithGatewayAsync.js.map +1 -1
- package/dist/providers/github/services/materializeGitHubRepositoryWithGatewayAsync.test.js +66 -8
- package/dist/providers/github/services/materializeGitHubRepositoryWithGatewayAsync.test.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# @ankhorage/repository
|
|
5
5
|
|
|
6
|
-
         
|
|
7
7
|
|
|
8
8
|
Standalone repository capability for connecting and managing an app project's source repository.
|
|
9
9
|
|
package/dist/github/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export type { GitHubRepositoryConnectionOptions } from '../providers/github/definitions/GitHubRepositoryConnectionOptions.js';
|
|
2
2
|
export type { GitHubRepositoryConnectionFailure, GitHubRepositoryConnectionResult, GitHubRepositoryConnectionStatus, } from '../providers/github/definitions/GitHubRepositoryConnectionResult.js';
|
|
3
3
|
export type { GitHubRepositoryMaterializationOptions } from '../providers/github/definitions/GitHubRepositoryMaterializationOptions.js';
|
|
4
|
-
export type { GitHubRepositoryMaterializationResult } from '../providers/github/definitions/GitHubRepositoryMaterializationResult.js';
|
|
4
|
+
export type { GitHubRepositoryMaterializationDiagnostic, GitHubRepositoryMaterializationResult, } from '../providers/github/definitions/GitHubRepositoryMaterializationResult.js';
|
|
5
5
|
export type { GitHubRepositoryVisibility } from '../providers/github/definitions/GitHubRepositoryVisibility.js';
|
|
6
6
|
export { connectGitHubRepositoryAsync } from '../providers/github/services/connectGitHubRepositoryAsync.js';
|
|
7
7
|
export { materializeGitHubRepositoryAsync } from '../providers/github/services/materializeGitHubRepositoryAsync.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/github/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iCAAiC,EAAE,MAAM,sEAAsE,CAAC;AAC9H,YAAY,EACV,iCAAiC,EACjC,gCAAgC,EAChC,gCAAgC,GACjC,MAAM,qEAAqE,CAAC;AAC7E,YAAY,EAAE,sCAAsC,EAAE,MAAM,2EAA2E,CAAC;AACxI,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/github/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iCAAiC,EAAE,MAAM,sEAAsE,CAAC;AAC9H,YAAY,EACV,iCAAiC,EACjC,gCAAgC,EAChC,gCAAgC,GACjC,MAAM,qEAAqE,CAAC;AAC7E,YAAY,EAAE,sCAAsC,EAAE,MAAM,2EAA2E,CAAC;AACxI,YAAY,EACV,yCAAyC,EACzC,qCAAqC,GACtC,MAAM,0EAA0E,CAAC;AAClF,YAAY,EAAE,0BAA0B,EAAE,MAAM,+DAA+D,CAAC;AAChH,OAAO,EAAE,4BAA4B,EAAE,MAAM,8DAA8D,CAAC;AAC5G,OAAO,EAAE,gCAAgC,EAAE,MAAM,kEAAkE,CAAC"}
|
package/dist/github/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/github/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/github/index.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,4BAA4B,EAAE,MAAM,8DAA8D,CAAC;AAC5G,OAAO,EAAE,gCAAgC,EAAE,MAAM,kEAAkE,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export interface GitHubRepositoryMaterializationResult {
|
|
2
2
|
readonly rootPath: string;
|
|
3
3
|
readonly revision: string;
|
|
4
|
+
readonly diagnostics: readonly GitHubRepositoryMaterializationDiagnostic[];
|
|
4
5
|
readonly repository: {
|
|
5
6
|
readonly owner: string;
|
|
6
7
|
readonly name: string;
|
|
@@ -9,4 +10,10 @@ export interface GitHubRepositoryMaterializationResult {
|
|
|
9
10
|
};
|
|
10
11
|
readonly cleanupAsync: () => Promise<void>;
|
|
11
12
|
}
|
|
13
|
+
export interface GitHubRepositoryMaterializationDiagnostic {
|
|
14
|
+
readonly code: 'symlink-skipped';
|
|
15
|
+
readonly severity: 'warning';
|
|
16
|
+
readonly path: string;
|
|
17
|
+
readonly message: string;
|
|
18
|
+
}
|
|
12
19
|
//# sourceMappingURL=GitHubRepositoryMaterializationResult.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GitHubRepositoryMaterializationResult.d.ts","sourceRoot":"","sources":["../../../../src/providers/github/definitions/GitHubRepositoryMaterializationResult.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qCAAqC;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE;QACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;KAChC,CAAC;IACF,QAAQ,CAAC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C"}
|
|
1
|
+
{"version":3,"file":"GitHubRepositoryMaterializationResult.d.ts","sourceRoot":"","sources":["../../../../src/providers/github/definitions/GitHubRepositoryMaterializationResult.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,qCAAqC;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,SAAS,yCAAyC,EAAE,CAAC;IAC3E,QAAQ,CAAC,UAAU,EAAE;QACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;KAChC,CAAC;IACF,QAAQ,CAAC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,yCAAyC;IACxD,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"materializeGitHubRepositoryWithGatewayAsync.d.ts","sourceRoot":"","sources":["../../../../src/providers/github/services/materializeGitHubRepositoryWithGatewayAsync.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sCAAsC,EAAE,MAAM,0DAA0D,CAAC;AACvH,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,yDAAyD,CAAC;AACrH,OAAO,KAAK,EACV,2BAA2B,
|
|
1
|
+
{"version":3,"file":"materializeGitHubRepositoryWithGatewayAsync.d.ts","sourceRoot":"","sources":["../../../../src/providers/github/services/materializeGitHubRepositoryWithGatewayAsync.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,sCAAsC,EAAE,MAAM,0DAA0D,CAAC;AACvH,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,yDAAyD,CAAC;AACrH,OAAO,KAAK,EACV,2BAA2B,EAI5B,MAAM,yCAAyC,CAAC;AAEjD,mGAAmG;AACnG,wBAAsB,2CAA2C,CAC/D,OAAO,EAAE,sCAAsC,EAC/C,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,qCAAqC,CAAC,CAqChD"}
|
|
@@ -3,15 +3,17 @@ import { tmpdir } from 'node:os';
|
|
|
3
3
|
import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
4
4
|
/*** Materialize a GitHub repository through an injected read gateway for deterministic testing. */
|
|
5
5
|
export async function materializeGitHubRepositoryWithGatewayAsync(options, gateway) {
|
|
6
|
-
const
|
|
7
|
-
const repository = await gateway.inspectRepositoryAsync(target);
|
|
8
|
-
const
|
|
9
|
-
const revision =
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
const parsed = parseGitHubRepositoryUrl(options.url);
|
|
7
|
+
const repository = await gateway.inspectRepositoryAsync(parsed.target);
|
|
8
|
+
const explicitRef = normalizeRef(options.ref);
|
|
9
|
+
const revision = explicitRef === undefined
|
|
10
|
+
? await resolveUrlRevisionAsync(gateway, parsed, repository.defaultBranch)
|
|
11
|
+
: await gateway.resolveRevisionAsync(parsed.target, explicitRef);
|
|
12
|
+
const tree = await gateway.readTreeAsync(parsed.target, revision.treeSha);
|
|
13
|
+
const validated = validateTree(tree.entries, tree.truncated);
|
|
12
14
|
const rootPath = await createMaterializationRootAsync(options.destinationPath);
|
|
13
15
|
try {
|
|
14
|
-
await writeFileBatchesAsync(gateway, target, revision.commitSha, rootPath, files);
|
|
16
|
+
await writeFileBatchesAsync(gateway, parsed.target, revision.commitSha, rootPath, validated.files);
|
|
15
17
|
}
|
|
16
18
|
catch (error) {
|
|
17
19
|
await rm(rootPath, { force: true, recursive: true });
|
|
@@ -20,9 +22,10 @@ export async function materializeGitHubRepositoryWithGatewayAsync(options, gatew
|
|
|
20
22
|
return {
|
|
21
23
|
rootPath,
|
|
22
24
|
revision: revision.commitSha,
|
|
25
|
+
diagnostics: validated.diagnostics,
|
|
23
26
|
repository: {
|
|
24
|
-
owner: target.owner,
|
|
25
|
-
name: target.name,
|
|
27
|
+
owner: parsed.target.owner,
|
|
28
|
+
name: parsed.target.name,
|
|
26
29
|
url: repository.url,
|
|
27
30
|
defaultBranch: repository.defaultBranch,
|
|
28
31
|
},
|
|
@@ -32,21 +35,42 @@ export async function materializeGitHubRepositoryWithGatewayAsync(options, gatew
|
|
|
32
35
|
const MAX_FILE_COUNT = 20_000;
|
|
33
36
|
const MAX_TOTAL_BYTES = 256 * 1024 * 1024;
|
|
34
37
|
const WRITE_BATCH_SIZE = 8;
|
|
35
|
-
/*** Parse
|
|
38
|
+
/*** Parse a normal GitHub repository, tree, blob, or commit URL into repository and ref intent. */
|
|
36
39
|
function parseGitHubRepositoryUrl(value) {
|
|
37
40
|
const url = parseRepositoryUrl(value);
|
|
38
41
|
assertGitHubRepositoryUrl(url);
|
|
39
|
-
const segments = url
|
|
40
|
-
if (segments.length
|
|
41
|
-
throw
|
|
42
|
+
const segments = decodePathSegments(url);
|
|
43
|
+
if (segments.length < 2) {
|
|
44
|
+
throw invalidRepositoryUrl();
|
|
42
45
|
}
|
|
43
|
-
const owner =
|
|
44
|
-
const repositorySegment = segments[1] ?? '';
|
|
46
|
+
const [owner = '', repositorySegment = '', route] = segments;
|
|
45
47
|
const name = repositorySegment.endsWith('.git')
|
|
46
48
|
? repositorySegment.slice(0, -4)
|
|
47
49
|
: repositorySegment;
|
|
48
50
|
assertRepositoryIdentity(owner, name);
|
|
49
|
-
|
|
51
|
+
const routeSegments = segments.slice(3);
|
|
52
|
+
if (route === undefined) {
|
|
53
|
+
return {
|
|
54
|
+
target: { owner, name, url: `https://github.com/${owner}/${name}` },
|
|
55
|
+
refCandidates: [],
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (route === 'commit') {
|
|
59
|
+
if (routeSegments.length !== 1)
|
|
60
|
+
throw invalidRepositoryUrl();
|
|
61
|
+
return {
|
|
62
|
+
target: { owner, name, url: `https://github.com/${owner}/${name}` },
|
|
63
|
+
refCandidates: [routeSegments[0] ?? ''],
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
if (route !== 'tree' && route !== 'blob')
|
|
67
|
+
throw invalidRepositoryUrl();
|
|
68
|
+
if (routeSegments.length === 0)
|
|
69
|
+
throw invalidRepositoryUrl();
|
|
70
|
+
return {
|
|
71
|
+
target: { owner, name, url: `https://github.com/${owner}/${name}` },
|
|
72
|
+
refCandidates: createRefCandidates(routeSegments),
|
|
73
|
+
};
|
|
50
74
|
}
|
|
51
75
|
/*** Parse a repository URL while preserving the original parsing failure as the cause. */
|
|
52
76
|
function parseRepositoryUrl(value) {
|
|
@@ -57,16 +81,49 @@ function parseRepositoryUrl(value) {
|
|
|
57
81
|
throw new Error('Repository URL must be a valid GitHub HTTPS URL.', { cause: error });
|
|
58
82
|
}
|
|
59
83
|
}
|
|
60
|
-
/*** Reject non-GitHub origins
|
|
84
|
+
/*** Reject non-GitHub origins and embedded credentials while ignoring normal page query/anchor state. */
|
|
61
85
|
function assertGitHubRepositoryUrl(url) {
|
|
62
86
|
if (url.protocol !== 'https:' ||
|
|
63
87
|
url.hostname.toLowerCase() !== 'github.com' ||
|
|
64
88
|
url.username !== '' ||
|
|
65
|
-
url.password !== ''
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
89
|
+
url.password !== '') {
|
|
90
|
+
throw invalidRepositoryUrl();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/*** Decode normal GitHub path segments and reject malformed encoded paths. */
|
|
94
|
+
function decodePathSegments(url) {
|
|
95
|
+
try {
|
|
96
|
+
return url.pathname
|
|
97
|
+
.split('/')
|
|
98
|
+
.filter(Boolean)
|
|
99
|
+
.map((segment) => decodeURIComponent(segment));
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
throw new Error('Repository URL contains an invalid encoded path.', { cause: error });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/*** Build longest-first ref candidates so slash-containing branch/tag names resolve like GitHub URLs. */
|
|
106
|
+
function createRefCandidates(segments) {
|
|
107
|
+
return Array.from({ length: segments.length }, (_, index) => segments.slice(0, segments.length - index).join('/'));
|
|
108
|
+
}
|
|
109
|
+
/*** Resolve URL-derived ref candidates, falling back to the repository default branch. */
|
|
110
|
+
async function resolveUrlRevisionAsync(gateway, parsed, defaultBranch) {
|
|
111
|
+
if (parsed.refCandidates.length === 0) {
|
|
112
|
+
return gateway.resolveRevisionAsync(parsed.target, defaultBranch);
|
|
113
|
+
}
|
|
114
|
+
for (const candidate of parsed.refCandidates) {
|
|
115
|
+
try {
|
|
116
|
+
return await gateway.resolveRevisionAsync(parsed.target, candidate);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// GitHub tree/blob URLs can contain both slash-containing refs and trailing repository paths.
|
|
120
|
+
}
|
|
69
121
|
}
|
|
122
|
+
throw new Error('GitHub repository URL does not resolve to a branch, tag, or commit.');
|
|
123
|
+
}
|
|
124
|
+
/*** Create the consistent public error for unsupported GitHub URL shapes. */
|
|
125
|
+
function invalidRepositoryUrl() {
|
|
126
|
+
return new Error('Repository URL must be a GitHub repository, tree, blob, or commit HTTPS URL.');
|
|
70
127
|
}
|
|
71
128
|
/*** Validate canonical GitHub owner and repository path segments. */
|
|
72
129
|
function assertRepositoryIdentity(owner, name) {
|
|
@@ -86,18 +143,16 @@ function normalizeRef(value) {
|
|
|
86
143
|
throw new Error('GitHub repository ref must not be empty.');
|
|
87
144
|
return normalized;
|
|
88
145
|
}
|
|
89
|
-
/*** Reject incomplete or unexpectedly large remote trees
|
|
146
|
+
/*** Reject incomplete or unexpectedly large remote trees while safely omitting symbolic links. */
|
|
90
147
|
function validateTree(entries, truncated) {
|
|
91
148
|
if (truncated) {
|
|
92
149
|
throw new Error('GitHub repository tree is truncated and cannot be materialized safely.');
|
|
93
150
|
}
|
|
94
|
-
const
|
|
151
|
+
const symlinks = entries.filter((entry) => entry.type === 'blob' && entry.mode === '120000');
|
|
152
|
+
const files = entries.filter((entry) => entry.type === 'blob' && entry.mode !== '120000');
|
|
95
153
|
if (files.length > MAX_FILE_COUNT) {
|
|
96
154
|
throw new Error(`GitHub repository exceeds the ${MAX_FILE_COUNT} file materialization limit.`);
|
|
97
155
|
}
|
|
98
|
-
if (files.some((entry) => entry.mode === '120000')) {
|
|
99
|
-
throw new Error('GitHub repository symbolic links are not supported by safe materialization.');
|
|
100
|
-
}
|
|
101
156
|
const totalBytes = files.reduce((sum, entry) => {
|
|
102
157
|
if (entry.size === undefined) {
|
|
103
158
|
throw new Error(`GitHub repository file size is missing for ${entry.path}.`);
|
|
@@ -107,7 +162,15 @@ function validateTree(entries, truncated) {
|
|
|
107
162
|
if (totalBytes > MAX_TOTAL_BYTES) {
|
|
108
163
|
throw new Error('GitHub repository exceeds the 256 MiB materialization limit.');
|
|
109
164
|
}
|
|
110
|
-
return
|
|
165
|
+
return {
|
|
166
|
+
files,
|
|
167
|
+
diagnostics: symlinks.map((entry) => ({
|
|
168
|
+
code: 'symlink-skipped',
|
|
169
|
+
severity: 'warning',
|
|
170
|
+
path: entry.path,
|
|
171
|
+
message: 'Symbolic link skipped during safe GitHub repository materialization.',
|
|
172
|
+
})),
|
|
173
|
+
};
|
|
111
174
|
}
|
|
112
175
|
/*** Create either an isolated temporary root or one explicitly requested empty destination. */
|
|
113
176
|
async function createMaterializationRootAsync(destinationPath) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"materializeGitHubRepositoryWithGatewayAsync.js","sourceRoot":"","sources":["../../../../src/providers/github/services/materializeGitHubRepositoryWithGatewayAsync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"materializeGitHubRepositoryWithGatewayAsync.js","sourceRoot":"","sources":["../../../../src/providers/github/services/materializeGitHubRepositoryWithGatewayAsync.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { access, readFile } from 'node:fs/promises';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { expect, test } from 'bun:test';
|
|
4
4
|
import { materializeGitHubRepositoryWithGatewayAsync } from './materializeGitHubRepositoryWithGatewayAsync.js';
|
|
5
|
-
test('materializes an exact GitHub revision and cleans up the isolated root', async () => {
|
|
5
|
+
test('materializes an exact explicit GitHub revision and cleans up the isolated root', async () => {
|
|
6
6
|
const requestedRefs = [];
|
|
7
7
|
const gateway = createGateway({
|
|
8
8
|
requestedRefs,
|
|
@@ -14,6 +14,7 @@ test('materializes an exact GitHub revision and cleans up the isolated root', as
|
|
|
14
14
|
const result = await materializeGitHubRepositoryWithGatewayAsync({ url: 'https://github.com/ankhorage/demo', ref: 'feature/read' }, gateway);
|
|
15
15
|
expect(requestedRefs).toEqual(['feature/read']);
|
|
16
16
|
expect(result.revision).toBe('commit-sha');
|
|
17
|
+
expect(result.diagnostics).toEqual([]);
|
|
17
18
|
expect(result.repository).toEqual({
|
|
18
19
|
owner: 'ankhorage',
|
|
19
20
|
name: 'demo',
|
|
@@ -24,12 +25,42 @@ test('materializes an exact GitHub revision and cleans up the isolated root', as
|
|
|
24
25
|
await result.cleanupAsync();
|
|
25
26
|
await expectMissingPathAsync(result.rootPath);
|
|
26
27
|
});
|
|
27
|
-
test('uses the remote default branch
|
|
28
|
+
test('uses the remote default branch for a normal repository URL', async () => {
|
|
28
29
|
const requestedRefs = [];
|
|
29
|
-
const result = await materializeGitHubRepositoryWithGatewayAsync({ url: 'https://github.com/ankhorage/demo.git' }, createGateway({ requestedRefs, defaultBranch: 'develop', files: {} }));
|
|
30
|
+
const result = await materializeGitHubRepositoryWithGatewayAsync({ url: 'https://github.com/ankhorage/demo.git?tab=readme-ov-file#readme' }, createGateway({ requestedRefs, defaultBranch: 'develop', files: {} }));
|
|
30
31
|
expect(requestedRefs).toEqual(['develop']);
|
|
31
32
|
await result.cleanupAsync();
|
|
32
33
|
});
|
|
34
|
+
test('resolves slash-containing refs from normal GitHub tree URLs', async () => {
|
|
35
|
+
const requestedRefs = [];
|
|
36
|
+
const result = await materializeGitHubRepositoryWithGatewayAsync({ url: 'https://github.com/ankhorage/demo/tree/feature/read' }, createGateway({
|
|
37
|
+
requestedRefs,
|
|
38
|
+
acceptedRefs: ['feature/read'],
|
|
39
|
+
files: { 'src/index.ts': 'export {};\n' },
|
|
40
|
+
}));
|
|
41
|
+
expect(requestedRefs).toEqual(['feature/read']);
|
|
42
|
+
await result.cleanupAsync();
|
|
43
|
+
});
|
|
44
|
+
test('resolves a ref from normal GitHub blob URLs while ignoring the file path', async () => {
|
|
45
|
+
const requestedRefs = [];
|
|
46
|
+
const result = await materializeGitHubRepositoryWithGatewayAsync({ url: 'https://github.com/ankhorage/demo/blob/main/src/index.ts#L1' }, createGateway({
|
|
47
|
+
requestedRefs,
|
|
48
|
+
acceptedRefs: ['main'],
|
|
49
|
+
files: { 'src/index.ts': 'export {};\n' },
|
|
50
|
+
}));
|
|
51
|
+
expect(requestedRefs).toEqual(['main/src/index.ts', 'main/src', 'main']);
|
|
52
|
+
await result.cleanupAsync();
|
|
53
|
+
});
|
|
54
|
+
test('resolves normal GitHub commit URLs directly', async () => {
|
|
55
|
+
const requestedRefs = [];
|
|
56
|
+
const result = await materializeGitHubRepositoryWithGatewayAsync({ url: 'https://github.com/ankhorage/demo/commit/deadbeef' }, createGateway({
|
|
57
|
+
requestedRefs,
|
|
58
|
+
acceptedRefs: ['deadbeef'],
|
|
59
|
+
files: {},
|
|
60
|
+
}));
|
|
61
|
+
expect(requestedRefs).toEqual(['deadbeef']);
|
|
62
|
+
await result.cleanupAsync();
|
|
63
|
+
});
|
|
33
64
|
test('rejects traversal before downloading an unsafe repository file', async () => {
|
|
34
65
|
let reads = 0;
|
|
35
66
|
const gateway = createGateway({
|
|
@@ -45,23 +76,46 @@ test('rejects truncated GitHub trees before materialization', async () => {
|
|
|
45
76
|
const gateway = createGateway({ files: {}, truncated: true });
|
|
46
77
|
await expectFailureAsync(() => materializeGitHubRepositoryWithGatewayAsync({ url: 'https://github.com/ankhorage/demo' }, gateway), 'repository tree is truncated');
|
|
47
78
|
});
|
|
48
|
-
test('
|
|
79
|
+
test('skips symbolic links with warnings without reading their target bytes', async () => {
|
|
80
|
+
const reads = [];
|
|
49
81
|
const gateway = {
|
|
50
|
-
...createGateway({
|
|
82
|
+
...createGateway({
|
|
83
|
+
files: { 'src/index.ts': 'export {};\n' },
|
|
84
|
+
onReadPath: (path) => reads.push(path),
|
|
85
|
+
}),
|
|
51
86
|
readTreeAsync: () => Promise.resolve({
|
|
52
87
|
truncated: false,
|
|
53
88
|
entries: [
|
|
54
89
|
{
|
|
55
90
|
mode: '120000',
|
|
56
|
-
path: '
|
|
91
|
+
path: 'CLAUDE.md',
|
|
57
92
|
sha: 'link-sha',
|
|
58
|
-
size:
|
|
93
|
+
size: 9,
|
|
94
|
+
type: 'blob',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
mode: '100644',
|
|
98
|
+
path: 'src/index.ts',
|
|
99
|
+
sha: 'file-sha',
|
|
100
|
+
size: 11,
|
|
59
101
|
type: 'blob',
|
|
60
102
|
},
|
|
61
103
|
],
|
|
62
104
|
}),
|
|
63
105
|
};
|
|
64
|
-
|
|
106
|
+
const result = await materializeGitHubRepositoryWithGatewayAsync({ url: 'https://github.com/ankhorage/demo' }, gateway);
|
|
107
|
+
expect(reads).toEqual(['src/index.ts']);
|
|
108
|
+
expect(await readFile(join(result.rootPath, 'src/index.ts'), 'utf8')).toBe('export {};\n');
|
|
109
|
+
expect(result.diagnostics).toEqual([
|
|
110
|
+
{
|
|
111
|
+
code: 'symlink-skipped',
|
|
112
|
+
severity: 'warning',
|
|
113
|
+
path: 'CLAUDE.md',
|
|
114
|
+
message: 'Symbolic link skipped during safe GitHub repository materialization.',
|
|
115
|
+
},
|
|
116
|
+
]);
|
|
117
|
+
await expectMissingPathAsync(join(result.rootPath, 'CLAUDE.md'));
|
|
118
|
+
await result.cleanupAsync();
|
|
65
119
|
});
|
|
66
120
|
function createGateway(options) {
|
|
67
121
|
const files = new Map(Object.entries(options.files));
|
|
@@ -79,6 +133,9 @@ function createGateway(options) {
|
|
|
79
133
|
}),
|
|
80
134
|
resolveRevisionAsync: (_target, ref) => {
|
|
81
135
|
options.requestedRefs?.push(ref);
|
|
136
|
+
if (options.acceptedRefs !== undefined && !options.acceptedRefs.includes(ref)) {
|
|
137
|
+
return Promise.reject(new Error(`Unknown fixture ref: ${ref}`));
|
|
138
|
+
}
|
|
82
139
|
return Promise.resolve({ commitSha: 'commit-sha', treeSha: 'tree-sha' });
|
|
83
140
|
},
|
|
84
141
|
readTreeAsync: () => Promise.resolve({
|
|
@@ -87,6 +144,7 @@ function createGateway(options) {
|
|
|
87
144
|
}),
|
|
88
145
|
readFileAsync: (_target, _revision, path) => {
|
|
89
146
|
options.onRead?.();
|
|
147
|
+
options.onReadPath?.(path);
|
|
90
148
|
const fileContent = files.get(path);
|
|
91
149
|
if (fileContent === undefined)
|
|
92
150
|
throw new Error(`Missing fixture: ${path}`);
|
package/dist/providers/github/services/materializeGitHubRepositoryWithGatewayAsync.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"materializeGitHubRepositoryWithGatewayAsync.test.js","sourceRoot":"","sources":["../../../../src/providers/github/services/materializeGitHubRepositoryWithGatewayAsync.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGxC,OAAO,EAAE,2CAA2C,EAAE,MAAM,kDAAkD,CAAC;AAE/G,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"materializeGitHubRepositoryWithGatewayAsync.test.js","sourceRoot":"","sources":["../../../../src/providers/github/services/materializeGitHubRepositoryWithGatewayAsync.test.ts"],"names":[],"mappings":"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"}
|