@serve.zone/gitops 2.13.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/.smartconfig.json +114 -0
- package/binary/gitops.ts +4 -0
- package/changelog.md +185 -0
- package/cli.child.js +4 -0
- package/cli.js +4 -0
- package/cli.ts.js +5 -0
- package/deno.json +10 -0
- package/dist_serve/bundle.js +36362 -0
- package/dist_serve/index.html +33 -0
- package/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/cache/classes.cache.cleaner.d.ts +23 -0
- package/dist_ts/cache/classes.cache.cleaner.js +61 -0
- package/dist_ts/cache/classes.cached.document.d.ts +30 -0
- package/dist_ts/cache/classes.cached.document.js +101 -0
- package/dist_ts/cache/classes.cachedb.d.ts +22 -0
- package/dist_ts/cache/classes.cachedb.js +58 -0
- package/dist_ts/cache/classes.secrets.scan.service.d.ts +51 -0
- package/dist_ts/cache/classes.secrets.scan.service.js +237 -0
- package/dist_ts/cache/documents/classes.cached.project.d.ts +13 -0
- package/dist_ts/cache/documents/classes.cached.project.js +101 -0
- package/dist_ts/cache/documents/classes.cached.secret.d.ts +24 -0
- package/dist_ts/cache/documents/classes.cached.secret.js +158 -0
- package/dist_ts/cache/documents/index.d.ts +2 -0
- package/dist_ts/cache/documents/index.js +3 -0
- package/dist_ts/cache/index.d.ts +7 -0
- package/dist_ts/cache/index.js +6 -0
- package/dist_ts/classes/actionlog.d.ts +19 -0
- package/dist_ts/classes/actionlog.js +44 -0
- package/dist_ts/classes/connectionmanager.d.ts +57 -0
- package/dist_ts/classes/connectionmanager.js +247 -0
- package/dist_ts/classes/gitopsapp.d.ts +30 -0
- package/dist_ts/classes/gitopsapp.js +101 -0
- package/dist_ts/classes/jobmanager.d.ts +47 -0
- package/dist_ts/classes/jobmanager.js +301 -0
- package/dist_ts/classes/jobrunners/autobookstackdocs.runner.d.ts +29 -0
- package/dist_ts/classes/jobrunners/autobookstackdocs.runner.js +361 -0
- package/dist_ts/classes/jobrunners/base.jobrunner.d.ts +14 -0
- package/dist_ts/classes/jobrunners/base.jobrunner.js +3 -0
- package/dist_ts/classes/jobrunners/index.d.ts +5 -0
- package/dist_ts/classes/jobrunners/index.js +14 -0
- package/dist_ts/classes/managedsecrets.manager.d.ts +47 -0
- package/dist_ts/classes/managedsecrets.manager.js +247 -0
- package/dist_ts/classes/syncmanager.d.ts +189 -0
- package/dist_ts/classes/syncmanager.js +1787 -0
- package/dist_ts/index.d.ts +6 -0
- package/dist_ts/index.js +32 -0
- package/dist_ts/logging.d.ts +49 -0
- package/dist_ts/logging.js +134 -0
- package/dist_ts/opsserver/classes.opsserver.d.ts +25 -0
- package/dist_ts/opsserver/classes.opsserver.js +70 -0
- package/dist_ts/opsserver/handlers/actionlog.handler.d.ts +9 -0
- package/dist_ts/opsserver/handlers/actionlog.handler.js +24 -0
- package/dist_ts/opsserver/handlers/actions.handler.d.ts +9 -0
- package/dist_ts/opsserver/handlers/actions.handler.js +38 -0
- package/dist_ts/opsserver/handlers/admin.handler.d.ts +19 -0
- package/dist_ts/opsserver/handlers/admin.handler.js +96 -0
- package/dist_ts/opsserver/handlers/connections.handler.d.ts +10 -0
- package/dist_ts/opsserver/handlers/connections.handler.js +109 -0
- package/dist_ts/opsserver/handlers/groups.handler.d.ts +9 -0
- package/dist_ts/opsserver/handlers/groups.handler.js +24 -0
- package/dist_ts/opsserver/handlers/index.d.ts +13 -0
- package/dist_ts/opsserver/handlers/index.js +14 -0
- package/dist_ts/opsserver/handlers/jobs.handler.d.ts +16 -0
- package/dist_ts/opsserver/handlers/jobs.handler.js +146 -0
- package/dist_ts/opsserver/handlers/logs.handler.d.ts +9 -0
- package/dist_ts/opsserver/handlers/logs.handler.js +21 -0
- package/dist_ts/opsserver/handlers/managedsecrets.handler.d.ts +11 -0
- package/dist_ts/opsserver/handlers/managedsecrets.handler.js +110 -0
- package/dist_ts/opsserver/handlers/pipelines.handler.d.ts +31 -0
- package/dist_ts/opsserver/handlers/pipelines.handler.js +204 -0
- package/dist_ts/opsserver/handlers/projects.handler.d.ts +9 -0
- package/dist_ts/opsserver/handlers/projects.handler.js +24 -0
- package/dist_ts/opsserver/handlers/secrets.handler.d.ts +10 -0
- package/dist_ts/opsserver/handlers/secrets.handler.js +171 -0
- package/dist_ts/opsserver/handlers/sync.handler.d.ts +16 -0
- package/dist_ts/opsserver/handlers/sync.handler.js +166 -0
- package/dist_ts/opsserver/handlers/webhook.handler.d.ts +7 -0
- package/dist_ts/opsserver/handlers/webhook.handler.js +55 -0
- package/dist_ts/opsserver/helpers/guards.d.ts +5 -0
- package/dist_ts/opsserver/helpers/guards.js +12 -0
- package/dist_ts/opsserver/index.d.ts +1 -0
- package/dist_ts/opsserver/index.js +2 -0
- package/dist_ts/paths.d.ts +9 -0
- package/dist_ts/paths.js +13 -0
- package/dist_ts/plugins.d.ts +25 -0
- package/dist_ts/plugins.js +32 -0
- package/dist_ts/providers/classes.baseprovider.d.ts +51 -0
- package/dist_ts/providers/classes.baseprovider.js +17 -0
- package/dist_ts/providers/classes.giteaprovider.d.ts +40 -0
- package/dist_ts/providers/classes.giteaprovider.js +224 -0
- package/dist_ts/providers/classes.gitlabprovider.d.ts +39 -0
- package/dist_ts/providers/classes.gitlabprovider.js +207 -0
- package/dist_ts/providers/index.d.ts +3 -0
- package/dist_ts/providers/index.js +4 -0
- package/dist_ts/storage/classes.storagemanager.d.ts +33 -0
- package/dist_ts/storage/classes.storagemanager.js +135 -0
- package/dist_ts/storage/index.d.ts +2 -0
- package/dist_ts/storage/index.js +2 -0
- package/dist_ts/timers.d.ts +4 -0
- package/dist_ts/timers.js +24 -0
- package/dist_ts_bundled/bundle.d.ts +4 -0
- package/dist_ts_bundled/bundle.js +12 -0
- package/dist_ts_interfaces/data/actionlog.d.ts +12 -0
- package/dist_ts_interfaces/data/actionlog.js +2 -0
- package/dist_ts_interfaces/data/branch.d.ts +8 -0
- package/dist_ts_interfaces/data/branch.js +2 -0
- package/dist_ts_interfaces/data/connection.d.ts +12 -0
- package/dist_ts_interfaces/data/connection.js +2 -0
- package/dist_ts_interfaces/data/group.d.ts +10 -0
- package/dist_ts_interfaces/data/group.js +2 -0
- package/dist_ts_interfaces/data/identity.d.ts +7 -0
- package/dist_ts_interfaces/data/identity.js +2 -0
- package/dist_ts_interfaces/data/index.d.ts +11 -0
- package/dist_ts_interfaces/data/index.js +12 -0
- package/dist_ts_interfaces/data/job.d.ts +37 -0
- package/dist_ts_interfaces/data/job.js +2 -0
- package/dist_ts_interfaces/data/managedsecret.d.ts +37 -0
- package/dist_ts_interfaces/data/managedsecret.js +2 -0
- package/dist_ts_interfaces/data/pipeline.d.ts +22 -0
- package/dist_ts_interfaces/data/pipeline.js +2 -0
- package/dist_ts_interfaces/data/project.d.ts +12 -0
- package/dist_ts_interfaces/data/project.js +2 -0
- package/dist_ts_interfaces/data/secret.d.ts +11 -0
- package/dist_ts_interfaces/data/secret.js +2 -0
- package/dist_ts_interfaces/data/sync.d.ts +34 -0
- package/dist_ts_interfaces/data/sync.js +2 -0
- package/dist_ts_interfaces/index.d.ts +5 -0
- package/dist_ts_interfaces/index.js +8 -0
- package/dist_ts_interfaces/plugins.d.ts +2 -0
- package/dist_ts_interfaces/plugins.js +4 -0
- package/dist_ts_interfaces/requests/actionlog.d.ts +15 -0
- package/dist_ts_interfaces/requests/actionlog.js +3 -0
- package/dist_ts_interfaces/requests/actions.d.ts +31 -0
- package/dist_ts_interfaces/requests/actions.js +3 -0
- package/dist_ts_interfaces/requests/admin.d.ts +31 -0
- package/dist_ts_interfaces/requests/admin.js +3 -0
- package/dist_ts_interfaces/requests/connections.d.ts +71 -0
- package/dist_ts_interfaces/requests/connections.js +3 -0
- package/dist_ts_interfaces/requests/groups.d.ts +14 -0
- package/dist_ts_interfaces/requests/groups.js +3 -0
- package/dist_ts_interfaces/requests/index.d.ts +13 -0
- package/dist_ts_interfaces/requests/index.js +14 -0
- package/dist_ts_interfaces/requests/jobs.d.ts +86 -0
- package/dist_ts_interfaces/requests/jobs.js +3 -0
- package/dist_ts_interfaces/requests/logs.d.ts +14 -0
- package/dist_ts_interfaces/requests/logs.js +3 -0
- package/dist_ts_interfaces/requests/managedsecrets.d.ts +84 -0
- package/dist_ts_interfaces/requests/managedsecrets.js +3 -0
- package/dist_ts_interfaces/requests/pipelines.d.ts +55 -0
- package/dist_ts_interfaces/requests/pipelines.js +3 -0
- package/dist_ts_interfaces/requests/projects.d.ts +14 -0
- package/dist_ts_interfaces/requests/projects.js +3 -0
- package/dist_ts_interfaces/requests/secrets.d.ts +72 -0
- package/dist_ts_interfaces/requests/secrets.js +3 -0
- package/dist_ts_interfaces/requests/sync.d.ts +120 -0
- package/dist_ts_interfaces/requests/sync.js +3 -0
- package/dist_ts_interfaces/requests/webhook.d.ts +13 -0
- package/dist_ts_interfaces/requests/webhook.js +3 -0
- package/license +21 -0
- package/package.json +81 -0
- package/readme.md +177 -0
- package/readme.todo.md +3 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/cache/classes.cache.cleaner.ts +69 -0
- package/ts/cache/classes.cached.document.ts +57 -0
- package/ts/cache/classes.cachedb.ts +72 -0
- package/ts/cache/classes.secrets.scan.service.ts +267 -0
- package/ts/cache/documents/classes.cached.project.ts +32 -0
- package/ts/cache/documents/classes.cached.secret.ts +81 -0
- package/ts/cache/documents/index.ts +2 -0
- package/ts/cache/index.ts +7 -0
- package/ts/classes/actionlog.ts +57 -0
- package/ts/classes/connectionmanager.ts +263 -0
- package/ts/classes/gitopsapp.ts +128 -0
- package/ts/classes/jobmanager.ts +337 -0
- package/ts/classes/jobrunners/autobookstackdocs.runner.ts +435 -0
- package/ts/classes/jobrunners/base.jobrunner.ts +16 -0
- package/ts/classes/jobrunners/index.ts +17 -0
- package/ts/classes/managedsecrets.manager.ts +322 -0
- package/ts/classes/syncmanager.ts +2117 -0
- package/ts/index.ts +37 -0
- package/ts/logging.ts +162 -0
- package/ts/opsserver/classes.opsserver.ts +86 -0
- package/ts/opsserver/handlers/actionlog.handler.ts +30 -0
- package/ts/opsserver/handlers/actions.handler.ts +50 -0
- package/ts/opsserver/handlers/admin.handler.ts +122 -0
- package/ts/opsserver/handlers/connections.handler.ts +162 -0
- package/ts/opsserver/handlers/groups.handler.ts +32 -0
- package/ts/opsserver/handlers/index.ts +13 -0
- package/ts/opsserver/handlers/jobs.handler.ts +189 -0
- package/ts/opsserver/handlers/logs.handler.ts +29 -0
- package/ts/opsserver/handlers/managedsecrets.handler.ts +158 -0
- package/ts/opsserver/handlers/pipelines.handler.ts +281 -0
- package/ts/opsserver/handlers/projects.handler.ts +32 -0
- package/ts/opsserver/handlers/secrets.handler.ts +224 -0
- package/ts/opsserver/handlers/sync.handler.ts +224 -0
- package/ts/opsserver/handlers/webhook.handler.ts +62 -0
- package/ts/opsserver/helpers/guards.ts +16 -0
- package/ts/opsserver/index.ts +1 -0
- package/ts/paths.ts +19 -0
- package/ts/plugins.ts +38 -0
- package/ts/providers/classes.baseprovider.ts +99 -0
- package/ts/providers/classes.giteaprovider.ts +279 -0
- package/ts/providers/classes.gitlabprovider.ts +265 -0
- package/ts/providers/index.ts +3 -0
- package/ts/storage/classes.storagemanager.ts +144 -0
- package/ts/storage/index.ts +2 -0
- package/ts/timers.ts +34 -0
- package/ts_interfaces/data/actionlog.ts +13 -0
- package/ts_interfaces/data/branch.ts +9 -0
- package/ts_interfaces/data/connection.ts +13 -0
- package/ts_interfaces/data/group.ts +10 -0
- package/ts_interfaces/data/identity.ts +7 -0
- package/ts_interfaces/data/index.ts +11 -0
- package/ts_interfaces/data/job.ts +42 -0
- package/ts_interfaces/data/managedsecret.ts +41 -0
- package/ts_interfaces/data/pipeline.ts +32 -0
- package/ts_interfaces/data/project.ts +12 -0
- package/ts_interfaces/data/secret.ts +11 -0
- package/ts_interfaces/data/sync.ts +37 -0
- package/ts_interfaces/index.ts +9 -0
- package/ts_interfaces/plugins.ts +6 -0
- package/ts_interfaces/requests/actionlog.ts +19 -0
- package/ts_interfaces/requests/actions.ts +39 -0
- package/ts_interfaces/requests/admin.ts +43 -0
- package/ts_interfaces/requests/connections.ts +95 -0
- package/ts_interfaces/requests/groups.ts +18 -0
- package/ts_interfaces/requests/index.ts +13 -0
- package/ts_interfaces/requests/jobs.ts +118 -0
- package/ts_interfaces/requests/logs.ts +18 -0
- package/ts_interfaces/requests/managedsecrets.ts +112 -0
- package/ts_interfaces/requests/pipelines.ts +71 -0
- package/ts_interfaces/requests/projects.ts +18 -0
- package/ts_interfaces/requests/secrets.ts +92 -0
- package/ts_interfaces/requests/sync.ts +157 -0
- package/ts_interfaces/requests/webhook.ts +18 -0
- package/ts_web/00_commitinfo_data.ts +8 -0
- package/ts_web/appstate.ts +1251 -0
- package/ts_web/elements/gitops-dashboard.ts +350 -0
- package/ts_web/elements/index.ts +10 -0
- package/ts_web/elements/shared/css.ts +29 -0
- package/ts_web/elements/shared/index.ts +1 -0
- package/ts_web/elements/views/actionlog/index.ts +101 -0
- package/ts_web/elements/views/actions/index.ts +209 -0
- package/ts_web/elements/views/buildlog/index.ts +196 -0
- package/ts_web/elements/views/connections/index.ts +260 -0
- package/ts_web/elements/views/groups/index.ts +134 -0
- package/ts_web/elements/views/jobs/index.ts +424 -0
- package/ts_web/elements/views/managedsecrets/index.ts +502 -0
- package/ts_web/elements/views/overview/index.ts +86 -0
- package/ts_web/elements/views/pipelines/index.ts +561 -0
- package/ts_web/elements/views/projects/index.ts +149 -0
- package/ts_web/elements/views/secrets/index.ts +310 -0
- package/ts_web/elements/views/sync/index.ts +512 -0
- package/ts_web/index.ts +7 -0
- package/ts_web/plugins.ts +15 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
|
|
3
|
+
export type TStorageBackend = 'filesystem' | 'memory';
|
|
4
|
+
|
|
5
|
+
export interface IStorageConfig {
|
|
6
|
+
backend?: TStorageBackend;
|
|
7
|
+
fsPath?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const isNotFoundError = (error: unknown): boolean => {
|
|
11
|
+
return error instanceof Error && (error as NodeJS.ErrnoException).code === 'ENOENT';
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Key-value storage abstraction with filesystem and memory backends.
|
|
16
|
+
* Keys must start with '/' and are normalized (no '..', no double slashes).
|
|
17
|
+
*/
|
|
18
|
+
export class StorageManager {
|
|
19
|
+
private backend: TStorageBackend;
|
|
20
|
+
private fsPath: string;
|
|
21
|
+
private memoryStore: Map<string, string>;
|
|
22
|
+
|
|
23
|
+
constructor(config: IStorageConfig = {}) {
|
|
24
|
+
this.backend = config.backend ?? 'filesystem';
|
|
25
|
+
this.fsPath = config.fsPath ?? './storage';
|
|
26
|
+
this.memoryStore = new Map();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Normalize and validate a storage key.
|
|
31
|
+
*/
|
|
32
|
+
private normalizeKey(key: string): string {
|
|
33
|
+
if (!key.startsWith('/')) {
|
|
34
|
+
throw new Error(`Storage key must start with '/': ${key}`);
|
|
35
|
+
}
|
|
36
|
+
// Strip '..' segments and normalize double slashes
|
|
37
|
+
const segments = key.split('/').filter((s) => s !== '' && s !== '..');
|
|
38
|
+
return '/' + segments.join('/');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Resolve a key to a filesystem path.
|
|
43
|
+
*/
|
|
44
|
+
private keyToPath(key: string): string {
|
|
45
|
+
const normalized = this.normalizeKey(key);
|
|
46
|
+
return plugins.path.join(this.fsPath, ...normalized.split('/').filter(Boolean));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async get(key: string): Promise<string | null> {
|
|
50
|
+
const normalized = this.normalizeKey(key);
|
|
51
|
+
if (this.backend === 'memory') {
|
|
52
|
+
return this.memoryStore.get(normalized) ?? null;
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
return await plugins.fs.readFile(this.keyToPath(normalized), 'utf8');
|
|
56
|
+
} catch (err) {
|
|
57
|
+
if (isNotFoundError(err)) return null;
|
|
58
|
+
throw err;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async set(key: string, value: string): Promise<void> {
|
|
63
|
+
const normalized = this.normalizeKey(key);
|
|
64
|
+
if (this.backend === 'memory') {
|
|
65
|
+
this.memoryStore.set(normalized, value);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const filePath = this.keyToPath(normalized);
|
|
69
|
+
const dir = plugins.path.dirname(filePath);
|
|
70
|
+
await plugins.fs.mkdir(dir, { recursive: true });
|
|
71
|
+
// Atomic write: write to temp then rename
|
|
72
|
+
const tmpPath = filePath + '.tmp';
|
|
73
|
+
await plugins.fs.writeFile(tmpPath, value, 'utf8');
|
|
74
|
+
await plugins.fs.rename(tmpPath, filePath);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async delete(key: string): Promise<boolean> {
|
|
78
|
+
const normalized = this.normalizeKey(key);
|
|
79
|
+
if (this.backend === 'memory') {
|
|
80
|
+
return this.memoryStore.delete(normalized);
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
await plugins.fs.rm(this.keyToPath(normalized));
|
|
84
|
+
return true;
|
|
85
|
+
} catch (err) {
|
|
86
|
+
if (isNotFoundError(err)) return false;
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async exists(key: string): Promise<boolean> {
|
|
92
|
+
const normalized = this.normalizeKey(key);
|
|
93
|
+
if (this.backend === 'memory') {
|
|
94
|
+
return this.memoryStore.has(normalized);
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
await plugins.fs.stat(this.keyToPath(normalized));
|
|
98
|
+
return true;
|
|
99
|
+
} catch (err) {
|
|
100
|
+
if (isNotFoundError(err)) return false;
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* List keys under a given prefix.
|
|
107
|
+
*/
|
|
108
|
+
async list(prefix: string): Promise<string[]> {
|
|
109
|
+
const normalized = this.normalizeKey(prefix);
|
|
110
|
+
if (this.backend === 'memory') {
|
|
111
|
+
const keys: string[] = [];
|
|
112
|
+
for (const key of this.memoryStore.keys()) {
|
|
113
|
+
if (key.startsWith(normalized)) {
|
|
114
|
+
keys.push(key);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return keys.sort();
|
|
118
|
+
}
|
|
119
|
+
const dirPath = this.keyToPath(normalized);
|
|
120
|
+
const keys: string[] = [];
|
|
121
|
+
try {
|
|
122
|
+
const entries = await plugins.fs.readdir(dirPath, { withFileTypes: true });
|
|
123
|
+
for (const entry of entries) {
|
|
124
|
+
if (entry.isFile()) {
|
|
125
|
+
keys.push(normalized.replace(/\/$/, '') + '/' + entry.name);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
} catch (err) {
|
|
129
|
+
if (isNotFoundError(err)) return [];
|
|
130
|
+
throw err;
|
|
131
|
+
}
|
|
132
|
+
return keys.sort();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async getJSON<T>(key: string): Promise<T | null> {
|
|
136
|
+
const raw = await this.get(key);
|
|
137
|
+
if (raw === null) return null;
|
|
138
|
+
return JSON.parse(raw) as T;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async setJSON(key: string, value: unknown): Promise<void> {
|
|
142
|
+
await this.set(key, JSON.stringify(value, null, 2));
|
|
143
|
+
}
|
|
144
|
+
}
|
package/ts/timers.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const MAX_TIMER_DELAY_MS = 2_147_483_647;
|
|
2
|
+
const MS_PER_MINUTE = 60_000;
|
|
3
|
+
|
|
4
|
+
export const MAX_INTERVAL_MINUTES = Math.floor(MAX_TIMER_DELAY_MS / MS_PER_MINUTE);
|
|
5
|
+
|
|
6
|
+
export const validateIntervalMinutes = (
|
|
7
|
+
value: number | undefined,
|
|
8
|
+
label = 'intervalMinutes',
|
|
9
|
+
fallback?: number,
|
|
10
|
+
): number => {
|
|
11
|
+
const intervalMinutes = value ?? fallback;
|
|
12
|
+
if (
|
|
13
|
+
intervalMinutes === undefined ||
|
|
14
|
+
!Number.isFinite(intervalMinutes) ||
|
|
15
|
+
!Number.isInteger(intervalMinutes) ||
|
|
16
|
+
intervalMinutes < 1 ||
|
|
17
|
+
intervalMinutes > MAX_INTERVAL_MINUTES
|
|
18
|
+
) {
|
|
19
|
+
throw new Error(`${label} must be an integer between 1 and ${MAX_INTERVAL_MINUTES}`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return intervalMinutes;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const intervalMinutesToMs = (value: number, label = 'intervalMinutes'): number => {
|
|
26
|
+
return validateIntervalMinutes(value, label) * MS_PER_MINUTE;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const unrefTimer = (timer: ReturnType<typeof setInterval> | ReturnType<typeof setTimeout>): void => {
|
|
30
|
+
const unref = (timer as { unref?: () => void }).unref;
|
|
31
|
+
if (typeof unref === 'function') {
|
|
32
|
+
unref.call(timer);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type TActionType = 'create' | 'update' | 'delete' | 'pause' | 'resume' | 'test' | 'scan' | 'sync' | 'obsolete' | 'push' | 'run';
|
|
2
|
+
export type TActionEntity = 'connection' | 'secret' | 'pipeline' | 'sync' | 'managed-secret' | 'job';
|
|
3
|
+
|
|
4
|
+
export interface IActionLogEntry {
|
|
5
|
+
id: string;
|
|
6
|
+
timestamp: number;
|
|
7
|
+
actionType: TActionType;
|
|
8
|
+
entityType: TActionEntity;
|
|
9
|
+
entityId: string;
|
|
10
|
+
entityName: string;
|
|
11
|
+
details: string;
|
|
12
|
+
username: string;
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type TProviderType = 'gitea' | 'gitlab';
|
|
2
|
+
|
|
3
|
+
export interface IProviderConnection {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
providerType: TProviderType;
|
|
7
|
+
baseUrl: string;
|
|
8
|
+
token: string;
|
|
9
|
+
createdAt: number;
|
|
10
|
+
status: 'connected' | 'disconnected' | 'error' | 'paused';
|
|
11
|
+
groupFilter?: string; // Restricts which repos this connection can see (e.g. "foss.global")
|
|
12
|
+
groupFilterId?: string; // Resolved filter group ID (numeric for GitLab, org name for Gitea)
|
|
13
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './identity.js';
|
|
2
|
+
export * from './connection.js';
|
|
3
|
+
export * from './project.js';
|
|
4
|
+
export * from './group.js';
|
|
5
|
+
export * from './branch.js';
|
|
6
|
+
export * from './secret.js';
|
|
7
|
+
export * from './pipeline.js';
|
|
8
|
+
export * from './actionlog.js';
|
|
9
|
+
export * from './sync.js';
|
|
10
|
+
export * from './managedsecret.js';
|
|
11
|
+
export * from './job.js';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export type TJobType = 'autobookstackdocs';
|
|
2
|
+
|
|
3
|
+
export type TJobStatus = 'active' | 'paused' | 'error';
|
|
4
|
+
|
|
5
|
+
export interface IBookstackTarget {
|
|
6
|
+
baseUrl: string;
|
|
7
|
+
tokenId: string;
|
|
8
|
+
tokenSecret: string; // "keychain:<id>" sentinel in storage, real value in memory
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface IAutoBookstackDocsConfig {
|
|
12
|
+
sourceConnectionIds: string[];
|
|
13
|
+
bookstackTarget: IBookstackTarget;
|
|
14
|
+
filePaths: string[]; // root-level files to sync, e.g. ["readme.md"]
|
|
15
|
+
docDirs: string[]; // directories to scan for .md files, e.g. ["docs"]
|
|
16
|
+
includeGroups?: string[];
|
|
17
|
+
excludeGroups?: string[];
|
|
18
|
+
propagateDeletes?: boolean; // remove stale shelves/books/pages (default false)
|
|
19
|
+
syncVisibility?: boolean; // map git visibility to BookStack permissions (default false)
|
|
20
|
+
privateRoleId?: number; // BookStack role ID for private content access
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface IJobLogEntry {
|
|
24
|
+
timestamp: number;
|
|
25
|
+
level: 'info' | 'warn' | 'error' | 'success' | 'debug';
|
|
26
|
+
message: string;
|
|
27
|
+
source?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface IJobConfig {
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
jobType: TJobType;
|
|
34
|
+
status: TJobStatus;
|
|
35
|
+
intervalMinutes: number;
|
|
36
|
+
lastRunAt: number;
|
|
37
|
+
lastRunDurationMs?: number;
|
|
38
|
+
lastRunError?: string;
|
|
39
|
+
createdAt: number;
|
|
40
|
+
updatedAt: number;
|
|
41
|
+
autoBookstackDocsConfig?: IAutoBookstackDocsConfig;
|
|
42
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface IManagedSecretTarget {
|
|
2
|
+
connectionId: string;
|
|
3
|
+
scope: 'project' | 'group';
|
|
4
|
+
scopeId: string;
|
|
5
|
+
scopeName: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type TPushStatus = 'pending' | 'success' | 'error';
|
|
9
|
+
|
|
10
|
+
export interface IManagedSecretTargetStatus {
|
|
11
|
+
connectionId: string;
|
|
12
|
+
scope: 'project' | 'group';
|
|
13
|
+
scopeId: string;
|
|
14
|
+
scopeName: string;
|
|
15
|
+
status: TPushStatus;
|
|
16
|
+
error?: string;
|
|
17
|
+
lastPushedAt?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface IManagedSecret {
|
|
21
|
+
id: string;
|
|
22
|
+
key: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
targets: IManagedSecretTarget[];
|
|
25
|
+
targetStatuses: IManagedSecretTargetStatus[];
|
|
26
|
+
createdAt: number;
|
|
27
|
+
updatedAt: number;
|
|
28
|
+
lastPushedAt?: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface IManagedSecretStored {
|
|
32
|
+
id: string;
|
|
33
|
+
key: string;
|
|
34
|
+
description?: string;
|
|
35
|
+
value: string;
|
|
36
|
+
targets: IManagedSecretTarget[];
|
|
37
|
+
targetStatuses: IManagedSecretTargetStatus[];
|
|
38
|
+
createdAt: number;
|
|
39
|
+
updatedAt: number;
|
|
40
|
+
lastPushedAt?: number;
|
|
41
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type TPipelineStatus =
|
|
2
|
+
| 'pending'
|
|
3
|
+
| 'running'
|
|
4
|
+
| 'success'
|
|
5
|
+
| 'failed'
|
|
6
|
+
| 'canceled'
|
|
7
|
+
| 'skipped'
|
|
8
|
+
| 'waiting'
|
|
9
|
+
| 'manual';
|
|
10
|
+
|
|
11
|
+
export interface IPipeline {
|
|
12
|
+
id: string;
|
|
13
|
+
projectId: string;
|
|
14
|
+
projectName: string;
|
|
15
|
+
connectionId: string;
|
|
16
|
+
status: TPipelineStatus;
|
|
17
|
+
ref: string;
|
|
18
|
+
sha: string;
|
|
19
|
+
webUrl: string;
|
|
20
|
+
duration: number;
|
|
21
|
+
createdAt: string;
|
|
22
|
+
source: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface IPipelineJob {
|
|
26
|
+
id: string;
|
|
27
|
+
pipelineId: string;
|
|
28
|
+
name: string;
|
|
29
|
+
stage: string;
|
|
30
|
+
status: TPipelineStatus;
|
|
31
|
+
duration: number;
|
|
32
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export type TSyncStatus = 'active' | 'paused' | 'error';
|
|
2
|
+
|
|
3
|
+
export interface ISyncConfig {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
sourceConnectionId: string;
|
|
7
|
+
targetConnectionId: string;
|
|
8
|
+
targetGroupOffset?: string; // Path prefix for target repos (e.g. "mirror/gitlab")
|
|
9
|
+
intervalMinutes: number; // Default 5
|
|
10
|
+
status: TSyncStatus;
|
|
11
|
+
lastSyncAt: number;
|
|
12
|
+
lastSyncError?: string;
|
|
13
|
+
lastSyncDurationMs?: number;
|
|
14
|
+
reposSynced: number;
|
|
15
|
+
enforceDelete: boolean; // When true, stale target repos are moved to obsolete
|
|
16
|
+
enforceGroupDelete: boolean; // When true, stale target groups/orgs are moved to obsolete
|
|
17
|
+
addMirrorHint?: boolean; // When true, target descriptions get "(This is a mirror of ...)" appended
|
|
18
|
+
useGroupAvatarsForProjects?: boolean; // When true, projects without avatars inherit the group avatar
|
|
19
|
+
createdAt: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ISyncRepoStatus {
|
|
23
|
+
id: string;
|
|
24
|
+
syncConfigId: string;
|
|
25
|
+
sourceFullPath: string; // e.g. "push.rocks/smartstate"
|
|
26
|
+
targetFullPath: string; // e.g. "foss.global/push.rocks/smartstate"
|
|
27
|
+
lastSyncAt: number;
|
|
28
|
+
lastSyncError?: string;
|
|
29
|
+
status: 'synced' | 'error' | 'pending';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface ISyncLogEntry {
|
|
33
|
+
timestamp: number;
|
|
34
|
+
level: 'info' | 'warn' | 'error' | 'success' | 'debug';
|
|
35
|
+
message: string;
|
|
36
|
+
source?: string; // e.g. 'preview', 'sync', 'git', 'api'
|
|
37
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as data from '../data/index.js';
|
|
3
|
+
|
|
4
|
+
export interface IReq_GetActionLog extends plugins.typedrequestInterfaces.implementsTR<
|
|
5
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
6
|
+
IReq_GetActionLog
|
|
7
|
+
> {
|
|
8
|
+
method: 'getActionLog';
|
|
9
|
+
request: {
|
|
10
|
+
identity: data.IIdentity;
|
|
11
|
+
limit?: number;
|
|
12
|
+
offset?: number;
|
|
13
|
+
entityType?: data.TActionEntity;
|
|
14
|
+
};
|
|
15
|
+
response: {
|
|
16
|
+
entries: data.IActionLogEntry[];
|
|
17
|
+
total: number;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as data from '../data/index.js';
|
|
3
|
+
|
|
4
|
+
export interface IReq_ForceScanSecrets extends plugins.typedrequestInterfaces.implementsTR<
|
|
5
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
6
|
+
IReq_ForceScanSecrets
|
|
7
|
+
> {
|
|
8
|
+
method: 'forceScanSecrets';
|
|
9
|
+
request: {
|
|
10
|
+
identity: data.IIdentity;
|
|
11
|
+
};
|
|
12
|
+
response: {
|
|
13
|
+
ok: boolean;
|
|
14
|
+
connectionsScanned: number;
|
|
15
|
+
secretsFound: number;
|
|
16
|
+
errors: string[];
|
|
17
|
+
durationMs: number;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface IReq_GetScanStatus extends plugins.typedrequestInterfaces.implementsTR<
|
|
22
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
23
|
+
IReq_GetScanStatus
|
|
24
|
+
> {
|
|
25
|
+
method: 'getScanStatus';
|
|
26
|
+
request: {
|
|
27
|
+
identity: data.IIdentity;
|
|
28
|
+
};
|
|
29
|
+
response: {
|
|
30
|
+
lastScanTimestamp: number;
|
|
31
|
+
isScanning: boolean;
|
|
32
|
+
lastResult: {
|
|
33
|
+
connectionsScanned: number;
|
|
34
|
+
secretsFound: number;
|
|
35
|
+
errors: string[];
|
|
36
|
+
durationMs: number;
|
|
37
|
+
} | null;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as data from '../data/index.js';
|
|
3
|
+
|
|
4
|
+
export interface IReq_AdminLogin extends plugins.typedrequestInterfaces.implementsTR<
|
|
5
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
6
|
+
IReq_AdminLogin
|
|
7
|
+
> {
|
|
8
|
+
method: 'adminLogin';
|
|
9
|
+
request: {
|
|
10
|
+
username: string;
|
|
11
|
+
password: string;
|
|
12
|
+
};
|
|
13
|
+
response: {
|
|
14
|
+
identity?: data.IIdentity;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface IReq_AdminLogout extends plugins.typedrequestInterfaces.implementsTR<
|
|
19
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
20
|
+
IReq_AdminLogout
|
|
21
|
+
> {
|
|
22
|
+
method: 'adminLogout';
|
|
23
|
+
request: {
|
|
24
|
+
identity: data.IIdentity;
|
|
25
|
+
};
|
|
26
|
+
response: {
|
|
27
|
+
ok: boolean;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface IReq_VerifyIdentity extends plugins.typedrequestInterfaces.implementsTR<
|
|
32
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
33
|
+
IReq_VerifyIdentity
|
|
34
|
+
> {
|
|
35
|
+
method: 'verifyIdentity';
|
|
36
|
+
request: {
|
|
37
|
+
identity: data.IIdentity;
|
|
38
|
+
};
|
|
39
|
+
response: {
|
|
40
|
+
valid: boolean;
|
|
41
|
+
identity?: data.IIdentity;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as data from '../data/index.js';
|
|
3
|
+
|
|
4
|
+
export interface IReq_GetConnections extends plugins.typedrequestInterfaces.implementsTR<
|
|
5
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
6
|
+
IReq_GetConnections
|
|
7
|
+
> {
|
|
8
|
+
method: 'getConnections';
|
|
9
|
+
request: {
|
|
10
|
+
identity: data.IIdentity;
|
|
11
|
+
};
|
|
12
|
+
response: {
|
|
13
|
+
connections: data.IProviderConnection[];
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface IReq_CreateConnection extends plugins.typedrequestInterfaces.implementsTR<
|
|
18
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
19
|
+
IReq_CreateConnection
|
|
20
|
+
> {
|
|
21
|
+
method: 'createConnection';
|
|
22
|
+
request: {
|
|
23
|
+
identity: data.IIdentity;
|
|
24
|
+
name: string;
|
|
25
|
+
providerType: data.TProviderType;
|
|
26
|
+
baseUrl: string;
|
|
27
|
+
token: string;
|
|
28
|
+
groupFilter?: string;
|
|
29
|
+
};
|
|
30
|
+
response: {
|
|
31
|
+
connection: data.IProviderConnection;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface IReq_UpdateConnection extends plugins.typedrequestInterfaces.implementsTR<
|
|
36
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
37
|
+
IReq_UpdateConnection
|
|
38
|
+
> {
|
|
39
|
+
method: 'updateConnection';
|
|
40
|
+
request: {
|
|
41
|
+
identity: data.IIdentity;
|
|
42
|
+
connectionId: string;
|
|
43
|
+
name?: string;
|
|
44
|
+
baseUrl?: string;
|
|
45
|
+
token?: string;
|
|
46
|
+
groupFilter?: string;
|
|
47
|
+
};
|
|
48
|
+
response: {
|
|
49
|
+
connection: data.IProviderConnection;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface IReq_TestConnection extends plugins.typedrequestInterfaces.implementsTR<
|
|
54
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
55
|
+
IReq_TestConnection
|
|
56
|
+
> {
|
|
57
|
+
method: 'testConnection';
|
|
58
|
+
request: {
|
|
59
|
+
identity: data.IIdentity;
|
|
60
|
+
connectionId: string;
|
|
61
|
+
};
|
|
62
|
+
response: {
|
|
63
|
+
ok: boolean;
|
|
64
|
+
error?: string;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface IReq_PauseConnection extends plugins.typedrequestInterfaces.implementsTR<
|
|
69
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
70
|
+
IReq_PauseConnection
|
|
71
|
+
> {
|
|
72
|
+
method: 'pauseConnection';
|
|
73
|
+
request: {
|
|
74
|
+
identity: data.IIdentity;
|
|
75
|
+
connectionId: string;
|
|
76
|
+
paused: boolean;
|
|
77
|
+
};
|
|
78
|
+
response: {
|
|
79
|
+
connection: data.IProviderConnection;
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface IReq_DeleteConnection extends plugins.typedrequestInterfaces.implementsTR<
|
|
84
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
85
|
+
IReq_DeleteConnection
|
|
86
|
+
> {
|
|
87
|
+
method: 'deleteConnection';
|
|
88
|
+
request: {
|
|
89
|
+
identity: data.IIdentity;
|
|
90
|
+
connectionId: string;
|
|
91
|
+
};
|
|
92
|
+
response: {
|
|
93
|
+
ok: boolean;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as plugins from '../plugins.js';
|
|
2
|
+
import * as data from '../data/index.js';
|
|
3
|
+
|
|
4
|
+
export interface IReq_GetGroups extends plugins.typedrequestInterfaces.implementsTR<
|
|
5
|
+
plugins.typedrequestInterfaces.ITypedRequest,
|
|
6
|
+
IReq_GetGroups
|
|
7
|
+
> {
|
|
8
|
+
method: 'getGroups';
|
|
9
|
+
request: {
|
|
10
|
+
identity: data.IIdentity;
|
|
11
|
+
connectionId: string;
|
|
12
|
+
search?: string;
|
|
13
|
+
page?: number;
|
|
14
|
+
};
|
|
15
|
+
response: {
|
|
16
|
+
groups: data.IGroup[];
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './admin.js';
|
|
2
|
+
export * from './connections.js';
|
|
3
|
+
export * from './projects.js';
|
|
4
|
+
export * from './groups.js';
|
|
5
|
+
export * from './secrets.js';
|
|
6
|
+
export * from './pipelines.js';
|
|
7
|
+
export * from './logs.js';
|
|
8
|
+
export * from './webhook.js';
|
|
9
|
+
export * from './actions.js';
|
|
10
|
+
export * from './actionlog.js';
|
|
11
|
+
export * from './sync.js';
|
|
12
|
+
export * from './managedsecrets.js';
|
|
13
|
+
export * from './jobs.js';
|