@quatrain/code-github 1.1.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.
@@ -0,0 +1,12 @@
1
+ import { AbstractRepositoryAdapter, CommitFile } from '@quatrain/code';
2
+ import { Octokit } from '@octokit/rest';
3
+ export declare class GithubAdapter extends AbstractRepositoryAdapter {
4
+ protected _octokit: Octokit;
5
+ protected _owner: string;
6
+ protected _repo: string;
7
+ constructor(auth: string, owner: string, repo: string);
8
+ pull(branch?: string): Promise<void>;
9
+ push(files: CommitFile[], message: string, branch?: string): Promise<void>;
10
+ createBranch(branchName: string, fromBranch?: string): Promise<void>;
11
+ }
12
+ //# sourceMappingURL=GithubAdapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GithubAdapter.d.ts","sourceRoot":"","sources":["../src/GithubAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AACtE,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,qBAAa,aAAc,SAAQ,yBAAyB;IACzD,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC3B,SAAS,CAAC,MAAM,EAAE,MAAM,CAAA;IACxB,SAAS,CAAC,KAAK,EAAE,MAAM,CAAA;gBAEX,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAO/C,IAAI,CAAC,MAAM,GAAE,MAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAS5C,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,MAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA8DlF,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,GAAE,MAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAcpF"}
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GithubAdapter = void 0;
4
+ const code_1 = require("@quatrain/code");
5
+ const rest_1 = require("@octokit/rest");
6
+ class GithubAdapter extends code_1.AbstractRepositoryAdapter {
7
+ _octokit;
8
+ _owner;
9
+ _repo;
10
+ constructor(auth, owner, repo) {
11
+ super();
12
+ this._octokit = new rest_1.Octokit({ auth });
13
+ this._owner = owner;
14
+ this._repo = repo;
15
+ }
16
+ async pull(branch = 'main') {
17
+ await this._octokit.repos.get({
18
+ owner: this._owner,
19
+ repo: this._repo,
20
+ });
21
+ }
22
+ async push(files, message, branch = 'main') {
23
+ const { data: refData } = await this._octokit.git.getRef({
24
+ owner: this._owner,
25
+ repo: this._repo,
26
+ ref: `heads/${branch}`,
27
+ });
28
+ const commitSha = refData.object.sha;
29
+ const { data: commitData } = await this._octokit.git.getCommit({
30
+ owner: this._owner,
31
+ repo: this._repo,
32
+ commit_sha: commitSha,
33
+ });
34
+ const baseTreeSha = commitData.tree.sha;
35
+ const tree = await Promise.all(files.map(async (file) => {
36
+ const { data: blobData } = await this._octokit.git.createBlob({
37
+ owner: this._owner,
38
+ repo: this._repo,
39
+ content: file.content,
40
+ encoding: 'utf-8',
41
+ });
42
+ return {
43
+ path: file.path,
44
+ mode: '100644',
45
+ type: 'blob',
46
+ sha: blobData.sha,
47
+ };
48
+ }));
49
+ const { data: treeData } = await this._octokit.git.createTree({
50
+ owner: this._owner,
51
+ repo: this._repo,
52
+ tree,
53
+ base_tree: baseTreeSha,
54
+ });
55
+ const { data: newCommitData } = await this._octokit.git.createCommit({
56
+ owner: this._owner,
57
+ repo: this._repo,
58
+ message,
59
+ tree: treeData.sha,
60
+ parents: [commitSha],
61
+ });
62
+ await this._octokit.git.updateRef({
63
+ owner: this._owner,
64
+ repo: this._repo,
65
+ ref: `heads/${branch}`,
66
+ sha: newCommitData.sha,
67
+ });
68
+ }
69
+ async createBranch(branchName, fromBranch = 'main') {
70
+ const { data: refData } = await this._octokit.git.getRef({
71
+ owner: this._owner,
72
+ repo: this._repo,
73
+ ref: `heads/${fromBranch}`,
74
+ });
75
+ await this._octokit.git.createRef({
76
+ owner: this._owner,
77
+ repo: this._repo,
78
+ ref: `refs/heads/${branchName}`,
79
+ sha: refData.object.sha,
80
+ });
81
+ }
82
+ }
83
+ exports.GithubAdapter = GithubAdapter;
84
+ //# sourceMappingURL=GithubAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GithubAdapter.js","sourceRoot":"","sources":["../src/GithubAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { GithubAdapter } from './GithubAdapter';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GithubAdapter = void 0;
4
+ var GithubAdapter_1 = require("./GithubAdapter");
5
+ Object.defineProperty(exports, "GithubAdapter", { enumerable: true, get: function () { return GithubAdapter_1.GithubAdapter; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iDAA+C;AAAtC,8GAAA,aAAa,OAAA"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@quatrain/code-github",
3
+ "version": "1.1.1",
4
+ "license": "AGPL-3.0-only",
5
+ "description": "GitHub repository adapter",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bun": "src/index.ts",
9
+ "files": [
10
+ "LICENSE.md",
11
+ "src/",
12
+ "dist/",
13
+ "README.md",
14
+ "NOTICE.md"
15
+ ],
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/Quatrain/Core.git",
19
+ "directory": "packages/code-github"
20
+ },
21
+ "author": "Quatrain Développement SAS <developers@quatrain.com>",
22
+ "dependencies": {
23
+ "@octokit/rest": "^20.0.2",
24
+ "@quatrain/code": "^1.1.1",
25
+ "@quatrain/core": "^1.1.52"
26
+ },
27
+ "devDependencies": {
28
+ "@tsconfig/recommended": "^1.0.1",
29
+ "@types/jest": "^29.5.12",
30
+ "@types/node": "^22.10.1",
31
+ "jest": "^29.7.0",
32
+ "jest-node-exports-resolver": "^1.1.6",
33
+ "jest-serial-runner": "^1.2.1",
34
+ "trace-unhandled": "^2.0.1",
35
+ "ts-jest": "^29.4.6",
36
+ "ts-node": "^10.9.1",
37
+ "typescript": "^5.1.5"
38
+ },
39
+ "scripts": {
40
+ "test-ci": "jest --runInBand",
41
+ "build": "tsc",
42
+ "wbuild": "tsc --watch",
43
+ "bump-to": "yarn version"
44
+ },
45
+ "typedoc": {
46
+ "entryPoint": "src/index.ts"
47
+ }
48
+ }
@@ -0,0 +1,101 @@
1
+ import { AbstractRepositoryAdapter, CommitFile } from '@quatrain/code'
2
+ import { Octokit } from '@octokit/rest'
3
+
4
+ export class GithubAdapter extends AbstractRepositoryAdapter {
5
+ protected _octokit: Octokit
6
+ protected _owner: string
7
+ protected _repo: string
8
+
9
+ constructor(auth: string, owner: string, repo: string) {
10
+ super()
11
+ this._octokit = new Octokit({ auth })
12
+ this._owner = owner
13
+ this._repo = repo
14
+ }
15
+
16
+ async pull(branch: string = 'main'): Promise<void> {
17
+ // In a real implementation, this would fetch latest refs
18
+ // Since this adapter is primarily to push changes from Studio, pull might be a no-op or fetch ref.
19
+ await this._octokit.repos.get({
20
+ owner: this._owner,
21
+ repo: this._repo,
22
+ })
23
+ }
24
+
25
+ async push(files: CommitFile[], message: string, branch: string = 'main'): Promise<void> {
26
+ // 1. Get latest commit SHA for branch
27
+ const { data: refData } = await this._octokit.git.getRef({
28
+ owner: this._owner,
29
+ repo: this._repo,
30
+ ref: `heads/${branch}`,
31
+ })
32
+ const commitSha = refData.object.sha
33
+
34
+ // 2. Get commit tree
35
+ const { data: commitData } = await this._octokit.git.getCommit({
36
+ owner: this._owner,
37
+ repo: this._repo,
38
+ commit_sha: commitSha,
39
+ })
40
+ const baseTreeSha = commitData.tree.sha
41
+
42
+ // 3. Create blobs and tree array
43
+ const tree = await Promise.all(
44
+ files.map(async (file) => {
45
+ const { data: blobData } = await this._octokit.git.createBlob({
46
+ owner: this._owner,
47
+ repo: this._repo,
48
+ content: file.content,
49
+ encoding: 'utf-8',
50
+ })
51
+
52
+ return {
53
+ path: file.path,
54
+ mode: '100644' as const,
55
+ type: 'blob' as const,
56
+ sha: blobData.sha,
57
+ }
58
+ })
59
+ )
60
+
61
+ // 4. Create new tree
62
+ const { data: treeData } = await this._octokit.git.createTree({
63
+ owner: this._owner,
64
+ repo: this._repo,
65
+ tree,
66
+ base_tree: baseTreeSha,
67
+ })
68
+
69
+ // 5. Create new commit
70
+ const { data: newCommitData } = await this._octokit.git.createCommit({
71
+ owner: this._owner,
72
+ repo: this._repo,
73
+ message,
74
+ tree: treeData.sha,
75
+ parents: [commitSha],
76
+ })
77
+
78
+ // 6. Update ref
79
+ await this._octokit.git.updateRef({
80
+ owner: this._owner,
81
+ repo: this._repo,
82
+ ref: `heads/${branch}`,
83
+ sha: newCommitData.sha,
84
+ })
85
+ }
86
+
87
+ async createBranch(branchName: string, fromBranch: string = 'main'): Promise<void> {
88
+ const { data: refData } = await this._octokit.git.getRef({
89
+ owner: this._owner,
90
+ repo: this._repo,
91
+ ref: `heads/${fromBranch}`,
92
+ })
93
+
94
+ await this._octokit.git.createRef({
95
+ owner: this._owner,
96
+ repo: this._repo,
97
+ ref: `refs/heads/${branchName}`,
98
+ sha: refData.object.sha,
99
+ })
100
+ }
101
+ }
@@ -0,0 +1,38 @@
1
+ import { GithubAdapter } from '../GithubAdapter'
2
+
3
+ jest.mock('@octokit/rest', () => ({
4
+ Octokit: jest.fn().mockImplementation(() => ({
5
+ repos: {
6
+ get: jest.fn().mockResolvedValue({ data: {} })
7
+ },
8
+ git: {
9
+ getRef: jest.fn().mockResolvedValue({ data: { object: { sha: 'base-sha' } } }),
10
+ getCommit: jest.fn().mockResolvedValue({ data: { tree: { sha: 'tree-sha' } } }),
11
+ createBlob: jest.fn().mockResolvedValue({ data: { sha: 'blob-sha' } }),
12
+ createTree: jest.fn().mockResolvedValue({ data: { sha: 'new-tree-sha' } }),
13
+ createCommit: jest.fn().mockResolvedValue({ data: { sha: 'new-commit-sha' } }),
14
+ updateRef: jest.fn().mockResolvedValue({ data: {} }),
15
+ createRef: jest.fn().mockResolvedValue({ data: {} })
16
+ }
17
+ }))
18
+ }))
19
+
20
+ describe('GithubAdapter', () => {
21
+ let adapter: GithubAdapter
22
+
23
+ beforeEach(() => {
24
+ adapter = new GithubAdapter('fake-token', 'owner', 'repo')
25
+ })
26
+
27
+ it('should fetch repo on pull', async () => {
28
+ await expect(adapter.pull('main')).resolves.not.toThrow()
29
+ })
30
+
31
+ it('should push files', async () => {
32
+ await expect(adapter.push([{ path: 'test.txt', content: 'hello' }], 'commit msg')).resolves.not.toThrow()
33
+ })
34
+
35
+ it('should create branch', async () => {
36
+ await expect(adapter.createBranch('new-feature')).resolves.not.toThrow()
37
+ })
38
+ })
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { GithubAdapter } from './GithubAdapter'