@uluops/ops-sdk 6.1.0 → 6.3.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/CHANGELOG.md +41 -1
- package/README.md +41 -1
- package/dist/client.d.ts +69 -78
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +70 -62
- package/dist/client.js.map +1 -1
- package/dist/config/constants.d.ts +3 -1
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/constants.js +2 -0
- package/dist/config/constants.js.map +1 -1
- package/dist/config/generated-version.d.ts +1 -1
- package/dist/config/generated-version.js +1 -1
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/workspace-org.d.ts +77 -0
- package/dist/config/workspace-org.d.ts.map +1 -0
- package/dist/config/workspace-org.js +182 -0
- package/dist/config/workspace-org.js.map +1 -0
- package/dist/errors/errors.d.ts +47 -0
- package/dist/errors/errors.d.ts.map +1 -1
- package/dist/errors/errors.js +39 -0
- package/dist/errors/errors.js.map +1 -1
- package/dist/http/http-client.d.ts +46 -0
- package/dist/http/http-client.d.ts.map +1 -1
- package/dist/http/http-client.js +88 -5
- package/dist/http/http-client.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/org.d.ts +25 -0
- package/dist/types/org.d.ts.map +1 -0
- package/dist/types/org.js +2 -0
- package/dist/types/org.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workspace org resolution — D13 of the project-org-routing-and-rehome spec.
|
|
3
|
+
*
|
|
4
|
+
* "Where you are" decides which org a tracker call lands in. The unit that
|
|
5
|
+
* distinguishes personal work from work-org work on one machine is the
|
|
6
|
+
* CHECKOUT, not the process or the person: an env var or a profile leaks the
|
|
7
|
+
* last-set org into whatever repo is opened next (spec §2.0 S3/S7). So the
|
|
8
|
+
* default comes from a file in the tree, found by walking upward from `cwd`
|
|
9
|
+
* to the nearest `.uluops.json` — the way `.npmrc` and `.gitignore` are found.
|
|
10
|
+
*
|
|
11
|
+
* Precedence, highest first:
|
|
12
|
+
* 1. `explicit` — a per-call / per-invocation value (`--org`, an MCP tool's
|
|
13
|
+
* `org` argument);
|
|
14
|
+
* 2. the nearest `.uluops.json` above `cwd` whose `org` is set — including
|
|
15
|
+
* the reserved value `"personal"`, which STOPS the walk and
|
|
16
|
+
* resolves to no org (a personal repo cloned under a work
|
|
17
|
+
* tree carries it so the outer file does not win);
|
|
18
|
+
* 3. `ULUOPS_ORG_SLUG` in `env` — kept as the lowest fall-through for
|
|
19
|
+
* headless environments with no checkout;
|
|
20
|
+
* 4. undefined — no header; the API key holder's personal org.
|
|
21
|
+
*
|
|
22
|
+
* The file may carry ONLY `org`. Credentials, base URLs and profiles are
|
|
23
|
+
* refused, not ignored: a `.env` in cwd once retargeted the CLI's base URL,
|
|
24
|
+
* and the one thing that keeps that footgun from transferring is that this
|
|
25
|
+
* file cannot name a target or an identity. An org slug is server-relative —
|
|
26
|
+
* the same file against a different base URL names a different org or none —
|
|
27
|
+
* so callers that print "where it landed" should print the base URL beside
|
|
28
|
+
* the org.
|
|
29
|
+
*
|
|
30
|
+
* Runtime-agnostic: reads are synchronous `fs` calls, no `process.cwd()` is
|
|
31
|
+
* consulted unless the caller passes none, and `env` is injectable so tests
|
|
32
|
+
* never touch the real environment.
|
|
33
|
+
*/
|
|
34
|
+
import { existsSync, readFileSync, statSync } from 'fs';
|
|
35
|
+
import { homedir } from 'os';
|
|
36
|
+
import { dirname, join, resolve, relative, isAbsolute } from 'path';
|
|
37
|
+
import { InputValidationError } from './validators.js';
|
|
38
|
+
import { ENV_VARS } from './constants.js';
|
|
39
|
+
/** The workspace file name, found by walking upward from cwd. */
|
|
40
|
+
export const WORKSPACE_ORG_FILE = '.uluops.json';
|
|
41
|
+
/** Reserved `org` value: stop the walk here and use the personal org. */
|
|
42
|
+
export const PERSONAL_ORG_SENTINEL = 'personal';
|
|
43
|
+
/** Same pattern as `OpsHttpClient`'s `orgSlug` — it is a header value. */
|
|
44
|
+
const ORG_SLUG_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,99}$/;
|
|
45
|
+
/**
|
|
46
|
+
* The ONLY keys a workspace file may carry. An allowlist, not a denylist:
|
|
47
|
+
* until 6.3.1 this was a list of ten forbidden names while the error message
|
|
48
|
+
* said "may carry only org" — `baseURL`, `apikey`, `token` and anything
|
|
49
|
+
* unlisted passed (security audit run #187, agentic-security-analyst F10).
|
|
50
|
+
* Inert then (only `org` was ever read), but the stated invariant must be
|
|
51
|
+
* the enforced one. `$schema` is allowed for editor tooling.
|
|
52
|
+
*/
|
|
53
|
+
const ALLOWED_KEYS = new Set(['org', '$schema']);
|
|
54
|
+
function assertSlug(value, where) {
|
|
55
|
+
if (typeof value !== 'string' || !ORG_SLUG_PATTERN.test(value)) {
|
|
56
|
+
throw new InputValidationError(`Invalid org in ${where}: must be 1-100 alphanumeric characters, hyphens, or underscores`, [{ code: 'custom', path: ['org'], message: 'must be 1-100 alphanumeric characters, hyphens, or underscores' }]);
|
|
57
|
+
}
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
/** True when `child` is `parent` or lies beneath it. */
|
|
61
|
+
function isUnder(child, parent) {
|
|
62
|
+
const rel = relative(parent, child);
|
|
63
|
+
return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Find the nearest `.uluops.json` at or above `cwd`, stopping at `stopAt`.
|
|
67
|
+
* With no `stopAt`, the walk is bounded by `home` (default `os.homedir()`)
|
|
68
|
+
* when `cwd` is under it: security audit run #187 (all four agents) — an
|
|
69
|
+
* unbounded walk makes a file at `/`, `/Users` or a container image root
|
|
70
|
+
* the silent default for every checkout beneath it, which is the
|
|
71
|
+
* single-default leak D13 exists to remove, one layer down. Outside the
|
|
72
|
+
* home directory the walk still reaches the filesystem root; the ownership
|
|
73
|
+
* check in `readWorkspaceOrgFile` is the guard there.
|
|
74
|
+
*/
|
|
75
|
+
export function findWorkspaceOrgFile(cwd, stopAt, home = homedir()) {
|
|
76
|
+
let dir = resolve(cwd);
|
|
77
|
+
const homeAbs = resolve(home);
|
|
78
|
+
const stop = stopAt !== undefined ? resolve(stopAt) : isUnder(dir, homeAbs) ? homeAbs : undefined;
|
|
79
|
+
for (;;) {
|
|
80
|
+
const candidate = join(dir, WORKSPACE_ORG_FILE);
|
|
81
|
+
if (existsSync(candidate))
|
|
82
|
+
return candidate;
|
|
83
|
+
if (stop !== undefined && dir === stop)
|
|
84
|
+
return undefined;
|
|
85
|
+
const parent = dirname(dir);
|
|
86
|
+
if (parent === dir)
|
|
87
|
+
return undefined;
|
|
88
|
+
dir = parent;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Read one workspace file. Returns the `org` it declares (`"personal"` is
|
|
93
|
+
* returned verbatim — the caller decides what it means), or `undefined` when
|
|
94
|
+
* the file exists but declares no `org`.
|
|
95
|
+
*
|
|
96
|
+
* A file not owned by `uid` (default: the running user) is REFUSED, not
|
|
97
|
+
* skipped: a shared parent directory another user can write to is the
|
|
98
|
+
* planting vector (run #187, circumvention A2), and a silently skipped file
|
|
99
|
+
* is a silently wrong org. Pass `uid: undefined` explicitly only on
|
|
100
|
+
* platforms with no uids.
|
|
101
|
+
*
|
|
102
|
+
* @throws {InputValidationError} on unreadable JSON, a non-object body, a
|
|
103
|
+
* key other than `org`/`$schema`, a file owned by another user, or an
|
|
104
|
+
* `org` that is not a valid slug (other than the sentinel).
|
|
105
|
+
*/
|
|
106
|
+
export function readWorkspaceOrgFile(path, uid = process.getuid?.()) {
|
|
107
|
+
if (uid !== undefined) {
|
|
108
|
+
let ownerUid;
|
|
109
|
+
try {
|
|
110
|
+
ownerUid = statSync(path).uid;
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
throw new InputValidationError(`Unreadable ${WORKSPACE_ORG_FILE} at ${path}: ${err instanceof Error ? err.message : String(err)}`, [{ code: 'custom', path: [], message: 'cannot stat' }]);
|
|
114
|
+
}
|
|
115
|
+
if (ownerUid !== uid) {
|
|
116
|
+
throw new InputValidationError(`Refusing ${WORKSPACE_ORG_FILE} at ${path}: owned by uid ${String(ownerUid)}, not you (uid ${String(uid)}). ` +
|
|
117
|
+
'A workspace file decides which org your writes land in; only your own may answer.', [{ code: 'custom', path: [], message: 'not owned by the running user' }]);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
let parsed;
|
|
121
|
+
try {
|
|
122
|
+
parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
throw new InputValidationError(`Unreadable ${WORKSPACE_ORG_FILE} at ${path}: ${err instanceof Error ? err.message : String(err)}`, [{ code: 'custom', path: [], message: 'invalid JSON' }]);
|
|
126
|
+
}
|
|
127
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
128
|
+
throw new InputValidationError(`Invalid ${WORKSPACE_ORG_FILE} at ${path}: expected an object`, [{ code: 'custom', path: [], message: 'expected an object' }]);
|
|
129
|
+
}
|
|
130
|
+
const body = parsed;
|
|
131
|
+
const forbidden = Object.keys(body).filter((k) => !ALLOWED_KEYS.has(k));
|
|
132
|
+
if (forbidden.length > 0) {
|
|
133
|
+
throw new InputValidationError(`Refusing ${WORKSPACE_ORG_FILE} at ${path}: it may carry only "org"; found ${forbidden.map((k) => `"${k}"`).join(', ')}. ` +
|
|
134
|
+
'Credentials and targets belong in ~/.uluops/credentials.json or the environment, never in the checkout.', forbidden.map((k) => ({ code: 'custom', path: [k], message: 'forbidden in the workspace file' })));
|
|
135
|
+
}
|
|
136
|
+
if (!('org' in body) || body['org'] === undefined || body['org'] === null)
|
|
137
|
+
return undefined;
|
|
138
|
+
if (body['org'] === PERSONAL_ORG_SENTINEL)
|
|
139
|
+
return PERSONAL_ORG_SENTINEL;
|
|
140
|
+
return assertSlug(body['org'], `${WORKSPACE_ORG_FILE} at ${path}`);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Resolve the org for a call: explicit > nearest workspace file > env > personal.
|
|
144
|
+
*
|
|
145
|
+
* Never returns the sentinel — a `"personal"` file yields `{ org: undefined,
|
|
146
|
+
* source: 'personal', path }`. Never consults a cache; the walk is a handful
|
|
147
|
+
* of `existsSync` calls and a resolver that remembered would reintroduce the
|
|
148
|
+
* process-level default the spec rejects.
|
|
149
|
+
*
|
|
150
|
+
* @throws {InputValidationError} for an invalid `explicit` slug, or a
|
|
151
|
+
* malformed / forbidden workspace file (loud on purpose: a silently ignored
|
|
152
|
+
* file is a silently wrong org).
|
|
153
|
+
*/
|
|
154
|
+
export function resolveWorkspaceOrg(options = {}) {
|
|
155
|
+
if (options.explicit !== undefined) {
|
|
156
|
+
// The sentinel is honoured on the explicit path too (6.3.1, run #187
|
|
157
|
+
// circumvention A3): a caller told "omit org for your personal org" will
|
|
158
|
+
// sometimes write `org: personal`, and until now that went to the wire
|
|
159
|
+
// as a slug (404, or a real org if anyone registers the name).
|
|
160
|
+
if (options.explicit === PERSONAL_ORG_SENTINEL)
|
|
161
|
+
return { org: undefined, source: 'explicit' };
|
|
162
|
+
return { org: assertSlug(options.explicit, 'explicit org'), source: 'explicit' };
|
|
163
|
+
}
|
|
164
|
+
const cwd = options.cwd ?? process.cwd();
|
|
165
|
+
const path = findWorkspaceOrgFile(cwd, options.stopAt, options.home);
|
|
166
|
+
if (path !== undefined) {
|
|
167
|
+
const declared = readWorkspaceOrgFile(path, 'uid' in options ? options.uid : process.getuid?.());
|
|
168
|
+
if (declared === PERSONAL_ORG_SENTINEL)
|
|
169
|
+
return { org: undefined, source: 'personal', path };
|
|
170
|
+
if (declared !== undefined)
|
|
171
|
+
return { org: declared, source: 'workspace', path };
|
|
172
|
+
// A file with no `org` is not an answer; keep walking would be surprising
|
|
173
|
+
// ("the nearest file wins" is the rule), so fall through to env.
|
|
174
|
+
}
|
|
175
|
+
const env = options.env ?? process.env;
|
|
176
|
+
const fromEnv = env[ENV_VARS.ORG_SLUG];
|
|
177
|
+
if (fromEnv !== undefined && fromEnv !== '') {
|
|
178
|
+
return { org: assertSlug(fromEnv, `env ${ENV_VARS.ORG_SLUG}`), source: 'env' };
|
|
179
|
+
}
|
|
180
|
+
return { org: undefined, source: 'personal' };
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=workspace-org.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-org.js","sourceRoot":"","sources":["../../src/config/workspace-org.ts"],"names":[],"mappings":"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"}
|
package/dist/errors/errors.d.ts
CHANGED
|
@@ -53,4 +53,51 @@ export declare class AnalysisEchoMismatchError extends Error {
|
|
|
53
53
|
analysisWrite: unknown;
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
|
+
import { SdkApiError as _SdkApiError } from '@uluops/sdk-core/errors';
|
|
57
|
+
/**
|
|
58
|
+
* 403 — the caller is a member of the org but below the write floor
|
|
59
|
+
* (`publisher`). On tracker writes the API rewrites the body: `details.applied`
|
|
60
|
+
* is `false` and the message forbids retrying without `org`. DO NOT retry the
|
|
61
|
+
* same call without an org: an org-less retry does not "fall back", it files
|
|
62
|
+
* the work in the caller's PERSONAL org (spec §3.1, S6).
|
|
63
|
+
*/
|
|
64
|
+
export declare const INSUFFICIENT_ORG_ROLE: "INSUFFICIENT_ORG_ROLE";
|
|
65
|
+
/** 403 — the caller is not a member of the org named by `org` / `orgSlug`, or the key is bound to a different org. */
|
|
66
|
+
export declare const ORG_ACCESS_DENIED: "ORG_ACCESS_DENIED";
|
|
67
|
+
/**
|
|
68
|
+
* 410 — the project this name once denoted in this org has been RE-HOMED to
|
|
69
|
+
* another org (spec D14). `details.target_org.slug` is where it lives now:
|
|
70
|
+
* pass it as `org` and the same call succeeds. Do not create a new project
|
|
71
|
+
* at the old address — the tombstone exists precisely to refuse that fork.
|
|
72
|
+
*/
|
|
73
|
+
export declare const PROJECT_REHOMED: "PROJECT_REHOMED";
|
|
74
|
+
/** `details` on an `INSUFFICIENT_ORG_ROLE` rejection from a tracker write. */
|
|
75
|
+
export interface InsufficientOrgRoleDetails {
|
|
76
|
+
currentRole?: string;
|
|
77
|
+
requiredRole?: string;
|
|
78
|
+
/** Present on tracker writes: the org the write was refused in. */
|
|
79
|
+
orgSlug?: string | null;
|
|
80
|
+
/** Present on tracker writes: always `false` — nothing was applied. */
|
|
81
|
+
applied?: boolean;
|
|
82
|
+
}
|
|
83
|
+
/** `details` on a `PROJECT_REHOMED` rejection (spec §4.4a). */
|
|
84
|
+
export interface ProjectRehomedDetails {
|
|
85
|
+
project_id: string;
|
|
86
|
+
target_org: {
|
|
87
|
+
id: string;
|
|
88
|
+
slug: string;
|
|
89
|
+
};
|
|
90
|
+
rehomed_at?: string;
|
|
91
|
+
reason?: string | null;
|
|
92
|
+
}
|
|
93
|
+
/** Type guard: the org write floor refused this call (403 `INSUFFICIENT_ORG_ROLE`). Terminal — do not retry without `org`. */
|
|
94
|
+
export declare function isInsufficientOrgRoleError(err: unknown): err is _SdkApiError & {
|
|
95
|
+
details?: InsufficientOrgRoleDetails;
|
|
96
|
+
};
|
|
97
|
+
/** Type guard: not a member of the named org, or the key is bound elsewhere (403 `ORG_ACCESS_DENIED`). Terminal. */
|
|
98
|
+
export declare function isOrgAccessDeniedError(err: unknown): err is _SdkApiError;
|
|
99
|
+
/** Type guard: the project was re-homed; `err.details.target_org.slug` is the org to pass (410 `PROJECT_REHOMED`). */
|
|
100
|
+
export declare function isProjectRehomedError(err: unknown): err is _SdkApiError & {
|
|
101
|
+
details: ProjectRehomedDetails;
|
|
102
|
+
};
|
|
56
103
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,WAAW,IAAI,WAAW,EAC1B,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,IAAI,aAAa,EAC9B,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,yBAAyB,EACzB,cAAc,EACd,eAAe,EACf,cAAc,GACf,MAAM,yBAAyB,CAAC;AAEjC;;;;GAIG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,mFAAmF;IACnF,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,eAAe,GAAG,uBAAuB,CAAC;IAC5E,kFAAkF;IAClF,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,0EAA0E;IAC1E,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,yEAAyE;IACzE,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,qEAAqE;IACrE,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;gBAEpB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE;QACpC,MAAM,EAAE,cAAc,GAAG,eAAe,GAAG,uBAAuB,CAAC;QACnE,kBAAkB,EAAE,MAAM,CAAC;QAC3B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC,GAAG,EAAE,OAAO,CAAC;QACb,aAAa,EAAE,OAAO,CAAC;KACxB;CASF"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,WAAW,IAAI,WAAW,EAC1B,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,IAAI,aAAa,EAC9B,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,yBAAyB,EACzB,cAAc,EACd,eAAe,EACf,cAAc,GACf,MAAM,yBAAyB,CAAC;AAEjC;;;;GAIG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,mFAAmF;IACnF,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,eAAe,GAAG,uBAAuB,CAAC;IAC5E,kFAAkF;IAClF,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,0EAA0E;IAC1E,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,yEAAyE;IACzE,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,qEAAqE;IACrE,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;gBAEpB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE;QACpC,MAAM,EAAE,cAAc,GAAG,eAAe,GAAG,uBAAuB,CAAC;QACnE,kBAAkB,EAAE,MAAM,CAAC;QAC3B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;QAChC,GAAG,EAAE,OAAO,CAAC;QACb,aAAa,EAAE,OAAO,CAAC;KACxB;CASF;AAMD,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEtE;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,EAAG,uBAAgC,CAAC;AACtE,sHAAsH;AACtH,eAAO,MAAM,iBAAiB,EAAG,mBAA4B,CAAC;AAC9D;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAG,iBAA0B,CAAC;AAE1D,8EAA8E;AAC9E,MAAM,WAAW,0BAA0B;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,+DAA+D;AAC/D,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAMD,8HAA8H;AAC9H,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,YAAY,GAAG;IAAE,OAAO,CAAC,EAAE,0BAA0B,CAAA;CAAE,CAEvH;AAED,oHAAoH;AACpH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,YAAY,CAExE;AAED,sHAAsH;AACtH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,YAAY,GAAG;IAAE,OAAO,EAAE,qBAAqB,CAAA;CAAE,CAI5G"}
|
package/dist/errors/errors.js
CHANGED
|
@@ -56,4 +56,43 @@ export class AnalysisEchoMismatchError extends Error {
|
|
|
56
56
|
this.analysisWrite = details.analysisWrite;
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Org routing (project-org-routing-and-rehome spec, 6.2.0)
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
import { SdkApiError as _SdkApiError } from '@uluops/sdk-core/errors';
|
|
63
|
+
/**
|
|
64
|
+
* 403 — the caller is a member of the org but below the write floor
|
|
65
|
+
* (`publisher`). On tracker writes the API rewrites the body: `details.applied`
|
|
66
|
+
* is `false` and the message forbids retrying without `org`. DO NOT retry the
|
|
67
|
+
* same call without an org: an org-less retry does not "fall back", it files
|
|
68
|
+
* the work in the caller's PERSONAL org (spec §3.1, S6).
|
|
69
|
+
*/
|
|
70
|
+
export const INSUFFICIENT_ORG_ROLE = 'INSUFFICIENT_ORG_ROLE';
|
|
71
|
+
/** 403 — the caller is not a member of the org named by `org` / `orgSlug`, or the key is bound to a different org. */
|
|
72
|
+
export const ORG_ACCESS_DENIED = 'ORG_ACCESS_DENIED';
|
|
73
|
+
/**
|
|
74
|
+
* 410 — the project this name once denoted in this org has been RE-HOMED to
|
|
75
|
+
* another org (spec D14). `details.target_org.slug` is where it lives now:
|
|
76
|
+
* pass it as `org` and the same call succeeds. Do not create a new project
|
|
77
|
+
* at the old address — the tombstone exists precisely to refuse that fork.
|
|
78
|
+
*/
|
|
79
|
+
export const PROJECT_REHOMED = 'PROJECT_REHOMED';
|
|
80
|
+
function hasCode(err, code) {
|
|
81
|
+
return err instanceof _SdkApiError && err.code === code;
|
|
82
|
+
}
|
|
83
|
+
/** Type guard: the org write floor refused this call (403 `INSUFFICIENT_ORG_ROLE`). Terminal — do not retry without `org`. */
|
|
84
|
+
export function isInsufficientOrgRoleError(err) {
|
|
85
|
+
return hasCode(err, INSUFFICIENT_ORG_ROLE);
|
|
86
|
+
}
|
|
87
|
+
/** Type guard: not a member of the named org, or the key is bound elsewhere (403 `ORG_ACCESS_DENIED`). Terminal. */
|
|
88
|
+
export function isOrgAccessDeniedError(err) {
|
|
89
|
+
return hasCode(err, ORG_ACCESS_DENIED);
|
|
90
|
+
}
|
|
91
|
+
/** Type guard: the project was re-homed; `err.details.target_org.slug` is the org to pass (410 `PROJECT_REHOMED`). */
|
|
92
|
+
export function isProjectRehomedError(err) {
|
|
93
|
+
if (!hasCode(err, PROJECT_REHOMED))
|
|
94
|
+
return false;
|
|
95
|
+
const d = err.details;
|
|
96
|
+
return typeof d?.target_org?.slug === 'string' && typeof d.project_id === 'string';
|
|
97
|
+
}
|
|
59
98
|
//# sourceMappingURL=errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,WAAW,IAAI,WAAW,EAC1B,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,IAAI,aAAa,EAC9B,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,yBAAyB,EACzB,cAAc,EACd,eAAe,EACf,cAAc,GACf,MAAM,yBAAyB,CAAC;AAEjC;;;;GAIG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,sBAAsB;AACtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD,mFAAmF;IAC1E,MAAM,CAA6D;IAC5E,kFAAkF;IACzE,kBAAkB,CAAS;IACpC,0EAA0E;IACjE,gBAAgB,CAAgB;IACzC,yEAAyE;IAChE,GAAG,CAAU;IACtB,qEAAqE;IAC5D,aAAa,CAAU;IAEhC,YAAY,OAAe,EAAE,OAM5B;QACC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;QACxC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;QACrD,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QACjD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAC7C,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,WAAW,IAAI,WAAW,EAC1B,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,IAAI,aAAa,EAC9B,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,yBAAyB,EACzB,cAAc,EACd,eAAe,EACf,cAAc,GACf,MAAM,yBAAyB,CAAC;AAEjC;;;;GAIG;AACH,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,sBAAsB;AACtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAClD,mFAAmF;IAC1E,MAAM,CAA6D;IAC5E,kFAAkF;IACzE,kBAAkB,CAAS;IACpC,0EAA0E;IACjE,gBAAgB,CAAgB;IACzC,yEAAyE;IAChE,GAAG,CAAU;IACtB,qEAAqE;IAC5D,aAAa,CAAU;IAEhC,YAAY,OAAe,EAAE,OAM5B;QACC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAC;QACxC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;QACrD,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;QACjD,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAC7C,CAAC;CACF;AAED,8EAA8E;AAC9E,2DAA2D;AAC3D,8EAA8E;AAE9E,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEtE;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,uBAAgC,CAAC;AACtE,sHAAsH;AACtH,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAA4B,CAAC;AAC9D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,iBAA0B,CAAC;AAoB1D,SAAS,OAAO,CAAC,GAAY,EAAE,IAAY;IACzC,OAAO,GAAG,YAAY,YAAY,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC;AAC1D,CAAC;AAED,8HAA8H;AAC9H,MAAM,UAAU,0BAA0B,CAAC,GAAY;IACrD,OAAO,OAAO,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;AAC7C,CAAC;AAED,oHAAoH;AACpH,MAAM,UAAU,sBAAsB,CAAC,GAAY;IACjD,OAAO,OAAO,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;AACzC,CAAC;AAED,sHAAsH;AACtH,MAAM,UAAU,qBAAqB,CAAC,GAAY;IAChD,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC;QAAE,OAAO,KAAK,CAAC;IACjD,MAAM,CAAC,GAAG,GAAG,CAAC,OAAqD,CAAC;IACpE,OAAO,OAAO,CAAC,EAAE,UAAU,EAAE,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC;AACrF,CAAC"}
|
|
@@ -68,6 +68,10 @@ export interface HttpClientConfig {
|
|
|
68
68
|
/** Org slug for multi-tenancy — sets X-Org-Slug header on all requests */
|
|
69
69
|
orgSlug?: string;
|
|
70
70
|
}
|
|
71
|
+
/** Alphanumeric + hyphens/underscores, 1–100 chars */
|
|
72
|
+
export declare const ORG_SLUG_PATTERN: RegExp;
|
|
73
|
+
/** The header the tracker's org-context middleware reads (after `:slug` and `X-Org-Id`). */
|
|
74
|
+
export declare const ORG_SLUG_HEADER = "X-Org-Slug";
|
|
71
75
|
/**
|
|
72
76
|
* HTTP client for ops-uluops-api using native fetch
|
|
73
77
|
*/
|
|
@@ -82,6 +86,48 @@ export declare class OpsHttpClient extends HttpClient {
|
|
|
82
86
|
* @throws {InputValidationError} If `orgSlug` is present but not 1–100
|
|
83
87
|
* alphanumeric characters, hyphens, or underscores.
|
|
84
88
|
*/
|
|
89
|
+
/**
|
|
90
|
+
* Per-call org override (project-org-routing-and-rehome spec §3.2, 6.2.0).
|
|
91
|
+
* Set only on views minted by {@link withOrg}; the root client never has one.
|
|
92
|
+
*/
|
|
93
|
+
private orgOverride?;
|
|
94
|
+
/**
|
|
95
|
+
* Set instead of throwing when `withOrg` is handed an invalid slug: every
|
|
96
|
+
* method on OpsClient returns a Promise, so the caller's `.catch`/`await`
|
|
97
|
+
* must see the error — a synchronous throw from inside a non-async arrow
|
|
98
|
+
* would escape both. Surfaced as a rejection of the view's first request.
|
|
99
|
+
*/
|
|
100
|
+
private orgInvalid?;
|
|
85
101
|
constructor(config?: HttpClientConfig);
|
|
102
|
+
/**
|
|
103
|
+
* A view of this client whose every request carries `X-Org-Slug: <org>`,
|
|
104
|
+
* overriding the constructor-level `orgSlug` (per-request headers win over
|
|
105
|
+
* `defaultHeaders` in sdk-core). The view shares this client's auth
|
|
106
|
+
* strategy, fetch adapter and configuration — it is the same client, seen
|
|
107
|
+
* through one org — so a session installed on the root is honoured here.
|
|
108
|
+
*
|
|
109
|
+
* Precedence on the wire, lowest to highest: personal org (no header) <
|
|
110
|
+
* constructor `orgSlug` < this per-call `org`. An API key BOUND to an org
|
|
111
|
+
* ignores both headers and 403s (`ORG_ACCESS_DENIED`) if they name a
|
|
112
|
+
* different org — that is the platform's rule, surfaced verbatim.
|
|
113
|
+
*
|
|
114
|
+
* An invalid `org` (not 1–100 alphanumeric characters, hyphens, or
|
|
115
|
+
* underscores — the same pattern as `orgSlug`; it is a header value, so
|
|
116
|
+
* CRLF/whitespace can never reach the wire) does not throw here: the view's
|
|
117
|
+
* requests REJECT with `InputValidationError` before anything is sent, so
|
|
118
|
+
* `await client.projects.list({ org })` fails the way every other input
|
|
119
|
+
* error does.
|
|
120
|
+
*/
|
|
121
|
+
withOrg(org: string): OpsHttpClient;
|
|
122
|
+
/** The org this view is scoped to, or `undefined` on the root client. */
|
|
123
|
+
get scopedOrg(): string | undefined;
|
|
124
|
+
request<T>(method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE', endpoint: string, data?: object, options?: {
|
|
125
|
+
params?: object;
|
|
126
|
+
retries?: number;
|
|
127
|
+
retryMutations?: boolean;
|
|
128
|
+
headers?: Record<string, string>;
|
|
129
|
+
skipAuth?: boolean;
|
|
130
|
+
rawEnvelope?: boolean;
|
|
131
|
+
}): Promise<T>;
|
|
86
132
|
}
|
|
87
133
|
//# sourceMappingURL=http-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/http/http-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAKlE,OAAO,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAKzF,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,QAAQ,EACR,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,KAAK,WAAW,IAAI,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAGjE;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,GAAG,GAAG,SAAS,CAiBrE;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,4EAA4E;IAC5E,sBAAsB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,kBAAkB,EAAE,aAAa,KAAK,IAAI,CAAC;IAClF,oFAAoF;IACpF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,2EAA2E;IAC3E,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAClG;;;;OAIG;IACH,eAAe,CAAC,EAAE,oBAAoB,CAAC;IACvC,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/http/http-client.ts"],"names":[],"mappings":"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"}
|
package/dist/http/http-client.js
CHANGED
|
@@ -47,7 +47,14 @@ export function toApiQuery(query) {
|
|
|
47
47
|
return Object.keys(params).length > 0 ? params : undefined;
|
|
48
48
|
}
|
|
49
49
|
/** Alphanumeric + hyphens/underscores, 1–100 chars */
|
|
50
|
-
const ORG_SLUG_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,99}$/;
|
|
50
|
+
export const ORG_SLUG_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,99}$/;
|
|
51
|
+
/** The header the tracker's org-context middleware reads (after `:slug` and `X-Org-Id`). */
|
|
52
|
+
export const ORG_SLUG_HEADER = 'X-Org-Slug';
|
|
53
|
+
function assertOrgSlug(value, path) {
|
|
54
|
+
if (!ORG_SLUG_PATTERN.test(value)) {
|
|
55
|
+
throw new InputValidationError(`Invalid ${path}: must be 1-100 alphanumeric characters, hyphens, or underscores`, [{ code: 'custom', path: [path], message: 'must be 1-100 alphanumeric characters, hyphens, or underscores' }]);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
51
58
|
/**
|
|
52
59
|
* HTTP client for ops-uluops-api using native fetch
|
|
53
60
|
*/
|
|
@@ -62,10 +69,21 @@ export class OpsHttpClient extends HttpClient {
|
|
|
62
69
|
* @throws {InputValidationError} If `orgSlug` is present but not 1–100
|
|
63
70
|
* alphanumeric characters, hyphens, or underscores.
|
|
64
71
|
*/
|
|
72
|
+
/**
|
|
73
|
+
* Per-call org override (project-org-routing-and-rehome spec §3.2, 6.2.0).
|
|
74
|
+
* Set only on views minted by {@link withOrg}; the root client never has one.
|
|
75
|
+
*/
|
|
76
|
+
orgOverride;
|
|
77
|
+
/**
|
|
78
|
+
* Set instead of throwing when `withOrg` is handed an invalid slug: every
|
|
79
|
+
* method on OpsClient returns a Promise, so the caller's `.catch`/`await`
|
|
80
|
+
* must see the error — a synchronous throw from inside a non-async arrow
|
|
81
|
+
* would escape both. Surfaced as a rejection of the view's first request.
|
|
82
|
+
*/
|
|
83
|
+
orgInvalid;
|
|
65
84
|
constructor(config = {}) {
|
|
66
|
-
if (config.orgSlug
|
|
67
|
-
|
|
68
|
-
}
|
|
85
|
+
if (config.orgSlug)
|
|
86
|
+
assertOrgSlug(config.orgSlug, 'orgSlug');
|
|
69
87
|
super({
|
|
70
88
|
...config,
|
|
71
89
|
baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,
|
|
@@ -73,9 +91,74 @@ export class OpsHttpClient extends HttpClient {
|
|
|
73
91
|
sdkVersion: SDK_VERSION,
|
|
74
92
|
loggerPrefix: '[ops-sdk:http]',
|
|
75
93
|
defaultHeaders: {
|
|
76
|
-
...(config.orgSlug ? {
|
|
94
|
+
...(config.orgSlug ? { [ORG_SLUG_HEADER]: config.orgSlug } : {}),
|
|
77
95
|
},
|
|
78
96
|
});
|
|
79
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* A view of this client whose every request carries `X-Org-Slug: <org>`,
|
|
100
|
+
* overriding the constructor-level `orgSlug` (per-request headers win over
|
|
101
|
+
* `defaultHeaders` in sdk-core). The view shares this client's auth
|
|
102
|
+
* strategy, fetch adapter and configuration — it is the same client, seen
|
|
103
|
+
* through one org — so a session installed on the root is honoured here.
|
|
104
|
+
*
|
|
105
|
+
* Precedence on the wire, lowest to highest: personal org (no header) <
|
|
106
|
+
* constructor `orgSlug` < this per-call `org`. An API key BOUND to an org
|
|
107
|
+
* ignores both headers and 403s (`ORG_ACCESS_DENIED`) if they name a
|
|
108
|
+
* different org — that is the platform's rule, surfaced verbatim.
|
|
109
|
+
*
|
|
110
|
+
* An invalid `org` (not 1–100 alphanumeric characters, hyphens, or
|
|
111
|
+
* underscores — the same pattern as `orgSlug`; it is a header value, so
|
|
112
|
+
* CRLF/whitespace can never reach the wire) does not throw here: the view's
|
|
113
|
+
* requests REJECT with `InputValidationError` before anything is sent, so
|
|
114
|
+
* `await client.projects.list({ org })` fails the way every other input
|
|
115
|
+
* error does.
|
|
116
|
+
*/
|
|
117
|
+
withOrg(org) {
|
|
118
|
+
// `"personal"` is the reserved no-org value (the same sentinel the
|
|
119
|
+
// workspace file uses): the root client, no per-call header. It does not
|
|
120
|
+
// cancel a constructor-level `orgSlug` — that is a defaultHeader sdk-core
|
|
121
|
+
// always sends; callers that need "personal despite a constructor org"
|
|
122
|
+
// construct without one (the tracker MCP has none since 2.1.0).
|
|
123
|
+
if (org === 'personal')
|
|
124
|
+
return this;
|
|
125
|
+
// Prototype-chained view: reads (auth strategy, adapter, config) fall
|
|
126
|
+
// through to this instance; only the override fields are set on the view.
|
|
127
|
+
// sdk-core's verbs (get/post/patch/put/delete) all delegate to `request`,
|
|
128
|
+
// so the override below covers every operation without touching them.
|
|
129
|
+
const view = Object.create(this);
|
|
130
|
+
try {
|
|
131
|
+
assertOrgSlug(org, 'org');
|
|
132
|
+
view.orgOverride = org;
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
view.orgInvalid = err;
|
|
136
|
+
}
|
|
137
|
+
return view;
|
|
138
|
+
}
|
|
139
|
+
/** The org this view is scoped to, or `undefined` on the root client. */
|
|
140
|
+
get scopedOrg() {
|
|
141
|
+
return this.orgOverride;
|
|
142
|
+
}
|
|
143
|
+
request(method, endpoint, data, options) {
|
|
144
|
+
if (this.orgInvalid)
|
|
145
|
+
return Promise.reject(this.orgInvalid);
|
|
146
|
+
if (this.orgOverride === undefined)
|
|
147
|
+
return super.request(method, endpoint, data, options);
|
|
148
|
+
// The per-call org is set LAST so a caller-supplied header cannot outrank
|
|
149
|
+
// it, and an org header in `options.headers` is refused outright: until
|
|
150
|
+
// 6.3.1 the spread order let `options.headers` win, and `X-Org-Id`
|
|
151
|
+
// outranks `X-Org-Slug` on the server, so a smuggled header would have
|
|
152
|
+
// silently redirected a scoped call (run #187, circumvention A7 /
|
|
153
|
+
// trust-boundary F7 — no live caller did this; the invariant held by luck).
|
|
154
|
+
const smuggled = Object.keys(options?.headers ?? {}).find((h) => /^x-org-(slug|id)$/i.test(h));
|
|
155
|
+
if (smuggled !== undefined) {
|
|
156
|
+
return Promise.reject(new InputValidationError(`Refusing request header ${smuggled} on an org-scoped call: the per-call org (${this.orgOverride}) is the only org channel`, [{ code: 'custom', path: ['headers', smuggled], message: 'org headers may not be set per request on a scoped view' }]));
|
|
157
|
+
}
|
|
158
|
+
return super.request(method, endpoint, data, {
|
|
159
|
+
...options,
|
|
160
|
+
headers: { ...(options?.headers ?? {}), [ORG_SLUG_HEADER]: this.orgOverride },
|
|
161
|
+
});
|
|
162
|
+
}
|
|
80
163
|
}
|
|
81
164
|
//# sourceMappingURL=http-client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-client.js","sourceRoot":"","sources":["../../src/http/http-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D,2EAA2E;AAC3E,OAAO,EAAE,OAAO,EAA0C,MAAM,wBAAwB,CAAC;AAiBzF,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,UAAU,CAAC,KAAyB;IAClD,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,MAAM,GAAQ,EAAE,CAAC;IACvB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YAC3G,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC;QACnC,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,qEAAqE;YACrE,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;YACrF,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;QACD,mEAAmE;IACrE,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7D,CAAC;AAyCD,sDAAsD;AACtD,MAAM,gBAAgB,GAAG,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"http-client.js","sourceRoot":"","sources":["../../src/http/http-client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -16,4 +16,5 @@ export * from './types/index.js';
|
|
|
16
16
|
export { isValidMetric, ANALYTICS_METRICS, type AnalyticsMetric } from './operations/analytics.js';
|
|
17
17
|
export { loadCredentials, loadConfig, loadEnvFiles, type Credentials, type SdkConfig } from './config/loaders.js';
|
|
18
18
|
export { DEFAULT_BASE_URL, API_KEY_PREFIX, ENV_VARS } from './config/constants.js';
|
|
19
|
+
export { resolveWorkspaceOrg, findWorkspaceOrgFile, readWorkspaceOrgFile, WORKSPACE_ORG_FILE, PERSONAL_ORG_SENTINEL, type WorkspaceOrgResolution, type WorkspaceOrgSource, type ResolveWorkspaceOrgOptions, } from './config/workspace-org.js';
|
|
19
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACrH,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,QAAQ,EACR,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAG7H,cAAc,oBAAoB,CAAC;AAGnC,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGnG,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAClH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACrH,YAAY,EACV,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,QAAQ,EACR,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAG7H,cAAc,oBAAoB,CAAC;AAGnC,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAGnG,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAClH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,GAChC,MAAM,2BAA2B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -21,4 +21,5 @@ export { isValidMetric, ANALYTICS_METRICS } from './operations/analytics.js';
|
|
|
21
21
|
// Config — credential loading from env vars, .env files, and ~/.uluops/credentials.json
|
|
22
22
|
export { loadCredentials, loadConfig, loadEnvFiles } from './config/loaders.js';
|
|
23
23
|
export { DEFAULT_BASE_URL, API_KEY_PREFIX, ENV_VARS } from './config/constants.js';
|
|
24
|
+
export { resolveWorkspaceOrg, findWorkspaceOrgFile, readWorkspaceOrgFile, WORKSPACE_ORG_FILE, PERSONAL_ORG_SENTINEL, } from './config/workspace-org.js';
|
|
24
25
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,2DAA2D;AAC3D,OAAO,EAAE,SAAS,EAAwB,MAAM,aAAa,CAAC;AAE9D,oFAAoF;AACpF,OAAO,EAAE,aAAa,EAAiE,MAAM,uBAAuB,CAAC;AAWrH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAsC,MAAM,yBAAyB,CAAC;AAE7H,0EAA0E;AAC1E,cAAc,oBAAoB,CAAC;AAEnC,gEAAgE;AAChE,cAAc,kBAAkB,CAAC;AAEjC,mEAAmE;AACnE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAwB,MAAM,2BAA2B,CAAC;AAEnG,wFAAwF;AACxF,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAoC,MAAM,qBAAqB,CAAC;AAClH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,2DAA2D;AAC3D,OAAO,EAAE,SAAS,EAAwB,MAAM,aAAa,CAAC;AAE9D,oFAAoF;AACpF,OAAO,EAAE,aAAa,EAAiE,MAAM,uBAAuB,CAAC;AAWrH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAsC,MAAM,yBAAyB,CAAC;AAE7H,0EAA0E;AAC1E,cAAc,oBAAoB,CAAC;AAEnC,gEAAgE;AAChE,cAAc,kBAAkB,CAAC;AAEjC,mEAAmE;AACnE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAwB,MAAM,2BAA2B,CAAC;AAEnG,wFAAwF;AACxF,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAoC,MAAM,qBAAqB,CAAC;AAClH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,GAItB,MAAM,2BAA2B,CAAC"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAC;AAG3B,cAAc,WAAW,CAAC;AAG1B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAC;AAG3B,cAAc,WAAW,CAAC;AAG1B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,gBAAgB,CAAC;AAG/B,cAAc,cAAc,CAAC"}
|
package/dist/types/index.js
CHANGED
package/dist/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,cAAc,YAAY,CAAC;AAE3B,aAAa;AACb,cAAc,WAAW,CAAC;AAE1B,eAAe;AACf,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAE/B,iBAAiB;AACjB,cAAc,gBAAgB,CAAC;AAE/B,iCAAiC;AACjC,cAAc,cAAc,CAAC;AAE7B,qGAAqG"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,cAAc,YAAY,CAAC;AAE3B,aAAa;AACb,cAAc,WAAW,CAAC;AAE1B,eAAe;AACf,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAE/B,iBAAiB;AACjB,cAAc,gBAAgB,CAAC;AAE/B,iCAAiC;AACjC,cAAc,cAAc,CAAC;AAE7B,qGAAqG"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Org scoping for a single call (project-org-routing-and-rehome spec §3.2, D12).
|
|
3
|
+
*
|
|
4
|
+
* Every project, run, issue and analytics operation accepts this as its last
|
|
5
|
+
* argument. `org` is the target org's slug and becomes the `X-Org-Slug`
|
|
6
|
+
* header on that one request, overriding the client-level `orgSlug`.
|
|
7
|
+
*
|
|
8
|
+
* Omit it to use the client's `orgSlug`, or — with neither — the key-holder's
|
|
9
|
+
* personal org. The API never infers an org from a project name (spec D2):
|
|
10
|
+
* a request that names no org creates or targets the PERSONAL project of that
|
|
11
|
+
* name, even when a work org has a project by the same name. Name the org.
|
|
12
|
+
*/
|
|
13
|
+
export interface OrgScopedOptions {
|
|
14
|
+
/** Org slug (1–100 chars: alphanumeric, hyphen, underscore). */
|
|
15
|
+
org?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Run write/preview options: client-side validation escape hatch + org scope. */
|
|
18
|
+
export interface RunCallOptions extends OrgScopedOptions {
|
|
19
|
+
/**
|
|
20
|
+
* Skip the SDK's input validation. A convenience escape for pre-validated
|
|
21
|
+
* callers (MCP, autosave hooks); the server validates regardless.
|
|
22
|
+
*/
|
|
23
|
+
_skipClientValidation?: boolean;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=org.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org.d.ts","sourceRoot":"","sources":["../../src/types/org.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,kFAAkF;AAClF,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org.js","sourceRoot":"","sources":["../../src/types/org.ts"],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uluops/ops-sdk",
|
|
3
|
-
"version": "6.1
|
|
3
|
+
"version": "6.3.1",
|
|
4
4
|
"description": "Track execution runs, manage issues, and query analytics against the UluOps platform API — typed TypeScript client with Zod runtime validation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|