@ory/argus 0.1.1 → 0.1.3
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/dist/dev.js +11 -0
- package/dist/registry/config.d.ts +17 -0
- package/dist/registry/config.js +36 -5
- package/dist/registry/manager.d.ts +11 -0
- package/dist/registry/manager.js +80 -4
- package/package.json +1 -1
package/dist/dev.js
CHANGED
|
@@ -127,8 +127,19 @@ function npmEnv() {
|
|
|
127
127
|
// the local registry through an isolated pacote cache, with the user's
|
|
128
128
|
// supply-chain freshness gate disabled (otherwise just-published tarballs
|
|
129
129
|
// get filtered out as `ENOVERSIONS — No versions available`).
|
|
130
|
+
//
|
|
131
|
+
// `npm_config_userconfig` swaps the userconfig file from `~/.npmrc` to a
|
|
132
|
+
// launcher-managed npmrc that pins `@ory:registry` to the local Verdaccio.
|
|
133
|
+
// Without this, a developer-level `@ory:registry=…` line in their own
|
|
134
|
+
// `~/.npmrc` (left over from `npm login --scope=@ory` or similar) wins
|
|
135
|
+
// against `--registry` for scoped packages and routes the launcher's
|
|
136
|
+
// `npm install @ory/<harness>` — and the harness's own runtime `npx`
|
|
137
|
+
// calls — back to npmjs.org. The symptoms are ENOVERSIONS or tarball
|
|
138
|
+
// sha512 corruption depending on which side of the manifest/tarball
|
|
139
|
+
// split each subprocess hits.
|
|
130
140
|
return {
|
|
131
141
|
...process.env,
|
|
142
|
+
npm_config_userconfig: (0, manager_js_1.ensureLauncherNpmrc)(),
|
|
132
143
|
npm_config_registry: config_js_1.REGISTRY_URL,
|
|
133
144
|
npm_config_cache: (0, manager_js_1.getLocalRegistryNpmCacheDir)(),
|
|
134
145
|
npm_config_min_release_age: "0",
|
|
@@ -21,3 +21,20 @@ export declare const REGISTRY_CONTAINER_STORAGE = "/verdaccio/storage";
|
|
|
21
21
|
export declare const REGISTRY_CONTAINER_CONFIG = "/verdaccio/conf/config.yaml";
|
|
22
22
|
export declare function verdaccioConfigYaml(): string;
|
|
23
23
|
export declare function npmrcContent(): string;
|
|
24
|
+
/**
|
|
25
|
+
* Userconfig file used by the dev launcher's npm/npx subprocesses.
|
|
26
|
+
*
|
|
27
|
+
* The scope-specific `@ory:registry=…` line is the critical bit. If a
|
|
28
|
+
* developer has ever run `npm login --scope=@ory` (or otherwise pinned
|
|
29
|
+
* `@ory:registry` in their `~/.npmrc`) to publish or fetch from npmjs.org,
|
|
30
|
+
* that pin takes precedence over `--registry` / `npm_config_registry` for
|
|
31
|
+
* scoped packages — so the launcher's `npm install @ory/<harness>` and the
|
|
32
|
+
* harness's own runtime `npx -y -p @ory/<harness>` calls silently hit
|
|
33
|
+
* npmjs.org instead of localhost, producing either `ENOVERSIONS` (because
|
|
34
|
+
* npmjs's manifest doesn't list the just-bumped local version) or a tarball
|
|
35
|
+
* sha512 mismatch (when the local manifest is consulted but npmjs serves
|
|
36
|
+
* the bytes). We expose this file as `npm_config_userconfig` so it
|
|
37
|
+
* displaces `~/.npmrc` entirely for subprocesses the launcher spawns,
|
|
38
|
+
* without modifying any global config or polluting the sandbox.
|
|
39
|
+
*/
|
|
40
|
+
export declare function launcherNpmrcContent(): string;
|
package/dist/registry/config.js
CHANGED
|
@@ -13,6 +13,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
13
13
|
exports.REGISTRY_CONTAINER_CONFIG = exports.REGISTRY_CONTAINER_STORAGE = exports.REGISTRY_CONTAINER = exports.REGISTRY_IMAGE = exports.REGISTRY_DIR_NAME = exports.REGISTRY_URL = exports.REGISTRY_PORT = void 0;
|
|
14
14
|
exports.verdaccioConfigYaml = verdaccioConfigYaml;
|
|
15
15
|
exports.npmrcContent = npmrcContent;
|
|
16
|
+
exports.launcherNpmrcContent = launcherNpmrcContent;
|
|
16
17
|
exports.REGISTRY_PORT = 4873;
|
|
17
18
|
exports.REGISTRY_URL = `http://localhost:${exports.REGISTRY_PORT}`;
|
|
18
19
|
exports.REGISTRY_DIR_NAME = ".ory-dev/registry";
|
|
@@ -44,15 +45,22 @@ uplinks:
|
|
|
44
45
|
cache: false
|
|
45
46
|
|
|
46
47
|
packages:
|
|
48
|
+
# @ory/client is a transitive Ory SDK dep that lives on npmjs.org — proxy
|
|
49
|
+
# it so installs can resolve it from upstream.
|
|
50
|
+
"@ory/client":
|
|
51
|
+
access: $all
|
|
52
|
+
publish: $all
|
|
53
|
+
proxy: npmjs
|
|
54
|
+
|
|
55
|
+
# All other @ory/* packages are workspace packages we publish locally.
|
|
56
|
+
# No proxy: if upstream were consulted, Verdaccio would merge npmjs.org's
|
|
57
|
+
# already-published versions into the manifest and reject every republish
|
|
58
|
+
# at the same version with "cannot publish over previously published
|
|
59
|
+
# versions: X.Y.Z".
|
|
47
60
|
"@ory/*":
|
|
48
61
|
access: $all
|
|
49
62
|
publish: $all
|
|
50
63
|
unpublish: $all
|
|
51
|
-
# Locally-published workspace packages (e.g. @ory/argus) are served from
|
|
52
|
-
# storage; everything else under @ory/* (notably @ory/client, a transitive
|
|
53
|
-
# dep) falls through to npmjs. Without this, transitive @ory/client
|
|
54
|
-
# resolution fails with E404 against the local registry.
|
|
55
|
-
proxy: npmjs
|
|
56
64
|
|
|
57
65
|
"**":
|
|
58
66
|
access: $all
|
|
@@ -78,3 +86,26 @@ function npmrcContent() {
|
|
|
78
86
|
//localhost:${exports.REGISTRY_PORT}/:_authToken=local-dev-token
|
|
79
87
|
`;
|
|
80
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Userconfig file used by the dev launcher's npm/npx subprocesses.
|
|
91
|
+
*
|
|
92
|
+
* The scope-specific `@ory:registry=…` line is the critical bit. If a
|
|
93
|
+
* developer has ever run `npm login --scope=@ory` (or otherwise pinned
|
|
94
|
+
* `@ory:registry` in their `~/.npmrc`) to publish or fetch from npmjs.org,
|
|
95
|
+
* that pin takes precedence over `--registry` / `npm_config_registry` for
|
|
96
|
+
* scoped packages — so the launcher's `npm install @ory/<harness>` and the
|
|
97
|
+
* harness's own runtime `npx -y -p @ory/<harness>` calls silently hit
|
|
98
|
+
* npmjs.org instead of localhost, producing either `ENOVERSIONS` (because
|
|
99
|
+
* npmjs's manifest doesn't list the just-bumped local version) or a tarball
|
|
100
|
+
* sha512 mismatch (when the local manifest is consulted but npmjs serves
|
|
101
|
+
* the bytes). We expose this file as `npm_config_userconfig` so it
|
|
102
|
+
* displaces `~/.npmrc` entirely for subprocesses the launcher spawns,
|
|
103
|
+
* without modifying any global config or polluting the sandbox.
|
|
104
|
+
*/
|
|
105
|
+
function launcherNpmrcContent() {
|
|
106
|
+
return `registry=${exports.REGISTRY_URL}/
|
|
107
|
+
@ory:registry=${exports.REGISTRY_URL}/
|
|
108
|
+
//localhost:${exports.REGISTRY_PORT}/:_authToken=local-dev-token
|
|
109
|
+
min-release-age=0
|
|
110
|
+
`;
|
|
111
|
+
}
|
|
@@ -19,6 +19,17 @@
|
|
|
19
19
|
* pnpm publish/npm install even after we drop the version from Verdaccio.
|
|
20
20
|
*/
|
|
21
21
|
export declare function getLocalRegistryNpmCacheDir(): string;
|
|
22
|
+
/**
|
|
23
|
+
* Path to the userconfig npmrc the dev launcher hands to its subprocesses.
|
|
24
|
+
* See `launcherNpmrcContent` in `./config.ts` for why this exists.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getLauncherNpmrcPath(): string;
|
|
27
|
+
/**
|
|
28
|
+
* Materialize the launcher userconfig npmrc on disk and return its path.
|
|
29
|
+
* Idempotent: rewrites the file every call so any drift in the rendered
|
|
30
|
+
* content (e.g. registry URL change) lands without a clean-and-restart.
|
|
31
|
+
*/
|
|
32
|
+
export declare function ensureLauncherNpmrc(): string;
|
|
22
33
|
/**
|
|
23
34
|
* Start the local registry if it isn't already running.
|
|
24
35
|
*/
|
package/dist/registry/manager.js
CHANGED
|
@@ -46,6 +46,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
46
46
|
})();
|
|
47
47
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
48
|
exports.getLocalRegistryNpmCacheDir = getLocalRegistryNpmCacheDir;
|
|
49
|
+
exports.getLauncherNpmrcPath = getLauncherNpmrcPath;
|
|
50
|
+
exports.ensureLauncherNpmrc = ensureLauncherNpmrc;
|
|
49
51
|
exports.ensureRegistryRunning = ensureRegistryRunning;
|
|
50
52
|
exports.publishHarnessToLocal = publishHarnessToLocal;
|
|
51
53
|
exports.registryStart = registryStart;
|
|
@@ -84,6 +86,24 @@ function getRegistryDir() {
|
|
|
84
86
|
function getLocalRegistryNpmCacheDir() {
|
|
85
87
|
return path.join(getRegistryDir(), "npm-cache");
|
|
86
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Path to the userconfig npmrc the dev launcher hands to its subprocesses.
|
|
91
|
+
* See `launcherNpmrcContent` in `./config.ts` for why this exists.
|
|
92
|
+
*/
|
|
93
|
+
function getLauncherNpmrcPath() {
|
|
94
|
+
return path.join(getRegistryDir(), "launcher.npmrc");
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Materialize the launcher userconfig npmrc on disk and return its path.
|
|
98
|
+
* Idempotent: rewrites the file every call so any drift in the rendered
|
|
99
|
+
* content (e.g. registry URL change) lands without a clean-and-restart.
|
|
100
|
+
*/
|
|
101
|
+
function ensureLauncherNpmrc() {
|
|
102
|
+
const npmrcPath = getLauncherNpmrcPath();
|
|
103
|
+
ensureDir(path.dirname(npmrcPath));
|
|
104
|
+
fs.writeFileSync(npmrcPath, (0, config_js_1.launcherNpmrcContent)());
|
|
105
|
+
return npmrcPath;
|
|
106
|
+
}
|
|
87
107
|
function ensureDir(dir) {
|
|
88
108
|
if (!fs.existsSync(dir)) {
|
|
89
109
|
fs.mkdirSync(dir, { recursive: true });
|
|
@@ -176,15 +196,28 @@ async function withLocalPublishConfig(workspaceRoot, fn) {
|
|
|
176
196
|
async function cleanScopeStorage() {
|
|
177
197
|
// Verdaccio caches package metadata in memory; deleting on-disk storage
|
|
178
198
|
// alone leaves stale manifests served and causes publish to report
|
|
179
|
-
// "already exists". Issue an HTTP DELETE for every known
|
|
180
|
-
// first (Verdaccio drops both memory + disk state), then
|
|
181
|
-
// residual scope dir for completeness.
|
|
199
|
+
// "already exists". Issue an authenticated HTTP DELETE for every known
|
|
200
|
+
// scoped package first (Verdaccio drops both memory + disk state), then
|
|
201
|
+
// remove any residual scope dir for completeness.
|
|
202
|
+
//
|
|
203
|
+
// The Authorization header is required: Verdaccio silently rejects
|
|
204
|
+
// unauthenticated DELETEs, leaves its in-memory manifest intact, and then
|
|
205
|
+
// rewrites the on-disk `package.json` from that cache on the next publish
|
|
206
|
+
// — so the second publish sees the stale versions and fails with
|
|
207
|
+
// "cannot publish over previously published versions".
|
|
182
208
|
const root = findProjectRoot(process.cwd());
|
|
183
209
|
const names = listWorkspaceScopedPackages(root);
|
|
210
|
+
const token = readToken(getRegistryDir());
|
|
211
|
+
const headers = token
|
|
212
|
+
? { Authorization: `Bearer ${token}` }
|
|
213
|
+
: {};
|
|
184
214
|
await Promise.all(names.map(async (name) => {
|
|
185
215
|
const encoded = name.replace("/", "%2f");
|
|
186
216
|
try {
|
|
187
|
-
await fetch(`${config_js_1.REGISTRY_URL}/${encoded}/-rev/0`, {
|
|
217
|
+
await fetch(`${config_js_1.REGISTRY_URL}/${encoded}/-rev/0`, {
|
|
218
|
+
method: "DELETE",
|
|
219
|
+
headers,
|
|
220
|
+
});
|
|
188
221
|
}
|
|
189
222
|
catch {
|
|
190
223
|
// Best-effort.
|
|
@@ -292,6 +325,48 @@ async function registerDevUser(registryDir) {
|
|
|
292
325
|
fs.writeFileSync(getTokenFile(registryDir), token);
|
|
293
326
|
return token;
|
|
294
327
|
}
|
|
328
|
+
/**
|
|
329
|
+
* Restart the registry container if the rendered Verdaccio config has
|
|
330
|
+
* drifted from what's on disk. Verdaccio 6 does not hot-reload `config.yaml`,
|
|
331
|
+
* so a config change in the codebase has no effect on a running container
|
|
332
|
+
* until it restarts — and a stale config can silently keep mis-routing
|
|
333
|
+
* publishes through the upstream proxy. Called from `publishAllOryToLocal`
|
|
334
|
+
* so any code-bundled policy fix lands without an explicit `registry:clean`.
|
|
335
|
+
*/
|
|
336
|
+
async function ensureConfigInSync(quiet) {
|
|
337
|
+
const registryDir = getRegistryDir();
|
|
338
|
+
// If the registry dir doesn't exist here, the running container was
|
|
339
|
+
// started from a different cwd (e.g. main repo while we're in a worktree,
|
|
340
|
+
// or vice versa). We don't own the on-disk state and writing a config
|
|
341
|
+
// file at this path wouldn't reach the container's bind mount anyway.
|
|
342
|
+
// Skip silently — the downstream auth-token check will surface a clear
|
|
343
|
+
// error if the caller actually needs local registry state.
|
|
344
|
+
if (!fs.existsSync(registryDir))
|
|
345
|
+
return;
|
|
346
|
+
const configPath = path.join(registryDir, "config.yaml");
|
|
347
|
+
const expected = (0, config_js_1.verdaccioConfigYaml)();
|
|
348
|
+
const current = fs.existsSync(configPath)
|
|
349
|
+
? fs.readFileSync(configPath, "utf-8")
|
|
350
|
+
: "";
|
|
351
|
+
if (current === expected)
|
|
352
|
+
return;
|
|
353
|
+
if (!quiet) {
|
|
354
|
+
console.log("Verdaccio config out of date — restarting registry...");
|
|
355
|
+
}
|
|
356
|
+
fs.writeFileSync(configPath, expected);
|
|
357
|
+
const restart = (0, node_child_process_1.spawnSync)("docker", ["restart", config_js_1.REGISTRY_CONTAINER], {
|
|
358
|
+
stdio: ["ignore", "ignore", "pipe"],
|
|
359
|
+
encoding: "utf-8",
|
|
360
|
+
});
|
|
361
|
+
if (restart.status !== 0) {
|
|
362
|
+
const stderr = (restart.stderr ?? "").toString().trim();
|
|
363
|
+
throw new Error(`Failed to restart registry container after config change (exit ${restart.status}): ${stderr}`);
|
|
364
|
+
}
|
|
365
|
+
const ready = await waitForRegistry();
|
|
366
|
+
if (!ready) {
|
|
367
|
+
throw new Error("Registry did not come back online after config restart within 30 seconds.");
|
|
368
|
+
}
|
|
369
|
+
}
|
|
295
370
|
// ─── Public lifecycle ──────────────────────────────────────────────
|
|
296
371
|
/**
|
|
297
372
|
* Start the local registry if it isn't already running.
|
|
@@ -362,6 +437,7 @@ async function publishAllOryToLocal(opts = {}) {
|
|
|
362
437
|
if (!isRegistryRunning()) {
|
|
363
438
|
throw new Error("Local registry is not running. Call ensureRegistryRunning() first.");
|
|
364
439
|
}
|
|
440
|
+
await ensureConfigInSync(opts.quiet);
|
|
365
441
|
const registryDir = getRegistryDir();
|
|
366
442
|
const token = readToken(registryDir);
|
|
367
443
|
if (!token) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ory/argus",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Ory Argus: the core API for building authentication, authorization, and audit into AI agent harness plugins, extensions, and custom integrations",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://ory.com",
|