@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,560 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
/**
|
|
4
|
+
* `profile.external` service module.
|
|
5
|
+
*
|
|
6
|
+
* The "external" sub-domain is the most heterogeneous of the 11 profile
|
|
7
|
+
* sub-domains: it bundles operations that the operation catalog clusters
|
|
8
|
+
* under the umbrella names `external profile / advanced profile / wizard`.
|
|
9
|
+
* Per issue #76 the v0 user-facing surface exposes:
|
|
10
|
+
*
|
|
11
|
+
* 1. {@link update} — set external profile URLs (linkedin/github/website/…)
|
|
12
|
+
* 2. {@link customRequirementsShow} — read the three onboarding-readiness toggles
|
|
13
|
+
* 3. {@link customRequirementsSet} — toggle the three onboarding-readiness booleans
|
|
14
|
+
* 4. {@link readiness} — read the per-section completion meter
|
|
15
|
+
* 5. {@link recommendations} — read the per-section "do this next" recommendations
|
|
16
|
+
* 6. {@link advancedWizardShow} — read the advanced-profile-wizard status
|
|
17
|
+
*
|
|
18
|
+
* ## Spec / API divergences (documented per #76 AC)
|
|
19
|
+
*
|
|
20
|
+
* The issue (#76) describes `customRequirementsSet` as multi-paragraph
|
|
21
|
+
* **free-text** (and the AC explicitly lists "Free-text helper (#70) consumed
|
|
22
|
+
* by `external custom-requirements set`"). Empirically — see
|
|
23
|
+
* `research/captures/web/inputs/UpdateCustomRequirementsInput.json` and
|
|
24
|
+
* `research/graphql/talent_profile/fragments/CustomRequirements.graphql` —
|
|
25
|
+
* the underlying `CustomRequirementsInput` is in fact **three booleans**
|
|
26
|
+
* (`backgroundCheck`, `drugTest`, `timeTrackingTools`); no free-text field
|
|
27
|
+
* exists on the schema. The capture notes:
|
|
28
|
+
*
|
|
29
|
+
* "Form has no save button — autosaves on checkbox toggle. Each toggle
|
|
30
|
+
* sends ALL three current states (no diff/PATCH semantics)."
|
|
31
|
+
*
|
|
32
|
+
* We follow API ground truth: the `set` function takes the boolean trio.
|
|
33
|
+
* The free-text helper (#70) is therefore **not** consumed by this leaf.
|
|
34
|
+
* The AC item failure is surfaced in the PR description and CHANGELOG.
|
|
35
|
+
*
|
|
36
|
+
* The issue spec also lists `--portfolio-url` as a field of `update`. The
|
|
37
|
+
* actual schema's settable external-profile fields are `linkedin / github /
|
|
38
|
+
* website / twitter / behance / dribbble`; a portfolio URL is a server-
|
|
39
|
+
* determined read (`getPublicProfileUrl`), not a settable input. We expose
|
|
40
|
+
* the schema-supported set; `--portfolio-url` is dropped.
|
|
41
|
+
*
|
|
42
|
+
* ## Operations explicitly NOT exposed at v0
|
|
43
|
+
*
|
|
44
|
+
* Per issue #76 § "Operations explicitly NOT exposed as user-facing CLI
|
|
45
|
+
* leaves", the following are intentionally **not** implemented at v0. None
|
|
46
|
+
* is exported from this module — they are not even private helpers — so
|
|
47
|
+
* future maintainers can audit the exact deferral set without shadow-API
|
|
48
|
+
* hazards. File a follow-up issue if user demand surfaces:
|
|
49
|
+
*
|
|
50
|
+
* - `getStepsAndLinks` — implementation-detail navigation helper
|
|
51
|
+
* - `getProfilePrefillStatus` — server-determined prefill state
|
|
52
|
+
* - `getProfileSettingsUrls` — settings-URL navigator
|
|
53
|
+
* - `getPublicProfileUrl` — single value; defer until user demand
|
|
54
|
+
* - `getProfileVersionsCount` — internal telemetry
|
|
55
|
+
* - `analyticsInfo` — internal telemetry
|
|
56
|
+
* - `getProfileTimestamps` — internal telemetry
|
|
57
|
+
* - `getProfileItems` — generic list with unclear semantics
|
|
58
|
+
* - `UpdateAdvancedProfileWizardStatus` — wizard-internal state mutation
|
|
59
|
+
*
|
|
60
|
+
* ## Wire-shape decisions
|
|
61
|
+
*
|
|
62
|
+
* All operations target the talent_profile surface
|
|
63
|
+
* (`https://www.toptal.com/api/talent_profile/graphql`) which is
|
|
64
|
+
* Cloudflare-protected and uses {@link impersonatedTransport}. Because the
|
|
65
|
+
* talent_profile backend does not publish a persisted-query catalog, every
|
|
66
|
+
* operation is sent as a full-document GraphQL request. We hand-write the
|
|
67
|
+
* query/mutation strings here (mirrored from `research/graphql/
|
|
68
|
+
* talent_profile/operations/`) and the input/output TypeScript types because
|
|
69
|
+
* codegen is currently scoped to the gateway surface only (see
|
|
70
|
+
* `codegen.config.ts`).
|
|
71
|
+
*
|
|
72
|
+
* Mutation input shapes follow Pattern 1 of
|
|
73
|
+
* `research/notes/10-mutation-input-patterns.md` (`{ input: { profileId,
|
|
74
|
+
* <wrapper>: { … } } }`). The wrapper key is `externalProfiles` for
|
|
75
|
+
* `UpdateExternalProfiles` and `customRequirements` for
|
|
76
|
+
* `updateCustomRequirements` (the latter is empirically validated by
|
|
77
|
+
* `research/captures/web/inputs/UpdateCustomRequirementsInput.json`).
|
|
78
|
+
*/
|
|
79
|
+
import { AuthRevokedError, TtctlError } from "../../../auth/errors.js";
|
|
80
|
+
import { impersonatedTransport } from "../../../transport.js";
|
|
81
|
+
import { ProfileError } from "../basic/index.js";
|
|
82
|
+
import { extractProfileId, isAuthRevokedExtensionCode } from "../shared.js";
|
|
83
|
+
// Re-export the shared `ProfileError` / `ProfileErrorCode` so consumers can
|
|
84
|
+
// continue to write `profile.external.ProfileError` (mirrors the
|
|
85
|
+
// `profile.basic.ProfileError` ergonomics).
|
|
86
|
+
export { ProfileError };
|
|
87
|
+
/**
|
|
88
|
+
* Parse a `TransportResponse` from the talent_profile surface into the
|
|
89
|
+
* typed `data` payload. Centralises the HTTP-status check, top-level
|
|
90
|
+
* GraphQL `errors` interpretation (with auth-revoked routing), and `data`
|
|
91
|
+
* presence check that every operation in this module needs.
|
|
92
|
+
*
|
|
93
|
+
* Returns `unknown` so callers can narrow to their operation-specific
|
|
94
|
+
* payload shape via a single `as` cast — this avoids `no-unnecessary-type-
|
|
95
|
+
* parameters` lint hits while keeping every call site one-line.
|
|
96
|
+
*
|
|
97
|
+
* `commandLabel` is folded into the error message ("<commandLabel> failed:
|
|
98
|
+
* …") so the user sees a meaningful prefix even for operations that share
|
|
99
|
+
* the same error code.
|
|
100
|
+
*/
|
|
101
|
+
function parseTalentProfileResponse(res, commandLabel, fallbackErrorCode = "UNKNOWN") {
|
|
102
|
+
if (res.status === 401) {
|
|
103
|
+
throw new AuthRevokedError("Session is invalid or expired.");
|
|
104
|
+
}
|
|
105
|
+
if (res.status < 200 || res.status >= 300) {
|
|
106
|
+
throw new ProfileError(fallbackErrorCode, `${commandLabel} returned HTTP ${res.status.toString()}`);
|
|
107
|
+
}
|
|
108
|
+
const body = res.body;
|
|
109
|
+
if (body && Array.isArray(body.errors) && body.errors.length > 0) {
|
|
110
|
+
const first = body.errors[0];
|
|
111
|
+
const message = first?.message ?? "GraphQL error";
|
|
112
|
+
if (isAuthRevokedExtensionCode(first?.extensions?.code)) {
|
|
113
|
+
throw new AuthRevokedError("Session is invalid or expired.");
|
|
114
|
+
}
|
|
115
|
+
throw new ProfileError("GRAPHQL_ERROR", `${commandLabel} failed: ${message}`);
|
|
116
|
+
}
|
|
117
|
+
if (!body?.data) {
|
|
118
|
+
throw new ProfileError(fallbackErrorCode, `${commandLabel} response had no \`data\` field`);
|
|
119
|
+
}
|
|
120
|
+
return body.data;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Wrap a transport call so any thrown error becomes a typed
|
|
124
|
+
* `ProfileError(NETWORK_ERROR)`. `TtctlError` and `ProfileError` subclasses
|
|
125
|
+
* are preserved verbatim (the former carry their own `recovery` hints; the
|
|
126
|
+
* latter are already shape-correct).
|
|
127
|
+
*/
|
|
128
|
+
async function withNetworkErrorMapping(commandLabel, fn) {
|
|
129
|
+
try {
|
|
130
|
+
return await fn();
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
if (err instanceof TtctlError)
|
|
134
|
+
throw err;
|
|
135
|
+
if (err instanceof ProfileError)
|
|
136
|
+
throw err;
|
|
137
|
+
throw new ProfileError("NETWORK_ERROR", `${commandLabel} request failed: ${err.message}`, {
|
|
138
|
+
cause: err,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function coerceBoolean(value) {
|
|
143
|
+
return typeof value === "boolean" ? value : null;
|
|
144
|
+
}
|
|
145
|
+
function coerceString(value) {
|
|
146
|
+
return typeof value === "string" ? value : null;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Full-document `UpdateExternalProfiles` mutation. Mirrors
|
|
150
|
+
* `research/graphql/talent_profile/operations/UpdateExternalProfiles.graphql`
|
|
151
|
+
* with the fragments inlined. The `recommendations` selection from the
|
|
152
|
+
* upstream document is intentionally omitted at v0 — recommendations are
|
|
153
|
+
* surfaced via the dedicated `getProfileRecommendations` query
|
|
154
|
+
* ({@link recommendations}) and pulling them through every external-update
|
|
155
|
+
* response would force an over-broad type contract that's hard to keep
|
|
156
|
+
* stable. Caller can re-fetch recommendations after a successful update if
|
|
157
|
+
* they need the freshest list.
|
|
158
|
+
*/
|
|
159
|
+
const UPDATE_EXTERNAL_PROFILES_MUTATION = `mutation UpdateExternalProfiles($input: UpdateExternalProfilesInput!) {
|
|
160
|
+
updateExternalProfiles(input: $input) {
|
|
161
|
+
profile {
|
|
162
|
+
id
|
|
163
|
+
updatedByTalentAt
|
|
164
|
+
linkedin
|
|
165
|
+
github
|
|
166
|
+
website
|
|
167
|
+
behance
|
|
168
|
+
dribbble
|
|
169
|
+
}
|
|
170
|
+
errors {
|
|
171
|
+
code
|
|
172
|
+
key
|
|
173
|
+
message
|
|
174
|
+
}
|
|
175
|
+
notice
|
|
176
|
+
success
|
|
177
|
+
}
|
|
178
|
+
}`;
|
|
179
|
+
/**
|
|
180
|
+
* Update external profile URLs (linkedin / github / website / twitter /
|
|
181
|
+
* behance / dribbble). Each field is optional; the caller must pass at
|
|
182
|
+
* least one. Unknown / extraneous fields are rejected at compile time by
|
|
183
|
+
* the {@link ExternalProfilesUpdate} type.
|
|
184
|
+
*
|
|
185
|
+
* Wire shape follows Pattern 1 of `research/notes/10-mutation-input-patterns.md`
|
|
186
|
+
* with the wrapper key `externalProfiles`. **INFERRED — UNVERIFIED**: no
|
|
187
|
+
* live curl capture exists in `research/captures/web/inputs/` for this
|
|
188
|
+
* mutation; deviations would surface as `USER_ERROR` at runtime.
|
|
189
|
+
*
|
|
190
|
+
* Errors:
|
|
191
|
+
* - `ProfileError("VALIDATION_ERROR")` when no fields are supplied
|
|
192
|
+
* - `ProfileError("USER_ERROR")` when the server rejects an individual
|
|
193
|
+
* field (e.g. malformed URL)
|
|
194
|
+
* - `AuthRevokedError`, `Cf403Error`, other `TtctlError` subclasses
|
|
195
|
+
* propagate verbatim
|
|
196
|
+
*/
|
|
197
|
+
export async function update(token, changes) {
|
|
198
|
+
const fields = {};
|
|
199
|
+
if (changes.linkedin !== undefined)
|
|
200
|
+
fields.linkedin = changes.linkedin;
|
|
201
|
+
if (changes.github !== undefined)
|
|
202
|
+
fields.github = changes.github;
|
|
203
|
+
if (changes.website !== undefined)
|
|
204
|
+
fields.website = changes.website;
|
|
205
|
+
if (changes.twitter !== undefined)
|
|
206
|
+
fields.twitter = changes.twitter;
|
|
207
|
+
if (changes.behance !== undefined)
|
|
208
|
+
fields.behance = changes.behance;
|
|
209
|
+
if (changes.dribbble !== undefined)
|
|
210
|
+
fields.dribbble = changes.dribbble;
|
|
211
|
+
if (Object.keys(fields).length === 0) {
|
|
212
|
+
throw new ProfileError("VALIDATION_ERROR", "External profile update requires at least one of linkedin/github/website/twitter/behance/dribbble.");
|
|
213
|
+
}
|
|
214
|
+
const profileId = await extractProfileId(token);
|
|
215
|
+
// No safe round-trip: the service has no read endpoint exposing
|
|
216
|
+
// linkedin/github/website/twitter/behance/dribbble (basic profile show
|
|
217
|
+
// does not include them; the mutation response gives POST-state only),
|
|
218
|
+
// so a sentinel value cannot be reverted without a captured pre-state.
|
|
219
|
+
// Overwriting the maintainer's real URLs is destructive. Wire shape
|
|
220
|
+
// inferred from research/notes/10 Pattern 1 (wrapper key
|
|
221
|
+
// `externalProfiles`); see packages/e2e/src/38-profile-external.e2e.test.ts.
|
|
222
|
+
const res = await withNetworkErrorMapping("External profile update", () => impersonatedTransport({
|
|
223
|
+
surface: "talent-profile",
|
|
224
|
+
authToken: token,
|
|
225
|
+
body: {
|
|
226
|
+
// e2e-exempt: destructive — see comment above the withNetworkErrorMapping call.
|
|
227
|
+
operationName: "UpdateExternalProfiles",
|
|
228
|
+
query: UPDATE_EXTERNAL_PROFILES_MUTATION,
|
|
229
|
+
variables: { input: { profileId, externalProfiles: fields } },
|
|
230
|
+
},
|
|
231
|
+
}));
|
|
232
|
+
const data = parseTalentProfileResponse(res, "External profile update");
|
|
233
|
+
const payload = data.updateExternalProfiles;
|
|
234
|
+
if (!payload) {
|
|
235
|
+
throw new ProfileError("UNKNOWN", "External profile update response had no `data.updateExternalProfiles` field");
|
|
236
|
+
}
|
|
237
|
+
if (Array.isArray(payload.errors) && payload.errors.length > 0) {
|
|
238
|
+
const first = payload.errors[0];
|
|
239
|
+
const fieldHint = first?.key ? ` (${first.key})` : "";
|
|
240
|
+
throw new ProfileError("USER_ERROR", `External profile update rejected${fieldHint}: ${first?.message ?? "unknown error"}`);
|
|
241
|
+
}
|
|
242
|
+
if (payload.success === false) {
|
|
243
|
+
throw new ProfileError("USER_ERROR", `External profile update reported success=false${payload.notice ? `: ${payload.notice}` : ""}`);
|
|
244
|
+
}
|
|
245
|
+
if (!payload.profile) {
|
|
246
|
+
throw new ProfileError("UNKNOWN", "External profile update succeeded but response had no profile payload");
|
|
247
|
+
}
|
|
248
|
+
return {
|
|
249
|
+
profile: {
|
|
250
|
+
id: payload.profile.id,
|
|
251
|
+
updatedByTalentAt: coerceString(payload.profile.updatedByTalentAt),
|
|
252
|
+
linkedin: payload.profile.linkedin ?? null,
|
|
253
|
+
github: payload.profile.github ?? null,
|
|
254
|
+
website: payload.profile.website ?? null,
|
|
255
|
+
behance: payload.profile.behance ?? null,
|
|
256
|
+
dribbble: payload.profile.dribbble ?? null,
|
|
257
|
+
},
|
|
258
|
+
notice: payload.notice ?? null,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
const GET_CUSTOM_REQUIREMENTS_QUERY = `query getCustomRequirements($profileId: ID!) {
|
|
262
|
+
profile(id: $profileId) {
|
|
263
|
+
id
|
|
264
|
+
customRequirements {
|
|
265
|
+
backgroundCheck
|
|
266
|
+
drugTest
|
|
267
|
+
timeTrackingTools
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}`;
|
|
271
|
+
/**
|
|
272
|
+
* Read the three onboarding-readiness toggles for the signed-in user.
|
|
273
|
+
*
|
|
274
|
+
* Errors: `AuthRevokedError`, `ProfileError(GRAPHQL_ERROR)`,
|
|
275
|
+
* `ProfileError(NETWORK_ERROR)`, `Cf403Error` (and other `TtctlError`
|
|
276
|
+
* subclasses) propagate verbatim.
|
|
277
|
+
*/
|
|
278
|
+
export async function customRequirementsShow(token) {
|
|
279
|
+
const profileId = await extractProfileId(token);
|
|
280
|
+
const res = await withNetworkErrorMapping("Custom requirements show", () => impersonatedTransport({
|
|
281
|
+
surface: "talent-profile",
|
|
282
|
+
authToken: token,
|
|
283
|
+
body: {
|
|
284
|
+
operationName: "getCustomRequirements",
|
|
285
|
+
query: GET_CUSTOM_REQUIREMENTS_QUERY,
|
|
286
|
+
variables: { profileId },
|
|
287
|
+
},
|
|
288
|
+
}));
|
|
289
|
+
const data = parseTalentProfileResponse(res, "Custom requirements show");
|
|
290
|
+
if (!data.profile) {
|
|
291
|
+
throw new ProfileError("NO_VIEWER", "Custom requirements query returned no profile.");
|
|
292
|
+
}
|
|
293
|
+
const cr = data.profile.customRequirements ?? {};
|
|
294
|
+
return {
|
|
295
|
+
backgroundCheck: coerceBoolean(cr.backgroundCheck),
|
|
296
|
+
drugTest: coerceBoolean(cr.drugTest),
|
|
297
|
+
timeTrackingTools: coerceBoolean(cr.timeTrackingTools),
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
const UPDATE_CUSTOM_REQUIREMENTS_MUTATION = `mutation updateCustomRequirements($input: UpdateCustomRequirementsInput!) {
|
|
301
|
+
updateCustomRequirements(input: $input) {
|
|
302
|
+
profile {
|
|
303
|
+
id
|
|
304
|
+
updatedByTalentAt
|
|
305
|
+
customRequirements {
|
|
306
|
+
backgroundCheck
|
|
307
|
+
drugTest
|
|
308
|
+
timeTrackingTools
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
errors {
|
|
312
|
+
code
|
|
313
|
+
key
|
|
314
|
+
message
|
|
315
|
+
}
|
|
316
|
+
notice
|
|
317
|
+
success
|
|
318
|
+
}
|
|
319
|
+
}`;
|
|
320
|
+
/**
|
|
321
|
+
* Toggle one or more of the three onboarding-readiness booleans
|
|
322
|
+
* (`backgroundCheck`, `drugTest`, `timeTrackingTools`). Caller-omitted
|
|
323
|
+
* fields are pre-filled from the current server state via
|
|
324
|
+
* {@link customRequirementsShow} before the mutation is sent (the underlying
|
|
325
|
+
* `updateCustomRequirements` mutation has no diff/PATCH semantics — every
|
|
326
|
+
* call resubmits all three booleans).
|
|
327
|
+
*
|
|
328
|
+
* Pre-fill of missing fields treats `null` (server has no value yet) as
|
|
329
|
+
* `false` for the post-merge wire shape, since the mutation input is
|
|
330
|
+
* `Boolean!` and rejects `null`.
|
|
331
|
+
*
|
|
332
|
+
* Errors: same taxonomy as {@link update}.
|
|
333
|
+
*/
|
|
334
|
+
export async function customRequirementsSet(token, changes) {
|
|
335
|
+
if (changes.backgroundCheck === undefined &&
|
|
336
|
+
changes.drugTest === undefined &&
|
|
337
|
+
changes.timeTrackingTools === undefined) {
|
|
338
|
+
throw new ProfileError("VALIDATION_ERROR", "Custom requirements update requires at least one of backgroundCheck/drugTest/timeTrackingTools.");
|
|
339
|
+
}
|
|
340
|
+
// Resolve current state to fill in any caller-omitted fields. We deliberately
|
|
341
|
+
// make this fetch every time (rather than caching) — the mutation input is
|
|
342
|
+
// `Boolean!` for all three, and a stale cache would silently flip a bit the
|
|
343
|
+
// user didn't mean to change. The cost (one extra round-trip per set) is
|
|
344
|
+
// small relative to the user-visible correctness improvement.
|
|
345
|
+
const current = await customRequirementsShow(token);
|
|
346
|
+
const profileId = await extractProfileId(token);
|
|
347
|
+
const merged = {
|
|
348
|
+
backgroundCheck: changes.backgroundCheck ?? current.backgroundCheck ?? false,
|
|
349
|
+
drugTest: changes.drugTest ?? current.drugTest ?? false,
|
|
350
|
+
timeTrackingTools: changes.timeTrackingTools ?? current.timeTrackingTools ?? false,
|
|
351
|
+
};
|
|
352
|
+
const res = await withNetworkErrorMapping("Custom requirements update", () => impersonatedTransport({
|
|
353
|
+
surface: "talent-profile",
|
|
354
|
+
authToken: token,
|
|
355
|
+
body: {
|
|
356
|
+
operationName: "updateCustomRequirements",
|
|
357
|
+
query: UPDATE_CUSTOM_REQUIREMENTS_MUTATION,
|
|
358
|
+
variables: { input: { profileId, customRequirements: merged } },
|
|
359
|
+
},
|
|
360
|
+
}));
|
|
361
|
+
const data = parseTalentProfileResponse(res, "Custom requirements update");
|
|
362
|
+
const payload = data.updateCustomRequirements;
|
|
363
|
+
if (!payload) {
|
|
364
|
+
throw new ProfileError("UNKNOWN", "Custom requirements update response had no payload field");
|
|
365
|
+
}
|
|
366
|
+
if (Array.isArray(payload.errors) && payload.errors.length > 0) {
|
|
367
|
+
const first = payload.errors[0];
|
|
368
|
+
const fieldHint = first?.key ? ` (${first.key})` : "";
|
|
369
|
+
throw new ProfileError("USER_ERROR", `Custom requirements update rejected${fieldHint}: ${first?.message ?? "unknown error"}`);
|
|
370
|
+
}
|
|
371
|
+
if (payload.success === false) {
|
|
372
|
+
throw new ProfileError("USER_ERROR", `Custom requirements update reported success=false${payload.notice ? `: ${payload.notice}` : ""}`);
|
|
373
|
+
}
|
|
374
|
+
if (!payload.profile) {
|
|
375
|
+
throw new ProfileError("UNKNOWN", "Custom requirements update succeeded but response had no profile payload");
|
|
376
|
+
}
|
|
377
|
+
const cr = payload.profile.customRequirements ?? {};
|
|
378
|
+
return {
|
|
379
|
+
profile: {
|
|
380
|
+
id: payload.profile.id,
|
|
381
|
+
updatedByTalentAt: coerceString(payload.profile.updatedByTalentAt),
|
|
382
|
+
customRequirements: {
|
|
383
|
+
backgroundCheck: coerceBoolean(cr.backgroundCheck),
|
|
384
|
+
drugTest: coerceBoolean(cr.drugTest),
|
|
385
|
+
timeTrackingTools: coerceBoolean(cr.timeTrackingTools),
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
notice: payload.notice ?? null,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
const GET_PROFILE_READINESS_QUERY = `query getProfileReadiness($profileId: ID!) {
|
|
392
|
+
profile(id: $profileId) {
|
|
393
|
+
id
|
|
394
|
+
submitAvailable
|
|
395
|
+
updatedByTalentAt
|
|
396
|
+
profileReadiness {
|
|
397
|
+
isPhotoResolutionSatisfied
|
|
398
|
+
isBasicInfoSatisfied
|
|
399
|
+
isCertificationsSatisfied
|
|
400
|
+
isEmploymentsCountSatisfied
|
|
401
|
+
isEmploymentConnectionsSatisfied
|
|
402
|
+
isSkillValidationsSatisfied
|
|
403
|
+
isPortfolioItemsCountSatisfied
|
|
404
|
+
isPortfolioItemConnectionsSatisfied
|
|
405
|
+
isWorkingHoursSatisfied
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}`;
|
|
409
|
+
/**
|
|
410
|
+
* Read the per-section profile-readiness booleans plus the rolled-up
|
|
411
|
+
* `submitAvailable` flag and the last-edit timestamp.
|
|
412
|
+
*
|
|
413
|
+
* Errors: same taxonomy as {@link customRequirementsShow}.
|
|
414
|
+
*/
|
|
415
|
+
export async function readiness(token) {
|
|
416
|
+
const profileId = await extractProfileId(token);
|
|
417
|
+
const res = await withNetworkErrorMapping("Profile readiness", () => impersonatedTransport({
|
|
418
|
+
surface: "talent-profile",
|
|
419
|
+
authToken: token,
|
|
420
|
+
body: {
|
|
421
|
+
operationName: "getProfileReadiness",
|
|
422
|
+
query: GET_PROFILE_READINESS_QUERY,
|
|
423
|
+
variables: { profileId },
|
|
424
|
+
},
|
|
425
|
+
}));
|
|
426
|
+
const data = parseTalentProfileResponse(res, "Profile readiness");
|
|
427
|
+
if (!data.profile) {
|
|
428
|
+
throw new ProfileError("NO_VIEWER", "Profile readiness query returned no profile.");
|
|
429
|
+
}
|
|
430
|
+
const pr = data.profile.profileReadiness ?? {};
|
|
431
|
+
return {
|
|
432
|
+
isPhotoResolutionSatisfied: coerceBoolean(pr.isPhotoResolutionSatisfied),
|
|
433
|
+
isBasicInfoSatisfied: coerceBoolean(pr.isBasicInfoSatisfied),
|
|
434
|
+
isCertificationsSatisfied: coerceBoolean(pr.isCertificationsSatisfied),
|
|
435
|
+
isEmploymentsCountSatisfied: coerceBoolean(pr.isEmploymentsCountSatisfied),
|
|
436
|
+
isEmploymentConnectionsSatisfied: coerceBoolean(pr.isEmploymentConnectionsSatisfied),
|
|
437
|
+
isSkillValidationsSatisfied: coerceBoolean(pr.isSkillValidationsSatisfied),
|
|
438
|
+
isPortfolioItemsCountSatisfied: coerceBoolean(pr.isPortfolioItemsCountSatisfied),
|
|
439
|
+
isPortfolioItemConnectionsSatisfied: coerceBoolean(pr.isPortfolioItemConnectionsSatisfied),
|
|
440
|
+
isWorkingHoursSatisfied: coerceBoolean(pr.isWorkingHoursSatisfied),
|
|
441
|
+
submitAvailable: coerceBoolean(data.profile.submitAvailable),
|
|
442
|
+
updatedByTalentAt: coerceString(data.profile.updatedByTalentAt),
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
const GET_PROFILE_RECOMMENDATIONS_QUERY = `query getProfileRecommendations($profileId: ID!) {
|
|
446
|
+
profile(id: $profileId) {
|
|
447
|
+
id
|
|
448
|
+
recommendations {
|
|
449
|
+
nodes {
|
|
450
|
+
type
|
|
451
|
+
... on EmploymentsCountRecommendation { minimumCount }
|
|
452
|
+
... on PortfolioItemsCountRecommendation { minimumCount }
|
|
453
|
+
... on AdvancedProfileRecommendation { isCustomRequirementsCompleted isTravelInformationCompleted }
|
|
454
|
+
... on ProfileFreshnessRecommendation {
|
|
455
|
+
skillsStatus
|
|
456
|
+
certificationsStatus
|
|
457
|
+
educationsStatus
|
|
458
|
+
workExperiencesStatus
|
|
459
|
+
portfolioItemsStatus
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}`;
|
|
465
|
+
/**
|
|
466
|
+
* Read the list of profile recommendations. Each recommendation has a
|
|
467
|
+
* discriminator `type` and a small payload of variant-specific fields.
|
|
468
|
+
*
|
|
469
|
+
* Recommendations that involve nested entity lists (e.g.
|
|
470
|
+
* `EmploymentsMissingDataRecommendation` with a `nodes` array of employments)
|
|
471
|
+
* are intentionally trimmed at the GraphQL level — at v0 the CLI/MCP only
|
|
472
|
+
* surfaces the recommendation `type` and any scalar variant fields. Drilling
|
|
473
|
+
* into nested entity lists requires fetching the underlying domain
|
|
474
|
+
* (employments, portfolio items, skills) directly, which is outside the
|
|
475
|
+
* recommendations leaf's scope.
|
|
476
|
+
*/
|
|
477
|
+
export async function recommendations(token) {
|
|
478
|
+
const profileId = await extractProfileId(token);
|
|
479
|
+
const res = await withNetworkErrorMapping("Profile recommendations", () => impersonatedTransport({
|
|
480
|
+
surface: "talent-profile",
|
|
481
|
+
authToken: token,
|
|
482
|
+
body: {
|
|
483
|
+
operationName: "getProfileRecommendations",
|
|
484
|
+
query: GET_PROFILE_RECOMMENDATIONS_QUERY,
|
|
485
|
+
variables: { profileId },
|
|
486
|
+
},
|
|
487
|
+
}));
|
|
488
|
+
const data = parseTalentProfileResponse(res, "Profile recommendations");
|
|
489
|
+
if (!data.profile) {
|
|
490
|
+
throw new ProfileError("NO_VIEWER", "Profile recommendations query returned no profile.");
|
|
491
|
+
}
|
|
492
|
+
const nodes = data.profile.recommendations?.nodes ?? [];
|
|
493
|
+
return nodes
|
|
494
|
+
.filter((n) => n !== null && typeof n === "object")
|
|
495
|
+
.map((node) => {
|
|
496
|
+
// Build a clean payload by stripping the discriminator and `__typename`.
|
|
497
|
+
const payload = {};
|
|
498
|
+
for (const [k, v] of Object.entries(node)) {
|
|
499
|
+
if (k === "type" || k === "__typename")
|
|
500
|
+
continue;
|
|
501
|
+
payload[k] = v;
|
|
502
|
+
}
|
|
503
|
+
const type = node.type;
|
|
504
|
+
return {
|
|
505
|
+
type: typeof type === "string" ? type : "Unknown",
|
|
506
|
+
payload,
|
|
507
|
+
};
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
const GET_ADVANCED_PROFILE_DATA_QUERY = `query getAdvancedProfileData($profileId: ID!) {
|
|
511
|
+
profile(id: $profileId) {
|
|
512
|
+
id
|
|
513
|
+
advancedProfileWizardStatus
|
|
514
|
+
travelVisas {
|
|
515
|
+
nodes {
|
|
516
|
+
id
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}`;
|
|
521
|
+
/**
|
|
522
|
+
* Read the advanced-profile-wizard status plus a summary of the talent's
|
|
523
|
+
* travel-visa list. This is the read-side combined view of
|
|
524
|
+
* `getAdvancedProfileData` — the spec also references
|
|
525
|
+
* `GetAdvancedProfileWizardStatus` as a separate operation, but
|
|
526
|
+
* `getAdvancedProfileData` already returns `advancedProfileWizardStatus`, so
|
|
527
|
+
* one query is sufficient.
|
|
528
|
+
*
|
|
529
|
+
* The full TravelVisa fragment is intentionally trimmed to `id` only. Visa
|
|
530
|
+
* CRUD operations live in the `visas` sub-domain — surfacing the rich shape
|
|
531
|
+
* here would create a partial duplication that drifts as the visas
|
|
532
|
+
* sub-domain evolves.
|
|
533
|
+
*/
|
|
534
|
+
export async function advancedWizardShow(token) {
|
|
535
|
+
const profileId = await extractProfileId(token);
|
|
536
|
+
const res = await withNetworkErrorMapping("Advanced profile wizard show", () => impersonatedTransport({
|
|
537
|
+
surface: "talent-profile",
|
|
538
|
+
authToken: token,
|
|
539
|
+
body: {
|
|
540
|
+
operationName: "getAdvancedProfileData",
|
|
541
|
+
query: GET_ADVANCED_PROFILE_DATA_QUERY,
|
|
542
|
+
variables: { profileId },
|
|
543
|
+
},
|
|
544
|
+
}));
|
|
545
|
+
const data = parseTalentProfileResponse(res, "Advanced profile wizard show");
|
|
546
|
+
if (!data.profile) {
|
|
547
|
+
throw new ProfileError("NO_VIEWER", "Advanced profile data query returned no profile.");
|
|
548
|
+
}
|
|
549
|
+
const visaNodes = data.profile.travelVisas?.nodes ?? [];
|
|
550
|
+
const travelVisaIds = visaNodes
|
|
551
|
+
.filter((n) => n !== null && typeof n === "object")
|
|
552
|
+
.map((n) => (typeof n.id === "string" ? n.id : ""))
|
|
553
|
+
.filter((id) => id.length > 0);
|
|
554
|
+
return {
|
|
555
|
+
wizardStatus: coerceString(data.profile.advancedProfileWizardStatus),
|
|
556
|
+
travelVisaCount: travelVisaIds.length,
|
|
557
|
+
travelVisaIds,
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/services/profile/external/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `profile` services-tree facade. The 11 sub-domains follow the v0 epic
|
|
3
|
+
* cartography (#68): basic, skills, industries, education, certifications,
|
|
4
|
+
* employment, portfolio, visas, resume, external, reviews. Each is exposed
|
|
5
|
+
* as a namespace on this module so consumers write
|
|
6
|
+
* `profile.basic.show(...)`, `profile.skills.add(...)`, etc.
|
|
7
|
+
*
|
|
8
|
+
* Only `basic` carries operations today (`show`, `set`, plus the shared
|
|
9
|
+
* `ProfileError`/`ProfileUpdate`/`UpdateProfileResult` types). The other
|
|
10
|
+
* 10 sub-domains are placeholder modules that land actual operations in
|
|
11
|
+
* the follow-up issues (#73-#76).
|
|
12
|
+
*/
|
|
13
|
+
export * as basic from "./basic/index.js";
|
|
14
|
+
export * as skills from "./skills/index.js";
|
|
15
|
+
export * as industries from "./industries/index.js";
|
|
16
|
+
export * as education from "./education/index.js";
|
|
17
|
+
export * as certifications from "./certifications/index.js";
|
|
18
|
+
export * as employment from "./employment/index.js";
|
|
19
|
+
export * as portfolio from "./portfolio/index.js";
|
|
20
|
+
export * as visas from "./visas/index.js";
|
|
21
|
+
export * as resume from "./resume/index.js";
|
|
22
|
+
export * as external from "./external/index.js";
|
|
23
|
+
export * as reviews from "./reviews/index.js";
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/profile/index.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
/**
|
|
4
|
+
* `profile` services-tree facade. The 11 sub-domains follow the v0 epic
|
|
5
|
+
* cartography (#68): basic, skills, industries, education, certifications,
|
|
6
|
+
* employment, portfolio, visas, resume, external, reviews. Each is exposed
|
|
7
|
+
* as a namespace on this module so consumers write
|
|
8
|
+
* `profile.basic.show(...)`, `profile.skills.add(...)`, etc.
|
|
9
|
+
*
|
|
10
|
+
* Only `basic` carries operations today (`show`, `set`, plus the shared
|
|
11
|
+
* `ProfileError`/`ProfileUpdate`/`UpdateProfileResult` types). The other
|
|
12
|
+
* 10 sub-domains are placeholder modules that land actual operations in
|
|
13
|
+
* the follow-up issues (#73-#76).
|
|
14
|
+
*/
|
|
15
|
+
export * as basic from "./basic/index.js";
|
|
16
|
+
export * as skills from "./skills/index.js";
|
|
17
|
+
export * as industries from "./industries/index.js";
|
|
18
|
+
export * as education from "./education/index.js";
|
|
19
|
+
export * as certifications from "./certifications/index.js";
|
|
20
|
+
export * as employment from "./employment/index.js";
|
|
21
|
+
export * as portfolio from "./portfolio/index.js";
|
|
22
|
+
export * as visas from "./visas/index.js";
|
|
23
|
+
export * as resume from "./resume/index.js";
|
|
24
|
+
export * as external from "./external/index.js";
|
|
25
|
+
export * as reviews from "./reviews/index.js";
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/services/profile/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,cAAc,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC"}
|