@segmentflow/segmentflow-mcp 0.7.0
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/LICENSE +201 -0
- package/README.md +101 -0
- package/auth.d.mts +6 -0
- package/auth.d.mts.map +1 -0
- package/auth.d.ts +6 -0
- package/auth.d.ts.map +1 -0
- package/auth.js +22 -0
- package/auth.js.map +1 -0
- package/auth.mjs +17 -0
- package/auth.mjs.map +1 -0
- package/code-tool-paths.cjs +8 -0
- package/code-tool-paths.cjs.map +1 -0
- package/code-tool-paths.d.cts +2 -0
- package/code-tool-paths.d.cts.map +1 -0
- package/code-tool-types.d.mts +14 -0
- package/code-tool-types.d.mts.map +1 -0
- package/code-tool-types.d.ts +14 -0
- package/code-tool-types.d.ts.map +1 -0
- package/code-tool-types.js +4 -0
- package/code-tool-types.js.map +1 -0
- package/code-tool-types.mjs +3 -0
- package/code-tool-types.mjs.map +1 -0
- package/code-tool-worker.d.mts +5 -0
- package/code-tool-worker.d.mts.map +1 -0
- package/code-tool-worker.d.ts +5 -0
- package/code-tool-worker.d.ts.map +1 -0
- package/code-tool-worker.js +280 -0
- package/code-tool-worker.js.map +1 -0
- package/code-tool-worker.mjs +242 -0
- package/code-tool-worker.mjs.map +1 -0
- package/code-tool.d.mts +21 -0
- package/code-tool.d.mts.map +1 -0
- package/code-tool.d.ts +21 -0
- package/code-tool.d.ts.map +1 -0
- package/code-tool.js +339 -0
- package/code-tool.js.map +1 -0
- package/code-tool.mjs +303 -0
- package/code-tool.mjs.map +1 -0
- package/docs-search-tool.d.mts +59 -0
- package/docs-search-tool.d.mts.map +1 -0
- package/docs-search-tool.d.ts +59 -0
- package/docs-search-tool.d.ts.map +1 -0
- package/docs-search-tool.js +104 -0
- package/docs-search-tool.js.map +1 -0
- package/docs-search-tool.mjs +99 -0
- package/docs-search-tool.mjs.map +1 -0
- package/http.d.mts +12 -0
- package/http.d.mts.map +1 -0
- package/http.d.ts +12 -0
- package/http.d.ts.map +1 -0
- package/http.js +190 -0
- package/http.js.map +1 -0
- package/http.mjs +182 -0
- package/http.mjs.map +1 -0
- package/index.d.mts +3 -0
- package/index.d.mts.map +1 -0
- package/index.d.ts +3 -0
- package/index.d.ts.map +1 -0
- package/index.js +60 -0
- package/index.js.map +1 -0
- package/index.mjs +58 -0
- package/index.mjs.map +1 -0
- package/instructions.d.mts +5 -0
- package/instructions.d.mts.map +1 -0
- package/instructions.d.ts +5 -0
- package/instructions.d.ts.map +1 -0
- package/instructions.js +61 -0
- package/instructions.js.map +1 -0
- package/instructions.mjs +55 -0
- package/instructions.mjs.map +1 -0
- package/local-docs-search.d.mts +28 -0
- package/local-docs-search.d.mts.map +1 -0
- package/local-docs-search.d.ts +28 -0
- package/local-docs-search.d.ts.map +1 -0
- package/local-docs-search.js +635 -0
- package/local-docs-search.js.map +1 -0
- package/local-docs-search.mjs +595 -0
- package/local-docs-search.mjs.map +1 -0
- package/logger.d.mts +7 -0
- package/logger.d.mts.map +1 -0
- package/logger.d.ts +7 -0
- package/logger.d.ts.map +1 -0
- package/logger.js +29 -0
- package/logger.js.map +1 -0
- package/logger.mjs +22 -0
- package/logger.mjs.map +1 -0
- package/methods.d.mts +10 -0
- package/methods.d.mts.map +1 -0
- package/methods.d.ts +10 -0
- package/methods.d.ts.map +1 -0
- package/methods.js +149 -0
- package/methods.js.map +1 -0
- package/methods.mjs +145 -0
- package/methods.mjs.map +1 -0
- package/options.d.mts +23 -0
- package/options.d.mts.map +1 -0
- package/options.d.ts +23 -0
- package/options.d.ts.map +1 -0
- package/options.js +141 -0
- package/options.js.map +1 -0
- package/options.mjs +134 -0
- package/options.mjs.map +1 -0
- package/package.json +235 -0
- package/server.d.mts +38 -0
- package/server.d.mts.map +1 -0
- package/server.d.ts +38 -0
- package/server.d.ts.map +1 -0
- package/server.js +170 -0
- package/server.js.map +1 -0
- package/server.mjs +160 -0
- package/server.mjs.map +1 -0
- package/src/auth.ts +25 -0
- package/src/code-tool-paths.cts +5 -0
- package/src/code-tool-types.ts +17 -0
- package/src/code-tool-worker.ts +293 -0
- package/src/code-tool.ts +397 -0
- package/src/docs-search-tool.ts +138 -0
- package/src/http.ts +227 -0
- package/src/index.ts +67 -0
- package/src/instructions.ts +83 -0
- package/src/local-docs-search.ts +719 -0
- package/src/logger.ts +28 -0
- package/src/methods.ts +170 -0
- package/src/options.ts +185 -0
- package/src/server.ts +210 -0
- package/src/stdio.ts +17 -0
- package/src/tsconfig.json +11 -0
- package/src/types.ts +126 -0
- package/src/util.ts +25 -0
- package/stdio.d.mts +3 -0
- package/stdio.d.mts.map +1 -0
- package/stdio.d.ts +3 -0
- package/stdio.d.ts.map +1 -0
- package/stdio.js +18 -0
- package/stdio.js.map +1 -0
- package/stdio.mjs +14 -0
- package/stdio.mjs.map +1 -0
- package/types.d.mts +65 -0
- package/types.d.mts.map +1 -0
- package/types.d.ts +65 -0
- package/types.d.ts.map +1 -0
- package/types.js +58 -0
- package/types.js.map +1 -0
- package/types.mjs +53 -0
- package/types.mjs.map +1 -0
- package/util.d.mts +4 -0
- package/util.d.mts.map +1 -0
- package/util.d.ts +4 -0
- package/util.d.ts.map +1 -0
- package/util.js +30 -0
- package/util.js.map +1 -0
- package/util.mjs +24 -0
- package/util.mjs.map +1 -0
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.LocalDocsSearch = void 0;
|
|
41
|
+
const minisearch_1 = __importDefault(require("minisearch"));
|
|
42
|
+
const fs = __importStar(require("node:fs/promises"));
|
|
43
|
+
const path = __importStar(require("node:path"));
|
|
44
|
+
const logger_1 = require("./logger.js");
|
|
45
|
+
const EMBEDDED_METHODS = [
|
|
46
|
+
{
|
|
47
|
+
name: 'get_brand_kit',
|
|
48
|
+
endpoint: '/api/v1/public/brand-kit',
|
|
49
|
+
httpMethod: 'get',
|
|
50
|
+
summary: 'List brand kits',
|
|
51
|
+
description: 'List brand kits',
|
|
52
|
+
stainlessPath: '(resource) v1.public > (method) get_brand_kit',
|
|
53
|
+
qualified: 'client.v1.public.getBrandKit',
|
|
54
|
+
response: '{ brandKits: { id: string; companyName: string; createdAt: string; isPrimary: boolean; logoUrl: string; name: string; previewColors: string[]; primaryFont: string; slug: string; updatedAt: string; website: string; }[]; count: number; }',
|
|
55
|
+
markdown: "## get_brand_kit\n\n`client.v1.public.getBrandKit(): { brandKits: object[]; count: number; }`\n\n**get** `/api/v1/public/brand-kit`\n\nList brand kits\n\n### Returns\n\n- `{ brandKits: { id: string; companyName: string; createdAt: string; isPrimary: boolean; logoUrl: string; name: string; previewColors: string[]; primaryFont: string; slug: string; updatedAt: string; website: string; }[]; count: number; }`\n\n - `brandKits: { id: string; companyName: string; createdAt: string; isPrimary: boolean; logoUrl: string; name: string; previewColors: string[]; primaryFont: string; slug: string; updatedAt: string; website: string; }[]`\n - `count: number`\n\n### Example\n\n```typescript\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI();\n\nconst response = await client.v1.public.getBrandKit();\n\nconsole.log(response);\n```",
|
|
56
|
+
perLanguage: {
|
|
57
|
+
typescript: {
|
|
58
|
+
method: 'client.v1.public.getBrandKit',
|
|
59
|
+
example: "import SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.v1.public.getBrandKit();\n\nconsole.log(response.brandKits);",
|
|
60
|
+
},
|
|
61
|
+
http: {
|
|
62
|
+
example: 'curl https://api.segmentflow.ai/api/v1/public/brand-kit \\\n -H "x-api-key: $SEGMENTFLOW_API_KEY"',
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: 'trigger',
|
|
68
|
+
endpoint: '/api/v1/public/journeys/{id}/trigger',
|
|
69
|
+
httpMethod: 'post',
|
|
70
|
+
summary: 'Trigger a journey for a profile',
|
|
71
|
+
description: 'Start an API-triggerable journey for a single profile. Returns immediately; poll GET /journeys/runs/{runId} for status. Supports Idempotency-Key header.',
|
|
72
|
+
stainlessPath: '(resource) v1.public.journeys > (method) trigger',
|
|
73
|
+
qualified: 'client.v1.public.journeys.trigger',
|
|
74
|
+
params: [
|
|
75
|
+
'id: string;',
|
|
76
|
+
'profile: { anonymousId?: string; email?: string; userId?: string; };',
|
|
77
|
+
'variables?: object;',
|
|
78
|
+
],
|
|
79
|
+
response: "{ runId: string; status: 'queued' | 'running' | 'completed' | 'failed' | 'exited'; }",
|
|
80
|
+
markdown: "## trigger\n\n`client.v1.public.journeys.trigger(id: string, profile: { anonymousId?: string; email?: string; userId?: string; }, variables?: object): { runId: string; status: 'queued' | 'running' | 'completed' | 'failed' | 'exited'; }`\n\n**post** `/api/v1/public/journeys/{id}/trigger`\n\nStart an API-triggerable journey for a single profile. Returns immediately; poll GET /journeys/runs/{runId} for status. Supports Idempotency-Key header.\n\n### Parameters\n\n- `id: string`\n\n- `profile: { anonymousId?: string; email?: string; userId?: string; }`\n - `anonymousId?: string`\n - `email?: string`\n - `userId?: string`\n\n- `variables?: object`\n\n### Returns\n\n- `{ runId: string; status: 'queued' | 'running' | 'completed' | 'failed' | 'exited'; }`\n\n - `runId: string`\n - `status: 'queued' | 'running' | 'completed' | 'failed' | 'exited'`\n\n### Example\n\n```typescript\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI();\n\nconst response = await client.v1.public.journeys.trigger('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', { profile: {} });\n\nconsole.log(response);\n```",
|
|
81
|
+
perLanguage: {
|
|
82
|
+
typescript: {
|
|
83
|
+
method: 'client.v1.public.journeys.trigger',
|
|
84
|
+
example: "import SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.v1.public.journeys.trigger('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e', {\n profile: {},\n});\n\nconsole.log(response.runId);",
|
|
85
|
+
},
|
|
86
|
+
http: {
|
|
87
|
+
example: 'curl https://api.segmentflow.ai/api/v1/public/journeys/$ID/trigger \\\n -H \'Content-Type: application/json\' \\\n -H "x-api-key: $SEGMENTFLOW_API_KEY" \\\n -d \'{\n "profile": {}\n }\'',
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: 'get_run_status',
|
|
93
|
+
endpoint: '/api/v1/public/journeys/runs/{runId}',
|
|
94
|
+
httpMethod: 'get',
|
|
95
|
+
summary: 'Get journey run status',
|
|
96
|
+
description: 'Fetch the status of a journey run previously created via POST /journeys/{id}/trigger.',
|
|
97
|
+
stainlessPath: '(resource) v1.public.journeys > (method) get_run_status',
|
|
98
|
+
qualified: 'client.v1.public.journeys.getRunStatus',
|
|
99
|
+
params: ['runId: string;'],
|
|
100
|
+
response: "{ completedAt: string; error: string; journeyId: string; profileId: string; runId: string; status: 'queued' | 'running' | 'completed' | 'failed' | 'exited'; triggeredAt: string; }",
|
|
101
|
+
markdown: "## get_run_status\n\n`client.v1.public.journeys.getRunStatus(runId: string): { completedAt: string; error: string; journeyId: string; profileId: string; runId: string; status: 'queued' | 'running' | 'completed' | 'failed' | 'exited'; triggeredAt: string; }`\n\n**get** `/api/v1/public/journeys/runs/{runId}`\n\nFetch the status of a journey run previously created via POST /journeys/{id}/trigger.\n\n### Parameters\n\n- `runId: string`\n\n### Returns\n\n- `{ completedAt: string; error: string; journeyId: string; profileId: string; runId: string; status: 'queued' | 'running' | 'completed' | 'failed' | 'exited'; triggeredAt: string; }`\n\n - `completedAt: string`\n - `error: string`\n - `journeyId: string`\n - `profileId: string`\n - `runId: string`\n - `status: 'queued' | 'running' | 'completed' | 'failed' | 'exited'`\n - `triggeredAt: string`\n\n### Example\n\n```typescript\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI();\n\nconst response = await client.v1.public.journeys.getRunStatus('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(response);\n```",
|
|
102
|
+
perLanguage: {
|
|
103
|
+
typescript: {
|
|
104
|
+
method: 'client.v1.public.journeys.getRunStatus',
|
|
105
|
+
example: "import SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.v1.public.journeys.getRunStatus(\n '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n);\n\nconsole.log(response.completedAt);",
|
|
106
|
+
},
|
|
107
|
+
http: {
|
|
108
|
+
example: 'curl https://api.segmentflow.ai/api/v1/public/journeys/runs/$RUN_ID \\\n -H "x-api-key: $SEGMENTFLOW_API_KEY"',
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: 'create',
|
|
114
|
+
endpoint: '/api/v1/public/broadcasts',
|
|
115
|
+
httpMethod: 'post',
|
|
116
|
+
summary: 'Create and send a broadcast',
|
|
117
|
+
description: 'Create a broadcast and send immediately. v1 does not support scheduledAt; providing it returns 501. Supports Idempotency-Key header.',
|
|
118
|
+
stainlessPath: '(resource) v1.public.broadcasts > (method) create',
|
|
119
|
+
qualified: 'client.v1.public.broadcasts.create',
|
|
120
|
+
params: [
|
|
121
|
+
'name: string;',
|
|
122
|
+
'segmentId: string;',
|
|
123
|
+
'templateId: string;',
|
|
124
|
+
'scheduledAt?: string;',
|
|
125
|
+
'subject?: string;',
|
|
126
|
+
],
|
|
127
|
+
response: "{ broadcastId: string; status: 'NotStarted' | 'InProgress' | 'Triggered' | 'Sent' | 'Failed' | 'Archived' | 'Warming' | 'Paused'; }",
|
|
128
|
+
markdown: "## create\n\n`client.v1.public.broadcasts.create(name: string, segmentId: string, templateId: string, scheduledAt?: string, subject?: string): { broadcastId: string; status: broadcast_status; }`\n\n**post** `/api/v1/public/broadcasts`\n\nCreate a broadcast and send immediately. v1 does not support scheduledAt; providing it returns 501. Supports Idempotency-Key header.\n\n### Parameters\n\n- `name: string`\n\n- `segmentId: string`\n\n- `templateId: string`\n\n- `scheduledAt?: string`\n\n- `subject?: string`\n\n### Returns\n\n- `{ broadcastId: string; status: 'NotStarted' | 'InProgress' | 'Triggered' | 'Sent' | 'Failed' | 'Archived' | 'Warming' | 'Paused'; }`\n\n - `broadcastId: string`\n - `status: 'NotStarted' | 'InProgress' | 'Triggered' | 'Sent' | 'Failed' | 'Archived' | 'Warming' | 'Paused'`\n\n### Example\n\n```typescript\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI();\n\nconst broadcast = await client.v1.public.broadcasts.create({\n name: 'x',\n segmentId: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n templateId: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n});\n\nconsole.log(broadcast);\n```",
|
|
129
|
+
perLanguage: {
|
|
130
|
+
typescript: {
|
|
131
|
+
method: 'client.v1.public.broadcasts.create',
|
|
132
|
+
example: "import SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n});\n\nconst broadcast = await client.v1.public.broadcasts.create({\n name: 'x',\n segmentId: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n templateId: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n});\n\nconsole.log(broadcast.broadcastId);",
|
|
133
|
+
},
|
|
134
|
+
http: {
|
|
135
|
+
example: 'curl https://api.segmentflow.ai/api/v1/public/broadcasts \\\n -H \'Content-Type: application/json\' \\\n -H "x-api-key: $SEGMENTFLOW_API_KEY" \\\n -d \'{\n "name": "x",\n "segmentId": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n "templateId": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"\n }\'',
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: 'cancel',
|
|
141
|
+
endpoint: '/api/v1/public/broadcasts/{id}/cancel',
|
|
142
|
+
httpMethod: 'post',
|
|
143
|
+
summary: 'Cancel an in-flight broadcast',
|
|
144
|
+
description: 'Cancel all in-flight workflows for a broadcast and mark it Failed. Idempotent — noop (still 200) on broadcasts in terminal states.',
|
|
145
|
+
stainlessPath: '(resource) v1.public.broadcasts > (method) cancel',
|
|
146
|
+
qualified: 'client.v1.public.broadcasts.cancel',
|
|
147
|
+
params: ['id: string;'],
|
|
148
|
+
response: "{ broadcastId: string; status: 'NotStarted' | 'InProgress' | 'Triggered' | 'Sent' | 'Failed' | 'Archived' | 'Warming' | 'Paused'; }",
|
|
149
|
+
markdown: "## cancel\n\n`client.v1.public.broadcasts.cancel(id: string): { broadcastId: string; status: broadcast_status; }`\n\n**post** `/api/v1/public/broadcasts/{id}/cancel`\n\nCancel all in-flight workflows for a broadcast and mark it Failed. Idempotent — noop (still 200) on broadcasts in terminal states.\n\n### Parameters\n\n- `id: string`\n\n### Returns\n\n- `{ broadcastId: string; status: 'NotStarted' | 'InProgress' | 'Triggered' | 'Sent' | 'Failed' | 'Archived' | 'Warming' | 'Paused'; }`\n\n - `broadcastId: string`\n - `status: 'NotStarted' | 'InProgress' | 'Triggered' | 'Sent' | 'Failed' | 'Archived' | 'Warming' | 'Paused'`\n\n### Example\n\n```typescript\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI();\n\nconst response = await client.v1.public.broadcasts.cancel('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(response);\n```",
|
|
150
|
+
perLanguage: {
|
|
151
|
+
typescript: {
|
|
152
|
+
method: 'client.v1.public.broadcasts.cancel',
|
|
153
|
+
example: "import SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.v1.public.broadcasts.cancel('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(response.broadcastId);",
|
|
154
|
+
},
|
|
155
|
+
http: {
|
|
156
|
+
example: 'curl https://api.segmentflow.ai/api/v1/public/broadcasts/$ID/cancel \\\n -X POST \\\n -H "x-api-key: $SEGMENTFLOW_API_KEY"',
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: 'prepare',
|
|
162
|
+
endpoint: '/api/v1/public/broadcasts/prepare',
|
|
163
|
+
httpMethod: 'post',
|
|
164
|
+
summary: 'Prepare a broadcast (dry-run, returns preparedSendId)',
|
|
165
|
+
description: 'Validate a broadcast draft and return a preparedSendId + audience snapshot. Bytes go nowhere until you redeem the id with /broadcasts/send-prepared. preparedSendIds expire after 15 minutes and are bound to the (organization, user) pair that created them.',
|
|
166
|
+
stainlessPath: '(resource) v1.public.broadcasts > (method) prepare',
|
|
167
|
+
qualified: 'client.v1.public.broadcasts.prepare',
|
|
168
|
+
params: ['name: string;', 'segmentId: string;', 'templateId: string;', 'subject?: string;'],
|
|
169
|
+
response: '{ audienceCount: number; expiresAt: string; preparedSendId: string; senderProfile: { id: string; fromEmail: string; name: string; }; subjectPreview: string; }',
|
|
170
|
+
markdown: "## prepare\n\n`client.v1.public.broadcasts.prepare(name: string, segmentId: string, templateId: string, subject?: string): { audienceCount: number; expiresAt: string; preparedSendId: string; senderProfile: object; subjectPreview: string; }`\n\n**post** `/api/v1/public/broadcasts/prepare`\n\nValidate a broadcast draft and return a preparedSendId + audience snapshot. Bytes go nowhere until you redeem the id with /broadcasts/send-prepared. preparedSendIds expire after 15 minutes and are bound to the (organization, user) pair that created them.\n\n### Parameters\n\n- `name: string`\n\n- `segmentId: string`\n\n- `templateId: string`\n\n- `subject?: string`\n\n### Returns\n\n- `{ audienceCount: number; expiresAt: string; preparedSendId: string; senderProfile: { id: string; fromEmail: string; name: string; }; subjectPreview: string; }`\n\n - `audienceCount: number`\n - `expiresAt: string`\n - `preparedSendId: string`\n - `senderProfile: { id: string; fromEmail: string; name: string; }`\n - `subjectPreview: string`\n\n### Example\n\n```typescript\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI();\n\nconst response = await client.v1.public.broadcasts.prepare({\n name: 'x',\n segmentId: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n templateId: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n});\n\nconsole.log(response);\n```",
|
|
171
|
+
perLanguage: {
|
|
172
|
+
typescript: {
|
|
173
|
+
method: 'client.v1.public.broadcasts.prepare',
|
|
174
|
+
example: "import SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.v1.public.broadcasts.prepare({\n name: 'x',\n segmentId: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n templateId: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n});\n\nconsole.log(response.audienceCount);",
|
|
175
|
+
},
|
|
176
|
+
http: {
|
|
177
|
+
example: 'curl https://api.segmentflow.ai/api/v1/public/broadcasts/prepare \\\n -H \'Content-Type: application/json\' \\\n -H "x-api-key: $SEGMENTFLOW_API_KEY" \\\n -d \'{\n "name": "x",\n "segmentId": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",\n "templateId": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"\n }\'',
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
name: 'send_prepared',
|
|
183
|
+
endpoint: '/api/v1/public/broadcasts/send-prepared',
|
|
184
|
+
httpMethod: 'post',
|
|
185
|
+
summary: 'Redeem a preparedSendId and trigger the broadcast',
|
|
186
|
+
description: "Atomically consumes a preparedSendId and starts the broadcast. One-time use — repeated calls with the same id replay the original response (idempotent), they never start a second send. Caller (organization, user) must match the prepare call. Requires the API key's `allowSends` metadata flag.",
|
|
187
|
+
stainlessPath: '(resource) v1.public.broadcasts > (method) send_prepared',
|
|
188
|
+
qualified: 'client.v1.public.broadcasts.sendPrepared',
|
|
189
|
+
params: ['preparedSendId: string;'],
|
|
190
|
+
response: "{ broadcastId: string; firstRedeem: boolean; status: 'NotStarted' | 'InProgress' | 'Triggered' | 'Sent' | 'Failed' | 'Archived' | 'Warming' | 'Paused'; }",
|
|
191
|
+
markdown: "## send_prepared\n\n`client.v1.public.broadcasts.sendPrepared(preparedSendId: string): { broadcastId: string; firstRedeem: boolean; status: broadcast_status; }`\n\n**post** `/api/v1/public/broadcasts/send-prepared`\n\nAtomically consumes a preparedSendId and starts the broadcast. One-time use — repeated calls with the same id replay the original response (idempotent), they never start a second send. Caller (organization, user) must match the prepare call. Requires the API key's `allowSends` metadata flag.\n\n### Parameters\n\n- `preparedSendId: string`\n\n### Returns\n\n- `{ broadcastId: string; firstRedeem: boolean; status: 'NotStarted' | 'InProgress' | 'Triggered' | 'Sent' | 'Failed' | 'Archived' | 'Warming' | 'Paused'; }`\n\n - `broadcastId: string`\n - `firstRedeem: boolean`\n - `status: 'NotStarted' | 'InProgress' | 'Triggered' | 'Sent' | 'Failed' | 'Archived' | 'Warming' | 'Paused'`\n\n### Example\n\n```typescript\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI();\n\nconst response = await client.v1.public.broadcasts.sendPrepared({ preparedSendId: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e' });\n\nconsole.log(response);\n```",
|
|
192
|
+
perLanguage: {
|
|
193
|
+
typescript: {
|
|
194
|
+
method: 'client.v1.public.broadcasts.sendPrepared',
|
|
195
|
+
example: "import SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.v1.public.broadcasts.sendPrepared({\n preparedSendId: '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n});\n\nconsole.log(response.broadcastId);",
|
|
196
|
+
},
|
|
197
|
+
http: {
|
|
198
|
+
example: 'curl https://api.segmentflow.ai/api/v1/public/broadcasts/send-prepared \\\n -H \'Content-Type: application/json\' \\\n -H "x-api-key: $SEGMENTFLOW_API_KEY" \\\n -d \'{\n "preparedSendId": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e"\n }\'',
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: 'get_status',
|
|
204
|
+
endpoint: '/api/v1/public/broadcasts/{id}',
|
|
205
|
+
httpMethod: 'get',
|
|
206
|
+
summary: 'Get broadcast status + stats',
|
|
207
|
+
description: 'Get broadcast status + stats',
|
|
208
|
+
stainlessPath: '(resource) v1.public.broadcasts > (method) get_status',
|
|
209
|
+
qualified: 'client.v1.public.broadcasts.getStatus',
|
|
210
|
+
params: ['id: string;'],
|
|
211
|
+
response: "{ id: string; completedAt: string; name: string; scheduledAt: string; startedAt: string; stats: { failed: number; queued: number; sent: number; }; status: 'NotStarted' | 'InProgress' | 'Triggered' | 'Sent' | 'Failed' | 'Archived' | 'Warming' | 'Paused'; }",
|
|
212
|
+
markdown: "## get_status\n\n`client.v1.public.broadcasts.getStatus(id: string): { id: string; completedAt: string; name: string; scheduledAt: string; startedAt: string; stats: object; status: broadcast_status; }`\n\n**get** `/api/v1/public/broadcasts/{id}`\n\nGet broadcast status + stats\n\n### Parameters\n\n- `id: string`\n\n### Returns\n\n- `{ id: string; completedAt: string; name: string; scheduledAt: string; startedAt: string; stats: { failed: number; queued: number; sent: number; }; status: 'NotStarted' | 'InProgress' | 'Triggered' | 'Sent' | 'Failed' | 'Archived' | 'Warming' | 'Paused'; }`\n\n - `id: string`\n - `completedAt: string`\n - `name: string`\n - `scheduledAt: string`\n - `startedAt: string`\n - `stats: { failed: number; queued: number; sent: number; }`\n - `status: 'NotStarted' | 'InProgress' | 'Triggered' | 'Sent' | 'Failed' | 'Archived' | 'Warming' | 'Paused'`\n\n### Example\n\n```typescript\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI();\n\nconst response = await client.v1.public.broadcasts.getStatus('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(response);\n```",
|
|
213
|
+
perLanguage: {
|
|
214
|
+
typescript: {
|
|
215
|
+
method: 'client.v1.public.broadcasts.getStatus',
|
|
216
|
+
example: "import SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.v1.public.broadcasts.getStatus(\n '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n);\n\nconsole.log(response.id);",
|
|
217
|
+
},
|
|
218
|
+
http: {
|
|
219
|
+
example: 'curl https://api.segmentflow.ai/api/v1/public/broadcasts/$ID \\\n -H "x-api-key: $SEGMENTFLOW_API_KEY"',
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
name: 'list',
|
|
225
|
+
endpoint: '/api/v1/public/templates',
|
|
226
|
+
httpMethod: 'get',
|
|
227
|
+
summary: 'List email templates',
|
|
228
|
+
description: 'List email templates',
|
|
229
|
+
stainlessPath: '(resource) v1.public.templates > (method) list',
|
|
230
|
+
qualified: 'client.v1.public.templates.list',
|
|
231
|
+
params: [
|
|
232
|
+
'cursor?: string;',
|
|
233
|
+
'limit?: number;',
|
|
234
|
+
'pageSize?: number;',
|
|
235
|
+
"purpose?: 'General' | 'Newsletter' | 'Promotional' | 'Transactional' | 'LeadMagnetDelivery';",
|
|
236
|
+
"status?: 'Active' | 'Archived';",
|
|
237
|
+
],
|
|
238
|
+
response: "{ id: string; createdAt: string; isComplete: boolean; language: string; name: string; purpose: 'General' | 'Newsletter' | 'Promotional' | 'Transactional' | 'LeadMagnetDelivery'; status: 'Active' | 'Archived'; type: string; updatedAt: string; }[]",
|
|
239
|
+
markdown: "## list\n\n`client.v1.public.templates.list(cursor?: string, limit?: number, pageSize?: number, purpose?: 'General' | 'Newsletter' | 'Promotional' | 'Transactional' | 'LeadMagnetDelivery', status?: 'Active' | 'Archived'): { id: string; createdAt: string; isComplete: boolean; language: string; name: string; purpose: 'General' | 'Newsletter' | 'Promotional' | 'Transactional' | 'LeadMagnetDelivery'; status: template_status; type: string; updatedAt: string; }[]`\n\n**get** `/api/v1/public/templates`\n\nList email templates\n\n### Parameters\n\n- `cursor?: string`\n\n- `limit?: number`\n\n- `pageSize?: number`\n\n- `purpose?: 'General' | 'Newsletter' | 'Promotional' | 'Transactional' | 'LeadMagnetDelivery'`\n\n- `status?: 'Active' | 'Archived'`\n Lifecycle status of a message template (Active or Archived)\n\n### Returns\n\n- `{ id: string; createdAt: string; isComplete: boolean; language: string; name: string; purpose: 'General' | 'Newsletter' | 'Promotional' | 'Transactional' | 'LeadMagnetDelivery'; status: 'Active' | 'Archived'; type: string; updatedAt: string; }[]`\n\n### Example\n\n```typescript\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI();\n\nconst templates = await client.v1.public.templates.list();\n\nconsole.log(templates);\n```",
|
|
240
|
+
perLanguage: {
|
|
241
|
+
typescript: {
|
|
242
|
+
method: 'client.v1.public.templates.list',
|
|
243
|
+
example: "import SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n});\n\nconst templates = await client.v1.public.templates.list();\n\nconsole.log(templates);",
|
|
244
|
+
},
|
|
245
|
+
http: {
|
|
246
|
+
example: 'curl https://api.segmentflow.ai/api/v1/public/templates \\\n -H "x-api-key: $SEGMENTFLOW_API_KEY"',
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
name: 'get',
|
|
252
|
+
endpoint: '/api/v1/public/templates/{id}',
|
|
253
|
+
httpMethod: 'get',
|
|
254
|
+
summary: 'Get an email template by id',
|
|
255
|
+
description: 'Get an email template by id',
|
|
256
|
+
stainlessPath: '(resource) v1.public.templates > (method) get',
|
|
257
|
+
qualified: 'client.v1.public.templates.get',
|
|
258
|
+
params: ['id: string;'],
|
|
259
|
+
response: "{ id: string; createdAt: string; isComplete: boolean; language: string; name: string; purpose: 'General' | 'Newsletter' | 'Promotional' | 'Transactional' | 'LeadMagnetDelivery'; status: 'Active' | 'Archived'; type: string; updatedAt: string; }",
|
|
260
|
+
markdown: "## get\n\n`client.v1.public.templates.get(id: string): { id: string; createdAt: string; isComplete: boolean; language: string; name: string; purpose: 'General' | 'Newsletter' | 'Promotional' | 'Transactional' | 'LeadMagnetDelivery'; status: template_status; type: string; updatedAt: string; }`\n\n**get** `/api/v1/public/templates/{id}`\n\nGet an email template by id\n\n### Parameters\n\n- `id: string`\n\n### Returns\n\n- `{ id: string; createdAt: string; isComplete: boolean; language: string; name: string; purpose: 'General' | 'Newsletter' | 'Promotional' | 'Transactional' | 'LeadMagnetDelivery'; status: 'Active' | 'Archived'; type: string; updatedAt: string; }`\n\n - `id: string`\n - `createdAt: string`\n - `isComplete: boolean`\n - `language: string`\n - `name: string`\n - `purpose: 'General' | 'Newsletter' | 'Promotional' | 'Transactional' | 'LeadMagnetDelivery'`\n - `status: 'Active' | 'Archived'`\n - `type: string`\n - `updatedAt: string`\n\n### Example\n\n```typescript\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI();\n\nconst template = await client.v1.public.templates.get('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(template);\n```",
|
|
261
|
+
perLanguage: {
|
|
262
|
+
typescript: {
|
|
263
|
+
method: 'client.v1.public.templates.get',
|
|
264
|
+
example: "import SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n});\n\nconst template = await client.v1.public.templates.get('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(template.id);",
|
|
265
|
+
},
|
|
266
|
+
http: {
|
|
267
|
+
example: 'curl https://api.segmentflow.ai/api/v1/public/templates/$ID \\\n -H "x-api-key: $SEGMENTFLOW_API_KEY"',
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
name: 'list',
|
|
273
|
+
endpoint: '/api/v1/public/segments',
|
|
274
|
+
httpMethod: 'get',
|
|
275
|
+
summary: 'List segments',
|
|
276
|
+
description: 'List segments',
|
|
277
|
+
stainlessPath: '(resource) v1.public.segments > (method) list',
|
|
278
|
+
qualified: 'client.v1.public.segments.list',
|
|
279
|
+
params: [
|
|
280
|
+
"membershipType?: 'computed' | 'static';",
|
|
281
|
+
"status?: 'NotStarted' | 'Running' | 'Paused' | 'Archived';",
|
|
282
|
+
],
|
|
283
|
+
response: "{ id: string; createdAt: string; lastComputedAt: string; membershipType: 'computed' | 'static'; name: string; status: 'NotStarted' | 'Running' | 'Paused' | 'Archived'; updatedAt: string; userCount: number; }[]",
|
|
284
|
+
markdown: "## list\n\n`client.v1.public.segments.list(membershipType?: 'computed' | 'static', status?: 'NotStarted' | 'Running' | 'Paused' | 'Archived'): { id: string; createdAt: string; lastComputedAt: string; membershipType: 'computed' | 'static'; name: string; status: 'NotStarted' | 'Running' | 'Paused' | 'Archived'; updatedAt: string; userCount: number; }[]`\n\n**get** `/api/v1/public/segments`\n\nList segments\n\n### Parameters\n\n- `membershipType?: 'computed' | 'static'`\n How segment membership is determined (computed or static)\n\n- `status?: 'NotStarted' | 'Running' | 'Paused' | 'Archived'`\n Lifecycle status of a segment\n\n### Returns\n\n- `{ id: string; createdAt: string; lastComputedAt: string; membershipType: 'computed' | 'static'; name: string; status: 'NotStarted' | 'Running' | 'Paused' | 'Archived'; updatedAt: string; userCount: number; }[]`\n\n### Example\n\n```typescript\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI();\n\nconst segments = await client.v1.public.segments.list();\n\nconsole.log(segments);\n```",
|
|
285
|
+
perLanguage: {
|
|
286
|
+
typescript: {
|
|
287
|
+
method: 'client.v1.public.segments.list',
|
|
288
|
+
example: "import SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n});\n\nconst segments = await client.v1.public.segments.list();\n\nconsole.log(segments);",
|
|
289
|
+
},
|
|
290
|
+
http: {
|
|
291
|
+
example: 'curl https://api.segmentflow.ai/api/v1/public/segments \\\n -H "x-api-key: $SEGMENTFLOW_API_KEY"',
|
|
292
|
+
},
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
name: 'preview',
|
|
297
|
+
endpoint: '/api/v1/public/segments/{id}/preview',
|
|
298
|
+
httpMethod: 'post',
|
|
299
|
+
summary: 'Preview segment audience count',
|
|
300
|
+
description: "Recompile the segment's live definition and count matching users from api.user_event. Bypasses the cached segment_membership table.",
|
|
301
|
+
stainlessPath: '(resource) v1.public.segments > (method) preview',
|
|
302
|
+
qualified: 'client.v1.public.segments.preview',
|
|
303
|
+
params: ['id: string;'],
|
|
304
|
+
response: '{ matchedUserCount: number; previewedAt: string; }',
|
|
305
|
+
markdown: "## preview\n\n`client.v1.public.segments.preview(id: string): { matchedUserCount: number; previewedAt: string; }`\n\n**post** `/api/v1/public/segments/{id}/preview`\n\nRecompile the segment's live definition and count matching users from api.user_event. Bypasses the cached segment_membership table.\n\n### Parameters\n\n- `id: string`\n\n### Returns\n\n- `{ matchedUserCount: number; previewedAt: string; }`\n\n - `matchedUserCount: number`\n - `previewedAt: string`\n\n### Example\n\n```typescript\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI();\n\nconst response = await client.v1.public.segments.preview('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(response);\n```",
|
|
306
|
+
perLanguage: {
|
|
307
|
+
typescript: {
|
|
308
|
+
method: 'client.v1.public.segments.preview',
|
|
309
|
+
example: "import SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.v1.public.segments.preview('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(response.matchedUserCount);",
|
|
310
|
+
},
|
|
311
|
+
http: {
|
|
312
|
+
example: 'curl https://api.segmentflow.ai/api/v1/public/segments/$ID/preview \\\n -X POST \\\n -H "x-api-key: $SEGMENTFLOW_API_KEY"',
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
name: 'request_upload',
|
|
318
|
+
endpoint: '/api/v1/public/assets/upload-request',
|
|
319
|
+
httpMethod: 'post',
|
|
320
|
+
summary: 'Request a presigned asset upload',
|
|
321
|
+
description: 'Pre-mints an asset id and returns a presigned S3 PUT URL. Upload the bytes with the returned headers, then call /assets/{assetId}/finalize.',
|
|
322
|
+
stainlessPath: '(resource) v1.public.assets > (method) request_upload',
|
|
323
|
+
qualified: 'client.v1.public.assets.requestUpload',
|
|
324
|
+
params: [
|
|
325
|
+
'contentType: string;',
|
|
326
|
+
'filename: string;',
|
|
327
|
+
'size: number;',
|
|
328
|
+
"assetType?: 'content-image' | 'content-document' | 'lead-magnet';",
|
|
329
|
+
],
|
|
330
|
+
response: '{ assetId: string; expiresAt: string; headers: object; uploadUrl: string; }',
|
|
331
|
+
markdown: "## request_upload\n\n`client.v1.public.assets.requestUpload(contentType: string, filename: string, size: number, assetType?: 'content-image' | 'content-document' | 'lead-magnet'): { assetId: string; expiresAt: string; headers: object; uploadUrl: string; }`\n\n**post** `/api/v1/public/assets/upload-request`\n\nPre-mints an asset id and returns a presigned S3 PUT URL. Upload the bytes with the returned headers, then call /assets/{assetId}/finalize.\n\n### Parameters\n\n- `contentType: string`\n\n- `filename: string`\n\n- `size: number`\n\n- `assetType?: 'content-image' | 'content-document' | 'lead-magnet'`\n\n### Returns\n\n- `{ assetId: string; expiresAt: string; headers: object; uploadUrl: string; }`\n\n - `assetId: string`\n - `expiresAt: string`\n - `headers: object`\n - `uploadUrl: string`\n\n### Example\n\n```typescript\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI();\n\nconst response = await client.v1.public.assets.requestUpload({\n contentType: 'x',\n filename: 'x',\n size: 9007199254740991,\n});\n\nconsole.log(response);\n```",
|
|
332
|
+
perLanguage: {
|
|
333
|
+
typescript: {
|
|
334
|
+
method: 'client.v1.public.assets.requestUpload',
|
|
335
|
+
example: "import SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.v1.public.assets.requestUpload({\n contentType: 'x',\n filename: 'x',\n size: 9007199254740991,\n});\n\nconsole.log(response.assetId);",
|
|
336
|
+
},
|
|
337
|
+
http: {
|
|
338
|
+
example: 'curl https://api.segmentflow.ai/api/v1/public/assets/upload-request \\\n -H \'Content-Type: application/json\' \\\n -H "x-api-key: $SEGMENTFLOW_API_KEY" \\\n -d \'{\n "contentType": "x",\n "filename": "x",\n "size": 9007199254740991\n }\'',
|
|
339
|
+
},
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
name: 'finalize_upload',
|
|
344
|
+
endpoint: '/api/v1/public/assets/{id}/finalize',
|
|
345
|
+
httpMethod: 'post',
|
|
346
|
+
summary: 'Finalize a presigned upload',
|
|
347
|
+
description: 'Verifies the bytes landed in S3, strips EXIF/GPS metadata, extracts dimensions, and commits the asset row.',
|
|
348
|
+
stainlessPath: '(resource) v1.public.assets > (method) finalize_upload',
|
|
349
|
+
qualified: 'client.v1.public.assets.finalizeUpload',
|
|
350
|
+
params: [
|
|
351
|
+
'id: string;',
|
|
352
|
+
'altText?: string;',
|
|
353
|
+
'description?: string;',
|
|
354
|
+
"imageType?: 'logo' | 'hero' | 'header' | 'product' | 'background' | 'icon' | 'other';",
|
|
355
|
+
],
|
|
356
|
+
response: '{ asset: { id: string; contentType: string; createdAt: string; filename: string; height: number; size: number; url: string; width: number; }; }',
|
|
357
|
+
markdown: "## finalize_upload\n\n`client.v1.public.assets.finalizeUpload(id: string, altText?: string, description?: string, imageType?: 'logo' | 'hero' | 'header' | 'product' | 'background' | 'icon' | 'other'): { asset: object; }`\n\n**post** `/api/v1/public/assets/{id}/finalize`\n\nVerifies the bytes landed in S3, strips EXIF/GPS metadata, extracts dimensions, and commits the asset row.\n\n### Parameters\n\n- `id: string`\n\n- `altText?: string`\n\n- `description?: string`\n\n- `imageType?: 'logo' | 'hero' | 'header' | 'product' | 'background' | 'icon' | 'other'`\n Category of image for use in email templates\n\n### Returns\n\n- `{ asset: { id: string; contentType: string; createdAt: string; filename: string; height: number; size: number; url: string; width: number; }; }`\n\n - `asset: { id: string; contentType: string; createdAt: string; filename: string; height: number; size: number; url: string; width: number; }`\n\n### Example\n\n```typescript\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI();\n\nconst response = await client.v1.public.assets.finalizeUpload('182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e');\n\nconsole.log(response);\n```",
|
|
358
|
+
perLanguage: {
|
|
359
|
+
typescript: {
|
|
360
|
+
method: 'client.v1.public.assets.finalizeUpload',
|
|
361
|
+
example: "import SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.v1.public.assets.finalizeUpload(\n '182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e',\n);\n\nconsole.log(response.asset);",
|
|
362
|
+
},
|
|
363
|
+
http: {
|
|
364
|
+
example: 'curl https://api.segmentflow.ai/api/v1/public/assets/$ID/finalize \\\n -X POST \\\n -H "x-api-key: $SEGMENTFLOW_API_KEY"',
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
];
|
|
369
|
+
const EMBEDDED_READMES = [
|
|
370
|
+
{
|
|
371
|
+
language: 'typescript',
|
|
372
|
+
content: "# Segmentflow AI TypeScript API Library\n\n[)](https://npmjs.org/package/@segmentflow/segmentflow-typescript) \n\nThis library provides convenient access to the Segmentflow AI REST API from server-side TypeScript or JavaScript.\n\n\n\nThe REST API documentation can be found on [segmentflow.ai](https://segmentflow.ai/docs). The full API of this library can be found in [api.md](api.md).\n\nIt is generated with [Stainless](https://www.stainless.com/).\n\n## MCP Server\n\nUse the Segmentflow AI MCP Server to enable AI assistants to interact with this API, allowing them to explore endpoints, make test requests, and use documentation to help integrate this SDK into your application.\n\n[](https://cursor.com/en-US/install-mcp?name=%40segmentflow%2Fsegmentflow-mcp&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBzZWdtZW50Zmxvdy9zZWdtZW50Zmxvdy1tY3AiXSwiZW52Ijp7IlNFR01FTlRGTE9XX0FQSV9LRVkiOiJNeSBBUEkgS2V5In19)\n[](https://vscode.stainless.com/mcp/%7B%22name%22%3A%22%40segmentflow%2Fsegmentflow-mcp%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40segmentflow%2Fsegmentflow-mcp%22%5D%2C%22env%22%3A%7B%22SEGMENTFLOW_API_KEY%22%3A%22My%20API%20Key%22%7D%7D)\n\n> Note: You may need to set environment variables in your MCP client.\n\n## Installation\n\n```sh\nnpm install @segmentflow/segmentflow-typescript\n```\n\n\n\n## Usage\n\nThe full API of this library can be found in [api.md](api.md).\n\n<!-- prettier-ignore -->\n```js\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n environment: 'development', // defaults to 'production'\n});\n\nconst response = await client.v1.public.journeys.trigger('REPLACE_ME', {\n profile: { email: 'user@example.com' },\n});\n\nconsole.log(response.runId);\n```\n\n\n\n### Request & Response types\n\nThis library includes TypeScript definitions for all request params and response fields. You may import and use them like so:\n\n<!-- prettier-ignore -->\n```ts\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n apiKey: process.env['SEGMENTFLOW_API_KEY'], // This is the default and can be omitted\n environment: 'development', // defaults to 'production'\n});\n\nconst params: SegmentflowAI.V1.Public.JourneyTriggerParams = {\n profile: { email: 'user@example.com' },\n};\nconst response: SegmentflowAI.V1.Public.JourneyTriggerResponse =\n await client.v1.public.journeys.trigger('REPLACE_ME', params);\n```\n\nDocumentation for each method, request param, and response field are available in docstrings and will appear on hover in most modern editors.\n\n\n\n\n\n## Handling errors\n\nWhen the library is unable to connect to the API,\nor if the API returns a non-success status code (i.e., 4xx or 5xx response),\na subclass of `APIError` will be thrown:\n\n<!-- prettier-ignore -->\n```ts\nconst response = await client.v1.public.journeys\n .trigger('REPLACE_ME', { profile: { email: 'user@example.com' } })\n .catch(async (err) => {\n if (err instanceof SegmentflowAI.APIError) {\n console.log(err.status); // 400\n console.log(err.name); // BadRequestError\n console.log(err.headers); // {server: 'nginx', ...}\n } else {\n throw err;\n }\n });\n```\n\nError codes are as follows:\n\n| Status Code | Error Type |\n| ----------- | -------------------------- |\n| 400 | `BadRequestError` |\n| 401 | `AuthenticationError` |\n| 403 | `PermissionDeniedError` |\n| 404 | `NotFoundError` |\n| 422 | `UnprocessableEntityError` |\n| 429 | `RateLimitError` |\n| >=500 | `InternalServerError` |\n| N/A | `APIConnectionError` |\n\n### Retries\n\nCertain errors will be automatically retried 2 times by default, with a short exponential backoff.\nConnection errors (for example, due to a network connectivity problem), 408 Request Timeout, 409 Conflict,\n429 Rate Limit, and >=500 Internal errors will all be retried by default.\n\nYou can use the `maxRetries` option to configure or disable this:\n\n<!-- prettier-ignore -->\n```js\n// Configure the default for all requests:\nconst client = new SegmentflowAI({\n maxRetries: 0, // default is 2\n});\n\n// Or, configure per-request:\nawait client.v1.public.journeys.trigger('REPLACE_ME', { profile: { email: 'user@example.com' } }, {\n maxRetries: 5,\n});\n```\n\n### Timeouts\n\nRequests time out after 1 minute by default. You can configure this with a `timeout` option:\n\n<!-- prettier-ignore -->\n```ts\n// Configure the default for all requests:\nconst client = new SegmentflowAI({\n timeout: 20 * 1000, // 20 seconds (default is 1 minute)\n});\n\n// Override per-request:\nawait client.v1.public.journeys.trigger('REPLACE_ME', { profile: { email: 'user@example.com' } }, {\n timeout: 5 * 1000,\n});\n```\n\nOn timeout, an `APIConnectionTimeoutError` is thrown.\n\nNote that requests which time out will be [retried twice by default](#retries).\n\n\n\n\n\n## Advanced Usage\n\n### Accessing raw Response data (e.g., headers)\n\nThe \"raw\" `Response` returned by `fetch()` can be accessed through the `.asResponse()` method on the `APIPromise` type that all methods return.\nThis method returns as soon as the headers for a successful response are received and does not consume the response body, so you are free to write custom parsing or streaming logic.\n\nYou can also use the `.withResponse()` method to get the raw `Response` along with the parsed data.\nUnlike `.asResponse()` this method consumes the body, returning once it is parsed.\n\n<!-- prettier-ignore -->\n```ts\nconst client = new SegmentflowAI();\n\nconst response = await client.v1.public.journeys\n .trigger('REPLACE_ME', { profile: { email: 'user@example.com' } })\n .asResponse();\nconsole.log(response.headers.get('X-My-Header'));\nconsole.log(response.statusText); // access the underlying Response object\n\nconst { data: response, response: raw } = await client.v1.public.journeys\n .trigger('REPLACE_ME', { profile: { email: 'user@example.com' } })\n .withResponse();\nconsole.log(raw.headers.get('X-My-Header'));\nconsole.log(response.runId);\n```\n\n### Logging\n\n> [!IMPORTANT]\n> All log messages are intended for debugging only. The format and content of log messages\n> may change between releases.\n\n#### Log levels\n\nThe log level can be configured in two ways:\n\n1. Via the `SEGMENTFLOW_AI_LOG` environment variable\n2. Using the `logLevel` client option (overrides the environment variable if set)\n\n```ts\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n logLevel: 'debug', // Show all log messages\n});\n```\n\nAvailable log levels, from most to least verbose:\n\n- `'debug'` - Show debug messages, info, warnings, and errors\n- `'info'` - Show info messages, warnings, and errors\n- `'warn'` - Show warnings and errors (default)\n- `'error'` - Show only errors\n- `'off'` - Disable all logging\n\nAt the `'debug'` level, all HTTP requests and responses are logged, including headers and bodies.\nSome authentication-related headers are redacted, but sensitive data in request and response bodies\nmay still be visible.\n\n#### Custom logger\n\nBy default, this library logs to `globalThis.console`. You can also provide a custom logger.\nMost logging libraries are supported, including [pino](https://www.npmjs.com/package/pino), [winston](https://www.npmjs.com/package/winston), [bunyan](https://www.npmjs.com/package/bunyan), [consola](https://www.npmjs.com/package/consola), [signale](https://www.npmjs.com/package/signale), and [@std/log](https://jsr.io/@std/log). If your logger doesn't work, please open an issue.\n\nWhen providing a custom logger, the `logLevel` option still controls which messages are emitted, messages\nbelow the configured level will not be sent to your logger.\n\n```ts\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\nimport pino from 'pino';\n\nconst logger = pino();\n\nconst client = new SegmentflowAI({\n logger: logger.child({ name: 'SegmentflowAI' }),\n logLevel: 'debug', // Send all messages to pino, allowing it to filter\n});\n```\n\n### Making custom/undocumented requests\n\nThis library is typed for convenient access to the documented API. If you need to access undocumented\nendpoints, params, or response properties, the library can still be used.\n\n#### Undocumented endpoints\n\nTo make requests to undocumented endpoints, you can use `client.get`, `client.post`, and other HTTP verbs.\nOptions on the client, such as retries, will be respected when making these requests.\n\n```ts\nawait client.post('/some/path', {\n body: { some_prop: 'foo' },\n query: { some_query_arg: 'bar' },\n});\n```\n\n#### Undocumented request params\n\nTo make requests using undocumented parameters, you may use `// @ts-expect-error` on the undocumented\nparameter. This library doesn't validate at runtime that the request matches the type, so any extra values you\nsend will be sent as-is.\n\n```ts\nclient.v1.public.journeys.trigger({\n // ...\n // @ts-expect-error baz is not yet public\n baz: 'undocumented option',\n});\n```\n\nFor requests with the `GET` verb, any extra params will be in the query, all other requests will send the\nextra param in the body.\n\nIf you want to explicitly send an extra argument, you can do so with the `query`, `body`, and `headers` request\noptions.\n\n#### Undocumented response properties\n\nTo access undocumented response properties, you may access the response object with `// @ts-expect-error` on\nthe response object, or cast the response object to the requisite type. Like the request params, we do not\nvalidate or strip extra properties from the response from the API.\n\n### Customizing the fetch client\n\nBy default, this library expects a global `fetch` function is defined.\n\nIf you want to use a different `fetch` function, you can either polyfill the global:\n\n```ts\nimport fetch from 'my-fetch';\n\nglobalThis.fetch = fetch;\n```\n\nOr pass it to the client:\n\n```ts\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\nimport fetch from 'my-fetch';\n\nconst client = new SegmentflowAI({ fetch });\n```\n\n### Fetch options\n\nIf you want to set custom `fetch` options without overriding the `fetch` function, you can provide a `fetchOptions` object when instantiating the client or making a request. (Request-specific options override client options.)\n\n```ts\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n fetchOptions: {\n // `RequestInit` options\n },\n});\n```\n\n#### Configuring proxies\n\nTo modify proxy behavior, you can provide custom `fetchOptions` that add runtime-specific proxy\noptions to requests:\n\n<img src=\"https://raw.githubusercontent.com/stainless-api/sdk-assets/refs/heads/main/node.svg\" align=\"top\" width=\"18\" height=\"21\"> **Node** <sup>[[docs](https://github.com/nodejs/undici/blob/main/docs/docs/api/ProxyAgent.md#example---proxyagent-with-fetch)]</sup>\n\n```ts\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\nimport * as undici from 'undici';\n\nconst proxyAgent = new undici.ProxyAgent('http://localhost:8888');\nconst client = new SegmentflowAI({\n fetchOptions: {\n dispatcher: proxyAgent,\n },\n});\n```\n\n<img src=\"https://raw.githubusercontent.com/stainless-api/sdk-assets/refs/heads/main/bun.svg\" align=\"top\" width=\"18\" height=\"21\"> **Bun** <sup>[[docs](https://bun.sh/guides/http/proxy)]</sup>\n\n```ts\nimport SegmentflowAI from '@segmentflow/segmentflow-typescript';\n\nconst client = new SegmentflowAI({\n fetchOptions: {\n proxy: 'http://localhost:8888',\n },\n});\n```\n\n<img src=\"https://raw.githubusercontent.com/stainless-api/sdk-assets/refs/heads/main/deno.svg\" align=\"top\" width=\"18\" height=\"21\"> **Deno** <sup>[[docs](https://docs.deno.com/api/deno/~/Deno.createHttpClient)]</sup>\n\n```ts\nimport SegmentflowAI from 'npm:@segmentflow/segmentflow-typescript';\n\nconst httpClient = Deno.createHttpClient({ proxy: { url: 'http://localhost:8888' } });\nconst client = new SegmentflowAI({\n fetchOptions: {\n client: httpClient,\n },\n});\n```\n\n## Frequently Asked Questions\n\n## Semantic versioning\n\nThis package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions:\n\n1. Changes that only affect static types, without breaking runtime behavior.\n2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_\n3. Changes that we do not expect to impact the vast majority of users in practice.\n\nWe take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience.\n\nWe are keen for your feedback; please open an [issue](https://www.github.com/segmentflow/segmentflow-typescript/issues) with questions, bugs, or suggestions.\n\n## Requirements\n\nTypeScript >= 4.9 is supported.\n\nThe following runtimes are supported:\n\n- Web browsers (Up-to-date Chrome, Firefox, Safari, Edge, and more)\n- Node.js 20 LTS or later ([non-EOL](https://endoflife.date/nodejs)) versions.\n- Deno v1.28.0 or higher.\n- Bun 1.0 or later.\n- Cloudflare Workers.\n- Vercel Edge Runtime.\n- Jest 28 or greater with the `\"node\"` environment (`\"jsdom\"` is not supported at this time).\n- Nitro v2.6 or greater.\n\nNote that React Native is not supported at this time.\n\nIf you are interested in other runtime environments, please open or upvote an issue on GitHub.\n\n## Contributing\n\nSee [the contributing documentation](./CONTRIBUTING.md).\n",
|
|
373
|
+
},
|
|
374
|
+
];
|
|
375
|
+
const INDEX_OPTIONS = {
|
|
376
|
+
fields: [
|
|
377
|
+
'name',
|
|
378
|
+
'endpoint',
|
|
379
|
+
'summary',
|
|
380
|
+
'description',
|
|
381
|
+
'qualified',
|
|
382
|
+
'stainlessPath',
|
|
383
|
+
'content',
|
|
384
|
+
'sectionContext',
|
|
385
|
+
],
|
|
386
|
+
storeFields: ['kind', '_original'],
|
|
387
|
+
searchOptions: {
|
|
388
|
+
prefix: true,
|
|
389
|
+
fuzzy: 0.1,
|
|
390
|
+
boost: {
|
|
391
|
+
name: 5,
|
|
392
|
+
stainlessPath: 3,
|
|
393
|
+
endpoint: 3,
|
|
394
|
+
qualified: 3,
|
|
395
|
+
summary: 2,
|
|
396
|
+
content: 1,
|
|
397
|
+
description: 1,
|
|
398
|
+
},
|
|
399
|
+
},
|
|
400
|
+
};
|
|
401
|
+
/**
|
|
402
|
+
* Self-contained local search engine backed by MiniSearch.
|
|
403
|
+
* Method data is embedded at SDK build time; prose documents
|
|
404
|
+
* can be loaded from an optional docs directory at runtime.
|
|
405
|
+
*/
|
|
406
|
+
class LocalDocsSearch {
|
|
407
|
+
methodIndex;
|
|
408
|
+
proseIndex;
|
|
409
|
+
constructor() {
|
|
410
|
+
this.methodIndex = new minisearch_1.default(INDEX_OPTIONS);
|
|
411
|
+
this.proseIndex = new minisearch_1.default(INDEX_OPTIONS);
|
|
412
|
+
}
|
|
413
|
+
static async create(opts) {
|
|
414
|
+
const instance = new LocalDocsSearch();
|
|
415
|
+
instance.indexMethods(EMBEDDED_METHODS);
|
|
416
|
+
for (const readme of EMBEDDED_READMES) {
|
|
417
|
+
instance.indexProse(readme.content, `readme:${readme.language}`);
|
|
418
|
+
}
|
|
419
|
+
if (opts?.docsDir) {
|
|
420
|
+
await instance.loadDocsDirectory(opts.docsDir);
|
|
421
|
+
}
|
|
422
|
+
return instance;
|
|
423
|
+
}
|
|
424
|
+
search(props) {
|
|
425
|
+
const { query, language = 'typescript', detail = 'default', maxResults = 5, maxLength = 100_000 } = props;
|
|
426
|
+
const useMarkdown = detail === 'verbose' || detail === 'high';
|
|
427
|
+
// Search both indices and merge results by score.
|
|
428
|
+
// Filter prose hits so language-tagged content (READMEs and docs with
|
|
429
|
+
// frontmatter) only matches the requested language.
|
|
430
|
+
const methodHits = this.methodIndex
|
|
431
|
+
.search(query)
|
|
432
|
+
.map((hit) => ({ ...hit, _kind: 'http_method' }));
|
|
433
|
+
const proseHits = this.proseIndex
|
|
434
|
+
.search(query)
|
|
435
|
+
.filter((hit) => {
|
|
436
|
+
const source = hit['_original']?.source;
|
|
437
|
+
if (!source)
|
|
438
|
+
return true;
|
|
439
|
+
// Check for language-tagged sources: "readme:<lang>" or "lang:<lang>:<filename>"
|
|
440
|
+
let taggedLang;
|
|
441
|
+
if (source.startsWith('readme:'))
|
|
442
|
+
taggedLang = source.slice('readme:'.length);
|
|
443
|
+
else if (source.startsWith('lang:'))
|
|
444
|
+
taggedLang = source.split(':')[1];
|
|
445
|
+
if (!taggedLang)
|
|
446
|
+
return true;
|
|
447
|
+
return taggedLang === language || (language === 'javascript' && taggedLang === 'typescript');
|
|
448
|
+
})
|
|
449
|
+
.map((hit) => ({ ...hit, _kind: 'prose' }));
|
|
450
|
+
const merged = [...methodHits, ...proseHits].sort((a, b) => b.score - a.score);
|
|
451
|
+
const top = merged.slice(0, maxResults);
|
|
452
|
+
const fullResults = [];
|
|
453
|
+
for (const hit of top) {
|
|
454
|
+
const original = hit['_original'];
|
|
455
|
+
if (hit._kind === 'http_method') {
|
|
456
|
+
const m = original;
|
|
457
|
+
if (useMarkdown && m.markdown) {
|
|
458
|
+
fullResults.push(m.markdown);
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
// Use per-language data when available, falling back to the
|
|
462
|
+
// top-level fields (which are TypeScript-specific in the
|
|
463
|
+
// legacy codepath).
|
|
464
|
+
const langData = m.perLanguage?.[language];
|
|
465
|
+
fullResults.push({
|
|
466
|
+
method: langData?.method ?? m.qualified,
|
|
467
|
+
summary: m.summary,
|
|
468
|
+
description: m.description,
|
|
469
|
+
endpoint: `${m.httpMethod.toUpperCase()} ${m.endpoint}`,
|
|
470
|
+
...(langData?.example ? { example: langData.example } : {}),
|
|
471
|
+
...(m.params ? { params: m.params } : {}),
|
|
472
|
+
...(m.response ? { response: m.response } : {}),
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
const c = original;
|
|
478
|
+
fullResults.push({
|
|
479
|
+
content: c.content,
|
|
480
|
+
...(c.source ? { source: c.source } : {}),
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
let totalLength = 0;
|
|
485
|
+
const results = [];
|
|
486
|
+
for (const result of fullResults) {
|
|
487
|
+
const len = typeof result === 'string' ? result.length : JSON.stringify(result).length;
|
|
488
|
+
totalLength += len;
|
|
489
|
+
if (totalLength > maxLength)
|
|
490
|
+
break;
|
|
491
|
+
results.push(result);
|
|
492
|
+
}
|
|
493
|
+
if (results.length < fullResults.length) {
|
|
494
|
+
results.unshift(`Truncated; showing ${results.length} of ${fullResults.length} results.`);
|
|
495
|
+
}
|
|
496
|
+
return { results };
|
|
497
|
+
}
|
|
498
|
+
indexMethods(methods) {
|
|
499
|
+
const docs = methods.map((m, i) => ({
|
|
500
|
+
id: `method-${i}`,
|
|
501
|
+
kind: 'http_method',
|
|
502
|
+
name: m.name,
|
|
503
|
+
endpoint: m.endpoint,
|
|
504
|
+
summary: m.summary,
|
|
505
|
+
description: m.description,
|
|
506
|
+
qualified: m.qualified,
|
|
507
|
+
stainlessPath: m.stainlessPath,
|
|
508
|
+
_original: m,
|
|
509
|
+
}));
|
|
510
|
+
if (docs.length > 0) {
|
|
511
|
+
this.methodIndex.addAll(docs);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
async loadDocsDirectory(docsDir) {
|
|
515
|
+
let entries;
|
|
516
|
+
try {
|
|
517
|
+
entries = await fs.readdir(docsDir, { withFileTypes: true });
|
|
518
|
+
}
|
|
519
|
+
catch (err) {
|
|
520
|
+
(0, logger_1.getLogger)().warn({ err, docsDir }, 'Could not read docs directory');
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
const files = entries
|
|
524
|
+
.filter((e) => e.isFile())
|
|
525
|
+
.filter((e) => e.name.endsWith('.md') || e.name.endsWith('.markdown') || e.name.endsWith('.json'));
|
|
526
|
+
for (const file of files) {
|
|
527
|
+
try {
|
|
528
|
+
const filePath = path.join(docsDir, file.name);
|
|
529
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
530
|
+
if (file.name.endsWith('.json')) {
|
|
531
|
+
const texts = extractTexts(JSON.parse(content));
|
|
532
|
+
if (texts.length > 0) {
|
|
533
|
+
this.indexProse(texts.join('\n\n'), file.name);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
else {
|
|
537
|
+
// Parse optional YAML frontmatter for language tagging.
|
|
538
|
+
// Files with a "language" field in frontmatter will only
|
|
539
|
+
// surface in searches for that language.
|
|
540
|
+
//
|
|
541
|
+
// Example:
|
|
542
|
+
// ---
|
|
543
|
+
// language: python
|
|
544
|
+
// ---
|
|
545
|
+
// # Error handling in Python
|
|
546
|
+
// ...
|
|
547
|
+
const frontmatter = parseFrontmatter(content);
|
|
548
|
+
const source = frontmatter.language ? `lang:${frontmatter.language}:${file.name}` : file.name;
|
|
549
|
+
this.indexProse(content, source);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
catch (err) {
|
|
553
|
+
(0, logger_1.getLogger)().warn({ err, file: file.name }, 'Failed to index docs file');
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
indexProse(markdown, source) {
|
|
558
|
+
const chunks = chunkMarkdown(markdown);
|
|
559
|
+
const baseId = this.proseIndex.documentCount;
|
|
560
|
+
const docs = chunks.map((chunk, i) => ({
|
|
561
|
+
id: `prose-${baseId + i}`,
|
|
562
|
+
kind: 'prose',
|
|
563
|
+
content: chunk.content,
|
|
564
|
+
...(chunk.sectionContext != null ? { sectionContext: chunk.sectionContext } : {}),
|
|
565
|
+
_original: { ...chunk, source },
|
|
566
|
+
}));
|
|
567
|
+
if (docs.length > 0) {
|
|
568
|
+
this.proseIndex.addAll(docs);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
exports.LocalDocsSearch = LocalDocsSearch;
|
|
573
|
+
/** Lightweight markdown chunker — splits on headers, chunks by word count. */
|
|
574
|
+
function chunkMarkdown(markdown) {
|
|
575
|
+
// Strip YAML frontmatter
|
|
576
|
+
const stripped = markdown.replace(/^---\n[\s\S]*?\n---\n?/, '');
|
|
577
|
+
const lines = stripped.split('\n');
|
|
578
|
+
const chunks = [];
|
|
579
|
+
const headers = [];
|
|
580
|
+
let current = [];
|
|
581
|
+
const flush = () => {
|
|
582
|
+
const text = current.join('\n').trim();
|
|
583
|
+
if (!text)
|
|
584
|
+
return;
|
|
585
|
+
const sectionContext = headers.length > 0 ? headers.join(' > ') : undefined;
|
|
586
|
+
// Split into ~200-word chunks
|
|
587
|
+
const words = text.split(/\s+/);
|
|
588
|
+
for (let i = 0; i < words.length; i += 200) {
|
|
589
|
+
const slice = words.slice(i, i + 200).join(' ');
|
|
590
|
+
if (slice) {
|
|
591
|
+
chunks.push({ content: slice, tag: 'p', ...(sectionContext != null ? { sectionContext } : {}) });
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
current = [];
|
|
595
|
+
};
|
|
596
|
+
for (const line of lines) {
|
|
597
|
+
const headerMatch = line.match(/^(#{1,6})\s+(.+)/);
|
|
598
|
+
if (headerMatch) {
|
|
599
|
+
flush();
|
|
600
|
+
const level = headerMatch[1].length;
|
|
601
|
+
const text = headerMatch[2].trim();
|
|
602
|
+
while (headers.length >= level)
|
|
603
|
+
headers.pop();
|
|
604
|
+
headers.push(text);
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
current.push(line);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
flush();
|
|
611
|
+
return chunks;
|
|
612
|
+
}
|
|
613
|
+
/** Recursively extracts string values from a JSON structure. */
|
|
614
|
+
function extractTexts(data, depth = 0) {
|
|
615
|
+
if (depth > 10)
|
|
616
|
+
return [];
|
|
617
|
+
if (typeof data === 'string')
|
|
618
|
+
return data.trim() ? [data] : [];
|
|
619
|
+
if (Array.isArray(data))
|
|
620
|
+
return data.flatMap((item) => extractTexts(item, depth + 1));
|
|
621
|
+
if (typeof data === 'object' && data !== null) {
|
|
622
|
+
return Object.values(data).flatMap((v) => extractTexts(v, depth + 1));
|
|
623
|
+
}
|
|
624
|
+
return [];
|
|
625
|
+
}
|
|
626
|
+
/** Parses YAML frontmatter from a markdown string, extracting the language field if present. */
|
|
627
|
+
function parseFrontmatter(markdown) {
|
|
628
|
+
const match = markdown.match(/^---\n([\s\S]*?)\n---/);
|
|
629
|
+
if (!match)
|
|
630
|
+
return {};
|
|
631
|
+
const body = match[1] ?? '';
|
|
632
|
+
const langMatch = body.match(/^language:\s*(.+)$/m);
|
|
633
|
+
return langMatch ? { language: langMatch[1].trim() } : {};
|
|
634
|
+
}
|
|
635
|
+
//# sourceMappingURL=local-docs-search.js.map
|