GitRoot
Craft your forge, Build your project, Grow your community freely
1// SPDX-FileCopyrightText: 2025 Romain Maneschi <romain@gitroot.dev>
2//
3// SPDX-License-Identifier: MIT
4
5import { JSON } from "json-as";
6import { HttpRequest, HttpResponse, Iterator } from "./server";
7import { FS, FsBaseCache, FsBaseWebcontent, FsBaseWorktree } from "./src/fs";
8import { HttpClient, needServer } from "./src/httpclient";
9import {
10 _call,
11 _canCall,
12 _commitAll,
13 _commits,
14 _diffWithParent,
15 _exec,
16 _forgeConf,
17 _httpClient,
18 _log,
19 _logError,
20 _merge,
21 _report,
22} from "./src/imports";
23import { Call, CallRes } from "./src/model/call";
24import { Commit } from "./src/model/commit";
25import { Exec, ExecStatus } from "./src/model/exec";
26import { ForgeConf } from "./src/model/forgeconf";
27import { PluginRun } from "./src/model/pluginrun";
28import { Report, ReportToGitroot } from "./src/model/report";
29import { exportFuncCallback, Server } from "./src/model/server";
30import { Plugin, PluginReporter } from "./src/plugin";
31
32export * from "./src/index";
33
34export let __server: server | null = null;
35
36export function Register(
37 run: Array<PluginRun>,
38 p: (server: Server) => Plugin,
39): void {
40 const s = new server();
41 s.plugin = p(s);
42 s.run = run;
43 __server = s;
44}
45
46class server implements Server, needServer {
47 private worktreeFS: FS = new FS(FsBaseWorktree);
48 private webcontentFS: FS = new FS(FsBaseWebcontent);
49 private cacheFS: FS = new FS(FsBaseCache);
50 private exportedFuncs: Map<string, exportFuncCallback> = new Map<
51 string,
52 exportFuncCallback
53 >();
54
55 plugin: Plugin | null = null;
56 run: Array<PluginRun> = [];
57 pluginOption: PluginReporter | null = null;
58
59 addPluginOption(opt: PluginReporter): void {
60 this.pluginOption = opt;
61 }
62
63 getExportedFuncs(name: string): exportFuncCallback {
64 return this.exportedFuncs.get(name);
65 }
66
67 forgeConf(): ForgeConf {
68 const ptrSize = _forgeConf();
69 const ptr = u32((ptrSize >> 32) & 0xffffffff);
70 const size = u32(ptrSize & 0xffffffff);
71 return JSON.parse<ForgeConf>(String.UTF8.decodeUnsafe(ptr, size));
72 }
73
74 worktree(): FS {
75 return this.worktreeFS;
76 }
77
78 webcontent(): FS {
79 return this.webcontentFS;
80 }
81
82 cache(): FS {
83 return this.cacheFS;
84 }
85
86 commitAllIfNeeded(message: string): void {
87 _commitAll(message);
88 }
89
90 diffWithParent(
91 hash: string,
92 oldFilepath: string,
93 newFilepath: string,
94 ): string {
95 const ptrSize = _diffWithParent(hash, oldFilepath, newFilepath);
96 const ptr = u32((ptrSize >> 32) & 0xffffffff);
97 const size = u32(ptrSize & 0xffffffff);
98 return String.UTF8.decodeUnsafe(ptr, size);
99 }
100
101 merge(from: string, to: string): void {
102 _merge(from, to);
103 }
104
105 log(message: string): void {
106 _log(message);
107 }
108
109 logError(message: string, error: string): void {
110 _logError(message, error);
111 }
112
113 commits(from: string, to: string): Array<Commit> {
114 const ptrSize = _commits(from, to);
115 const ptr = u32((ptrSize >> 32) & 0xffffffff);
116 const size = u32(ptrSize & 0xffffffff);
117 return JSON.parse<Array<Commit>>(String.UTF8.decodeUnsafe(ptr, size));
118 }
119
120 exec(exec: Exec): ExecStatus {
121 const execJson = JSON.stringify(exec);
122 const ptrSize = _exec(execJson);
123 const ptr = u32((ptrSize >> 32) & 0xffffffff);
124 const size = u32(ptrSize & 0xffffffff);
125 return JSON.parse<ExecStatus>(String.UTF8.decodeUnsafe(ptr, size));
126 }
127
128 report(level: string, content: Array<string>): void {
129 const reportMarshalled = JSON.stringify(
130 new ReportToGitroot(level, content),
131 );
132 _report(reportMarshalled);
133 }
134
135 reportToPlugin(iteratorName: string): void {
136 if (this.pluginOption != null) {
137 this.pluginOption!.report(new Iterator<Report>(iteratorName));
138 }
139 }
140
141 exportFunc(name: string, callback: exportFuncCallback): void {
142 this.exportedFuncs.set(name, callback);
143 }
144
145 canCallFunc(plugin: string, name: string, args: Map<string, string>): bool {
146 const call = new Call(plugin, name, args);
147 const callJson = JSON.stringify(call);
148 return _canCall(callJson) != 0;
149 }
150
151 callFunc(plugin: string, name: string, args: Map<string, string>): CallRes {
152 const call = new Call(plugin, name, args);
153 const callJson = JSON.stringify(call);
154 const ptrSize = _call(callJson);
155 const ptrRes = u32(ptrSize >> 32);
156 const sizeRes = u32(ptrSize);
157 const res = String.UTF8.decodeUnsafe(ptrRes, sizeRes);
158 return JSON.parse<CallRes>(res);
159 }
160
161 httpClient(header: Map<string, Array<string>>): HttpClient {
162 return new HttpClient(this, header);
163 }
164
165 doRequest(request: HttpRequest): HttpResponse {
166 const requestJson = JSON.stringify(request);
167 const ptrSize = _httpClient(requestJson);
168 if (ptrSize === 0) {
169 return new HttpResponse(0, "unknown error");
170 }
171 const ptrRes = u32(ptrSize >> 32);
172 const sizeRes = u32(ptrSize);
173 const res = String.UTF8.decodeUnsafe(ptrRes, sizeRes);
174 return JSON.parse<HttpResponse>(res);
175 }
176}