@serve.zone/gitops 3.0.0 → 3.1.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.
- package/changelog.md +17 -0
- package/deno.json +1 -1
- package/dist_serve/bundle.js +726 -694
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes/connectionmanager.d.ts +5 -1
- package/dist_ts/classes/connectionmanager.js +62 -7
- package/dist_ts/classes/syncmanager.d.ts +40 -0
- package/dist_ts/classes/syncmanager.js +804 -111
- package/dist_ts/classes/syncpath.d.ts +13 -0
- package/dist_ts/classes/syncpath.js +53 -0
- package/dist_ts/opsserver/handlers/connections.handler.js +8 -2
- package/dist_ts/opsserver/handlers/sync.handler.js +5 -1
- package/dist_ts/providers/classes.baseprovider.d.ts +22 -0
- package/dist_ts/providers/classes.baseprovider.js +93 -1
- package/dist_ts/providers/classes.giteaprovider.d.ts +18 -1
- package/dist_ts/providers/classes.giteaprovider.js +236 -1
- package/dist_ts/providers/classes.gitlabprovider.d.ts +16 -1
- package/dist_ts/providers/classes.gitlabprovider.js +235 -1
- package/dist_ts_interfaces/data/artifact.d.ts +39 -0
- package/dist_ts_interfaces/data/artifact.js +2 -0
- package/dist_ts_interfaces/data/connection.d.ts +3 -0
- package/dist_ts_interfaces/data/index.d.ts +1 -0
- package/dist_ts_interfaces/data/index.js +2 -1
- package/dist_ts_interfaces/data/sync.d.ts +21 -0
- package/dist_ts_interfaces/requests/connections.d.ts +6 -0
- package/dist_ts_interfaces/requests/sync.d.ts +4 -0
- package/package.json +3 -3
- package/readme.md +8 -4
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes/connectionmanager.ts +61 -6
- package/ts/classes/syncmanager.ts +1095 -119
- package/ts/classes/syncpath.ts +71 -0
- package/ts/opsserver/handlers/connections.handler.ts +9 -0
- package/ts/opsserver/handlers/sync.handler.ts +4 -0
- package/ts/providers/classes.baseprovider.ts +137 -0
- package/ts/providers/classes.giteaprovider.ts +293 -1
- package/ts/providers/classes.gitlabprovider.ts +292 -1
- package/ts_interfaces/data/artifact.ts +43 -0
- package/ts_interfaces/data/connection.ts +3 -0
- package/ts_interfaces/data/index.ts +1 -0
- package/ts_interfaces/data/sync.ts +22 -0
- package/ts_interfaces/requests/connections.ts +6 -0
- package/ts_interfaces/requests/sync.ts +4 -0
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/appstate.ts +10 -0
- package/ts_web/elements/views/connections/index.ts +26 -0
- package/ts_web/elements/views/sync/index.ts +26 -4
|
@@ -8,6 +8,8 @@ const LEGACY_CONNECTIONS_FILE = './.nogit/connections.json';
|
|
|
8
8
|
const CONNECTIONS_PREFIX = '/connections/';
|
|
9
9
|
const KEYCHAIN_PREFIX = 'keychain:';
|
|
10
10
|
|
|
11
|
+
const getRegistryTokenSecretId = (connectionId: string): string => `${connectionId}:registry`;
|
|
12
|
+
|
|
11
13
|
/**
|
|
12
14
|
* Manages provider connections — persists each connection as an
|
|
13
15
|
* individual JSON file via StorageManager. Tokens are stored in
|
|
@@ -98,6 +100,18 @@ export class ConnectionManager {
|
|
|
98
100
|
// Plaintext token found — auto-migrate to keychain
|
|
99
101
|
await this.migrateTokenToKeychain(conn);
|
|
100
102
|
}
|
|
103
|
+
if (conn.registryToken?.startsWith(KEYCHAIN_PREFIX)) {
|
|
104
|
+
const registrySecretId = conn.registryToken.substring(KEYCHAIN_PREFIX.length);
|
|
105
|
+
const realRegistryToken = await this.smartSecret.getSecret(registrySecretId);
|
|
106
|
+
if (realRegistryToken) {
|
|
107
|
+
conn.registryToken = realRegistryToken;
|
|
108
|
+
} else {
|
|
109
|
+
logger.warn(`Could not retrieve registry token for connection ${conn.id} from keychain`);
|
|
110
|
+
conn.registryToken = undefined;
|
|
111
|
+
}
|
|
112
|
+
} else if (conn.registryToken && conn.registryToken !== '***') {
|
|
113
|
+
await this.migrateRegistryTokenToKeychain(conn);
|
|
114
|
+
}
|
|
101
115
|
this.connections.push(conn);
|
|
102
116
|
}
|
|
103
117
|
}
|
|
@@ -125,21 +139,53 @@ export class ConnectionManager {
|
|
|
125
139
|
}
|
|
126
140
|
}
|
|
127
141
|
|
|
142
|
+
private async migrateRegistryTokenToKeychain(
|
|
143
|
+
conn: interfaces.data.IProviderConnection,
|
|
144
|
+
): Promise<void> {
|
|
145
|
+
try {
|
|
146
|
+
const secretId = getRegistryTokenSecretId(conn.id);
|
|
147
|
+
await this.smartSecret.setSecret(secretId, conn.registryToken!);
|
|
148
|
+
const jsonConn = {
|
|
149
|
+
...conn,
|
|
150
|
+
token: `${KEYCHAIN_PREFIX}${conn.id}`,
|
|
151
|
+
registryToken: `${KEYCHAIN_PREFIX}${secretId}`,
|
|
152
|
+
};
|
|
153
|
+
await this.storageManager.setJSON(`${CONNECTIONS_PREFIX}${conn.id}.json`, jsonConn);
|
|
154
|
+
logger.info(`Migrated registry token for connection "${conn.name}" to keychain`);
|
|
155
|
+
} catch (err) {
|
|
156
|
+
logger.warn(`Failed to migrate registry token for ${conn.id} to keychain: ${err}`);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
128
160
|
private async persistConnection(conn: interfaces.data.IProviderConnection): Promise<void> {
|
|
129
161
|
// Store real token in keychain
|
|
130
162
|
await this.smartSecret.setSecret(conn.id, conn.token);
|
|
163
|
+
if (conn.registryToken) {
|
|
164
|
+
await this.smartSecret.setSecret(getRegistryTokenSecretId(conn.id), conn.registryToken);
|
|
165
|
+
} else {
|
|
166
|
+
await this.smartSecret.deleteSecret(getRegistryTokenSecretId(conn.id));
|
|
167
|
+
}
|
|
131
168
|
// Save JSON with sentinel value
|
|
132
|
-
const jsonConn = {
|
|
169
|
+
const jsonConn = {
|
|
170
|
+
...conn,
|
|
171
|
+
token: `${KEYCHAIN_PREFIX}${conn.id}`,
|
|
172
|
+
registryToken: conn.registryToken ? `${KEYCHAIN_PREFIX}${getRegistryTokenSecretId(conn.id)}` : undefined,
|
|
173
|
+
};
|
|
133
174
|
await this.storageManager.setJSON(`${CONNECTIONS_PREFIX}${conn.id}.json`, jsonConn);
|
|
134
175
|
}
|
|
135
176
|
|
|
136
177
|
private async removeConnection(id: string): Promise<void> {
|
|
137
178
|
await this.smartSecret.deleteSecret(id);
|
|
179
|
+
await this.smartSecret.deleteSecret(getRegistryTokenSecretId(id));
|
|
138
180
|
await this.storageManager.delete(`${CONNECTIONS_PREFIX}${id}.json`);
|
|
139
181
|
}
|
|
140
182
|
|
|
141
183
|
getConnections(): interfaces.data.IProviderConnection[] {
|
|
142
|
-
return this.connections.map((c) => ({
|
|
184
|
+
return this.connections.map((c) => ({
|
|
185
|
+
...c,
|
|
186
|
+
token: '***',
|
|
187
|
+
registryToken: c.registryToken ? '***' : undefined,
|
|
188
|
+
}));
|
|
143
189
|
}
|
|
144
190
|
|
|
145
191
|
getConnection(id: string): interfaces.data.IProviderConnection | undefined {
|
|
@@ -152,6 +198,9 @@ export class ConnectionManager {
|
|
|
152
198
|
baseUrl: string,
|
|
153
199
|
token: string,
|
|
154
200
|
groupFilter?: string,
|
|
201
|
+
registryUrl?: string,
|
|
202
|
+
registryUsername?: string,
|
|
203
|
+
registryToken?: string,
|
|
155
204
|
): Promise<interfaces.data.IProviderConnection> {
|
|
156
205
|
const connection: interfaces.data.IProviderConnection = {
|
|
157
206
|
id: crypto.randomUUID(),
|
|
@@ -162,16 +211,19 @@ export class ConnectionManager {
|
|
|
162
211
|
createdAt: Date.now(),
|
|
163
212
|
status: 'disconnected',
|
|
164
213
|
groupFilter: groupFilter || undefined,
|
|
214
|
+
registryUrl: registryUrl || undefined,
|
|
215
|
+
registryUsername: registryUsername || undefined,
|
|
216
|
+
registryToken: registryToken || undefined,
|
|
165
217
|
};
|
|
166
218
|
this.connections.push(connection);
|
|
167
219
|
await this.persistConnection(connection);
|
|
168
220
|
logger.success(`Connection created: ${name} (${providerType})`);
|
|
169
|
-
return { ...connection, token: '***' };
|
|
221
|
+
return { ...connection, token: '***', registryToken: connection.registryToken ? '***' : undefined };
|
|
170
222
|
}
|
|
171
223
|
|
|
172
224
|
async updateConnection(
|
|
173
225
|
id: string,
|
|
174
|
-
updates: { name?: string; baseUrl?: string; token?: string; groupFilter?: string },
|
|
226
|
+
updates: { name?: string; baseUrl?: string; token?: string; groupFilter?: string; registryUrl?: string; registryUsername?: string; registryToken?: string },
|
|
175
227
|
): Promise<interfaces.data.IProviderConnection> {
|
|
176
228
|
const conn = this.connections.find((c) => c.id === id);
|
|
177
229
|
if (!conn) throw new Error(`Connection not found: ${id}`);
|
|
@@ -182,8 +234,11 @@ export class ConnectionManager {
|
|
|
182
234
|
conn.groupFilter = updates.groupFilter || undefined;
|
|
183
235
|
conn.groupFilterId = undefined; // Will be re-resolved on next test
|
|
184
236
|
}
|
|
237
|
+
if (updates.registryUrl !== undefined) conn.registryUrl = updates.registryUrl || undefined;
|
|
238
|
+
if (updates.registryUsername !== undefined) conn.registryUsername = updates.registryUsername || undefined;
|
|
239
|
+
if (updates.registryToken !== undefined) conn.registryToken = updates.registryToken || undefined;
|
|
185
240
|
await this.persistConnection(conn);
|
|
186
|
-
return { ...conn, token: '***' };
|
|
241
|
+
return { ...conn, token: '***', registryToken: conn.registryToken ? '***' : undefined };
|
|
187
242
|
}
|
|
188
243
|
|
|
189
244
|
async deleteConnection(id: string): Promise<void> {
|
|
@@ -200,7 +255,7 @@ export class ConnectionManager {
|
|
|
200
255
|
conn.status = paused ? 'paused' : 'disconnected';
|
|
201
256
|
await this.persistConnection(conn);
|
|
202
257
|
logger.info(`Connection ${paused ? 'paused' : 'resumed'}: ${conn.name}`);
|
|
203
|
-
return { ...conn, token: '***' };
|
|
258
|
+
return { ...conn, token: '***', registryToken: conn.registryToken ? '***' : undefined };
|
|
204
259
|
}
|
|
205
260
|
|
|
206
261
|
async testConnection(id: string): Promise<{ ok: boolean; error?: string }> {
|