@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.
Files changed (195) hide show
  1. package/README.md +49 -9
  2. package/dist/__generated__/gateway.d.ts +4546 -0
  3. package/dist/__generated__/gateway.d.ts.map +1 -0
  4. package/dist/__generated__/gateway.js +9 -0
  5. package/dist/__generated__/gateway.js.map +1 -0
  6. package/dist/__generated__/talent-profile-zod-schemas.d.ts +1187 -0
  7. package/dist/__generated__/talent-profile-zod-schemas.d.ts.map +1 -0
  8. package/dist/__generated__/talent-profile-zod-schemas.js +1136 -0
  9. package/dist/__generated__/talent-profile-zod-schemas.js.map +1 -0
  10. package/dist/__generated__/talent-profile.d.ts +1397 -0
  11. package/dist/__generated__/talent-profile.d.ts.map +1 -0
  12. package/dist/__generated__/talent-profile.js +9 -0
  13. package/dist/__generated__/talent-profile.js.map +1 -0
  14. package/dist/__generated__/zod-schemas.d.ts +2895 -0
  15. package/dist/__generated__/zod-schemas.d.ts.map +1 -0
  16. package/dist/__generated__/zod-schemas.js +3121 -0
  17. package/dist/__generated__/zod-schemas.js.map +1 -0
  18. package/dist/__tests__/fixtures/profile/builders.d.ts +74 -0
  19. package/dist/__tests__/fixtures/profile/builders.d.ts.map +1 -0
  20. package/dist/__tests__/fixtures/profile/builders.js +196 -0
  21. package/dist/__tests__/fixtures/profile/builders.js.map +1 -0
  22. package/dist/__tests__/fixtures/profile/data.d.ts +39 -0
  23. package/dist/__tests__/fixtures/profile/data.d.ts.map +1 -0
  24. package/dist/__tests__/fixtures/profile/data.js +230 -0
  25. package/dist/__tests__/fixtures/profile/data.js.map +1 -0
  26. package/dist/__tests__/fixtures/profile/index.d.ts +9 -0
  27. package/dist/__tests__/fixtures/profile/index.d.ts.map +1 -0
  28. package/dist/__tests__/fixtures/profile/index.js +10 -0
  29. package/dist/__tests__/fixtures/profile/index.js.map +1 -0
  30. package/dist/__tests__/fixtures/profile/types.d.ts +53 -0
  31. package/dist/__tests__/fixtures/profile/types.d.ts.map +1 -0
  32. package/dist/__tests__/fixtures/profile/types.js +4 -0
  33. package/dist/__tests__/fixtures/profile/types.js.map +1 -0
  34. package/dist/auth/errors.d.ts +82 -0
  35. package/dist/auth/errors.d.ts.map +1 -0
  36. package/dist/auth/errors.js +68 -0
  37. package/dist/auth/errors.js.map +1 -0
  38. package/dist/auth.d.ts +192 -0
  39. package/dist/auth.d.ts.map +1 -0
  40. package/dist/auth.js +294 -0
  41. package/dist/auth.js.map +1 -0
  42. package/dist/config.d.ts +212 -0
  43. package/dist/config.d.ts.map +1 -0
  44. package/dist/config.js +349 -0
  45. package/dist/config.js.map +1 -0
  46. package/dist/configLock.d.ts +50 -0
  47. package/dist/configLock.d.ts.map +1 -0
  48. package/dist/configLock.js +88 -0
  49. package/dist/configLock.js.map +1 -0
  50. package/dist/configWriter.d.ts +97 -0
  51. package/dist/configWriter.d.ts.map +1 -0
  52. package/dist/configWriter.js +687 -0
  53. package/dist/configWriter.js.map +1 -0
  54. package/dist/index.d.ts +37 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +28 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/kill-switch.d.ts +161 -0
  59. package/dist/kill-switch.d.ts.map +1 -0
  60. package/dist/kill-switch.js +235 -0
  61. package/dist/kill-switch.js.map +1 -0
  62. package/dist/lib/date.d.ts +58 -0
  63. package/dist/lib/date.d.ts.map +1 -0
  64. package/dist/lib/date.js +104 -0
  65. package/dist/lib/date.js.map +1 -0
  66. package/dist/lib/diagnostic-log.d.ts +159 -0
  67. package/dist/lib/diagnostic-log.d.ts.map +1 -0
  68. package/dist/lib/diagnostic-log.js +186 -0
  69. package/dist/lib/diagnostic-log.js.map +1 -0
  70. package/dist/lib/package-version.d.ts +19 -0
  71. package/dist/lib/package-version.d.ts.map +1 -0
  72. package/dist/lib/package-version.js +38 -0
  73. package/dist/lib/package-version.js.map +1 -0
  74. package/dist/lib/redact.d.ts +153 -0
  75. package/dist/lib/redact.d.ts.map +1 -0
  76. package/dist/lib/redact.js +207 -0
  77. package/dist/lib/redact.js.map +1 -0
  78. package/dist/lib/text.d.ts +14 -0
  79. package/dist/lib/text.d.ts.map +1 -0
  80. package/dist/lib/text.js +21 -0
  81. package/dist/lib/text.js.map +1 -0
  82. package/dist/lib/wire-shape.d.ts +131 -0
  83. package/dist/lib/wire-shape.d.ts.map +1 -0
  84. package/dist/lib/wire-shape.js +376 -0
  85. package/dist/lib/wire-shape.js.map +1 -0
  86. package/dist/onepassword.d.ts +29 -0
  87. package/dist/onepassword.d.ts.map +1 -0
  88. package/dist/onepassword.js +112 -0
  89. package/dist/onepassword.js.map +1 -0
  90. package/dist/services/_shared/transport.d.ts +148 -0
  91. package/dist/services/_shared/transport.d.ts.map +1 -0
  92. package/dist/services/_shared/transport.js +102 -0
  93. package/dist/services/_shared/transport.js.map +1 -0
  94. package/dist/services/applications/index.d.ts +210 -0
  95. package/dist/services/applications/index.d.ts.map +1 -0
  96. package/dist/services/applications/index.js +240 -0
  97. package/dist/services/applications/index.js.map +1 -0
  98. package/dist/services/availability/index.d.ts +254 -0
  99. package/dist/services/availability/index.d.ts.map +1 -0
  100. package/dist/services/availability/index.js +310 -0
  101. package/dist/services/availability/index.js.map +1 -0
  102. package/dist/services/contracts/index.d.ts +132 -0
  103. package/dist/services/contracts/index.d.ts.map +1 -0
  104. package/dist/services/contracts/index.js +211 -0
  105. package/dist/services/contracts/index.js.map +1 -0
  106. package/dist/services/engagements/index.d.ts +504 -0
  107. package/dist/services/engagements/index.d.ts.map +1 -0
  108. package/dist/services/engagements/index.js +613 -0
  109. package/dist/services/engagements/index.js.map +1 -0
  110. package/dist/services/jobs/index.d.ts +490 -0
  111. package/dist/services/jobs/index.d.ts.map +1 -0
  112. package/dist/services/jobs/index.js +753 -0
  113. package/dist/services/jobs/index.js.map +1 -0
  114. package/dist/services/payments/index.d.ts +415 -0
  115. package/dist/services/payments/index.d.ts.map +1 -0
  116. package/dist/services/payments/index.js +636 -0
  117. package/dist/services/payments/index.js.map +1 -0
  118. package/dist/services/profile/__tests__/fixtures.d.ts +214 -0
  119. package/dist/services/profile/__tests__/fixtures.d.ts.map +1 -0
  120. package/dist/services/profile/__tests__/fixtures.js +176 -0
  121. package/dist/services/profile/__tests__/fixtures.js.map +1 -0
  122. package/dist/services/profile/basic/index.d.ts +390 -0
  123. package/dist/services/profile/basic/index.d.ts.map +1 -0
  124. package/dist/services/profile/basic/index.js +1007 -0
  125. package/dist/services/profile/basic/index.js.map +1 -0
  126. package/dist/services/profile/certifications/index.d.ts +74 -0
  127. package/dist/services/profile/certifications/index.d.ts.map +1 -0
  128. package/dist/services/profile/certifications/index.js +169 -0
  129. package/dist/services/profile/certifications/index.js.map +1 -0
  130. package/dist/services/profile/education/index.d.ts +73 -0
  131. package/dist/services/profile/education/index.d.ts.map +1 -0
  132. package/dist/services/profile/education/index.js +168 -0
  133. package/dist/services/profile/education/index.js.map +1 -0
  134. package/dist/services/profile/employment/index.d.ts +111 -0
  135. package/dist/services/profile/employment/index.d.ts.map +1 -0
  136. package/dist/services/profile/employment/index.js +202 -0
  137. package/dist/services/profile/employment/index.js.map +1 -0
  138. package/dist/services/profile/external/index.d.ts +219 -0
  139. package/dist/services/profile/external/index.d.ts.map +1 -0
  140. package/dist/services/profile/external/index.js +560 -0
  141. package/dist/services/profile/external/index.js.map +1 -0
  142. package/dist/services/profile/index.d.ts +24 -0
  143. package/dist/services/profile/index.d.ts.map +1 -0
  144. package/dist/services/profile/index.js +26 -0
  145. package/dist/services/profile/index.js.map +1 -0
  146. package/dist/services/profile/industries/index.d.ts +130 -0
  147. package/dist/services/profile/industries/index.d.ts.map +1 -0
  148. package/dist/services/profile/industries/index.js +292 -0
  149. package/dist/services/profile/industries/index.js.map +1 -0
  150. package/dist/services/profile/portfolio/index.d.ts +352 -0
  151. package/dist/services/profile/portfolio/index.d.ts.map +1 -0
  152. package/dist/services/profile/portfolio/index.js +833 -0
  153. package/dist/services/profile/portfolio/index.js.map +1 -0
  154. package/dist/services/profile/resume/index.d.ts +60 -0
  155. package/dist/services/profile/resume/index.d.ts.map +1 -0
  156. package/dist/services/profile/resume/index.js +212 -0
  157. package/dist/services/profile/resume/index.js.map +1 -0
  158. package/dist/services/profile/reviews/index.d.ts +137 -0
  159. package/dist/services/profile/reviews/index.d.ts.map +1 -0
  160. package/dist/services/profile/reviews/index.js +431 -0
  161. package/dist/services/profile/reviews/index.js.map +1 -0
  162. package/dist/services/profile/shared.d.ts +127 -0
  163. package/dist/services/profile/shared.d.ts.map +1 -0
  164. package/dist/services/profile/shared.js +155 -0
  165. package/dist/services/profile/shared.js.map +1 -0
  166. package/dist/services/profile/skills/index.d.ts +212 -0
  167. package/dist/services/profile/skills/index.d.ts.map +1 -0
  168. package/dist/services/profile/skills/index.js +461 -0
  169. package/dist/services/profile/skills/index.js.map +1 -0
  170. package/dist/services/profile/visas/index.d.ts +74 -0
  171. package/dist/services/profile/visas/index.d.ts.map +1 -0
  172. package/dist/services/profile/visas/index.js +306 -0
  173. package/dist/services/profile/visas/index.js.map +1 -0
  174. package/dist/services/timesheet/index.d.ts +326 -0
  175. package/dist/services/timesheet/index.d.ts.map +1 -0
  176. package/dist/services/timesheet/index.js +324 -0
  177. package/dist/services/timesheet/index.js.map +1 -0
  178. package/dist/services/translations.d.ts +79 -0
  179. package/dist/services/translations.d.ts.map +1 -0
  180. package/dist/services/translations.js +136 -0
  181. package/dist/services/translations.js.map +1 -0
  182. package/dist/transport-resilience.d.ts +136 -0
  183. package/dist/transport-resilience.d.ts.map +1 -0
  184. package/dist/transport-resilience.js +247 -0
  185. package/dist/transport-resilience.js.map +1 -0
  186. package/dist/transport.d.ts +408 -0
  187. package/dist/transport.d.ts.map +1 -0
  188. package/dist/transport.js +691 -0
  189. package/dist/transport.js.map +1 -0
  190. package/dist/types.d.ts +41 -0
  191. package/dist/types.d.ts.map +1 -0
  192. package/dist/types.js +18 -0
  193. package/dist/types.js.map +1 -0
  194. package/package.json +40 -12
  195. package/index.js +0 -7
@@ -0,0 +1,130 @@
1
+ /**
2
+ * `IndustryProfile` row as ttctl exposes it. Mirrors the read-side
3
+ * `IndustryProfile` GraphQL fragment (see
4
+ * `research/graphql/talent_profile/fragments/IndustryProfile.graphql`)
5
+ * trimmed to identity fields. The richer relational fields (`employments`,
6
+ * `educations`, `certifications`, `portfolioItems`, `highlights`) are
7
+ * exposed as raw `unknown` for now — callers who need them can deserialize
8
+ * via the generated GraphQL types.
9
+ */
10
+ export interface IndustryProfile {
11
+ id: string;
12
+ title: string;
13
+ about: string | null;
14
+ domainArea: string | null;
15
+ }
16
+ /**
17
+ * Fields editable on an `IndustryProfile` row. Mirrors the inferred
18
+ * `IndustryProfileInput` shape per Pattern 1/2 in
19
+ * `research/notes/10-mutation-input-patterns.md`. The CLI exposes
20
+ * `--name` (→ title) and `--connection` (→ domainArea) plus `--about` for
21
+ * an optional description.
22
+ */
23
+ export interface IndustryProfileFields {
24
+ title?: string;
25
+ about?: string | null;
26
+ domainArea?: string | null;
27
+ }
28
+ /**
29
+ * Catalog `Industry` entry returned by `industriesAutocomplete`. Light —
30
+ * just the catalog ID (used to wire connections later) and the display
31
+ * name.
32
+ */
33
+ export interface IndustryCatalogEntry {
34
+ id: string;
35
+ name: string;
36
+ }
37
+ /**
38
+ * List the signed-in user's `IndustryProfile` rows.
39
+ *
40
+ * Walks `profile(id: $profileId) { industryProfiles { nodes { ... } } }`
41
+ * — the document hand-authored against the inferred live wire (see
42
+ * {@link LIST_INDUSTRY_PROFILES_QUERY}). The synthesized `Profile` type
43
+ * has no `industryProfiles` field, so structural validation is done at
44
+ * runtime: if the response does not carry a `profile.industryProfiles.nodes`
45
+ * array, the helper throws `GRAPHQL_ERROR` rather than silently defaulting
46
+ * to `[]` (AC #6 of #321 — optional-chain defaults are forbidden where
47
+ * the chain hides a wire-shape mismatch).
48
+ *
49
+ * An empty array (`nodes: []`) is the legitimate "user has zero industry
50
+ * rows" return and is propagated as `[]`. Only structural absence —
51
+ * `profile` null or `industryProfiles` missing — produces a thrown
52
+ * `GRAPHQL_ERROR`.
53
+ *
54
+ * `options.profileId` lets callers (notably {@link add}) reuse an already-
55
+ * resolved profile id and avoid the duplicate `basic.show` round-trip
56
+ * implicit in `extractProfileId`. When omitted, `extractProfileId` runs.
57
+ */
58
+ export declare function list(token: string, options?: {
59
+ profileId?: string;
60
+ }): Promise<IndustryProfile[]>;
61
+ /**
62
+ * Fetch a single `IndustryProfile` by id via the schema's `node()`
63
+ * resolver.
64
+ */
65
+ export declare function show(token: string, id: string): Promise<IndustryProfile>;
66
+ /**
67
+ * Create a new `IndustryProfile` row. Wire format (verified live
68
+ * 2026-05-16, #321): FLAT input with `profileId` plus the
69
+ * `IndustryProfile` field set; see {@link buildIndustryProfileInputBody}.
70
+ * The mutation payload is `{ success, errors }` only — it does NOT
71
+ * echo the created entity (#321: a prior implementation selected a
72
+ * non-existent `industryProfile` field on the payload, which the live
73
+ * API rejected at document-validation time).
74
+ *
75
+ * To return the created entity, this function reads the row back via
76
+ * `list()` after the mutation succeeds, using a pre/post id-set diff
77
+ * to identify the new row reliably even when the user has duplicate
78
+ * titles. The diff approach costs one extra wire round-trip but
79
+ * survives the "two rows with the same title" failure mode that a
80
+ * title-match strategy would mis-attribute.
81
+ *
82
+ * `--name` (→ `title`) is required. `--connection` (→ `domainArea`)
83
+ * is optional and represents the user's domain expertise modifier
84
+ * (e.g., "Healthcare" + connection "Backend"); when omitted, the
85
+ * server-required non-null is satisfied with an empty string.
86
+ */
87
+ export declare function add(token: string, fields: IndustryProfileFields): Promise<IndustryProfile>;
88
+ /**
89
+ * Update an existing `IndustryProfile`. Wire format (verified live
90
+ * 2026-05-16, #321): FLAT input with `industryProfileId` plus the same
91
+ * field set used by Create — see {@link buildIndustryProfileInputBody}.
92
+ * The mutation payload is `{ success, errors }` only — it does NOT
93
+ * echo the updated entity. The updated entity is read back via
94
+ * `show(id)` after the mutation succeeds.
95
+ *
96
+ * `update()` does a partial-update over a server-side full-replace
97
+ * shape: it `show()`s the current row, merges the user-supplied
98
+ * fields, and sends the merged shape so unspecified fields preserve
99
+ * their current values rather than being clobbered to empty.
100
+ */
101
+ export declare function update(token: string, id: string, fields: IndustryProfileFields): Promise<IndustryProfile>;
102
+ /**
103
+ * Remove an `IndustryProfile` row. Wire format per Pattern 3:
104
+ * `{ industryProfileId }`.
105
+ *
106
+ * Note: the synthesized SDL does not declare a `removeIndustryProfile`
107
+ * mutation, but the CLI surface promises a `remove` leaf for industries.
108
+ * The mutation is sent under the assumed name; a top-level GraphQL error
109
+ * (e.g. "Cannot find mutation `removeIndustryProfile`") surfaces as
110
+ * `ProfileError("GRAPHQL_ERROR")` so the user can file an issue with the
111
+ * captured response.
112
+ */
113
+ export declare function remove(token: string, id: string): Promise<string>;
114
+ /**
115
+ * Search the industry catalog for known industry names.
116
+ *
117
+ * Issues `industriesAutocomplete($search, $limit, $withoutIds)` against
118
+ * the talent-profile surface. Schema-typed return is a single `Industry`
119
+ * but real responses are list-shaped — accepting either keeps callers
120
+ * stable.
121
+ *
122
+ * `withoutIds` excludes industries the user already has on their profile;
123
+ * leave undefined for "any match". `limit` defaults to `10` (mirrors the
124
+ * web client).
125
+ */
126
+ export declare function autocomplete(token: string, search: string, options?: {
127
+ limit?: number;
128
+ withoutIds?: string[];
129
+ }): Promise<IndustryCatalogEntry[]>;
130
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/services/profile/industries/index.ts"],"names":[],"mappings":"AAOA;;;;;;;;GAQG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAyHD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAiCtG;AAED;;;GAGG;AACH,wBAAsB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAe9E;AAqCD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAyBhG;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,eAAe,CAAC,CAmB/G;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAUvE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CAAO,GACtD,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAmBjC"}
@@ -0,0 +1,292 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { ProfileError } from "../basic/index.js";
4
+ import { applyUserErrorsAndSuccess, callTalentProfile, ensureNoTopLevelErrors, extractProfileId } from "../shared.js";
5
+ const INDUSTRY_PROFILE_FRAGMENT = `fragment IndustryProfile on IndustryProfile {
6
+ id
7
+ title
8
+ about
9
+ domainArea
10
+ }`;
11
+ const GET_INDUSTRY_PROFILE_QUERY = `query GetIndustryProfile($id: ID!) {
12
+ node(id: $id) { ...IndustryProfile }
13
+ }
14
+ ${INDUSTRY_PROFILE_FRAGMENT}`;
15
+ /**
16
+ * `CreateIndustryProfile` mutation. The payload shape per the synthesized
17
+ * schema (`packages/core/src/__generated__/talent-profile.ts`,
18
+ * `CreateIndustryProfilePayload`) AND the live capture in
19
+ * `research/graphql/talent_profile/operations/CreateIndustryProfile.graphql`
20
+ * is `{ success, errors }` ONLY — neither `notice` nor `industryProfile`
21
+ * are members. Selecting either field causes the live API to reject the
22
+ * entire document with "Field 'X' doesn't exist on type
23
+ * 'CreateIndustryProfilePayload'" before the resolver runs, which is the
24
+ * #321 originating incident.
25
+ *
26
+ * The mutation therefore does NOT echo the created entity. {@link add}
27
+ * compensates by reading the row back via `list()` after the mutation
28
+ * succeeds — see that function for the `pre-list → mutate → post-list`
29
+ * diff pattern.
30
+ */
31
+ const CREATE_INDUSTRY_PROFILE_MUTATION = `mutation CreateIndustryProfile($input: CreateIndustryProfileInput!) {
32
+ createIndustryProfile(input: $input) {
33
+ success
34
+ errors { code key message }
35
+ }
36
+ }`;
37
+ /**
38
+ * `UpdateIndustryProfile` mutation. Same payload-shape constraint as
39
+ * {@link CREATE_INDUSTRY_PROFILE_MUTATION} per the synthesized schema +
40
+ * live capture. {@link update} reads the row back via `show(id)` after
41
+ * the mutation since the payload does not echo the updated entity.
42
+ */
43
+ const UPDATE_INDUSTRY_PROFILE_MUTATION = `mutation UpdateIndustryProfile($input: UpdateIndustryProfileInput!) {
44
+ updateIndustryProfile(input: $input) {
45
+ success
46
+ errors { code key message }
47
+ }
48
+ }`;
49
+ /**
50
+ * `RemoveIndustryProfile` mutation. Wire format per Pattern 3:
51
+ * `{ industryProfileId }`. The synthesized schema does NOT declare a
52
+ * `removeIndustryProfile` mutation (gap region per `research/notes/11`);
53
+ * the mutation is sent under the assumed name and a top-level GraphQL
54
+ * error from the server (e.g. "Cannot find mutation
55
+ * `removeIndustryProfile`") surfaces as `ProfileError("GRAPHQL_ERROR")`
56
+ * so the user can file an issue with the captured response.
57
+ */
58
+ const REMOVE_INDUSTRY_PROFILE_MUTATION = `mutation RemoveIndustryProfile($input: RemoveIndustryProfileInput!) {
59
+ removeIndustryProfile(input: $input) {
60
+ success
61
+ errors { code key message }
62
+ }
63
+ }`;
64
+ const INDUSTRIES_AUTOCOMPLETE_QUERY = `query GET_INDUSTRIES_FOR_AUTOCOMPLETE($search: String!, $limit: Int!, $withoutIds: [ID!]) {
65
+ industriesAutocomplete(search: $search, limit: $limit, withoutIds: $withoutIds) {
66
+ id
67
+ name
68
+ }
69
+ }`;
70
+ /**
71
+ * `ListIndustryProfiles` query. Walks the profile's authored industry
72
+ * rows via `profile(id) { industryProfiles { nodes } }`. The synthesized
73
+ * `Profile` type in `__generated__/talent-profile.ts` does NOT declare
74
+ * an `industryProfiles` field (schema-synthesis gap), so this query is
75
+ * hand-authored against the inferred live shape. The wire validation
76
+ * happens at runtime: {@link list} explicitly verifies the response
77
+ * has the expected `nodes` array and throws `GRAPHQL_ERROR` otherwise
78
+ * — no silent-empty defaulting (AC #6 of #321).
79
+ */
80
+ const LIST_INDUSTRY_PROFILES_QUERY = `query ListIndustryProfiles($profileId: ID!) {
81
+ profile(id: $profileId) {
82
+ id
83
+ industryProfiles { nodes { ...IndustryProfile } }
84
+ }
85
+ }
86
+ ${INDUSTRY_PROFILE_FRAGMENT}`;
87
+ /**
88
+ * List the signed-in user's `IndustryProfile` rows.
89
+ *
90
+ * Walks `profile(id: $profileId) { industryProfiles { nodes { ... } } }`
91
+ * — the document hand-authored against the inferred live wire (see
92
+ * {@link LIST_INDUSTRY_PROFILES_QUERY}). The synthesized `Profile` type
93
+ * has no `industryProfiles` field, so structural validation is done at
94
+ * runtime: if the response does not carry a `profile.industryProfiles.nodes`
95
+ * array, the helper throws `GRAPHQL_ERROR` rather than silently defaulting
96
+ * to `[]` (AC #6 of #321 — optional-chain defaults are forbidden where
97
+ * the chain hides a wire-shape mismatch).
98
+ *
99
+ * An empty array (`nodes: []`) is the legitimate "user has zero industry
100
+ * rows" return and is propagated as `[]`. Only structural absence —
101
+ * `profile` null or `industryProfiles` missing — produces a thrown
102
+ * `GRAPHQL_ERROR`.
103
+ *
104
+ * `options.profileId` lets callers (notably {@link add}) reuse an already-
105
+ * resolved profile id and avoid the duplicate `basic.show` round-trip
106
+ * implicit in `extractProfileId`. When omitted, `extractProfileId` runs.
107
+ */
108
+ export async function list(token, options) {
109
+ const profileId = options?.profileId ?? (await extractProfileId(token));
110
+ const res = await callTalentProfile(token, "ListIndustryProfiles", LIST_INDUSTRY_PROFILES_QUERY, { profileId }, "industries list");
111
+ const body = res.body;
112
+ ensureNoTopLevelErrors(body, "industries list");
113
+ const profile = body?.data?.profile;
114
+ if (profile === undefined || profile === null) {
115
+ throw new ProfileError("GRAPHQL_ERROR", `industries list returned no \`data.profile\` for the signed-in user (wire shape mismatch).`);
116
+ }
117
+ const industryProfiles = profile.industryProfiles;
118
+ if (industryProfiles === undefined || industryProfiles === null) {
119
+ throw new ProfileError("GRAPHQL_ERROR", `industries list returned no \`data.profile.industryProfiles\` (wire shape mismatch — \`industryProfiles\` field absent on Profile).`);
120
+ }
121
+ const nodes = industryProfiles.nodes;
122
+ if (!Array.isArray(nodes)) {
123
+ throw new ProfileError("GRAPHQL_ERROR", `industries list returned non-array \`data.profile.industryProfiles.nodes\` (wire shape mismatch).`);
124
+ }
125
+ return nodes.filter((n) => n !== null);
126
+ }
127
+ /**
128
+ * Fetch a single `IndustryProfile` by id via the schema's `node()`
129
+ * resolver.
130
+ */
131
+ export async function show(token, id) {
132
+ const res = await callTalentProfile(token, "GetIndustryProfile", GET_INDUSTRY_PROFILE_QUERY, { id }, "industries show");
133
+ const body = res.body;
134
+ ensureNoTopLevelErrors(body, "industries show");
135
+ const node = body?.data?.node;
136
+ if (!node) {
137
+ throw new ProfileError("VALIDATION_ERROR", `IndustryProfile with id "${id}" not found.`);
138
+ }
139
+ return node;
140
+ }
141
+ /**
142
+ * Construct the FLAT wire-input for Create / Update mutations per the
143
+ * live `CreateIndustryProfileInput` shape verified empirically
144
+ * 2026-05-16 against `talent-profile/graphql`:
145
+ *
146
+ * { profileId, title, about, domainArea,
147
+ * highlights, educations, employments, certifications, portfolioItems }
148
+ *
149
+ * The server is strict about presence + non-null on every field — a
150
+ * missing or explicit-null `about` / `domainArea` produces a
151
+ * `Variable $input ... Expected value to not be null` GraphQL error
152
+ * before the resolver runs. The five list-typed fields
153
+ * (`highlights` / `educations` / `employments` / `certifications` /
154
+ * `portfolioItems`) are connection arrays; for a brand-new industry
155
+ * they must be present as empty arrays.
156
+ *
157
+ * The `industryProfile` wrapper key from `research/notes/10` Pattern 2
158
+ * is NOT used by this mutation — the inferred Pattern was wrong for
159
+ * `CreateIndustryProfile` (#321 originating bug). The wire input is
160
+ * flat. This helper centralizes the defaulting so `add()` and
161
+ * `update()` stay narrow.
162
+ */
163
+ function buildIndustryProfileInputBody(fields) {
164
+ return {
165
+ title: fields.title ?? "",
166
+ about: fields.about ?? "",
167
+ domainArea: fields.domainArea ?? "",
168
+ highlights: [],
169
+ educations: [],
170
+ employments: [],
171
+ certifications: [],
172
+ portfolioItems: [],
173
+ };
174
+ }
175
+ /**
176
+ * Create a new `IndustryProfile` row. Wire format (verified live
177
+ * 2026-05-16, #321): FLAT input with `profileId` plus the
178
+ * `IndustryProfile` field set; see {@link buildIndustryProfileInputBody}.
179
+ * The mutation payload is `{ success, errors }` only — it does NOT
180
+ * echo the created entity (#321: a prior implementation selected a
181
+ * non-existent `industryProfile` field on the payload, which the live
182
+ * API rejected at document-validation time).
183
+ *
184
+ * To return the created entity, this function reads the row back via
185
+ * `list()` after the mutation succeeds, using a pre/post id-set diff
186
+ * to identify the new row reliably even when the user has duplicate
187
+ * titles. The diff approach costs one extra wire round-trip but
188
+ * survives the "two rows with the same title" failure mode that a
189
+ * title-match strategy would mis-attribute.
190
+ *
191
+ * `--name` (→ `title`) is required. `--connection` (→ `domainArea`)
192
+ * is optional and represents the user's domain expertise modifier
193
+ * (e.g., "Healthcare" + connection "Backend"); when omitted, the
194
+ * server-required non-null is satisfied with an empty string.
195
+ */
196
+ export async function add(token, fields) {
197
+ if (!fields.title) {
198
+ throw new ProfileError("VALIDATION_ERROR", "industries add requires <name> (mapped to title).");
199
+ }
200
+ const profileId = await extractProfileId(token);
201
+ const beforeIds = new Set((await list(token, { profileId })).map((row) => row.id));
202
+ const res = await callTalentProfile(token, "CreateIndustryProfile", CREATE_INDUSTRY_PROFILE_MUTATION, { input: { profileId, ...buildIndustryProfileInputBody(fields) } }, "industries add");
203
+ unwrapMutation(res, "createIndustryProfile", "industries add");
204
+ const after = await list(token, { profileId });
205
+ const newRow = after.find((row) => !beforeIds.has(row.id));
206
+ if (newRow === undefined) {
207
+ throw new ProfileError("UNKNOWN", "industries add reported success but no new row appeared in the post-mutation list (wire-shape regression or server-side filter).");
208
+ }
209
+ return newRow;
210
+ }
211
+ /**
212
+ * Update an existing `IndustryProfile`. Wire format (verified live
213
+ * 2026-05-16, #321): FLAT input with `industryProfileId` plus the same
214
+ * field set used by Create — see {@link buildIndustryProfileInputBody}.
215
+ * The mutation payload is `{ success, errors }` only — it does NOT
216
+ * echo the updated entity. The updated entity is read back via
217
+ * `show(id)` after the mutation succeeds.
218
+ *
219
+ * `update()` does a partial-update over a server-side full-replace
220
+ * shape: it `show()`s the current row, merges the user-supplied
221
+ * fields, and sends the merged shape so unspecified fields preserve
222
+ * their current values rather than being clobbered to empty.
223
+ */
224
+ export async function update(token, id, fields) {
225
+ if (Object.keys(fields).length === 0) {
226
+ throw new ProfileError("VALIDATION_ERROR", "industries update requires at least one field flag.");
227
+ }
228
+ const current = await show(token, id);
229
+ const merged = {
230
+ title: fields.title ?? current.title,
231
+ about: fields.about !== undefined ? fields.about : current.about,
232
+ domainArea: fields.domainArea !== undefined ? fields.domainArea : current.domainArea,
233
+ };
234
+ const res = await callTalentProfile(token, "UpdateIndustryProfile", UPDATE_INDUSTRY_PROFILE_MUTATION, { input: { industryProfileId: id, ...buildIndustryProfileInputBody(merged) } }, "industries update");
235
+ unwrapMutation(res, "updateIndustryProfile", "industries update");
236
+ return show(token, id);
237
+ }
238
+ /**
239
+ * Remove an `IndustryProfile` row. Wire format per Pattern 3:
240
+ * `{ industryProfileId }`.
241
+ *
242
+ * Note: the synthesized SDL does not declare a `removeIndustryProfile`
243
+ * mutation, but the CLI surface promises a `remove` leaf for industries.
244
+ * The mutation is sent under the assumed name; a top-level GraphQL error
245
+ * (e.g. "Cannot find mutation `removeIndustryProfile`") surfaces as
246
+ * `ProfileError("GRAPHQL_ERROR")` so the user can file an issue with the
247
+ * captured response.
248
+ */
249
+ export async function remove(token, id) {
250
+ const res = await callTalentProfile(token, "RemoveIndustryProfile", REMOVE_INDUSTRY_PROFILE_MUTATION, { input: { industryProfileId: id } }, "industries remove");
251
+ unwrapMutation(res, "removeIndustryProfile", "industries remove");
252
+ return id;
253
+ }
254
+ /**
255
+ * Search the industry catalog for known industry names.
256
+ *
257
+ * Issues `industriesAutocomplete($search, $limit, $withoutIds)` against
258
+ * the talent-profile surface. Schema-typed return is a single `Industry`
259
+ * but real responses are list-shaped — accepting either keeps callers
260
+ * stable.
261
+ *
262
+ * `withoutIds` excludes industries the user already has on their profile;
263
+ * leave undefined for "any match". `limit` defaults to `10` (mirrors the
264
+ * web client).
265
+ */
266
+ export async function autocomplete(token, search, options = {}) {
267
+ if (!search) {
268
+ throw new ProfileError("VALIDATION_ERROR", "industries autocomplete requires a non-empty search query.");
269
+ }
270
+ const limit = options.limit ?? 10;
271
+ const variables = { search, limit };
272
+ if (options.withoutIds !== undefined)
273
+ variables["withoutIds"] = options.withoutIds;
274
+ const res = await callTalentProfile(token, "GET_INDUSTRIES_FOR_AUTOCOMPLETE", INDUSTRIES_AUTOCOMPLETE_QUERY, variables, "industries autocomplete");
275
+ const body = res.body;
276
+ ensureNoTopLevelErrors(body, "industries autocomplete");
277
+ const raw = body?.data?.industriesAutocomplete;
278
+ if (raw === null || raw === undefined)
279
+ return [];
280
+ return Array.isArray(raw) ? raw : [raw];
281
+ }
282
+ function unwrapMutation(res, payloadKey, verb) {
283
+ const body = res.body;
284
+ ensureNoTopLevelErrors(body, verb);
285
+ const payload = body?.data?.[payloadKey];
286
+ if (!payload) {
287
+ throw new ProfileError("UNKNOWN", `${verb} response had no \`data.${payloadKey}\` field`);
288
+ }
289
+ applyUserErrorsAndSuccess(payload, verb);
290
+ return payload;
291
+ }
292
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/services/profile/industries/index.ts"],"names":[],"mappings":"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"}