@honest-pitches/pitch-sdk 0.4.6 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +80 -0
- package/README.md +38 -69
- package/dist/index.cjs +156 -547
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.mts +3 -4
- package/dist/index.mjs +156 -540
- package/dist/index.mjs.map +4 -4
- package/package.json +6 -6
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { createRequire as topLevelCreateRequire } from "node:module";
|
|
2
|
+
const require = topLevelCreateRequire(import.meta.url);
|
|
1
3
|
var __create = Object.create;
|
|
2
4
|
var __defProp = Object.defineProperty;
|
|
3
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -30,168 +32,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
32
|
mod
|
|
31
33
|
));
|
|
32
34
|
|
|
33
|
-
// vendor/platform-libs/pitcher-api-key-core/dist/index.cjs
|
|
34
|
-
var require_dist = __commonJS({
|
|
35
|
-
"vendor/platform-libs/pitcher-api-key-core/dist/index.cjs"(exports, module) {
|
|
36
|
-
"use strict";
|
|
37
|
-
var __defProp2 = Object.defineProperty;
|
|
38
|
-
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
39
|
-
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
40
|
-
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
41
|
-
var __export = (target, all) => {
|
|
42
|
-
for (var name in all)
|
|
43
|
-
__defProp2(target, name, { get: all[name], enumerable: true });
|
|
44
|
-
};
|
|
45
|
-
var __copyProps2 = (to, from, except, desc) => {
|
|
46
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
47
|
-
for (let key of __getOwnPropNames2(from))
|
|
48
|
-
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
49
|
-
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
50
|
-
}
|
|
51
|
-
return to;
|
|
52
|
-
};
|
|
53
|
-
var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
54
|
-
var index_exports = {};
|
|
55
|
-
__export(index_exports, {
|
|
56
|
-
ALL_API_KEY_SCOPES: () => ALL_API_KEY_SCOPES,
|
|
57
|
-
API_KEY_PREFIX: () => API_KEY_PREFIX,
|
|
58
|
-
API_KEY_PREFIX_LEN: () => API_KEY_PREFIX_LEN,
|
|
59
|
-
API_KEY_RANDOM_LEN: () => API_KEY_RANDOM_LEN,
|
|
60
|
-
HASH_ALGO: () => HASH_ALGO,
|
|
61
|
-
extractKeyPrefix: () => extractKeyPrefix2,
|
|
62
|
-
generateApiKeyRandomSegment: () => generateApiKeyRandomSegment,
|
|
63
|
-
hashApiKey: () => hashApiKey,
|
|
64
|
-
isApiKeyScope: () => isApiKeyScope,
|
|
65
|
-
isApiKeyUsable: () => isApiKeyUsable2,
|
|
66
|
-
isWellFormedApiKey: () => isWellFormedApiKey2,
|
|
67
|
-
mintApiKey: () => mintApiKey,
|
|
68
|
-
parseApiKeyScopes: () => parseApiKeyScopes,
|
|
69
|
-
parseBearerHeader: () => parseBearerHeader,
|
|
70
|
-
verifyApiKey: () => verifyApiKey2
|
|
71
|
-
});
|
|
72
|
-
module.exports = __toCommonJS(index_exports);
|
|
73
|
-
var import_node_crypto = __require("crypto");
|
|
74
|
-
var API_KEY_PREFIX = "hp_pk_";
|
|
75
|
-
var API_KEY_PREFIX_LEN = 8;
|
|
76
|
-
var API_KEY_RANDOM_LEN = 48;
|
|
77
|
-
var HASH_ALGO = "sha256";
|
|
78
|
-
var BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
79
|
-
function generateApiKeyRandomSegment(len) {
|
|
80
|
-
if (!Number.isInteger(len) || len <= 0) {
|
|
81
|
-
throw new Error("len must be a positive integer");
|
|
82
|
-
}
|
|
83
|
-
const out = [];
|
|
84
|
-
while (out.length < len) {
|
|
85
|
-
const buf = (0, import_node_crypto.randomBytes)(len + 4);
|
|
86
|
-
for (let i = 0; i < buf.length && out.length < len; i++) {
|
|
87
|
-
const byte = buf[i];
|
|
88
|
-
if (byte < 248) {
|
|
89
|
-
out.push(BASE62[byte % 62]);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return out.join("");
|
|
94
|
-
}
|
|
95
|
-
function hashApiKey(rawToken) {
|
|
96
|
-
if (typeof rawToken !== "string" || rawToken.length === 0) {
|
|
97
|
-
throw new Error("hashApiKey: rawToken must be a non-empty string");
|
|
98
|
-
}
|
|
99
|
-
return (0, import_node_crypto.createHash)(HASH_ALGO).update(rawToken, "utf8").digest("hex");
|
|
100
|
-
}
|
|
101
|
-
function isWellFormedApiKey2(rawToken) {
|
|
102
|
-
if (typeof rawToken !== "string") return false;
|
|
103
|
-
if (!rawToken.startsWith(API_KEY_PREFIX)) return false;
|
|
104
|
-
const rest = rawToken.slice(API_KEY_PREFIX.length);
|
|
105
|
-
if (rest.length !== API_KEY_RANDOM_LEN) return false;
|
|
106
|
-
for (let i = 0; i < rest.length; i++) {
|
|
107
|
-
const code = rest.charCodeAt(i);
|
|
108
|
-
const isDigit = code >= 48 && code <= 57;
|
|
109
|
-
const isUpper = code >= 65 && code <= 90;
|
|
110
|
-
const isLower = code >= 97 && code <= 122;
|
|
111
|
-
if (!isDigit && !isUpper && !isLower) return false;
|
|
112
|
-
}
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
function extractKeyPrefix2(rawToken) {
|
|
116
|
-
if (!isWellFormedApiKey2(rawToken)) return null;
|
|
117
|
-
return rawToken.slice(API_KEY_PREFIX.length, API_KEY_PREFIX.length + API_KEY_PREFIX_LEN);
|
|
118
|
-
}
|
|
119
|
-
var ALL_API_KEY_SCOPES = ["mcp", "sdk"];
|
|
120
|
-
function isApiKeyScope(value) {
|
|
121
|
-
return value === "mcp" || value === "sdk";
|
|
122
|
-
}
|
|
123
|
-
function parseApiKeyScopes(input) {
|
|
124
|
-
if (!Array.isArray(input)) {
|
|
125
|
-
throw new Error("scopes must be an array of strings");
|
|
126
|
-
}
|
|
127
|
-
const seen = /* @__PURE__ */ new Set();
|
|
128
|
-
for (const raw of input) {
|
|
129
|
-
if (!isApiKeyScope(raw)) {
|
|
130
|
-
throw new Error(
|
|
131
|
-
`unknown scope: ${JSON.stringify(raw)}. Valid scopes: ${ALL_API_KEY_SCOPES.join(", ")}`
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
seen.add(raw);
|
|
135
|
-
}
|
|
136
|
-
return Array.from(seen);
|
|
137
|
-
}
|
|
138
|
-
function mintApiKey(input) {
|
|
139
|
-
if (typeof input.label !== "string" || input.label.length === 0) {
|
|
140
|
-
throw new Error("mintApiKey: label must be a non-empty string");
|
|
141
|
-
}
|
|
142
|
-
if (input.label.length > 128) {
|
|
143
|
-
throw new Error("mintApiKey: label must be <= 128 chars");
|
|
144
|
-
}
|
|
145
|
-
if (!Array.isArray(input.scopes) || input.scopes.length === 0) {
|
|
146
|
-
throw new Error("mintApiKey: scopes must be a non-empty array");
|
|
147
|
-
}
|
|
148
|
-
if (input.expiresAt != null && typeof input.expiresAt !== "number") {
|
|
149
|
-
throw new Error("mintApiKey: expiresAt must be a number (epoch ms) or null");
|
|
150
|
-
}
|
|
151
|
-
const randomSegment = generateApiKeyRandomSegment(API_KEY_RANDOM_LEN);
|
|
152
|
-
const rawToken = `${API_KEY_PREFIX}${randomSegment}`;
|
|
153
|
-
const keyHash = hashApiKey(rawToken);
|
|
154
|
-
const keyPrefix = extractKeyPrefix2(rawToken);
|
|
155
|
-
if (keyPrefix === null) {
|
|
156
|
-
throw new Error("mintApiKey: generated key is not well-formed");
|
|
157
|
-
}
|
|
158
|
-
return { rawToken, keyHash, keyPrefix };
|
|
159
|
-
}
|
|
160
|
-
function constantTimeEqualHex(a, b) {
|
|
161
|
-
if (a.length !== b.length) return false;
|
|
162
|
-
let diff = 0;
|
|
163
|
-
for (let i = 0; i < a.length; i++) {
|
|
164
|
-
diff |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
165
|
-
}
|
|
166
|
-
return diff === 0;
|
|
167
|
-
}
|
|
168
|
-
function verifyApiKey2(presented, storedHash) {
|
|
169
|
-
if (typeof presented !== "string" || typeof storedHash !== "string") return false;
|
|
170
|
-
if (presented.length === 0 || storedHash.length === 0) return false;
|
|
171
|
-
let presentedHash;
|
|
172
|
-
try {
|
|
173
|
-
presentedHash = hashApiKey(presented);
|
|
174
|
-
} catch {
|
|
175
|
-
return false;
|
|
176
|
-
}
|
|
177
|
-
return constantTimeEqualHex(presentedHash, storedHash);
|
|
178
|
-
}
|
|
179
|
-
function isApiKeyUsable2(row, now = Date.now()) {
|
|
180
|
-
if (row.revokedAt != null) return false;
|
|
181
|
-
if (row.expiresAt != null && row.expiresAt <= now) return false;
|
|
182
|
-
return true;
|
|
183
|
-
}
|
|
184
|
-
function parseBearerHeader(header) {
|
|
185
|
-
if (!header || typeof header !== "string") return null;
|
|
186
|
-
const match = /^Bearer\s+(\S+)\s*$/i.exec(header.trim());
|
|
187
|
-
if (!match) return null;
|
|
188
|
-
return { token: match[1] };
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
|
|
193
35
|
// vendor/platform-libs/hp-codes/dist/index.cjs
|
|
194
|
-
var
|
|
36
|
+
var require_dist = __commonJS({
|
|
195
37
|
"vendor/platform-libs/hp-codes/dist/index.cjs"(exports, module) {
|
|
196
38
|
"use strict";
|
|
197
39
|
var __defProp2 = Object.defineProperty;
|
|
@@ -332,7 +174,7 @@ var require_dist2 = __commonJS({
|
|
|
332
174
|
});
|
|
333
175
|
|
|
334
176
|
// vendor/platform-libs/pitch-core/dist/index.cjs
|
|
335
|
-
var
|
|
177
|
+
var require_dist2 = __commonJS({
|
|
336
178
|
"vendor/platform-libs/pitch-core/dist/index.cjs"(exports, module) {
|
|
337
179
|
"use strict";
|
|
338
180
|
var __create2 = Object.create;
|
|
@@ -12341,7 +12183,7 @@ and ensure you are accounting for this risk.
|
|
|
12341
12183
|
TEST_CONCLUSIONS: () => TEST_CONCLUSIONS,
|
|
12342
12184
|
TEST_PRIMARY_METRICS: () => TEST_PRIMARY_METRICS,
|
|
12343
12185
|
TEST_STATUSES: () => TEST_STATUSES,
|
|
12344
|
-
assertFrameworkSwitchable: () =>
|
|
12186
|
+
assertFrameworkSwitchable: () => assertFrameworkSwitchable,
|
|
12345
12187
|
assertSameTestBase: () => assertSameTestBase,
|
|
12346
12188
|
baseKey: () => baseKey,
|
|
12347
12189
|
buildPitchVariantIndexes: () => buildPitchVariantIndexes,
|
|
@@ -12373,13 +12215,13 @@ and ensure you are accounting for this risk.
|
|
|
12373
12215
|
lifecycleFromRow: () => lifecycleFromRow2,
|
|
12374
12216
|
loadFrameworkGuidance: () => loadFrameworkGuidance,
|
|
12375
12217
|
loadFrameworks: () => loadFrameworks3,
|
|
12376
|
-
loadPitchSections: () =>
|
|
12218
|
+
loadPitchSections: () => loadPitchSections,
|
|
12377
12219
|
loadSegments: () => loadSegments2,
|
|
12378
12220
|
mergeSectionsForFramework: () => mergeSectionsForFramework,
|
|
12379
12221
|
mismatchedSectionKinds: () => mismatchedSectionKinds,
|
|
12380
12222
|
normalizeClips: () => normalizeClips,
|
|
12381
12223
|
normalizeCreatePitchInput: () => normalizeCreatePitchInput,
|
|
12382
|
-
normalizePitchContent: () =>
|
|
12224
|
+
normalizePitchContent: () => normalizePitchContent,
|
|
12383
12225
|
normalizePitchLayout: () => normalizePitchLayout,
|
|
12384
12226
|
parseClipsJson: () => parseClipsJson,
|
|
12385
12227
|
parsePitchSectionsColumn: () => parsePitchSectionsColumn,
|
|
@@ -14247,7 +14089,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
14247
14089
|
function sectionsFromDescription(description) {
|
|
14248
14090
|
return [{ kind: "problem", body: description, mediaIds: [] }];
|
|
14249
14091
|
}
|
|
14250
|
-
function
|
|
14092
|
+
function normalizePitchContent(row) {
|
|
14251
14093
|
const frameworkRaw = String(row.framework ?? "pas");
|
|
14252
14094
|
const framework = isFrameworkId3(frameworkRaw) ? frameworkRaw : "pas";
|
|
14253
14095
|
const parsed = parseSectionsJson2(
|
|
@@ -15597,7 +15439,7 @@ ${raw.slice(0, 200)}`
|
|
|
15597
15439
|
}
|
|
15598
15440
|
return { ok: true };
|
|
15599
15441
|
}
|
|
15600
|
-
var import_hp_codes =
|
|
15442
|
+
var import_hp_codes = require_dist();
|
|
15601
15443
|
function baseKey(pitch) {
|
|
15602
15444
|
const result = (0, import_hp_codes.validateCode)(pitch.hpCode);
|
|
15603
15445
|
if (!result.valid || !result.payload || !result.checkDigit) {
|
|
@@ -15797,7 +15639,7 @@ ${raw.slice(0, 200)}`
|
|
|
15797
15639
|
"expired",
|
|
15798
15640
|
"archived"
|
|
15799
15641
|
];
|
|
15800
|
-
function
|
|
15642
|
+
function assertFrameworkSwitchable(input) {
|
|
15801
15643
|
if (input.status === "draft") return { ok: true };
|
|
15802
15644
|
if (input.status === "live" || input.status === "expired" || input.status === "archived") {
|
|
15803
15645
|
return { ok: false, reason: "immutable" };
|
|
@@ -15809,7 +15651,7 @@ ${raw.slice(0, 200)}`
|
|
|
15809
15651
|
if (from === "draft" && to !== "draft") {
|
|
15810
15652
|
return { ok: false, reason: "locked" };
|
|
15811
15653
|
}
|
|
15812
|
-
return
|
|
15654
|
+
return assertFrameworkSwitchable({ status: from });
|
|
15813
15655
|
}
|
|
15814
15656
|
function isPitchLifecycleState(value) {
|
|
15815
15657
|
return PITCH_LIFECYCLE_STATES.includes(value);
|
|
@@ -16644,7 +16486,7 @@ ${raw.slice(0, 200)}`
|
|
|
16644
16486
|
};
|
|
16645
16487
|
});
|
|
16646
16488
|
}
|
|
16647
|
-
function
|
|
16489
|
+
function loadPitchSections({
|
|
16648
16490
|
pitchId,
|
|
16649
16491
|
doc,
|
|
16650
16492
|
rows,
|
|
@@ -16731,9 +16573,6 @@ ${raw.slice(0, 200)}`
|
|
|
16731
16573
|
}
|
|
16732
16574
|
});
|
|
16733
16575
|
|
|
16734
|
-
// src/config.ts
|
|
16735
|
-
import { Client } from "node-appwrite";
|
|
16736
|
-
|
|
16737
16576
|
// src/errors.ts
|
|
16738
16577
|
var PitcherSdkError = class extends Error {
|
|
16739
16578
|
code;
|
|
@@ -16773,71 +16612,50 @@ var HpCodeImmutableError = class extends PitcherSdkError {
|
|
|
16773
16612
|
this.name = "HpCodeImmutableError";
|
|
16774
16613
|
}
|
|
16775
16614
|
};
|
|
16776
|
-
var
|
|
16615
|
+
var PitcherRequestError = class extends PitcherSdkError {
|
|
16777
16616
|
status;
|
|
16778
|
-
constructor(status, message) {
|
|
16779
|
-
super("
|
|
16780
|
-
this.name = "
|
|
16617
|
+
constructor(status, code, message) {
|
|
16618
|
+
super(code || "PITCHER_REQUEST", message);
|
|
16619
|
+
this.name = "PitcherRequestError";
|
|
16781
16620
|
this.status = status;
|
|
16782
16621
|
}
|
|
16783
16622
|
};
|
|
16784
16623
|
|
|
16785
16624
|
// src/config.ts
|
|
16625
|
+
var DEFAULT_PITCHER_BASE_URL = "https://mcp.honestpitches.com";
|
|
16786
16626
|
function resolvePitcherConfig(input) {
|
|
16787
|
-
if (input.
|
|
16627
|
+
if (input.jwt && input.apiKey) {
|
|
16788
16628
|
throw new PitcherSdkError(
|
|
16789
16629
|
"PITCHER_AUTH_AMBIGUOUS",
|
|
16790
|
-
"Set either
|
|
16630
|
+
"Set either jwt or apiKey, not both \u2014 the SDK can only act as one principal per client"
|
|
16791
16631
|
);
|
|
16792
16632
|
}
|
|
16793
|
-
const
|
|
16794
|
-
|
|
16795
|
-
|
|
16796
|
-
|
|
16797
|
-
|
|
16798
|
-
const c = new Client().setEndpoint(endpoint).setProject(input.projectId);
|
|
16799
|
-
return c;
|
|
16800
|
-
})();
|
|
16801
|
-
if (input.initialJwt) {
|
|
16802
|
-
try {
|
|
16803
|
-
client.setJWT(input.initialJwt);
|
|
16804
|
-
} catch {
|
|
16805
|
-
}
|
|
16806
|
-
}
|
|
16807
|
-
let jwt = input.initialJwt ?? null;
|
|
16808
|
-
let jwtExpiresAt = input.initialJwtExpiresAt ?? null;
|
|
16633
|
+
const baseUrl = (input.baseUrl ?? DEFAULT_PITCHER_BASE_URL).replace(/\/$/, "");
|
|
16634
|
+
const state = {
|
|
16635
|
+
jwt: input.jwt ?? null,
|
|
16636
|
+
jwtExpiresAt: input.jwtExpiresAt ?? null
|
|
16637
|
+
};
|
|
16809
16638
|
const apiKey = input.apiKey ?? null;
|
|
16639
|
+
const fetchImpl = input.fetchImpl ?? globalThis.fetch;
|
|
16640
|
+
if (!fetchImpl) {
|
|
16641
|
+
throw new PitcherSdkError(
|
|
16642
|
+
"PITCHER_NO_FETCH",
|
|
16643
|
+
"PitcherClient requires a fetch implementation \u2014 Node 20+ provides globalThis.fetch; older runtimes must pass { fetchImpl }"
|
|
16644
|
+
);
|
|
16645
|
+
}
|
|
16810
16646
|
return {
|
|
16811
|
-
|
|
16812
|
-
|
|
16813
|
-
|
|
16814
|
-
pitchesTableId: input.pitchesTableId ?? "pitches",
|
|
16815
|
-
creatorsTableId: input.creatorsTableId ?? "creators",
|
|
16816
|
-
pitchSectionsTableId: input.pitchSectionsTableId ?? "pitch_sections",
|
|
16817
|
-
pitchCreateFunctionId: input.pitchCreateFunctionId ?? "pitch-write",
|
|
16818
|
-
pitchAssetUploadFunctionId: input.pitchAssetUploadFunctionId ?? "pitch-asset-upload",
|
|
16819
|
-
pitcherApiKeysTableId: input.pitcherApiKeysTableId ?? "pitcher_api_keys",
|
|
16820
|
-
client,
|
|
16821
|
-
getJwt: () => jwt,
|
|
16822
|
-
getJwtExpiresAt: () => jwtExpiresAt,
|
|
16647
|
+
baseUrl,
|
|
16648
|
+
getJwt: () => state.jwt,
|
|
16649
|
+
getJwtExpiresAt: () => state.jwtExpiresAt,
|
|
16823
16650
|
setJwt: (next, expiresAt) => {
|
|
16824
|
-
jwt = next;
|
|
16825
|
-
jwtExpiresAt = expiresAt ?? null;
|
|
16826
|
-
if (!apiKey) {
|
|
16827
|
-
try {
|
|
16828
|
-
client.setJWT(next);
|
|
16829
|
-
} catch {
|
|
16830
|
-
}
|
|
16831
|
-
}
|
|
16651
|
+
state.jwt = next;
|
|
16652
|
+
state.jwtExpiresAt = expiresAt ?? null;
|
|
16832
16653
|
},
|
|
16833
|
-
getApiKey: () => apiKey
|
|
16654
|
+
getApiKey: () => apiKey,
|
|
16655
|
+
fetchImpl
|
|
16834
16656
|
};
|
|
16835
16657
|
}
|
|
16836
16658
|
|
|
16837
|
-
// src/creators.ts
|
|
16838
|
-
var import_pitcher_api_key_core = __toESM(require_dist(), 1);
|
|
16839
|
-
import { Query } from "node-appwrite";
|
|
16840
|
-
|
|
16841
16659
|
// src/jwt.ts
|
|
16842
16660
|
function decodeJwtSub(jwt) {
|
|
16843
16661
|
const parts = jwt.split(".");
|
|
@@ -16860,214 +16678,92 @@ function isJwtExpired(expiresAt) {
|
|
|
16860
16678
|
return Date.now() >= expiresAt;
|
|
16861
16679
|
}
|
|
16862
16680
|
|
|
16863
|
-
// src/
|
|
16864
|
-
|
|
16865
|
-
|
|
16866
|
-
|
|
16867
|
-
var PUBLIC_API_FUNCTION_ID = "honest-pitches-public-api";
|
|
16868
|
-
var STRIPE_API_FUNCTION_ID = "stripe-api";
|
|
16869
|
-
var STUDIO_API_FUNCTION_ID = "honest-pitches-studio-api";
|
|
16870
|
-
var MEDIA_API_FUNCTION_ID = "honest-pitches-media";
|
|
16871
|
-
var FUNCTION_BUNDLE_MAP = {
|
|
16872
|
-
"pitch-write": STUDIO_API_FUNCTION_ID,
|
|
16873
|
-
"pitch-transition": STUDIO_API_FUNCTION_ID,
|
|
16874
|
-
"pitch-asset-upload": MEDIA_API_FUNCTION_ID,
|
|
16875
|
-
"agent-magic-link-issue": STUDIO_API_FUNCTION_ID
|
|
16876
|
-
};
|
|
16877
|
-
function resolveConsolidatedRoute(functionId, path) {
|
|
16878
|
-
const bundle = FUNCTION_BUNDLE_MAP[functionId];
|
|
16879
|
-
if (!bundle) return { functionId, path };
|
|
16880
|
-
const sub = path.startsWith("/") ? path : `/${path}`;
|
|
16881
|
-
const prefixed = sub === "/" ? `/${functionId}` : `/${functionId}${sub}`;
|
|
16882
|
-
return { functionId: bundle, path: prefixed };
|
|
16883
|
-
}
|
|
16884
|
-
|
|
16885
|
-
// src/http.ts
|
|
16886
|
-
function requireJwt(config) {
|
|
16681
|
+
// src/fetch-pitcher.ts
|
|
16682
|
+
function requireAuthHeader(config) {
|
|
16683
|
+
const apiKey = config.getApiKey();
|
|
16684
|
+
if (apiKey) return `Bearer ${apiKey}`;
|
|
16887
16685
|
const jwt = config.getJwt();
|
|
16888
16686
|
if (!jwt) {
|
|
16889
|
-
throw new PitcherNotAuthenticatedError(
|
|
16687
|
+
throw new PitcherNotAuthenticatedError(
|
|
16688
|
+
"PitcherClient requires { apiKey: 'hp_pk_\u2026' } or { jwt: '<jwt>' }"
|
|
16689
|
+
);
|
|
16890
16690
|
}
|
|
16891
16691
|
if (isJwtExpired(config.getJwtExpiresAt())) {
|
|
16892
|
-
throw new PitcherNotAuthenticatedError(
|
|
16692
|
+
throw new PitcherNotAuthenticatedError(
|
|
16693
|
+
"JWT expired \u2014 refresh via pitcher-mcp OAuth"
|
|
16694
|
+
);
|
|
16893
16695
|
}
|
|
16894
|
-
return jwt
|
|
16696
|
+
return `Bearer ${jwt}`;
|
|
16895
16697
|
}
|
|
16896
|
-
function
|
|
16897
|
-
|
|
16898
|
-
|
|
16899
|
-
|
|
16900
|
-
|
|
16901
|
-
|
|
16902
|
-
|
|
16903
|
-
|
|
16904
|
-
|
|
16905
|
-
|
|
16906
|
-
|
|
16907
|
-
|
|
16908
|
-
const code = err.code;
|
|
16909
|
-
const message = err.message;
|
|
16910
|
-
const status = typeof code === "number" && code > 0 ? code : 500;
|
|
16911
|
-
if (status === 401) {
|
|
16912
|
-
throw new PitcherNotAuthenticatedError(message || "Unauthorized");
|
|
16913
|
-
}
|
|
16914
|
-
throw new AppwriteRequestError(status, message || fallbackMessage);
|
|
16698
|
+
async function fetchPitches(config, opts) {
|
|
16699
|
+
const auth = requireAuthHeader(config);
|
|
16700
|
+
const url = `${config.baseUrl}/pitcher${opts.path.startsWith("/") ? opts.path : `/${opts.path}`}`;
|
|
16701
|
+
const headers = {
|
|
16702
|
+
Authorization: auth,
|
|
16703
|
+
Accept: "application/json",
|
|
16704
|
+
"User-Agent": "@honest-pitches/pitch-sdk/0.5.0"
|
|
16705
|
+
};
|
|
16706
|
+
let body;
|
|
16707
|
+
if (opts.body !== void 0 && (opts.method === "POST" || opts.method === "PATCH")) {
|
|
16708
|
+
headers["Content-Type"] = "application/json";
|
|
16709
|
+
body = JSON.stringify(opts.body);
|
|
16915
16710
|
}
|
|
16916
|
-
|
|
16917
|
-
500,
|
|
16918
|
-
err instanceof Error ? err.message : fallbackMessage
|
|
16919
|
-
);
|
|
16920
|
-
}
|
|
16921
|
-
function tablesDB(config) {
|
|
16922
|
-
return new TablesDB(config.client);
|
|
16923
|
-
}
|
|
16924
|
-
function functions(config) {
|
|
16925
|
-
return new Functions(config.client);
|
|
16926
|
-
}
|
|
16927
|
-
function applyApiKeyHeader(config) {
|
|
16928
|
-
const apiKey = config.getApiKey();
|
|
16929
|
-
if (!apiKey) return;
|
|
16930
|
-
config.client.addHeader("Authorization", `Bearer ${apiKey}`);
|
|
16931
|
-
}
|
|
16932
|
-
async function executePitchFunction(config, opts) {
|
|
16933
|
-
if (!config.getApiKey()) requireJwt(config);
|
|
16934
|
-
applyApiKeyHeader(config);
|
|
16935
|
-
const fn = functions(config);
|
|
16936
|
-
const legacyFn = opts.functionId ?? config.pitchCreateFunctionId;
|
|
16937
|
-
const route = resolveConsolidatedRoute(legacyFn, opts.path ?? "/");
|
|
16711
|
+
let res;
|
|
16938
16712
|
try {
|
|
16939
|
-
|
|
16940
|
-
functionId: route.functionId,
|
|
16941
|
-
body: JSON.stringify(opts.body),
|
|
16942
|
-
async: false,
|
|
16713
|
+
res = await config.fetchImpl(url, {
|
|
16943
16714
|
method: opts.method,
|
|
16944
|
-
|
|
16945
|
-
|
|
16946
|
-
|
|
16947
|
-
const status = execution.responseStatusCode ?? 201;
|
|
16948
|
-
const responseBody = execution.responseBody ?? "";
|
|
16949
|
-
if (status >= 400) {
|
|
16950
|
-
let message = responseBody;
|
|
16951
|
-
try {
|
|
16952
|
-
const parsed = JSON.parse(responseBody);
|
|
16953
|
-
message = parsed.error ?? responseBody;
|
|
16954
|
-
} catch {
|
|
16955
|
-
}
|
|
16956
|
-
throw new AppwriteRequestError(status, message);
|
|
16957
|
-
}
|
|
16958
|
-
if (!responseBody) {
|
|
16959
|
-
throw new AppwriteRequestError(status, "Empty response from pitch-write");
|
|
16960
|
-
}
|
|
16961
|
-
return JSON.parse(responseBody);
|
|
16962
|
-
} catch (err) {
|
|
16963
|
-
if (err instanceof AppwriteRequestError) throw err;
|
|
16964
|
-
if (err instanceof PitcherNotAuthenticatedError) throw err;
|
|
16965
|
-
mapAppwriteException(err, "pitch-write execution failed");
|
|
16966
|
-
}
|
|
16967
|
-
}
|
|
16968
|
-
async function tablesListRows(config, tableId, queries) {
|
|
16969
|
-
if (!config.getApiKey()) requireJwt(config);
|
|
16970
|
-
applyApiKeyHeader(config);
|
|
16971
|
-
try {
|
|
16972
|
-
const result = await tablesDB(config).listRows({
|
|
16973
|
-
databaseId: config.databaseId,
|
|
16974
|
-
tableId,
|
|
16975
|
-
queries
|
|
16715
|
+
headers,
|
|
16716
|
+
...body !== void 0 ? { body } : {},
|
|
16717
|
+
...opts.signal ? { signal: opts.signal } : {}
|
|
16976
16718
|
});
|
|
16977
|
-
const total = result.total ?? 0;
|
|
16978
|
-
const rows = result.rows ?? [];
|
|
16979
|
-
return { total, documents: rows };
|
|
16980
16719
|
} catch (err) {
|
|
16981
|
-
|
|
16720
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
16721
|
+
throw new PitcherRequestError(0, "PITCHER_NETWORK", `fetchPitches failed: ${message}`);
|
|
16982
16722
|
}
|
|
16983
|
-
|
|
16984
|
-
|
|
16985
|
-
if (!config.getApiKey()) requireJwt(config);
|
|
16986
|
-
applyApiKeyHeader(config);
|
|
16723
|
+
const text = await res.text();
|
|
16724
|
+
let envelope = null;
|
|
16987
16725
|
try {
|
|
16988
|
-
|
|
16989
|
-
|
|
16990
|
-
|
|
16991
|
-
|
|
16992
|
-
|
|
16993
|
-
|
|
16994
|
-
} catch (err) {
|
|
16995
|
-
mapAppwriteException(err, `getRow(${tableId}/${rowId}) failed`);
|
|
16996
|
-
}
|
|
16997
|
-
}
|
|
16998
|
-
|
|
16999
|
-
// src/creators.ts
|
|
17000
|
-
async function findCreatorIdForJwtUser(config) {
|
|
17001
|
-
const jwt = config.getJwt();
|
|
17002
|
-
if (!jwt) throw new PitcherNotAuthenticatedError();
|
|
17003
|
-
const userId = decodeJwtSub(jwt);
|
|
17004
|
-
if (!userId) {
|
|
17005
|
-
throw new PitcherNotAuthenticatedError(
|
|
17006
|
-
"JWT missing userId/sub \u2014 use account.createJWT().jwt from studio"
|
|
17007
|
-
);
|
|
17008
|
-
}
|
|
17009
|
-
const json = await tablesListRows(
|
|
17010
|
-
config,
|
|
17011
|
-
config.creatorsTableId,
|
|
17012
|
-
[Query.equal("userId", userId), Query.limit(1)]
|
|
17013
|
-
);
|
|
17014
|
-
const doc = json.documents?.[0];
|
|
17015
|
-
return doc?.$id ? String(doc.$id) : null;
|
|
17016
|
-
}
|
|
17017
|
-
async function findCreatorIdForApiKey(config) {
|
|
17018
|
-
const apiKey = config.getApiKey();
|
|
17019
|
-
if (!apiKey) {
|
|
17020
|
-
throw new PitcherNotAuthenticatedError(
|
|
17021
|
-
"findCreatorIdForApiKey requires the SDK to be configured with { apiKey: 'hp_pk_\u2026' }; for JWT auth use findCreatorIdForJwtUser instead"
|
|
16726
|
+
envelope = JSON.parse(text);
|
|
16727
|
+
} catch {
|
|
16728
|
+
throw new PitcherRequestError(
|
|
16729
|
+
res.status,
|
|
16730
|
+
"PITCHER_NON_JSON",
|
|
16731
|
+
`MCP server returned non-JSON body (status ${res.status}): ${text.slice(0, 256)}`
|
|
17022
16732
|
);
|
|
17023
16733
|
}
|
|
17024
|
-
if (
|
|
17025
|
-
return
|
|
16734
|
+
if (envelope && envelope.ok === true) {
|
|
16735
|
+
return envelope.data;
|
|
17026
16736
|
}
|
|
17027
|
-
|
|
17028
|
-
|
|
17029
|
-
|
|
16737
|
+
if (envelope && envelope.ok === false) {
|
|
16738
|
+
throw new PitcherRequestError(
|
|
16739
|
+
res.status,
|
|
16740
|
+
envelope.error.code,
|
|
16741
|
+
envelope.error.message
|
|
16742
|
+
);
|
|
17030
16743
|
}
|
|
17031
|
-
|
|
17032
|
-
|
|
17033
|
-
|
|
17034
|
-
|
|
17035
|
-
);
|
|
17036
|
-
const keyDoc = apiKeyRows.documents?.[0];
|
|
17037
|
-
if (!keyDoc) return null;
|
|
17038
|
-
const keyHash = String(keyDoc["keyHash"] ?? "");
|
|
17039
|
-
if (!(0, import_pitcher_api_key_core.verifyApiKey)(apiKey, keyHash)) return null;
|
|
17040
|
-
const rowShape = {
|
|
17041
|
-
revokedAt: typeof keyDoc["revokedAt"] === "string" ? Date.parse(String(keyDoc["revokedAt"])) : null,
|
|
17042
|
-
expiresAt: typeof keyDoc["expiresAt"] === "string" ? Date.parse(String(keyDoc["expiresAt"])) : null
|
|
17043
|
-
};
|
|
17044
|
-
if (!(0, import_pitcher_api_key_core.isApiKeyUsable)(rowShape)) return null;
|
|
17045
|
-
const userId = String(keyDoc["userId"] ?? "");
|
|
17046
|
-
if (!userId) return null;
|
|
17047
|
-
const creatorRows = await tablesListRows(
|
|
17048
|
-
config,
|
|
17049
|
-
config.creatorsTableId,
|
|
17050
|
-
[Query.equal("userId", userId), Query.limit(1)]
|
|
16744
|
+
throw new PitcherRequestError(
|
|
16745
|
+
res.status,
|
|
16746
|
+
"PITCHER_MALFORMED",
|
|
16747
|
+
`MCP server returned malformed envelope: ${text.slice(0, 256)}`
|
|
17051
16748
|
);
|
|
17052
|
-
const creatorDoc = creatorRows.documents?.[0];
|
|
17053
|
-
return creatorDoc?.$id ? String(creatorDoc.$id) : null;
|
|
17054
16749
|
}
|
|
17055
16750
|
|
|
17056
|
-
// src/
|
|
17057
|
-
|
|
17058
|
-
|
|
17059
|
-
|
|
17060
|
-
|
|
17061
|
-
|
|
17062
|
-
return
|
|
16751
|
+
// src/creators.ts
|
|
16752
|
+
async function findCreatorIdForJwtUser(config) {
|
|
16753
|
+
const result = await fetchPitches(config, {
|
|
16754
|
+
method: "GET",
|
|
16755
|
+
path: "/creators/me"
|
|
16756
|
+
});
|
|
16757
|
+
return result.creatorId;
|
|
17063
16758
|
}
|
|
17064
|
-
function
|
|
17065
|
-
return
|
|
16759
|
+
async function findCreatorIdForApiKey(config) {
|
|
16760
|
+
return findCreatorIdForJwtUser(config);
|
|
17066
16761
|
}
|
|
17067
16762
|
|
|
17068
16763
|
// src/pitches.ts
|
|
17069
|
-
|
|
17070
|
-
|
|
16764
|
+
var import_pitch_core = __toESM(require_dist2(), 1);
|
|
16765
|
+
function rowToPitch(doc) {
|
|
16766
|
+
const sections = Array.isArray(doc.sections) ? doc.sections : [];
|
|
17071
16767
|
const lifecycle = (0, import_pitch_core.lifecycleFromRow)({
|
|
17072
16768
|
status: String(doc.status ?? "draft"),
|
|
17073
16769
|
previewToken: doc.previewToken
|
|
@@ -17079,14 +16775,6 @@ function rowToPitch(doc, precomputedSections) {
|
|
|
17079
16775
|
status: String(doc.status ?? "draft")
|
|
17080
16776
|
};
|
|
17081
16777
|
}
|
|
17082
|
-
async function loadPitchSectionsFor(config, pitchId) {
|
|
17083
|
-
const json = await tablesListRows(
|
|
17084
|
-
config,
|
|
17085
|
-
config.pitchSectionsTableId,
|
|
17086
|
-
[appwriteQueryEqual("pitchId", pitchId)]
|
|
17087
|
-
);
|
|
17088
|
-
return json.documents ?? [];
|
|
17089
|
-
}
|
|
17090
16778
|
function validatePitchContent(framework, sections) {
|
|
17091
16779
|
if (!(0, import_pitch_core.isFrameworkId)(framework)) {
|
|
17092
16780
|
throw new InvalidSectionKindError(`Unknown framework: ${framework}`);
|
|
@@ -17099,7 +16787,9 @@ function validatePitchContent(framework, sections) {
|
|
|
17099
16787
|
}
|
|
17100
16788
|
}
|
|
17101
16789
|
async function assertCreatorOwnedByAuthContext(config, creatorId) {
|
|
17102
|
-
if (!config.getJwt()
|
|
16790
|
+
if (!config.getJwt() && !config.getApiKey()) {
|
|
16791
|
+
throw new PitcherNotAuthenticatedError();
|
|
16792
|
+
}
|
|
17103
16793
|
const owningCreatorId = await findCreatorIdForJwtUser(config);
|
|
17104
16794
|
if (!owningCreatorId) {
|
|
17105
16795
|
throw new PitcherNotAuthenticatedError(
|
|
@@ -17116,10 +16806,8 @@ var PitchesApi = class {
|
|
|
17116
16806
|
}
|
|
17117
16807
|
config;
|
|
17118
16808
|
async create(input) {
|
|
17119
|
-
await assertCreatorOwnedByAuthContext(this.config, input.creatorId);
|
|
17120
16809
|
validatePitchContent(input.framework, input.sections);
|
|
17121
|
-
|
|
17122
|
-
if (!switchCheck.ok) throw new FrameworkLockedError();
|
|
16810
|
+
await assertCreatorOwnedByAuthContext(this.config, input.creatorId);
|
|
17123
16811
|
const payload = {
|
|
17124
16812
|
creatorId: input.creatorId,
|
|
17125
16813
|
slug: input.slug,
|
|
@@ -17134,151 +16822,76 @@ var PitchesApi = class {
|
|
|
17134
16822
|
ctaLabel: input.ctaLabel ?? "Get it now",
|
|
17135
16823
|
intendedAudience: input.intendedAudience ?? "",
|
|
17136
16824
|
visibility: input.visibility ?? "private"
|
|
17137
|
-
// 2026-06-21: `listingMode` removed (clean-break).
|
|
17138
16825
|
};
|
|
17139
16826
|
if (input.categorySlug != null) payload.categorySlug = input.categorySlug;
|
|
17140
16827
|
if (input.priceNote != null && input.priceNote !== "") {
|
|
17141
16828
|
payload.priceNote = String(input.priceNote).slice(0, 64);
|
|
17142
16829
|
}
|
|
17143
|
-
const doc = await
|
|
16830
|
+
const doc = await fetchPitches(this.config, {
|
|
17144
16831
|
method: "POST",
|
|
17145
|
-
path: "/",
|
|
16832
|
+
path: "/pitches",
|
|
17146
16833
|
body: payload
|
|
17147
16834
|
});
|
|
17148
16835
|
return rowToPitch(doc);
|
|
17149
16836
|
}
|
|
17150
16837
|
async get(id) {
|
|
17151
|
-
const doc = await
|
|
17152
|
-
|
|
17153
|
-
|
|
17154
|
-
id
|
|
17155
|
-
);
|
|
17156
|
-
const rows = await loadPitchSectionsFor(this.config, id);
|
|
17157
|
-
const resolved = (0, import_pitch_core.loadPitchSections)({
|
|
17158
|
-
pitchId: id,
|
|
17159
|
-
doc,
|
|
17160
|
-
rows,
|
|
17161
|
-
// The SDK is silent on the self-heal path; the build log
|
|
17162
|
-
// catches disagreement via its own `loadPitchSections`
|
|
17163
|
-
// invocation. Keeping the SDK quiet preserves the
|
|
17164
|
-
// "read-only" contract of `pitches.get`.
|
|
17165
|
-
log: () => {
|
|
17166
|
-
}
|
|
16838
|
+
const doc = await fetchPitches(this.config, {
|
|
16839
|
+
method: "GET",
|
|
16840
|
+
path: `/pitches/${encodeURIComponent(id)}`
|
|
17167
16841
|
});
|
|
17168
|
-
return rowToPitch(doc
|
|
16842
|
+
return rowToPitch(doc);
|
|
17169
16843
|
}
|
|
17170
16844
|
async find(opts = {}) {
|
|
17171
|
-
const
|
|
17172
|
-
if (opts.status)
|
|
17173
|
-
|
|
17174
|
-
|
|
17175
|
-
const
|
|
17176
|
-
|
|
17177
|
-
|
|
17178
|
-
queries
|
|
17179
|
-
);
|
|
17180
|
-
const docs = json.documents ?? [];
|
|
17181
|
-
if (docs.length === 0) return [];
|
|
17182
|
-
const pitchIds = docs.map((d) => String(d["$id"] ?? ""));
|
|
17183
|
-
const sectionRowsByPitch = /* @__PURE__ */ new Map();
|
|
17184
|
-
for (const pitchId of pitchIds) {
|
|
17185
|
-
if (!pitchId) continue;
|
|
17186
|
-
if (sectionRowsByPitch.has(pitchId)) continue;
|
|
17187
|
-
const rows = await loadPitchSectionsFor(this.config, pitchId);
|
|
17188
|
-
sectionRowsByPitch.set(pitchId, rows);
|
|
17189
|
-
}
|
|
17190
|
-
return docs.map((doc) => {
|
|
17191
|
-
const pitchId = String(doc["$id"] ?? "");
|
|
17192
|
-
const rows = sectionRowsByPitch.get(pitchId) ?? [];
|
|
17193
|
-
const resolved = (0, import_pitch_core.loadPitchSections)({
|
|
17194
|
-
pitchId,
|
|
17195
|
-
doc,
|
|
17196
|
-
rows,
|
|
17197
|
-
log: () => {
|
|
17198
|
-
}
|
|
17199
|
-
});
|
|
17200
|
-
return rowToPitch(doc, resolved.sections);
|
|
16845
|
+
const params = new URLSearchParams();
|
|
16846
|
+
if (opts.status) params.set("status", opts.status);
|
|
16847
|
+
if (typeof opts.limit === "number") params.set("limit", String(opts.limit));
|
|
16848
|
+
const qs = params.toString();
|
|
16849
|
+
const docs = await fetchPitches(this.config, {
|
|
16850
|
+
method: "GET",
|
|
16851
|
+
path: `/pitches${qs ? `?${qs}` : ""}`
|
|
17201
16852
|
});
|
|
16853
|
+
return docs.map((d) => rowToPitch(d));
|
|
17202
16854
|
}
|
|
17203
16855
|
async update(id, input) {
|
|
17204
|
-
const
|
|
17205
|
-
await assertCreatorOwnedByAuthContext(this.config, String(existing.creatorId));
|
|
17206
|
-
const nextFramework = input.framework ?? existing.framework;
|
|
17207
|
-
const nextSections = input.sections ?? (0, import_pitch_core.parseSectionsJson)(existing.sections);
|
|
17208
|
-
if (input.framework != null && input.framework !== existing.framework) {
|
|
17209
|
-
const from = existing.lifecycle;
|
|
17210
|
-
const check = (0, import_pitch_core.canChangeFramework)(from, from);
|
|
17211
|
-
if (!check.ok) throw new FrameworkLockedError(check.reason);
|
|
17212
|
-
}
|
|
17213
|
-
validatePitchContent(nextFramework, nextSections);
|
|
17214
|
-
const body = { ...input };
|
|
17215
|
-
const doc = await executePitchFunction(this.config, {
|
|
16856
|
+
const doc = await fetchPitches(this.config, {
|
|
17216
16857
|
method: "PATCH",
|
|
17217
|
-
path:
|
|
17218
|
-
body
|
|
16858
|
+
path: `/pitches/${encodeURIComponent(id)}`,
|
|
16859
|
+
body: { ...input }
|
|
17219
16860
|
});
|
|
17220
16861
|
return rowToPitch(doc);
|
|
17221
16862
|
}
|
|
17222
16863
|
async transition(id, input) {
|
|
17223
|
-
const
|
|
17224
|
-
await assertCreatorOwnedByAuthContext(this.config, String(existing.creatorId));
|
|
17225
|
-
const doc = await executePitchFunction(this.config, {
|
|
16864
|
+
const doc = await fetchPitches(this.config, {
|
|
17226
16865
|
method: "POST",
|
|
17227
|
-
path:
|
|
17228
|
-
body: {
|
|
17229
|
-
to: input.to,
|
|
17230
|
-
previewToken: input.previewToken
|
|
17231
|
-
}
|
|
16866
|
+
path: `/pitches/${encodeURIComponent(id)}/transition`,
|
|
16867
|
+
body: { to: input.to, previewToken: input.previewToken }
|
|
17232
16868
|
});
|
|
17233
16869
|
return rowToPitch(doc);
|
|
17234
16870
|
}
|
|
17235
16871
|
/**
|
|
17236
16872
|
* Upload a media file (thumbnail, og-image, video-poster, etc.)
|
|
17237
|
-
*
|
|
17238
|
-
*
|
|
17239
|
-
*
|
|
17240
|
-
* Added 2026-06-23 to address Finding #4 of
|
|
17241
|
-
* `docs-new/hp-cli-cycle-finds-2026-06-23.md`. The CLI's
|
|
17242
|
-
* `hp pitches media upload` command calls this method.
|
|
17243
|
-
*
|
|
17244
|
-
* The `kind` must be one of the `AssetKind` values exported by
|
|
17245
|
-
* `@honest-pitches/pitch-asset-core`. The server reads the bytes
|
|
17246
|
-
* from `bytesBase64` (the base64 of `bytes`), uploads them to
|
|
17247
|
-
* Bunny Storage, and writes a `pitch_assets` row. The returned
|
|
17248
|
-
* record carries the wired `bunnyPath` and `cdnUrl`.
|
|
16873
|
+
* via the MCP server's `POST /pitcher/pitches/:id/media` route.
|
|
16874
|
+
* The MCP server handles the Bunny Storage upload + the
|
|
16875
|
+
* `pitch_assets` row insert.
|
|
17249
16876
|
*/
|
|
17250
16877
|
async uploadMedia(input) {
|
|
17251
|
-
const doc = await
|
|
17252
|
-
functionId: this.config.pitchAssetUploadFunctionId,
|
|
16878
|
+
const doc = await fetchPitches(this.config, {
|
|
17253
16879
|
method: "POST",
|
|
17254
|
-
path:
|
|
16880
|
+
path: `/pitches/${encodeURIComponent(input.pitchId)}/media`,
|
|
17255
16881
|
body: {
|
|
17256
|
-
pitchId: input.pitchId,
|
|
17257
16882
|
kind: input.kind,
|
|
17258
16883
|
mimeType: input.mimeType,
|
|
17259
|
-
|
|
17260
|
-
isPublic: input.isPublic ?? true
|
|
17261
|
-
// Buffer.from(Uint8Array) is the canonical Node 22 path to
|
|
17262
|
-
// get the raw bytes. In browsers this is also covered by the
|
|
17263
|
-
// same Buffer.from(uint8) shim, but the SDK is Node-only
|
|
17264
|
-
// today so we don't need a cross-runtime polyfill.
|
|
17265
|
-
bytesBase64: Buffer.from(input.bytes).toString("base64")
|
|
16884
|
+
bytesBase64: Buffer.from(input.bytes).toString("base64"),
|
|
16885
|
+
isPublic: input.isPublic ?? true
|
|
17266
16886
|
}
|
|
17267
16887
|
});
|
|
17268
16888
|
return doc;
|
|
17269
16889
|
}
|
|
17270
16890
|
/**
|
|
17271
|
-
* Restore an archived pitch to `draft
|
|
17272
|
-
*
|
|
17273
|
-
*
|
|
17274
|
-
*
|
|
17275
|
-
* the unarchive path reuses the same token so subsequent
|
|
17276
|
-
* `draft → preview` moves don't require a re-mint).
|
|
17277
|
-
*
|
|
17278
|
-
* Added 2026-06-23 to address Finding #5 of
|
|
17279
|
-
* `docs-new/hp-cli-cycle-finds-2026-06-23.md`. The CLI's
|
|
17280
|
-
* `hp pitches transition <id> --to draft` command routes through
|
|
17281
|
-
* this method when the current lifecycle is `archived`.
|
|
16891
|
+
* Restore an archived pitch to `draft`. Same as `transition(id, {
|
|
16892
|
+
* to: "draft", previewToken })` but with a placeholder previewToken
|
|
16893
|
+
* if the caller didn't pass one. The server's "to=draft" path
|
|
16894
|
+
* mirrors the existing "to=preview" pre-condition.
|
|
17282
16895
|
*/
|
|
17283
16896
|
async unarchive(id, opts = {}) {
|
|
17284
16897
|
return this.transition(id, {
|
|
@@ -17295,25 +16908,16 @@ function createPitcherClient(config) {
|
|
|
17295
16908
|
pitches: new PitchesApi(resolved),
|
|
17296
16909
|
setJwt: (jwt, expiresAt) => resolved.setJwt(jwt, expiresAt),
|
|
17297
16910
|
getJwt: () => resolved.getJwt(),
|
|
17298
|
-
resolveCreatorId: async () => {
|
|
17299
|
-
const id = await findCreatorIdForJwtUser(resolved);
|
|
17300
|
-
if (!id) {
|
|
17301
|
-
throw new Error(
|
|
17302
|
-
"No creators row for this user \u2014 sign in via studio once so user-onboard runs"
|
|
17303
|
-
);
|
|
17304
|
-
}
|
|
17305
|
-
return id;
|
|
17306
|
-
},
|
|
17307
16911
|
findCreatorIdForJwtUser: () => findCreatorIdForJwtUser(resolved),
|
|
17308
16912
|
findCreatorIdForApiKey: () => findCreatorIdForApiKey(resolved)
|
|
17309
16913
|
};
|
|
17310
16914
|
}
|
|
17311
16915
|
|
|
17312
16916
|
// src/index.ts
|
|
17313
|
-
var import_pitch_core3 = __toESM(
|
|
16917
|
+
var import_pitch_core3 = __toESM(require_dist2(), 1);
|
|
17314
16918
|
|
|
17315
16919
|
// src/scaffold.ts
|
|
17316
|
-
var import_pitch_core2 = __toESM(
|
|
16920
|
+
var import_pitch_core2 = __toESM(require_dist2(), 1);
|
|
17317
16921
|
function scaffoldPitchFromFramework(input) {
|
|
17318
16922
|
if (!(0, import_pitch_core2.isFrameworkId)(input.framework)) {
|
|
17319
16923
|
throw new Error(`Unknown framework id: ${input.framework}`);
|
|
@@ -17334,25 +16938,37 @@ function scaffoldPitchFromFramework(input) {
|
|
|
17334
16938
|
ctaLabel: input.ctaLabel
|
|
17335
16939
|
};
|
|
17336
16940
|
}
|
|
16941
|
+
|
|
16942
|
+
// src/resolve-consolidated-route.ts
|
|
16943
|
+
var STUDIO_API_FUNCTION_ID = "honest-pitches-studio-api";
|
|
16944
|
+
var MEDIA_API_FUNCTION_ID = "honest-pitches-media";
|
|
16945
|
+
var FUNCTION_BUNDLE_MAP = {
|
|
16946
|
+
"pitch-write": STUDIO_API_FUNCTION_ID,
|
|
16947
|
+
"pitch-transition": STUDIO_API_FUNCTION_ID,
|
|
16948
|
+
"pitch-asset-upload": MEDIA_API_FUNCTION_ID,
|
|
16949
|
+
"agent-magic-link-issue": STUDIO_API_FUNCTION_ID
|
|
16950
|
+
};
|
|
16951
|
+
function resolveConsolidatedRoute(functionId, path) {
|
|
16952
|
+
const bundle = FUNCTION_BUNDLE_MAP[functionId];
|
|
16953
|
+
if (!bundle) return { functionId, path };
|
|
16954
|
+
const sub = path.startsWith("/") ? path : `/${path}`;
|
|
16955
|
+
const prefixed = sub === "/" ? `/${functionId}` : `/${functionId}${sub}`;
|
|
16956
|
+
return { functionId: bundle, path: prefixed };
|
|
16957
|
+
}
|
|
17337
16958
|
var export_getSegmentDefinition = import_pitch_core3.getSegmentDefinition;
|
|
17338
16959
|
var export_loadFrameworks = import_pitch_core3.loadFrameworks;
|
|
17339
16960
|
var export_loadSegments = import_pitch_core3.loadSegments;
|
|
17340
16961
|
var export_suggestedSectionsForFramework = import_pitch_core3.suggestedSectionsForFramework;
|
|
17341
16962
|
export {
|
|
17342
|
-
|
|
16963
|
+
DEFAULT_PITCHER_BASE_URL,
|
|
17343
16964
|
FrameworkLockedError,
|
|
17344
16965
|
HpCodeImmutableError,
|
|
17345
16966
|
InvalidSectionKindError,
|
|
17346
|
-
MEDIA_API_FUNCTION_ID,
|
|
17347
|
-
PUBLIC_API_FUNCTION_ID,
|
|
17348
16967
|
PitcherNotAuthenticatedError,
|
|
17349
16968
|
PitcherNotOwnedCreatorError,
|
|
16969
|
+
PitcherRequestError,
|
|
17350
16970
|
PitcherSdkError,
|
|
17351
16971
|
PitchesApi,
|
|
17352
|
-
STRIPE_API_FUNCTION_ID,
|
|
17353
|
-
STUDIO_API_FUNCTION_ID,
|
|
17354
|
-
appwriteQueryEqual,
|
|
17355
|
-
appwriteQueryLimit,
|
|
17356
16972
|
createPitcherClient,
|
|
17357
16973
|
decodeJwtSub,
|
|
17358
16974
|
findCreatorIdForApiKey,
|