@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,352 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Portfolio sub-domain error codes. All file-shape and field-shape
|
|
3
|
+
* validation failures collapse into `VALIDATION_ERROR`; the cross-cutting
|
|
4
|
+
* `AuthRevokedError` / `Cf403Error` (from `TtctlError` hierarchy) propagate
|
|
5
|
+
* unchanged so the CLI / MCP surfaces apply their uniform `Recovery: ...`
|
|
6
|
+
* presentation per #77.
|
|
7
|
+
*/
|
|
8
|
+
export type PortfolioErrorCode = "NO_VIEWER" | "GRAPHQL_ERROR" | "NETWORK_ERROR" | "USER_ERROR" | "VALIDATION_ERROR" | "FILE_NOT_FOUND" | "FILE_READ_ERROR" | "WIRE_SHAPE_ERROR" | "UNKNOWN";
|
|
9
|
+
export declare class PortfolioError extends Error {
|
|
10
|
+
readonly code: PortfolioErrorCode;
|
|
11
|
+
readonly name = "PortfolioError";
|
|
12
|
+
constructor(code: PortfolioErrorCode, message: string, options?: {
|
|
13
|
+
cause?: unknown;
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Skill reference shape carried by `createPortfolioItem` /
|
|
18
|
+
* `updatePortfolioItem` inputs. Extracted from the Portfolio fragment
|
|
19
|
+
* (`research/graphql/talent_profile/fragments/Portfolio.graphql`) which
|
|
20
|
+
* names `skills.nodes[].id` and `.name` — the input variant takes
|
|
21
|
+
* `{ id, name }` per the Pattern 1/2 inferred shapes in
|
|
22
|
+
* `research/notes/10-mutation-input-patterns.md`.
|
|
23
|
+
*/
|
|
24
|
+
export interface SkillRef {
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Portfolio item kind enumeration. Empirically the server requires this
|
|
30
|
+
* as a non-null field on `CreatePortfolioItemInput.portfolioItem`. The
|
|
31
|
+
* WRITE-side enum uses **lowercase snake_case** values — the
|
|
32
|
+
* SCREAMING_SNAKE forms returned by the read-side `PortfolioItemKindEnum`
|
|
33
|
+
* in `research/graphql/gateway/schema.graphql` are REJECTED on create
|
|
34
|
+
* with `"kind: is not included in the list"` (verified live 2026-05-16
|
|
35
|
+
* during issue #314 investigation, see `.tmp/probe-portfolio-kind.mjs`).
|
|
36
|
+
*
|
|
37
|
+
* Use the {@link PORTFOLIO_ITEM_KIND} constant for autocomplete-friendly
|
|
38
|
+
* references. The {@link PortfolioItemKind} type is derived so adding a
|
|
39
|
+
* member here automatically extends the type.
|
|
40
|
+
*/
|
|
41
|
+
export declare const PORTFOLIO_ITEM_KIND: {
|
|
42
|
+
readonly ACCOMPLISHMENT: "accomplishment";
|
|
43
|
+
readonly BASIC: "basic";
|
|
44
|
+
readonly CLASSIC: "classic";
|
|
45
|
+
readonly CODE_BASE: "code_base";
|
|
46
|
+
readonly OTHER_AMAZING_THINGS: "other_amazing_things";
|
|
47
|
+
};
|
|
48
|
+
export type PortfolioItemKind = (typeof PORTFOLIO_ITEM_KIND)[keyof typeof PORTFOLIO_ITEM_KIND];
|
|
49
|
+
/**
|
|
50
|
+
* Portfolio item write-side input shape.
|
|
51
|
+
*
|
|
52
|
+
* **[INFERRED — partially verified live]** Mirrors the read-side `Portfolio`
|
|
53
|
+
* fragment field-by-field per Pattern 1/2 in
|
|
54
|
+
* `research/notes/10-mutation-input-patterns.md`. The `UPDATE_BASIC_INFO`
|
|
55
|
+
* precedent showed that wrapper-key inference can be falsified by live
|
|
56
|
+
* capture (`profile` vs the predicted `basicInfo`). The 2026-05-15 batch
|
|
57
|
+
* (issue #314) live-discovered that `kind`, `showViaToptal`, and `skills`
|
|
58
|
+
* are non-null required on create — {@link add} applies safe defaults so
|
|
59
|
+
* existing callers do not need to thread these fields.
|
|
60
|
+
*/
|
|
61
|
+
export interface PortfolioItemInput {
|
|
62
|
+
title?: string;
|
|
63
|
+
description?: string;
|
|
64
|
+
link?: string;
|
|
65
|
+
websiteUrl?: string;
|
|
66
|
+
accomplishment?: string;
|
|
67
|
+
publicationPermit?: boolean;
|
|
68
|
+
clientOrCompanyName?: string;
|
|
69
|
+
toptalRelated?: boolean;
|
|
70
|
+
showViaToptal?: boolean;
|
|
71
|
+
highlight?: boolean;
|
|
72
|
+
kind?: PortfolioItemKind;
|
|
73
|
+
skills?: SkillRef[];
|
|
74
|
+
/**
|
|
75
|
+
* Catalog Industry IDs (from `industriesAutocomplete`) that this
|
|
76
|
+
* portfolio item belongs to. Required by the server on create — empty
|
|
77
|
+
* array surfaces as `industries: You can't leave this empty` USER_ERROR
|
|
78
|
+
* (verified live 2026-05-16, see `.tmp/probe-portfolio-industries.mjs`).
|
|
79
|
+
*
|
|
80
|
+
* **Per-item explicit choice**: industries are NOT defaulted from
|
|
81
|
+
* `Profile.basicInfoIndustries`, `industriesAutocomplete`, skill
|
|
82
|
+
* inference, or any other source. Each portfolio item's industry
|
|
83
|
+
* association is the caller's deliberate decision; auto-defaulting
|
|
84
|
+
* would silently mis-tag work and pollute the portfolio.
|
|
85
|
+
*/
|
|
86
|
+
industryIds?: string[];
|
|
87
|
+
/**
|
|
88
|
+
* Cover-image cache name returned by a prior `uploadCover()` call. The
|
|
89
|
+
* two-step "upload, then create with the cache name" flow is what the
|
|
90
|
+
* talent-profile web client uses to bind a cover to a new portfolio
|
|
91
|
+
* item — the read-side `Portfolio.coverImage` field surfaces a URL
|
|
92
|
+
* once the server has resolved the cache name.
|
|
93
|
+
*/
|
|
94
|
+
coverImage?: string;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Read-side portfolio item shape — projection of the `Portfolio` fragment.
|
|
98
|
+
* Service callers receive this on `list()` / mutation responses; the
|
|
99
|
+
* mutation responses also surface the full mutated list on `profile.portfolioItems.nodes`.
|
|
100
|
+
*
|
|
101
|
+
* The `kind`, `skills`, and `industries` fields are populated for callers
|
|
102
|
+
* that need the full state (e.g. {@link update}'s read-modify-write
|
|
103
|
+
* path); the server enforces these as non-null on `update` mutations.
|
|
104
|
+
*/
|
|
105
|
+
export interface PortfolioItem {
|
|
106
|
+
id: string;
|
|
107
|
+
title: string | null;
|
|
108
|
+
description: string | null;
|
|
109
|
+
link: string | null;
|
|
110
|
+
highlight: boolean;
|
|
111
|
+
coverImage: string | null;
|
|
112
|
+
accomplishment: string | null;
|
|
113
|
+
publicationPermit: boolean | null;
|
|
114
|
+
clientOrCompanyName: string | null;
|
|
115
|
+
websiteUrl: string | null;
|
|
116
|
+
toptalRelated: boolean | null;
|
|
117
|
+
showViaToptal: boolean | null;
|
|
118
|
+
kind: PortfolioItemKind | null;
|
|
119
|
+
skills: SkillRef[];
|
|
120
|
+
industries: {
|
|
121
|
+
id: string;
|
|
122
|
+
name: string;
|
|
123
|
+
}[];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Fetch the signed-in user's portfolio items. Takes the user's auth token
|
|
127
|
+
* and returns the typed array; the empty-list case returns `[]` (not
|
|
128
|
+
* `null`).
|
|
129
|
+
*/
|
|
130
|
+
export declare function list(token: string): Promise<PortfolioItem[]>;
|
|
131
|
+
/**
|
|
132
|
+
* Create a new portfolio item.
|
|
133
|
+
*
|
|
134
|
+
* Returns the full updated portfolio list — the server treats portfolio
|
|
135
|
+
* items as a profile-scoped collection, and the mutation response always
|
|
136
|
+
* carries the post-mutation snapshot. Callers that only want the new item
|
|
137
|
+
* find it as the last entry (or by matching `title`).
|
|
138
|
+
*
|
|
139
|
+
* **Required-field defaults**: live capture (issue #314, batch 2026-05-15;
|
|
140
|
+
* extended 2026-05-16 with empirical re-investigation via
|
|
141
|
+
* `.tmp/probe-portfolio-*.mjs`) showed the server requires `kind`,
|
|
142
|
+
* `showViaToptal`, `skills`, `description`, `publicationPermit`, and
|
|
143
|
+
* `industryIds` as non-null (and `description` carries a ≥200-character
|
|
144
|
+
* minimum-length constraint). We project safe defaults so existing
|
|
145
|
+
* callers (e.g. the `ttctl profile portfolio add --title ...` CLI
|
|
146
|
+
* surface) do not need to thread the structural fields; users who want
|
|
147
|
+
* explicit control can still pass them through.
|
|
148
|
+
*
|
|
149
|
+
* - `kind` defaults to `"basic"` — the most neutral enum member,
|
|
150
|
+
* matching a portfolio entry with only `title` / `description` /
|
|
151
|
+
* `link` and no special structural framing (vs. `accomplishment`,
|
|
152
|
+
* `classic` case-study, `code_base` repo, or `other_amazing_things`).
|
|
153
|
+
* Note: write-side enum is LOWERCASE; the synthesized read-side
|
|
154
|
+
* `PortfolioItemKindEnum` uses SCREAMING_SNAKE which is rejected on
|
|
155
|
+
* create.
|
|
156
|
+
* - `showViaToptal` defaults to `true` — a TTCtl-created item is
|
|
157
|
+
* intended for visibility on the user's Toptal profile; users who
|
|
158
|
+
* want to hide can `update` after create.
|
|
159
|
+
* - `skills` defaults to the first profile skill — preserves the
|
|
160
|
+
* "minimal CLI invocation just works" UX; empty-profile case
|
|
161
|
+
* surfaces VALIDATION_ERROR.
|
|
162
|
+
* - `description` defaults to {@link DEFAULT_PORTFOLIO_DESCRIPTION},
|
|
163
|
+
* a 273-character placeholder that satisfies the server's ≥200-char
|
|
164
|
+
* minimum and obviously reads as a placeholder users would refine
|
|
165
|
+
* via `ttctl profile portfolio update`.
|
|
166
|
+
* - `publicationPermit` defaults to `true`. The server treats `false`
|
|
167
|
+
* as blank (`USER_ERROR code: blank, key: publicationPermit`) — only
|
|
168
|
+
* `true` is accepted on create. Users who want to flip the field can
|
|
169
|
+
* `update` after create (the update path may handle `false`
|
|
170
|
+
* differently — uninvestigated).
|
|
171
|
+
* - `industryIds` is **REQUIRED** — caller MUST supply at least one
|
|
172
|
+
* catalog Industry ID per portfolio item. We do NOT default from
|
|
173
|
+
* `Profile.basicInfoIndustries`, `industriesAutocomplete`, or skill
|
|
174
|
+
* inference: each portfolio item's industry association is the
|
|
175
|
+
* caller's deliberate choice; auto-defaulting would silently mis-tag
|
|
176
|
+
* work. Discover IDs via `ttctl profile industries autocomplete
|
|
177
|
+
* <query>`.
|
|
178
|
+
*/
|
|
179
|
+
/**
|
|
180
|
+
* `add()` parameter shape: `PortfolioItemInput` with `industryIds` narrowed
|
|
181
|
+
* to a required field. `update()` still accepts the base
|
|
182
|
+
* `PortfolioItemInput` (where `industryIds` is optional — partial-update
|
|
183
|
+
* semantics). Splitting at the function-parameter level keeps a single
|
|
184
|
+
* input vocabulary and lets TypeScript catch missing-industries at the
|
|
185
|
+
* call site instead of waiting for the runtime guard.
|
|
186
|
+
*
|
|
187
|
+
* The empty-array case is still checked at runtime — `[]` is structurally
|
|
188
|
+
* a `string[]` but semantically invalid; TS lacks a native non-empty-array
|
|
189
|
+
* type and `[string, ...string[]]` would be hostile to spread-from-array
|
|
190
|
+
* call sites.
|
|
191
|
+
*/
|
|
192
|
+
export type PortfolioItemAddInput = PortfolioItemInput & {
|
|
193
|
+
industryIds: string[];
|
|
194
|
+
};
|
|
195
|
+
export declare function add(token: string, input: PortfolioItemAddInput): Promise<PortfolioItem[]>;
|
|
196
|
+
/**
|
|
197
|
+
* Update a portfolio item by id. Conceptually a partial update — callers
|
|
198
|
+
* supply only the fields they want to change — but the server's
|
|
199
|
+
* `updatePortfolioItem` mutation enforces full-replace semantics on
|
|
200
|
+
* `PortfolioItemUpdateInput` non-null fields. Verified live 2026-05-16
|
|
201
|
+
* (probe `.tmp/probe-portfolio-update-shape2.mjs`): the update input
|
|
202
|
+
* shape DIFFERS from create:
|
|
203
|
+
*
|
|
204
|
+
* - GQL-level non-null required: `showViaToptal`, `skills`.
|
|
205
|
+
* - USER_ERROR (`code: blank`) if missing: `description` (≥200 chars),
|
|
206
|
+
* `publicationPermit`, `industries` (i.e. `industryIds`).
|
|
207
|
+
* - **NOT defined** on `PortfolioItemUpdateInput` (rejected at GQL
|
|
208
|
+
* layer): `kind`, `coverImage`. These are write-once on create; to
|
|
209
|
+
* change a cover, the caller goes through `uploadCover()` →
|
|
210
|
+
* separate mutation, not via `update`.
|
|
211
|
+
*
|
|
212
|
+
* To preserve the partial-update UX over the full-replace wire shape,
|
|
213
|
+
* this function does read-modify-write: fetch the current item, merge
|
|
214
|
+
* caller's `changes` on top of the current state, then send the merged
|
|
215
|
+
* input. The mutation response carries the full post-mutation list,
|
|
216
|
+
* which is returned to callers as `PortfolioItem[]`.
|
|
217
|
+
*
|
|
218
|
+
* The function ACCEPTS the broader `PortfolioItemInput` shape (which
|
|
219
|
+
* still types `kind` / `coverImage`) so callers don't need a separate
|
|
220
|
+
* partial type, but it INTENTIONALLY DROPS those fields from the merged
|
|
221
|
+
* payload before sending — keeping them would surface a confusing
|
|
222
|
+
* "Field is not defined on PortfolioItemUpdateInput" GraphQL error.
|
|
223
|
+
*/
|
|
224
|
+
export declare function update(token: string, id: string, changes: PortfolioItemInput): Promise<PortfolioItem[]>;
|
|
225
|
+
/** Remove a portfolio item by id. Returns the post-removal list. */
|
|
226
|
+
export declare function remove(token: string, id: string): Promise<PortfolioItem[]>;
|
|
227
|
+
/**
|
|
228
|
+
* Reorder portfolio items by setting `id` to the absolute `position`. The
|
|
229
|
+
* CLI surface translates the more user-friendly `--before <id>` /
|
|
230
|
+
* `--after <id>` flags to this absolute position; the helpers
|
|
231
|
+
* {@link positionBefore} / {@link positionAfter} compute the position
|
|
232
|
+
* given the current list.
|
|
233
|
+
*
|
|
234
|
+
* Wire shape (verified live 2026-05-16, probe
|
|
235
|
+
* `.tmp/probe-portfolio-reorder.mjs`): the position lives INSIDE
|
|
236
|
+
* `portfolioItem: { position: Int! }` — NOT at the top level of
|
|
237
|
+
* `ChangePortfolioItemPositionInput`. The naive `{ portfolioItemId,
|
|
238
|
+
* position }` shape is rejected with "Field is not defined on
|
|
239
|
+
* ChangePortfolioItemPositionInput" (for `position`) and
|
|
240
|
+
* "portfolioItem (Expected value to not be null)".
|
|
241
|
+
*/
|
|
242
|
+
export declare function reorder(token: string, id: string, position: number): Promise<PortfolioItem[]>;
|
|
243
|
+
/**
|
|
244
|
+
* Compute the absolute position (0-based) the moved item should land at,
|
|
245
|
+
* given a target item to be placed BEFORE. Returns `null` if `targetId`
|
|
246
|
+
* is not in the list. The current list is required because the server's
|
|
247
|
+
* `changePortfolioItemPosition` takes an absolute index, not a relative
|
|
248
|
+
* one — the CLI computes the index from a friendlier neighbour-anchored
|
|
249
|
+
* flag.
|
|
250
|
+
*
|
|
251
|
+
* Verified live 2026-05-16: the server interprets `position` against the
|
|
252
|
+
* POST-REMOVAL list (i.e. it first removes the moving item, then inserts
|
|
253
|
+
* at `position`). Valid range is `[0, N-1]` where `N` is the original
|
|
254
|
+
* list length; `position = N` (= the naive "after the last item")
|
|
255
|
+
* returns `USER_ERROR code: invalidPosition` ("Position should be
|
|
256
|
+
* greater or equal to 0 and less than the number of items").
|
|
257
|
+
*
|
|
258
|
+
* When `movingId` is supplied AND points at an item that exists in
|
|
259
|
+
* `items`, that item is filtered out before computing the target's
|
|
260
|
+
* index — this correctly handles the case where the moving item is
|
|
261
|
+
* already in the list and sits before the target (removing it shifts
|
|
262
|
+
* the target left by 1).
|
|
263
|
+
*/
|
|
264
|
+
export declare function positionBefore(items: PortfolioItem[], targetId: string, movingId?: string): number | null;
|
|
265
|
+
/**
|
|
266
|
+
* Compute the absolute position the moved item should land at, given a
|
|
267
|
+
* target item to be placed AFTER. Returns `null` if `targetId` is not in
|
|
268
|
+
* the list.
|
|
269
|
+
*
|
|
270
|
+
* Same post-removal semantics as {@link positionBefore} — pass the
|
|
271
|
+
* `movingId` so the helper can filter it out of `items` before
|
|
272
|
+
* computing the target's index. Without `movingId`, the helper assumes
|
|
273
|
+
* the moving item is not present and computes `idx + 1` directly; that
|
|
274
|
+
* value will be one too high for the common "move A `--after` B" CLI
|
|
275
|
+
* flow when both items are in the list and A is before B, and the
|
|
276
|
+
* server will reject it.
|
|
277
|
+
*/
|
|
278
|
+
export declare function positionAfter(items: PortfolioItem[], targetId: string, movingId?: string): number | null;
|
|
279
|
+
/**
|
|
280
|
+
* Set or clear the "highlight" flag on a portfolio item. Returns the
|
|
281
|
+
* minimal `{ id, highlight }` projection from the mutation payload —
|
|
282
|
+
* fetching the full updated item is a separate `list()` round-trip when
|
|
283
|
+
* needed.
|
|
284
|
+
*/
|
|
285
|
+
export declare function highlight(token: string, id: string, flag?: boolean): Promise<{
|
|
286
|
+
id: string;
|
|
287
|
+
highlight: boolean;
|
|
288
|
+
}>;
|
|
289
|
+
/**
|
|
290
|
+
* File-upload input — service callers pass either a filesystem path (the
|
|
291
|
+
* helper opens it) or a pre-loaded {@link MultipartFile} buffer. The MCP
|
|
292
|
+
* surface uses the buffer path for hosts that lack filesystem access (it
|
|
293
|
+
* decodes base64 first); the CLI surface uses the path-based variant.
|
|
294
|
+
*/
|
|
295
|
+
export type FileSource = {
|
|
296
|
+
kind: "path";
|
|
297
|
+
path: string;
|
|
298
|
+
} | {
|
|
299
|
+
kind: "buffer";
|
|
300
|
+
filename: string;
|
|
301
|
+
content: Buffer | Uint8Array;
|
|
302
|
+
contentType?: string;
|
|
303
|
+
};
|
|
304
|
+
export interface UploadPortfolioCoverResult {
|
|
305
|
+
coverImageCacheName: string | null;
|
|
306
|
+
coverImageUrl: string | null;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Crop transformation input for {@link uploadCover}. Pixel-based; all
|
|
310
|
+
* four values are required by the server. {@link uploadCover} accepts
|
|
311
|
+
* this as an optional parameter — when omitted, the service attempts to
|
|
312
|
+
* read the source image's dimensions (PNG header parsing) and defaults
|
|
313
|
+
* to a whole-image crop. For non-PNG sources or parse failures, the
|
|
314
|
+
* service falls back to an oversized `(0, 0, 99999, 99999)` bounding
|
|
315
|
+
* box and lets the server clamp.
|
|
316
|
+
*/
|
|
317
|
+
export interface PortfolioCoverTransformation {
|
|
318
|
+
cropX: number;
|
|
319
|
+
cropY: number;
|
|
320
|
+
cropW: number;
|
|
321
|
+
cropH: number;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Upload a cover image for a portfolio item. The cover image is bound to
|
|
325
|
+
* the user's profile rather than a specific portfolio item — the response
|
|
326
|
+
* carries a `coverImageCacheName` the caller passes back into a
|
|
327
|
+
* subsequent `update()` call (or `add()` for new items) via the
|
|
328
|
+
* `coverImage` field.
|
|
329
|
+
*
|
|
330
|
+
* The `transformation` parameter is optional. When omitted, the service
|
|
331
|
+
* resolves a sensible default: PNG sources have their dimensions read
|
|
332
|
+
* from the IHDR header and used as the whole-image crop
|
|
333
|
+
* `(0, 0, width, height)`; non-PNG sources fall back to a large
|
|
334
|
+
* bounding box `(0, 0, 99999, 99999)` (the server clamps oversized
|
|
335
|
+
* crops). Callers who need explicit control pass `transformation`
|
|
336
|
+
* directly.
|
|
337
|
+
*
|
|
338
|
+
* The server enforces a minimum cover-image size of 750x500px — the
|
|
339
|
+
* service does NOT pre-validate this; callers receive a `USER_ERROR`
|
|
340
|
+
* (`code: invalidImage`) when the image is too small.
|
|
341
|
+
*/
|
|
342
|
+
export declare function uploadCover(token: string, source: FileSource, transformation?: PortfolioCoverTransformation): Promise<UploadPortfolioCoverResult>;
|
|
343
|
+
export interface UploadPortfolioFileResult {
|
|
344
|
+
fileCacheName: string | null;
|
|
345
|
+
fileUrl: string | null;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Upload a file attachment associated with the user's portfolio. Returns
|
|
349
|
+
* the cache name + url; the CLI surface prints both for downstream use.
|
|
350
|
+
*/
|
|
351
|
+
export declare function uploadFile(token: string, source: FileSource): Promise<UploadPortfolioFileResult>;
|
|
352
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/services/profile/portfolio/index.ts"],"names":[],"mappings":"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"}
|