@openparachute/hub 0.5.10 → 0.5.12-rc.2
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/package.json +1 -1
- package/src/__tests__/api-modules-ops.test.ts +283 -1
- package/src/__tests__/api-settings-hub-origin.test.ts +452 -0
- package/src/__tests__/bootstrap-token.test.ts +148 -0
- package/src/__tests__/hub-origin-resolution.test.ts +154 -0
- package/src/__tests__/hub-settings.test.ts +94 -0
- package/src/__tests__/oauth-ui.test.ts +117 -0
- package/src/__tests__/serve.test.ts +132 -1
- package/src/__tests__/setup-gate.test.ts +93 -0
- package/src/__tests__/setup-wizard.test.ts +392 -0
- package/src/api-modules-ops.ts +120 -1
- package/src/api-settings-hub-origin.ts +253 -0
- package/src/bootstrap-token.ts +153 -0
- package/src/commands/serve.ts +65 -1
- package/src/hub-server.ts +136 -18
- package/src/hub-settings.ts +53 -1
- package/src/oauth-ui.ts +45 -3
- package/src/setup-wizard.ts +178 -13
- package/src/well-known.ts +82 -1
- package/web/ui/dist/assets/index-BKFoB4gE.js +61 -0
- package/web/ui/dist/index.html +1 -1
- package/web/ui/dist/assets/index-XhxYXDT5.js +0 -61
package/src/well-known.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, renameSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { CONFIG_DIR } from "./config.ts";
|
|
4
|
-
import type
|
|
4
|
+
import { type ModuleManifest, readModuleManifest } from "./module-manifest.ts";
|
|
5
|
+
import { type ServiceEntry, readManifest } from "./services-manifest.ts";
|
|
5
6
|
|
|
6
7
|
export interface WellKnownServiceEntry {
|
|
7
8
|
url: string;
|
|
@@ -214,3 +215,83 @@ export function writeWellKnownFile(doc: WellKnownDocument, path: string = WELL_K
|
|
|
214
215
|
renameSync(tmp, path);
|
|
215
216
|
return path;
|
|
216
217
|
}
|
|
218
|
+
|
|
219
|
+
export interface RegenerateWellKnownOpts {
|
|
220
|
+
/** Path to services.json. Defaults to `SERVICES_MANIFEST_PATH`. */
|
|
221
|
+
manifestPath: string;
|
|
222
|
+
/**
|
|
223
|
+
* Origin to embed in the doc's `url` fields. The hub HTTP path uses
|
|
224
|
+
* `configuredIssuer ?? new URL(req.url).origin`; module-ops callers don't
|
|
225
|
+
* have a request, so they pass `issuer` (the configured hub origin from
|
|
226
|
+
* `ApiModulesOpsDeps`) — same canonical URL the per-request build would
|
|
227
|
+
* emit.
|
|
228
|
+
*/
|
|
229
|
+
canonicalOrigin: string;
|
|
230
|
+
/** Override the on-disk well-known path (test seam). Defaults to `WELL_KNOWN_PATH`. */
|
|
231
|
+
wellKnownPath?: string;
|
|
232
|
+
/**
|
|
233
|
+
* Reader for a module's `.parachute/module.json`. Production uses
|
|
234
|
+
* `readModuleManifest`; tests inject a stub. Mirrors hub-server's
|
|
235
|
+
* `readModuleManifest` seam so the disk regen and the per-request build
|
|
236
|
+
* stay in lockstep.
|
|
237
|
+
*/
|
|
238
|
+
readModuleManifest?: (installDir: string) => Promise<ModuleManifest | null>;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Regenerate `/.well-known/parachute.json` on disk from current services.json.
|
|
243
|
+
*
|
|
244
|
+
* Mirrors the dynamic build inside `hub-server.ts`'s
|
|
245
|
+
* `/.well-known/parachute.json` handler so the on-disk doc tracks the same
|
|
246
|
+
* `uiUrl` / `displayName` / `managementUrl` shape the live discovery page
|
|
247
|
+
* fetches. Returns the path written + the resulting doc so callers can log
|
|
248
|
+
* and tests can assert without re-reading from disk.
|
|
249
|
+
*
|
|
250
|
+
* Used by `/api/modules/:short/{install,upgrade,uninstall}` post-mutation so
|
|
251
|
+
* the on-disk doc stays current after lifecycle ops. The per-request build
|
|
252
|
+
* in hub-server.ts remains the source of truth for live HTTP reads — this
|
|
253
|
+
* disk write is the inspection / debug artifact (and a belt-and-suspenders
|
|
254
|
+
* canary for anything that reads the file directly).
|
|
255
|
+
*/
|
|
256
|
+
export async function regenerateWellKnown(
|
|
257
|
+
opts: RegenerateWellKnownOpts,
|
|
258
|
+
): Promise<{ path: string; doc: WellKnownDocument }> {
|
|
259
|
+
const read = opts.readModuleManifest ?? readModuleManifest;
|
|
260
|
+
const path = opts.wellKnownPath ?? WELL_KNOWN_PATH;
|
|
261
|
+
const services = readManifest(opts.manifestPath).services;
|
|
262
|
+
// Build the resolver maps the same way hub-server does — read each
|
|
263
|
+
// module's `.parachute/module.json` from `installDir` and harvest
|
|
264
|
+
// managementUrl (vault rows) + uiUrl + displayName (non-vault rows).
|
|
265
|
+
// Per-entry errors land in console.warn so one malformed manifest doesn't
|
|
266
|
+
// block the regen for everyone else.
|
|
267
|
+
const managementUrls = new Map<string, string>();
|
|
268
|
+
const uiUrls = new Map<string, string>();
|
|
269
|
+
const displayNames = new Map<string, string>();
|
|
270
|
+
await Promise.all(
|
|
271
|
+
services.map(async (s) => {
|
|
272
|
+
if (!s.installDir) return;
|
|
273
|
+
try {
|
|
274
|
+
const m = await read(s.installDir);
|
|
275
|
+
if (!m) return;
|
|
276
|
+
if (isVaultEntry(s)) {
|
|
277
|
+
if (m.managementUrl) managementUrls.set(s.name, m.managementUrl);
|
|
278
|
+
} else {
|
|
279
|
+
if (m.uiUrl) uiUrls.set(s.name, m.uiUrl);
|
|
280
|
+
if (m.displayName) displayNames.set(s.name, m.displayName);
|
|
281
|
+
}
|
|
282
|
+
} catch (err) {
|
|
283
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
284
|
+
console.warn(`well-known regen: skipping module metadata for ${s.name}: ${msg}`);
|
|
285
|
+
}
|
|
286
|
+
}),
|
|
287
|
+
);
|
|
288
|
+
const doc = buildWellKnown({
|
|
289
|
+
services,
|
|
290
|
+
canonicalOrigin: opts.canonicalOrigin,
|
|
291
|
+
managementUrlFor: (entry) => managementUrls.get(entry.name),
|
|
292
|
+
uiUrlFor: (entry) => uiUrls.get(entry.name),
|
|
293
|
+
displayNameFor: (entry) => displayNames.get(entry.name),
|
|
294
|
+
});
|
|
295
|
+
writeWellKnownFile(doc, path);
|
|
296
|
+
return { path, doc };
|
|
297
|
+
}
|