@ttctl/core 0.0.0 → 0.1.0-rc.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/README.md +49 -9
- package/dist/__generated__/gateway.d.ts +4546 -0
- package/dist/__generated__/gateway.d.ts.map +1 -0
- package/dist/__generated__/gateway.js +9 -0
- package/dist/__generated__/gateway.js.map +1 -0
- package/dist/__generated__/talent-profile-zod-schemas.d.ts +1187 -0
- package/dist/__generated__/talent-profile-zod-schemas.d.ts.map +1 -0
- package/dist/__generated__/talent-profile-zod-schemas.js +1136 -0
- package/dist/__generated__/talent-profile-zod-schemas.js.map +1 -0
- package/dist/__generated__/talent-profile.d.ts +1397 -0
- package/dist/__generated__/talent-profile.d.ts.map +1 -0
- package/dist/__generated__/talent-profile.js +9 -0
- package/dist/__generated__/talent-profile.js.map +1 -0
- package/dist/__generated__/zod-schemas.d.ts +2895 -0
- package/dist/__generated__/zod-schemas.d.ts.map +1 -0
- package/dist/__generated__/zod-schemas.js +3121 -0
- package/dist/__generated__/zod-schemas.js.map +1 -0
- package/dist/__tests__/fixtures/profile/builders.d.ts +74 -0
- package/dist/__tests__/fixtures/profile/builders.d.ts.map +1 -0
- package/dist/__tests__/fixtures/profile/builders.js +196 -0
- package/dist/__tests__/fixtures/profile/builders.js.map +1 -0
- package/dist/__tests__/fixtures/profile/data.d.ts +39 -0
- package/dist/__tests__/fixtures/profile/data.d.ts.map +1 -0
- package/dist/__tests__/fixtures/profile/data.js +230 -0
- package/dist/__tests__/fixtures/profile/data.js.map +1 -0
- package/dist/__tests__/fixtures/profile/index.d.ts +9 -0
- package/dist/__tests__/fixtures/profile/index.d.ts.map +1 -0
- package/dist/__tests__/fixtures/profile/index.js +10 -0
- package/dist/__tests__/fixtures/profile/index.js.map +1 -0
- package/dist/__tests__/fixtures/profile/types.d.ts +53 -0
- package/dist/__tests__/fixtures/profile/types.d.ts.map +1 -0
- package/dist/__tests__/fixtures/profile/types.js +4 -0
- package/dist/__tests__/fixtures/profile/types.js.map +1 -0
- package/dist/auth/errors.d.ts +82 -0
- package/dist/auth/errors.d.ts.map +1 -0
- package/dist/auth/errors.js +68 -0
- package/dist/auth/errors.js.map +1 -0
- package/dist/auth.d.ts +192 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +294 -0
- package/dist/auth.js.map +1 -0
- package/dist/config.d.ts +212 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +349 -0
- package/dist/config.js.map +1 -0
- package/dist/configLock.d.ts +50 -0
- package/dist/configLock.d.ts.map +1 -0
- package/dist/configLock.js +88 -0
- package/dist/configLock.js.map +1 -0
- package/dist/configWriter.d.ts +97 -0
- package/dist/configWriter.d.ts.map +1 -0
- package/dist/configWriter.js +687 -0
- package/dist/configWriter.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/kill-switch.d.ts +161 -0
- package/dist/kill-switch.d.ts.map +1 -0
- package/dist/kill-switch.js +235 -0
- package/dist/kill-switch.js.map +1 -0
- package/dist/lib/date.d.ts +58 -0
- package/dist/lib/date.d.ts.map +1 -0
- package/dist/lib/date.js +104 -0
- package/dist/lib/date.js.map +1 -0
- package/dist/lib/diagnostic-log.d.ts +159 -0
- package/dist/lib/diagnostic-log.d.ts.map +1 -0
- package/dist/lib/diagnostic-log.js +186 -0
- package/dist/lib/diagnostic-log.js.map +1 -0
- package/dist/lib/package-version.d.ts +19 -0
- package/dist/lib/package-version.d.ts.map +1 -0
- package/dist/lib/package-version.js +38 -0
- package/dist/lib/package-version.js.map +1 -0
- package/dist/lib/redact.d.ts +153 -0
- package/dist/lib/redact.d.ts.map +1 -0
- package/dist/lib/redact.js +207 -0
- package/dist/lib/redact.js.map +1 -0
- package/dist/lib/text.d.ts +14 -0
- package/dist/lib/text.d.ts.map +1 -0
- package/dist/lib/text.js +21 -0
- package/dist/lib/text.js.map +1 -0
- package/dist/lib/wire-shape.d.ts +131 -0
- package/dist/lib/wire-shape.d.ts.map +1 -0
- package/dist/lib/wire-shape.js +376 -0
- package/dist/lib/wire-shape.js.map +1 -0
- package/dist/onepassword.d.ts +29 -0
- package/dist/onepassword.d.ts.map +1 -0
- package/dist/onepassword.js +112 -0
- package/dist/onepassword.js.map +1 -0
- package/dist/services/_shared/transport.d.ts +148 -0
- package/dist/services/_shared/transport.d.ts.map +1 -0
- package/dist/services/_shared/transport.js +102 -0
- package/dist/services/_shared/transport.js.map +1 -0
- package/dist/services/applications/index.d.ts +210 -0
- package/dist/services/applications/index.d.ts.map +1 -0
- package/dist/services/applications/index.js +240 -0
- package/dist/services/applications/index.js.map +1 -0
- package/dist/services/availability/index.d.ts +254 -0
- package/dist/services/availability/index.d.ts.map +1 -0
- package/dist/services/availability/index.js +310 -0
- package/dist/services/availability/index.js.map +1 -0
- package/dist/services/contracts/index.d.ts +132 -0
- package/dist/services/contracts/index.d.ts.map +1 -0
- package/dist/services/contracts/index.js +211 -0
- package/dist/services/contracts/index.js.map +1 -0
- package/dist/services/engagements/index.d.ts +504 -0
- package/dist/services/engagements/index.d.ts.map +1 -0
- package/dist/services/engagements/index.js +613 -0
- package/dist/services/engagements/index.js.map +1 -0
- package/dist/services/jobs/index.d.ts +490 -0
- package/dist/services/jobs/index.d.ts.map +1 -0
- package/dist/services/jobs/index.js +753 -0
- package/dist/services/jobs/index.js.map +1 -0
- package/dist/services/payments/index.d.ts +415 -0
- package/dist/services/payments/index.d.ts.map +1 -0
- package/dist/services/payments/index.js +636 -0
- package/dist/services/payments/index.js.map +1 -0
- package/dist/services/profile/__tests__/fixtures.d.ts +214 -0
- package/dist/services/profile/__tests__/fixtures.d.ts.map +1 -0
- package/dist/services/profile/__tests__/fixtures.js +176 -0
- package/dist/services/profile/__tests__/fixtures.js.map +1 -0
- package/dist/services/profile/basic/index.d.ts +390 -0
- package/dist/services/profile/basic/index.d.ts.map +1 -0
- package/dist/services/profile/basic/index.js +1007 -0
- package/dist/services/profile/basic/index.js.map +1 -0
- package/dist/services/profile/certifications/index.d.ts +74 -0
- package/dist/services/profile/certifications/index.d.ts.map +1 -0
- package/dist/services/profile/certifications/index.js +169 -0
- package/dist/services/profile/certifications/index.js.map +1 -0
- package/dist/services/profile/education/index.d.ts +73 -0
- package/dist/services/profile/education/index.d.ts.map +1 -0
- package/dist/services/profile/education/index.js +168 -0
- package/dist/services/profile/education/index.js.map +1 -0
- package/dist/services/profile/employment/index.d.ts +111 -0
- package/dist/services/profile/employment/index.d.ts.map +1 -0
- package/dist/services/profile/employment/index.js +202 -0
- package/dist/services/profile/employment/index.js.map +1 -0
- package/dist/services/profile/external/index.d.ts +219 -0
- package/dist/services/profile/external/index.d.ts.map +1 -0
- package/dist/services/profile/external/index.js +560 -0
- package/dist/services/profile/external/index.js.map +1 -0
- package/dist/services/profile/index.d.ts +24 -0
- package/dist/services/profile/index.d.ts.map +1 -0
- package/dist/services/profile/index.js +26 -0
- package/dist/services/profile/index.js.map +1 -0
- package/dist/services/profile/industries/index.d.ts +130 -0
- package/dist/services/profile/industries/index.d.ts.map +1 -0
- package/dist/services/profile/industries/index.js +292 -0
- package/dist/services/profile/industries/index.js.map +1 -0
- package/dist/services/profile/portfolio/index.d.ts +352 -0
- package/dist/services/profile/portfolio/index.d.ts.map +1 -0
- package/dist/services/profile/portfolio/index.js +833 -0
- package/dist/services/profile/portfolio/index.js.map +1 -0
- package/dist/services/profile/resume/index.d.ts +60 -0
- package/dist/services/profile/resume/index.d.ts.map +1 -0
- package/dist/services/profile/resume/index.js +212 -0
- package/dist/services/profile/resume/index.js.map +1 -0
- package/dist/services/profile/reviews/index.d.ts +137 -0
- package/dist/services/profile/reviews/index.d.ts.map +1 -0
- package/dist/services/profile/reviews/index.js +431 -0
- package/dist/services/profile/reviews/index.js.map +1 -0
- package/dist/services/profile/shared.d.ts +127 -0
- package/dist/services/profile/shared.d.ts.map +1 -0
- package/dist/services/profile/shared.js +155 -0
- package/dist/services/profile/shared.js.map +1 -0
- package/dist/services/profile/skills/index.d.ts +212 -0
- package/dist/services/profile/skills/index.d.ts.map +1 -0
- package/dist/services/profile/skills/index.js +461 -0
- package/dist/services/profile/skills/index.js.map +1 -0
- package/dist/services/profile/visas/index.d.ts +74 -0
- package/dist/services/profile/visas/index.d.ts.map +1 -0
- package/dist/services/profile/visas/index.js +306 -0
- package/dist/services/profile/visas/index.js.map +1 -0
- package/dist/services/timesheet/index.d.ts +326 -0
- package/dist/services/timesheet/index.d.ts.map +1 -0
- package/dist/services/timesheet/index.js +324 -0
- package/dist/services/timesheet/index.js.map +1 -0
- package/dist/services/translations.d.ts +79 -0
- package/dist/services/translations.d.ts.map +1 -0
- package/dist/services/translations.js +136 -0
- package/dist/services/translations.js.map +1 -0
- package/dist/transport-resilience.d.ts +136 -0
- package/dist/transport-resilience.d.ts.map +1 -0
- package/dist/transport-resilience.js +247 -0
- package/dist/transport-resilience.js.map +1 -0
- package/dist/transport.d.ts +408 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +691 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +18 -0
- package/dist/types.js.map +1 -0
- package/package.json +40 -12
- package/index.js +0 -7
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared GraphQL transport wrapper for service modules (issue #329).
|
|
3
|
+
*
|
|
4
|
+
* Replaces 8 near-identical `callGateway` / `callTalentProfile`
|
|
5
|
+
* helpers that previously lived inside individual service files
|
|
6
|
+
* (`services/{applications,availability,contracts,engagements,jobs,
|
|
7
|
+
* payments,profile/skills,timesheet}`). The Zod-validation hook
|
|
8
|
+
* (`buildWireShapeError`, Z-3 / #286) used to be duplicated across 9
|
|
9
|
+
* sites; here it lives once.
|
|
10
|
+
*
|
|
11
|
+
* The per-service helpers all shared a common envelope but differed in
|
|
12
|
+
* three bounded ways:
|
|
13
|
+
*
|
|
14
|
+
* 1. **Surface**: mobile-gateway (via `stockTransport`) or
|
|
15
|
+
* talent-profile (via `impersonatedTransport`). Resolved here by
|
|
16
|
+
* delegating to `callSurface`, which dispatches based on
|
|
17
|
+
* `SURFACES_REQUIRING_IMPERSONATION`.
|
|
18
|
+
* 2. **Domain error class**: each service threw its own typed error
|
|
19
|
+
* (`ApplicationsError`, `JobsError`, …) so callers can pattern-
|
|
20
|
+
* match `instanceof ServiceError && err.code === "GRAPHQL_ERROR"`
|
|
21
|
+
* without importing a cross-domain enum. We accept the class
|
|
22
|
+
* itself via the `errorFactory` parameter and instantiate it
|
|
23
|
+
* with the code strings every existing helper already used.
|
|
24
|
+
* 3. **Viewer-binding check**: `applications` requires that the
|
|
25
|
+
* response include a non-null `viewer` (the gateway treats a
|
|
26
|
+
* missing viewer as "session valid but no viewer bound", which
|
|
27
|
+
* should surface as `NO_VIEWER` rather than a generic error). All
|
|
28
|
+
* other services omit this check. Toggled via
|
|
29
|
+
* `opts.requireViewer`.
|
|
30
|
+
*
|
|
31
|
+
* `profile/shared.ts#callTalentProfile` remains a separate helper for
|
|
32
|
+
* the moment because its signature differs (it returns the raw
|
|
33
|
+
* `TransportResponse`, takes a `verb` parameter for error tagging, and
|
|
34
|
+
* defers top-level error handling to `ensureNoTopLevelErrors`). The 4
|
|
35
|
+
* profile sub-domains (`industries`, `education`, `employment`,
|
|
36
|
+
* `certifications`) consume it, so a separate migration will handle
|
|
37
|
+
* that consolidation — see #329 follow-up.
|
|
38
|
+
*
|
|
39
|
+
* @see {@link callGatewayShared}
|
|
40
|
+
*/
|
|
41
|
+
import type { z } from "zod";
|
|
42
|
+
import type { ToptalSurface } from "../../types.js";
|
|
43
|
+
/**
|
|
44
|
+
* Codes that {@link callGatewayShared} may throw via its
|
|
45
|
+
* {@link DomainErrorFactory}. Every consuming service's per-domain
|
|
46
|
+
* error code union (e.g. `ApplicationsErrorCode`, `JobsErrorCode`)
|
|
47
|
+
* must be a superset of this set (plus its own domain-specific
|
|
48
|
+
* extensions like `NOT_FOUND`).
|
|
49
|
+
*
|
|
50
|
+
* `NO_VIEWER` is included unconditionally even though only callers
|
|
51
|
+
* passing `opts.requireViewer: true` will see it — services that
|
|
52
|
+
* don't opt into the viewer check still need their factory's code
|
|
53
|
+
* union to permit it for the parameter type to satisfy the factory
|
|
54
|
+
* signature. The runtime never throws `NO_VIEWER` for these services.
|
|
55
|
+
*/
|
|
56
|
+
export type SharedTransportErrorCode = "NETWORK_ERROR" | "GRAPHQL_ERROR" | "WIRE_SHAPE_ERROR" | "NO_VIEWER" | "UNKNOWN";
|
|
57
|
+
/**
|
|
58
|
+
* Constructor signature for any domain-error class consumed by
|
|
59
|
+
* {@link callGatewayShared}.
|
|
60
|
+
*
|
|
61
|
+
* The `code` parameter is typed as {@link SharedTransportErrorCode}.
|
|
62
|
+
* Each consuming service's domain error code union
|
|
63
|
+
* (e.g. `ApplicationsErrorCode`, `JobsErrorCode`) must be a
|
|
64
|
+
* **superset** of {@link SharedTransportErrorCode} — i.e., every
|
|
65
|
+
* shared code is one of the domain's accepted code strings. Under
|
|
66
|
+
* TypeScript's constructor-parameter contravariance, a class whose
|
|
67
|
+
* constructor accepts a wider code union (e.g.
|
|
68
|
+
* `ApplicationsErrorCode = "NO_VIEWER" | "NOT_FOUND" | …shared codes`)
|
|
69
|
+
* satisfies `new (code: SharedTransportErrorCode, …) => ApplicationsError`.
|
|
70
|
+
*
|
|
71
|
+
* This is verified at compile time at every `callGatewayShared` call
|
|
72
|
+
* site: passing a domain error class whose code union is missing a
|
|
73
|
+
* shared code (e.g. lacks `NO_VIEWER`) raises an assignment error.
|
|
74
|
+
*/
|
|
75
|
+
export interface DomainErrorFactory<E extends Error> {
|
|
76
|
+
new (code: SharedTransportErrorCode, message: string, options?: {
|
|
77
|
+
cause?: unknown;
|
|
78
|
+
}): E;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Optional knobs for {@link callGatewayShared}.
|
|
82
|
+
*/
|
|
83
|
+
export interface CallGatewaySharedOptions<T> {
|
|
84
|
+
/**
|
|
85
|
+
* Zod schema applied to `body.data` before returning. On parse
|
|
86
|
+
* failure the helper throws `errorFactory("WIRE_SHAPE_ERROR", …)`
|
|
87
|
+
* with the original {@link z.ZodError} chained via `cause` and a
|
|
88
|
+
* field-level diff in the message per
|
|
89
|
+
* `docs/wire-validation-error-format.md` (Z-3 / #286). When
|
|
90
|
+
* omitted, the existing pass-through behavior is preserved.
|
|
91
|
+
*
|
|
92
|
+
* `| undefined` accommodates `exactOptionalPropertyTypes` — per-
|
|
93
|
+
* service wrappers thread their own `schema?: z.ZodType<T>`
|
|
94
|
+
* parameter through unchanged (which may be `undefined`).
|
|
95
|
+
*/
|
|
96
|
+
schema?: z.ZodType<T> | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* When `true`, the helper additionally narrows `data` to
|
|
99
|
+
* `{ viewer: { id: string } | null }` and throws
|
|
100
|
+
* `errorFactory("NO_VIEWER", …)` if `data.viewer === null`. Used
|
|
101
|
+
* by `applications` (the gateway returns `viewer === null` when
|
|
102
|
+
* the session is technically valid but no viewer is bound — e.g.
|
|
103
|
+
* the bearer maps to a non-talent account). Other services either
|
|
104
|
+
* use schemas that already constrain `viewer` or don't carry a
|
|
105
|
+
* `viewer` field in their wire shape.
|
|
106
|
+
*/
|
|
107
|
+
requireViewer?: boolean | undefined;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Fire a GraphQL request against a Toptal surface and turn
|
|
111
|
+
* transport-level outcomes into a typed domain error.
|
|
112
|
+
*
|
|
113
|
+
* Surface routing: {@link impersonatedTransport} for surfaces in
|
|
114
|
+
* {@link SURFACES_REQUIRING_IMPERSONATION} (talent-profile,
|
|
115
|
+
* scheduler), {@link stockTransport} otherwise (mobile-gateway).
|
|
116
|
+
* Routing is inlined here rather than delegating to `callSurface`
|
|
117
|
+
* because existing service-level tests mock these transport
|
|
118
|
+
* functions directly via `vi.mock("../../transport.js", …)`;
|
|
119
|
+
* routing through `callSurface` would bypass those mocks
|
|
120
|
+
* (the function captures a closure reference at module-load time).
|
|
121
|
+
*
|
|
122
|
+
* Error mapping:
|
|
123
|
+
* - {@link TtctlError} subclasses ({@link AuthRevokedError},
|
|
124
|
+
* `Cf403Error`, etc.) propagate as-is so the CLI / MCP surfaces
|
|
125
|
+
* apply uniform `recovery` rendering.
|
|
126
|
+
* - Other transport throws → `errorFactory("NETWORK_ERROR", …)`.
|
|
127
|
+
* - HTTP 401 → {@link AuthRevokedError}.
|
|
128
|
+
* - Non-2xx → `errorFactory("UNKNOWN", …)`.
|
|
129
|
+
* - Top-level `errors[]` with an auth-revoked extension code (per
|
|
130
|
+
* {@link isAuthRevokedExtensionCode}) → {@link AuthRevokedError}.
|
|
131
|
+
* - Top-level `errors[]` otherwise → `errorFactory("GRAPHQL_ERROR", …)`
|
|
132
|
+
* with the offending {@link GraphQLErrorEntry} chained via `cause`
|
|
133
|
+
* (callers that remap to a domain-specific code — e.g. contracts
|
|
134
|
+
* translating `Record not found` to `NOT_FOUND` — can lift the wire
|
|
135
|
+
* message off `err.cause.message` without parsing `err.message`).
|
|
136
|
+
* - Missing `data` field → `errorFactory("UNKNOWN", …)`.
|
|
137
|
+
* - Zod parse failure (when `schema` provided) →
|
|
138
|
+
* `errorFactory("WIRE_SHAPE_ERROR", …)` carrying the diff payload.
|
|
139
|
+
* - `data.viewer === null` (when `requireViewer` true) →
|
|
140
|
+
* `errorFactory("NO_VIEWER", …)`.
|
|
141
|
+
*
|
|
142
|
+
* Returns the validated `body.data` narrowed to `T`. When `schema` is
|
|
143
|
+
* omitted, the cast is unverified — callers should provide a schema
|
|
144
|
+
* for any operation whose wire shape is gappy in the synthesized SDL
|
|
145
|
+
* (CLAUDE.md § Track 1 vs Track 2 disposition).
|
|
146
|
+
*/
|
|
147
|
+
export declare function callGatewayShared<T, E extends Error>(surface: ToptalSurface, token: string, operationName: string, query: string, variables: Record<string, unknown>, errorFactory: DomainErrorFactory<E>, opts?: CallGatewaySharedOptions<T>): Promise<T>;
|
|
148
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../../src/services/_shared/transport.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAO7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAIpD;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,wBAAwB,GAAG,eAAe,GAAG,eAAe,GAAG,kBAAkB,GAAG,WAAW,GAAG,SAAS,CAAC;AAExH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,KAAK;IACjD,KAAK,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,CAAC,CAAC;CACzF;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB,CAAC,CAAC;IACzC;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAClC;;;;;;;;;OASG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACrC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,CAAC,SAAS,KAAK,EACxD,OAAO,EAAE,aAAa,EACtB,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,YAAY,EAAE,kBAAkB,CAAC,CAAC,CAAC,EACnC,IAAI,CAAC,EAAE,wBAAwB,CAAC,CAAC,CAAC,GACjC,OAAO,CAAC,CAAC,CAAC,CAyDZ"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { AuthRevokedError, TtctlError } from "../../auth/errors.js";
|
|
4
|
+
import { buildWireShapeError } from "../../lib/wire-shape.js";
|
|
5
|
+
import { impersonatedTransport, stockTransport } from "../../transport.js";
|
|
6
|
+
import { SURFACES_REQUIRING_IMPERSONATION } from "../../types.js";
|
|
7
|
+
import { isAuthRevokedExtensionCode } from "../profile/shared.js";
|
|
8
|
+
/**
|
|
9
|
+
* Fire a GraphQL request against a Toptal surface and turn
|
|
10
|
+
* transport-level outcomes into a typed domain error.
|
|
11
|
+
*
|
|
12
|
+
* Surface routing: {@link impersonatedTransport} for surfaces in
|
|
13
|
+
* {@link SURFACES_REQUIRING_IMPERSONATION} (talent-profile,
|
|
14
|
+
* scheduler), {@link stockTransport} otherwise (mobile-gateway).
|
|
15
|
+
* Routing is inlined here rather than delegating to `callSurface`
|
|
16
|
+
* because existing service-level tests mock these transport
|
|
17
|
+
* functions directly via `vi.mock("../../transport.js", …)`;
|
|
18
|
+
* routing through `callSurface` would bypass those mocks
|
|
19
|
+
* (the function captures a closure reference at module-load time).
|
|
20
|
+
*
|
|
21
|
+
* Error mapping:
|
|
22
|
+
* - {@link TtctlError} subclasses ({@link AuthRevokedError},
|
|
23
|
+
* `Cf403Error`, etc.) propagate as-is so the CLI / MCP surfaces
|
|
24
|
+
* apply uniform `recovery` rendering.
|
|
25
|
+
* - Other transport throws → `errorFactory("NETWORK_ERROR", …)`.
|
|
26
|
+
* - HTTP 401 → {@link AuthRevokedError}.
|
|
27
|
+
* - Non-2xx → `errorFactory("UNKNOWN", …)`.
|
|
28
|
+
* - Top-level `errors[]` with an auth-revoked extension code (per
|
|
29
|
+
* {@link isAuthRevokedExtensionCode}) → {@link AuthRevokedError}.
|
|
30
|
+
* - Top-level `errors[]` otherwise → `errorFactory("GRAPHQL_ERROR", …)`
|
|
31
|
+
* with the offending {@link GraphQLErrorEntry} chained via `cause`
|
|
32
|
+
* (callers that remap to a domain-specific code — e.g. contracts
|
|
33
|
+
* translating `Record not found` to `NOT_FOUND` — can lift the wire
|
|
34
|
+
* message off `err.cause.message` without parsing `err.message`).
|
|
35
|
+
* - Missing `data` field → `errorFactory("UNKNOWN", …)`.
|
|
36
|
+
* - Zod parse failure (when `schema` provided) →
|
|
37
|
+
* `errorFactory("WIRE_SHAPE_ERROR", …)` carrying the diff payload.
|
|
38
|
+
* - `data.viewer === null` (when `requireViewer` true) →
|
|
39
|
+
* `errorFactory("NO_VIEWER", …)`.
|
|
40
|
+
*
|
|
41
|
+
* Returns the validated `body.data` narrowed to `T`. When `schema` is
|
|
42
|
+
* omitted, the cast is unverified — callers should provide a schema
|
|
43
|
+
* for any operation whose wire shape is gappy in the synthesized SDL
|
|
44
|
+
* (CLAUDE.md § Track 1 vs Track 2 disposition).
|
|
45
|
+
*/
|
|
46
|
+
export async function callGatewayShared(surface, token, operationName, query, variables, errorFactory, opts) {
|
|
47
|
+
const transport = SURFACES_REQUIRING_IMPERSONATION.has(surface) ? impersonatedTransport : stockTransport;
|
|
48
|
+
let res;
|
|
49
|
+
try {
|
|
50
|
+
res = await transport({
|
|
51
|
+
surface,
|
|
52
|
+
authToken: token,
|
|
53
|
+
body: { operationName, query, variables },
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
if (err instanceof TtctlError)
|
|
58
|
+
throw err;
|
|
59
|
+
throw new errorFactory("NETWORK_ERROR", `${operationName} request failed: ${err.message}`, {
|
|
60
|
+
cause: err,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
if (res.status === 401) {
|
|
64
|
+
throw new AuthRevokedError("Session is invalid or expired.");
|
|
65
|
+
}
|
|
66
|
+
if (res.status < 200 || res.status >= 300) {
|
|
67
|
+
throw new errorFactory("UNKNOWN", `${operationName} returned HTTP ${res.status.toString()}`);
|
|
68
|
+
}
|
|
69
|
+
const body = res.body;
|
|
70
|
+
if (body && Array.isArray(body.errors) && body.errors.length > 0) {
|
|
71
|
+
const first = body.errors[0];
|
|
72
|
+
if (isAuthRevokedExtensionCode(first?.extensions?.code)) {
|
|
73
|
+
throw new AuthRevokedError("Session is invalid or expired.");
|
|
74
|
+
}
|
|
75
|
+
throw new errorFactory("GRAPHQL_ERROR", `${operationName} failed: ${first?.message ?? "GraphQL error"}`, {
|
|
76
|
+
cause: first,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (!body?.data) {
|
|
80
|
+
throw new errorFactory("UNKNOWN", `${operationName} response had no \`data\` field`);
|
|
81
|
+
}
|
|
82
|
+
let data;
|
|
83
|
+
if (opts?.schema !== undefined) {
|
|
84
|
+
const parsed = opts.schema.safeParse(body.data);
|
|
85
|
+
if (!parsed.success) {
|
|
86
|
+
const payload = buildWireShapeError(operationName, parsed.error, body.data);
|
|
87
|
+
throw new errorFactory("WIRE_SHAPE_ERROR", payload.message, { cause: parsed.error });
|
|
88
|
+
}
|
|
89
|
+
data = parsed.data;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
data = body.data;
|
|
93
|
+
}
|
|
94
|
+
if (opts?.requireViewer === true) {
|
|
95
|
+
const withViewer = data;
|
|
96
|
+
if (withViewer.viewer === null) {
|
|
97
|
+
throw new errorFactory("NO_VIEWER", "Session is valid but no viewer is bound to it.");
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return data;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/services/_shared/transport.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AA6CpC,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAE3E,OAAO,EAAE,gCAAgC,EAAE,MAAM,gBAAgB,CAAC;AAElE,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAsElE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAsB,EACtB,KAAa,EACb,aAAqB,EACrB,KAAa,EACb,SAAkC,EAClC,YAAmC,EACnC,IAAkC;IAElC,MAAM,SAAS,GAAG,gCAAgC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,cAAc,CAAC;IACzG,IAAI,GAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,SAAS,CAAC;YACpB,OAAO;YACP,SAAS,EAAE,KAAK;YAChB,IAAI,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,SAAS,EAAE;SAC1C,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,UAAU;YAAE,MAAM,GAAG,CAAC;QACzC,MAAM,IAAI,YAAY,CAAC,eAAe,EAAE,GAAG,aAAa,oBAAqB,GAAa,CAAC,OAAO,EAAE,EAAE;YACpG,KAAK,EAAE,GAAG;SACX,CAAC,CAAC;IACL,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACvB,MAAM,IAAI,gBAAgB,CAAC,gCAAgC,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;QAC1C,MAAM,IAAI,YAAY,CAAC,SAAS,EAAE,GAAG,aAAa,kBAAkB,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC/F,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,CAAC,IAAuE,CAAC;IACzF,IAAI,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,0BAA0B,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,gBAAgB,CAAC,gCAAgC,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,IAAI,YAAY,CAAC,eAAe,EAAE,GAAG,aAAa,YAAY,KAAK,EAAE,OAAO,IAAI,eAAe,EAAE,EAAE;YACvG,KAAK,EAAE,KAAK;SACb,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QAChB,MAAM,IAAI,YAAY,CAAC,SAAS,EAAE,GAAG,aAAa,iCAAiC,CAAC,CAAC;IACvF,CAAC;IAED,IAAI,IAAO,CAAC;IACZ,IAAI,IAAI,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,OAAO,GAAG,mBAAmB,CAAC,aAAa,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5E,MAAM,IAAI,YAAY,CAAC,kBAAkB,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QACvF,CAAC;QACD,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,IAAI,IAAI,EAAE,aAAa,KAAK,IAAI,EAAE,CAAC;QACjC,MAAM,UAAU,GAAG,IAAoD,CAAC;QACxE,IAAI,UAAU,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC/B,MAAM,IAAI,YAAY,CAAC,WAAW,EAAE,gDAAgD,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Applications-domain error codes. Mirrors the `ProfileError` /
|
|
3
|
+
* `SkillsError` shape per project convention so each sub-domain carries
|
|
4
|
+
* its own typed error class without callers having to import a shared
|
|
5
|
+
* cross-domain enum. Auth-revoked failures throw `AuthRevokedError`
|
|
6
|
+
* (cross-cutting `TtctlError` subclass per #77), not a code on this
|
|
7
|
+
* enum.
|
|
8
|
+
*
|
|
9
|
+
* `NOT_FOUND` is specific to `show()`: the gateway returns a successful
|
|
10
|
+
* response with `viewer.jobActivityItem === null` when the supplied id
|
|
11
|
+
* doesn't resolve to an item the signed-in user can see (no separate
|
|
12
|
+
* 404 status). The service translates that explicit null to a typed
|
|
13
|
+
* `NOT_FOUND` so the CLI can render a "no such application" line and
|
|
14
|
+
* the MCP tool can return a structured `(NOT_FOUND)` error response.
|
|
15
|
+
*/
|
|
16
|
+
export type ApplicationsErrorCode = "NO_VIEWER" | "NOT_FOUND" | "GRAPHQL_ERROR" | "NETWORK_ERROR" | "WIRE_SHAPE_ERROR" | "UNKNOWN";
|
|
17
|
+
export declare class ApplicationsError extends Error {
|
|
18
|
+
readonly code: ApplicationsErrorCode;
|
|
19
|
+
readonly name = "ApplicationsError";
|
|
20
|
+
constructor(code: ApplicationsErrorCode, message: string, options?: {
|
|
21
|
+
cause?: unknown;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The five known values of `JobActivityItemStatusGroupEnum` from the
|
|
26
|
+
* synthesized schema (`../research/graphql/gateway/schema.graphql`
|
|
27
|
+
* line 176). Re-declared here as a literal-typed tuple so consumers
|
|
28
|
+
* (CLI flag validation, MCP `z.enum`, `stats()` iteration) share one
|
|
29
|
+
* source of truth without depending on the codegen output.
|
|
30
|
+
*
|
|
31
|
+
* Order matches the schema declaration. `stats()` iterates this array
|
|
32
|
+
* to issue one count call per group.
|
|
33
|
+
*/
|
|
34
|
+
export declare const STATUS_GROUPS: readonly ["ACTIVE_ENGAGEMENT", "ARCHIVED", "CLOSED_ENGAGEMENT", "ON_CLIENT_REVIEW", "ON_RECRUITER_REVIEW"];
|
|
35
|
+
export type StatusGroup = (typeof STATUS_GROUPS)[number];
|
|
36
|
+
/**
|
|
37
|
+
* Optional list filter — both fields fold straight into the captured
|
|
38
|
+
* operation's variables (`keywords`, `onlyStatusGroupFilter`).
|
|
39
|
+
*/
|
|
40
|
+
export interface ListOptions {
|
|
41
|
+
/**
|
|
42
|
+
* Free-text keyword filter. Each entry is matched server-side against
|
|
43
|
+
* job title, client name, and other indexed fields. Multiple keywords
|
|
44
|
+
* AND together (per observed behavior in the mobile app).
|
|
45
|
+
*/
|
|
46
|
+
keywords?: string[];
|
|
47
|
+
/**
|
|
48
|
+
* Restrict the list to one or more status groups. When omitted the
|
|
49
|
+
* server returns rows from every group.
|
|
50
|
+
*/
|
|
51
|
+
statusGroups?: StatusGroup[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Status payload — both `statusV2` (specific) and `statusGroupV2`
|
|
55
|
+
* (coarse, one of {@link STATUS_GROUPS}) carry the same shape on the
|
|
56
|
+
* wire. `verbose` is the human-readable label the Toptal UI shows
|
|
57
|
+
* (e.g. "Active Engagement", "Archived").
|
|
58
|
+
*/
|
|
59
|
+
export interface ApplicationStatus {
|
|
60
|
+
value: string;
|
|
61
|
+
verbose: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Reference to a job an activity row points at. The full `TalentJob`
|
|
65
|
+
* type carries 30+ fields; this projection surfaces only what `list` /
|
|
66
|
+
* `show` render. `client.fullName` is the company name as the user
|
|
67
|
+
* sees it.
|
|
68
|
+
*/
|
|
69
|
+
export interface ApplicationJobRef {
|
|
70
|
+
id: string;
|
|
71
|
+
title: string | null;
|
|
72
|
+
url: string | null;
|
|
73
|
+
client: {
|
|
74
|
+
id: string;
|
|
75
|
+
fullName: string | null;
|
|
76
|
+
} | null;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* One row in the activity list — the CLI's `applications list` and the
|
|
80
|
+
* MCP's `ttctl_applications_list` both surface this shape. `engagement`,
|
|
81
|
+
* `jobApplication`, `availabilityRequest`, and `interview` are all
|
|
82
|
+
* presence indicators (only `id` is selected) — a non-null value tells
|
|
83
|
+
* the consumer "this row has reached the corresponding lifecycle
|
|
84
|
+
* stage". The `mostRelevantApplication` union from the captured
|
|
85
|
+
* operation is intentionally elided here: it duplicates information
|
|
86
|
+
* `jobApplication` / `availabilityRequest` already carry.
|
|
87
|
+
*/
|
|
88
|
+
export interface JobActivityItem {
|
|
89
|
+
id: string;
|
|
90
|
+
statusV2: ApplicationStatus;
|
|
91
|
+
statusGroupV2: ApplicationStatus;
|
|
92
|
+
statusColor: string | null;
|
|
93
|
+
lastUpdatedAt: string;
|
|
94
|
+
job: ApplicationJobRef;
|
|
95
|
+
jobApplication: {
|
|
96
|
+
id: string;
|
|
97
|
+
} | null;
|
|
98
|
+
engagement: {
|
|
99
|
+
id: string;
|
|
100
|
+
} | null;
|
|
101
|
+
availabilityRequest: {
|
|
102
|
+
id: string;
|
|
103
|
+
} | null;
|
|
104
|
+
interview: {
|
|
105
|
+
id: string;
|
|
106
|
+
} | null;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Detail-view shape for `applications show <id>`. Extends
|
|
110
|
+
* {@link JobActivityItem} with extra job metadata (description, work
|
|
111
|
+
* type, dates) and engagement / application detail fields (rate,
|
|
112
|
+
* commitment, current billing cycle).
|
|
113
|
+
*
|
|
114
|
+
* Field selection is deliberately conservative — the captured
|
|
115
|
+
* `JobActivityItem` operation pulls in the full `jobData` +
|
|
116
|
+
* `jobActivityEngagementData` fragments (~50 fields). The shape here
|
|
117
|
+
* picks the fields the CLI's `pretty` formatter actually renders;
|
|
118
|
+
* future expansions can additively widen the projection.
|
|
119
|
+
*/
|
|
120
|
+
export interface JobActivityItemDetail extends JobActivityItem {
|
|
121
|
+
job: ApplicationJobRef & {
|
|
122
|
+
descriptionMd: string | null;
|
|
123
|
+
expectedHours: number | null;
|
|
124
|
+
commitment: {
|
|
125
|
+
slug: string;
|
|
126
|
+
} | null;
|
|
127
|
+
workType: {
|
|
128
|
+
slug: string;
|
|
129
|
+
} | null;
|
|
130
|
+
specialization: {
|
|
131
|
+
title: string;
|
|
132
|
+
} | null;
|
|
133
|
+
startDate: string | null;
|
|
134
|
+
postedWhen: string | null;
|
|
135
|
+
estimatedLength: {
|
|
136
|
+
enumValue: string;
|
|
137
|
+
} | null;
|
|
138
|
+
isCoaching: boolean | null;
|
|
139
|
+
isToptalProject: boolean | null;
|
|
140
|
+
};
|
|
141
|
+
jobApplication: {
|
|
142
|
+
id: string;
|
|
143
|
+
requestedHourlyRate: {
|
|
144
|
+
decimal: string;
|
|
145
|
+
} | null;
|
|
146
|
+
} | null;
|
|
147
|
+
engagement: {
|
|
148
|
+
id: string;
|
|
149
|
+
startDate: string | null;
|
|
150
|
+
endDate: string | null;
|
|
151
|
+
commitment: {
|
|
152
|
+
slug: string;
|
|
153
|
+
} | null;
|
|
154
|
+
expectedHours: number | null;
|
|
155
|
+
} | null;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Aggregate stats payload returned by `stats()`. `total` is the sum
|
|
159
|
+
* across all status groups (also the cross-check value — the
|
|
160
|
+
* unfiltered list call returns the same number); each entry in
|
|
161
|
+
* `groups` is a server-provided count for the named status group.
|
|
162
|
+
*/
|
|
163
|
+
export interface ApplicationsStats {
|
|
164
|
+
total: number;
|
|
165
|
+
groups: {
|
|
166
|
+
name: StatusGroup;
|
|
167
|
+
count: number;
|
|
168
|
+
}[];
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* List the signed-in user's job activity items (applications,
|
|
172
|
+
* availability requests, interviews, engagements).
|
|
173
|
+
*
|
|
174
|
+
* Default scope is whatever the server returns when neither filter is
|
|
175
|
+
* supplied (empirically the full unpaginated set, capped at the
|
|
176
|
+
* server's default limit). The returned array preserves server order;
|
|
177
|
+
* the CLI / MCP do not re-sort.
|
|
178
|
+
*
|
|
179
|
+
* **AC scope adjustment** (per #15 user decision 2026-05-10): the
|
|
180
|
+
* operation accepts NO date filter and NO pagination args. `--from` /
|
|
181
|
+
* `--to` and `--page` / `--per-page` flags are deliberately not exposed
|
|
182
|
+
* by this leaf; the AC items that referenced them are deferred. See
|
|
183
|
+
* `.tmp/workitem-15.md` § Open Questions (RESOLVED) for the rationale.
|
|
184
|
+
*/
|
|
185
|
+
export declare function list(token: string, opts?: ListOptions): Promise<JobActivityItem[]>;
|
|
186
|
+
export declare function show(token: string, id: string): Promise<JobActivityItemDetail>;
|
|
187
|
+
/**
|
|
188
|
+
* Aggregate per-status-group counts plus the overall total. Issues N+1
|
|
189
|
+
* `JobActivityItems` calls — one per `JobActivityItemStatusGroupEnum`
|
|
190
|
+
* value — in parallel via `Promise.all`. Each call's
|
|
191
|
+
* `data.viewer.jobActivityList.totalCount` is a server-provided
|
|
192
|
+
* scalar; the helper does NOT count the returned `entities` array
|
|
193
|
+
* (which would be the synthesis the AC forbids).
|
|
194
|
+
*
|
|
195
|
+
* `total` is the sum of per-group counts. The unfiltered call's
|
|
196
|
+
* `totalCount` would yield the same number; we don't issue an extra
|
|
197
|
+
* call to verify because the per-group sum is already authoritative.
|
|
198
|
+
*
|
|
199
|
+
* **Failure mode**: `Promise.all` rejects on the first failed call. A
|
|
200
|
+
* single GraphQL error on one of the 5 groups loses the 4 successful
|
|
201
|
+
* counts. This is intentional: `applications stats` is an aggregate;
|
|
202
|
+
* surfacing partial counts (e.g. "118 total" when one group's call
|
|
203
|
+
* failed) would be misleading because the user reads `total` as
|
|
204
|
+
* authoritative. The right behavior on partial failure is "show no
|
|
205
|
+
* stats and surface the error" — the caller (`runApplicationsStats`)
|
|
206
|
+
* routes the rejection through the structured error envelope so the
|
|
207
|
+
* user knows exactly what went wrong.
|
|
208
|
+
*/
|
|
209
|
+
export declare function stats(token: string): Promise<ApplicationsStats>;
|
|
210
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/applications/index.ts"],"names":[],"mappings":"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"}
|